Skip to content

Refactor density matrix module. - #8000

Open
mohanchen wants to merge 137 commits into
deepmodeling:developfrom
mohanchen:2026-09-20
Open

mohanchen wants to merge 137 commits into
deepmodeling:developfrom
mohanchen:2026-09-20

Conversation

@mohanchen

Copy link
Copy Markdown
Collaborator

Refactor density matrix module.

abacus_fixer and others added 30 commits September 16, 2026 09:02
…ol flow

Mechanical cleanup as the first step of the module_charge governance
refactor: convert leading tabs to 4-space indentation (1011 occurrences
across 11 files) and add braces around all single-statement if/for/while
bodies (11 sites). No functional change.
Introduce a MixingConfig POD that bundles the INPUT mixing parameters
with the runtime globals (nspin, scf_thr_type, double_grid), and change
set_mixing from a 12-argument interface to set_mixing(const MixingConfig&,
double&, double&). Charge_Mixing now stores the config and reads nspin /
scf_thr_type / double_grid from it instead of PARAM.inp / PARAM.globalv,
removing the direct PARAM reads in set_mixing and init_mixing.

The single production call site (esolver_ks.cpp) fills the config, and
the unit test drives set_mixing via a make_cfg() helper. The
'#define private public' access hack is kept for now with a TODO: the
test still must write Parameter::input/sys, Charge::_space_* and
XC_Functional privates, which need the Step 4/5 global-state
parameterization before it can be removed.

Verified: make -j30 MODULE_ESTATE_charge_mixing (build_max_para_test)
passes with no errors.
…th std::vector

Extract the repeated two-beta mixing functor in mix_rho_recip/mix_rho_real
into a make_twobeta_mix<T> template helper (6 lambda copies removed), and
convert all local raw new[]/delete[] buffers in charge_mixing_rho.cpp to
zero-initialized std::vector, dropping the paired ZEROS calls.
Extend MixingConfig with gamma_only_pw/domag/domag_z so mix_resid.cpp
(get_drho, get_dkin, inner_product_recip_{rho,simple,hartree,real}) no
longer reads PARAM/GlobalV; all branches now consume this->cfg_.
inner_product_recip_rho's raw pointer-array views are switched to
std::vector. Production fills the three new fields in esolver_ks, and
the test fixture gains a sync_cfg() helper to push PARAM mutations into
cfg_ for the inner-product branch tests.
Replace the six private raw _space_rho/_space_rho_save/_space_rhog/
_space_rhog_save/_space_kin_r/_space_kin_r_save buffers with
std::vector, so Charge's underlying contiguous storage self-manages and
the matching delete[] calls in destroy() (which relied on reading
possibly-uninitialized pointers) go away. The public rho/rhog/rho_save/
rhog_save/kin_r/kin_r_save views keep their double**/complex** shape and
still alias the vector memory via .data(), so all external consumers are
unaffected. Tests that drove _space_* directly are adapted to
resize()/.data() and drop their manual delete[] of the buffers.
chgmixing_ks already takes a const Input_para& inp but still read
PARAM.inp.mixing_restart / PARAM.inp.scf_nmax from the global. Use the
inp argument instead so the function no longer reads INPUT state through
the global for these two fields. PARAM.globalv.ks_run is a runtime
per-process flag (set from band-parallel topology), not an input, so it
is intentionally left as-is rather than threading it through the
interface.
init_rho had a cyclomatic complexity of 36 from five sequential stages
(file read, atomic fallback, Thomas-Fermi tau, restart load, wfc read)
interleaved through shared read_error/read_kin_error flags. Extract the
four branches into private methods -- read_rho_from_file,
init_rho_atomic_and_tau, load_rho_from_restart, init_rho_from_wfc -- and
leave init_rho as a thin sequence of stage calls. Logic is unchanged; the
error flags are threaded through as parameters. The deepest stage
(read_rho_from_file) now sits at complexity 19, down from 36 for the
monolith. The remaining global reads inside the stages are untouched and
deferred to a later parameterization step.
…tions

