20 #ifndef JDFTX_ELECTRONIC_EXCORR_INTERNAL_LDA_H 21 #define JDFTX_ELECTRONIC_EXCORR_INTERNAL_LDA_H 81 void evaluate(
int N, std::vector<const double*> n, std::vector<const double*> sigma,
82 std::vector<const double*> lap, std::vector<const double*> tau,
83 double* E, std::vector<double*> E_n, std::vector<double*> E_sigma,
84 std::vector<double*> E_lap, std::vector<double*> E_tau)
const;
94 #define SwitchTemplate_LDA(variant,nCount, fTemplate,argList) \ 96 { case LDA_X_Slater: fTemplate< LDA_X_Slater, nCount> argList; break; \ 97 case LDA_C_PZ: fTemplate< LDA_C_PZ, nCount> argList; break; \ 98 case LDA_C_PW: fTemplate< LDA_C_PW, nCount> argList; break; \ 99 case LDA_C_PW_prec: fTemplate< LDA_C_PW_prec, nCount> argList; break; \ 100 case LDA_C_VWN: fTemplate< LDA_C_VWN, nCount> argList; break; \ 101 case LDA_XC_Teter: fTemplate< LDA_XC_Teter, nCount> argList; break; \ 102 case LDA_KE_TF: fTemplate< LDA_KE_TF, nCount> argList; break; \ 108 template<LDA_Variant variant> __hostanddev__
109 double LDA_eval(
double rs,
double zeta,
double& e_rs,
double& e_zeta);
114 template<LDA_Variant variant,
int nCount>
struct LDA_calc 115 { __hostanddev__
static 118 double nTot = (nCount==1) ? n[0][i] : n[0][i]+n[1][i];
119 if(nTot<nCutoff)
return;
120 double rs =
pow((4.*M_PI/3.)*nTot, (-1./3));
123 double zeta = (nCount==1) ? 0. : (n[0][i] - n[1][i])/nTot;
124 double e_rs, e_zeta, e = LDA_eval<variant>(rs, zeta, e_rs, e_zeta);
128 {
double e_nTot = -e_rs * rs / (3. * nTot);
129 double E_nTot = e + nTot * e_nTot;
130 E_n[0][i] += scaleFac*( E_nTot - e_zeta * (zeta-1) );
131 if(nCount>1) E_n[1][i] += scaleFac*( E_nTot - e_zeta * (zeta+1) );
133 E[i] += scaleFac*( nTot * e );
139 { __hostanddev__
static 142 const double KEprefac = (0.3/nCount)*
pow(3*M_PI*M_PI, 2./3.);
143 for(
int s=0; s<nCount; s++)
144 {
double ns = n[s][i] * nCount;
145 double nsTo23 =
pow(ns, 2./3.);
146 E[i] += scaleFac*( KEprefac * nsTo23 * ns );
148 E_n[s][i] += scaleFac*( (nCount * KEprefac * 5./3.) * nsTo23 );
155 { __hostanddev__
static 158 const double Xprefac = (-0.75/nCount) *
pow(3./M_PI, 1./3);
159 for(
int s=0; s<nCount; s++)
160 {
double ns = n[s][i] * nCount;
161 double nsCbrt =
pow(ns, 1./3);
162 E[i] += scaleFac*( Xprefac * nsCbrt * ns );
164 E_n[s][i] += scaleFac*( (nCount * Xprefac * 4./3) * nsCbrt );
174 { __hostanddev__
double operator()(
double rs,
double& e_rs)
const 176 {
const double a = para ? 0.0311 : 0.01555;
177 const double b = para ? -0.0480 : -0.0269;
178 const double c = para ? 0.0020 : 0.0007;
179 const double d = para ? -0.0116 : -0.0048;
180 e_rs = a/rs + c*(1+
log(rs)) + d;
181 return (a + c*rs) *
log(rs) + b + d*rs;
184 {
const double gamma = para ? -0.1423 : -0.0843;
185 const double beta1 = para ? 1.0529 : 1.3981;
186 const double beta2 = para ? 0.3334 : 0.2611;
187 double denInv = 1./(1. + beta1*
sqrt(rs) + beta2*rs);
188 double denPrime = beta1/(2.*
sqrt(rs)) + beta2;
189 e_rs = gamma * (-denInv*denInv) * denPrime;
190 return gamma * denInv;
195 template<> __hostanddev__
204 { __hostanddev__
double operator()(
double rs,
double& e_rs)
const 206 const double A = prec
207 ? ( (spinID==0) ? 0.0310907 : ((spinID==1) ? 0.01554535 : 0.0168869) )
208 : ( (spinID==0) ? 0.031091 : ((spinID==1) ? 0.015545 : 0.016887) );
209 const double alpha = (spinID==0) ? 0.21370 : ((spinID==1) ? 0.20548 : 0.11125);
210 const double beta1 = (spinID==0) ? 7.5957 : ((spinID==1) ? 14.1189 : 10.357);
211 const double beta2 = (spinID==0) ? 3.5876 : ((spinID==1) ? 6.1977 : 3.6231);
212 const double beta3 = (spinID==0) ? 1.6382 : ((spinID==1) ? 3.3662 : 0.88026);
213 const double beta4 = (spinID==0) ? 0.49294 : ((spinID==1) ? 0.62517 : 0.49671);
216 double den = (2*A)*x*(beta1 + x*(beta2 + x*(beta3 + x*(beta4))));
217 double den_x = (2*A)*(beta1 + x*(2*beta2 + x*(3*beta3 + x*(4*beta4))));
218 double den_rs = den_x * 0.5/x;
220 double logTerm =
log(1.+1./den);
221 double logTerm_rs = -den_rs/(den*(1.+den));
223 e_rs = -(2*A) * (alpha * logTerm + (1+alpha*rs) * logTerm_rs);
224 return -(2*A) * (1+alpha*rs) * logTerm;
228 template<> __hostanddev__
235 template<> __hostanddev__
245 { __hostanddev__
double operator()(
double rs,
double& e_rs)
const 247 const double A = (spinID==0) ? 0.0310907 : ((spinID==1) ? 0.01554535 : 1./(6.*M_PI*M_PI));
248 const double b = (spinID==0) ? 3.72744 : ((spinID==1) ? 7.06042 : 1.13107);
249 const double c = (spinID==0) ? 12.9352 : ((spinID==1) ? 18.0578 : 13.0045);
250 const double x0 = (spinID==0) ? -0.10498 : ((spinID==1) ? -0.32500 : -0.0047584);
251 const double X0 = c + x0*(b + x0);
252 const double Q =
sqrt(4.*c - b*b);
254 double X = c + x*(b + x);
255 double X_x = 2*x + b;
257 double atanTerm = (2./Q) * atan(Q/X_x), atanTerm_x = -4./(Q*Q + X_x*X_x);
258 double logTerm1 =
log(x*x/X), logTerm1_x = 2./x - X_x/X;
259 double logTerm2 =
log((x-x0)*(x-x0)/X), logTerm2_x = 2./(x-x0) - X_x/X;
261 double e = A*(logTerm1 + b * (atanTerm - (x0/X0)*(logTerm2 + (b+2*x0) * atanTerm)));
262 double e_x = A*(logTerm1_x + b * (atanTerm_x - (x0/X0)*(logTerm2_x + (b+2*x0) * atanTerm_x)));
268 template<> __hostanddev__
276 template<> __hostanddev__
279 const double pa0 = 0.4581652932831429 , da0 = 0.119086804055547;
280 const double pa1 = 2.217058676663745 , da1 = 0.6157402568883345;
281 const double pa2 = 0.7405551735357053 , da2 = 0.1574201515892867;
282 const double pa3 = 0.01968227878617998, da3 = 0.003532336663397157;
283 const double pb2 = 4.504130959426697 , db2 = 0.2673612973836267;
284 const double pb3 = 1.110667363742916 , db3 = 0.2052004607777787;
285 const double pb4 = 0.02359291751427506, db4 = 0.004200005045691381;
288 double a0 = pa0 + f * da0;
289 double a1 = pa1 + f * da1;
290 double a2 = pa2 + f * da2;
291 double a3 = pa3 + f * da3;
292 double b2 = pb2 + f * db2;
293 double b3 = pb3 + f * db3;
294 double b4 = pb4 + f * db4;
296 double num = a0 + rs*(a1 + rs*(a2 + rs*(a3)));
297 double den = rs*(1. + rs*(b2 + rs*(b3 + rs*(b4))));
298 double num_rs = a1 + rs*(2*a2 + rs*(3*a3));
299 double den_rs = 1. + rs*(2*b2 + rs*(3*b3 + rs*(4*b4)));
300 double num_f = da0 + rs*(da1 + rs*(da2 + rs*(da3)));
301 double den_f = rs*rs*(db2 + rs*(db3 + rs*(db4)));
302 e_rs = (num*den_rs - den*num_rs)/(den*den);
303 e_zeta = (num*den_f - den*num_f)*f_zeta/(den*den);
307 #endif // JDFTX_ELECTRONIC_EXCORR_INTERNAL_LDA_H ScalarField pow(const ScalarField &, double alpha)
Elementwise power (preserve input)
ScalarField sqrt(const ScalarField &)
Elementwise square root (preserve input)
bool needsSigma() const
return true if density gradients are used
Definition: ExCorr_internal_LDA.h:44
Definition: ExCorr_internal_LDA.h:244
LDA_Variant
Available LDA functionals.
Definition: ExCorr_internal_LDA.h:29
__hostanddev__ double LDA_eval< LDA_XC_Teter >(double rs, double zeta, double &e_rs, double &e_zeta)
Teter LSD exchange & correlation [Phys. Rev. B 54, 1703 (1996)].
Definition: ExCorr_internal_LDA.h:277
double scaleFac
scale factor (to support mixing for hybrid functionals)
Definition: ExCorr_internal.h:45
bool hasEnergy() const
whether total energy is meaningful for this functional
Definition: ExCorr_internal_LDA.h:76
__hostanddev__ double spinInterpolation(double zeta, double &f_zeta)
LDA spin interpolation function f(zeta) and its derivative.
Definition: ExCorr_internal.h:128
Vosko-Wilk-Nusair LDA correlation.
Definition: ExCorr_internal_LDA.h:34
__hostanddev__ double LDA_eval(double rs, double zeta, double &e_rs, double &e_zeta)
Perdew-Wang LDA correlation.
Definition: ExCorr_internal_LDA.h:32
Definition: ExCorr_internal_LDA.h:114
LDA exchange (Slater functional)
Definition: ExCorr_internal_LDA.h:30
ScalarField log(const ScalarField &)
Elementwise logarithm (preserve input)
void evaluate(int N, std::vector< const double * > n, std::vector< const double * > sigma, std::vector< const double * > lap, std::vector< const double * > tau, double *E, std::vector< double * > E_n, std::vector< double * > E_sigma, std::vector< double * > E_lap, std::vector< double * > E_tau) const
Definition: operators_internal.h:37
bool needsLap() const
return true if laplacian of density is used (MGGA)
Definition: ExCorr_internal_LDA.h:45
Definition: ExCorr_internal_LDA.h:173
bool hasKinetic() const
whether this functional includes kinetic energy
Definition: ExCorr_internal_LDA.h:68
Abstract base class for functionals.
Definition: ExCorr_internal.h:42
__hostanddev__ double LDA_eval< LDA_C_PW >(double rs, double zeta, double &e_rs, double &e_zeta)
Perdew-Wang correlation (original version, for numerical compatibility with LibXC's PW91) ...
Definition: ExCorr_internal_LDA.h:229
Common interface to the compute kernels shared by all LDA functionals.
Definition: ExCorr_internal_LDA.h:40
Perdew-Wang LDA correlation (with higher precision constants used in PBE)
Definition: ExCorr_internal_LDA.h:33
bool hasCorrelation() const
whether this functional includes correlation
Definition: ExCorr_internal_LDA.h:56
__hostanddev__ double spinInterpolate(double rs, double zeta, double &e_rs, double &e_zeta, const Para ¶, const Ferro &ferro)
Spin-interpolate an LDA functional given its paramagnetic and ferromagnetic functors.
Definition: ExCorr_internal.h:138
Perdew-Zunger LDA correlation.
Definition: ExCorr_internal_LDA.h:31
__hostanddev__ double LDA_eval< LDA_C_VWN >(double rs, double zeta, double &e_rs, double &e_zeta)
Vosko-Wilk-Nusair correlation.
Definition: ExCorr_internal_LDA.h:269
bool needsTau() const
return true if orbital kinetic energy density is used (MGGA)
Definition: ExCorr_internal_LDA.h:46
__hostanddev__ double LDA_eval< LDA_C_PW_prec >(double rs, double zeta, double &e_rs, double &e_zeta)
Perdew-Wang correlation (extended precision version, for numerical compatibility with LibXC's PBE) ...
Definition: ExCorr_internal_LDA.h:236
Definition: ExCorr_internal_LDA.h:203
Teter LDA exchange and correlation.
Definition: ExCorr_internal_LDA.h:35
Thomas-Fermi kinetic energy functional.
Definition: ExCorr_internal_LDA.h:36
__hostanddev__ double LDA_eval< LDA_C_PZ >(double rs, double zeta, double &e_rs, double &e_zeta)
Perdew-Zunger correlation.
Definition: ExCorr_internal_LDA.h:196
bool hasExchange() const
whether this functional includes exchange
Definition: ExCorr_internal_LDA.h:47