@@ -51,6 +51,28 @@ XC_Functional_Libxc::convert_rho_amag_nspin4(
5151 return std::make_tuple (std::move (rho), std::move (amag));
5252}
5353
54+ std::vector<double > XC_Functional_Libxc::compute_mag_part_nspin4 (
55+ const std::size_t nrxx,
56+ const Charge* const chr)
57+ {
58+ std::vector<double > mag_part (3 * nrxx, 0.0 );
59+ #ifdef _OPENMP
60+ #pragma omp parallel for schedule(static, 1024)
61+ #endif
62+ for (std::size_t ir = 0 ; ir < nrxx; ++ir)
63+ {
64+ double mx = chr->rho [1 ][ir], my = chr->rho [2 ][ir], mz = chr->rho [3 ][ir];
65+ double amag = std::sqrt (mx * mx + my * my + mz * mz);
66+ if (amag > 1e-12 )
67+ {
68+ mag_part[ir] = mx / amag;
69+ mag_part[ir + nrxx] = my / amag;
70+ mag_part[ir + 2 * nrxx] = mz / amag;
71+ }
72+ }
73+ return mag_part;
74+ }
75+
5476// calculating grho
5577std::vector<std::vector<ModuleBase::Vector3<double >>>
5678XC_Functional_Libxc::cal_gdr (
@@ -213,22 +235,48 @@ std::pair<double,ModuleBase::matrix> XC_Functional_Libxc::convert_vtxc_v(
213235
214236 if (func.info ->family == XC_FAMILY_GGA || func.info ->family == XC_FAMILY_HYB_GGA )
215237 {
216- const std::vector<std::vector<double >> dh = XC_Functional_Libxc::cal_dh (nspin, nrxx, sgn, gdr, vsigma, tpiba, chr);
217-
218- double rvtxc = 0.0 ;
219- #ifdef _OPENMP
220- #pragma omp parallel for collapse(2) reduction(+:rvtxc) schedule(static, 256)
221- #endif
222- for ( int is=0 ; is<nspin; ++is )
238+ if (PARAM .inp .nspin ==4 && PARAM .inp .gga_grad >= 2 && (PARAM .globalv .domag || PARAM .globalv .domag_z ))
223239 {
224- for ( std::size_t ir=0 ; ir<nrxx; ++ir )
240+ std::vector<double > mag_part_tmp = XC_Functional_Libxc::compute_mag_part_nspin4 (nrxx, chr);
241+ const std::vector<std::vector<double >> dh = XC_Functional_Libxc::cal_dh_sf (nspin, nrxx, sgn, gdr, vsigma, mag_part_tmp, tpiba, chr);
242+
243+ constexpr int nspin4 = 4 ;
244+ double rvtxc = 0.0 ;
245+ #ifdef _OPENMP
246+ #pragma omp parallel for collapse(2) reduction(+:rvtxc) schedule(static, 256)
247+ #endif
248+ for (int is = 0 ; is < nspin4; ++is)
225249 {
226- rvtxc += dh[is][ir] * rho[ir*nspin+is];
227- v (is,ir) -= dh[is][ir];
250+ for (std::size_t ir = 0 ; ir < nrxx; ++ir)
251+ {
252+ double rho_ir = 0.0 ;
253+ if (is == 0 ) { rho_ir = rho[ir * nspin + 0 ]; }
254+ else { rho_ir = rho[ir * nspin + 0 ] * mag_part_tmp[ir + (is - 1 ) * nrxx]; }
255+ rvtxc += dh[is][ir] * rho_ir;
256+ v (is, ir) -= dh[is][ir];
257+ }
228258 }
259+ vtxc -= rvtxc;
229260 }
261+ else
262+ {
263+ const std::vector<std::vector<double >> dh = XC_Functional_Libxc::cal_dh (nspin, nrxx, sgn, gdr, vsigma, tpiba, chr);
264+
265+ double rvtxc = 0.0 ;
266+ #ifdef _OPENMP
267+ #pragma omp parallel for collapse(2) reduction(+:rvtxc) schedule(static, 256)
268+ #endif
269+ for ( int is=0 ; is<nspin; ++is )
270+ {
271+ for ( std::size_t ir=0 ; ir<nrxx; ++ir )
272+ {
273+ rvtxc += dh[is][ir] * rho[ir*nspin+is];
274+ v (is,ir) -= dh[is][ir];
275+ }
276+ }
230277
231- vtxc -= rvtxc;
278+ vtxc -= rvtxc;
279+ }
232280 } // end if(func.info->family == XC_FAMILY_GGA || func.info->family == XC_FAMILY_HYB_GGA))
233281
234282 return std::make_pair (vtxc, std::move (v));
@@ -317,4 +365,159 @@ ModuleBase::matrix XC_Functional_Libxc::convert_v_nspin4(
317365 return v_nspin4;
318366}
319367
368+ std::vector<std::vector<ModuleBase::Vector3<double >>> XC_Functional_Libxc::cal_gdr_sf (
369+ const int nspin,
370+ const std::size_t nrxx,
371+ const std::vector<double > &rho,
372+ const std::vector<double > &mag_part,
373+ const double tpiba,
374+ const Charge* const chr)
375+ {
376+ std::vector<std::vector<ModuleBase::Vector3<double >>> gdr (nspin);
377+ std::vector<double > rhor (nrxx);
378+ std::vector<std::complex <double >> rhog (chr->rhopw ->npw );
379+ std::vector<ModuleBase::Vector3<double >> gdr_tmp (nrxx);
380+
381+ #ifdef _OPENMP
382+ #pragma omp parallel for schedule(static, 1024)
383+ #endif
384+ for (std::size_t ir = 0 ; ir < nrxx; ++ir)
385+ {
386+ rhor[ir] = rho[ir * nspin + 0 ];
387+ }
388+ chr->rhopw ->real2recip (rhor.data (), rhog.data ());
389+ gdr[0 ].resize (nrxx);
390+ XC_Functional::grad_rho (rhog.data (), gdr[0 ].data (), chr->rhopw , tpiba);
391+
392+ gdr[1 ].resize (nrxx);
393+ #ifdef _OPENMP
394+ #pragma omp parallel for schedule(static, 1024)
395+ #endif
396+ for (std::size_t ir = 0 ; ir < nrxx; ++ir)
397+ {
398+ gdr_tmp[ir] = gdr[0 ][ir];
399+ gdr[0 ][ir] = 0.5 * gdr_tmp[ir];
400+ gdr[1 ][ir] = 0.5 * gdr_tmp[ir];
401+ }
402+
403+ for (int is = 1 ; is <= 3 ; ++is)
404+ {
405+ chr->rhopw ->real2recip (chr->rho [is], rhog.data ());
406+ XC_Functional::grad_rho (rhog.data (), gdr_tmp.data (), chr->rhopw , tpiba);
407+ const double * mp = mag_part.data () + (is - 1 ) * nrxx;
408+ #ifdef _OPENMP
409+ #pragma omp parallel for schedule(static, 1024)
410+ #endif
411+ for (std::size_t ir = 0 ; ir < nrxx; ++ir)
412+ {
413+ const ModuleBase::Vector3<double > g = 0.5 * gdr_tmp[ir] * mp[ir];
414+ gdr[0 ][ir] += g;
415+ gdr[1 ][ir] -= g;
416+ }
417+ }
418+
419+ return gdr;
420+ }
421+
422+ std::vector<std::vector<double >> XC_Functional_Libxc::cal_dh_sf (
423+ const int nspin,
424+ const std::size_t nrxx,
425+ const std::vector<double > &sgn,
426+ const std::vector<std::vector<ModuleBase::Vector3<double >>> &gdr,
427+ const std::vector<double > &vsigma,
428+ const std::vector<double > &mag_part,
429+ const double tpiba,
430+ const Charge* const chr)
431+ {
432+ std::vector<ModuleBase::Vector3<double >> h1 (nrxx), h2 (nrxx);
433+ #ifdef _OPENMP
434+ #pragma omp parallel for schedule(static, 1024)
435+ #endif
436+ for (std::size_t ir = 0 ; ir < nrxx; ++ir)
437+ {
438+ h1[ir] = 2.0 * (gdr[0 ][ir] * vsigma[ir*3 ] * sgn[ir*2 ] * 2.0
439+ + gdr[1 ][ir] * vsigma[ir*3 +1 ] * sgn[ir*2 ] * sgn[ir*2 +1 ]);
440+ h2[ir] = 2.0 * (gdr[1 ][ir] * vsigma[ir*3 +2 ] * sgn[ir*2 +1 ] * 2.0
441+ + gdr[0 ][ir] * vsigma[ir*3 +1 ] * sgn[ir*2 ] * sgn[ir*2 +1 ]);
442+ }
443+
444+ std::vector<ModuleBase::Vector3<double >> tmp_h (nrxx);
445+ std::vector<double > dh0 (nrxx), dh_mu (nrxx);
446+
447+ #ifdef _OPENMP
448+ #pragma omp parallel for schedule(static, 1024)
449+ #endif
450+ for (std::size_t ir = 0 ; ir < nrxx; ++ir)
451+ {
452+ tmp_h[ir] = 0.5 * (h1[ir] + h2[ir]);
453+ }
454+ XC_Functional::grad_dot (tmp_h.data (), dh0.data (), chr->rhopw , tpiba);
455+
456+ std::vector<std::vector<double >> dh_total (4 , std::vector<double >(nrxx, 0.0 ));
457+ #ifdef _OPENMP
458+ #pragma omp parallel for schedule(static, 1024)
459+ #endif
460+ for (std::size_t ir = 0 ; ir < nrxx; ++ir)
461+ {
462+ dh_total[0 ][ir] = dh0[ir];
463+ }
464+
465+ for (int mu = 1 ; mu < 4 ; ++mu)
466+ {
467+ const double * mp_mu = mag_part.data () + (mu - 1 ) * nrxx;
468+ #ifdef _OPENMP
469+ #pragma omp parallel for schedule(static, 1024)
470+ #endif
471+ for (std::size_t ir = 0 ; ir < nrxx; ++ir)
472+ {
473+ tmp_h[ir] = 0.5 * (h1[ir] - h2[ir]) * mp_mu[ir];
474+ }
475+ XC_Functional::grad_dot (tmp_h.data (), dh_mu.data (), chr->rhopw , tpiba);
476+ #ifdef _OPENMP
477+ #pragma omp parallel for schedule(static, 1024)
478+ #endif
479+ for (std::size_t ir = 0 ; ir < nrxx; ++ir)
480+ {
481+ dh_total[mu][ir] = dh_mu[ir];
482+ }
483+ }
484+
485+ return dh_total;
486+ }
487+
488+ ModuleBase::matrix XC_Functional_Libxc::convert_v_nspin4_sf (
489+ const std::size_t nrxx,
490+ const Charge* const chr,
491+ const std::vector<double > &mag_part,
492+ const ModuleBase::matrix &v)
493+ {
494+ assert (PARAM .inp .nspin ==4 );
495+ constexpr double vanishing_charge = 1.0e-10 ;
496+ ModuleBase::matrix v_nspin4 (PARAM .inp .nspin , nrxx);
497+
498+ for (std::size_t ir = 0 ; ir < nrxx; ++ir)
499+ {
500+ v_nspin4 (0 , ir) = 0.5 * (v (0 , ir) + v (1 , ir));
501+ }
502+
503+ if (PARAM .globalv .domag || PARAM .globalv .domag_z )
504+ {
505+ for (std::size_t ir = 0 ; ir < nrxx; ++ir)
506+ {
507+ double amag = std::sqrt (std::pow (chr->rho [1 ][ir], 2 )
508+ + std::pow (chr->rho [2 ][ir], 2 )
509+ + std::pow (chr->rho [3 ][ir], 2 ));
510+ if (amag > vanishing_charge)
511+ {
512+ const double vs = 0.5 * (v (0 , ir) - v (1 , ir));
513+ for (int ipol = 1 ; ipol < PARAM .inp .nspin ; ++ipol)
514+ {
515+ v_nspin4 (ipol, ir) = vs * mag_part[ir + (ipol - 1 ) * nrxx];
516+ }
517+ }
518+ }
519+ }
520+ return v_nspin4;
521+ }
522+
320523#endif
0 commit comments