20 #ifndef JDFTX_ELECTRONIC_EXCORR_INTERNAL_H 21 #define JDFTX_ELECTRONIC_EXCORR_INTERNAL_H 26 #include <electronic/operators_internal.h> 28 static const double nCutoff = 1e-16;
33 #define SwitchTemplate_spin(SwitchTemplate_functional,variant,nCount, fTemplate,argList) \ 35 { case 1: { SwitchTemplate_functional(variant,1, fTemplate,argList) break; } \ 36 case 2: { SwitchTemplate_functional(variant,2, fTemplate,argList) break; } \ 47 Functional(
double scaleFac=1.0) : scaleFac(scaleFac) {}
69 virtual void evaluate(
int N, std::vector<const double*> n, std::vector<const double*> sigma,
70 std::vector<const double*> lap, std::vector<const double*> tau,
71 double* E, std::vector<double*> E_n, std::vector<double*> E_sigma,
72 std::vector<double*> E_lap, std::vector<double*> E_tau)
const=0;
76 std::vector<const double*> n, std::vector<const double*> sigma,
77 std::vector<const double*> lap, std::vector<const double*> tau,
78 double* E, std::vector<double*> E_n, std::vector<double*> E_sigma,
79 std::vector<double*> E_lap, std::vector<double*> E_tau)
const;
84 { x0 = x[0][i] + x[1][i];
85 xVec =
vector3<>( 2*x[2][i], -2*x[3][i], x[0][i]-x[1][i] );
88 { E_x[0][i] += (E_x0 + E_xVec[2]);
89 E_x[1][i] += (E_x0 - E_xVec[2]);
90 E_x[2][i] += 2 * E_xVec[0];
91 E_x[3][i] -= 2 * E_xVec[1];
98 double mNormFac = 1./
sqrt(mVec.length_squared() + nCutoff);
103 double xdotmHat =
dot(xVec,mHat);
104 xDiag[0][i] = 0.5*(x0 + xdotmHat);
105 xDiag[1][i] = 0.5*(x0 - xdotmHat);
109 __hostanddev__
void spinDiagonalizeGrad_calc(
int i,
array<const double*,4> n,
array<const double*,4> x,
array<const double*,2> E_xDiag,
array<double*,4> E_n,
array<double*,4> E_x)
112 double mNormFac = 1./
sqrt(mVec.length_squared() + nCutoff);
117 double E_x0 = 0.5*(E_xDiag[0][i] + E_xDiag[1][i]);
118 double E_xdotmHat = 0.5*(E_xDiag[0][i] - E_xDiag[1][i]);
120 vector3<> E_mVec = (E_xdotmHat * mNormFac) * (xVec -
dot(xVec,mHat)*mHat);
122 accumSpinVectorGrad( 0. ,E_mVec, E_n,i);
123 accumSpinVectorGrad(E_x0,E_xVec, E_x,i);
129 {
const double scale = 1./(
pow(2.,4./3) - 2);
130 double zetaPlusCbrt =
pow(1+zeta, 1./3);
131 double zetaMinusCbrt =
pow(1-zeta, 1./3);
132 f_zeta = scale*(zetaPlusCbrt - zetaMinusCbrt)*(4./3);
133 return scale*((1+zeta)*zetaPlusCbrt + (1-zeta)*zetaMinusCbrt - 2.);
137 template<
typename Para,
typename Ferro> __hostanddev__
138 double spinInterpolate(
double rs,
double zeta,
double& e_rs,
double& e_zeta,
const Para& para,
const Ferro& ferro)
139 {
double ePara_rs, ePara = para(rs, ePara_rs);
147 {
double eFerro_rs, eFerro = ferro(rs, eFerro_rs);
149 e_rs = ePara_rs + f*(eFerro_rs - ePara_rs);
150 e_zeta = f_zeta*(eFerro - ePara);
151 return ePara + f*(eFerro - ePara);
158 template<
typename Para,
typename Ferro,
typename Stiff> __hostanddev__
160 const Para& para,
const Ferro& ferro,
const Stiff& stiff,
161 const double fDblPrime0 = 4./(9*(
pow(2., 1./3)-1)))
163 double ePara_rs, ePara = para(rs, ePara_rs);
170 {
double eFerro_rs, eFerro = ferro(rs, eFerro_rs);
171 double eStiff_rs, eStiff = stiff(rs, eStiff_rs);
174 double zeta2=zeta*zeta, zeta3=zeta2*zeta, zeta4=zeta2*zeta2;
175 const double scale = -1./fDblPrime0;
176 double w1 = zeta4*f, w1_zeta = 4*zeta3*f + zeta4*f_zeta;
177 double w2 = scale*((1-zeta4)*f), w2_zeta = scale*(-4*zeta3*f + (1-zeta4)*f_zeta);
179 e_rs = ePara_rs + w1*(eFerro_rs-ePara_rs) + w2*eStiff_rs;
180 e_zeta = w1_zeta*(eFerro-ePara) + w2_zeta*eStiff;
181 return ePara + w1*(eFerro-ePara) + w2*eStiff;
185 #endif // JDFTX_ELECTRONIC_EXCORR_INTERNAL_H virtual bool hasExchange() const =0
whether this functional includes exchange
virtual bool needsTau() const =0
return true if orbital kinetic energy density is used (MGGA)
ScalarField pow(const ScalarField &, double alpha)
Elementwise power (preserve input)
void evaluateSub(int iStart, int iStop, 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
Call evaluate for a subset of data points:
ScalarField sqrt(const ScalarField &)
Elementwise square root (preserve input)
complex dot(const Tptr &X, const Tptr &Y)
Definition: Operators.h:196
double scaleFac
scale factor (to support mixing for hybrid functionals)
Definition: ExCorr_internal.h:45
virtual bool hasEnergy() const =0
whether total energy is meaningful for this functional
virtual bool hasKinetic() const =0
whether this functional includes kinetic energy
__hostanddev__ double spinInterpolation(double zeta, double &f_zeta)
LDA spin interpolation function f(zeta) and its derivative.
Definition: ExCorr_internal.h:128
virtual bool needsLap() const =0
return true if laplacian of density is used (MGGA)
__hostanddev__ void spinDiagonalizeGrad_calc(int i, array< const double *, 4 > n, array< const double *, 4 > x, array< const double *, 2 > E_xDiag, array< double *, 4 > E_n, array< double *, 4 > E_x)
Propagate gradients corresponding to spinDiagonalize_calc(), from E_xDiag and accumulate to E_n and E...
Definition: ExCorr_internal.h:109
Definition: operators_internal.h:37
__hostanddev__ void spinDiagonalize_calc(int i, array< const double *, 4 > n, array< const double *, 4 > x, array< double *, 2 > xDiag)
Transform spin-density-matrix-like quantity x into the basis where spin-density-matrix n is diagonal...
Definition: ExCorr_internal.h:95
Abstract base class for functionals.
Definition: ExCorr_internal.h:42
__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
virtual bool hasCorrelation() const =0
whether this functional includes correlation
virtual bool needsSigma() const =0
return true if density gradients are used
__hostanddev__ void loadSpinVector(array< const double *, 4 > x, int i, double &x0, vector3<> &xVec)
Utility function for converting to/from spin-density matrices to scalar+vector combinations (via Paul...
Definition: ExCorr_internal.h:83
virtual 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 =0