@@ -89,16 +89,19 @@ namespace LR
8989 this ->gint_ ->reset_DMRGint (dm_gs.get_DMR_vector ().size ());
9090 elecstate::Potential pot_hxc = this ->dm_to_hxc_potential (dm_gs);
9191 this ->gint_ ->reset_DMRGint (relax_diff_dm.get_DMR_vector ().size ());
92+ // `cal_pulay_fs` calculates 1*Pulay-term.
93+ // For ground-state DFT, Pulay term = Hellmann-Feynman term, F = 1/2(Pulay + H-F) = Pulay, so directly call it once gives correct result.
9294 PulayForceStress::cal_pulay_fs (relax_diff_dm.get_DMR_vector ().size ()/* nspin*/ , fhxc_dphi, stress_tmp,
9395 relax_diff_dm, this ->ucell_ , &pot_hxc, *this ->gint_ , true , false );
94- fhxc_dphi *= 0.5 ; // avoid double count
96+ // fhxc_dphi *= 0.5; // avoid double count
9597
9698 // 3.3 Hartree + xc (Hellmann-Feynman)
9799 ModuleBase::matrix fhxc_dvhxc (this ->ucell_ .nat , 3 );
98100 elecstate::Potential pot_hxc_relaxed_diff = this ->dm_to_hxc_potential (relax_diff_dm);
101+ // `cal_pulay_fs` calculates only one spin channel because `relax_diff_dm` has only one.
99102 PulayForceStress::cal_pulay_fs (1 /* nspin*/ , fhxc_dvhxc, stress_tmp,
100103 dm_gs, this ->ucell_ , &pot_hxc_relaxed_diff, *this ->gint_ , true , false );
101- // fhxc_dvhxc *= 0.5 ; // avoid double count, but nspin=2 of ground-state dm cancels it here
104+ fhxc_dvhxc *= 2 ; // for the two channels of the ground-state dm.
102105
103106 // 4. kinetic (Pulay)
104107 std::vector<hamilt::HContainer<double >> dT = cal_hs_grad (' T' , this ->ucell_ , this ->pv_ , this ->gd_ , this ->two_center_bundle_ );
@@ -120,6 +123,9 @@ namespace LR
120123 template <typename TK >
121124 ModuleBase::matrix LR_Force<TK >::cal_force_hxc_dmtrans(const elecstate::DensityMatrix<TK , double >& dm_trans, const PotHxcLR& pot_hxc)
122125 {
126+ // `dm_trans` (D^X) carries the singlet spin normalization (sqrt(2) per channel),
127+ // so D^X in pot_hxc and cal_pulay_fs together already contribute a factor 2.
128+ // So cal_pulay_fs here returns 2*Pulay = Pulay + Hellmann-Feynman force. *2 is not needed here.
123129 return PulayForceStress::cal_pulay_fs (dm_trans, this ->ucell_ , &pot_hxc, *this ->gint_ );
124130 }
125131
@@ -134,12 +140,13 @@ namespace LR
134140 auto & exx_lri_kernel = this ->exx_lri_ .lock ()->get ();
135141 exx_lri_kernel.set_Ds (dm_trans, this ->exx_lri_ .lock ()->get_info ().dm_threshold , spin_suffix);
136142 exx_lri_kernel.cal_Hs ({ " " , " " , spin_suffix });
137- exx_lri_kernel.cal_force ({ " " , " " , spin_suffix, " " , " " });// using dm_trans
143+ exx_lri_kernel.cal_force ({ " " , " " , spin_suffix, " " , " " });// using dm_trans,Pulay term only
138144 for (std::size_t idim = 0 ; idim < 3 ; ++idim)
139145 for (const auto & force_item : exx_lri_kernel.force [idim])
140146 f_exx_dmtrans (force_item.first , idim) = std::real (force_item.second );
141147 const double fac = -2.0 * alpha; // -2 is the same as post_process_Hexx, Hartree to Ry (which didn't act on Hs)
142- return f_exx_dmtrans * fac; // dm_trans (DX) already contain the spin channel (sqrt(2) times of up/down channel DX)
148+ const double pulay_to_total_sym = 2.0 ; // Pulay -> Pulay + Hellmann-Feynman, only when Ds_left and Ds_right are equal
149+ return f_exx_dmtrans * fac * pulay_to_total_sym; // dm_trans (DX) already contain the spin channel (sqrt(2) times of up/down channel DX)
143150 // return f_exx_dmtrans * fac * 2; // 2 is the same in post_process_Eexx at nspin=1 ( up->up + down->down, 2 spin-conserving transitions)
144151 }
145152
@@ -199,8 +206,9 @@ namespace LR
199206
200207 // -2 * 0.5 * alpha
201208 // -2 is the same as post_process_Hexx (a.u. to Ry, which didn't act on Hs)
202- // 0.5 is the 2-electron integral prefactor
203- const double fac = -alpha;
209+ // 0.5 is the 2-electron integral prefactor,used in ground-state energy/force where two density matrix are identical
210+ // But the LR-grad Lagrangian/force 2-e term here Tr[(T+Z)H[D]] does not have 1/2 factor.
211+ const double fac = -2 * alpha;
204212 return f_exx_gs_diff * fac;
205213 }
206214#endif
0 commit comments