@@ -25,9 +25,35 @@ namespace LR
2525 return chr;
2626 }
2727
28+ template <typename TK>
29+ elecstate::Potential LR_Force<TK>::dm_to_hxc_potential(const elecstate::DensityMatrix<TK, double >& dm)
30+ {
31+ double etxc = 0.0 , vtxc = 0.0 ;
32+ elecstate::Potential pot (&this ->rhodpw_ , &this ->rhopw_ , &this ->ucell_ ,
33+ &this ->locpp_ .vloc , const_cast <Structure_Factor*>(&this ->sf_ ),
34+ nullptr /* surchem*/ , &etxc, &vtxc);
35+ PARAM.inp .vh_in_h ? pot.pot_register ({ " hartree" , " xc" }) : pot.pot_register ({ " xc" });
36+ const Charge& charge = this ->dm_to_charge (dm);
37+ pot.init_pot (0 , &charge); // call update_from_charge inside
38+ return pot;
39+ }
40+
41+ template <typename TK>
42+ elecstate::Potential LR_Force<TK>::local_potential()
43+ {
44+ elecstate::Potential pot (&this ->rhodpw_ , &this ->rhopw_ , &this ->ucell_ ,
45+ &this ->locpp_ .vloc , const_cast <Structure_Factor*>(&this ->sf_ ),
46+ nullptr /* surchem*/ , nullptr /* etxc*/ , nullptr /* vtxc*/ );
47+ pot.pot_register ({ " local" });
48+ pot.init_pot (0 , nullptr );
49+ return pot;
50+ }
51+
2852 template <typename TK>
2953 ModuleBase::matrix LR_Force<TK>::cal_force_hamilt_gs_dm_relaxed_diff(const elecstate::DensityMatrix<TK, double >& relax_diff_dm,
30- const elecstate::Potential& pot_gs, const bool with_ewald)
54+ const elecstate::DensityMatrix<TK, double >& dm_gs,
55+ // const elecstate::Potential& pot_gs,
56+ const bool with_ewald)
3157 {
3258 const Charge chr_diff_relaxed = dm_to_charge (relax_diff_dm);
3359
@@ -39,11 +65,40 @@ namespace LR
3965 // 2. nonlocal pp (Hellmann-Feynman + Pulay)
4066 ModuleBase::matrix fvnl = cal_force_nonlocal (this ->ucell_ , this ->kvec_d_ , this ->gd_ , this ->two_center_bundle_ , relax_diff_dm);
4167
42- // 3. local pp (Pulay) + Hartree + xc (grid integration)
68+ // // 3. local pp (Pulay) + Hartree + xc (grid integration)
69+ // ModuleBase::matrix fvl_dphi(this->ucell_.nat, 3);
70+ // ModuleBase::matrix stress_tmp; // no use now, only for passing into interfaces
71+ // PulayForceStress::cal_pulay_fs(relax_diff_dm.get_DMR_vector().size()/*nspin*/, fvl_dphi, stress_tmp,
72+ // relax_diff_dm, this->ucell_, &pot_gs, *this->gint_, true, false);
73+
74+ // 3.1. local pp (Pulay)
4375 ModuleBase::matrix fvl_dphi (this ->ucell_ .nat , 3 );
4476 ModuleBase::matrix stress_tmp; // no use now, only for passing into interfaces
77+ elecstate::Potential pot_loc = this ->local_potential ();
4578 PulayForceStress::cal_pulay_fs (relax_diff_dm.get_DMR_vector ().size ()/* nspin*/ , fvl_dphi, stress_tmp,
46- relax_diff_dm, this ->ucell_ , &pot_gs, *this ->gint_ , true , false );
79+ relax_diff_dm, this ->ucell_ , &pot_loc, *this ->gint_ , true , false );
80+
81+ // 3.2. Hartree + xc (Pulay)
82+ // method 1
83+ // ModuleBase::matrix fgs_dphi(this->ucell_.nat, 3);
84+ // PulayForceStress::cal_pulay_fs(relax_diff_dm.get_DMR_vector().size()/*nspin*/, fgs_dphi, stress_tmp,
85+ // relax_diff_dm, this->ucell_, &pot_gs, *this->gint_, true, false);
86+ // ModuleBase::matrix fhxc_dphi = (fgs_dphi - fvl_dphi) * 0.5; // avoid double count of hxc Pulay term
87+ // method 2
88+ ModuleBase::matrix fhxc_dphi (this ->ucell_ .nat , 3 );
89+ this ->gint_ ->reset_DMRGint (dm_gs.get_DMR_vector ().size ());
90+ elecstate::Potential pot_hxc = this ->dm_to_hxc_potential (dm_gs);
91+ this ->gint_ ->reset_DMRGint (relax_diff_dm.get_DMR_vector ().size ());
92+ PulayForceStress::cal_pulay_fs (relax_diff_dm.get_DMR_vector ().size ()/* nspin*/ , fhxc_dphi, stress_tmp,
93+ relax_diff_dm, this ->ucell_ , &pot_hxc, *this ->gint_ , true , false );
94+ fhxc_dphi *= 0.5 ; // avoid double count
95+
96+ // 3.3 Hartree + xc (Hellmann-Feynman)
97+ ModuleBase::matrix fhxc_dvhxc (this ->ucell_ .nat , 3 );
98+ elecstate::Potential pot_hxc_relaxed_diff = this ->dm_to_hxc_potential (relax_diff_dm);
99+ PulayForceStress::cal_pulay_fs (1 /* nspin*/ , fhxc_dvhxc, stress_tmp,
100+ relax_diff_dm, 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
47102
48103 // 4. kinetic (Pulay)
49104 std::vector<hamilt::HContainer<double >> dT = cal_hs_grad (' T' , this ->ucell_ , this ->pv_ , this ->gd_ , this ->two_center_bundle_ );
@@ -54,11 +109,13 @@ namespace LR
54109 ModuleIO::print_force (GlobalV::ofs_running, this ->ucell_ , " PW FORCE (eV/Angstrom)" , f_pw, false );
55110 ModuleIO::print_force (GlobalV::ofs_running, this ->ucell_ , " NONLOCAL FORCE (eV/Angstrom)" , fvnl, false );
56111 ModuleIO::print_force (GlobalV::ofs_running, this ->ucell_ , " KINETIC FORCE (eV/Angstrom)" , ft_dphi, false );
57- ModuleIO::print_force (GlobalV::ofs_running, this ->ucell_ , " LOCAL Pulay FORCE (pp+Hartree+XC) (eV/Angstrom)" , fvl_dphi, false );
112+ ModuleIO::print_force (GlobalV::ofs_running, this ->ucell_ , " LOCAL-PP Pulay FORCE (eV/Angstrom)" , fvl_dphi, false );
113+ ModuleIO::print_force (GlobalV::ofs_running, this ->ucell_ , " HARTREE+XC Pulay FORCE (eV/Angstrom)" , fhxc_dphi, false );
114+ ModuleIO::print_force (GlobalV::ofs_running, this ->ucell_ , " HARTREE+XC Hellmann-Feynman FORCE (eV/Angstrom)" , fhxc_dvhxc, false );
58115 }
59116
60117 // from the formula, we do not need the non-ortho term (overlap*edm) here.
61- return f_pw + fvnl + ft_dphi + fvl_dphi;
118+ return f_pw + fvnl + ft_dphi + fvl_dphi + fhxc_dphi + fhxc_dvhxc ;
62119 }
63120 template <typename TK>
64121 ModuleBase::matrix LR_Force<TK>::cal_force_hxc_dmtrans(const elecstate::DensityMatrix<TK, double >& dm_trans, const PotHxcLR& pot_hxc)
@@ -85,12 +142,11 @@ namespace LR
85142 template <typename TK>
86143 ModuleBase::matrix LR_Force<TK>::reproduce_force_gs(
87144 const elecstate::DensityMatrix<TK, double >& dm_gs,
88- const elecstate::DensityMatrix<TK, double >& edm_gs,
89- const elecstate::Potential& pot_gs)
145+ const elecstate::DensityMatrix<TK, double >& edm_gs)
90146 {
91147 this ->gint_ ->reset_DMRGint (PARAM.inp .nspin );
92- // Hartree+ xc term
93- ModuleBase::matrix f_gs_hf_pulay = cal_force_hamilt_gs_dm_relaxed_diff (dm_gs, pot_gs ); // pw+vnl+t_dphi+vl_dphi
148+ // local + Hartree + xc term, including Hellmann-Feynman and Pulay
149+ ModuleBase::matrix f_gs_hf_pulay = cal_force_hamilt_gs_dm_relaxed_diff (dm_gs, dm_gs ); // pw+vnl+t_dphi+vl_dphi
94150 // edm term
95151 ModuleBase::matrix f_nonortho = cal_force_overlap_edm (edm_gs); // overlap
96152 this ->gint_ ->reset_DMRGint (1 );
0 commit comments