sum_rho, cal_rho2ne and non_linear_core_correction each used Charge
members only to reach a handful of scalars (nrxx/nxyz/omega) or the
reciprocal-shell table (gg_uniq/ngg); the rest of each body is pure
numerics. Move the three bodies into a new charge_math namespace as free
functions with those values passed explicitly, and leave the Charge
members as thin forwarding wrappers so no caller outside the module
changes. The kernels are now unit-testable in isolation and no longer
coupled to Charge state. One behavior note: the pre-quit debug line that
printed sum_rho to ofs_warning is dropped so the free function stays free
of global-stream dependencies. charge_math.cpp is wired into the estate
library and the charge_test target.
The CMake build already picks up charge_math.cpp; mirror that in
Makefile.Objects so the legacy Makefile flow links the new charge_math
kernels too. The module_charge directory is already on VPATH, so adding
charge_math.o to the object list is sufficient.
…ction

Remove Charge::atomic_rho entirely and replace all call sites with
module_charge::atomic_rho(..., rhopw), eliminating the need for a thin
wrapper on the Charge class. This decouples atomic density initialization
from Charge's state and improves charge.cpp quality score from 2 to 44.
scf_out_chg_tau aborted in Parallel_Grid::reduce on
assert(rhoin != nullptr) because the kin_r_save[is] handed to
write_vdata_palgrid was not a valid buffer. After the _space_* storage
became std::vector (ecf5084), a copied/moved Charge leaves its
rho/kin_r views dangling into another object's vector buffer, and a
kin_r_save never allocated (ked_flag set after allocate) stays nullptr;
both surface as a null rhoin deep inside MPI gather instead of at the
source.

Delete Charge's copy constructor/assignment so any value copy of the
vector-aliasing views fails at compile time, and check kin_r_save in
ctrl_output_fp before writing tau.cube so a missing allocation reports
a clear message instead of tripping the MPI assert.

Verification: not run locally (per user request, user compiles).
scf_out_chg_tau (LCAO, SCAN, out_chg=1, 4 MPI ranks) aborted in
Parallel_Grid::reduce on assert(rhoin != nullptr). Bisecting between
83eb5d0 (good) and ecf5084 (bad) isolated the regression to
ecf5084, which moved Charge's _space_* storage from raw new[] to
std::vector.

Root cause: with 4 ranks the FFT grid is slab-decomposed so that the
last rank owns zero real-space points (nrxx == 0, confirmed via a
temporary diagnostic printing fn/is/rank/nrxx at the reduce call site).
Before ecf5084, _space_rho = new double[nspin * 0] == new double[0]
returned a unique non-null pointer, so rho_save[is] was non-null and the
assert passed. After the change, an empty vector's .data() returns
nullptr, so the rank with nrxx == 0 handed a null rhoin to reduce and
tripped the assert (Debug) or fed MPI_Gatherv a null buffer (Release).

A rank with nrxx == 0 is legitimate: MPI_Gatherv is invoked with
sendcount 0 and ignores the send buffer. Relax the assert to only flag a
null buffer when nrxx != 0, and revert the now-unneeded kin_r_save guard
in ctrl_output_fp (it would have falsely aborted on the nrxx == 0 rank).

Verification: Release build (build_max_para_test), ran
  cd tests/03_NAO_multik/scf_out_chg_tau &&
  OMP_NUM_THREADS=1 mpirun -np 4 ../../../build_max_para_test/abacus_max_para
Result: exit 0, chg.cube and tau.cube written; numerical comparison
against chg.cube.ref/tau.cube.ref gives maxdiff 0 (chg) and 1e-14 (tau).
…ction

