JDFTx  1.2.0
ExCorr_internal_mGGA.h
Go to the documentation of this file.
1 /*-------------------------------------------------------------------
2 Copyright 2012 Ravishankar Sundararaman
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_MGGA_H
21 #define JDFTX_ELECTRONIC_EXCORR_INTERNAL_MGGA_H
22 
24 
27 
28 static const double tauCutoff = 1e-8;
29 
36 };
37 
39 class FunctionalMGGA : public Functional
40 {
41 public:
42  FunctionalMGGA(mGGA_Variant variant, double scaleFac=1.0);
43  bool needsSigma() const { return true; }
44  bool needsLap() const
45  { switch(variant)
46  { case mGGA_X_TPSS:
47  case mGGA_C_TPSS:
48  case mGGA_X_revTPSS:
49  case mGGA_C_revTPSS:
50  return false;
51  default:
52  return true;
53  }
54  }
55  bool needsTau() const { return true; }
56  bool hasExchange() const
57  { switch(variant)
58  { case mGGA_X_TPSS:
59  case mGGA_X_revTPSS:
60  return true;
61  default:
62  return false;
63  }
64  }
65  bool hasCorrelation() const
66  { switch(variant)
67  { case mGGA_C_TPSS:
68  case mGGA_C_revTPSS:
69  return true;
70  default:
71  return false;
72  }
73  }
74 bool hasKinetic() const { return false; }
75  bool hasEnergy() const { return true; }
76 
80  void evaluate(int N, std::vector<const double*> n, std::vector<const double*> sigma,
81  std::vector<const double*> lap, std::vector<const double*> tau,
82  double* E, std::vector<double*> E_n, std::vector<double*> E_sigma,
83  std::vector<double*> E_lap, std::vector<double*> E_tau) const;
84 
85 private:
86  mGGA_Variant variant;
87 };
88 
94 #define SwitchTemplate_mGGA(variant,nCount, fTemplate,argList) \
95  switch(variant) \
96  { case mGGA_X_TPSS: fTemplate< mGGA_X_TPSS, true, nCount> argList; break; \
97  case mGGA_C_TPSS: fTemplate< mGGA_C_TPSS, false, nCount> argList; break; \
98  case mGGA_X_revTPSS: fTemplate< mGGA_X_revTPSS, true, nCount> argList; break; \
99  case mGGA_C_revTPSS: fTemplate< mGGA_C_revTPSS, false, nCount> argList; break; \
100  default: break; \
101  }
102 
106 template<mGGA_Variant variant> __hostanddev__
107 double mGGA_eval(double rs, double s2, double q, double z,
108  double& e_rs, double& e_s2, double& e_q, double& e_z);
109 
115 template<mGGA_Variant variant> __hostanddev__
116 double mGGA_eval(double rs, double zeta, double g, double t2,
117  double t2up, double t2dn, double zi2, double z,
118  double& e_rs, double& e_zeta, double& e_g, double& e_t2,
119  double& e_t2up, double& e_t2dn, double& e_zi2, double& e_z);
120 
124 template<mGGA_Variant variant, bool spinScaling, int nCount> struct mGGA_calc;
125 
127 template<mGGA_Variant variant, int nCount>
128 struct mGGA_calc <variant, true, nCount>
129 { __hostanddev__ static
132  double* E, array<double*,nCount> E_n, array<double*,2*nCount-1> E_sigma,
134  { //Each spin component is computed separately:
135  for(int s=0; s<nCount; s++)
136  { //Scale up s-density and gradient:
137  double ns = n[s][i] * nCount;
138  if(ns < nCutoff) continue;
139  double sigmas = sigma[2*s][i];
140  if(sigmas < nCutoff) sigmas = nCutoff;
141  //Compute dimensionless quantities rs, s2, q and z: (see TPSS reference)
142  double rs = pow((4.*M_PI/3.)*ns, (-1./3));
143  double s2_sigma = pow(ns, -8./3) * ((0.25*nCount*nCount) * pow(3.*M_PI*M_PI, -2./3));
144  double s2 = s2_sigma * sigmas;
145  double q_lap = pow(ns, -5./3) * ((0.25*nCount) * pow(3.*M_PI*M_PI, -2./3));
146  double q = q_lap * (lap[s] ? lap[s][i] : 0.);
147  if(tau[s] && tau[s][i]<tauCutoff) continue;
148  double z_sigma = tau[s] ? (0.125*nCount)/(ns * tau[s][i]) : 0.;
149  double z = z_sigma * sigmas;
150  bool zOffRange = false;
151  if(z>1.) { z=1.; zOffRange = true; }
152  //Compute energy density and its gradients using GGA_eval:
153  double e_rs, e_s2, e_q, e_z, e = mGGA_eval<variant>(rs, s2, q, z, e_rs, e_s2, e_q, e_z);
154  if(zOffRange) e_z = 0;
155  //Compute gradients if required:
156  if(E_n[0])
157  { //Propagate rs, s2, q, z gradients to n, sigma, lap, tau:
158  double e_n = -(e_rs*rs + 8*e_s2*s2 + 5*e_q*q + 3*e_z*z) / (3. * n[s][i]);
159  double e_sigma = e_s2 * s2_sigma + e_z * z_sigma;
160  double e_lap = e_q * q_lap;
161  double e_tau = tau[s] ? -e_z*z/tau[s][i] : 0.;
162  //Convert form per-particle to per volume:
163  E_n[s][i] += scaleFac*( n[s][i] * e_n + e );
164  E_sigma[2*s][i] += scaleFac*( n[s][i] * e_sigma );
165  if(lap[s]) E_lap[s][i] += scaleFac*( n[s][i] * e_lap );
166  if(tau[s]) E_tau[s][i] += scaleFac*( n[s][i] * e_tau );
167  }
168  E[i] += scaleFac*( n[s][i] * e );
169  }
170  }
171 };
172 
177 template<mGGA_Variant variant, int nCount>
178 struct mGGA_calc <variant, false, nCount>
179 { __hostanddev__ static
182  double* E, array<double*,nCount> E_n, array<double*,2*nCount-1> E_sigma,
184  {
185  //Compute nTot and rs, and ignore tiny densities:
186  double nTot = (nCount==1) ? n[0][i] : n[0][i]+n[1][i];
187  if(nTot<nCutoff) return;
188  double rs = pow((4.*M_PI/3.)*nTot, (-1./3));
189  //Compute zeta, g(zeta)
190  double zeta = (nCount==1) ? 0. : (n[0][i] - n[1][i])/nTot;
191  double g = 0.5*(pow(1+zeta, 2./3) + pow(1-zeta, 2./3));
192  //Compute dimensionless gradient squared t2 (and t2up/t2dn):
193  double t2_sigma = (pow(M_PI/3, 1./3)/16.) * pow(nTot,-7./3) / (g*g);
194  double sigmaTot = (nCount==1) ? sigma[0][i] : sigma[0][i]+2*sigma[1][i]+sigma[2][i];
195  double t2 = t2_sigma * sigmaTot;
196  double t2up_sigmaUp, t2dn_sigmaDn, t2up, t2dn;
197  if(nCount==1) t2up = t2dn = 2*t2;
198  else
199  { if(n[0][i]<nCutoff || n[1][i]<nCutoff) return;
200  t2up_sigmaUp = (pow(4*M_PI/3, 1./3)/16.) * pow(n[0][i],-7./3);
201  t2dn_sigmaDn = (pow(4*M_PI/3, 1./3)/16.) * pow(n[1][i],-7./3);
202  t2up = t2up_sigmaUp * sigma[0][i];
203  t2dn = t2dn_sigmaDn * sigma[2][i];
204  }
205  //Compute dimensionless gradient squared zi2:
206  double zi2_sigmaDiff = pow(nTot,-14./3) * pow(3*M_PI*M_PI,-2./3);
207  double sigmaDiff = (nCount==1) ? 0. :
208  n[1][i]*n[1][i]*sigma[0][i] - 2*n[0][i]*n[1][i]*sigma[1][i] + n[0][i]*n[0][i]*sigma[2][i];
209  double zi2 = zi2_sigmaDiff * sigmaDiff;
210  //Compute reduced KE density, z = tauW/tau
211  double tauTot = (nCount==1) ? tau[0][i] : tau[0][i]+tau[1][i];
212  if(tauTot<tauCutoff) return;
213  double z_sigma = 0.125/(nTot * tauTot);
214  double z = z_sigma * sigmaTot;
215  bool zOffRange = false;
216  if(z>1.) { z=1.; zOffRange = true; }
217 
218  //Compute per-particle energy and derivatives:
219  double e_rs, e_zeta, e_g, e_t2, e_t2up, e_t2dn, e_zi2, e_z;
220  double e = mGGA_eval<variant>(rs, zeta, g, t2, t2up, t2dn, zi2, z,
221  e_rs, e_zeta, e_g, e_t2, e_t2up, e_t2dn, e_zi2, e_z);
222  if(zOffRange) e_z = 0;
223 
224  //Compute and store final n/sigma derivatives if required
225  if(E_n[0])
226  { if(nCount==1) e_t2 += 2*(e_t2up+e_t2dn);
227  else
228  { double E_t2up = scaleFac * nTot * e_t2up;
229  double E_t2dn = scaleFac * nTot * e_t2dn;
230  E_sigma[0][i] += E_t2up * t2up_sigmaUp;
231  E_sigma[2][i] += E_t2dn * t2dn_sigmaDn;
232  E_n[0][i] += (-7./3) * E_t2up * t2up / n[0][i];
233  E_n[1][i] += (-7./3) * E_t2dn * t2dn / n[1][i];
234  }
235  double e_nTot = -(e_rs*rs + 7.*e_t2*t2 + 14.*e_zi2*zi2 + 3*e_z*z) / (3.*nTot);
236  double e_sigma = e_t2 * t2_sigma + e_z * z_sigma; //derivative w.r.t |DnTot|^2
237  double e_tau = -e_z*z/tauTot;
238 
239  double g_zeta = (1./3) * //Avoid singularities at zeta = +/- 1:
240  ( (1+zeta > nCutoff ? pow(1+zeta, -1./3) : 0.)
241  - (1-zeta > nCutoff ? pow(1-zeta, -1./3) : 0.) );
242  e_zeta += (e_g - 2. * e_t2*t2 / g) * g_zeta;
243 
244  double E_nTot = e + nTot * e_nTot;
245  E_n[0][i] += scaleFac*( E_nTot - e_zeta * (zeta-1) );
246  E_sigma[0][i] += scaleFac*( (nTot * e_sigma) );
247  E_tau[0][i] += scaleFac*( nTot * e_tau );
248  if(nCount>1)
249  { E_n[1][i] += scaleFac*( E_nTot - e_zeta * (zeta+1) );
250  E_sigma[1][i] += scaleFac*( (nTot * e_sigma) * 2 );
251  E_sigma[2][i] += scaleFac*( (nTot * e_sigma) );
252  E_tau[1][i] += scaleFac*( nTot * e_tau );
253  //Propagate gradients from zi2 to n, sigma
254  double E_sigmaDiff = scaleFac*(nTot* (e_zi2 * zi2_sigmaDiff));
255  E_sigma[0][i] += n[1][i]*n[1][i] * E_sigmaDiff;
256  E_sigma[1][i] -= 2*n[0][i]*n[1][i] * E_sigmaDiff;
257  E_sigma[2][i] += n[0][i]*n[0][i] * E_sigmaDiff;
258  E_n[0][i] += 2*(sigma[2][i]*n[0][i] - sigma[1][i]*n[1][i]) * E_sigmaDiff;
259  E_n[1][i] += 2*(sigma[0][i]*n[1][i] - sigma[1][i]*n[0][i]) * E_sigmaDiff;
260  }
261  }
262  E[i] += scaleFac*( nTot * e ); //energy density per volume
263  }
264 };
265 
266 //-------------------- meta-GGA exchange implementations -------------------------
267 
271 template<bool revised> __hostanddev__
272 double mGGA_TPSS_Exchange(double rs, double s2, double q, double z,
273  double& e_rs, double& e_s2, double& e_q, double& e_z)
274 { //Eqn. (7) of ref and its gradient:
275  const double b = 0.40;
276  double alphazmz = (5./3)*s2*(1-z) - z; //(alpha-1)*z (rearranging eqn (8) to avoid z=0 issues)
277  double alphazmz_z = -(5./3)*s2 - 1.;
278  double alphazmz_s2 = (5./3)*(1-z);
279  double qbDen = 1./sqrt(z*z + b*alphazmz*(alphazmz+z));
280  double qbDenPrime = -0.5*qbDen*qbDen*qbDen;
281  double qbDen_z = qbDenPrime*( 2*z + b*alphazmz + b*(2*alphazmz+z)*alphazmz_z );
282  double qbDen_s2 = qbDenPrime*( b*(2*alphazmz+z)*alphazmz_s2 );
283  double qb = 0.45*alphazmz*qbDen + (2./3) * s2;
284  double qb_z = 0.45*(alphazmz_z*qbDen + alphazmz*qbDen_z);
285  double qb_s2 = 0.45*(alphazmz_s2*qbDen + alphazmz*qbDen_s2) + (2./3);
286  //Eqn. (10) of ref and its gradient:
287  const double kappa = 0.804;
288  const double mu = revised ? 0.14 : 0.21951;
289  const double c = revised ? 2.35204 : 1.59096;
290  const double e = revised ? 2.1677 : 1.537;
291  double z2 = z*z, s4=s2*s2;
292  //--- Term 1 of numerator:
293  double xNumTerm1_s2 = 10./81 + c*(revised ? z2*z : z2)/((1+z2)*(1+z2));
294  double xNumTerm1 = xNumTerm1_s2 * s2;
295  double xNumTerm1_z = s2 * c*(revised ? z2*(3-z2) : 2*z*(1-z2))/((1+z2)*(1+z2)*(1+z2));
296  //--- Term 3 of numerator
297  double xNumTerm3arg = 0.18*z2+0.5*s4;
298  double xNumTerm3_qb = (-73./405)*sqrt(xNumTerm3arg);
299  double xNumTerm3 = xNumTerm3_qb * qb;
300  double xNumTerm3_z = 0.18*z*(xNumTerm3/xNumTerm3arg);
301  double xNumTerm3_s2 = 0.5*s2*(xNumTerm3/xNumTerm3arg);
302  //--- Numerator
303  double xNum = xNumTerm1 + (146./2025)*qb*qb + xNumTerm3
304  + (100./(6561*kappa))*s4 + (4.*sqrt(e)/45)*z2 + (e*mu)*s4*s2;
305  double xNum_qb = (146./2025)*2*qb +xNumTerm3_qb;
306  double xNum_z = xNumTerm1_z + xNumTerm3_z + (4.*sqrt(e)/45)*2*z;
307  double xNum_s2 = xNumTerm1_s2 + xNumTerm3_s2 + (100./(6561*kappa))*2*s2 + (e*mu)*3*s4;
308  //--- Denominator
309  double xDenSqrt = 1./(1+sqrt(e)*s2);
310  double xDen = xDenSqrt*xDenSqrt;
311  double xDen_s2 = -2*sqrt(e)*xDen*xDenSqrt;
312  //--- Eqn (10) for x:
313  double x = xNum*xDen;
314  double x_s2 = (xNum_s2 + xNum_qb*qb_s2)*xDen + xNum*xDen_s2;
315  double x_z = (xNum_z + xNum_qb*qb_z)*xDen;
316  //TPSS Enhancement factor:
317  double F = 1+kappa - (kappa*kappa)/(kappa+x);
318  double F_x = (kappa*kappa)/((kappa+x)*(kappa+x));
319  //TPSS Exchange energy per particle:
320  double eSlater_rs, eSlater = slaterExchange(rs, eSlater_rs);
321  e_rs = eSlater_rs * F;
322  e_s2 = eSlater * F_x * x_s2;
323  e_q = 0.;
324  e_z = eSlater * F_x * x_z;
325  return eSlater * F;
326 }
327 
329 template<> __hostanddev__ double mGGA_eval<mGGA_X_TPSS>(double rs, double s2, double q, double z,
330  double& e_rs, double& e_s2, double& e_q, double& e_z)
331 { return mGGA_TPSS_Exchange<false>(rs, s2, q, z, e_rs, e_s2, e_q, e_z);
332 }
333 
335 template<> __hostanddev__ double mGGA_eval<mGGA_X_revTPSS>(double rs, double s2, double q, double z,
336  double& e_rs, double& e_s2, double& e_q, double& e_z)
337 { return mGGA_TPSS_Exchange<true>(rs, s2, q, z, e_rs, e_s2, e_q, e_z);
338 }
339 
340 
341 //-------------------- meta-GGA correlation implementations -------------------------
342 
344 template<bool revised> __hostanddev__
345 double betaTPSS(double rs, double& beta_rs)
346 { if(revised==false)
347  { beta_rs = 0.; //The constant value used in PBE:
348  return 0.06672455060314922;
349  }
350  else
351  { //Eqn. (3) of the revTPSS ref
352  const double num_rs=0.1, num = 1+num_rs*rs;
353  const double den_rs=0.1778, den = 1+den_rs*rs;
354  const double beta0 = 0.066725;
355  beta_rs = beta0*(num_rs*den-num*den_rs)/(den*den);
356  return beta0*num/den;
357  }
358 }
359 
363 template<bool revised> __hostanddev__
365  double rs, double zeta, double g, double t2,
366  double t2up, double t2dn, double zi2, double z,
367  double& e_rs, double& e_zeta, double& e_g, double& e_t2,
368  double& e_t2up, double& e_t2dn, double& e_zi2, double& e_z)
369 {
370  //Compute C(zeta,0) and its derivatives (eqn (13))
371  const double C0 = revised ? 0.59 : 0.53;
372  const double C1 = revised ? 0.9269 : 0.87;
373  const double C2 = revised ? 0.6225 : 0.50;
374  const double C3 = revised ? 2.1540 : 2.26;
375  double zeta2 = zeta*zeta;
376  double Czeta0 = C0 + zeta2*(C1 + zeta2*(C2 + zeta2*(C3)));
377  double Czeta0_zeta = zeta*(2*C1 + zeta2*(4*C2 + zeta2*(6*C3)));
378  //Compute C(zeta,zi) and its derivatives (eqn (14))
379  double zetapCbrt = pow(1+zeta, 1./3);
380  double zetamCbrt = pow(1-zeta, 1./3);
381  double Cnum = (1+zeta)*zetapCbrt * (1-zeta)*zetamCbrt; //bring (1+/-zeta)^-4/3 from denominator to numerator
382  double Cnum_zeta = (-8./3)*zeta*zetapCbrt*zetamCbrt;
383  double Cden_zi2 = 0.5*((1+zeta)*zetapCbrt + (1-zeta)*zetamCbrt);
384  double Cden = Cnum + zi2*Cden_zi2;
385  double Cden_zeta = Cnum_zeta + (2./3)*zi2*(zetapCbrt - zetamCbrt);
386  double Cratio = Cnum/Cden, Cratio2 = Cratio*Cratio, Cratio4 = Cratio2*Cratio2;
387  double C = Czeta0*Cratio4;
388  double C_zeta = Czeta0_zeta*Cratio4 + 4*Czeta0*Cratio2*Cratio*(Cnum_zeta/Cden - Cratio*Cden_zeta/Cden);
389  double C_zi2 = -4*Czeta0*Cratio4*Cden_zi2/Cden;
390  if(!Cnum && !Cden) { C=Czeta0; C_zeta=0.; C_zi2=0.; } //Avoid 0/0 error
391 
392  //Ingredients for eqn (12):
393  //PBE correlation at target spin densities:
394  double ec_rs, ec_zeta, ec_g, ec_t2;
395  double beta_rs, beta = betaTPSS<revised>(rs, beta_rs);
396  double ec = GGA_PBE_correlation(beta, beta_rs, rs, zeta, g, t2, ec_rs, ec_zeta, ec_g, ec_t2);
397  const double gPol = pow(2., -1./3); //g for a fully polarized density
398  //PBE correlation with up-spins alone:
399  double ecUp, ecUp_rs, ecUp_zeta, ecUp_t2up;
400  { double ecUp_rsUp, ecUp_zetaPol, ecUp_gPol;
401  double rsUp = rs/(zetapCbrt*gPol);
402  double betaUp_rsUp, betaUp = betaTPSS<revised>(rsUp, betaUp_rsUp);
403  ecUp = GGA_PBE_correlation(betaUp, betaUp_rsUp,
404  rsUp, 1., gPol, t2up, ecUp_rsUp, ecUp_zetaPol, ecUp_gPol, ecUp_t2up);
405  ecUp_rs = ecUp_rsUp * rsUp / rs;
406  ecUp_zeta = ecUp_rsUp * rsUp * (1+zeta>nCutoff ? (-1./3)/(1+zeta) : 0.);
407  }
408  //PBE correlation with down-spins alone:
409  double ecDn, ecDn_rs, ecDn_zeta, ecDn_t2dn;
410  if(!zeta && t2up==t2dn)
411  { ecDn = ecUp;
412  ecDn_rs = ecUp_rs;
413  ecDn_zeta = -ecUp_zeta;
414  ecDn_t2dn = ecUp_t2up;
415  }
416  else
417  { double ecDn_rsDn, ecDn_zetaPol, ecDn_gPol;
418  double rsDn = rs/(zetamCbrt*gPol);
419  double betaDn_rsDn, betaDn = betaTPSS<revised>(rsDn, betaDn_rsDn);
420  ecDn = GGA_PBE_correlation(betaDn, betaDn_rsDn,
421  rsDn, 1., gPol, t2dn, ecDn_rsDn, ecDn_zetaPol, ecDn_gPol, ecDn_t2dn);
422  ecDn_rs = ecDn_rsDn * rsDn / rs;
423  ecDn_zeta = ecDn_rsDn * rsDn * (1-zeta>nCutoff ? (1./3)/(1-zeta) : 0.);
424  }
425  //Compute ecTilde = 0.5*(1+zeta) max(ec, ecUp) + 0.5*(1-zeta) max(ec, ecDn):
426  double ecTilde=0., ecTilde_rs=0., ecTilde_zeta=0., ecTilde_g=0.;
427  double ecTilde_t2=0., ecTilde_t2up=0., ecTilde_t2dn=0.;
428  if(ec > ecUp)
429  { double scale = 0.5*(1+zeta);
430  ecTilde += scale*ec;
431  ecTilde_rs += scale*ec_rs;
432  ecTilde_zeta += scale*ec_zeta + 0.5*ec;
433  ecTilde_g += scale*ec_g;
434  ecTilde_t2 += scale*ec_t2;
435  }
436  else
437  { double scale = 0.5*(1+zeta);
438  ecTilde += scale*ecUp;
439  ecTilde_rs += scale*ecUp_rs;
440  ecTilde_zeta += scale*ecUp_zeta + 0.5*ecUp;
441  ecTilde_t2up += scale*ecUp_t2up;
442  }
443  if(ec > ecDn)
444  { double scale = 0.5*(1-zeta);
445  ecTilde += scale*ec;
446  ecTilde_rs += scale*ec_rs;
447  ecTilde_zeta += scale*ec_zeta - 0.5*ec;
448  ecTilde_g += scale*ec_g;
449  ecTilde_t2 += scale*ec_t2;
450  }
451  else
452  { double scale = 0.5*(1-zeta);
453  ecTilde += scale*ecDn;
454  ecTilde_rs += scale*ecDn_rs;
455  ecTilde_zeta += scale*ecDn_zeta - 0.5*ecDn;
456  ecTilde_t2dn += scale*ecDn_t2dn;
457  }
458  //Put together eqn. (12):
459  double z2=z*z, z3=z2*z;
460  double ecPKZB_ec = (1+C*z2);
461  double ecPKZB_ecTilde = -(1+C)*z2;
462  double ecPKZB = ecPKZB_ec*ec + ecPKZB_ecTilde*ecTilde;
463  double ecPKZB_C = z2*ec - z2*ecTilde;
464  double ecPKZB_z = 2*z*(C*ec - (1+C)*ecTilde);
465  //Put together the final correlation energy (eqn. (11)):
466  const double d = 2.8;
467  double e = ecPKZB * (1 + d*ecPKZB*z3);
468  double e_ecPKZB = 1 + 2*d*ecPKZB*z3;
469  e_rs = e_ecPKZB*(ecPKZB_ec*ec_rs + ecPKZB_ecTilde*ecTilde_rs);
470  e_zeta = e_ecPKZB*(ecPKZB_C*C_zeta + ecPKZB_ec*ec_zeta + ecPKZB_ecTilde*ecTilde_zeta);
471  e_g = e_ecPKZB*(ecPKZB_ec*ec_g + ecPKZB_ecTilde*ecTilde_g);
472  e_t2 = e_ecPKZB*(ecPKZB_ec*ec_t2 + ecPKZB_ecTilde*ecTilde_t2);
473  e_t2up = e_ecPKZB*ecPKZB_ecTilde*ecTilde_t2up;
474  e_t2dn = e_ecPKZB*ecPKZB_ecTilde*ecTilde_t2dn;
475  e_zi2 = e_ecPKZB*ecPKZB_C*C_zi2;
476  e_z = e_ecPKZB*ecPKZB_z + 3*d*ecPKZB*ecPKZB*z2;
477  return e;
478 }
479 
481 template<> __hostanddev__ double mGGA_eval<mGGA_C_TPSS>(
482  double rs, double zeta, double g, double t2,
483  double t2up, double t2dn, double zi2, double z,
484  double& e_rs, double& e_zeta, double& e_g, double& e_t2,
485  double& e_t2up, double& e_t2dn, double& e_zi2, double& e_z)
486 {
487  return mGGA_TPSS_Correlation<false>(rs, zeta, g, t2, t2up, t2dn, zi2, z,
488  e_rs, e_zeta, e_g, e_t2, e_t2up, e_t2dn, e_zi2, e_z);
489 }
490 
492 template<> __hostanddev__ double mGGA_eval<mGGA_C_revTPSS>(
493  double rs, double zeta, double g, double t2,
494  double t2up, double t2dn, double zi2, double z,
495  double& e_rs, double& e_zeta, double& e_g, double& e_t2,
496  double& e_t2up, double& e_t2dn, double& e_zi2, double& e_z)
497 {
498  return mGGA_TPSS_Correlation<true>(rs, zeta, g, t2, t2up, t2dn, zi2, z,
499  e_rs, e_zeta, e_g, e_t2, e_t2up, e_t2dn, e_zi2, e_z);
500 }
501 
502 #endif // JDFTX_ELECTRONIC_EXCORR_INTERNAL_MGGA_H
__hostanddev__ double betaTPSS(double rs, double &beta_rs)
Compute beta(rs) for the TPSS/revTPSS correlation functionals.
Definition: ExCorr_internal_mGGA.h:345
ScalarField pow(const ScalarField &, double alpha)
Elementwise power (preserve input)
Common interface to the compute kernels for mGGA-like functionals.
Definition: ExCorr_internal_mGGA.h:39
ScalarField sqrt(const ScalarField &)
Elementwise square root (preserve input)
__hostanddev__ double slaterExchange(double rs, double &e_rs)
Slater exchange as a function of rs (PER PARTICLE):
Definition: ExCorr_internal_GGA.h:223
__hostanddev__ double mGGA_eval< mGGA_X_revTPSS >(double rs, double s2, double q, double z, double &e_rs, double &e_s2, double &e_q, double &e_z)
revTPSS Exchange: J.P. Perdew et al, Phys. Rev. Lett. 103, 026403 (2009)
Definition: ExCorr_internal_mGGA.h:335
__hostanddev__ double mGGA_eval< mGGA_C_TPSS >(double rs, double zeta, double g, double t2, double t2up, double t2dn, double zi2, double z, double &e_rs, double &e_zeta, double &e_g, double &e_t2, double &e_t2up, double &e_t2dn, double &e_zi2, double &e_z)
TPSS Correlation: J.P. Perdew et al, Phys. Rev. Lett. 91, 146401 (2003)
Definition: ExCorr_internal_mGGA.h:481
double scaleFac
scale factor (to support mixing for hybrid functionals)
Definition: ExCorr_internal.h:45
revTPSS mGGA correlation
Definition: ExCorr_internal_mGGA.h:35
bool needsLap() const
return true if laplacian of density is used (MGGA)
Definition: ExCorr_internal_mGGA.h:44
__hostanddev__ double mGGA_TPSS_Correlation(double rs, double zeta, double g, double t2, double t2up, double t2dn, double zi2, double z, double &e_rs, double &e_zeta, double &e_g, double &e_t2, double &e_t2up, double &e_t2dn, double &e_zi2, double &e_z)
Definition: ExCorr_internal_mGGA.h:364
__hostanddev__ double mGGA_eval< mGGA_X_TPSS >(double rs, double s2, double q, double z, double &e_rs, double &e_s2, double &e_q, double &e_z)
TPSS Exchange: J.P. Perdew et al, Phys. Rev. Lett. 91, 146401 (2003)
Definition: ExCorr_internal_mGGA.h:329
bool hasExchange() const
whether this functional includes exchange
Definition: ExCorr_internal_mGGA.h:56
mGGA_Variant
Available mGGA functionals.
Definition: ExCorr_internal_mGGA.h:31
TPSS mGGA exchange.
Definition: ExCorr_internal_mGGA.h:32
Definition: operators_internal.h:37
__hostanddev__ double mGGA_eval< mGGA_C_revTPSS >(double rs, double zeta, double g, double t2, double t2up, double t2dn, double zi2, double z, double &e_rs, double &e_zeta, double &e_g, double &e_t2, double &e_t2up, double &e_t2dn, double &e_zi2, double &e_z)
revTPSS Correlation: J.P. Perdew et al, Phys. Rev. Lett. 103, 026403 (2009)
Definition: ExCorr_internal_mGGA.h:492
Abstract base class for functionals.
Definition: ExCorr_internal.h:42
bool needsSigma() const
return true if density gradients are used
Definition: ExCorr_internal_mGGA.h:43
__hostanddev__ double mGGA_eval(double rs, double s2, double q, double z, double &e_rs, double &e_s2, double &e_q, double &e_z)
bool hasCorrelation() const
whether this functional includes correlation
Definition: ExCorr_internal_mGGA.h:65
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: ExCorr_internal_mGGA.h:124
bool needsTau() const
return true if orbital kinetic energy density is used (MGGA)
Definition: ExCorr_internal_mGGA.h:55
revTPSS mGGA exchange
Definition: ExCorr_internal_mGGA.h:34
__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
TPSS mGGA correlation.
Definition: ExCorr_internal_mGGA.h:33
bool hasEnergy() const
whether total energy is meaningful for this functional
Definition: ExCorr_internal_mGGA.h:75
__hostanddev__ double mGGA_TPSS_Exchange(double rs, double s2, double q, double z, double &e_rs, double &e_s2, double &e_q, double &e_z)
Definition: ExCorr_internal_mGGA.h:272
bool hasKinetic() const
whether this functional includes kinetic energy
Definition: ExCorr_internal_mGGA.h:74