Skip to content

Commit d8ff3fb

Browse files
dyzhengdyzheng
andauthored
Fix: DeltaSpin energy fix (#7748)
* Fix(deltaspin): enable DeltaSpin constraint energy calculation for PW basis - cal_escon(): replace is_Mi_converged gate with lambda_/Mi_ empty check to prevent segfault when uninitialized - elecstate_pw: add get_spin_constrain_energy() override so PW basis computes DeltaSpin constraint energy (previously returned 0.0) - elecstate_pw.h: declare get_spin_constrain_energy() override Note: this fix enables escon computation for PW DeltaSpin but lambda values from BFGS optimizer may differ from accel branch due to energy functional convention differences. Full convergence with accel requires lambda_loop.cpp migration. * Fix(deltaspin): enable PW DeltaSpin constraint energy and update test refs Source changes: - cal_escon(): replace is_Mi_converged guard with lambda_/Mi_ empty check to prevent segfault when uninitialized (matching accel convention) - elecstate_pw: add get_spin_constrain_energy() override so PW basis includes DeltaSpin constraint energy in total energy (was always 0) Test refs regenerated for 7 cases with significant energy changes: - 14_PW_DS_S4_XYZ, 15_PW_DS_S4_Z, 16_PW_DS_S4_XY - 18_PW_DFTU_DS_S2_Z, 19_PW_DFTU_DS_S4_XY, 21_PW_DFTU_DS_S4_Z - 41_PW_DS_S4_Thr10_XY nspin=2 tests and ReadLam/Thr1e10 tests unchanged. * Fix(deltaspin): fix pauli_to_moment My sign convention and enable PW escon Source fixes: - spin_constrain.h: fix My = -Im(occ1-occ2) → Im(occ1-occ2) The magnetic moment y-component had the wrong sign in the Pauli matrix transformation, causing incorrect Mi computation for nspin=4 DeltaSpin. - cal_escon(): replace is_Mi_converged guard with lambda_/Mi_ empty check - elecstate_pw: add get_spin_constrain_energy() for PW basis DeltaSpin Refs regenerated for nspin=4 DeltaSpin cases: 14, 15, 16, 19, 21, 41 Test 18 unchanged, nspin=2 tests unchanged. * Fix(build): link deltaspin sources into MODULE_ESTATE_elecstate_pw test elecstate_pw.cpp now calls spinconstrain::SpinConstrain< std::complex<double>>::getScInstance()/cal_escon() via the new get_spin_constrain_energy() override. The MODULE_ESTATE_elecstate_pw unit test compiles elecstate_pw.cpp directly but did not link the deltaspin module, causing undefined-reference link errors in BUILD_TESTING builds (test.yml and cuda.yml CI jobs). Add spin_constrain.cpp to the test SOURCES, mirroring the existing MODULE_LCAO_deltaspin_spin_constrain_test pattern. * fix: add get_spin_constrain_energy stub to hsolver supplementary mock ElecStatePW::get_spin_constrain_energy() is a new virtual override that needs a definition in the vtable. Test targets (MODULE_HSOLVER_base, MODULE_HSOLVER_pw, MODULE_HSOLVER_sdft) compile a mock implementation of ElecStatePW methods instead of linking elecstate_pw.cpp, and were missing a stub for this new method, causing: undefined reference to ElecStatePW::get_spin_constrain_energy() --------- Co-authored-by: dyzheng <zhengdy@bjaisi.com>
1 parent 4261f5e commit d8ff3fb

12 files changed

Lines changed: 38 additions & 20 deletions

File tree

source/source_estate/elecstate_pw.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "source_base/timer.h"
99
#include "source_hamilt/module_xc/xc_functional.h"
1010
#include "source_io/module_parameter/parameter.h"
11+
#include "source_lcao/module_deltaspin/spin_constrain.h"
1112
#include "source_pw/module_pwdft/vnl_pw.h"
1213

1314
namespace elecstate {
@@ -56,6 +57,14 @@ ElecStatePW<T, Device>::~ElecStatePW()
5657
delmem_complex_op()(this->wfcr_another_spin);
5758
}
5859

60+
template<typename T, typename Device>
61+
double ElecStatePW<T, Device>::get_spin_constrain_energy()
62+
{
63+
spinconstrain::SpinConstrain<std::complex<double>>& sc
64+
= spinconstrain::SpinConstrain<std::complex<double>>::getScInstance();
65+
return sc.cal_escon();
66+
}
67+
5968
template<typename T, typename Device>
6069
void ElecStatePW<T, Device>::init_rho_data()
6170
{

source/source_estate/elecstate_pw.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ class ElecStatePW : public ElecState
3636

3737
virtual void cal_tau(const psi::Psi<T, Device>& psi);
3838

39+
double get_spin_constrain_energy() override;
40+
3941
//! calculate becsum for uspp
4042
void cal_becsum(const psi::Psi<T, Device>& psi);
4143

source/source_estate/test/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ AddTest(
5151
../elecstate.cpp
5252
../occupy.cpp
5353
../module_charge/charge_mpi.cpp
54+
../../source_lcao/module_deltaspin/spin_constrain.cpp
5455
../../source_psi/psi.cpp
5556
../../source_base/module_device/memory_op.cpp
5657
)

source/source_hsolver/test/hsolver_supplementary_mock.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@ void ElecStatePW<T, Device>::cal_becsum(const psi::Psi<T, Device>& psi)
5959
{
6060
}
6161

62+
template <typename T, typename Device>
63+
double ElecStatePW<T, Device>::get_spin_constrain_energy()
64+
{
65+
return 0.0;
66+
}
67+
6268
template class ElecStatePW<std::complex<float>, base_device::DEVICE_CPU>;
6369
template class ElecStatePW<std::complex<double>, base_device::DEVICE_CPU>;
6470
#if ((defined __CUDA) || (defined __ROCM))

source/source_lcao/module_deltaspin/spin_constrain.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ template <typename TK>
4545
double SpinConstrain<TK>::cal_escon()
4646
{
4747
this->escon_ = 0.0;
48-
if (!this->is_Mi_converged)
48+
if (this->lambda_.empty() || this->Mi_.empty())
4949
{
5050
return this->escon_;
5151
}

source/source_lcao/module_deltaspin/spin_constrain.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ inline ModuleBase::Vector3<double> pauli_to_moment(const std::complex<double> oc
7979
{
8080
return ModuleBase::Vector3<double>(
8181
weight * (occ[1] + occ[2]).real(),
82-
-weight * (occ[1] - occ[2]).imag(),
82+
weight * (occ[1] - occ[2]).imag(),
8383
weight * (occ[0] - occ[3]).real()
8484
);
8585
}
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
etotref -6366.562922988214
2-
etotperatomref -3183.2814614941
3-
totaltimeref 4.23
1+
etotref -6369.19895097706
2+
etotperatomref -3184.59947548853
3+
totaltimeref 1.0
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
etotref -6366.562433916121
2-
etotperatomref -3183.2812169581
3-
totaltimeref 4.26
1+
etotref -6369.198273166801
2+
etotperatomref -3184.5991365834007
3+
totaltimeref 1.0
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
etotref -6366.562695059035
2-
etotperatomref -3183.2813475295
3-
totaltimeref 4.19
1+
etotref -6369.198274098935
2+
etotperatomref -3184.5991370494676
3+
totaltimeref 1.0
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
etotref -6355.9841673819892094
2-
etotperatomref -3177.9920836910
3-
totaltimeref 5.88
1+
etotref -6360.5554588729937677
2+
etotperatomref -3180.277729436497
3+
totaltimeref 1.0

0 commit comments

Comments
 (0)