|
1 | 1 | #ifndef CAL_ATOMS_INFO_H |
2 | 2 | #define CAL_ATOMS_INFO_H |
3 | | -#include "source_io/module_parameter/parameter.h" |
4 | | -#include "source_estate/cal_nelec_nband.h" |
| 3 | +#include "source_cell/cal_nelec_nband.h" |
5 | 4 | #include "source_base/global_function.h" |
| 5 | + |
| 6 | +struct AtomsInfoResult |
| 7 | +{ |
| 8 | + int nlocal = 0; |
| 9 | + double nelec = 0.0; |
| 10 | + int nbands = 0; |
| 11 | + double nupdown = 0.0; |
| 12 | + bool use_uspp = false; |
| 13 | + int nbands_l = 0; |
| 14 | + bool ks_run = false; |
| 15 | +}; |
| 16 | + |
6 | 17 | class CalAtomsInfo |
7 | 18 | { |
8 | 19 | public: |
9 | 20 | CalAtomsInfo(){}; |
10 | 21 | ~CalAtomsInfo(){}; |
11 | 22 |
|
12 | 23 | /** |
13 | | - * @brief Calculate the atom information from pseudopotential to set Parameter |
| 24 | + * @brief Calculate the atom information from pseudopotential |
| 25 | + * |
| 26 | + * IMPORTANT: The nbands and nelec parameters must be the user-specified values from INPUT file. |
| 27 | + * This function passes nbands to cal_nbands() and nelec to cal_nelec(). |
| 28 | + * If nbands is 0, cal_nbands() will auto-calculate a default. |
| 29 | + * If nelec is 0, cal_nelec() will auto-calculate based on atomic valence. |
14 | 30 | * |
15 | 31 | * @param atoms [in] Atom pointer |
16 | 32 | * @param ntype [in] number of atom types |
17 | | - * @param para [out] Parameter object |
| 33 | + * @param nspin [in] number of spin components |
| 34 | + * @param two_fermi [in] two fermi level flag |
| 35 | + * @param nelec_delta [in] electron number delta |
| 36 | + * @param esolver_type [in] solver type |
| 37 | + * @param lspinorb [in] spin-orbit coupling flag |
| 38 | + * @param basis_type [in] basis type |
| 39 | + * @param smearing_method [in] smearing method |
| 40 | + * @param ks_solver [in] KS solver type |
| 41 | + * @param bndpar [in] band parallel parameter |
| 42 | + * @param nbands [in] user-specified number of bands from INPUT file |
| 43 | + * @param nelec [in] user-specified number of electrons from INPUT file |
| 44 | + * @param nupdown [in] user-specified spin polarization from INPUT file |
| 45 | + * @return AtomsInfoResult containing calculated atom information |
18 | 46 | */ |
19 | | - void cal_atoms_info(const Atom* atoms, const int& ntype, Parameter& para) |
| 47 | + AtomsInfoResult cal_atoms_info(Atom* atoms, const int& ntype, |
| 48 | + const int nspin, const bool two_fermi, |
| 49 | + const double nelec_delta, |
| 50 | + const std::string& esolver_type, |
| 51 | + const bool lspinorb, |
| 52 | + const std::string& basis_type, |
| 53 | + const std::string& smearing_method, |
| 54 | + const std::string& ks_solver, |
| 55 | + const int bndpar, |
| 56 | + const int nbands, |
| 57 | + const double nelec, |
| 58 | + const double nupdown) |
20 | 59 | { |
| 60 | + AtomsInfoResult result; |
| 61 | + |
21 | 62 | // calculate initial total magnetization when NSPIN=2 |
22 | | - if (para.inp.nspin == 2 && !para.globalv.two_fermi) |
| 63 | + if (nspin == 2 && !two_fermi) |
23 | 64 | { |
24 | 65 | for (int it = 0; it < ntype; ++it) |
25 | 66 | { |
26 | 67 | for (int ia = 0; ia < atoms[it].na; ++ia) |
27 | 68 | { |
28 | | - para.input.nupdown += atoms[it].mag[ia]; |
| 69 | + result.nupdown += atoms[it].mag[ia]; |
29 | 70 | } |
30 | 71 | } |
31 | 72 | GlobalV::ofs_running << std::endl; |
32 | | - ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "The readin total magnetization", para.inp.nupdown); |
| 73 | + ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "The readin total magnetization", result.nupdown); |
| 74 | + } |
| 75 | + else if (nspin == 2 && two_fermi) |
| 76 | + { |
| 77 | + result.nupdown = nupdown; |
| 78 | + ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "The user-specified total magnetization", result.nupdown); |
33 | 79 | } |
34 | | - |
35 | 80 |
|
36 | 81 | // decide whether to be USPP |
37 | 82 | for (int it = 0; it < ntype; ++it) |
38 | 83 | { |
39 | 84 | if (atoms[it].ncpp.tvanp) |
40 | 85 | { |
41 | | - para.sys.use_uspp = true; |
| 86 | + result.use_uspp = true; |
42 | 87 | } |
43 | 88 | } |
44 | 89 |
|
| 90 | + // set index for atoms before calculating nlocal |
| 91 | + // this ensures consistency with cal_nwfc() which also calls set_index() first |
| 92 | + for (int it = 0; it < ntype; ++it) |
| 93 | + { |
| 94 | + atoms[it].set_index(); |
| 95 | + } |
| 96 | + |
45 | 97 | // calculate the total number of local basis |
46 | | - para.sys.nlocal = 0; |
| 98 | + // nlocal = sum over all atom types of (atoms[it].nw * atoms[it].na) |
| 99 | + // For nspin == 4 (non-collinear), each basis function has 2 polarizations, |
| 100 | + // so nlocal is doubled. This value is used by cal_nwfc() to initialize |
| 101 | + // index arrays (iwt2iat, iwt2iw, itia2iat). |
| 102 | + result.nlocal = 0; |
47 | 103 | for (int it = 0; it < ntype; ++it) |
48 | 104 | { |
49 | 105 | const int nlocal_it = atoms[it].nw * atoms[it].na; |
50 | | - if (para.inp.nspin != 4) |
| 106 | + if (nspin != 4) |
51 | 107 | { |
52 | | - para.sys.nlocal += nlocal_it; |
| 108 | + result.nlocal += nlocal_it; |
53 | 109 | } |
54 | 110 | else |
55 | 111 | { |
56 | | - para.sys.nlocal += nlocal_it * 2; // zhengdy-soc |
| 112 | + result.nlocal += nlocal_it * 2; // zhengdy-soc |
57 | 113 | } |
58 | 114 | } |
59 | 115 |
|
60 | | - // calculate the total number of electrons |
61 | | - elecstate::cal_nelec(atoms, ntype, para.input.nelec); |
| 116 | + result.nelec = nelec; |
| 117 | + unitcell::cal_nelec(atoms, ntype, result.nelec, nelec_delta); |
62 | 118 |
|
63 | 119 | // autoset and check GlobalV::NBANDS |
64 | 120 | std::vector<double> nelec_spin(2, 0.0); |
65 | | - if (para.inp.nspin == 2) |
| 121 | + if (nspin == 2) |
66 | 122 | { |
67 | | - nelec_spin[0] = (para.inp.nelec + para.inp.nupdown ) / 2.0; |
68 | | - nelec_spin[1] = (para.inp.nelec - para.inp.nupdown ) / 2.0; |
| 123 | + nelec_spin[0] = (result.nelec + result.nupdown) / 2.0; |
| 124 | + nelec_spin[1] = (result.nelec - result.nupdown) / 2.0; |
69 | 125 | } |
70 | | - elecstate::cal_nbands(para.inp.nelec, para.sys.nlocal, nelec_spin, para.input.nbands); |
| 126 | + result.nbands = nbands; |
| 127 | + unitcell::cal_nbands(static_cast<int>(result.nelec), result.nlocal, nelec_spin, result.nbands, |
| 128 | + esolver_type, lspinorb, nspin, basis_type, smearing_method); |
71 | 129 |
|
72 | 130 | // calculate the number of nbands_local |
73 | | - para.sys.nbands_l = para.inp.nbands; |
74 | | - if (para.inp.ks_solver == "bpcg") // only bpcg support band parallel |
| 131 | + result.nbands_l = result.nbands; |
| 132 | + if (ks_solver == "bpcg") |
75 | 133 | { |
76 | | - para.sys.nbands_l = para.inp.nbands / para.inp.bndpar; |
77 | | - if (GlobalV::MY_BNDGROUP < para.inp.nbands % para.inp.bndpar) |
| 134 | + result.nbands_l = result.nbands / bndpar; |
| 135 | + if (GlobalV::MY_BNDGROUP < result.nbands % bndpar) |
78 | 136 | { |
79 | | - para.sys.nbands_l++; |
| 137 | + result.nbands_l++; |
80 | 138 | } |
81 | 139 | } |
82 | 140 | // temporary code |
83 | | - if (GlobalV::MY_BNDGROUP == 0 || para.inp.ks_solver == "bpcg") |
| 141 | + if (GlobalV::MY_BNDGROUP == 0 || ks_solver == "bpcg") |
84 | 142 | { |
85 | | - para.sys.ks_run = true; |
| 143 | + result.ks_run = true; |
86 | 144 | } |
87 | | - return; |
| 145 | + return result; |
88 | 146 | } |
89 | 147 | }; |
90 | 148 | #endif |
0 commit comments