JDFTx  1.2.0
ExCorr_internal_GGA.h
Go to the documentation of this file.
1 /*-------------------------------------------------------------------
2 Copyright 2012 Ravishankar Sundararaman, Kendra Letchworth Weaver
3 
4 This file is part of JDFTx.
5 
6 JDFTx is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10 
11 JDFTx is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with JDFTx. If not, see <http://www.gnu.org/licenses/>.
18 -------------------------------------------------------------------*/
19 
20 #ifndef JDFTX_ELECTRONIC_EXCORR_INTERNAL_GGA_H
21 #define JDFTX_ELECTRONIC_EXCORR_INTERNAL_GGA_H
22 
24 
27 
41 };
42 
44 class FunctionalGGA : public Functional
45 {
46 public:
47  FunctionalGGA(GGA_Variant variant, double scaleFac=1.0);
48  bool needsSigma() const { return true; }
49  bool needsLap() const { return false; }
50  bool needsTau() const { return false; }
51  bool hasExchange() const
52  { switch(variant)
53  { case GGA_X_PBE:
54  case GGA_X_PBEsol:
55  case GGA_X_PW91:
56  case GGA_X_wPBE_SR:
57  case GGA_X_GLLBsc:
58  case GGA_X_LB94:
59  return true;
60  default:
61  return false;
62  }
63  }
64  bool hasCorrelation() const
65  { switch(variant)
66  { case GGA_C_PBE:
67  case GGA_C_PBEsol:
68  case GGA_C_PW91:
69  return true;
70  default:
71  return false;
72  }
73  }
74  bool hasKinetic() const
75  { switch(variant)
76  { case GGA_KE_VW:
77  case GGA_KE_PW91:
78  return true;
79  default:
80  return false;
81  }
82  }
83  bool hasEnergy() const
84  { switch(variant)
85  { case GGA_X_GLLBsc:
86  return false;
87  default:
88  return true;
89  }
90  }
91 
95  void evaluate(int N, std::vector<const double*> n, std::vector<const double*> sigma,
96  std::vector<const double*> lap, std::vector<const double*> tau,
97  double* E, std::vector<double*> E_n, std::vector<double*> E_sigma,
98  std::vector<double*> E_lap, std::vector<double*> E_tau) const;
99 
100 private:
101  GGA_Variant variant;
102 };
103 
109 #define SwitchTemplate_GGA(variant,nCount, fTemplate,argList) \
110  switch(variant) \
111  { case GGA_X_PBE: fTemplate< GGA_X_PBE, true, nCount> argList; break; \
112  case GGA_C_PBE: fTemplate< GGA_C_PBE, false, nCount> argList; break; \
113  case GGA_X_PBEsol: fTemplate< GGA_X_PBEsol, true, nCount> argList; break; \
114  case GGA_C_PBEsol: fTemplate< GGA_C_PBEsol, false, nCount> argList; break; \
115  case GGA_X_PW91: fTemplate< GGA_X_PW91, true, nCount> argList; break; \
116  case GGA_C_PW91: fTemplate< GGA_C_PW91, false, nCount> argList; break; \
117  case GGA_X_wPBE_SR: fTemplate< GGA_X_wPBE_SR, true, nCount> argList; break; \
118  case GGA_X_GLLBsc: fTemplate< GGA_X_GLLBsc, true, nCount> argList; break; \
119  case GGA_X_LB94: fTemplate< GGA_X_LB94, true, nCount> argList; break; \
120  case GGA_KE_VW: fTemplate< GGA_KE_VW, true, nCount> argList; break; \
121  case GGA_KE_PW91: fTemplate< GGA_KE_PW91, true, nCount> argList; break; \
122  default: break; \
123  }
124 
125 
128 template<GGA_Variant variant> __hostanddev__
129 double GGA_eval(double rs, double s2, double& e_rs, double& e_s2);
130 
134 template<GGA_Variant variant> __hostanddev__
135 double GGA_eval(double rs, double zeta, double g, double t2,
136  double& e_rs, double& e_zeta, double& e_g, double& e_t2);
137 
141 template<GGA_Variant variant, bool spinScaling, int nCount> struct GGA_calc;
142 
144 template<GGA_Variant variant, int nCount>
145 struct GGA_calc <variant, true, nCount>
146 { __hostanddev__ static
148  double* E, array<double*,nCount> E_n, array<double*,2*nCount-1> E_sigma, double scaleFac)
149  { //Each spin component is computed separately:
150  for(int s=0; s<nCount; s++)
151  { //Scale up s-density and gradient:
152  double ns = n[s][i] * nCount;
153  if(ns < nCutoff) continue;
154  //Compute dimensionless quantities rs and s2:
155  double rs = pow((4.*M_PI/3.)*ns, (-1./3));
156  double s2_sigma = pow(ns, -8./3) * ((0.25*nCount*nCount) * pow(3.*M_PI*M_PI, -2./3));
157  double s2 = s2_sigma * sigma[2*s][i];
158  //Compute energy density and its gradients using GGA_eval:
159  double e_rs, e_s2, e = GGA_eval<variant>(rs, s2, e_rs, e_s2);
160  //Compute gradients if required:
161  if(E_n[0])
162  { //Propagate s and rs gradients to n and sigma:
163  double e_n = -(e_rs*rs + 8*e_s2*s2) / (3. * n[s][i]);
164  double e_sigma = e_s2 * s2_sigma;
165  //Convert form per-particle to per volume:
166  E_n[s][i] += scaleFac*( n[s][i] * e_n + e );
167  E_sigma[2*s][i] += scaleFac*( n[s][i] * e_sigma );
168  }
169  E[i] += scaleFac*( n[s][i] * e );
170  }
171  }
172 };
173 
175 template<GGA_Variant variant, int nCount>
176 struct GGA_calc <variant, false, nCount>
177 { __hostanddev__ static
179  double* E, array<double*,nCount> E_n, array<double*,2*nCount-1> E_sigma, double scaleFac)
180  {
181  //Compute nTot and rs, and ignore tiny densities:
182  double nTot = (nCount==1) ? n[0][i] : n[0][i]+n[1][i];
183  if(nTot<nCutoff) return;
184  double rs = pow((4.*M_PI/3.)*nTot, (-1./3));
185 
186  //Compute zeta, g(zeta) and dimensionless gradient squared t2:
187  double zeta = (nCount==1) ? 0. : (n[0][i] - n[1][i])/nTot;
188  double g = 0.5*(pow(1+zeta, 2./3) + pow(1-zeta, 2./3));
189  double t2_sigma = (pow(M_PI/3, 1./3)/16.) * pow(nTot,-7./3) / (g*g);
190  double t2 = t2_sigma * ((nCount==1) ? sigma[0][i] : sigma[0][i]+2*sigma[1][i]+sigma[2][i]);
191 
192  //Compute per-particle energy and derivatives:
193  double e_rs, e_zeta, e_g, e_t2;
194  double e = GGA_eval<variant>(rs, zeta, g, t2, e_rs, e_zeta, e_g, e_t2);
195 
196  //Compute and store final n/sigma derivatives if required
197  if(E_n[0])
198  { double e_nTot = -(e_rs*rs + 7.*e_t2*t2) / (3.*nTot); //propagate rs and t2 derivatives to nTot
199  double e_sigma = e_t2 * t2_sigma; //derivative w.r.t |DnTot|^2
200 
201  double g_zeta = (1./3) * //Avoid singularities at zeta = +/- 1:
202  ( (1+zeta > nCutoff ? pow(1+zeta, -1./3) : 0.)
203  - (1-zeta > nCutoff ? pow(1-zeta, -1./3) : 0.) );
204  e_zeta += (e_g - 2. * e_t2*t2 / g) * g_zeta;
205 
206  double E_nTot = e + nTot * e_nTot;
207  E_n[0][i] += scaleFac*( E_nTot - e_zeta * (zeta-1) );
208  E_sigma[0][i] += scaleFac*( (nTot * e_sigma));
209  if(nCount>1)
210  { E_n[1][i] += scaleFac*( E_nTot - e_zeta * (zeta+1) );
211  E_sigma[1][i] += scaleFac*( (nTot * e_sigma) * 2 );
212  E_sigma[2][i] += scaleFac*( (nTot * e_sigma) );
213  }
214  }
215  E[i] += scaleFac*( nTot * e ); //energy density per volume
216  }
217 };
218 
219 
220 //---------------------- GGA exchange implementations ---------------------------
221 
223 __hostanddev__ double slaterExchange(double rs, double& e_rs)
224 {
225  double rsInvMinus = -1./rs;
226  double e = rsInvMinus * (0.75*pow(1.5/M_PI, 2./3));
227  e_rs = rsInvMinus * e;
228  return e;
229 }
230 
232 __hostanddev__ double GGA_PBE_exchange(const double kappa, const double mu,
233  double rs, double s2, double& e_rs, double& e_s2)
234 { //Slater exchange:
235  double eSlater_rs, eSlater = slaterExchange(rs, eSlater_rs);
236  //PBE Enhancement factor:
237  const double kappaByMu = kappa/mu;
238  double frac = -1./(kappaByMu + s2);
239  double F = 1+kappa + (kappa*kappaByMu) * frac;
240  double F_s2 = (kappa*kappaByMu) * frac * frac;
241  //GGA result:
242  e_rs = eSlater_rs * F;
243  e_s2 = eSlater * F_s2;
244  return eSlater * F;
245 }
246 
248 template<> __hostanddev__ double GGA_eval<GGA_X_PBE>(double rs, double s2, double& e_rs, double& e_s2)
249 { return GGA_PBE_exchange(0.804, 0.2195149727645171, rs, s2, e_rs, e_s2);
250 }
251 
253 template<> __hostanddev__ double GGA_eval<GGA_X_PBEsol>(double rs, double s2, double& e_rs, double& e_s2)
254 { return GGA_PBE_exchange(0.804, 10./81, rs, s2, e_rs, e_s2);
255 }
256 
257 
261 __hostanddev__ double GGA_PW91_Enhancement(double s2, double& F_s2,
262  const double P, const double Q, const double R, const double S, const double T, const double U)
263 { //-- Transcendental pieces and derivatives:
264  double s = sqrt(s2);
265  double asinhTerm = P * s * asinh(Q*s);
266  double asinhTerm_s2 = (s2 ? 0.5*(asinhTerm/s2 + (P*Q)/sqrt(1+(Q*Q)*s2)) : P*Q);
267  double gaussTerm = S * exp(-T*s2);
268  double gaussTerm_s2 = -T * gaussTerm;
269  //-- Numerator and denominator of equation (8) and derivatives:
270  double num = 1. + asinhTerm + s2*(R - gaussTerm);
271  double num_s2 = asinhTerm_s2 + (R - gaussTerm) - s2 * gaussTerm_s2;
272  double den = 1 + asinhTerm + U*s2*s2;
273  double den_s2 = asinhTerm_s2 + 2*U*s2;
274  //-- Put together enhancement factor and derivative w.r.t s2:
275  F_s2 = (num_s2*den - num*den_s2)/(den*den);
276  return num/den;
277 }
278 
280 template<> __hostanddev__ double GGA_eval<GGA_X_PW91>(double rs, double s2, double& e_rs, double& e_s2)
281 { //Slater exchange:
282  double eSlater_rs, eSlater = slaterExchange(rs, eSlater_rs);
283  //Enhancement factor:
284  //-- Fit parameters in order of appearance in equation (8) of reference
285  const double P = 0.19645; //starting at P for PW91 :D
286  const double Q = 7.7956;
287  const double R = 0.2743;
288  const double S = 0.1508;
289  const double T = 100.;
290  const double U = 0.004;
291  double F_s2, F = GGA_PW91_Enhancement(s2, F_s2, P,Q,R,S,T,U);
292  //GGA result:
293  e_rs = eSlater_rs * F;
294  e_s2 = eSlater * F_s2;
295  return eSlater * F;
296 }
297 
298 
299 
301 template<int n> __hostanddev__
302 double integralErfcGaussian(double A, double B, double& result_A, double& result_B);
303 
304 template<> __hostanddev__
305 double integralErfcGaussian<1>(double A, double B, double& result_A, double& result_B)
306 { double invApBsq = 1./(A + B*B);
307  double invsqrtApBsq = sqrt(invApBsq); //(A+B^2) ^ (-1/2)
308  double inv3sqrtApBsq = invsqrtApBsq * invApBsq; //(A+B^2) ^ (-3/2)
309  double invA = 1./A;
310  result_A = (B*(1.5*A + B*B)*inv3sqrtApBsq - 1.) * 0.5*invA*invA;
311  result_B = -0.5 * inv3sqrtApBsq;
312  return (1. - B*invsqrtApBsq) * 0.5*invA;
313 }
314 
315 template<> __hostanddev__
316 double integralErfcGaussian<2>(double A, double B, double& result_A, double& result_B)
317 { const double invsqrtPi = 1./sqrt(M_PI);
318  double invApBsq = 1./(A + B*B);
319  double invA = 1./A;
320  double atanTerm = atan(sqrt(A)/B)*invA/sqrt(A);
321  result_A = invsqrtPi * (B*(1.25+0.75*B*B*invA)*invApBsq*invApBsq*invA - 0.75*atanTerm/A);
322  result_B = -invsqrtPi * invApBsq*invApBsq;
323  return 0.5*invsqrtPi* (-B*invApBsq/A + atanTerm);
324 }
325 
326 template<> __hostanddev__
327 double integralErfcGaussian<3>(double A, double B, double& result_A, double& result_B)
328 { double invApBsq = 1./(A + B*B);
329  double invsqrtApBsq = sqrt(invApBsq); //(A+B^2) ^ (-1/2)
330  double inv3sqrtApBsq = invsqrtApBsq * invApBsq; //(A+B^2) ^ (-3/2)
331  double inv5sqrtApBsq = inv3sqrtApBsq * invApBsq; //(A+B^2) ^ (-5/2)
332  double invA = 1./A;
333  result_A = (-invA*invA + B*(0.375*inv5sqrtApBsq + invA*(0.5*inv3sqrtApBsq + invA*invsqrtApBsq))) * invA;
334  result_B = -0.75*inv5sqrtApBsq;
335  return (1. - B*(invsqrtApBsq + 0.5*A*inv3sqrtApBsq)) * 0.5*invA*invA;
336 }
337 
338 template<> __hostanddev__
339 double integralErfcGaussian<5>(double A, double B, double& result_A, double& result_B)
340 { double invApBsq = 1./(A + B*B);
341  double invsqrtApBsq = sqrt(invApBsq); //(A+B^2) ^ (-1/2)
342  double inv3sqrtApBsq = invsqrtApBsq * invApBsq; //(A+B^2) ^ (-3/2)
343  double inv5sqrtApBsq = inv3sqrtApBsq * invApBsq; //(A+B^2) ^ (-5/2)
344  double inv7sqrtApBsq = inv5sqrtApBsq * invApBsq; //(A+B^2) ^ (-7/2)
345  double invA = 1./A;
346  result_A = -3.*invA* (invA*invA*invA
347  - B*(0.3125*inv7sqrtApBsq + invA*(0.375*inv5sqrtApBsq
348  + invA*(0.5*inv3sqrtApBsq + invA*invsqrtApBsq))));
349  result_B = -1.875*inv7sqrtApBsq;
350  return invA * (invA*invA - B*(0.375*inv5sqrtApBsq + invA*(0.5*inv3sqrtApBsq + invA*invsqrtApBsq)));
351 }
352 
353 
354 
357 template<> __hostanddev__ double GGA_eval<GGA_X_wPBE_SR>(double rs, double s2, double& e_rs, double& e_s2)
358 { //Slater exchange:
359  double eSlater_rs, eSlater = slaterExchange(rs, eSlater_rs);
360  //omega-PBE enhancement factor:
361  const double omega = 0.11; //range-parameter recommended in the HSE06 paper
362 
363  //Parametrization of PBE hole [J. Perdew and M. Ernzerhof, J. Chem. Phys. 109, 3313 (1998)]
364  const double A = 1.0161144;
365  const double B = -0.37170836;
366  const double C = -0.077215461;
367  const double D = 0.57786348;
368  //-- Function h := s2 H using the Pade approximant eqn (A5) for H(s)
369  const double H_a1 = 0.00979681;
370  const double H_a2 = 0.0410834;
371  const double H_a3 = 0.187440;
372  const double H_a4 = 0.00120824;
373  const double H_a5 = 0.0347188;
374  double s = sqrt(s2);
375  double hNum = s2*s2*(H_a1 + s2*H_a2);
376  double hNum_s2 = s2*(2.*H_a1 + s2*(3.*H_a2));
377  double hDenInv = 1./(1. + s2*s2*(H_a3 + s*H_a4 + s2*H_a5));
378  double hDen_s2 = s2*(2.*H_a3 + s*(2.5*H_a4) + s2*(3.*H_a5));
379  double h = hNum * hDenInv;
380  double h_s2 = (hNum_s2 - hNum*hDenInv*hDen_s2) * hDenInv;
381  //-- Function f := C (1 + s2 F) in terms of h using eqn (25)
382  //-- and noting that eqn (14) => (4./9)*A*A + B - A*D = -1/2
383  double f = C - 0.5*h - (1./27)*s2;
384  double f_s2 = -0.5*h_s2 - (1./27);
385  //-- Function g := E (1 + s2 G) in terms of f and h using eqns (A1-A3)
386  double Dph = D+h, sqrtDph = sqrt(Dph);
387  const double gExpArg_h = 2.25/A;
388  double gExpArg = gExpArg_h*h, gErfcArg = sqrt(gExpArg);
389  double gExpErfcTerm = exp(gExpArg) * erfc(gErfcArg);
390  double gExpErfcTerm_h = (gExpErfcTerm - (1./sqrt(M_PI))/gErfcArg) * gExpArg_h;
391  double g = -Dph*(0.2*f + Dph*((4./15)*B + Dph*((8./15)*A
392  + sqrtDph*(0.8*sqrt(M_PI))*(sqrt(A)*gExpErfcTerm-1.))));
393  double g_h = -(0.2*f + Dph*((8./15)*B + Dph*(1.6*A
394  + sqrtDph*(0.8*sqrt(M_PI))*(sqrt(A)*(3.5*gExpErfcTerm+Dph*gExpErfcTerm_h)-3.5))));
395  double g_f = -Dph*0.2;
396  double g_s2 = g_h * h_s2 + g_f * f_s2;
397 
398  //Accumulate contributions from each gaussian-erfc-polynomial integral:
399  //(The prefactor of -8/9 in the enhancement factor is included at the end)
400  const double erfcArgPrefac = omega * pow(4./(9*M_PI),1./3); //prefactor to rs in the argument to erfc
401  double erfcArg = erfcArgPrefac * rs;
402  double I=0., I_s2=0., I_erfcArg=0.;
403  //5 fit gaussians for the 1/y part of the hole from the HSE paper:
404  const double a1 = -0.000205484, b1 = 0.006601306;
405  const double a2 = -0.109465240, b2 = 0.259931140;
406  const double a3 = -0.064078780, b3 = 0.520352224;
407  const double a4 = -0.008181735, b4 = 0.118551043;
408  const double a5 = -0.000110666, b5 = 0.046003777;
409  double fit1_h, fit1_erfcArg, fit1 = integralErfcGaussian<1>(b1+h, erfcArg, fit1_h, fit1_erfcArg);
410  double fit2_h, fit2_erfcArg, fit2 = integralErfcGaussian<1>(b2+h, erfcArg, fit2_h, fit2_erfcArg);
411  double fit3_h, fit3_erfcArg, fit3 = integralErfcGaussian<2>(b3+h, erfcArg, fit3_h, fit3_erfcArg);
412  double fit4_h, fit4_erfcArg, fit4 = integralErfcGaussian<2>(b4+h, erfcArg, fit4_h, fit4_erfcArg);
413  double fit5_h, fit5_erfcArg, fit5 = integralErfcGaussian<3>(b5+h, erfcArg, fit5_h, fit5_erfcArg);
414  I += a1*fit1 + a2*fit2 + a3*fit3 + a4*fit4 + a5*fit5;
415  I_s2 += (a1*fit1_h + a2*fit2_h + a3*fit3_h + a4*fit4_h + a5*fit5_h) * h_s2;
416  I_erfcArg += a1*fit1_erfcArg + a2*fit2_erfcArg + a3*fit3_erfcArg + a4*fit4_erfcArg + a5*fit5_erfcArg;
417  //Analytical gaussian terms present in the PBE hole:
418  double term1_h, term1_erfcArg, term1 = integralErfcGaussian<1>(D+h, erfcArg, term1_h, term1_erfcArg);
419  double term2_h, term2_erfcArg, term2 = integralErfcGaussian<3>(D+h, erfcArg, term2_h, term2_erfcArg);
420  double term3_h, term3_erfcArg, term3 = integralErfcGaussian<5>(D+h, erfcArg, term3_h, term3_erfcArg);
421  I += B*term1 + f*term2 + g*term3;
422  I_s2 += f_s2*term2 + g_s2*term3 + (B*term1_h + f*term2_h + g*term3_h) * h_s2;
423  I_erfcArg += B*term1_erfcArg + f*term2_erfcArg + g*term3_erfcArg;
424  //GGA result:
425  e_rs = (-8./9)* (eSlater_rs * I + eSlater * I_erfcArg * erfcArgPrefac);
426  e_s2 = (-8./9)* eSlater * I_s2;
427  return (-8./9)* eSlater * I;
428 }
429 
430 
433 template<int nCount> struct GGA_calc <GGA_X_GLLBsc, true, nCount>
434 { __hostanddev__ static
436  double* E, array<double*,nCount> E_n, array<double*,2*nCount-1> E_sigma, double scaleFac)
437  { //Each spin component is computed separately:
438  for(int s=0; s<nCount; s++)
439  { //Scale up s-density and gradient:
440  double ns = n[s][i] * nCount;
441  if(ns < nCutoff) continue;
442  //Compute dimensionless quantities rs and s2:
443  double rs = pow((4.*M_PI/3.)*ns, (-1./3));
444  double s2_sigma = pow(ns, -8./3) * ((0.25*nCount*nCount) * pow(3.*M_PI*M_PI, -2./3));
445  double s2 = s2_sigma * sigma[2*s][i];
446  //Compute energy density and its gradients using GGA_eval:
447  double e_rs, e_s2, e = GGA_eval<GGA_X_PBEsol>(rs, s2, e_rs, e_s2);
448  //Compute gradients if required:
449  if(E_n[0]) E_n[s][i] += scaleFac*( 2*e ); //NOTE: contributes only to potential (no concept of energy, will not FD test)
450  E[i] += scaleFac*( n[s][i]*e ); //So that the computed total energy is approximately that of PBEsol (only for aesthetic reasons!)
451  }
452  }
453 };
454 
457 template<int nCount> struct GGA_calc <GGA_X_LB94, true, nCount>
458 { __hostanddev__ static
460  double* E, array<double*,nCount> E_n, array<double*,2*nCount-1> E_sigma, double scaleFac)
461  { if(!E_n[0]) return; //only computes potential, so no point proceeding if E_n not requested
462  //Each spin component is computed separately:
463  for(int s=0; s<nCount; s++)
464  { //Scale up s-density and gradient:
465  double ns = n[s][i] * nCount;
466  if(ns < nCutoff) continue;
467  double nsCbrt = pow(ns, 1./3);
468  //Compute dimensionless gradient x = nabla n / n^(4/3):
469  double x = nCount*sqrt(sigma[2*s][i]) / (nsCbrt*ns);
470  //Compute potential correction:
471  const double beta = 0.05;
472  E_n[s][i] += scaleFac*( -beta*nsCbrt * x*x / (1. + 3*beta*x*asinh(x)) );
473  }
474  }
475 };
476 
477 
478 //---------------------- GGA correlation implementations ---------------------------
479 
484 __hostanddev__ double PW91_H0(const double gamma,
485  double beta, double g3, double t2, double ecUnif,
486  double& H0_beta, double& H0_g3, double& H0_t2, double& H0_ecUnif)
487 {
488  const double betaByGamma = beta/gamma;
489  //Compute A (PBE equation (8), PW91 equation (14)) and its derivatives:
490  double expArg = ecUnif/(gamma*g3);
491  double expTerm = exp(-expArg);
492  double A_betaByGamma = 1./(expTerm-1);
493  double A = betaByGamma * A_betaByGamma;
494  double A_expArg = A * A_betaByGamma * expTerm;
495  double A_ecUnif = A_expArg/(gamma*g3);
496  double A_g3 = -A_expArg*expArg/g3;
497  //Start with the innermost rational function
498  double At2 = A*t2;
499  double num = 1.+At2, num_At2 = 1.;
500  double den = 1.+At2*(1.+At2), den_At2 = 1.+2*At2;
501  double frac = num/den, frac_At2 = (num_At2*den-num*den_At2)/(den*den);
502  //Log of the rational function
503  double logArg = 1 + betaByGamma*t2*frac;
504  double logTerm = log(logArg);
505  double logTerm_betaByGamma = t2*frac/logArg;
506  double logTerm_t2 = betaByGamma*(frac + t2*A*frac_At2)/logArg;
507  double logTerm_A = betaByGamma*t2*t2*frac_At2/logArg;
508  //Final expression:
509  double H0_A = gamma*g3*logTerm_A;
510  H0_beta = (gamma*g3*logTerm_betaByGamma + H0_A * A_betaByGamma)/gamma;
511  H0_g3 = gamma*logTerm + H0_A * A_g3;
512  H0_t2 = gamma*g3*logTerm_t2;
513  H0_ecUnif = H0_A * A_ecUnif;
514  return gamma*g3*logTerm;
515 }
516 
517 
520 __hostanddev__ double GGA_PBE_correlation(const double beta, const double beta_rs,
521  double rs, double zeta, double g, double t2,
522  double& e_rs, double& e_zeta, double& e_g, double& e_t2)
523 {
524  //Compute uniform correlation energy and its derivatives:
525  double ecUnif_rs, ecUnif_zeta;
526  double ecUnif = LDA_eval<LDA_C_PW_prec>(rs, zeta, ecUnif_rs, ecUnif_zeta);
527 
528  //Compute gradient correction H:
529  double g2=g*g, g3 = g*g2;
530  double H_beta, H_g3, H_t2, H_ecUnif;
531  const double gamma = (1. - log(2.))/(M_PI*M_PI);
532  double H = PW91_H0(gamma, beta, g3, t2, ecUnif, H_beta, H_g3, H_t2, H_ecUnif);
533 
534  //Put together final results (propagate gradients):
535  e_rs = ecUnif_rs + H_ecUnif*ecUnif_rs + H_beta*beta_rs;
536  e_zeta = ecUnif_zeta + H_ecUnif * ecUnif_zeta;
537  e_g = H_g3 * (3*g2);
538  e_t2 = H_t2;
539  return ecUnif + H;
540 }
541 
543 template<> __hostanddev__ double GGA_eval<GGA_C_PBE>(double rs, double zeta, double g, double t2,
544  double& e_rs, double& e_zeta, double& e_g, double& e_t2)
545 { return GGA_PBE_correlation(0.06672455060314922, 0., rs, zeta, g, t2, e_rs, e_zeta, e_g, e_t2);
546 }
547 
549 template<> __hostanddev__ double GGA_eval<GGA_C_PBEsol>(double rs, double zeta, double g, double t2,
550  double& e_rs, double& e_zeta, double& e_g, double& e_t2)
551 { return GGA_PBE_correlation(0.046, 0., rs, zeta, g, t2, e_rs, e_zeta, e_g, e_t2);
552 }
553 
555 template<> __hostanddev__
556 double GGA_eval<GGA_C_PW91>(double rs, double zeta, double g, double t2,
557  double& e_rs, double& e_zeta, double& e_g, double& e_t2)
558 {
559  //Rasolt-Geldart function Cxc(rs) and its derivatives:
560  //Numerator (I pulled in the prefactor of 1e-3 into these)
561  const double Cxc0 = 2.568e-3;
562  const double aCxc = 2.3266e-2;
563  const double bCxc = 7.389e-6;
564  double numCxc = Cxc0 + rs*(aCxc + rs*(bCxc));
565  double numCxc_rs = aCxc + rs*(2*bCxc);
566  //Denominator
567  const double cCxc = 8.723;
568  const double dCxc = 0.472;
569  double denCxc = 1. + rs*(cCxc + rs*(dCxc + rs*(1e4*bCxc)));
570  double denCxc_rs = cCxc + rs*(2*dCxc + rs*(3*1e4*bCxc));
571  //Pade form:
572  double Cxc = numCxc/denCxc;
573  double Cxc_rs = (numCxc_rs*denCxc - numCxc*denCxc_rs)/(denCxc*denCxc);
574 
575  //Compute uniform correlation energy and its derivatives:
576  double ecUnif_rs, ecUnif_zeta;
577  double ecUnif = LDA_eval<LDA_C_PW>(rs, zeta, ecUnif_rs, ecUnif_zeta);
578 
579  //Compute gradient correction H1 and its derivatives:
580  //Difference between C coefficients:
581  const double nu = (16./M_PI) * pow(3.*M_PI*M_PI, 1./3);
582  const double Cx = -1.667e-3;
583  double nuCdiff = nu*(Cxc - Cxc0 - (3./7)*Cx);
584  double nuCdiff_rs = nu * Cxc_rs;
585  //Exponential cutoff:
586  const double sigma = 100 * pow(16./(3*M_PI*M_PI), 2./3); //coefficient in exponent (converting ks/kF to rs)
587  double g2=g*g, g3=g*g2, g4=g2*g2;
588  double expCutoff = exp(-sigma*g4*rs*t2);
589  //Put together correction:
590  double H1 = nuCdiff * g3 * t2 * expCutoff;
591  double H1_rs = nuCdiff_rs * g3 * t2 * expCutoff - (sigma*g4*t2)*H1;
592  double H1_g = nuCdiff * (3*g2) * t2 * expCutoff - (sigma*4*g3*rs*t2)*H1;
593  double H1_t2 = nuCdiff * g3 * expCutoff - (sigma*g4*rs)*H1;
594 
595  //Compute gradient correction H0 and its derivatives:
596  const double beta = nu*(Cxc0-Cx);
597  const double alpha = 0.09;
598  const double gamma = (beta*beta)/(2.*alpha);
599  double H0_beta, H0_g3, H0_t2, H0_ecUnif;
600  double H0 = PW91_H0(gamma, beta, g3, t2, ecUnif, H0_beta, H0_g3, H0_t2, H0_ecUnif);
601 
602  //Put together final results (propagate gradients):
603  e_rs = ecUnif_rs + H1_rs + H0_ecUnif * ecUnif_rs;
604  e_zeta = ecUnif_zeta + H0_ecUnif * ecUnif_zeta;
605  e_g = H1_g + H0_g3 * (3*g2);
606  e_t2 = H1_t2 + H0_t2;
607  return ecUnif + H1 + H0;
608 }
609 
610 //---------------------- GGA kinetic energy implementations ---------------------------
611 
613 __hostanddev__ double TFKinetic(double rs, double& e_rs)
614 {
615  double rsInv = 1./rs;
616  const double KEprefac = 9.0/20.0 * pow(1.5*M_PI*M_PI, 1./3.);
617  double e = KEprefac * pow(rsInv, 2.);
618  e_rs = -2.0 * e * rsInv;
619  return e;
620 }
621 
623 template<> __hostanddev__ double GGA_eval<GGA_KE_VW>(double rs, double s2, double& e_rs, double& e_s2)
624 {
625  //const double lambda = 1.0/9.0; //proper coefficient in gradient expansion <Sov. Phys. -- JETP 5,64 (1957)>
626  const double lambda = 1.0; //original Von Weisacker correction <Z. Phys. 96, 431 (1935)>
627  //const double lambda = 1.0/5.0; //Empirical "best fit" < J. Phys. Soc. Jpn. 20, 1051, (1965)>
628 
629  double rsInv = 1./rs;
630  const double prefac = lambda * 3.0/4.0 * pow(1.5*M_PI*M_PI, 1./3.);
631  e_s2 = prefac * pow(rsInv, 2.);
632  double e = e_s2 * s2;
633  e_rs = -2.0 * e * rsInv;
634  return e;
635 }
636 
638 template<> __hostanddev__ double GGA_eval<GGA_KE_PW91>(double rs, double s2, double& e_rs, double& e_s2)
639 { //Thomas-Fermi Kinetic Energy:
640  double eTF_rs, eTF = TFKinetic(rs, eTF_rs);
641  //Enhancement factor of the PW91 form:
642  //-- Fit parameters (in order of appearance in equation (8) of PW91 Exchange functional reference)
643  const double P = 0.093907;
644  const double Q = 76.320;
645  const double R = 0.26608;
646  const double S = 0.0809615;
647  const double T = 100.;
648  const double U = 0.57767e-4;
649  double F_s2, F = GGA_PW91_Enhancement(s2, F_s2, P,Q,R,S,T,U);
650  //GGA result:
651  e_rs = eTF_rs * F;
652  e_s2 = eTF * F_s2;
653  return eTF * F;
654 }
655 
656 #endif // JDFTX_ELECTRONIC_EXCORR_INTERNAL_GGA_H
ScalarField pow(const ScalarField &, double alpha)
Elementwise power (preserve input)
__hostanddev__ double GGA_eval< GGA_C_PW91 >(double rs, double zeta, double g, double t2, double &e_rs, double &e_zeta, double &e_g, double &e_t2)
PW91 GGA correlation [JP Perdew et al, Phys. Rev. B 46, 6671 (1992)].
Definition: ExCorr_internal_GGA.h:556
bool needsTau() const
return true if orbital kinetic energy density is used (MGGA)
Definition: ExCorr_internal_GGA.h:50
ScalarField sqrt(const ScalarField &)
Elementwise square root (preserve input)
__hostanddev__ double GGA_eval< GGA_C_PBE >(double rs, double zeta, double g, double t2, double &e_rs, double &e_zeta, double &e_g, double &e_t2)
PBE GGA correlation [JP Perdew, K Burke, and M Ernzerhof, Phys. Rev. Lett. 77, 3865 (1996)]...
Definition: ExCorr_internal_GGA.h:543
Perdew-Wang 1991 GGA exchange.
Definition: ExCorr_internal_GGA.h:34
__hostanddev__ double slaterExchange(double rs, double &e_rs)
Slater exchange as a function of rs (PER PARTICLE):
Definition: ExCorr_internal_GGA.h:223
Semi-local part of GLLB-sc exchange (potential-only, equal to 2x PBEsol per-particle energy) ...
Definition: ExCorr_internal_GGA.h:37
Common interface to the compute kernels for GGA-like functionals.
Definition: ExCorr_internal_GGA.h:44
bool hasEnergy() const
whether total energy is meaningful for this functional
Definition: ExCorr_internal_GGA.h:83
__hostanddev__ double GGA_eval< GGA_KE_PW91 >(double rs, double s2, double &e_rs, double &e_s2)
PW91k GGA kinetic energy [PRB 46, 6671-6687 (1992)] parameterized by Lembarki and Chermette [PRA 50...
Definition: ExCorr_internal_GGA.h:638
__hostanddev__ double TFKinetic(double rs, double &e_rs)
Thomas Fermi kinetic energy as a function of rs (PER PARTICLE):
Definition: ExCorr_internal_GGA.h:613
__hostanddev__ double GGA_eval< GGA_X_PBE >(double rs, double s2, double &e_rs, double &e_s2)
PBE GGA exchange [JP Perdew, K Burke, and M Ernzerhof, Phys. Rev. Lett. 77, 3865 (1996)].
Definition: ExCorr_internal_GGA.h:248
double scaleFac
scale factor (to support mixing for hybrid functionals)
Definition: ExCorr_internal.h:45
GGA_Variant
Available GGA functionals.
Definition: ExCorr_internal_GGA.h:29
__hostanddev__ double GGA_eval< GGA_X_wPBE_SR >(double rs, double s2, double &e_rs, double &e_s2)
Definition: ExCorr_internal_GGA.h:357
__hostanddev__ double GGA_eval< GGA_C_PBEsol >(double rs, double zeta, double g, double t2, double &e_rs, double &e_zeta, double &e_g, double &e_t2)
PBEsol GGA correlation [JP Perdew et al, Phys. Rev. Lett. 100, 136406 (2008)].
Definition: ExCorr_internal_GGA.h:549
__hostanddev__ double integralErfcGaussian(double A, double B, double &result_A, double &result_B)
Evaluate and its derivatives.
ScalarFieldTilde D(const ScalarFieldTilde &, int iDir)
compute the gradient in the iDir&#39;th cartesian direction
Perdew-Burke-Ernzerhof GGA exchange.
Definition: ExCorr_internal_GGA.h:30
van Leeuwen-Baerends asymptotically-correct exchange potential correction (potential-only) ...
Definition: ExCorr_internal_GGA.h:38
ScalarField I(const ScalarFieldTilde &, bool compat=false, int nThreads=0)
Forward transform: PW basis -> real space (preserve input)
ScalarField log(const ScalarField &)
Elementwise logarithm (preserve input)
bool hasKinetic() const
whether this functional includes kinetic energy
Definition: ExCorr_internal_GGA.h:74
Definition: operators_internal.h:37
bool hasExchange() const
whether this functional includes exchange
Definition: ExCorr_internal_GGA.h:51
__hostanddev__ double GGA_eval(double rs, double s2, double &e_rs, double &e_s2)
Definition: ExCorr_internal_GGA.h:141
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
Short-ranged part of omega-PBE exchange (used in HSE06 hybrid)
Definition: ExCorr_internal_GGA.h:36
Abstract base class for functionals.
Definition: ExCorr_internal.h:42
Perdew-Burke-Ernzerhof GGA exchange reparametrized for solids.
Definition: ExCorr_internal_GGA.h:32
__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&#39;s PW91) ...
Definition: ExCorr_internal_LDA.h:229
bool needsLap() const
return true if laplacian of density is used (MGGA)
Definition: ExCorr_internal_GGA.h:49
Teter GGA kinetic energy.
Definition: ExCorr_internal_GGA.h:40
__hostanddev__ double GGA_eval< GGA_X_PBEsol >(double rs, double s2, double &e_rs, double &e_s2)
PBEsol GGA exchange [JP Perdew et al, Phys. Rev. Lett. 100, 136406 (2008)].
Definition: ExCorr_internal_GGA.h:253
ScalarField exp(const ScalarField &)
Elementwise exponential (preserve input)
__hostanddev__ double GGA_PBE_exchange(const double kappa, const double mu, double rs, double s2, double &e_rs, double &e_s2)
PBE GGA exchange [JP Perdew, K Burke, and M Ernzerhof, Phys. Rev. Lett. 77, 3865 (1996)].
Definition: ExCorr_internal_GGA.h:232
__hostanddev__ double GGA_eval< GGA_X_PW91 >(double rs, double s2, double &e_rs, double &e_s2)
PW91 GGA exchange [JP Perdew et al, Phys. Rev. B 46, 6671 (1992)].
Definition: ExCorr_internal_GGA.h:280
__hostanddev__ double PW91_H0(const double gamma, double beta, double g3, double t2, double ecUnif, double &H0_beta, double &H0_g3, double &H0_t2, double &H0_ecUnif)
Definition: ExCorr_internal_GGA.h:484
__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&#39;s PBE) ...
Definition: ExCorr_internal_LDA.h:236
__hostanddev__ double GGA_eval< GGA_KE_VW >(double rs, double s2, double &e_rs, double &e_s2)
von Weisacker gradient correction to Thomas Fermi LDA kinetic energy (with correct gradient expansion...
Definition: ExCorr_internal_GGA.h:623
bool needsSigma() const
return true if density gradients are used
Definition: ExCorr_internal_GGA.h:48
bool hasCorrelation() const
whether this functional includes correlation
Definition: ExCorr_internal_GGA.h:64
Perdew-Burke-Ernzerhof GGA correlation reparametrized for solids.
Definition: ExCorr_internal_GGA.h:33
Perdew-Wang 1991 GGA correlation.
Definition: ExCorr_internal_GGA.h:35
__hostanddev__ double GGA_PW91_Enhancement(double s2, double &F_s2, const double P, const double Q, const double R, const double S, const double T, const double U)
Definition: ExCorr_internal_GGA.h:261
__hostanddev__ double GGA_PBE_correlation(const double beta, const double beta_rs, double rs, double zeta, double g, double t2, double &e_rs, double &e_zeta, double &e_g, double &e_t2)
Definition: ExCorr_internal_GGA.h:520
Perdew-Burke-Ernzerhof GGA correlation.
Definition: ExCorr_internal_GGA.h:31
von Weisacker gradient correction to Thomas Fermi LDA kinetic energy
Definition: ExCorr_internal_GGA.h:39