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