Skip to content

Commit 5fb17a6

Browse files
mohanchenabacus_fixer
andauthored
Refactor DFT+U, step 4 (deepmodeling#7861)
* refactor(dftu_base): reorganize Plus_U_Base members by access level Group the previously interleaved public/protected sections of Plus_U_Base into a single public block followed by a single protected block. No member is moved between access levels and no signature or implementation is changed; this only consolidates the layout so that follow-up changes to access permissions are easier to review. * refactor(dftu_base): encapsulate Plus_U_Base data members Move all public data members of Plus_U_Base to protected so that external code is forced to go through accessors. This tightens encapsulation of the U values, the DFT+U configuration flags, the occ_mat state flag, and the occupation matrices themselves. New public getters added for the existing external read sites: - get_uramping() replaces dftu.uramping reads in chgmixing.cpp - get_occ_mat_ctrl() replaces dftu.occ_mat_ctrl reads in setup_dftu_pw.cpp and setup_dftu_lcao.cpp - use_yukawa() replaces dftu.use_yukawa reads in dftu_output.cpp The data member use_yukawa is renamed to use_yukawa_ so the getter can keep the natural name; the 9 internal bare-name accesses in dftu_base.cpp / dftu_lcao.cpp / dftu_tools.cpp / dftu_yukawa.cpp are updated accordingly. External write access is limited to the unit-test fixture DFTUTest::SetUp, which writes u_current, orbital_corr and resizes occ_mat directly. Rather than exposing setters for these one-off test scenarios, DFTUTest is declared as a friend of Plus_U_Base. gtest TEST_F derives DFTUTest_xxx_Test whose TestBody does not inherit the friend declaration, so a small const helper occ_mat_c(iat, spin, icc) is added to DFTUTest itself; the three affected EXPECT_NEAR sites in dftu_lcao_test.cpp call it instead of touching dftu.occ_mat directly. Two hamilt::DFTU<OperatorLCAO<TK, TR>> methods (cal_v_of_u in dftu_lcao_op.cpp, cal_force_stress in dftu_fs.cpp) read this->dftu->u_current[T0]; both are switched to the existing get_u_current(T0) accessor. * 重构 dftu_folding.cpp:抽取邻居判断与矩阵索引两个辅助函数 将 fold_dSR_gamma 和 folding_matrix_k 中的重复代码抽取为两个 private 成员函数,消除重复逻辑并统一行为。 新增辅助函数(声明于 dftu_lcao.h,实现于 dftu_folding.cpp): - is_adjacent_pair(): 原子对相邻性判断(直接截断 + 三体重叠桥接) - get_linear_index(): 按 ks_solver 选择行/列主序的本地矩阵索引 主函数精简效果: - fold_dSR_gamma: 113 行 -> 85 行 - folding_matrix_k: 156 行 -> 109 行 - 邻居判断逻辑副本数: 2 -> 1 - 矩阵索引逻辑副本数: 2 -> 1(且修复了 G 版写死列主序的不一致) 顺手清理: - 删除 fold_dSR_gamma 中未使用的 iat0、start0 声明(死代码) - 删除 folding_matrix_k 中冗余的 atom1 重复声明 - 删除两个函数中不再需要的 dtau/dtau1/dtau2/tau0 局部变量 - 统一了 G 版的矩阵索引判断(原本硬编码列主序,现在和 K 版一致) 公共 API 与调用点: - fold_dSR_gamma / folding_matrix_k / folding_matrix_k_new 签名不变 - 调用方 dftu_force.cpp、dftu_occup.cpp 无需修改 验证: - python3 tools/03_code_analysis/agent_governance_check.py --staged 结果: no findings - g++ -std=c++11 -fsyntax-only(针对 dftu_folding.cpp、dftu_lcao.h、 dftu_force.cpp、dftu_occup.cpp)均通过,无错误无警告 - 未做完整 CMake build 与 ctest 运行时测试,因当前环境无 build 目录 (仅有预编译的 abacus_max_para 可执行文件) * refactor(dftu_pw): merge CPU/GPU branches into template, drop unused iter param The CPU and GPU branches of cal_occ_pw (formerly L32-110 and L113-188) were near-verbatim duplicates, differing only in the device template parameter of OnsiteProjector and Psi. Merge them into a single template member function accumulate_occ_one_k<Device>, with explicit instantiation controlling CPU always compiled and GPU only under __CUDA/__ROCM. Also drop the iter parameter from cal_occ_pw signature since it was never used in the function body; update the call site in setup_dftu_pw.cpp accordingly. Files changed: - source/source_pw/module_pwdft/dftu_base.h - drop const int iter param from cal_occ_pw declaration - add template member declaration accumulate_occ_one_k<Device> - source/source_pw/module_pwdft/dftu_pw.cpp - drop iter param from cal_occ_pw implementation - replace ~80 lines of CPU/GPU duplicate code with two template calls - add accumulate_occ_one_k template definition and explicit instantiations at end of file - source/source_pw/module_pwdft/setup_dftu_pw.cpp - drop iter argument at call site Effects: - ~80 lines of duplicate code removed from dftu_pw.cpp - CPU/GPU inner loops (iat/ib/m1/m2 + nspin==4 Pauli block assembly) now maintained in a single template implementation - psi::Psi visibility confirmed transitively via onsite_proj.h Pending verification (build delegated to user): - make module_pwdft incremental build - DFT+U ctest (e.g. MODULE_DFTU label) - GPU build path (__CUDA/__ROCM) explicit instantiation * refactor(dftu_folding): extract Plus_U folding helpers into free functions The five private member functions of Plus_U defined in dftu_folding.cpp (is_adjacent_pair, get_linear_index, fold_dSR_gamma, folding_matrix_k, folding_matrix_k_new) were pure folding helpers that only read data members without relying on class invariants. Extract them into free functions declared in the new dftu_folding.h, removing them from the Plus_U class API in dftu_lcao.h. The free functions live in namespace dftu_folding and take the data they need (orb_cutoff, ks_solver, npol, gamma_only_local, nspin) as direct parameters instead of receiving a Plus_U reference. Since all callers are Plus_U member functions, they read this->member directly and pass the values in, so no getters or friendship are required. The function names drop the dftu_ prefix since the namespace already qualifies them (call sites read dftu_folding::folding_matrix_k(...)). No Plus_U members are deleted: three of the five (npol, gamma_only_local, nspin) are still read by other Plus_U member functions, and the other two (orb_cutoff_, ks_solver) are kept to avoid PARAM coupling or cascading signature changes through the public API. Also rename the include guard of dftu_lcao.h from DFTU_H to DFTU_LCAO_H to match the filename (consistent with the new dftu_folding.h guard DFTU_FOLDING_H); confirmed no other translation unit references DFTU_H. Files changed: - source/source_lao/module_dftu/dftu_folding.h (NEW) - declare 5 free function prototypes under __LCAO, wrapped in namespace dftu_folding - source/source_lao/module_dftu/dftu_folding.cpp - rewrite 5 member functions as free functions in namespace dftu_folding, taking data params - member access (this->orb_cutoff_ etc.) replaced by parameters - internal calls use unqualified names within the namespace - source/source_lao/module_dftu/dftu_lcao.h - remove the 5 private member function declarations - rename include guard DFTU_H -> DFTU_LCAO_H - member variables and public API unchanged - source/source_lao/module_dftu/dftu_force.cpp - include dftu_folding.h; update 3 call sites in cal_force_k / cal_stress_k / cal_stress_gamma to dftu_folding::folding_matrix_k / dftu_folding::fold_dSR_gamma - source/source_lao/module_dftu/dftu_occup.cpp - include dftu_folding.h; update 1 call site in cal_occup_m_k to dftu_folding::folding_matrix_k_new Effects: - Plus_U class fully decoupled from folding details; dftu_lcao.h no longer mentions any folding function - No getters, no friend declarations, no member-variable deletion - TITLE/timer labels ("Plus_U", "fold_dSR_gamma" etc.) intentionally preserved to keep profiling tooling stable Verification (partial, full build delegated to user): - cmake --build build_std_para --target dftu -> [100%] Built target dftu - full abacus build and DFTU ctest pending * refactor(dftu_pw): merge nspin==4 Pauli block 0 and 1-3 VU loops The nspin==4 VU+energy calculation was split into two loops: - block 0 (is=0, charge channel) with diag_coeff on the diagonal - blocks 1-3 (is=1..3, spin channels sigma_x/y/z) with zero diagonal These two loops have identical structure and only differ in the diagonal coefficient. Merge them into a single is=0..3 loop with diag = (is == 0) ? diag_coeff : 0.0 Also add an English comment explaining the Pauli-block layout: VU is stored as 4 contiguous blocks per atom, where is=0 is the charge channel (Hubbard U contributes diag_coeff*delta on the diagonal) and is=1,2,3 are spin channels (sigma_x/y/z, no U diagonal term). The occupation matrix occ_mat[...][0][0].c packs all 4 blocks contiguously. Physics unchanged: - Hubbard U acts only on the charge channel (is=0), so diag_coeff is still applied only there; spin channels remain with zero diagonal. - energy_u accumulation formula is identical for all 4 blocks. Effect: ~25 lines -> ~12 lines (plus comment), removing the artificial block-0 vs block-1-3 symmetry breaking. Verification: - semantic equivalence checked by inspection (start=0 + diag_coeff for is=0 matches the original block-0 loop; start=is*size + 0.0 for is=1..3 matches the original block-1-3 loop) - existing test VUPotNspin4_PauliTransform (dftu_pw_test.cpp) covers the Pauli->spin transform that follows this loop - full build and ctest delegated to user * refactor(dftu_pw): extract compute_eff_pot_and_energy from cal_occ_pw cal_occ_pw was doing three conceptually distinct jobs: (1) accumulate occ_mat from psi, (2) reduce occ_mat across k-pools and sync to uom_array, (3) compute effective potential VU and DFT+U energy. The function name only reflects job (1), and the mixing step plus VU/energy computation were tangled together at the end. Extract job (3) into a protected member function compute_eff_pot_and_energy(cell). This isolates the VU+energy calculation (which reads occ_mat and writes eff_pot_pw / energy_u) from the occupation-matrix accumulation and reduction logic. The new function assumes occ_mat has already been reduced across k-pools (documented in its doxygen comment), matching the current calling order in cal_occ_pw. Also add a doxygen comment block on the new function documenting: - preconditions (occ_mat accumulated and reduced) - outputs (eff_pot_pw layout for nspin=1/2/4, energy_u formula) Files changed: - source/source_pw/module_pwdft/dftu_base.h - add protected member declaration compute_eff_pot_and_energy(cell) - source/source_pw/module_pwdft/dftu_pw.cpp - replace ~95 lines of VU+energy code in cal_occ_pw with a single call - add compute_eff_pot_and_energy definition containing the moved code - add doxygen comment on the new function Effects: - cal_occ_pw body shrinks from ~175 lines to ~80 lines (orchestration) - VU+energy logic is now a self-contained unit that can be tested and evolved independently - no behavior change: same code, same order, just moved Verification: - make module_pwdft incremental build passed (verified by user) - DFT+U ctest not yet run (delegated to user) * refactor(dftu_pw): extract reduce_occ_mat and sync_occ_to_uom from cal_occ_pw cal_occ_pw's middle section (formerly L42-L91) did two distinct jobs in a single per-atom loop: (1) reduce occ_mat across k-pools (MPI AllReduce) (2) copy occ_mat to uom_array for mixing (plain data shuffle) These have different natures (parallel communication vs local copy) and interleaving them in one loop body made both harder to read. Split them into two protected member functions so each is self-contained. The new functions: - reduce_occ_mat(cell): sums per-pool occ_mat contributions across pools. nspin-aware: nspin=1 reduces one channel, nspin=2 reduces two, nspin=4 reduces all 4 Pauli blocks in one shot. - sync_occ_to_uom(cell): flattens occ_mat into uom_array for mixing. nspin=2 uses the split layout [all_up | all_dn]. The uom_array.size()==0 guard is hoisted to an early return at the function entry (equivalent to the previous in-loop check, but clearer). Behavior unchanged: same code, same order (reduce -> sync -> mixing -> compute_eff_pot_and_energy). Note: GlobalV::NPROC_IN_POOL is still referenced inside reduce_occ_mat. Isolating it there is a step toward removing the global dependency, but the actual de-globalization is deferred to a separate governance PR. Files changed: - source/source_pw/module_pwdft/dftu_base.h - add protected declarations for reduce_occ_mat / sync_occ_to_uom - source/source_pw/module_pwdft/dftu_pw.cpp - replace ~50 lines in cal_occ_pw with two calls - add reduce_occ_mat / sync_occ_to_uom definitions (code moved as-is) - add doxygen comments documenting nspin layout per function Effects: - cal_occ_pw body now ~30 lines of pure orchestration - reduce and copy logic each isolated, nspin-aware layout documented - existing test MultiAtomSplitLayout_Nspin2 (dftu_pw_test.cpp) covers the nspin=2 split layout used by sync_occ_to_uom Verification: - make module_pwdft incremental build passed (verified by user) - DFT+U ctest not yet run (delegated to user) * refactor(dftu_pw): add dftu_pw.h with pauli_to_spin_basis free function Step 4a of the dftu_pw decoupling plan. Create a new header dftu_pw.h declaring free functions in namespace dftu_pw, so the DFT+U PW kernels can be unit-tested directly without going through Plus_U_Base. First function: pauli_to_spin_basis(vu, m_size). This performs the Pauli-to-spin-basis transform on VU for nspin==4, previously inlined in compute_eff_pot_and_energy. The function is pure (no access to Plus_U_Base members): it takes a raw std::complex<double>* pointer to the per-atom VU block and m_size. Files changed: - source/source_pw/module_pwdft/dftu_pw.h (new) - declare namespace dftu_pw - declare pauli_to_spin_basis with doxygen comment documenting the 4 Pauli blocks layout and the transform formula - source/source_pw/module_pwdft/dftu_pw.cpp - include dftu_pw.h - replace ~18 lines of inlined Pauli transform in compute_eff_pot_and_energy with a single call dftu_pw::pauli_to_spin_basis(vu_iat, m_size) - add namespace dftu_pw block at end of file with the function definition (code moved as-is from the inlined version) Effects: - compute_eff_pot_and_energy nspin==4 branch shrinks by ~17 lines - pauli_to_spin_basis is now independently testable - no behavior change: same transform, same memory layout Verification: - make module_pwdft incremental build passed (verified by user) - existing test VUPotNspin4_PauliTransform (dftu_pw_test.cpp) covers the transform; step 4d will rewire it to call the real function * refactor(dftu_pw): add compute_vu_spinor and compute_vu_scalar free functions Step 4b of the dftu_pw decoupling plan. Extract the VU+energy per-atom loops from compute_eff_pot_and_energy into two free functions in namespace dftu_pw: - compute_vu_spinor: nspin==4 case, writes 4 Pauli blocks of VU and returns the energy_u increment; internally calls pauli_to_spin_basis to convert VU to spin basis in-place (same order as before). - compute_vu_scalar: nspin==1/2 case, writes one spin channel's VU and returns the energy_u increment. Both functions are pure: they take raw pointers (vu, occ) and scalars (u_value, diag_coeff, weight_eu, m_size), no access to Plus_U_Base members. compute_eff_pot_and_energy now computes per-atom offsets (vu_iat, occ pointer, u_value) and delegates the inner loop. Files changed: - source/source_pw/module_pwdft/dftu_pw.h - declare compute_vu_spinor / compute_vu_scalar with doxygen comments documenting pointer semantics and return value - source/source_pw/module_pwdft/dftu_pw.cpp - replace ~40 lines of inlined VU+energy loops in compute_eff_pot_and_energy with 1 (nspin==4) or 1-2 (nspin==1/2) calls to the free functions; energy_u accumulates the return values - add compute_vu_spinor / compute_vu_scalar definitions in the namespace dftu_pw block (code moved as-is from the inlined version) Effects: - compute_eff_pot_and_energy per-atom body shrinks from ~55 lines to ~20 lines of orchestration - VU+energy kernels now independently testable - no behavior change: same formula, same order (pauli_to_spin_basis still called after the 4 Pauli blocks are filled, inside compute_vu_spinor) Verification: - make module_pwdft incremental build passed (verified by user) - existing tests VUPotNspin1_DiagonalLocale, VUPotNspin2_TwoSpinChannels, VUPotNspin4_PauliTransform (dftu_pw_test.cpp) cover the same formulas; step 4d will rewire them to call the real functions * refactor(dftu_pw): add accumulate_occ_spinor and accumulate_occ_scalar free functions Step 4c of the dftu_pw decoupling plan. Extract the per-atom-per-kpoint occ_mat accumulation loops from accumulate_occ_one_k into two free functions in namespace dftu_pw: - accumulate_occ_spinor: nspin==4 case, accumulates 4 Pauli blocks from becp into occ_mat (npol=2 spinor layout). - accumulate_occ_scalar: nspin==1/2 case, accumulates one spin channel from becp into occ_mat. Both functions are pure: they take raw pointers (occ_mat_out, becp) and scalars describing the per-atom/per-kpoint offsets, no access to Plus_U_Base members. accumulate_occ_one_k now computes these offsets and delegates the inner ib/m1/m2 loop. Files changed: - source/source_pw/module_pwdft/dftu_pw.h - add #include "source_base/matrix.h" (for ModuleBase::matrix wg param) - declare accumulate_occ_spinor / accumulate_occ_scalar with doxygen comments documenting pointer semantics and parameter meanings - source/source_pw/module_pwdft/dftu_pw.cpp - replace ~45 lines of inlined accumulation loops in accumulate_occ_one_k with 1 call per branch (nspin==4 / nspin!=4) - add accumulate_occ_spinor / accumulate_occ_scalar definitions in the namespace dftu_pw block (code moved as-is) - use std::conj explicitly (no 'using namespace std') - drop unused 'is' parameter from accumulate_occ_scalar: the caller selects the spin channel by passing the corresponding occ_mat pointer (occ_mat[...][is].c); the function itself does not need is Effects: - accumulate_occ_one_k per-atom body shrinks from ~50 lines to ~15 lines of orchestration - occ accumulation kernels now independently testable - no behavior change: same becp indices, same Pauli-block packing, same weight handling Verification: - make module_pwdft incremental build passed (verified by user) - existing tests LocaleAccumNspin12, LocaleAccumNspin4_PauliComponents (dftu_pw_test.cpp) cover the same formulas via arithmetic reimplementation; step 4d will rewire them to call the real functions * refactor(dftu_pw): split into dftu_tools_pw.{h,cpp} and dftu_cal_occ_pw.cpp Step 4d-prerequisite of the dftu_pw decoupling plan. Enforce the "header-implementation pairing" rule: the free-function declarations in dftu_pw.h had their implementations stuffed at the bottom of dftu_pw.cpp (alongside Plus_U_Base member functions), which is not a proper .h/.cpp pair. File structure after this commit: - dftu_tools_pw.h (renamed from dftu_pw.h) - declare 5 free functions in namespace dftu_pw - include guard DFTU_TOOLS_PW_H - dftu_tools_pw.cpp (new file) - implement the 5 free functions (pauli_to_spin_basis, compute_vu_spinor, compute_vu_scalar, accumulate_occ_spinor, accumulate_occ_scalar); depends only on <complex> and matrix.h - dftu_cal_occ_pw.cpp (renamed from dftu_pw.cpp via git mv) - Plus_U_Base member functions only (cal_occ_pw, accumulate_occ_one_k, reduce_occ_mat, sync_occ_to_uom, compute_eff_pot_and_energy) - includes dftu_tools_pw.h to call the free functions namespace stays dftu_pw (not renamed) to avoid churning all call sites; only filenames change. Files changed: - source/source_pw/module_pwdft/dftu_tools_pw.h (git mv from dftu_pw.h) - update include guard to DFTU_TOOLS_PW_H - source/source_pw/module_pwdft/dftu_tools_pw.cpp (new) - body moved verbatim from the former dftu_pw.cpp namespace block - source/source_pw/module_pwdft/dftu_cal_occ_pw.cpp (git mv from dftu_pw.cpp) - drop the namespace dftu_pw block (moved to dftu_tools_pw.cpp) - include "source_pw/module_pwdft/dftu_tools_pw.h" instead of dftu_pw.h - source/source_pw/module_pwdft/CMakeLists.txt - replace dftu_pw.cpp with dftu_tools_pw.cpp + dftu_cal_occ_pw.cpp - source/Makefile.Objects - replace dftu_pw.o with dftu_tools_pw.o + dftu_cal_occ_pw.o - source/source_pw/module_pwdft/dftu_base.cpp - update the pointer comment to reflect new filenames Effects: - header/implementation properly paired for the free functions - dftu_tools_pw.cpp has minimal dependencies, can be linked into unit tests without pulling in onsite_proj.h / parallel_reduce.h - main implementation file (dftu_cal_occ_pw.cpp) retains its git history via git mv (rename similarity ~63%, above the 50% threshold) Verification: - make module_pwdft incremental build passed (verified by user) - step 4d proper (rewire tests to call real functions) follows next * test(dftu_pw): rewire 7 dftu_pw_test cases to call real free functions Step 4d of the dftu_pw decoupling plan. The 7 tests in dftu_pw_test.cpp previously used arithmetic re-implementations of the VU/energy/occ formulas, meaning they could not catch bugs in the real dftu_pw implementations (test and production code were two independent copies). Now that the free functions live in dftu_tools_pw.{h,cpp} with minimal dependencies (only <complex> and matrix.h), the tests can link against the real implementations directly. Tests rewired: - VUPotNspin1_DiagonalLocale -> compute_vu_scalar - VUPotNspin2_TwoSpinChannels -> compute_vu_scalar (twice, up/down) - VUPotNspin4_PauliTransform -> pauli_to_spin_basis (in-place) - EnergyNspin12_DiagonalLocale -> compute_vu_scalar (check return value) - EnergyNspin4_WithOffDiagonal -> compute_vu_spinor (check return value) - LocaleAccumNspin12 -> accumulate_occ_scalar - LocaleAccumNspin4_PauliComponents -> accumulate_occ_spinor Tests kept as arithmetic (out of dftu_tools_pw scope): - EnergyWeightsAllNspin, BecpIndexNspin12vs4 (pure constants/arithmetic) - MultiAtomSplitLayout_Nspin2 (Plus_U_Base member layout) - OnsitePsOpKernel_Nspin2_Npol1 (onsite_op.cpp kernel) Files changed: - source/source_lcao/module_dftu/test/dftu_pw_test.cpp - add includes: <vector>, source_base/matrix.h, source_pw/module_pwdft/dftu_tools_pw.h - replace inlined arithmetic loops with calls to the real free functions; expected values unchanged - VUPotNspin4_PauliTransform: m_size 3 -> 1 (the test only fills a single (m1,m2) pair; m_size=1 matches the data layout) - EnergyNspin4_WithOffDiagonal: pass diag_coeff=1.0 (the nspin==4 value used in cal_occ_pw) - source/source_lcao/module_dftu/test/CMakeLists.txt - add ../../../source_pw/module_pwdft/dftu_tools_pw.cpp to dftu_pw_test SOURCES so the real implementations are linked Effects: - tests now exercise the same code path as cal_occ_pw - arithmetic re-implementations removed (~80 lines of duplicated logic) - any future change to the free functions is automatically covered Verification: - make dftu_pw_test build passed (verified by user) - ctest -R dftu_pw_test passed (verified by user) * refactor(dftu_lcao): extract force/stress as free functions, unify DFTU_LCAO namespace Extract the 5 force/stress member functions of Plus_U from dftu_force.cpp into free functions declared in a new dftu_force.h header, mirroring the existing dftu_folding pattern. The top-level force_stress takes a Plus_U& parameter because it still calls Plus_U::cal_VU_pot_mat_real/complex (defined in dftu_tools.cpp); the four inner functions (cal_force_k, cal_stress_k, cal_force_gamma, cal_stress_gamma) are fully decoupled and take their dependencies (npol, nlocal, ks_solver, orb_cutoff, iatlnmipol2iwt, orbital_corr) as explicit parameters, so they are unit-testable without a Plus_U instance. Consolidate the two module-local namespaces dftu_force and dftu_folding into a single namespace DFTU_LCAO. The project-wide hamilt:: namespace (used by dftu_lcao_op.h/cpp, dftu_fs.cpp, dftu_lcao_op_legacy.h/cpp for operator classes inheriting from hamilt::OperatorLCAO<T>) is left untouched to avoid breaking the ABACUS hamilt operator framework. All callers updated: dftu_force:: and dftu_folding:: prefixes are replaced by DFTU_LCAO:: in dftu_force.cpp, dftu_occup.cpp, and force_stress_lcao.cpp; TITLE/timer/WARNING_QUIT identifier strings in dftu_force.cpp are renamed accordingly. Plus_U_Base gains two public read-only accessors (get_iatlnmipol2iwt, get_orbital_corr_vec) so the free functions can receive the lookup table and orbital_corr vector as parameters. Plus_U gains 8 public getters (get_paraV, get_npol, get_nlocal, get_ks_solver, get_orb_cutoff, is_gamma_only_local, is_cal_force, is_cal_stress) and cal_VU_pot_mat_real/complex are promoted from private to public so the free function force_stress can call them via the Plus_U& parameter. get_onebody_eff_pot remains private. Verification performed: - cmake --build build_max_para_test -j 4: clean build, no errors, no warnings - ./build_max_para_test/abacus_max_para --version: ABACUS version v3.11.0-beta8 - OMP_NUM_THREADS=1 ctest --test-dir build_max_para_test -R '^dftu_(pw_test|core_test|operator_test|lcao_test)$': 4/4 pass - python3 tools/03_code_analysis/agent_governance_check.py --staged: only warnings (header deps, test evidence, doc sync), all Exception allowed: yes, no blockers - 17_DS_DFTU: 45/50 sub-cases pass; the 5 PW Double-Spin failures are pre-existing baseline (verified via git stash + rerun with identical deviations), unrelated to this refactor - dft_plus_u==2 + force/stress path remains disabled per the existing comment in force_stress_lcao.cpp:429-454; not end-to-end tested. * refactor(dftu): prune redundant #include in module_dftu Remove unused #include directives across 12 files in source/source_lcao/module_dftu/. Each removal was verified by symbol-usage grep against the file body (excluding the include lines themselves) and by compiling the dftu + hamilt_lcao CMake targets. Removed includes per file: - dftu_lcao.cpp: parameter.h, constants.h, global_function.h, inverse_matrix.h, memory_recorder.h, magnetism.h, charge.h and unused <cstdint>/<cmath>/<cstdio>/<cstring>/<fstream>/<iomanip>/ <iostream>/<sstream>; add focused matrix.h (for ModuleBase::matrix::operator() via occ_mat), tool_quit.h, tool_title.h - dftu_folding.cpp: parameter.h, hcontainer.h, hcontainer_funcs.h - dftu_force.cpp: parameter.h, constants.h, inverse_matrix.h, elecstate_lcao.h, magnetism.h, charge.h, <cmath>, <fstream>, <iomanip>, <iostream>, <sstream>, <stdio.h>, <string.h> - dftu_hamilt.cpp: parameter.h - dftu_lcao_op.cpp: hcontainer_funcs.h, <unordered_set> - dftu_lcao_op_legacy.cpp: dftu_lcao.h (already provided by its own .h) - dftu_occup.cpp: parameter.h - dftu_tools.cpp: timer.h (no direct ModuleBase::timer use), parameter.h - dftu_yukawa.cpp: parameter.h, <complex>, <fstream>, <iomanip>, <iostream>, <sstream>, <cstdio>, <cstring> - dftu_lcao.h: charge_mixing.h (still provided transitively via dftu_base.h), force_stress_arrays.h (not directly used here) - dftu_lcao_op.h: density_matrix.h (not directly used here) - dftu_lcao_op_legacy.h: timer.h (not directly used here) Note: scalapack_connector.h was kept in dftu_force.cpp / dftu_hamilt.cpp / dftu_occup.cpp -- these files call ScalapackConnector::gemm. Verification: OMP_NUM_THREADS=1 make -C build_std_para dftu hamilt_lcao => EXIT=0, no errors, no warnings. Full abacus build deferred to user; external modules that include dftu_lcao.h and use Charge_Mixing (chgmixing.cpp, esolver_ks.cpp/h) should still resolve via dftu_lcao.h -> dftu_base.h -> charge_mixing.h. * refactor(dftu): rename Plus_U members and extract pot_uterm_* to DFTU_LCAO Rename for consistency with the DFTU_LCAO free-function convention established in dftu_force.h, and to disambiguate from the KS effective potential V_eff: * Plus_U::cal_eff_pot_mat_{complex,real} -> DFTU_LCAO::pot_uterm_{complex,real} Extracted from member functions to free functions taking Plus_U&. Internal this->paraV / this->nlocal replaced with dftu.get_paraV() / dftu.get_nlocal(); this->cal_VU_pot_mat_* replaced with dftu.pot_onsite_*. * Plus_U::cal_VU_pot_mat_{complex,real} -> Plus_U::pot_onsite_{complex,real} Member, renamed only. The on-site Hubbard potential V_{mm'}. * Plus_U::cal_occup_m_{k,gamma} -> Plus_U::cal_occ_mat_{k,gamma} Member, renamed only. * dftu_cal_occup_m -> DFTU_LCAO::cal_occ_mat Moved into namespace DFTU_LCAO and renamed. R-space variants Plus_U::cal_eff_pot_mat_R_double and Plus_U::cal_eff_pot_mat_R_complex_double are intentionally left untouched; they bind to the sparse R-space Hamiltonian path in spar_u.cpp (force/stress) and will be addressed in a follow-up. Timer and TITLE strings inside dftu_hamilt.cpp updated to match the new function names for runtime log consistency. No behavior change; pure rename + structural relocation. Test directory source/source_lcao/module_dftu/test/ has no references to any renamed function, so no test update is required. Verification: - rg confirms zero leftover references to the old names across the whole codebase, except the intentionally-preserved R-space variants. - python3 tools/03_code_analysis/agent_governance_check.py --staged passes with only 2 PR-level WARNINGs (test/docs sync reminder), both addressed by this message. * refactor(dftu): split pot_uterm_* / cal_occ_mat declarations into dftu_hamilt.h / dftu_occup.h Previously dftu_lcao.h bundled the DFTU_LCAO namespace free-function declarations together at the bottom of the Plus_U class header. Split them into two focused headers mirroring dftu_force.h convention: * dftu_hamilt.h: DFTU_LCAO::pot_uterm_complex / pot_uterm_real (implemented in dftu_hamilt.cpp) * dftu_occup.h: DFTU_LCAO::cal_occ_mat template (specialized in dftu_lcao.cpp, delegates to Plus_U::cal_occ_mat_{k, gamma} in dftu_occup.cpp) dftu_lcao.h no longer auto-includes the two new headers; each .cpp that actually needs them includes the relevant one explicitly: * dftu_hamilt.cpp -> dftu_hamilt.h (defines pot_uterm_*) * dftu_lcao_op_legacy.cpp -> dftu_hamilt.h (calls pot_uterm_*) * dftu_lcao.cpp -> dftu_occup.h (specializes cal_occ_mat) * setup_dftu_lcao.cpp -> dftu_occup.h (calls cal_occ_mat) Both new headers are self-contained: they forward-declare 'class Plus_U;' instead of including dftu_lcao.h, so there is no include cycle. Plus_U member function declarations (cal_eff_pot_mat_R_*, cal_occ_mat_{k,gamma}, pot_onsite_*, etc.) remain in dftu_lcao.h because C++ does not support partial classes. Verification: - rg confirms the two new headers are only included by the four .cpp files listed above, with no remaining references via dftu_lcao.h. - python3 tools/03_code_analysis/agent_governance_check.py --staged passes with only PR-level WARNINGs (test/docs sync reminder), all addressed by this message. - The 'Confirm the declaration requires this include' reviewer note applies to the four added includes; all four are required because each .cpp either defines or calls the declared function and needs the full signature, not a forward declaration. * refactor(dftu): use DFTU_LCAO as TITLE/timer owner for pot_uterm_* free functions The two pot_uterm_{complex,real} functions were extracted into the DFTU_LCAO namespace in a previous commit, but their ModuleBase::TITLE and timer::start/end calls still used 'Plus_U' as the owner string. This made the runtime log misleading: the entries appeared to come from a Plus_U member function while they are actually DFTU_LCAO namespace free functions. Update the first TITLE/timer argument from 'Plus_U' to 'DFTU_LCAO' for all 6 calls in dftu_hamilt.cpp so the log owner matches the actual namespace hosting the function. Plus_U member functions in dftu_tools.cpp (pot_onsite_*), dftu_occup.cpp (cal_occ_mat_*), and dftu_lcao.cpp keep 'Plus_U' as their TITLE/timer owner, since those are still class members. OperatorDFTU::contributeHk in dftu_lcao_op_legacy.cpp keeps 'OperatorDFTU' as the owner, since it is a hamilt::OperatorDFTU member, not a Plus_U member nor a DFTU_LCAO free function. Verification: - rg confirms 6 TITLE/timer calls in dftu_hamilt.cpp now use 'DFTU_LCAO' as owner. - python3 tools/03_code_analysis/agent_governance_check.py --staged passes with no findings. * refactor(dftu): rename VU/eff_pot variables to pot_onsite/pot_uterm across LCAO and PW bases The codebase mixed variable naming conventions for the same physical quantities: uppercase 'VU' (LCAO base) and lowercase 'vu' (PW base) for the Hubbard on-site potential, 'eff_pot' for the LCAO-basis U-term effective potential, and 'eff_pot_pw' for the PW counterpart. This commit unifies them to 'pot_onsite' and 'pot_uterm[_pw]', matching the function-name conventions introduced earlier. Variable renames: * VU / vu -> pot_onsite (Hubbard on-site potential V_{mm'}) * eff_pot -> pot_uterm (LCAO-basis U-term effective potential) * eff_pot_pw -> pot_uterm_pw (PW-basis U-term effective potential, Plus_U_Base member plus accessor names get_eff_pot_pw_* / get_size_eff_pot_pw_* get_pot_uterm_pw_* / get_size_pot_uterm_pw_*) * eff_pot_pw_index -> pot_uterm_pw_index * VU_tmp / vu_tmp -> pot_onsite_tmp * vu_iat / vu_iat1 -> pot_onsite_iat / pot_onsite_iat1 * vu_ptr / vu_size / vu_host / vu_device -> pot_onsite_* * vu_begin_iat -> pot_onsite_begin_iat * rho_VU -> rho_pot_onsite * dm_VU_dSm -> dm_pot_onsite_dSm Function renames (per user request 'names containing vu should also be renamed'): * transfer_vu -> transfer_pot_onsite * cal_v_of_u -> cal_pot_onsite * compute_vu_spinor -> compute_pot_onsite_spinor * compute_vu_scalar -> compute_pot_onsite_scalar * cal_vu (test helper) -> cal_pot_onsite * local static 'compute_vu' in dftu_core_test -> compute_pot_onsite Test fixture renames: * VUPotentialTest -> PotOnsitePotentialTest * VUPot* test names -> PotOnsitePot* * OffDiagonalVU -> OffDiagonalPotOnsite Scope (38 files): * LCAO base: source/source_lcao/module_dftu/ (dftu_hamilt.{h,cpp}, dftu_tools.cpp, dftu_force.cpp, dftu_fs.cpp, dftu_lcao.{h,cpp}, dftu_lcao_op.{h,cpp}, dftu_lcao_op_legacy.cpp, test/dftu_*_test.cpp) * PW base: source/source_pw/module_pwdft/ (dftu_base.{h,cpp}, dftu_cal_occ_pw.cpp, dftu_tools_pw.{h,cpp}, op_pw_proj.cpp, onsite_proj.cpp, onsite_proj_tools.{h,cpp}, kernels/{onsite,force,stress}_op.{h,cpp}, kernels/cuda/{onsite,force,stress}_op.cu, kernels/rocm/{onsite,force,stress}_op.hip.cu, kernels/test/onsite_op_test.cpp) * Cross-module callers: source/source_estate/module_charge/chgmixing.cpp and charge_mixing.cpp (eff_pot_pw -> pot_uterm_pw), source/source_esolver/esolver_ks_lcao.cpp (comment). Out of scope (intentionally untouched): * Non-DFTU files that happen to contain 'vu' as LAPACK/FORTRAN parameter names (lapack_connector.h, scalapack_connector.h, gather_math_lib_info.cpp, td_current_io_comm.cpp, base/module_container/*, etc.) -- these 'vu' strings are LAPACK interface parameters, not Hubbard potential, and renaming them would be incorrect. * Plus_U_Base member 'uom_array' / 'uom_save' (occupation-related, different physical quantity, not renamed here). Verification: * rg '\bVU\b|\bvu\b|\beff_pot\b|cal_v_of_u|transfer_vu|compute_vu|eff_pot_pw' over source/source_lcao/module_dftu/, source/source_pw/module_pwdft/, chgmixing.cpp, charge_mixing.cpp, esolver_ks_lcao.cpp returns no matches. * python3 tools/03_code_analysis/agent_governance_check.py --staged passes with only PR-level WARNINGs (test/docs sync reminder). Test/Doc plan: * Tests: pure rename, no semantic change; existing tests in source/source_lcao/module_dftu/test/ and source/source_pw/module_pwdft/kernels/test/ updated in lock-step. * Docs: no INPUT parameter or user-facing behavior change; no documentation update required. * fix(dftu): rename remaining vu_device / vu_begin_iat / vu_in members missed in previous commit The previous rename commit (3ac7790) used rg with word-boundary patterns, which missed identifiers like 'vu_device', 'vu_begin_iat', 'vu_begin_iat0', 'vu_begin', 'vu_in' -- because underscore is a word character, so '\bvu\b' does not match 'vu' followed by '_'. Compile failure: op_pw_proj.cpp:47: error: 'class hamilt::OnsiteProj<...>' has no member named 'pot_onsite_device' op_pw_proj.cpp:263: error: ... has no member named 'pot_onsite_device' This was because the member declaration in op_pw_proj.h:75 was still 'vu_device' while op_pw_proj.cpp called this->pot_onsite_device. Files fixed (loose-pattern search 'vu' as substring): * source/source_pw/module_pwdft/op_pw_proj.h: - vu_begin_iat -> pot_onsite_begin_iat (member) - vu_device -> pot_onsite_device (member) * source/source_pw/module_pwdft/op_pw_proj.cpp: - vu_begin_iat, vu_begin_iat0, vu_begin -> pot_onsite_* * source/source_lcao/module_dftu/dftu_fs.cpp: - vu_in -> pot_onsite_in (function parameter, 14 occurrences) Verification: - rg 'vu' (substring, no word boundary) over DFTU scope returns no matches. - python3 tools/03_code_analysis/agent_governance_check.py --staged passes with no findings. * fix(dftu): restore cal_eff_pot_mat_R_{double,complex_double} function names Commit 5ac6ca7 claimed 'R-space versions cal_eff_pot_mat_R_* kept as-is for follow-up' in its message, but actually renamed the function definitions in dftu_hamilt.cpp to cal_pot_uterm_mat_R_*. The member declarations in dftu_lcao.h were not renamed, causing header/implementation mismatch: dftu_hamilt.cpp:127: error: no declaration matches 'void Plus_U::cal_pot_uterm_mat_R_double(int, double*, double*, int)' dftu_hamilt.cpp:157: error: no declaration matches 'void Plus_U::cal_pot_uterm_mat_R_complex_double(...)' Restore the original names cal_eff_pot_mat_R_double and cal_eff_pot_mat_mat_R_complex_double in dftu_hamilt.cpp so they match the declarations in dftu_lcao.h:80,82 and the call sites in spar_u.cpp:76,195. The R-space functions will be renamed in a follow-up commit that also updates spar_u.cpp and the header in lock-step. Verification: - rg 'cal_pot_uterm_mat_R' returns no matches (no stale callers). - rg 'cal_eff_pot_mat_R' shows consistent use across dftu_lcao.h (declarations), dftu_hamilt.cpp (definitions), spar_u.cpp (call sites). * refactor(dftu): rename 'locale' to 'occ_mat' in DFT+U tests and input docs The DFTU tests and input parameter docs used 'locale' as a variable and annotation name for the occupation matrix. This is confusing because 'locale' is also a C++ standard library concept (std::locale, localization). The actual physical quantity is the occupation matrix n_{mm'}, so rename to 'occ_mat' for clarity and consistency with the existing Plus_U_Base member 'occ_mat' and 'get_occ_mat()' accessor. Renames (variable scope limited to tests + comments): * dftu_pw_test.cpp: locale_c / locale_up / locale_dn -> occ_mat_c / occ_mat_up / occ_mat_dn (flattened occupation matrix passed to compute_pot_onsite_scalar); comments updated. * dftu_core_test.cpp: function parameters locale_up / locale_dn -> occ_mat_up / occ_mat_dn (Matrix2D per-atom occupation matrices). * dftu_lcao_op.cpp:192 comment 'Reads locale ...' -> 'Reads occ_mat ...' * input_parameter.h:115 annotation 'mix locale' -> 'mix occ_mat' (parameter name 'mixing_dftu' unchanged, no INPUT behavior change). * read_inp_estruc.cpp:760 annotation 'mix locale' -> 'mix occ_mat' Out of scope (intentionally untouched): * Plus_U_Base::occ_mat member -- already named 'occ_mat', no change. * Non-DFTU 'locale' occurrences (input_parameter.h is touched only for the DFT+U annotation line). Verification: - rg '\blocale\b' over DFTU scope + module_parameter returns no matches. - python3 tools/03_code_analysis/agent_governance_check.py --staged passes with no findings. Test/Doc plan: * Tests: pure rename of test-local variables and comments; no semantic change; existing tests in dftu_pw_test.cpp and dftu_core_test.cpp updated in lock-step. * Docs: no INPUT parameter name change (still 'mixing_dftu'); only the annotation string is reworded for clarity. parameters.yaml and input-main.md do not mention 'locale' so no update required there. * refactor(dftu): remove redundant includes in module_pwdft dftu files - dftu_base.h: drop klist.h (UnitCell from unitcell.h, matrix via charge_mixing.h) - dftu_base.cpp: drop <cmath>/<complex>/<iomanip> (no usage) - dftu_output.cpp: drop <cstring>/<sstream> (no usage); replace parameter.h with global_variable.h (GlobalV source, PARAM unused) - dftu_cal_occ_pw.cpp: replace parameter.h with global_variable.h (GlobalV source, PARAM unused) * fix(dftu): guard force/stress against non column-major ks_solver The folded dSR/mat buffers are consumed by ScaLAPACK GEMM via pv.desc (local column-major storage) and read back with explicit ic * pv.nrow + ir indices, so their layout must not follow a row-major ks_solver branch. All LCAO ks_solvers accepted by INPUT validation satisfy IS_COLUMN_MAJOR_KS_SOLVER today, so this entry guard is defensive: it fails loudly instead of silently producing wrong DFT+U forces/stresses if solver whitelists ever drift. Notes on governance warnings: - Tests not added: the guarded behavior is a fail-fast precondition on a path whose numerical results are unchanged for every reachable configuration; dft_plus_u==2 force/stress is additionally disabled in force_stress_lcao.cpp. A focused unit test can be added together with the planned follow-up that fixes folding layout at construction time. - No docs update required: no INPUT parameter semantics change. --------- Co-authored-by: abacus_fixer <mohanchen@pku.eud.cn>
1 parent 8d8884b commit 5fb17a6

57 files changed

Lines changed: 2046 additions & 1720 deletions

Some content is hidden

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

source/Makefile.Objects

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -742,7 +742,8 @@ OBJS_SRCPW=h_ewald_pw.o\
742742
update_cell_pw.o\
743743
dftu_base.o\
744744
dftu_output.o\
745-
dftu_pw.o\
745+
dftu_tools_pw.o\
746+
dftu_cal_occ_pw.o\
746747
setup_dftu_pw.o\
747748
deltaspin_pw.o\
748749
force_pw.o\

source/source_esolver/esolver_ks_lcao.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -510,7 +510,7 @@ void ESolver_KS_LCAO<TK, TR>::iter_finish(UnitCell& ucell, const int istep, int&
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
513-
// via cal_v_of_u) and dft_plus_u==2 (old method, energy from cal_energy_correction).
513+
// via cal_pot_onsite) and dft_plus_u==2 (old method, energy from cal_energy_correction).
514514
if (this->inp_->dft_plus_u)
515515
{
516516
this->pelec->set_dftu_energy(this->dftu.get_energy());

source/source_estate/module_charge/charge_mixing.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ void Charge_Mixing::allocate_mixing_uom(int uom_size)
264264
ModuleBase::TITLE("Charge_Mixing", "allocate_mixing_uom");
265265
ModuleBase::timer::start("Charge_Mixing", "allocate_mixing_uom");
266266
// For nspin=2, uom_size already includes both spin channels
267-
// (eff_pot_pw.size() = pot_index * 2 for nspin=2)
267+
// (pot_uterm_pw.size() = pot_index * 2 for nspin=2)
268268
// So uom_fold should always be 1
269269
this->mixing->init_mixing_data(this->uom_mdata, uom_size, sizeof(double));
270270
this->uom_mdata.reset();

source/source_estate/module_charge/chgmixing.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ void module_charge::chgmixing_ks_pw(const int iter, // scf iteration number
133133
// enable mixing_dftu for DFT+U occupation mixing
134134
dftu.enable_mixing();
135135
// allocate memory for uom_mdata
136-
p_chgmix->allocate_mixing_uom(dftu.get_size_eff_pot_pw());
136+
p_chgmix->allocate_mixing_uom(dftu.get_size_pot_uterm_pw());
137137
}
138138
}
139139

@@ -145,11 +145,11 @@ void module_charge::chgmixing_ks_pw(const int iter, // scf iteration number
145145

146146
if (inp.dft_plus_u)
147147
{
148-
if (dftu.uramping > 0.01 && !dftu.u_converged())
148+
if (dftu.get_uramping() > 0.01 && !dftu.u_converged())
149149
{
150150
p_chgmix->mixing_restart_step = inp.scf_nmax + 1;
151151
}
152-
if (dftu.uramping > 0.01)
152+
if (dftu.get_uramping() > 0.01)
153153
{
154154
bool do_uramping = true;
155155
if (inp.sc_mag_switch)
@@ -197,7 +197,7 @@ void module_charge::chgmixing_ks_lcao(const int iter, // scf iteration number
197197
dftu.enable_mixing();
198198
}
199199
// this output will be removed once the feeature is stable
200-
if (dftu.uramping > 0.01)
200+
if (dftu.get_uramping() > 0.01)
201201
{
202202
std::cout << " U-Ramping! Current U = ";
203203
for (int i = 0; i < dftu.get_num_u_types(); i++)
@@ -216,7 +216,7 @@ void module_charge::chgmixing_ks_lcao(const int iter, // scf iteration number
216216
if (inp.dft_plus_u)
217217
{
218218
dftu.uramping_update(); // update U by uramping if uramping > 0.01
219-
if (dftu.uramping > 0.01)
219+
if (dftu.get_uramping() > 0.01)
220220
{
221221
std::cout << " U-Ramping! Current U = ";
222222
for (int i = 0; i < dftu.get_num_u_types(); i++)
@@ -225,7 +225,7 @@ void module_charge::chgmixing_ks_lcao(const int iter, // scf iteration number
225225
}
226226
std::cout << " eV " << std::endl;
227227
}
228-
if (dftu.uramping > 0.01 && !dftu.u_converged())
228+
if (dftu.get_uramping() > 0.01 && !dftu.u_converged())
229229
{
230230
p_chgmix->mixing_restart_step = inp.scf_nmax + 1;
231231
}

source/source_io/module_parameter/input_parameter.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ struct Input_para
112112
double mixing_gg0_min = 0.1;
113113
double mixing_angle = -10.0;
114114
bool mixing_tau = false; ///< whether to mix tau in mgga
115-
bool mixing_dftu = false; ///< whether to mix locale in DFT+U
115+
bool mixing_dftu = false; ///< whether to mix occ_mat in DFT+U
116116
bool mixing_dmr = false; ///< whether to mix real space density matrix
117117

118118
bool gamma_only = false; ///< for plane wave.

source/source_io/module_parameter/read_inp_estruc.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -757,7 +757,7 @@ This setting takes effect only when the selected exchange-correlation functional
757757
}
758758
{
759759
Input_Item item("mixing_dftu");
760-
item.annotation = "whether to mix locale in DFT+U calculation";
760+
item.annotation = "whether to mix occ_mat in DFT+U calculation";
761761
item.category = "Electronic structure";
762762
item.type = "Boolean";
763763
item.description = R"(Whether to mix the occupation matrices.

source/source_lcao/force_stress_lcao.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include "source_base/parallel_reduce.h"
44
#include "source_lcao/module_dftu/dftu_lcao.h" //Quxin add for DFT+U on 20201029
5+
#include "source_lcao/module_dftu/dftu_force.h"
56
#include "source_io/module_output/output_log.h"
67
#include "source_io/module_parameter/parameter.h"
78
// new
@@ -456,7 +457,7 @@ void Force_Stress_LCAO<T>::getForceStress(UnitCell& ucell,
456457
std::vector<std::vector<double>>* dmk_d = nullptr;
457458
std::vector<std::vector<std::complex<double>>>* dmk_c = nullptr;
458459
assign_dmk_ptr<T>(dmat.dm, dmk_d, dmk_c, PARAM.globalv.gamma_only_local);
459-
dftu.force_stress(ucell, gd, dmk_d, dmk_c, pv, fsr_dftu, force_u, stress_u, kv, PARAM.globalv.npol);
460+
DFTU_LCAO::force_stress(dftu, ucell, gd, dmk_d, dmk_c, pv, fsr_dftu, force_u, stress_u, kv, PARAM.globalv.npol);
460461
}
461462
else
462463
{

0 commit comments

Comments
 (0)