Skip to content

Commit 705ea1c

Browse files
authored
Merge branch 'develop' into 2026-09-02-line2-DFPT
2 parents d91fada + c567031 commit 705ea1c

50 files changed

Lines changed: 2334 additions & 1458 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: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -827,7 +827,6 @@ OBJS_SRCPW=h_ewald_pw.o\
827827
yukawa_screening.o\
828828
setup_dftu_pw.o\
829829
deltaspin_pw.o\
830-
deltaspin_pw_impl.o\
831830
force_pw.o\
832831
force_pw_us.o\
833832
force_pw_nl.o\
@@ -914,12 +913,14 @@ OBJS_DFTU=dftu_nao.o\
914913
OBJS_DELTASPIN=basic_funcs.o\
915914
cal_mw_from_lambda.o\
916915
cal_mw.o\
917-
init_sc.o\
916+
deltaspin_init.o\
918917
lambda_loop_helper.o\
919918
lambda_loop.o\
920919
spin_constrain.o\
921-
cal_mw_helper.o\
922920
deltaspin_lcao.o\
921+
deltaspin_lcao_mi.o\
922+
deltaspin_state.o\
923+
deltaspin_pw_mi.o\
923924
mi_tools.o\
924925
template_helpers.o\
925926

source/source_estate/test/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ AddTest(
5454
../occupy.cpp
5555
../module_charge/charge_mpi.cpp
5656
../../source_lcao/module_deltaspin/spin_constrain.cpp
57+
../../source_lcao/module_deltaspin/deltaspin_state.cpp
5758
../../source_psi/psi.cpp
5859
../../source_base/module_device/memory_op.cpp
5960
../../source_cell/klist.cpp ../../source_cell/parallel_kpoints.cpp ../../source_cell/reciprocal_grid.cpp

source/source_io/module_ctrl/ctrl_output_pw.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "../module_wf/write_wfc_pw.h" // use write_wfc_pw
1212
#include "source_base/formatter.h"
1313
#include "source_lcao/module_deltaspin/lambda_loop_helper.h"
14+
#include "source_lcao/module_deltaspin/deltaspin_pw_mi.h"
1415
#include "source_lcao/module_deltaspin/spin_constrain.h"
1516
#include "source_pw/module_pwdft/elecond.h"
1617
#include "source_pw/module_pwdft/onsite_proj.h" // use projector
@@ -219,7 +220,7 @@ void ModuleIO::ctrl_scf_pw(const int istep,
219220
if (inp.sc_mag_switch)
220221
{
221222
spinconstrain::SpinConstrain<std::complex<double>>& sc = spinconstrain::SpinConstrain<std::complex<double>>::getScInstance();
222-
sc.cal_mi_pw();
223+
spinconstrain::pw::cal_mi_pw(sc.state_, sc.psi, sc.pelec);
223224
spinconstrain::print_Mag_Force(sc, GlobalV::ofs_running);
224225
}
225226

source/source_lcao/module_deltaspin/CMakeLists.txt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
list(APPEND objects
22
spin_constrain.cpp
3-
init_sc.cpp
3+
deltaspin_init.cpp
44
cal_mw.cpp
55
basic_funcs.cpp
66
lambda_loop_helper.cpp
77
lambda_loop.cpp
88
cal_mw_from_lambda.cpp
99
template_helpers.cpp
1010
deltaspin_lcao.cpp
11-
cal_mw_helper.cpp
11+
deltaspin_lcao_mi.cpp
12+
deltaspin_state.cpp
13+
deltaspin_pw_mi.cpp
1214
mi_tools.cpp
1315
)
1416

Lines changed: 14 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1,103 +1,40 @@
1-
#include "source_base/tool_title.h"
2-
#include "source_base/timer.h"
3-
#include "spin_constrain.h"
41
#ifdef __LCAO
5-
#include "source_estate/elecstate_lcao.h"
6-
#include "source_lcao/hamilt_lcao.h"
7-
#include "source_lcao/module_operator_lcao/dspin_lcao.h"
82

93
/**
104
* @file cal_mw.cpp
11-
* @brief Magnetic moment calculation for LCAO and PW basis sets.
12-
*
13-
* @par cal_mi_lcao (LCAO)
14-
* Uses the DeltaSpin operator to compute magnetic moments from the density
15-
* matrix via real-space projection. For nspin=2, only the z-component is
16-
* extracted. For nspin=4, all three components are extracted from the
17-
* interleaved 4-component spinor density matrix.
5+
* @brief Thin LCAO shells on SpinConstrain: cal_mi_lcao() and set_operator().
186
*
19-
* @par cal_mi_pw (PW)
20-
* Uses the OnsiteProjector to compute atomic projections <alpha_{l,m}|psi_{k,i}>
21-
* (becp coefficients), then decomposes these into magnetic moments using
22-
* Pauli matrix traces (accumulate_Mi_from_becp).
23-
*
24-
* @par Error conditions
25-
* - Dynamic cast failure: p_operator is not the correct DeltaSpin type.
26-
* This happens if set_operator() was not called with the correct type.
27-
* Solution: Ensure set_operator() is called before cal_mi_lcao().
7+
* The actual LCAO magnetic-moment implementation lives in
8+
* deltaspin_lcao_mi.cpp as free functions over ScState; the member
9+
* functions below only adapt the singleton's stored pointers.
2810
*/
2911

30-
/**
31-
* @brief Calculate atomic magnetic moments using real-space projection (LCAO basis).
32-
*
33-
* @details The DeltaSpin operator computes magnetic moments by projecting the
34-
* density matrix onto atomic orbitals. For each constrained atom:
35-
* M_i = Tr[P_at * (rho_up - rho_dn)] (nspin=2)
36-
* M_i = Tr[P_at * rho_spinor] (nspin=4, decomposed via Pauli matrices)
37-
*
38-
* @param step Current SCF iteration number (for logging)
39-
* @param print Whether to print moments (unused in this implementation)
40-
*/
12+
#include "spin_constrain.h"
13+
14+
#include "deltaspin_lcao_mi.h"
15+
#include "source_lcao/module_operator_lcao/dspin_lcao.h"
16+
#include "source_estate/module_dm/density_matrix.h"
17+
4118
template <>
4219
void spinconstrain::SpinConstrain<std::complex<double>>::cal_mi_lcao(const int& step, bool print)
4320
{
44-
ModuleBase::TITLE("module_deltaspin", "cal_mi_lcao");
45-
ModuleBase::timer::start("spinconstrain::SpinConstrain", "cal_mi_lcao");
46-
// Reset Mi before calculation
47-
this->zero_Mi();
48-
const hamilt::HContainer<double>* dmr = this->dm_->get_DMR_pointer(1);
49-
std::vector<double> moments;
50-
if(this->nspin_==2)
51-
{
52-
// Switch to spin-difference density matrix (rho_up - rho_dn)
53-
this->dm_->switch_dmr(2);
54-
55-
// Compute moments via DeltaSpin operator
56-
moments = static_cast<hamilt::DeltaSpin<hamilt::OperatorLCAO<std::complex<double>, double>>*>(this->p_operator)->cal_moment(dmr, this->get_constrain());
57-
58-
// Switch back to total density matrix
59-
this->dm_->switch_dmr(0);
60-
61-
// For nspin=2, only z-component is meaningful
62-
for(int iat=0;iat<this->Mi_.size();iat++)
63-
{
64-
this->Mi_[iat].x = 0.0;
65-
this->Mi_[iat].y = 0.0;
66-
this->Mi_[iat].z = moments[iat];
67-
}
68-
}
69-
else if(this->nspin_==4)
70-
{
71-
// For nspin=4, moments array contains interleaved [Mx, My, Mz] per atom
72-
moments = static_cast<hamilt::DeltaSpin<hamilt::OperatorLCAO<std::complex<double>, std::complex<double>>>*>(this->p_operator)->cal_moment(dmr, this->get_constrain());
73-
for(int iat=0;iat<this->Mi_.size();iat++)
74-
{
75-
this->Mi_[iat].x = moments[iat*3];
76-
this->Mi_[iat].y = moments[iat*3+1];
77-
this->Mi_[iat].z = moments[iat*3+2];
78-
}
79-
}
80-
81-
ModuleBase::timer::end("spinconstrain::SpinConstrain", "cal_mi_lcao");
21+
lcao::cal_mi_lcao(this->state_, this->p_operator, this->dm_, step, print);
8222
}
8323

84-
#endif
24+
// cal_mi_lcao<double> stub lives in template_helpers.cpp (single definition).
8525

86-
// cal_mi_pw() has been moved to source/source_pw/module_pwdft/deltaspin_pw_impl.cpp
87-
// because it depends on PW-specific OnsiteProjector.
88-
89-
/// @brief Set the DeltaSpin operator pointer for LCAO magnetic moment calculation
9026
template <>
9127
void spinconstrain::SpinConstrain<std::complex<double>>::set_operator(
9228
hamilt::Operator<std::complex<double>>* op_in)
9329
{
9430
this->p_operator = op_in;
9531
}
9632

97-
/// @brief Set the DeltaSpin operator pointer (double specialization)
9833
template <>
9934
void spinconstrain::SpinConstrain<double>::set_operator(
10035
hamilt::Operator<double>* op_in)
10136
{
10237
this->p_operator = op_in;
10338
}
39+
40+
#endif // __LCAO

source/source_lcao/module_deltaspin/cal_mw_from_lambda.cpp

Lines changed: 27 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "source_hsolver/diago_iter_assist.h"
55
#include "source_io/module_parameter/parameter.h"
66
#include "spin_constrain.h"
7+
#include "deltaspin_pw_mi.h"
78
#include "mi_tools.h"
89
#include "source_pw/module_pwdft/onsite_proj.h"
910
#include "source_base/parallel_reduce.h"
@@ -105,19 +106,19 @@ void spinconstrain::SpinConstrain<std::complex<double>>::cal_mw_from_lambda(
105106
PARAM.inp.nbands,
106107
PARAM.inp.nelec,
107108
PARAM.inp.device == "gpu");
108-
if (this->nspin_ == 2)
109+
if (this->state_.nspin_ == 2)
109110
{
110111
dynamic_cast<hamilt::DeltaSpin<hamilt::OperatorLCAO<std::complex<double>, double>>*>(this->p_operator)
111112
->update_lambda();
112113
}
113-
else if (this->nspin_ == 4)
114+
else if (this->state_.nspin_ == 4)
114115
{
115116
dynamic_cast<hamilt::DeltaSpin<hamilt::OperatorLCAO<std::complex<double>, std::complex<double>>>*>(
116117
this->p_operator)
117118
->update_lambda();
118119
}
119120
// Diagonalization without updating charge density (last param = true means skip charge update)
120-
hsolver_t.solve(hamilt_t, psi_t[0], this->pelec, *this->dm_, *this->pelec->charge, this->nspin_, true);
121+
hsolver_t.solve(hamilt_t, psi_t[0], this->pelec, *this->dm_, *this->pelec->charge, this->state_.nspin_, true);
121122
elecstate::calculate_weights(this->pelec->ekb,
122123
this->pelec->wg,
123124
this->pelec->klist,
@@ -164,23 +165,21 @@ void spinconstrain::SpinConstrain<std::complex<double>>::cal_mw_from_lambda(
164165
becp_tmp.resize(size_becp * nk);
165166
std::vector<std::complex<double>> h_tmp(nbands * nbands), s_tmp(nbands * nbands);
166167
int initial_hs = 0;
167-
if(this->sub_h_save == nullptr)
168+
if(!this->pw_cache_.allocated())
168169
{
169170
// FIRST CALL: save subspace data for reuse across lambda steps
170171
initial_hs = 1;
171-
this->sub_h_save = new std::complex<double>[nbands * nbands * nk];
172-
this->sub_s_save = new std::complex<double>[nbands * nbands * nk];
173-
this->becp_save = new std::complex<double>[size_becp * nk];
174-
this->lambda_in_sub_ = this->lambda_;
172+
this->pw_cache_.allocate_cpu(nbands, nk, size_becp);
173+
this->pw_cache_.lambda_in_sub() = this->state_.lambda_;
175174
}
176175
for (int ik = 0; ik < nk; ++ik)
177176
{
178177

179178
psi_t->fix_k(ik);
180179

181-
std::complex<double>* h_k = this->sub_h_save + ik * nbands * nbands;
182-
std::complex<double>* s_k = this->sub_s_save + ik * nbands * nbands;
183-
std::complex<double>* becp_k = this->becp_save + ik * size_becp;
180+
std::complex<double>* h_k = this->pw_cache_.h_k(ik, nbands);
181+
std::complex<double>* s_k = this->pw_cache_.s_k(ik, nbands);
182+
std::complex<double>* becp_k = this->pw_cache_.becp_k(ik, size_becp);
184183
if(initial_hs)
185184
{
186185
/// Compute H(k) and extract subspace matrices for this k-point
@@ -191,7 +190,7 @@ void spinconstrain::SpinConstrain<std::complex<double>>::cal_mw_from_lambda(
191190
memcpy(h_tmp.data(), h_k, sizeof(std::complex<double>) * nbands * nbands);
192191
memcpy(s_tmp.data(), s_k, sizeof(std::complex<double>) * nbands * nbands);
193192
// Apply DeltaSpin correction (skip for initialization step i_step=-1)
194-
if (i_step != -1) this->calculate_delta_hcc(h_tmp.data(), becp_k, this->lambda_.data(), nbands, nkb, nh_iat, ik, true);
193+
if (i_step != -1) pw::calculate_delta_hcc(this->state_, this->pw_cache_, this->pelec, h_tmp.data(), becp_k, this->state_.lambda_.data(), nbands, nkb, nh_iat, ik, true);
195194

196195
// Diagonalize in subspace, update becp (response wavefunctions)
197196
hsolver::DiagoIterAssist<std::complex<double>>::diag_responce(h_tmp.data(),
@@ -224,23 +223,21 @@ void spinconstrain::SpinConstrain<std::complex<double>>::cal_mw_from_lambda(
224223
base_device::memory::resize_memory_op<std::complex<double>, base_device::DEVICE_GPU>()(h_tmp, nbands * nbands);
225224
base_device::memory::resize_memory_op<std::complex<double>, base_device::DEVICE_GPU>()(s_tmp, nbands * nbands);
226225
int initial_hs = 0;
227-
if(this->sub_h_save == nullptr)
226+
if(!this->pw_cache_.allocated())
228227
{
229228
initial_hs = 1;
230-
base_device::memory::resize_memory_op<std::complex<double>, base_device::DEVICE_GPU>()(this->sub_h_save, nbands * nbands * nk);
231-
base_device::memory::resize_memory_op<std::complex<double>, base_device::DEVICE_GPU>()(this->sub_s_save, nbands * nbands * nk);
232-
base_device::memory::resize_memory_op<std::complex<double>, base_device::DEVICE_GPU>()(this->becp_save, size_becp * nk);
233-
this->lambda_in_sub_ = this->lambda_;
229+
this->pw_cache_.allocate_gpu(nbands, nk, size_becp);
230+
this->pw_cache_.lambda_in_sub() = this->state_.lambda_;
234231
}
235232
std::complex<double>* becp_pointer = nullptr;
236233
base_device::memory::resize_memory_op<std::complex<double>, base_device::DEVICE_GPU>()(becp_pointer, size_becp);
237234
for (int ik = 0; ik < nk; ++ik)
238235
{
239236
psi_t->fix_k(ik);
240237

241-
std::complex<double>* h_k = this->sub_h_save + ik * nbands * nbands;
242-
std::complex<double>* s_k = this->sub_s_save + ik * nbands * nbands;
243-
std::complex<double>* becp_k = this->becp_save + ik * size_becp;
238+
std::complex<double>* h_k = this->pw_cache_.h_k(ik, nbands);
239+
std::complex<double>* s_k = this->pw_cache_.s_k(ik, nbands);
240+
std::complex<double>* becp_k = this->pw_cache_.becp_k(ik, size_becp);
244241
if(initial_hs)
245242
{
246243
hamilt_t->updateHk(ik);
@@ -249,7 +246,7 @@ void spinconstrain::SpinConstrain<std::complex<double>>::cal_mw_from_lambda(
249246
}
250247
base_device::memory::synchronize_memory_op<std::complex<double>, base_device::DEVICE_GPU, base_device::DEVICE_GPU>()(h_tmp, h_k, nbands * nbands);
251248
base_device::memory::synchronize_memory_op<std::complex<double>, base_device::DEVICE_GPU, base_device::DEVICE_GPU>()(s_tmp, s_k, nbands * nbands);
252-
if (i_step != -1) this->calculate_delta_hcc(h_tmp, becp_k, this->lambda_.data(), nbands, nkb, nh_iat, ik, true);
249+
if (i_step != -1) pw::calculate_delta_hcc(this->state_, this->pw_cache_, this->pelec, h_tmp, becp_k, this->state_.lambda_.data(), nbands, nkb, nh_iat, ik, true);
253250

254251
hsolver::DiagoIterAssist<std::complex<double>, base_device::DEVICE_GPU>::diag_responce(h_tmp,
255252
s_tmp,
@@ -280,15 +277,15 @@ void spinconstrain::SpinConstrain<std::complex<double>>::cal_mw_from_lambda(
280277
for (int ik = 0; ik < nk; ik++)
281278
{
282279
const std::complex<double>* becp = &becp_tmp[ik * size_becp];
283-
const int spin_sign = (this->npol_ == 2) ? 1 : this->get_spin_sign(ik);
284-
accumulate_Mi_from_becp(becp, nkb, nbands, this->npol_, spin_sign,
285-
&this->pelec->wg(ik, 0), nh_iat, this->Mi_);
280+
const int spin_sign = (this->state_.npol_ == 2) ? 1 : this->get_spin_sign(ik);
281+
accumulate_Mi_from_becp(becp, nkb, nbands, this->state_.npol_, spin_sign,
282+
&this->pelec->wg(ik, 0), nh_iat, this->state_.Mi_);
286283
}
287284
// MPI reduction: sum Mi across all k-pool ranks
288285
Parallel_Reduce::reduce_double_allpool(PARAM.inp.kpar,
289286
GlobalV::NPROC_IN_POOL,
290-
&(this->Mi_[0][0]),
291-
3 * this->Mi_.size());
287+
&(this->state_.Mi_[0][0]),
288+
3 * this->state_.Mi_.size());
292289
}
293290
}
294291
ModuleBase::timer::end("spinconstrain::SpinConstrain", "cal_mw_from_lambda");
@@ -328,12 +325,14 @@ void spinconstrain::SpinConstrain<std::complex<double>>::update_psi_charge(const
328325
{
329326
if (PARAM.inp.device == "cpu")
330327
{
331-
this->update_psi_charge_pw_cpu(delta_lambda, pw_solve, full_update);
328+
pw::update_psi_charge_pw_cpu(this->state_, this->pw_cache_, this->psi, this->p_hamilt,
329+
this->pelec, this->pw_wfc_, delta_lambda, pw_solve, full_update);
332330
}
333331
#if ((defined __CUDA) || (defined __ROCM))
334332
else
335333
{
336-
this->update_psi_charge_pw_gpu(delta_lambda, pw_solve, full_update);
334+
pw::update_psi_charge_pw_gpu(this->state_, this->pw_cache_, this->psi, this->p_hamilt,
335+
this->pelec, this->pw_wfc_, delta_lambda, pw_solve, full_update);
337336
}
338337
#endif
339338
}

0 commit comments

Comments
 (0)