Move set_rho_core to charge_math::set_rho_core with rho_core,
rhog_core and rhopw passed explicitly instead of reading Charge
state, and call charge_math::non_linear_core_correction directly.
Remove the now-unused Charge::non_linear_core_correction wrapper,
use std::vector for the rhocg/vg scratch buffers, update the
init_scf call site, and drop the obsolete member stubs in the
elecstate unit tests.
Replace the raw new[]/delete[] displacement arrays (dis_old1, dis_old2,
dis_now) with std::vector and remove the hand-written destructor. This
fixes a read of uninitialized pot_order when an object is destroyed
before Init_CE, a memory leak when Init_CE is called repeatedly, and a
double-free risk from the implicitly generated shallow copy. The copy
constructor and copy assignment are deleted so the molecular-dynamics
trajectory history cannot be silently forked. The unit test now checks
vector sizes instead of non-null pointers.
- Rename module_charge/charge_math.{h,cpp} to chg_tools.{h,cpp} via git mv
- Change namespace charge_math to module_charge to match charge_atomic
  and chgmixing in the same directory
- Update include guard CHG_TOOLS_H and TITLE/timer labels accordingly
- Update call sites in init_scf.cpp, charge.cpp, charge_init.cpp
- Update build references in Makefile.Objects and both CMakeLists.txt
Convert the stateless class Symmetry_rho into namespace module_charge
free functions and rename files for consistency:
  symm_rho.{h,cpp}      -> chg_symm.{h,cpp}
  symm_rho_detail.h     -> chg_symm_detail.h
  symm_rhog.cpp         -> chg_symm_detail.cpp

- 5 public functions become module_charge::symmetrize_rho / cal_rhog_symm
  (2 overloads) / cal_rhog_symm_soc (2 overloads)
- 2 cross-TU helpers (psymmg/psymmg_soc) moved to module_charge::detail
  via chg_symm_detail.h
- 3 internal MPI helpers moved to anonymous namespace
- Delete dead code psymm (real-space symmetrization, never called)
- Remove empty ctor/dtor and parallel_grid.h include
- Rename begin/begin_soc to cal_rhog_symm/cal_rhog_symm_soc for clarity
- Update timer/TITLE labels from "Symmetry_rho" to "module_charge"
- Migrate all 14 call sites and 1 test stub
- Remove obsolete Makefile special rule (no more name collision)
…uct_recip_simple

Move MixingConfig from charge_mixing.h into its own mixing_config.h so
stateless residual kernels can include the config without dragging in
Charge_Mixing. Remove inner_product_recip_simple, which had no production
call sites, together with its unit test.
Relocate gint_prec_ctrl.{h,cpp} and its test into module_gint, update the
include in esolver_ks_lcao.h and rewire the CMake/Makefile object lists.
…ions

Rename mix_resid.cpp to chg_drho.cpp and turn inner_product_real and
inner_product_recip_hartree into module_charge free functions declared
in chg_drho.h; inner_product_recip_rho, which is only shared with the
unit test, moves to module_charge::detail in chg_drho_detail.h.
Charge_Mixing loses the three private inner-product members and
mix_rho_recip/mix_rho_real bind the free functions through lambdas.
get_drho/get_dkin stay as members for this step.
Move the get_drho/get_dkin implementations into file-local cal_drho/
cal_dkin free functions with all inputs explicit; the public
Charge_Mixing methods become thin forwarding wrappers so esolver call
sites stay unchanged.
…nctions

Move Charge_Mixing::Kerker_screen_recip/real to module_charge namespace
as free functions in chg_precond.{h,cpp}, renaming mix_precond.cpp via
git mv. Config/grid/geometry are passed explicitly via MixingConfig,
PW_Basis*, and tpiba, eliminating the function's direct read of
PARAM.inp.nspin. Replace 8 std::bind call sites in charge_mixing_rho.cpp
with lambdas, update 2 commented-out bind sites in charge_mixing_dmr.cpp,
and rewrite 12 test call sites in charge_mixing_test.cpp to construct an
independent MixingConfig instead of poking at Charge_Mixing privates.
Drop the now-unused member function declarations from charge_mixing.h.
…rename

