20 #ifndef JDFTX_ELECTRONIC_SPECIESINFO_INTERNAL_H 21 #define JDFTX_ELECTRONIC_SPECIESINFO_INTERNAL_H 25 #include <core/matrix3.h> 26 #include <electronic/RadialFunction.h> 27 #include <electronic/SphericalHarmonics.h> 31 template<
int l,
int m> __hostanddev__
37 double q = qvec.length();
38 vector3<> qhat = qvec * (q ? 1.0/q : 0.0);
39 double prefac = Ylm<l,m>(qhat) * VnlRadial(q);
41 for(
int atom=0; atom<nAtoms; atom++)
42 Vnl[atom*atomStride+n] = prefac * cis((-2*M_PI)*
dot(pos[atom],kpG));
44 void Vnl(
int nbasis,
int atomStride,
int nAtoms,
int l,
int m,
const vector3<> k,
const vector3<int>* iGarr,
47 void Vnl_gpu(
int nbasis,
int atomStride,
int nAtoms,
int l,
int m,
const vector3<> k,
const vector3<int>* iGarr,
58 { __hostanddev__
static void exec(Functor* f)
63 template<
int Nlm,
typename Functor>
struct StaticLoopYlm< Nlm, Functor, 0>
64 { __hostanddev__
static void exec(Functor* f) {
return; }
66 template<
int Nlm,
typename Functor> __hostanddev__
void staticLoopYlm(Functor* f)
70 #define SwitchTemplate_Nlm(Nlm, func, args) \ 72 { case 1: func<1> args; break; \ 73 case 4: func<4> args; break; \ 74 case 9: func<9> args; break; \ 75 case 16: func<16> args; break; \ 76 case 25: func<25> args; break; \ 77 case 49: func<49> args; break; \ 78 default: fprintf(stderr, "Invalid Nlm in SwitchTemplate_Nlm"); exit(1); \ 87 int nCoeff;
double dGinv;
const double* nRadial;
91 : nCoeff(nCoeff), dGinv(dGinv), nRadial(nRadial)
93 qhat = qvec * (q ? 1.0/q : 0.0);
98 complex mIota(0,-1), phase(1,0);
99 for(
int l=0; l*(l+2) < lm; l++) phase *= mIota;
101 double Gindex = q * dGinv;
102 if(Gindex < nCoeff-5)
106 template<
int Nlm> __hostanddev__
108 int nCoeff,
double dGinv,
const double* nRadial,
const vector3<>& atpos,
complex* n)
111 staticLoopYlm<Nlm>(&functor);
112 n[i] += functor.n * cis((-2*M_PI)*
dot(atpos,iG));
114 void nAugment(
int Nlm,
116 int nCoeff,
double dGinv,
const double* nRadial,
const vector3<>& atpos,
complex* n);
118 void nAugment_gpu(
int Nlm,
120 int nCoeff,
double dGinv,
const double* nRadial,
const vector3<>& atpos,
complex* n);
126 { uint64_t Gindex = uint64_t((iG*G).length() * dGinv);
127 vector3<int> iv = iG;
for(
int k=0; k<3; k++)
if(iv[k]<0) iv[k] += S[k];
128 return (Gindex << 48)
129 + (uint64_t(iv[0]) << 32) + (uint64_t(iv[1]) << 16) + uint64_t(iv[2]);
131 __hostanddev__
void setNagIndexPtr_calc(
int i,
int iMax,
int nCoeff,
const uint64_t* nagIndex,
size_t* nagIndexPtr)
132 {
int Gindex = int(nagIndex[i] >> 48);
133 int GindexNext = (i+1<iMax) ?
int(nagIndex[i+1] >> 48) : nCoeff;
134 if(i==0)
for(
int j=0; j<=Gindex; j++) nagIndexPtr[j] = 0;
135 for(
int j=Gindex; j<GindexNext; j++)
136 nagIndexPtr[j+1] = i+1;
138 void setNagIndex(
const vector3<int>& S,
const matrix3<>& G,
int iGstart,
int iGstop,
int nCoeff,
double dGinv, uint64_t*& nagIndex,
size_t*& nagIndexPtr);
140 void setNagIndex_gpu(
const vector3<int>& S,
const matrix3<>& G,
int iGstart,
int iGstop,
int nCoeff,
double dGinv, uint64_t*& nagIndex,
size_t*& nagIndexPtr);
147 int nCoeff;
double dGinv;
const double* nRadial;
153 : nCoeff(nCoeff), dGinv(dGinv), nRadial(nRadial), E_n(E_n), E_nRadial(E_nRadial), dotPrefac(dotPrefac)
155 qhat = qvec * (q ? 1.0/q : 0.0);
160 complex mIota(0,-1), phase(1,0);
161 for(
int l=0; l*(l+2) < lm; l++) phase *= mIota;
163 double Gindex = q * dGinv;
164 if(Gindex < nCoeff-5)
165 {
complex term = phase * Ylm<lm>(qhat) * E_n;
171 template<
int Nlm> __hostanddev__
173 int nCoeff,
double dGinv,
const double* nRadial,
const vector3<>& atpos,
178 iG[2] = int(0xFFFF & key); key >>= 16;
179 iG[1] = int(0xFFFF & key); key >>= 16;
180 iG[0] = int(0xFFFF & key);
181 size_t i = iG[2] + (S[2]/2+1)*
size_t(iG[1] + S[1]*iG[0]);
182 for(
int j=0; j<3; j++) if(2*iG[j]>S[j]) iG[j]-=S[j];
183 int dotPrefac = (iG[2]==0||2*iG[2]==S[2]) ? 1 : 2;
186 staticLoopYlm<Nlm>(&functor);
187 if(nRadial && !dummyGpuThread)
accumVector((functor.nE_n *
complex(0,-2*M_PI)) * iG, E_atpos, i);
190 int nCoeff,
double dGinv,
const double* nRadial,
const vector3<>& atpos,
192 const uint64_t* nagIndex,
const size_t* nagIndexPtr);
195 int nCoeff,
double dGinv,
const double* nRadial,
const vector3<>& atpos,
197 const uint64_t* nagIndex,
const size_t* nagIndexPtr);
204 for(
int atom=0; atom<nAtoms; atom++)
205 SG += cis(-2*M_PI*
dot(iG,atpos[atom]));
219 double Zchargeball,
double wChargeball)
221 double Gsq = GGT.metric_length_squared(iG);
227 Vlocps[i] += SGinvVol * VlocRadial(
sqrt(Gsq));
230 rhoIon[i] += SGinvVol * (-Z);
234 nChargeball[i] += SGinvVol * Zchargeball *
exp(-0.5*Gsq*
pow(wChargeball,2));
237 if(nCore) nCore[i] += SGinvVol * nCoreRadial(
sqrt(Gsq));
238 if(tauCore) tauCore[i] += SGinvVol * tauCoreRadial(
sqrt(Gsq));
244 double Zchargeball,
double wChargeball);
250 double Zchargeball,
double wChargeball);
260 double Zchargeball,
double wChargeball)
262 double Gsq = GGT.metric_length_squared(iG);
266 ccgrad_SGinvVol += ccgrad_Vlocps[i] * VlocRadial(
sqrt(Gsq));
270 ccgrad_SGinvVol += ccgrad_rhoIon[i] * (-Z);
273 if(ccgrad_nChargeball)
274 ccgrad_SGinvVol += ccgrad_nChargeball[i] * Zchargeball *
exp(-0.5*Gsq*
pow(wChargeball,2));
277 if(ccgrad_nCore) ccgrad_SGinvVol += ccgrad_nCore[i] * nCoreRadial(
sqrt(Gsq));
278 if(ccgrad_tauCore) ccgrad_SGinvVol += ccgrad_tauCore[i] * tauCoreRadial(
sqrt(Gsq));
281 ccgrad_SG[i] = ccgrad_SGinvVol;
288 double Zchargeball,
double wChargeball);
295 double Zchargeball,
double wChargeball);
304 complex term =
complex(0,-2*M_PI) * cis(-2*M_PI*
dot(iG,atpos)) * ccgrad_SG[i].conj();
315 #endif // JDFTX_ELECTRONIC_SPECIESINFO_INTERNAL_H __hostanddev__ uint64_t setNagIndex_calc(const vector3< int > &iG, const vector3< int > &S, const matrix3<> &G, double dGinv)
(In MPI mode, only a subset of G-vectors are indexed on each process (to correspond to nAUgment)) ...
Definition: SpeciesInfo_internal.h:125
ScalarField pow(const ScalarField &, double alpha)
Elementwise power (preserve input)
ScalarField sqrt(const ScalarField &)
Elementwise square root (preserve input)
Tptr conj(Tptr &&in)
Generic elementwise conjugate for complex data:
Definition: Operators.h:122
void getSG(const vector3< int > S, int nAtoms, const vector3<> *atpos, double invVol, complex *SG)
Get structure factor in a ScalarFieldTilde's data/dataGpu (with 1/vol normalization factor) ...
complex dot(const Tptr &X, const Tptr &Y)
Definition: Operators.h:196
Definition: SpeciesInfo_internal.h:145
Definition: SpeciesInfo_internal.h:57
__hostanddev__ void gradSGtoAtpos_calc(int i, const vector3< int > iG, const vector3<> atpos, const complex *ccgrad_SG, vector3< complex * > grad_atpos)
Definition: SpeciesInfo_internal.h:301
__hostanddev__ double value(const double *coeff, double x)
Compute value of quintic spline. Warning: x is not range-checked.
__hostanddev__ void storeVector(const vector3< scalar > &v, vector3< scalar * > &vArr, int i)
Store vector to a vector field.
Definition: vector3.h:171
__hostanddev__ void accumVector(const vector3< scalar > &v, vector3< scalar * > &vArr, int i)
Accumulate vector onto a vector field.
Definition: vector3.h:175
Definition: SpeciesInfo_internal.h:56
Definition: SpeciesInfo_internal.h:85
__hostanddev__ complex getSG_calc(const vector3< int > &iG, const int &nAtoms, const vector3<> *atpos)
Get structure factor for a specific iG, given a list of atoms.
Definition: SpeciesInfo_internal.h:202
G-space radial function stored on a uniform grid (of |G|)
Definition: RadialFunction.h:28
ScalarField exp(const ScalarField &)
Elementwise exponential (preserve input)
__hostanddev__ void gradLocalToSG_calc(int i, const vector3< int > iG, const matrix3<> GGT, const complex *ccgrad_Vlocps, const complex *ccgrad_rhoIon, const complex *ccgrad_nChargeball, const complex *ccgrad_nCore, const complex *ccgrad_tauCore, complex *ccgrad_SG, const RadialFunctionG &VlocRadial, double Z, const RadialFunctionG &nCoreRadial, const RadialFunctionG &tauCoreRadial, double Zchargeball, double wChargeball)
Propagate (complex conjugates of) gradients w.r.t Vlocps, rhoIon etc to complex conjugate gradient w...
Definition: SpeciesInfo_internal.h:255
__hostanddev__ void Vnl_calc(int n, int atomStride, int nAtoms, const vector3<> &k, const vector3< int > *iGarr, const matrix3<> &G, const vector3<> *pos, const RadialFunctionG &VnlRadial, complex *Vnl)
Compute Vnl and optionally its gradients for a subset of the basis space, and for multiple atomic pos...
Definition: SpeciesInfo_internal.h:32
__hostanddev__ void updateLocal_calc(int i, const vector3< int > &iG, const matrix3<> &GGT, complex *Vlocps, complex *rhoIon, complex *nChargeball, complex *nCore, complex *tauCore, int nAtoms, const vector3<> *atpos, double invVol, const RadialFunctionG &VlocRadial, double Z, const RadialFunctionG &nCoreRadial, const RadialFunctionG &tauCoreRadial, double Zchargeball, double wChargeball)
Calculate local pseudopotential, ionic density and chargeball due to one species at a given G-vector...
Definition: SpeciesInfo_internal.h:215
__hostanddev__ void valueGrad(double E_value, double *E_coeff, double x)
Gradient propagation corresponding to value()
Complex number (need to define our own because we need operators for gpu code as well) ...
Definition: scalar.h:49