1515#include < xc.h>
1616
1717#include < vector>
18+ #include < complex>
1819
1920std::tuple<double ,double ,ModuleBase::matrix> XC_Functional_Libxc::v_xc_libxc ( // Peize Lin update for nspin==4 at 2023.01.14
2021 const std::vector<int > &func_id,
@@ -225,13 +226,12 @@ std::tuple<double,double,ModuleBase::matrix,ModuleBase::matrix> XC_Functional_Li
225226 ModuleBase::TITLE (" XC_Functional_Libxc" ," v_xc_meta" );
226227 ModuleBase::timer::start (" XC_Functional_Libxc" ," v_xc_meta" );
227228
228- double e2 = 2.0 ;
229-
230229 // output of the subroutine
231230 double etxc = 0.0 ;
232231 double vtxc = 0.0 ;
233232 ModuleBase::matrix v (nspin,nrxx);
234233 ModuleBase::matrix vofk (nspin,nrxx);
234+ ModuleBase::matrix voflapl (nspin,nrxx);
235235
236236 // ----------------------------------------------------------
237237 // xc_func_type is defined in Libxc package
@@ -246,8 +246,10 @@ std::tuple<double,double,ModuleBase::matrix,ModuleBase::matrix> XC_Functional_Li
246246 /* hse_omega = */ hse_omega);
247247
248248 const std::vector<double > rho = XC_Functional_Libxc::convert_rho (nspin, nrxx, chr);
249- const std::vector<std::vector<ModuleBase::Vector3<double >>> gdr
250- = XC_Functional_Libxc::cal_gdr (nspin, nrxx, rho, tpiba, chr);
249+ const bool need_laplacian = XC_Functional::get_need_laplacian ();
250+ std::vector<std::vector<ModuleBase::Vector3<double >>> gdr;
251+ std::vector<double > lapl;
252+ XC_Functional_Libxc::cal_gdr_and_lapl (nspin, nrxx, rho, tpiba, chr, gdr, lapl, need_laplacian);
251253 const std::vector<double > sigma = XC_Functional_Libxc::convert_sigma (gdr);
252254
253255 // converting kin_r
@@ -328,7 +330,7 @@ std::tuple<double,double,ModuleBase::matrix,ModuleBase::matrix> XC_Functional_Li
328330 nrxx_thread,
329331 rho.data () + ir_start * nspin,
330332 sigma.data () + ir_start * ((1 ==nspin)?1 :3 ),
331- sigma .data () + ir_start * (( 1 == nspin)? 1 : 3 ) ,
333+ lapl .data () + ir_start * nspin,
332334 kin_r.data () + ir_start * nspin,
333335 exc.data () + ir_start,
334336 vrho.data () + ir_start * nspin,
@@ -441,7 +443,7 @@ std::tuple<double,double,ModuleBase::matrix,ModuleBase::matrix> XC_Functional_Li
441443 }
442444 vtxc -= rvtxc;
443445
444- // process vtau
446+ // process vtau and vlapl
445447#ifdef _OPENMP
446448#pragma omp parallel for collapse(2) schedule(static, 1024)
447449#endif
@@ -453,9 +455,41 @@ std::tuple<double,double,ModuleBase::matrix,ModuleBase::matrix> XC_Functional_Li
453455 if (func.info ->number == XC_MGGA_X_SCAN && XC_Functional::get_func_type () == 5 )
454456 {
455457 vtau[ir*nspin+is] *= (1.0 - XC_Functional::get_hybrid_alpha ());
458+ vlapl[ir*nspin+is] *= (1.0 - XC_Functional::get_hybrid_alpha ());
456459 }
457460#endif
458461 vofk (is,ir) += vtau[ir*nspin+is] * sgn[ir*nspin+is];
462+ voflapl (is,ir) += vlapl[ir*nspin+is] * sgn[ir*nspin+is];
463+ }
464+ }
465+ }
466+
467+ // v_xc += nabla^2(vlapl) where vlapl = d(rho*eps_xc)/d(nabla^2 rho)
468+ if (need_laplacian)
469+ {
470+ const int ng = chr->rhopw ->npw ;
471+ const double tpiba2 = tpiba * tpiba;
472+ std::vector<std::complex <double >> lapl_tmp (chr->rhopw ->nmaxgr );
473+ for (int is = 0 ; is < voflapl.nr ; is++)
474+ {
475+ for (int ir = 0 ; ir < nrxx; ir++)
476+ lapl_tmp[ir] = std::complex <double >(voflapl (is, ir), 0.0 );
477+ for (int ig = ng; ig < chr->rhopw ->nmaxgr ; ig++)
478+ lapl_tmp[ig] = std::complex <double >(0.0 , 0.0 );
479+ chr->rhopw ->real2recip (lapl_tmp.data (), lapl_tmp.data ());
480+ for (int ig = 0 ; ig < ng; ig++)
481+ {
482+ double g2 = 0.0 ;
483+ for (int i = 0 ; i < 3 ; i++)
484+ g2 += chr->rhopw ->gcar [ig][i] * chr->rhopw ->gcar [ig][i];
485+ lapl_tmp[ig] *= -g2 * tpiba2;
486+ }
487+ chr->rhopw ->recip2real (lapl_tmp.data (), lapl_tmp.data ());
488+ for (int ir = 0 ; ir < nrxx; ir++)
489+ {
490+ double vlapl_corr = ModuleBase::e2 * lapl_tmp[ir].real ();
491+ v (is, ir) += vlapl_corr;
492+ vtxc += vlapl_corr * chr->rho [is][ir];
459493 }
460494 }
461495 }
0 commit comments