Update the non-CMake object list to track the renamed translation unit so
make-based builds do not reference the deleted mix_precond.o.
Expose cal_drho/cal_dkin as module_charge free functions in chg_drho.h
and let ESolver_KS call them directly with explicit arguments; add
Charge_Mixing::get_mixing_config() as a const observer for the config.
Align with the chg_<feature> naming pattern used in the same directory
(chg_drho, chg_precond, chg_symm, chg_tools). Update include guard to
CHG_ROUTINE_H, the self-include in chg_routine.cpp, the entry in
source_estate/CMakeLists.txt and source/Makefile.Objects, and the three
#include sites in esolver_ks{,_pw,_lcao}.cpp. Function names
(chgmixing_ks{,_pw,_lcao}) and TITLE/timer tags are intentionally left
unchanged to keep the diff minimal.
Rename the MixingConfig header to align with the chg_* naming
convention in module_charge. Update the include guard and the four
in-tree includers; no CMake change is needed since the header is not
listed explicitly.
…tions

Rename charge_mpi.cpp to chg_parallel.cpp and add chg_parallel.h, moving
the three stateless Charge member functions (reduce_diff_pools, rho_mpi,
kin_r_mpi) to module_charge namespace free functions that take the
Charge object explicitly. Remove their declarations from charge.h and
update all call sites in elecstate_pw, stress_mgga, read_wf2rho_pw and
sto_iter. Rename the unit test to test_chg_parallel.cpp and update the
test target name accordingly.

GlobalV/PARAM reads and the direct MPI_Allreduce in reduce_diff_pools
are preserved as pre-existing technical debt (migration-neutral).
- Rename module_charge/charge_atomic.{h,cpp} to chg_atomic.{h,cpp}
- Update include guard to CHG_ATOMIC_H
- Update includes in charge_init.cpp and charge_extra.cpp
- Update source paths in CMakeLists.txt, test CMakeLists.txt
- Fix stale object names in Makefile.Objects: replace
  symm_rho_charge.o/symm_rhog.o with chg_symm.o/chg_symm_detail.o
…e functions

Introduce module_charge::split_dgrid / merge_dgrid in chg_uspp.{h,cpp} as
RAII, parameter-explicit replacements for Charge_Mixing::divide_data /
combine_data / clean_data, which paired raw new[] with manual delete[]
across ~160 lines of mixing code.

- chg_uspp.{h,cpp}: stateless free functions in module_charge namespace;
  outputs are caller-pre-sized std::vector, no new/delete; parameter
  validation via WARNING_QUIT; TITLE/timer tags preserved
- charge_mixing_rho.cpp: rho and tau double-grid paths switched to the new
  functions; raw pointer aliases kept for !double_grid so the existing
  mixing call sites (nspin==1/2/4) are untouched
- CMakeLists.txt (source + test): wire chg_uspp.cpp

The legacy divide_data/combine_data/clean_data members are not yet removed;
that follows in a later step after the test is updated.
abacus_fixer added 25 commits September 20, 2026 17:02
init_mixing() branched on this->mixing_mode and passed
this->mixing_ndim/mixing_beta to the Broyden/Pulay/Plain_Mixing
constructors. These legacy mirrors were kept in sync with cfg_
manually by set_mixing(). Route through cfg_ directly so cfg_
remains the single source of INPUT parameters. The Mixing objects
themselves still copy beta/ndim into their own members at
construction; that is a one-time snapshot and not a continuous
sync surface, so it is left untouched.
Both mix_rho_recip and mix_rho_real built the twobeta_mix functor by
reading this->mixing_beta / this->mixing_beta_mag, which are legacy
mirrors that set_mixing() kept in sync with cfg_. Route the six
construction sites through cfg_.mixing_beta / cfg_.mixing_beta_mag
so cfg_ is the single source of INPUT parameters consumed by the
mixing logic. Behavior is unchanged since the mirrors and cfg_
hold identical values after set_mixing().
set_mixing() copied mixing_mode, mixing_beta, mixing_beta_mag,
mixing_ndim from cfg into legacy mirror members, then validation
and logging read from the mirrors. Now that all internal readers
(init_mixing, mix_rho_recip, mix_rho_real, getters) read from
cfg_, the mirror writes are dead work. Drop them and route
validation and log output through cfg_ directly. omega and tpiba
remain pointer members because they alias external runtime state
(cell volume, lattice constant) that changes across SCF iterations
and so do not belong in MixingConfig (an immutable INPUT snapshot).
…urce

