Skip to content

Commit 00ce1e2

Browse files
committed
DeltaP LCAO force/stress implementation
Add cal_force_stress() to DeltaPOperator following DeltaSpin pattern: deltap_force_stress.hpp (new file, 270 lines): - cal_force_stress(): iterates over constrained atoms, calls intor_->snap(cal_deri=1) for projector derivatives, accumulates force/stress via cal_force_IJR/cal_stress_IJR - cal_force_IJR(): force = lambda * nlm_deriv * nlm * DM (same structure as DeltaSpin, scalar lambda instead of Vector3) - cal_stress_IJR(): stress = force * r_vector projection deltap_lcao.h: add force/stress method declarations + static s_stored_lambda for cross-module lambda access deltap_lcao.cpp: include deltap_force_stress.hpp + static member definition FORCE_STRESS.cpp: create temp DeltaPOperator with stored lambda, call cal_force_stress(), accumulate into fcs/scs esolver_ks_lcao.cpp: store lambda before getForceStress BN LCAO + PW regression pass.
1 parent ecbde57 commit 00ce1e2

5 files changed

Lines changed: 452 additions & 0 deletions

File tree

source/source_esolver/esolver_ks_lcao.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,18 @@ void ESolver_KS_LCAO<TK, TR>::cal_force(UnitCell& ucell, ModuleBase::matrix& for
236236

237237
Force_Stress_LCAO<TK> fsl(this->RA, ucell.nat);
238238

239+
// Store DeltaP lambda for force/stress computation
240+
if (PARAM.inp.deltap_switch && PARAM.inp.deltap_corr)
241+
{
242+
auto* hamilt_lcao = dynamic_cast<hamilt::HamiltLCAO<TK, TR>*>(this->p_hamilt);
243+
if (hamilt_lcao != nullptr)
244+
{
245+
auto* dp_op = hamilt_lcao->get_dp_operator();
246+
if (dp_op != nullptr)
247+
hamilt::DeltaPOperator<TK, TR>::store_lambda_for_force(dp_op->get_lambda());
248+
}
249+
}
250+
239251
deepks.dpks_out_type = "tot"; // for deepks method
240252

241253
fsl.getForceStress(ucell, PARAM.inp.cal_force, PARAM.inp.cal_stress,

source/source_lcao/FORCE_STRESS.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#endif
2222
#include "source_lcao/module_operator_lcao/dftu_lcao.h"
2323
#include "source_lcao/module_operator_lcao/dspin_lcao.h"
24+
#include "source_lcao/module_operator_lcao/deltap_lcao.h"
2425
#include "source_lcao/module_operator_lcao/nonlocal.h"
2526
#include "source_lcao/module_operator_lcao/ekinetic.h"
2627
#include "source_lcao/module_operator_lcao/overlap.h"
@@ -429,6 +430,29 @@ void Force_Stress_LCAO<T>::getForceStress(UnitCell& ucell,
429430
}
430431
}
431432

433+
// atomic force and stress for DeltaP
434+
ModuleBase::matrix force_deltap;
435+
ModuleBase::matrix stress_deltap;
436+
if (PARAM.inp.deltap_switch && PARAM.inp.deltap_corr)
437+
{
438+
const auto& dp_lambda = hamilt::DeltaPOperator<std::complex<double>, double>::get_stored_lambda();
439+
if (!dp_lambda.empty())
440+
{
441+
if (isforce) force_deltap.create(nat, 3);
442+
if (isstress) stress_deltap.create(3, 3);
443+
444+
double rm = PARAM.inp.deltap_rm > 0.0 ? PARAM.inp.deltap_rm : 3.0;
445+
hamilt::DeltaPOperator<std::complex<double>, double> tmp_dp(
446+
nullptr, kv.kvec_d, nullptr, ucell, &gd,
447+
two_center_bundle.overlap_orb_onsite.get(), orb.cutoffs(), rm);
448+
tmp_dp.set_lambda(dp_lambda);
449+
tmp_dp.set_gdir(PARAM.inp.deltap_gdir);
450+
451+
const hamilt::HContainer<double>* dmr = dmat.dm->get_DMR_pointer(1);
452+
tmp_dp.cal_force_stress(isforce, isstress, dmr, force_deltap, stress_deltap);
453+
}
454+
}
455+
432456
// NOTE: finish_ftable is no longer needed as we don't use ForceStressArrays for overlap/kinetic
433457
// if (!PARAM.globalv.gamma_only_local)
434458
// {
@@ -498,6 +522,10 @@ void Force_Stress_LCAO<T>::getForceStress(UnitCell& ucell,
498522
{
499523
fcs(iat, i) += force_dspin(iat, i);
500524
}
525+
if (PARAM.inp.deltap_switch && PARAM.inp.deltap_corr)
526+
{
527+
fcs(iat, i) += force_deltap(iat, i);
528+
}
501529
#ifdef __EXX
502530
// Force contribution from exx
503531
if (GlobalC::exx_info.info_global.cal_exx)
@@ -709,6 +737,10 @@ void Force_Stress_LCAO<T>::getForceStress(UnitCell& ucell,
709737
{
710738
scs(i, j) += stress_dspin(i, j);
711739
}
740+
if (PARAM.inp.deltap_switch && PARAM.inp.deltap_corr)
741+
{
742+
scs(i, j) += stress_deltap(i, j);
743+
}
712744
#ifdef __EXX
713745
// Stress contribution from exx
714746
if (GlobalC::exx_info.info_global.cal_exx)

0 commit comments

Comments
 (0)