2424#include " source_lcao/module_operator_lcao/nonlocal.h"
2525#include " source_lcao/module_operator_lcao/ekinetic.h"
2626#include " source_lcao/module_operator_lcao/overlap.h"
27+ #include " source_lcao/module_operator_lcao/td_pot_hybrid.h"
2728#include " source_lcao/pulay_fs.h"
29+ #include " source_lcao/module_rt/force_rt_overlap.h"
2830
2931
3032// mohan add 2025-11-04
@@ -85,7 +87,9 @@ void Force_Stress_LCAO<T>::getForceStress(UnitCell& ucell,
8587 Plus_U &dftu, // mohan add 2025-11-07
8688 Setup_DeePKS<T>& deepks,
8789 Exx_NAO<T> &exx_nao,
88- ModuleSymmetry::Symmetry* symm)
90+ ModuleSymmetry::Symmetry* symm,
91+ const int td_stype,
92+ hamilt::Hamilt<T>* p_hamilt)
8993{
9094 ModuleBase::TITLE (" Force_Stress_LCAO" , " getForceStress" );
9195 ModuleBase::timer::start (" Force_Stress_LCAO" , " getForceStress" );
@@ -113,6 +117,7 @@ void Force_Stress_LCAO<T>::getForceStress(UnitCell& ucell,
113117 ModuleBase::matrix fcc;
114118 ModuleBase::matrix fscc;
115119 ModuleBase::matrix fvnl_dalpha; // deepks
120+ ModuleBase::matrix fpothybrid;
116121
117122 fvl_dphi.create (nat, 3 ); // must do it now, update it later, noted by zhengdy
118123
@@ -127,6 +132,7 @@ void Force_Stress_LCAO<T>::getForceStress(UnitCell& ucell,
127132 fcc.create (nat, 3 ); // force due to core correction
128133 fscc.create (nat, 3 ); // force due to self-consistent field
129134 fvnl_dalpha.create (nat, 3 ); // deepks
135+ fpothybrid.create (nat, 3 ); // pulay force for hybrid gauge rt-tddft
130136
131137 // calculate basic terms in Force, same method with PW base
132138 this ->calForcePwPart (ucell, fvl_dvl, fewalds, fcc, fscc, pelec->f_en .etxc ,
@@ -199,14 +205,26 @@ void Force_Stress_LCAO<T>::getForceStress(UnitCell& ucell,
199205 hamilt::Overlap<hamilt::OperatorLCAO<T, double >> tmp_overlap (
200206 nullptr , kv.kvec_d , nullptr , nullptr , &ucell, orb.cutoffs (), &gd,
201207 two_center_bundle.overlap_orb .get ());
202- tmp_overlap.cal_force_stress (isforce, isstress, edmR, foverlap, soverlap);
208+ if (td_stype != 2 )
209+ {
210+ tmp_overlap.cal_force_stress (isforce, isstress, edmR, foverlap, soverlap);
211+ }
203212
204213 // Calculate nonlocal force/stress (uses DM)
205214 hamilt::Nonlocal<hamilt::OperatorLCAO<T, double >> tmp_nonlocal (
206215 nullptr , kv.kvec_d , nullptr , &ucell, orb.cutoffs (), &gd,
207216 two_center_bundle.overlap_orb_beta .get ());
208217 tmp_nonlocal.cal_force_stress (isforce, isstress, dmR, fvnl_dbeta, svnl_dbeta);
209218
219+ if (td_stype == 2 )
220+ {
221+ hamilt::TD_pot_hybrid<hamilt::OperatorLCAO<T, double >> tmp_hybrid (
222+ nullptr , &kv, nullptr , nullptr , orb, &ucell, orb.cutoffs (), &gd, nullptr );
223+ tmp_hybrid.cal_force_stress (isforce, dmR, fpothybrid);
224+
225+ cal_foverlap_rt (foverlap, dmat, p_hamilt, kv, pv, ucell);
226+ }
227+
210228 // Switch back to spin channel 0
211229 if (PARAM .inp .nspin == 2 )
212230 {
@@ -501,6 +519,7 @@ void Force_Stress_LCAO<T>::getForceStress(UnitCell& ucell,
501519 // ---------------------------------
502520 // sum all parts of force!
503521 // ---------------------------------
522+ ModuleBase::Vector3<double > net_force = {0.0 , 0.0 , 0.0 };
504523 for (int i = 0 ; i < 3 ; i++)
505524 {
506525 double sum = 0.0 ;
@@ -511,7 +530,8 @@ void Force_Stress_LCAO<T>::getForceStress(UnitCell& ucell,
511530 + fvl_dvl (iat, i) // derivative of local potential force (pw)
512531 + fewalds (iat, i) // ewald force (pw)
513532 + fcc (iat, i) // nonlinear core correction force (pw)
514- + fscc (iat, i); // self consistent corretion force (pw)
533+ + fscc (iat, i) // self consistent corretion force (pw)
534+ + fpothybrid (iat, i); // pulay force for hybrid gauge rt-tddft
515535
516536 // Force contribution from DFT+U, Quxin add on 20201029
517537 if (PARAM .inp .dft_plus_u )
@@ -564,7 +584,7 @@ void Force_Stress_LCAO<T>::getForceStress(UnitCell& ucell,
564584 // sum total force for correction
565585 sum += fcs (iat, i);
566586 }
567-
587+ net_force[i]=sum;
568588 if (!(PARAM .inp .gate_flag || PARAM .inp .efield_flag ))
569589 {
570590 for (int iat = 0 ; iat < nat; ++iat)
@@ -678,6 +698,9 @@ void Force_Stress_LCAO<T>::getForceStress(UnitCell& ucell,
678698
679699 // this->printforce_total(ry, istestf, fcs);
680700 ModuleIO::print_force (GlobalV::ofs_running, ucell, " TOTAL-FORCE (eV/Angstrom)" , fcs, false );
701+ net_force*= ModuleBase::Ry_to_eV / ModuleBase::BOHR_TO_A ;
702+ ModuleBase::GlobalFunc::OUT (GlobalV::ofs_running, " Net force vector (eV/Ang)" , net_force.x , net_force.y , net_force.z );
703+ ModuleBase::GlobalFunc::OUT (GlobalV::ofs_running, " Total drift (ev/Ang)" , net_force.norm ());
681704 if (istestf)
682705 {
683706 GlobalV::ofs_running << " \n FORCE INVALID TABLE." << std::endl;
0 commit comments