@@ -17,7 +17,7 @@ namespace LR
1717 :xc_kernel_(xc_kernel), tpiba_(ucell.tpiba), spin_type_(st), rho_basis_(rho_basis), nrxx_(chg_gs.nrxx),
1818 nspin_ (PARAM.inp.nspin == 1 || (PARAM.inp.nspin == 4 && !PARAM.globalv.domag && !PARAM.globalv.domag_z) ? 1 : 2),
1919 pot_hartree_(LR_Util::make_unique<elecstate::PotHartree>(&rho_basis)),
20- xc_kernel_components_(rho_basis, ucell, chg_gs, pgrid, nspin_, xc_kernel, lr_init_xc_kernel), // call XC_Functional::set_func_type and libxc
20+ xc_kernel_components_(rho_basis, ucell, chg_gs, pgrid, nspin_, xc_kernel, lr_init_xc_kernel, (st == SpinType::S2_updown) ), // call XC_Functional::set_func_type and libxc
2121 xc_type_(XCType(XC_Functional::get_func_type()))
2222 {
2323 if (std::set<std::string>({ " lda" , " pwlda" , " pbe" , " hse" }).count (xc_kernel)) { this ->set_integral_func (this ->spin_type_ , this ->xc_type_ ); }
@@ -127,7 +127,7 @@ namespace LR
127127 for (int ir = 0 ;ir < nrxx;++ir)
128128 {
129129 e_drho[ir] = -(fxc.v2rhosigma_2drho .at (ir) * rho[ir]
130- + fxc.v2sigma2_4drho .at (ir) * (fxc.drho_gs .at (ir) * drho.at (ir))
130+ + fxc.v2sigma2_4drho .at (ir) * (fxc.drho_gs .at (0 ). at ( ir) * drho.at (ir))
131131 + drho.at (ir) * fxc.vsigma .at (ir) * 2 .);
132132 }
133133 XC_Functional::grad_dot (e_drho.data (), vxc_tmp.data (), &this ->rho_basis_ , this ->tpiba_ );
@@ -141,10 +141,149 @@ namespace LR
141141 BlasConnector::axpy (nrxx, ModuleBase::e2 , vxc_tmp.data (), 1 , v_eff.c , 1 );
142142 };
143143 break ;
144- // case SpinType::S2_singlet:
145- // break;
146- // case SpinType::S2_triplet:
147- // break;
144+ case SpinType::S2_singlet:
145+ funcs[s] = [this , &fxc](FXC_PARA_TYPE)-> void
146+ {
147+ std::vector<ModuleBase::Vector3<double >> drho (nrxx); // transition density gradient
148+ LR_Util::grad (rho, drho.data (), this ->rho_basis_ , this ->tpiba_ );
149+
150+ std::vector<double > vxc_tmp (nrxx, 0.0 );
151+
152+ // 1. the terms in grad_dot int f_uu
153+ std::vector<ModuleBase::Vector3<double >> gdot_terms (nrxx);
154+ for (int ir = 0 ;ir < nrxx;++ir)
155+ {
156+ // gdot terms in f_uu
157+ gdot_terms[ir] = -(rho[ir] * fxc.v2rhosigma_drho_singlet .at (ir)
158+ + (fxc.drho_gs .at (0 ).at (ir) * drho.at (ir)) * fxc.v2sigma2_drho_singlet .at (ir)
159+ + drho.at (ir) * (fxc.vsigma .at (ir * 3 ) * 2 . + fxc.vsigma .at (ir * 3 + 1 )));
160+ }
161+ XC_Functional::grad_dot (gdot_terms.data (), vxc_tmp.data (), &this ->rho_basis_ , this ->tpiba_ );
162+
163+ // 2. terms not in grad_dot
164+ for (int ir = 0 ;ir < nrxx;++ir)
165+ {
166+ vxc_tmp[ir] += rho[ir] * (fxc.v2rho2 .at (ir * 3 ) + fxc.v2rho2 .at (ir * 3 + 1 ))
167+ + drho.at (ir) * fxc.v2rhosigma_drho_singlet .at (ir);
168+ }
169+ BlasConnector::axpy (nrxx, ModuleBase::e2 , vxc_tmp.data (), 1 , v_eff.c , 1 );
170+ };
171+ break ;
172+ case SpinType::S2_triplet:
173+ funcs[s] = [this , &fxc](FXC_PARA_TYPE)->void
174+ {
175+ std::vector<ModuleBase::Vector3<double >> drho (nrxx); // transition density gradient
176+ LR_Util::grad (rho, drho.data (), this ->rho_basis_ , this ->tpiba_ );
177+
178+ std::vector<double > vxc_tmp (nrxx, 0.0 );
179+
180+ // 1. the terms in grad_dot int f_uu
181+ std::vector<ModuleBase::Vector3<double >> gdot_terms (nrxx);
182+ for (int ir = 0 ;ir < nrxx;++ir)
183+ {
184+ // gdot terms in f_uu
185+ gdot_terms[ir] = -(rho[ir] * fxc.v2rhosigma_drho_triplet .at (ir)
186+ + (fxc.drho_gs .at (0 ).at (ir) * drho.at (ir)) * fxc.v2sigma2_drho_triplet .at (ir)
187+ + drho.at (ir) * (fxc.vsigma .at (ir * 3 ) * 2 . - fxc.vsigma .at (ir * 3 + 1 )));
188+ }
189+ XC_Functional::grad_dot (gdot_terms.data (), vxc_tmp.data (), &this ->rho_basis_ , this ->tpiba_ );
190+
191+ // 2. terms not in grad_dot
192+ for (int ir = 0 ;ir < nrxx;++ir)
193+ {
194+ vxc_tmp[ir] += rho[ir] * (fxc.v2rho2 .at (ir * 3 ) - fxc.v2rho2 .at (ir * 3 + 1 ))
195+ + drho.at (ir) * fxc.v2rhosigma_drho_triplet .at (ir);
196+ }
197+ BlasConnector::axpy (nrxx, ModuleBase::e2 , vxc_tmp.data (), 1 , v_eff.c , 1 );
198+ };
199+ break ;
200+ case SpinType::S2_updown:
201+ funcs[s] = [this , &fxc](FXC_PARA_TYPE)->void
202+ {
203+ assert (ispin_op.size () >= 2 );
204+ std::vector<ModuleBase::Vector3<double >> drho (nrxx); // transition density gradient
205+ LR_Util::grad (rho, drho.data (), this ->rho_basis_ , this ->tpiba_ );
206+
207+ std::vector<double > vxc_tmp (nrxx, 0.0 );
208+
209+ // 1. the terms in grad_dot int f_uu
210+ std::vector<ModuleBase::Vector3<double >> gdot_terms (nrxx);
211+ switch (ispin_op[0 ] << 1 | ispin_op[1 ])
212+ {
213+ case 0 : // (0,0)
214+ for (int ir = 0 ;ir < nrxx;++ir)
215+ {
216+ gdot_terms[ir] = -(rho[ir] * fxc.v2rhosigma_drho_uu .at (ir)
217+ + (fxc.drho_gs .at (0 ).at (ir) * drho.at (ir)) * fxc.v2sigma2_drho_uu_u .at (ir)
218+ + (fxc.drho_gs .at (1 ).at (ir) * drho.at (ir)) * fxc.v2sigma2_drho_uu_d .at (ir)
219+ + drho.at (ir) * fxc.vsigma .at (ir * 3 ) * 2 .);
220+ }
221+ break ;
222+ case 1 : // (0,1)
223+ for (int ir = 0 ;ir < nrxx;++ir)
224+ {
225+ gdot_terms[ir] = -(rho[ir] * fxc.v2rhosigma_drho_du .at (ir) // rho_d, drho_u
226+ + (fxc.drho_gs .at (0 ).at (ir) * drho.at (ir)) * fxc.v2sigma2_drho_ud_u .at (ir)
227+ + (fxc.drho_gs .at (1 ).at (ir) * drho.at (ir)) * fxc.v2sigma2_drho_ud_d .at (ir)
228+ + drho.at (ir) * fxc.vsigma .at (ir * 3 + 1 ));
229+ }
230+ break ;
231+ case 2 : // (1,0)
232+ for (int ir = 0 ;ir < nrxx;++ir)
233+ {
234+ gdot_terms[ir] = -(rho[ir] * fxc.v2rhosigma_drho_ud .at (ir) // rho_u, drho_d
235+ + (fxc.drho_gs .at (0 ).at (ir) * drho.at (ir)) * fxc.v2sigma2_drho_du_u .at (ir)
236+ + (fxc.drho_gs .at (1 ).at (ir) * drho.at (ir)) * fxc.v2sigma2_drho_du_d .at (ir)
237+ + drho.at (ir) * fxc.vsigma .at (ir * 3 + 1 ));
238+ }
239+ break ;
240+ case 3 : // (1,1)
241+ for (int ir = 0 ;ir < nrxx;++ir)
242+ {
243+ gdot_terms[ir] = -(rho[ir] * fxc.v2rhosigma_drho_dd .at (ir)
244+ + (fxc.drho_gs .at (0 ).at (ir) * drho.at (ir)) * fxc.v2sigma2_drho_dd_u .at (ir)
245+ + (fxc.drho_gs .at (1 ).at (ir) * drho.at (ir)) * fxc.v2sigma2_drho_dd_d .at (ir)
246+ + drho.at (ir) * fxc.vsigma .at (ir * 3 + 2 ) * 2 .);
247+ }
248+ break ;
249+ default :
250+ throw std::runtime_error (" Invalid ispin_op" );
251+ }
252+ XC_Functional::grad_dot (gdot_terms.data (), vxc_tmp.data (), &this ->rho_basis_ , this ->tpiba_ );
253+
254+ // 2. terms not in grad_dot
255+ switch (ispin_op[0 ] << 1 | ispin_op[1 ])
256+ {
257+ case 0 :
258+ for (int ir = 0 ;ir < nrxx;++ir)
259+ {
260+ vxc_tmp[ir] += rho[ir] * fxc.v2rho2 .at (ir * 3 ) + drho.at (ir) * fxc.v2rhosigma_drho_uu .at (ir);
261+ }
262+ break ;
263+ case 1 :
264+ for (int ir = 0 ;ir < nrxx;++ir)
265+ {
266+ vxc_tmp[ir] += rho[ir] * fxc.v2rho2 .at (ir * 3 + 1 ) + drho.at (ir) * fxc.v2rhosigma_drho_ud .at (ir);
267+ }
268+ break ;
269+ case 2 :
270+ for (int ir = 0 ;ir < nrxx;++ir)
271+ {
272+ vxc_tmp[ir] += rho[ir] * fxc.v2rho2 .at (ir * 3 + 1 ) + drho.at (ir) * fxc.v2rhosigma_drho_du .at (ir);
273+ }
274+ break ;
275+ case 3 :
276+ for (int ir = 0 ;ir < nrxx;++ir)
277+ {
278+ vxc_tmp[ir] += rho[ir] * fxc.v2rho2 .at (ir * 3 + 2 ) + drho.at (ir) * fxc.v2rhosigma_drho_dd .at (ir);
279+ }
280+ break ;
281+ default :
282+ throw std::runtime_error (" Invalid ispin_op" );
283+ }
284+ BlasConnector::axpy (nrxx, ModuleBase::e2 , vxc_tmp.data (), 1 , v_eff.c , 1 );
285+ };
286+ break ;
148287 default :
149288 throw std::domain_error (" SpinType =" + std::to_string (static_cast <int >(s)) + " for GGA or HYB_GGA is unfinished in "
150289 + std::string (__FILE__) + " line " + std::to_string (__LINE__));
0 commit comments