Skip to content

Commit bf54db6

Browse files
mohanchenabacus_fixer
andauthored
Remove PARAM in source_cell (including tests); revert the dependency between unitcell in source_cell and ORB files in source_basis; update some agent governance (#7644)
* add nonlocal_info_base.h * move setup_nonloal to source_lcao * refactor: dependency inversion for non-local pseudopotential This commit implements dependency inversion to decouple source_cell from source_basis ORB files. The key changes are: 1. Created abstract base class NonlocalInfoBase in source_cell/nonlocal_info_base.h - Provides pure virtual interface for non-local pseudopotential data access - Eliminates source_cell's direct dependency on ORB headers 2. Implemented adapter class LCAONonlocalInfo in source_lcao/LCAO_nonlocal_info.h - Inherits from NonlocalInfoBase - Wraps the existing InfoNonlocal class - Provides type-safe access to underlying LCAO-specific non-local data 3. Modified UnitCell to use NonlocalInfoBase* instead of InfoNonlocal - Changed from value member to pointer - Added proper cleanup in destructor 4. Moved setup_nonlocal.h/cpp from source_cell to source_lcao - Consolidates LCAO-specific code in the appropriate module - Updated include paths in dependent files 5. Updated all call sites to use the new abstract interface - Replaced direct member access with getter methods - Ensured const-correctness throughout This design follows the Dependency Inversion Principle: - High-level module (source_cell) now depends on abstraction (NonlocalInfoBase) - Low-level module (source_lcao) implements the abstraction - source_cell no longer depends on source_basis ORB headers * fix bug * fix compile bugs * due to the change of unitcell, we need to change related tests * remove some PARAM * fix GPU compiling bug * remove PARAM in source_cell * remove PARAM * remove PARAM * remove PARAM * update read pseudopotentials * update removing PARAM * update * remove PARAM * remove PARAM in klist * update, removing PARAM * update * update * update * update * update * remove parameter.h * update cmake * remove PARAM in symm * fix test * fix * fix bug * update fix bugs * fix problems * update * fix * fix * move cal_nelec_nband from estate to cell * fix bug * remove PARAM in deepks test * fix bug * fix important bug! * fix another important bug! * fix tests and input parameter documentation: not needed * update, fix bugs * update agent governance * update agent governance * use a method to eliminate the define private public method * fix nupdown bug * remove some notes * update headers * replace NonlocalInfoBase* infoNL = nullptr with std::unique_ptr<NonlocalInfoBase> infoNL --------- Co-authored-by: abacus_fixer <mohanchen@pku.eud.cn>
1 parent 5a6a6f5 commit bf54db6

171 files changed

Lines changed: 9035 additions & 1446 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

docs/developers_guide/agent_governance.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ decisions.
8080
| Heterogeneous test evidence | CUDA/ROCM/kernel change has test evidence or reason | phase-one mechanical warning + AI review | CI + AI review | high | warn | changed paths and PR body | Sufficiency is human-reviewed |
8181
| Test existence | Source change has test evidence or reason | phase-one mechanical warning + AI review | CI + AI review | high | warn | PR body and changed paths | Sufficiency is human-reviewed |
8282
| Test sufficiency | Tests cover important behavior | AI review + human confirmation | AI + human review | medium | human confirmation | semantic review | Not mechanically blocked |
83-
| INPUT behavior linkage | Parameter metadata/default/type/parser behavior updates YAML and docs | phase-one mechanical + AI review | CI + AI review | high | block | behavior-field diff plus docs/PR body | Comment-only parameter-file changes are not blocked |
83+
| INPUT behavior linkage | Parameter metadata/default/type/parser behavior updates YAML and docs | phase-one mechanical + AI review | CI + AI review | high | warn | behavior-field diff plus docs/PR body | Comment-only parameter-file changes are not blocked |
8484
| Documentation sync | Behavior/interface docs updated | phase-one mechanical warning + AI review | CI + AI review | medium | warn | changed paths and PR body | Major behavior changes escalate to reviewers |
8585
| PR metadata completeness | Issue, tests, behavior, INPUT, core impact, exceptions | phase-one mechanical | CI or GitHub bot | medium | warn | PR template fields | Not run by local hook |
8686
| AI workflow | Interface lookup, uncertainty, verification report | AI review | AI review | high | warn | review transcript/output | Applies to AI agents |
@@ -215,13 +215,15 @@ setup workflows and should be added only through a later governance change.
215215
## INPUT Parameter Changes
216216

217217
Changes to parameter metadata, default values, type, availability, description,
218-
or parsing behavior must include both:
218+
or parsing behavior should include both:
219219

220220
- `docs/parameters.yaml`
221221
- `docs/advanced/input_files/input-main.md`
222222

223223
If the diff touches parameter internals but does not change user-visible INPUT
224-
behavior, the PR must state why no documentation update is required.
224+
behavior, the PR should state why no documentation update is required. Missing
225+
documentation updates trigger a governance warning (not a block), but maintainers
226+
may still request documentation updates before merging.
225227

226228
## PR Self-Consistency
227229

python/pyabacus/src/ModuleDriver/py_driver.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -425,7 +425,10 @@ CalculationResult PyDriver::run(
425425
);
426426

427427
// Read structure
428-
impl_->ucell_->setup_cell(PARAM.globalv.global_in_stru, GlobalV::ofs_running);
428+
impl_->ucell_->setup_cell(PARAM.globalv.global_in_stru, GlobalV::ofs_running, PARAM.inp.symmetry_prec, PARAM.inp.dfthalf_type, PARAM.inp.pseudo_dir, PARAM.inp.nspin,
429+
PARAM.inp.basis_type, PARAM.inp.orbital_dir, PARAM.inp.init_wfc,
430+
PARAM.inp.onsite_radius, PARAM.globalv.deepks_setorb, PARAM.inp.rpa,
431+
PARAM.inp.fixed_atoms, PARAM.inp.noncolin, PARAM.inp.calculation, PARAM.inp.esolver_type);
429432

430433
// Check atomic structure
431434
unitcell::check_atomic_stru(*impl_->ucell_, PARAM.inp.min_dist_coef);

source/Makefile.Objects

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ OBJS_CELL=atom_pseudo.o\
205205
read_atom_species.o\
206206
sep.o\
207207
sep_cell.o\
208+
cal_nelec_nband.o\
208209

209210
OBJS_DEEPKS=LCAO_deepks.o\
210211
deepks_basic.o\
@@ -247,7 +248,6 @@ OBJS_ELECSTAT=elecstate.o\
247248
pot_xc.o\
248249
cal_ux.o\
249250
read_orb.o\
250-
cal_nelec_nband.o\
251251
read_pseudo.o\
252252
cal_wfc.o\
253253
setup_estate_pw.o\

source/source_cell/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ add_library(
1818
read_atoms.cpp
1919
read_atoms_helper.cpp
2020
read_orb.cpp
21-
setup_nonlocal.cpp
2221
klist.cpp
2322
parallel_kpoints.cpp
2423
cell_index.cpp
@@ -34,6 +33,7 @@ add_library(
3433
sep_cell.cpp
3534
qlist.cpp
3635
qlist.h
36+
cal_nelec_nband.cpp
3737
)
3838

3939
if(ENABLE_COVERAGE)

source/source_cell/atom_pseudo.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
#include "atom_pseudo.h"
2-
#include "source_io/module_parameter/parameter.h"
32

4-
#include "source_io/module_parameter/parameter.h"
53
Atom_pseudo::Atom_pseudo()
64
{
75
}
@@ -14,8 +12,12 @@ Atom_pseudo::~Atom_pseudo()
1412
void Atom_pseudo::set_d_so(ModuleBase::ComplexMatrix& d_so_in,
1513
const int& nproj_in,
1614
const int& nproj_in_so,
17-
const bool has_so)
15+
const bool has_so,
16+
const bool lspinorb,
17+
const int nspin)
1818
{
19+
const bool lspinorb_ = lspinorb;
20+
const int nspin_ = nspin;
1921
if (this->lmax < -1 || this->lmax > 20)
2022
{
2123
ModuleBase::WARNING_QUIT("Numerical_Nonlocal", "bad input of lmax : should be between -1 and 20");
@@ -69,7 +71,7 @@ void Atom_pseudo::set_d_so(ModuleBase::ComplexMatrix& d_so_in,
6971

7072
if (this->lmax > -1)
7173
{
72-
if (PARAM.inp.lspinorb)
74+
if (lspinorb_)
7375
{
7476
int is = 0;
7577
for (int is1 = 0; is1 < 2; is1++)
@@ -107,7 +109,7 @@ void Atom_pseudo::set_d_so(ModuleBase::ComplexMatrix& d_so_in,
107109
{
108110
for (int is2 = 0; is2 < 2; is2++)
109111
{
110-
if (is >= PARAM.inp.nspin) {
112+
if (is >= nspin_) {
111113
break;
112114
}
113115
for (int L1 = 0; L1 < nproj_soc; L1++)

source/source_cell/atom_pseudo.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@ class Atom_pseudo : public pseudo
2727
ModuleBase::ComplexMatrix &d_so_in,
2828
const int &nproj_in,
2929
const int &nproj_in_so,
30-
const bool has_so);
30+
const bool has_so,
31+
const bool lspinorb,
32+
const int nspin);
3133

3234

3335
inline void get_d(const int& is, const int& p1, const int& p2, const std::complex<double>*& tmp_d)

source/source_cell/bcast_cell.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#include "unitcell.h"
22
#include "source_base/parallel_common.h"
3-
#include "source_io/module_parameter/parameter.h"
3+
44
#include "source_hamilt/module_xc/exx_info.h" // use GlobalC::exx_info
55

66
#include <string>
@@ -99,32 +99,32 @@ namespace unitcell
9999
#endif
100100
}
101101

102-
void bcast_magnetism(Magnetism& magnet, const int ntype)
102+
void bcast_magnetism(Magnetism& magnet, const int ntype, const int nspin)
103103
{
104-
#ifdef __MPI
104+
#ifdef __MPI
105105
MPI_Barrier(MPI_COMM_WORLD);
106106
if (GlobalV::MY_RANK != 0)
107107
{
108108
magnet.start_mag.resize(ntype, 0.0);
109109
}
110110
Parallel_Common::bcast_double(magnet.start_mag.data(), ntype);
111-
if (PARAM.inp.nspin == 4)
111+
if (nspin == 4)
112112
{
113113
Parallel_Common::bcast_double(magnet.ux_[0]);
114114
Parallel_Common::bcast_double(magnet.ux_[1]);
115115
Parallel_Common::bcast_double(magnet.ux_[2]);
116116
}
117-
#endif
117+
#endif
118118
}
119119

120-
void bcast_unitcell(UnitCell& ucell)
120+
void bcast_unitcell(UnitCell& ucell, const int nspin)
121121
{
122-
#ifdef __MPI
122+
#ifdef __MPI
123123
const int ntype = ucell.ntype;
124124
Parallel_Common::bcast_int(ucell.nat);
125125

126126
bcast_Lattice(ucell.lat);
127-
bcast_magnetism(ucell.magnet,ntype);
127+
bcast_magnetism(ucell.magnet,ntype, nspin);
128128
bcast_atoms_tau(ucell.atoms,ntype);
129129

130130
for (int i = 0; i < ntype; i++)

source/source_cell/bcast_cell.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,17 @@ namespace unitcell
3535
* @param nytpe: the number of types of the atoms [in]
3636
*/
3737
void bcast_magnetism(Magnetism& magnet,
38-
const int ntype);
39-
38+
const int ntype,
39+
const int nspin);
40+
4041
/**
4142
* @brief broadcast the unitcell
4243
*
4344
* @param ucell: the unitcell to be broadcasted [in/out]
45+
* @param nspin: the number of spin components
4446
*/
45-
void bcast_unitcell(UnitCell& ucell);
47+
void bcast_unitcell(UnitCell& ucell,
48+
const int nspin);
4649

4750

4851
}
Lines changed: 86 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,90 +1,148 @@
11
#ifndef CAL_ATOMS_INFO_H
22
#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"
54
#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+
617
class CalAtomsInfo
718
{
819
public:
920
CalAtomsInfo(){};
1021
~CalAtomsInfo(){};
1122

1223
/**
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.
1430
*
1531
* @param atoms [in] Atom pointer
1632
* @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
1846
*/
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)
2059
{
60+
AtomsInfoResult result;
61+
2162
// calculate initial total magnetization when NSPIN=2
22-
if (para.inp.nspin == 2 && !para.globalv.two_fermi)
63+
if (nspin == 2 && !two_fermi)
2364
{
2465
for (int it = 0; it < ntype; ++it)
2566
{
2667
for (int ia = 0; ia < atoms[it].na; ++ia)
2768
{
28-
para.input.nupdown += atoms[it].mag[ia];
69+
result.nupdown += atoms[it].mag[ia];
2970
}
3071
}
3172
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);
3379
}
34-
3580

3681
// decide whether to be USPP
3782
for (int it = 0; it < ntype; ++it)
3883
{
3984
if (atoms[it].ncpp.tvanp)
4085
{
41-
para.sys.use_uspp = true;
86+
result.use_uspp = true;
4287
}
4388
}
4489

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+
4597
// 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;
47103
for (int it = 0; it < ntype; ++it)
48104
{
49105
const int nlocal_it = atoms[it].nw * atoms[it].na;
50-
if (para.inp.nspin != 4)
106+
if (nspin != 4)
51107
{
52-
para.sys.nlocal += nlocal_it;
108+
result.nlocal += nlocal_it;
53109
}
54110
else
55111
{
56-
para.sys.nlocal += nlocal_it * 2; // zhengdy-soc
112+
result.nlocal += nlocal_it * 2; // zhengdy-soc
57113
}
58114
}
59115

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);
62118

63119
// autoset and check GlobalV::NBANDS
64120
std::vector<double> nelec_spin(2, 0.0);
65-
if (para.inp.nspin == 2)
121+
if (nspin == 2)
66122
{
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;
69125
}
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);
71129

72130
// 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")
75133
{
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)
78136
{
79-
para.sys.nbands_l++;
137+
result.nbands_l++;
80138
}
81139
}
82140
// temporary code
83-
if (GlobalV::MY_BNDGROUP == 0 || para.inp.ks_solver == "bpcg")
141+
if (GlobalV::MY_BNDGROUP == 0 || ks_solver == "bpcg")
84142
{
85-
para.sys.ks_run = true;
143+
result.ks_run = true;
86144
}
87-
return;
145+
return result;
88146
}
89147
};
90148
#endif

0 commit comments

Comments
 (0)