Drop mixing_mode, mixing_beta, mixing_beta_mag, mixing_ndim mirror
members. After the previous commits every internal reader (getters,
init_mixing, mix_rho_recip, mix_rho_real, set_mixing validation
and log output) routes through cfg_, so the mirrors are dead state
that set_mixing() no longer writes. cfg_ is now the single source
of truth for INPUT mixing parameters.

Update test_chg_mix.cpp accordingly: the two assertions that
reached directly into CMtest.mixing_beta_mag and CMtest.mixing_mode
now read CMtest.get_mixing_config().mixing_beta_mag and
CMtest.get_mixing_mode(), matching the public API used by the
other assertions in the same block. No production caller accessed
these members directly (esolver_ks_lcao, lcao_others, pw_others
all used the getters), so the change is test-only on the consumer
side.
The non-static data member initializers in MixingConfig provided
plausible-looking defaults (e.g. mixing_beta=0.8, mixing_mode=
"broyden") that silently masked forgotten fields when a new field
was added but not wired up at construction sites. With the
defaults removed, every construction site must use aggregate
initialization (or copy-assign from a fully-initialized instance),
and a missing field yields value-initialized (zero/empty) members
that are far more likely to trip a test than the old defaults.
Combined with -Wmissing-field-initializers promoted to error in
the next commits, adding a field to MixingConfig without updating
all aggregate-initialization sites becomes a compile error.
Convert the 17-line field-by-field assignment of mix_cfg into a
single aggregate initialization in declaration order. Wrap it in
#pragma GCC diagnostic error "-Wmissing-field-initializers" so
that adding a field to MixingConfig without updating this list
becomes a compile error rather than silently using a default.
Each initializer is annotated with the field name it corresponds
to, making the declaration-order dependency auditable at a glance.
Convert make_cfg()'s 17-line field-by-field assignment into a
single aggregate initialization in declaration order, matching
the esolver-side change. Wrap in the same
#pragma GCC diagnostic error "-Wmissing-field-initializers" so
that adding a field to MixingConfig without updating the test
helper is also a compile error. Both construction sites (esolver
and test) now fail at compile time if a field is missing, closing
the maintenance gap where a new field could silently fall back to
a default value.
Add validation to turn latent misuse (skipped set_rhopw/set_mixing)
into clear WARNING_QUIT errors instead of null dereference or heap
corruption:
- init_mixing rejects a null rhopw
- if_scf_oscillate checks scf_nmax > 0 and iteration range
- mix_rho validates chr/chr->rhopw and the grid pointers

Fix three chg_mix unit tests that read cfg_ before set_mixing, which
caused a SIGSEGV in SCFOscillationTest and assertion failures in the
two inner-product tests.
Add test_chg_uspp.cpp covering split_dgrid/merge_dgrid (normal split,
round-trip, nspin=1/2, empty high-frequency/smooth boundaries, and
input-validation abort paths).

Add test_chg_dmr.cpp covering init_mixing_dmr/mix_dmr (nspin=1/2/4
mixing with Plain_Mixing analytically verified, empty-partition null
buffer allowance, and input-validation abort paths).

Wire both targets into unittests/CMakeLists.txt.
…ho_inner, chg_mix_rho

