@@ -25,9 +25,34 @@ 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+ elecstate::Potential pot (nullptr /* remaining for uspp*/ ,
32+ &this ->rhopw_ , &this ->ucell_ , &this ->locpp_ .vloc , const_cast <Structure_Factor*>(&this ->sf_ ),
33+ nullptr /* surchem*/ , nullptr /* etxc*/ , nullptr /* vtxc*/ );
34+ PARAM .inp .vh_in_h ? pot.pot_register ({ " hartree" , " xc" }) : pot.pot_register ({ " xc" });
35+ const Charge& charge = this ->dm_to_charge (dm);
36+ pot.init_pot (0 , &charge); // call update_from_charge inside
37+ return pot;
38+ }
39+
40+ template <typename TK >
41+ elecstate::Potential LR_Force<TK >::local_potential()
42+ {
43+ elecstate::Potential pot (nullptr /* remaining for uspp*/ ,
44+ &this ->rhopw_ , &this ->ucell_ , &this ->locpp_ .vloc , const_cast <Structure_Factor*>(&this ->sf_ ),
45+ nullptr /* surchem*/ , nullptr /* etxc*/ , nullptr /* vtxc*/ );
46+ pot.pot_register ({ " local" });
47+ pot.init_pot (0 , nullptr );
48+ return pot;
49+ }
50+
2851 template <typename TK >
2952 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)
53+ const elecstate::DensityMatrix<TK , double >& dm_gs,
54+ // const elecstate::Potential& pot_gs,
55+ const bool with_ewald)
3156 {
3257 const Charge chr_diff_relaxed = dm_to_charge (relax_diff_dm);
3358
@@ -39,11 +64,38 @@ namespace LR
3964 // 2. nonlocal pp (Hellmann-Feynman + Pulay)
4065 ModuleBase::matrix fvnl = cal_force_nonlocal (this ->ucell_ , this ->kvec_d_ , this ->gd_ , this ->two_center_bundle_ , relax_diff_dm);
4166
42- // 3. local pp (Pulay) + Hartree + xc (grid integration)
67+ // // 3. local pp (Pulay) + Hartree + xc (grid integration)
68+ // ModuleBase::matrix fvl_dphi(this->ucell_.nat, 3);
69+ // ModuleBase::matrix stress_tmp; // no use now, only for passing into interfaces
70+ // PulayForceStress::cal_pulay_fs(relax_diff_dm.get_DMR_vector().size()/*nspin*/, fvl_dphi, stress_tmp,
71+ // relax_diff_dm, this->ucell_, &pot_gs, *this->gint_, true, false);
72+
73+ // 3.1. local pp (Pulay)
4374 ModuleBase::matrix fvl_dphi (this ->ucell_ .nat , 3 );
4475 ModuleBase::matrix stress_tmp; // no use now, only for passing into interfaces
76+ elecstate::Potential pot_loc = this ->local_potential ();
4577 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 );
78+ relax_diff_dm, this ->ucell_ , &pot_loc, *this ->gint_ , true , false );
79+
80+ // 3.2. Hartree + xc (Pulay)
81+ // method 1
82+ // ModuleBase::matrix fgs_dphi(this->ucell_.nat, 3);
83+ // PulayForceStress::cal_pulay_fs(relax_diff_dm.get_DMR_vector().size()/*nspin*/, fgs_dphi, stress_tmp,
84+ // relax_diff_dm, this->ucell_, &pot_gs, *this->gint_, true, false);
85+ // ModuleBase::matrix fhxc_dphi = (fgs_dphi - fvl_dphi) * 0.5; // avoid double count of hxc Pulay term
86+ // method 2
87+ ModuleBase::matrix fhxc_dphi (this ->ucell_ .nat , 3 );
88+ elecstate::Potential pot_hxc = this ->dm_to_hxc_potential (dm_gs);
89+ PulayForceStress::cal_pulay_fs (relax_diff_dm.get_DMR_vector ().size ()/* nspin*/ , fhxc_dphi, stress_tmp,
90+ relax_diff_dm, this ->ucell_ , &pot_hxc, *this ->gint_ , true , false );
91+ fhxc_dphi *= 0.5 ; // avoid double count
92+
93+ // 3.3 Hartree + xc (Hellmann-Feynman)
94+ ModuleBase::matrix fhxc_dvhxc (this ->ucell_ .nat , 3 );
95+ elecstate::Potential pot_hxc_relaxed_diff = this ->dm_to_hxc_potential (relax_diff_dm);
96+ PulayForceStress::cal_pulay_fs (dm_gs.get_DMR_vector ().size ()/* nspin*/ , fhxc_dvhxc, stress_tmp,
97+ relax_diff_dm, this ->ucell_ , &pot_hxc_relaxed_diff, *this ->gint_ , false , true );
98+ fhxc_dvhxc *= 0.5 ; // avoid double count
4799
48100 // 4. kinetic (Pulay)
49101 std::vector<hamilt::HContainer<double >> dT = cal_hs_grad (' T' , this ->ucell_ , this ->pv_ , this ->gd_ , this ->two_center_bundle_ );
@@ -54,11 +106,13 @@ namespace LR
54106 ModuleIO::print_force (GlobalV::ofs_running, this ->ucell_ , " PW FORCE (eV/Angstrom)" , f_pw, false );
55107 ModuleIO::print_force (GlobalV::ofs_running, this ->ucell_ , " NONLOCAL FORCE (eV/Angstrom)" , fvnl, false );
56108 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 );
109+ ModuleIO::print_force (GlobalV::ofs_running, this ->ucell_ , " LOCAL-PP Pulay FORCE (eV/Angstrom)" , fvl_dphi, false );
110+ ModuleIO::print_force (GlobalV::ofs_running, this ->ucell_ , " HARTREE+XC Pulay FORCE (eV/Angstrom)" , fhxc_dphi, false );
111+ ModuleIO::print_force (GlobalV::ofs_running, this ->ucell_ , " HARTREE+XC Hellmann-Feynman FORCE (eV/Angstrom)" , fhxc_dvhxc, false );
58112 }
59113
60114 // from the formula, we do not need the non-ortho term (overlap*edm) here.
61- return f_pw + fvnl + ft_dphi + fvl_dphi;
115+ return f_pw + fvnl + ft_dphi + fvl_dphi + fhxc_dphi + fhxc_dvhxc ;
62116 }
63117 template <typename TK >
64118 ModuleBase::matrix LR_Force<TK >::cal_force_hxc_dmtrans(const elecstate::DensityMatrix<TK , double >& dm_trans, const PotHxcLR& pot_hxc)
@@ -85,12 +139,11 @@ namespace LR
85139 template <typename TK >
86140 ModuleBase::matrix LR_Force<TK >::reproduce_force_gs(
87141 const elecstate::DensityMatrix<TK , double >& dm_gs,
88- const elecstate::DensityMatrix<TK , double >& edm_gs,
89- const elecstate::Potential& pot_gs)
142+ const elecstate::DensityMatrix<TK , double >& edm_gs)
90143 {
91144 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
145+ // local + Hartree + xc term, including Hellmann-Feynman and Pulay
146+ ModuleBase::matrix f_gs_hf_pulay = cal_force_hamilt_gs_dm_relaxed_diff (dm_gs, dm_gs ); // pw+vnl+t_dphi+vl_dphi
94147 // edm term
95148 ModuleBase::matrix f_nonortho = cal_force_overlap_edm (edm_gs); // overlap
96149 this ->gint_ ->reset_DMRGint (1 );
0 commit comments