Skip to content

Commit 370e024

Browse files
mohanchenabacus_fixer
andauthored
Refactor DFT+U, step 5 (deepmodeling#7867)
* refactor(dftu): remove redundant cal_force/cal_stress members from Plus_U These flags were constant copies of PARAM.inp.cal_force/cal_stress stored at init time. The sole consumer DFTU_LCAO::force_stress now receives them as explicit parameters from its caller, consistent with the operator cal_force_stress interfaces. * refactor(dftu): pass pv and gamma_only_local as function parameters - Replace implicit Plus_U member access with an explicit `const Parallel_Orbitals* pv` argument for all module_dftu functions (pot_onsite_*, cal_occ_mat_*, cal_eff_pot_mat_R_*, pot_uterm_*, cal_nlm_all, cal_occ/cal_HR_IJR/cal_force_IJR/cal_stress_IJR, folding) - Thread the removed gamma_only_local member through explicit arguments: esolver_ks_lcao -> finish_dftu_lcao -> DFTU_LCAO::cal_occ_mat -> Plus_U::cal_occ_mat_k -> folding_matrix_k_new - Update call sites: spar_u.cpp, force_stress_lcao.cpp, lcao_set.cpp, setup_dftu_lcao.{h,cpp}, esolver_ks_lcao.cpp, dftu_lcao_op_legacy.cpp * refactor(dftu): pass nspin as function parameter to cal_occ_mat_k/gamma To prepare for extracting cal_occ_mat_k and cal_occ_mat_gamma into free functions in dftu_occup.h/cpp, remove their dependency on the Plus_U_Base::nspin member variable. Changes: - Add const int nspin parameter to Plus_U::cal_occ_mat_k and Plus_U::cal_occ_mat_gamma declarations and definitions. - Replace all this->nspin reads inside both functions with the nspin parameter (8 occurrences). - Add nspin to DFTU_LCAO::cal_occ_mat template and its two specializations, passing it through to cal_occ_mat_k/gamma. - finish_dftu_lcao already receives nspin; pass it to cal_occ_mat. Plus_U_Base::nspin member is kept intact since it is still used by PW-side code (dftu_base.cpp, dftu_cal_occ_pw.cpp) and LCAO force/stress/operators (dftu_fs.cpp, dftu_lcao_op.cpp, dftu_yukawa.cpp). Governance rules: rule 2 (reduce hidden state dependency in the target functions), rule 5 (no default args added; call sites updated). Verification: make -j 30 in build_max_para_test succeeded, target abacus_max_para linked. * refactor(dftu): pass npol/nlocal/ks_solver as parameters to cal_occ_mat_k/gamma Continue decoupling cal_occ_mat_k and cal_occ_mat_gamma from Plus_U member variables, following the same pattern as nspin. Changes: - Add const int npol, const int nlocal to both cal_occ_mat_k and cal_occ_mat_gamma; add const std::string& ks_solver to cal_occ_mat_k. - Replace all this->npol, this->nlocal, this->ks_solver reads inside both functions with the new parameters. - DFTU_LCAO::cal_occ_mat template signature unchanged; specializations pass dftu.get_npol(), dftu.get_nlocal(), dftu.get_ks_solver(). - setup_dftu_lcao.cpp unchanged because the wrapper still receives Plus_U& dftu and reads the accessors. Governance rules: rule 2 (reduce hidden state dependency), rule 5 (no default args added). Verification: make -j 30 in build_max_para_test succeeded, target abacus_max_para linked. * refactor(dftu): pass iatlnmipol2iwt as parameter to cal_occ_mat_k/gamma Step 2 of decoupling cal_occ_mat_k/gamma from Plus_U member variables. Changes: - Add const reference parameter iatlnmipol2iwt to both function declarations and definitions. - Replace all this->iatlnmipol2iwt reads (4 occurrences) with the parameter. - cal_occ_mat specializations pass dftu.get_iatlnmipol2iwt(). Governance rules: rule 2 (reduce hidden state dependency), rule 5 (no default args added). Verification: make -j 30 in build_max_para_test succeeded, target abacus_max_para linked. * refactor(dftu): pass orbital_corr as parameter to cal_occ_mat_k/gamma Step 3 of decoupling cal_occ_mat_k/gamma from Plus_U member variables. Changes: - Add const std::vector<int>& orbital_corr parameter to both function declarations and definitions. - Replace get_orbital_corr(it) with orbital_corr[it]. - Replace has_correlated_orbital(it) with orbital_corr[it] != -1. - cal_occ_mat specializations pass dftu.get_orbital_corr_vec(). Governance rules: rule 2 (reduce hidden state dependency), rule 5 (no default args added). Verification: make -j 30 in build_max_para_test succeeded, target abacus_max_para linked. * refactor(dftu): pass occ_mat data as parameters to cal_occ_mat_k/gamma Step 4 of decoupling cal_occ_mat_k/gamma from Plus_U member variables. Changes: - Add occ_mat, occ_mat_save, occ_mat_initialized as reference parameters to both function declarations and definitions. - Inline copy_occ_mat and zero_occ_mat logic (LCAO version, without PW-side uom_save handling) into both functions. - Inline mix_occ_mat logic (LCAO version, without uom_save) into both functions. - Replace is_mixing_enabled() && is_occ_mat_initialized() with is_mixing_enabled() && occ_mat_initialized (occ_mat_initialized is now a parameter). - Keep mark_occ_mat_initialized() as member call since it writes to the Plus_U_Base member; the value is only read on subsequent calls. - Add get_occ_mat_data(), get_occ_mat_save_data(), get_occ_mat_initialized() accessors to Plus_U_Base. - cal_occ_mat specializations pass the new parameters via accessors. Governance rules: rule 2 (reduce hidden state dependency), rule 5 (no default args added). Verification: make -j 30 in build_max_para_test succeeded, target abacus_max_para linked. * refactor(dftu): convert cal_occ_mat_k/gamma to DFTU_LCAO free functions Move cal_occ_mat_k and cal_occ_mat_gamma from Plus_U member functions to DFTU_LCAO namespace free functions in dftu_occup.cpp. Changes: - Remove Plus_U::cal_occ_mat_k and Plus_U::cal_occ_mat_gamma member declarations from dftu_lcao.h. - Add DFTU_LCAO::cal_occ_mat_k and DFTU_LCAO::cal_occ_mat_gamma free function declarations at the end of dftu_lcao.h. - Change definitions in dftu_occup.cpp from Plus_U:: to DFTU_LCAO::. - Change occ_mat_initialized parameter from const bool& to bool&. - Replace is_mixing_enabled() with PARAM.inp.mixing_dftu (direct read of input parameter, same semantics). - Replace mark_occ_mat_initialized() with occ_mat_initialized = true (write through reference parameter). - Add Plus_U_Base::set_occ_mat_initialized(bool) setter. - cal_occ_mat specializations call DFTU_LCAO:: free functions, copy occ_mat_initialized in/out via local variable. Governance rules: rule 1 (dependencies passed explicitly), rule 2 (eliminate hidden workflow state from member functions), rule 5 (no default args added). Verification: make -j 30 in build_max_para_test succeeded, target abacus_max_para linked. * docs(agents): add member-to-free-function refactoring pattern Capture the incremental refactoring workflow validated in the DFTU occupancy-matrix refactor: inventory this-> reads, pass them as explicit parameters (const for config, reference for mutable state), move the function only when the body is this-free, keep a thin wrapper at the old entry point, and compile each step. * fix compiler bug * refactor(dftu): move cal_occ_mat_k/gamma declarations into dftu_lcao_occ.h Rename dftu_occup.h/.cpp to dftu_lcao_occ.h/.cpp so the occupation-matrix declarations (template cal_occ_mat<T> dispatcher plus the two concrete free functions) live in one header, and drop the now-unneeded hamilt forward declaration from dftu_lcao.h. Build files updated accordingly. Verified: make -j 30 in build_max_para_test (exit 0, abacus_max_para v3.11.0-beta8); agent_governance_check.py --staged passed with warnings only (header includes required by moved declarations). * fix bug * update format * refactor(dftu): move cal_occ_mat<T> specializations into dftu_lcao_occ.cpp Co-locate the template specializations with the cal_occ_mat_k/gamma implementations they dispatch to, so dftu_lcao.cpp only keeps Plus_U class methods. Drop the dftu_lcao_occ.h and matrix.h includes that were only needed by the moved code, and include dftu_lcao.h in dftu_lcao_occ.cpp for the Plus_U accessors. Verified: make -j 30 (exit 0) and scf_u_spin2_old FINAL_ETOT unchanged (-6304.2287463338761881 eV). * refactor(dftu): extract cal_energy_correction and onsite potential to DFTU_LCAO free functions Move the DFT+U energy correction and onsite potential routines out of Plus_U member functions into DFTU_LCAO namespace free functions, following the member-to-free-function refactoring pattern: - dftu_lcao_pots.{h,cpp} (renamed from dftu_tools.cpp via git mv): DFTU_LCAO::get_onsite_pot (renamed from get_onebody_eff_pot) and pot_onsite_complex/real free functions. Plus_U::pot_onsite_complex/real kept as thin wrappers since the OperatorDFTU call sites lack a ucell. - dftu_lcao_energy.{h,cpp}: DFTU_LCAO::cal_energy_correction; drop the unused istep parameter; read nspin from PARAM.inp.nspin instead of the Plus_U::nspin member (member indirection being removed); accumulate energy_u in a local then write back via set_energy. - setup_dftu_lcao.cpp: call site switched to DFTU_LCAO::cal_energy_correction(*dftu_ptr, ucell). - dftu_base.h: add get_cal_type() and a const get_occ_mat_save() accessor so the free functions can read private Plus_U_Base state. - Update TITLE/timer class-name labels from "Plus_U" to "DFTU_LCAO" in all DFTU_LCAO free functions (occ/pots/energy) for consistency; Plus_U::pot_onsite_* member wrappers keep "Plus_U". Verified: cmake --build build -j4 (exit 0); scf_u_spin2_old FINAL_ETOT bit-for-bit unchanged vs pre-refactor baseline (-10991.9324016761565872 eV; E_plusU 53.9747137694 eV); agent_governance_check: 1 ERROR (PARAM.inp.nspin, intentional, removes the Plus_U::nspin member indirection) + 3 non-blocking WARNINGs. * refactor(dftu): extract Yukawa potential functions to free functions Move all Yukawa-potential-related member functions of Plus_U to free functions in the DFTU_LCAO namespace, declared in the new header dftu_yukawa.h and defined in dftu_yukawa.cpp: - spherical_Bessel / spherical_Hankel (pure math helpers) - cal_yukawa_lambda (lambda from rho, nspin read from PARAM.inp.nspin) - cal_slater_Fk (Slater integrals Fk) - cal_slater_UJ (driver: lambda + Fk -> U/J/u_current writeback) To keep the free functions compiling without exposing protected state to the world, add focused accessors on the base/derived classes: - Plus_U_Base: set_U_Yukawa / set_J_Yukawa / get_lambda / set_lambda / get_Fk_data (reference) / set_u_current - Plus_U: get_yukawa_lambda / get_ptr_orb Drop the now-redundant member declarations from dftu_lcao.h and switch the sole external caller in setup_dftu_lcao.cpp to the free function. Verification: - dftu + hamilt_lcao + full build all pass (ENABLE_LCAO=ON, ENABLE_MPI=ON) - agent_governance_check.py: no findings - Bit-exact equivalence vs pre-refactor on scf_u_spin2 (non-Yukawa path, dft_plus_u=1 + hubbard_u): E_KohnSham = -11033.1345305277 eV identical pre/post; only timestamp/timing lines differ. - Bit-exact equivalence vs pre-refactor on a Yukawa-enabled case (yukawa_potential=true): iter-1 ETOT/DRHO and the pre-existing NaN in U/J (separate latent bug in the rho->lambda path, not introduced here) are identical pre/post; both binaries crash at iter 2 for the same ScaLAPACK reason. * fix(dftu): clamp negative rho in Yukawa lambda + add scf_u_yukawa test cal_yukawa_lambda forms a Thomas-Fermi-like estimate lambda_ir = 2 * pow(3*rho_ir/PI, 1/6) and integrates sum_rho_lambda / sum_rho. Negative grid-point values of rho appear whenever atomic densities are superposed onto the FFT grid (oscillation near atom boundaries); pow(negative, 1/6) returns NaN in C++, which silently poisons sum_rho_lambda, lambda, U/J, u_current and finally the Hamiltonian (ScaLAPACK info=8 at iter 2). Fix: clamp rho to 0 before the pow (negative rho has no physical meaning here and these near-boundary points contribute negligibly to the integral). Keep a sanity check that fails loud via WARNING_QUIT if sum_rho is still 0 / non-finite (rho not populated, or grid mismatch), reporting sum_rho / sum_rho_lambda / min_rho for diagnosis. Add tests/02_NAO_Gamma/scf_u_yukawa (Fe2O2, gamma-only, nspin=2, dft_plus_u=1 + yukawa_potential=1) and register it in CASES_CPU.txt. Before the fix this case crashed at SCF iter 2 with U/J=-nan; after the fix it converges (#SCF IS CONVERGED#) with finite U/J (Fe U=6.47 eV J=1.03 eV, O U=4.54 eV J=0.93 eV). Verification: - cmake --build build --target dftu hamilt_lcao abacus_basic_para -j4: pass - mpirun -np 4 from tests/02_NAO_Gamma/scf_u_yukawa: SCF converged, FINAL_ETOT=-11032.8053805705148989 eV; result.ref generated by catch_properties.sh from this run. - agent_governance_check.py --staged: 1 warning (docs sync, exception-allowed; yukawa_potential already in parameters.yaml). - Non-Yukawa path unaffected: cal_slater_UJ early-returns when !use_yukawa(), so the clamp is never reached for dft_plus_u runs without yukawa_potential. * refactor(dftu): pass Parallel_Orbitals explicitly to cal_occ_mat instead of storing on Plus_U Remove the Plus_U::paraV member and its get_paraV() accessor; the pointer was set once in init() and read only from DFTU_LCAO::cal_occ_mat, so it behaves as hidden mutable state. Pass pv as an explicit first parameter of the cal_occ_mat template (and its two specializations) instead. At the call site in setup_dftu_lcao.cpp the pointer is sourced from hamilt_lcao_ptr->getHR()->get_paraV(), which is the same Parallel_Orbitals instance used to build the Hamiltonian and density matrix. The init() signature keeps its pv parameter since it is still used for the global row/column dimension checks. Adds a doxygen @PARAM pv note on the cal_occ_mat declaration. Governance warnings (exception allowed): no test path changes (pure refactor, no behavior change; dftu_lcao_test.cpp does not reference Plus_U::get_paraV or cal_occ_mat) and no docs change (no INPUT parameter behavior change). Verified: make -C source/source_lcao/module_dftu -j4 (exit 0), make -C source/source_lcao -j4 (exit 0), make -j4 (exit 0, abacus linked). * refactor(dftu): drop Plus_U::pot_onsite_* wrappers, call DFTU_LCAO free functions directly The free functions DFTU_LCAO::pot_onsite_complex and DFTU_LCAO::pot_onsite_real already live in dftu_lcao_pots.h/.cpp with the full implementation; the two Plus_U member functions of the same name were only thin forwards (*this, *this->ucell, ...). Remove the member wrappers and their declarations, and update the six call sites in dftu_hamilt.cpp (four) and dftu_force.cpp (two) to invoke the DFTU_LCAO free functions directly. Sites that already have ucell in scope (Plus_U::cal_eff_pot_mat_R_* use *this->ucell; force_stress takes ucell as a parameter) pass it through directly. The two DFTU_LCAO::pot_uterm_* free functions only held a Plus_U& reference, so add a Plus_U::get_ucell() const accessor (mirroring the existing get_ptr_orb/get_orb_cutoff read-only accessors) to source the unit cell without cascading a new parameter through pot_uterm_* and its OperatorDFTU callers. Also drop the now-orphaned "In dftu_lcao_pots.cpp" section header that used to label the removed member declarations. Governance warnings (exception allowed): no test path changes (pure refactor, no behavior change; the free functions are unchanged and were already the implementations being called) and no docs change (no INPUT parameter behavior change). Verified: make -C source/source_lcao/module_dftu -j4 (exit 0), make -j4 (exit 0, abacus linked). * refactor(module_dftu): thread ucell explicitly, drop Plus_U::ucell member Remove the Plus_U private member `const UnitCell* ucell` and its `get_ucell()` accessor. The 4 read sites now receive ucell as an explicit parameter: - DFTU_LCAO::pot_uterm_{complex,real}: add `const UnitCell& ucell` param, passed through the legacy OperatorDFTU operator which now holds its own `ucell` pointer set once in the constructor. - Plus_U::cal_eff_pot_mat_R_{double,complex_double}: add `const UnitCell&` param; their only callers (sparse_format::cal_HR_dftu{,_soc}) are updated to thread ucell through. Construction sites updated to pass ucell: - hamilt_lcao.cpp (HamiltLCAO ctor, 2 sites) - write_vxc.hpp (vdftu_op_ao local, 1 site) Also fix a stale doxygen on pot_uterm_* (the Plus_U::pot_onsite_* wrappers were removed in the previous commit; the comment now reads "Calls DFTU_LCAO::pot_onsite_*"). Pure refactor, no behavior change. No INPUT parameter affected. Verification: - make -j4 (full build): 100%, linked abacus_basic_para - python3 tools/03_code_analysis/agent_governance_check.py --staged: no findings - grep: no residual Plus_U::ucell / get_ucell() references Signed-off-by: Abacus Agent <abacus@example.com> * refactor(module_dftu): drop Plus_U npol/nlocal/ks_solver members Remove the Plus_U private members `npol`, `nlocal`, `ks_solver` and their read-only accessors `get_npol()`, `get_nlocal()`, `get_ks_solver()`. All read sites now take these values from sources already in scope: - nlocal: Parallel_Orbitals::get_global_row_size() (matches the GEMM global matrix dimension the member was initialized from in init()) - npol: UnitCell::get_npol(), or the existing npol parameter of DFTU_LCAO::force_stress (which previously shadowed it with dftu) - ks_solver: PARAM.inp.ks_solver (dftu_force.cpp now includes source_io/module_parameter/parameter.h) No function signature changes; the PW path is untouched (Plus_U_Base::init_base uses its local parameter, not these members). Pure refactor, no behavior change. No INPUT parameter affected. Verification: - make -j4 (full build): 100%, linked abacus_basic_para - python3 tools/03_code_analysis/agent_governance_check.py --staged: no findings - grep: no residual Plus_U npol/nlocal/ks_solver member or accessor uses Signed-off-by: Abacus Agent <abacus@example.com> * update test * reduce number of PARAM --------- Signed-off-by: Abacus Agent <abacus@example.com> Co-authored-by: abacus_fixer <mohanchen@pku.eud.cn>
1 parent 196d199 commit 370e024

43 files changed

Lines changed: 1781 additions & 1212 deletions

Some content is hidden

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

AGENTS.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,12 @@ rules. Read the complete governance document before making or reviewing changes:
9494
ask the developer whether to write them in; be cautious and skip unclear
9595
or unverified lessons.
9696

97+
## Refactoring Patterns
98+
99+
- Member -> free function: inventory `this->` reads; pass as params (const
100+
for config, ref for mutable state); move only when body is `this`-free;
101+
keep thin wrapper; compile each step.
102+
97103
## Local Commands
98104

99105
```bash

source/Makefile.Objects

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -818,7 +818,7 @@ OBJS_DFTU=dftu.o\
818818
dftu_yukawa.o\
819819
dftu_folding.o\
820820
dftu_tools.o\
821-
dftu_occup.o\
821+
dftu_lcao_occ.o\
822822
dftu_hamilt.o\
823823
setup_dftu_pw.o
824824

source/source_esolver/esolver_ks_lcao.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -506,7 +506,7 @@ void ESolver_KS_LCAO<TK, TR>::iter_finish(UnitCell& ucell, const int istep, int&
506506
const std::vector<std::vector<TK>>& dm_vec = this->dmat.dm->get_DMK_vector();
507507

508508
// 1) calculate the local occupation number matrix and energy correction in DFT+U
509-
finish_dftu_lcao<TK>(iter, conv_esolver, this->inp_->dft_plus_u, this->inp_->out_chg[0], &(this->dftu), ucell, dm_vec, this->kv, this->p_chgmix->get_mixing_beta(), hamilt_lcao, PARAM.globalv.global_out_dir, this->inp_->nspin, PARAM.globalv.npol);
509+
finish_dftu_lcao<TK>(iter, conv_esolver, this->inp_->dft_plus_u, this->inp_->out_chg[0], &(this->dftu), ucell, dm_vec, this->kv, this->p_chgmix->get_mixing_beta(), hamilt_lcao, PARAM.globalv.global_out_dir, this->inp_->nspin, PARAM.globalv.npol, PARAM.globalv.gamma_only_local);
510510

511511
// mohan add 2025-11: push DFT+U energy from Plus_U instance to ElecState.
512512
// Covers both dft_plus_u==1 (new method, energy accumulated by DFTU::contributeHR

source/source_io/module_hs/write_vxc.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ void write_Vxc(const int nspin,
209209
&vxcs_R_ao[0],ucell,/*for paraV*/ kv, Hexxd, Hexxc, &exx_info, hamilt::Add_Hexx_Type::k);
210210
std::vector<std::vector<double>> e_orb_exx; // orbital energy (EXX)
211211
#endif
212-
hamilt::OperatorDFTU<hamilt::OperatorLCAO<TK, TR>> vdftu_op_ao(&vxc_k_ao, kv.kvec_d, nullptr, nullptr, kv.isk, PARAM.globalv.npol);
212+
hamilt::OperatorDFTU<hamilt::OperatorLCAO<TK, TR>> vdftu_op_ao(&vxc_k_ao, kv.kvec_d, nullptr, ucell, nullptr, kv.isk, PARAM.globalv.npol);
213213

214214
// 4. calculate and write the MO-matrix Exc
215215
Parallel_2D p2d;

source/source_lcao/force_stress_lcao.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,7 @@ void Force_Stress_LCAO<T>::getForceStress(UnitCell& ucell,
457457
std::vector<std::vector<double>>* dmk_d = nullptr;
458458
std::vector<std::vector<std::complex<double>>>* dmk_c = nullptr;
459459
assign_dmk_ptr<T>(dmat.dm, dmk_d, dmk_c, PARAM.globalv.gamma_only_local);
460-
DFTU_LCAO::force_stress(dftu, ucell, gd, dmk_d, dmk_c, pv, fsr_dftu, force_u, stress_u, kv, PARAM.globalv.npol);
460+
DFTU_LCAO::force_stress(dftu, isforce, isstress, ucell, gd, dmk_d, dmk_c, pv, fsr_dftu, force_u, stress_u, kv, PARAM.globalv.npol, PARAM.globalv.gamma_only_local);
461461
}
462462
else
463463
{

source/source_lcao/hamilt_lcao.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -226,10 +226,11 @@ HamiltLCAO<TK, TR>::HamiltLCAO(const UnitCell& ucell,
226226
{
227227
plus_u = new OperatorDFTU<OperatorLCAO<TK, TR>>(this->hsk,
228228
this->kv->kvec_d,
229-
this->hR,
230-
p_dftu,
231-
this->kv->isk,
232-
PARAM.globalv.npol);
229+
this->hR,
230+
ucell,
231+
p_dftu,
232+
this->kv->isk,
233+
PARAM.globalv.npol);
233234
}
234235
else
235236
{
@@ -383,8 +384,9 @@ HamiltLCAO<TK, TR>::HamiltLCAO(const UnitCell& ucell,
383384
{
384385
plus_u = new OperatorDFTU<OperatorLCAO<TK, TR>>(this->hsk,
385386
this->kv->kvec_d,
386-
this->hR,
387-
p_dftu,
387+
this->hR,
388+
ucell,
389+
p_dftu,
388390
this->kv->isk,
389391
PARAM.globalv.npol);
390392
}

source/source_lcao/lcao_set.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,10 +89,7 @@ void LCAO_domain::set_pot(
8989
PARAM.globalv.global_out_dir,
9090
inp.init_chg,
9191
pv.get_global_row_size(),
92-
PARAM.globalv.gamma_only_local,
9392
inp.ks_solver,
94-
inp.cal_force,
95-
inp.cal_stress,
9693
inp.device,
9794
inp.kpar,
9895
PARAM.globalv.hubbard_u,

source/source_lcao/module_dftu/CMakeLists.txt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@ list(APPEND objects
33
dftu_force.cpp
44
dftu_yukawa.cpp
55
dftu_folding.cpp
6-
dftu_tools.cpp
7-
dftu_occup.cpp
6+
dftu_lcao_pots.cpp
7+
dftu_lcao_occ.cpp
8+
dftu_lcao_energy.cpp
89
dftu_hamilt.cpp
910
)
1011

source/source_lcao/module_dftu/dftu_force.cpp

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@
22
#include "dftu_force.h"
33
#include "dftu_folding.h"
44
#include "dftu_lcao.h"
5+
#include "dftu_lcao_pots.h"
56
#include "source_base/global_function.h"
67
#include "source_base/module_external/scalapack_connector.h"
78
#include "source_base/parallel_reduce.h"
9+
#include "source_io/module_parameter/parameter.h"
810
#include "source_base/timer.h"
911

1012
#include <complex>
@@ -14,6 +16,8 @@
1416
namespace DFTU_LCAO {
1517

1618
void force_stress(Plus_U& dftu,
19+
const bool cal_force,
20+
const bool cal_stress,
1721
const UnitCell& ucell,
1822
const Grid_Driver& gd,
1923
std::vector<std::vector<double>>* dmk_d,
@@ -23,7 +27,8 @@ void force_stress(Plus_U& dftu,
2327
ModuleBase::matrix& force_dftu,
2428
ModuleBase::matrix& stress_dftu,
2529
const K_Vectors& kv,
26-
const int npol)
30+
const int npol,
31+
const bool gamma_only_local)
2732
{
2833
ModuleBase::TITLE("DFTU_LCAO", "force_stress");
2934
ModuleBase::timer::start("DFTU_LCAO", "force_stress");
@@ -35,16 +40,16 @@ void force_stress(Plus_U& dftu,
3540
// fsr_dftu is created without allocation), we fail early with a clear
3641
// message instead of letting pdgemm_ dereference nullptr and crash.
3742
// See force_stress_lcao.cpp for the historical background.
38-
if (dftu.is_gamma_only_local())
43+
if (gamma_only_local)
3944
{
40-
if (dftu.is_cal_force()
45+
if (cal_force
4146
&& (fsr.DSloc_x == nullptr || fsr.DSloc_y == nullptr || fsr.DSloc_z == nullptr))
4247
{
4348
ModuleBase::WARNING_QUIT("DFTU_LCAO::force_stress",
4449
"fsr.DSloc_x/y/z are nullptr in gamma_only path; the caller must allocate and fill them. "
4550
"See notes in source/source_lcao/force_stress_lcao.cpp.");
4651
}
47-
if (dftu.is_cal_stress()
52+
if (cal_stress
4853
&& (fsr.DSloc_x == nullptr || fsr.DSloc_y == nullptr || fsr.DSloc_z == nullptr
4954
|| fsr.DH_r == nullptr))
5055
{
@@ -56,14 +61,14 @@ void force_stress(Plus_U& dftu,
5661
}
5762
else
5863
{
59-
if (dftu.is_cal_force()
64+
if (cal_force
6065
&& (fsr.DSloc_Rx == nullptr || fsr.DSloc_Ry == nullptr || fsr.DSloc_Rz == nullptr))
6166
{
6267
ModuleBase::WARNING_QUIT("DFTU_LCAO::force_stress",
6368
"fsr.DSloc_Rx/Ry/Rz are nullptr in multik path; the caller must allocate and fill them. "
6469
"See notes in source/source_lcao/force_stress_lcao.cpp.");
6570
}
66-
if (dftu.is_cal_stress()
71+
if (cal_stress
6772
&& (fsr.DSloc_Rx == nullptr || fsr.DSloc_Ry == nullptr || fsr.DSloc_Rz == nullptr
6873
|| fsr.DH_r == nullptr))
6974
{
@@ -79,26 +84,26 @@ void force_stress(Plus_U& dftu,
7984
// explicit ic * pv.nrow + ir indices. All ks_solvers accepted by INPUT
8085
// validation are column-major today; abort loudly instead of silently
8186
// producing wrong forces/stresses if that assumption ever changes.
82-
if ((dftu.is_cal_force() || dftu.is_cal_stress())
83-
&& !ModuleBase::GlobalFunc::IS_COLUMN_MAJOR_KS_SOLVER(dftu.get_ks_solver()))
87+
if ((cal_force || cal_stress)
88+
&& !ModuleBase::GlobalFunc::IS_COLUMN_MAJOR_KS_SOLVER(PARAM.inp.ks_solver))
8489
{
8590
ModuleBase::WARNING_QUIT("DFTU_LCAO::force_stress",
8691
"non column-major ks_solver is not supported for DFT+U force/stress; "
8792
"the folded matrix layout assumption would be violated");
8893
}
8994

90-
const int nlocal = dftu.get_nlocal();
95+
const int nlocal = pv.get_global_row_size();
9196

92-
if (dftu.is_cal_force())
97+
if (cal_force)
9398
{
9499
force_dftu.zero_out();
95100
}
96-
if (dftu.is_cal_stress())
101+
if (cal_stress)
97102
{
98103
stress_dftu.zero_out();
99104
}
100105

101-
if (dftu.is_gamma_only_local())
106+
if (gamma_only_local)
102107
{
103108
const char transN = 'N';
104109
const char transT = 'T';
@@ -115,7 +120,7 @@ void force_stress(Plus_U& dftu,
115120

116121
double* pot_onsite = new double[pv.nloc];
117122

118-
dftu.pot_onsite_real(spin, false, pot_onsite, npol);
123+
DFTU_LCAO::pot_onsite_real(dftu, ucell, &pv, spin, false, pot_onsite, npol);
119124

120125
#ifdef __MPI
121126
ScalapackConnector::gemm(transT, transN, nlocal, nlocal, nlocal,
@@ -127,18 +132,18 @@ void force_stress(Plus_U& dftu,
127132

128133
delete[] pot_onsite;
129134

130-
if (dftu.is_cal_force())
135+
if (cal_force)
131136
{
132-
cal_force_gamma(dftu.get_nlocal(), dftu.get_npol(),
137+
cal_force_gamma(nlocal, npol,
133138
dftu.get_orbital_corr_vec(), dftu.get_iatlnmipol2iwt(),
134139
ucell, &rho_pot_onsite[0], pv,
135140
fsr.DSloc_x, fsr.DSloc_y, fsr.DSloc_z, force_dftu);
136141
}
137142

138-
if (dftu.is_cal_stress())
143+
if (cal_stress)
139144
{
140-
cal_stress_gamma(dftu.get_nlocal(), dftu.get_npol(),
141-
dftu.get_ks_solver(), dftu.get_orb_cutoff(),
145+
cal_stress_gamma(nlocal, npol,
146+
PARAM.inp.ks_solver, dftu.get_orb_cutoff(),
142147
ucell, pv, &gd,
143148
fsr.DSloc_x, fsr.DSloc_y, fsr.DSloc_z, fsr.DH_r,
144149
&rho_pot_onsite[0], stress_dftu);
@@ -161,7 +166,7 @@ void force_stress(Plus_U& dftu,
161166

162167
std::complex<double>* pot_onsite = new std::complex<double>[pv.nloc];
163168

164-
dftu.pot_onsite_complex(spin, false, pot_onsite, npol);
169+
DFTU_LCAO::pot_onsite_complex(dftu, ucell, &pv, spin, false, pot_onsite, npol);
165170

166171

167172
#ifdef __MPI
@@ -173,28 +178,28 @@ void force_stress(Plus_U& dftu,
173178

174179
delete[] pot_onsite;
175180

176-
if (dftu.is_cal_force())
181+
if (cal_force)
177182
{
178-
cal_force_k(dftu.get_nlocal(), dftu.get_npol(),
179-
dftu.get_ks_solver(), dftu.get_orb_cutoff(),
183+
cal_force_k(nlocal, npol,
184+
PARAM.inp.ks_solver, dftu.get_orb_cutoff(),
180185
dftu.get_orbital_corr_vec(), dftu.get_iatlnmipol2iwt(),
181186
ucell, gd, fsr, pv, ik, &rho_pot_onsite[0], force_dftu, kv.kvec_d[ik]);
182187
}
183-
if (dftu.is_cal_stress())
188+
if (cal_stress)
184189
{
185-
cal_stress_k(dftu.get_nlocal(), dftu.get_npol(),
186-
dftu.get_ks_solver(), dftu.get_orb_cutoff(),
190+
cal_stress_k(nlocal, npol,
191+
PARAM.inp.ks_solver, dftu.get_orb_cutoff(),
187192
ucell, gd, fsr, pv, ik, &rho_pot_onsite[0], stress_dftu, kv.kvec_d[ik]);
188193
}
189194
} // ik
190195
}
191196

192-
if (dftu.is_cal_force())
197+
if (cal_force)
193198
{
194199
Parallel_Reduce::reduce_pool(force_dftu.c, force_dftu.nr * force_dftu.nc);
195200
}
196201

197-
if (dftu.is_cal_stress())
202+
if (cal_stress)
198203
{
199204
Parallel_Reduce::reduce_pool(stress_dftu.c, stress_dftu.nr * stress_dftu.nc);
200205

source/source_lcao/module_dftu/dftu_force.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ namespace DFTU_LCAO {
3030
/// Takes Plus_U& because it calls dftu.pot_onsite_real/complex,
3131
/// which are still members of Plus_U (defined in dftu_tools.cpp).
3232
void force_stress(Plus_U& dftu,
33+
const bool cal_force,
34+
const bool cal_stress,
3335
const UnitCell& ucell,
3436
const Grid_Driver& gd,
3537
std::vector<std::vector<double>>* dmk_d,
@@ -39,7 +41,8 @@ void force_stress(Plus_U& dftu,
3941
ModuleBase::matrix& force_dftu,
4042
ModuleBase::matrix& stress_dftu,
4143
const K_Vectors& kv,
42-
const int npol);
44+
const int npol,
45+
const bool gamma_only_local);
4346

4447
/// @brief Force contribution at a k-point (multik path).
4548
void cal_force_k(int nlocal,

0 commit comments

Comments
 (0)