- test_chg_precond.cpp: kerker_screen_recip/real (early return, nspin=1/2/4
  filter, nspin=4 with mixing_angle resize, real-space matches reciprocal).
- test_chg_drho.cpp: inner_product_real, cal_drho real-space path
  (nspin=1/2/4+domag_z), cal_dkin (meta_gga false/true).
- test_chg_drho_inner.cpp: inner_product_recip_rho and
  inner_product_recip_hartree for nspin=1 with a single G component,
  analytically verified against the Coulomb metric.
- test_chg_mix_rho.cpp: mix_rho abort paths (null chr/chr->rhopw, unset
  rhopw, double_grid without rhodpw) and real-space plain mixing value.

Wire all four targets into unittests/CMakeLists.txt.
…g_atomic, chg_atomic_inner

- test_chg_symm.cpp: symmetrize_rho / cal_rhog_symm / cal_rhog_symm_soc
  no-op paths when symm_flag == 0, for nspin=1 and nspin=4.
- test_chg_symm_detail.cpp: psymmg and psymmg_soc idempotence on a
  manually built D_4 point group over a serial cubic PW_Basis.
- test_chg_atomic_inner.cpp: compute_rhoatm USPP direct-copy branch and
  NCPP integrate+scale-to-zv branch (Gaussian rho_at with known analytic
  integral); normalize_and_check renormalizes uniform density to nelec.
- test_chg_atomic.cpp: atomic_rho ntype==0 path (skips atom loop) and
  spin_number_need==3 abort path.

Wire all four targets into unittests/CMakeLists.txt.
…rious XC_Functional stubs

Fourth batch of module_charge unit tests:
- test_chg_tau.cpp: mix_tau_recip abort paths (null chr/grid/mixing, nspin<1,
  double_grid without high-f mixer) and non-double-grid plain mixing value.
- test_chg_routine.cpp: chgmixing_ks_pw/lcao iter==1 restart-step setup, and
  chgmixing_ks convergence branches (conv_esolver true / drho<hsolver_error
  skip mix_rho).
- test_chg_init.cpp: init_rho "wfc" with null wfcpw abort, and "atomic" with
  ntype==0 + meta_gga Thomas-Fermi tau initialization.
Wire all three targets into unittests/CMakeLists.txt.

Cleanup: remove the XC_Functional::func_type / ked_flag definitions from
test_chg_drho, test_chg_mix_rho, test_chg_symm, test_chg_atomic_inner,
test_chg_atomic, test_chg_tau, test_chg_routine, and test_chg_init. None of
the non-test sources compiled into these targets reference these statics
(charge.cpp, chg_*.cpp, and the linked base/cell_info/planewave_serial/
symmetry libraries are clean), so the definitions were pure dead weight.
Also drop the now-unneeded xc_functional.h include from test_chg_mix_rho.cpp
and correct the stub comments.
- include chg_atomic_detail.h instead of nonexistent chg_atomic_inner.h
  in test_chg_atomic_inner.cpp; add math_integral.h for Simpson_Integral
- include chg_drho.h in test_chg_drho_inner.cpp for
  module_charge::inner_product_recip_hartree
- include source_cell/magnetism.h in tests that define Magnetism stubs
  (test_chg_drho, test_chg_symm, test_chg_tau, test_chg_mix_rho)
- fix nonexistent source_charge/mixing includes in test_chg_tau.cpp to
  source_base/module_mixing
…ne/init targets

- test_chg_tau: use Plain_Mixing(beta) ctor and init_mixing_data with
  complex type_size (old set_mixing_beta/init_mixing no longer exist)
- test_chg_symm_detail: add Magnetism stub required by cell_info's
  unitcell.cpp, matching other tests in this directory
- test_chg_routine: adapt to two-arg set_rhopw and tpiba from ucell
- disable MODULE_CHARGE_routine and MODULE_CHARGE_init targets with
  documented reasons: their transitive dependencies (Plus_U_Base,
  elecstate, source_io) are deeply coupled; to be resolved later
Resolved conflicts by adopting 20260916's refactored interface:
- esolver_ks.cpp: aggregate-initialize MixingConfig with compile-time
  missing-field check; call set_rhopw() separately from set_mixing()
- chg_mix.cpp: store mixing params in cfg_ instead of individual members
- test_chg_mix.cpp: adapt tests to new set_mixing signature and getters
Fold the smooth/dense PW_Basis pointer assignment into
Charge_Mixing::set_mixing so grid injection happens together with the
rest of the mixing configuration, and remove the now-redundant
set_rhopw setter. Update the esolver_ks call site and unit tests
accordingly.

This re-applies 20260916 commit f07937e, which was accidentally
reverted by the merge b879341 ("Merge branch '20260916' into
2026-09-20") that kept the pre-refactor split interface at the
chg_mix conflict resolution.
# Conflicts:
#	source/source_esolver/esolver_ks.cpp
#	source/source_estate/module_charge/chg_mix.cpp
#	source/source_estate/module_charge/chg_mix.h
#	source/source_estate/module_charge/chg_mix_rho.cpp
#	source/source_estate/module_charge/unittests/test_chg_mix.cpp
#	source/source_estate/module_charge/unittests/test_chg_mix_rho.cpp
#	source/source_estate/module_charge/unittests/test_chg_routine.cpp
#	source/source_estate/module_dm/init_dm.cpp
Extract ShiftRealComplex trait into dm_shift.h and DensityMatrix_Tools
free-function declarations into dm_tools.h (with forward-declared
HContainer to keep header dependencies minimal). Move the
func_exp_mul_dmk / func_xyz_to_updown specializations from
density_matrix.cpp into dmr_cal.cpp so all DensityMatrix_Tools
implementations live in one TU. Tests that only call
func_xyz_to_updown now include the lighter dm_tools.h directly and
link dmr_cal.cpp for the moved definitions.
…tions

Move the DMK file IO bodies out of DensityMatrix<TK,TR> into
DensityMatrix_Tools::read_DMK_file / write_DMK_file free functions
(declared in dm_tools.h, befriended by the class). The member
functions become 3-line thin wrappers, so all existing call sites
(test_dm_io.cpp) are unchanged. The two old explicit member
specializations of write_DMK collapse into one generic template plus
a single <complex,double> specialization that writes .real().
…DMR_td

Change the cal_DMR / cal_DMR_td free-function signatures to take a
non-const DensityMatrix& and set _dmr_ready=true inside them, matching
the behavior the member wrappers previously provided. The member
specializations drop their now-redundant flag assignments. This
decouples the readiness bookkeeping from the member API so the next
step can route all call sites through the free functions.
@mohanchen mohanchen added Refactor Refactor ABACUS codes The Absolute Zero Reduce the "entropy" of the code to 0 labels Sep 21, 2026
abacus_fixer added 3 commits September 21, 2026 17:26
The member function was a thin pass-through to
DensityMatrix_Tools::read_DMK_file. Call the free function directly in
the remaining test call sites and drop the redundant wrapper.
The member function was a thin pass-through to
DensityMatrix_Tools::write_DMK_file. Call the free function directly in
the remaining test call site and drop the redundant wrapper.
…m namespace

Move the DensityMatrix class and the whole module_dm component (cal_dm_psi,
cal_edm_tddft, init_dm, dm_tools, dm_shift, dmr_cal, dm_io) out of the
elecstate namespace into a top-level module_dm namespace. Update all
elecstate::DensityMatrix / elecstate::<moved-fn> references and forward
declarations across the codebase accordingly.

Extract read_DMK_file/write_DMK_file into new dm_io.h/cpp under module_dm.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Refactor Refactor ABACUS codes The Absolute Zero Reduce the "entropy" of the code to 0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants