1 /*-------------------------------------------------------------------
2 Copyright 2011 Ravishankar Sundararaman, Kendra Letchworth Weaver, Deniz Gunceler
3 Copyright 1996-2003 Sohrab Ismail-Beigi
4
5 This file is part of JDFTx.
6
7 JDFTx is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11
12 JDFTx is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with JDFTx. If not, see <http://www.gnu.org/licenses/>.
19 -------------------------------------------------------------------*/
20
21 #include <electronic/Everything.h>
22 #include <electronic/ElecMinimizer.h>
23 #include <electronic/ColumnBundle.h>
24 #include <electronic/ExCorr.h>
25 #include <electronic/ExactExchange.h>
26 #include <fluid/FluidSolver.h>
27 #include <core/matrix.h>
28 #include <core/Units.h>
29 #include <core/ScalarFieldIO.h>
30 #include <cstdio>
31 #include <cmath>
32 #include <limits.h>
33
ElecVars()34 ElecVars::ElecVars()
35 : isRandom(true), initLCAO(true), skipWfnsInit(false), HauxInitialized(false), lcaoIter(-1), lcaoTol(1e-6)
36 {
37 }
38
39 // Kernel for generating box shaped external potentials
applyBoxPot(int i,vector3<> r,matrix3<> & R,const ElecVars::BoxPotential * bP,double * Vbox)40 void applyBoxPot(int i, vector3<> r, matrix3<>& R, const ElecVars::BoxPotential* bP, double* Vbox)
41 { // Map lattice intervals [0,1) to [-0.5,0.5)
42 r = inv(R)*r;
43 for(int j=0; j<3; j++) r[j] -= floor(0.5+r[j]);
44 r = R*r;
45 //Set potential
46 for(int j=0; j<3; j++)
47 { if((r[j] < bP->min[j]) or (r[j] > bP->max[j]))
48 { Vbox[i] = bP->Vout;
49 return;
50 }
51 }
52 Vbox[i] = bP->Vin;
53 }
54
55 //Helper function to read density (or potential) array
readDensityArray(ScalarFieldArray & var,string varName,string fnamePattern,const Everything * e)56 void readDensityArray(ScalarFieldArray& var, string varName, string fnamePattern, const Everything* e)
57 {
58 #define READchannel(var, suffix) \
59 { string fname = fnamePattern; \
60 size_t pos = fname.find("$VAR"); \
61 assert(pos != string::npos); \
62 fname.replace(pos,4, (suffix)); \
63 logPrintf("Reading %s from file '%s' ... ", (suffix).c_str(), fname.c_str()); logFlush(); \
64 nullToZero(var, e->gInfo); \
65 loadRawBinary(var, fname.c_str()); \
66 logPrintf("done\n"); logFlush(); \
67 }
68 var.resize(e->eInfo.nDensities);
69 if(var.size()==1) { READchannel(var[0], varName) }
70 else
71 { READchannel(var[0], varName+"_up")
72 READchannel(var[1], varName+"_dn")
73 if(var.size()==4)
74 { READchannel(var[2], varName+"_re")
75 READchannel(var[3], varName+"_im")
76 }
77 }
78 #undef READchannel
79 }
80
setup(const Everything & everything)81 void ElecVars::setup(const Everything &everything)
82 {
83 this->e = &everything;
84 logPrintf("\n---------- Allocating electronic variables ----------\n"); logFlush();
85
86 const ElecInfo &eInfo = e->eInfo;
87 const IonInfo& iInfo = e->iInfo;
88 const std::vector<Basis>& basis = e->basis;
89 const GridInfo& gInfo = e->gInfo;
90
91 n.resize(eInfo.nDensities);
92 if(e->ionicDynParams.nSteps)
93 nAccum.resize(eInfo.nDensities);
94 Vscloc.resize(n.size());
95 if(eInfo.hasU)
96 { iInfo.rhoAtom_initZero(rhoAtom);
97 iInfo.rhoAtom_initZero(U_rhoAtom);
98 }
99
100 if(VexternalFilename.size())
101 { Vexternal.resize(VexternalFilename.size());
102 for(unsigned s=0; s<Vexternal.size(); s++)
103 { Vexternal[s] = ScalarFieldData::alloc(gInfo);
104 logPrintf("Reading external potential from '%s'\n", VexternalFilename[s].c_str());
105 loadRawBinary(Vexternal[s], VexternalFilename[s].c_str());
106 }
107 if(Vexternal.size()==1 && n.size()==2) //Replicate potential for second spin:
108 Vexternal.push_back(Vexternal[0]->clone());
109 if(e->iInfo.computeStress)
110 die("\nStress calculation not supported with external potentials.\n\n");
111 }
112
113 //Vexternal contributions from boxPot's.
114 for(size_t j = 0; j<boxPot.size(); j++)
115 { //Create potential
116 ScalarField temp; nullToZero(temp, e->gInfo);
117 applyFunc_r(e->gInfo, applyBoxPot, gInfo.R, &boxPot[j], temp->data());
118 temp = I(gaussConvolve(J(temp), boxPot[j].convolve_radius));
119 //Add to Vexternal
120 if(!Vexternal.size()) Vexternal.resize(n.size());
121 for(unsigned s=0; s<n.size(); s++) Vexternal[s] += temp;
122 }
123
124 //Vexternal contributions due to external field
125 if(e->coulombParams.Efield.length_squared())
126 { ScalarField temp = e->coulomb->getEfieldPotential();
127 //Add to Vexternal
128 if(!Vexternal.size()) Vexternal.resize(n.size());
129 for(unsigned s=0; s<n.size(); s++) Vexternal[s] += temp;
130 }
131
132 if(rhoExternalFilename.length())
133 { logPrintf("Reading external charge from '%s'\n", rhoExternalFilename.c_str());
134 ScalarField temp(ScalarFieldData::alloc(gInfo));
135 loadRawBinary(temp, rhoExternalFilename.c_str());
136 rhoExternal = J(temp);
137 if(e->iInfo.computeStress)
138 die("\nStress calculation not supported with external charge densities.\n\n");
139 }
140
141
142 //Initialize matrix arrays if required:
143 Hsub.resize(eInfo.nStates);
144 Hsub_evecs.resize(eInfo.nStates);
145 Hsub_eigs.resize(eInfo.nStates);
146 if(eInfo.fillingsUpdate==ElecInfo::FillingsHsub)
147 Haux_eigs.resize(eInfo.nStates);
148 if(eigsFilename.length())
149 { eInfo.read(Hsub_eigs, eigsFilename.c_str());
150 if(eInfo.fillingsUpdate==ElecInfo::FillingsHsub)
151 { Haux_eigs = Hsub_eigs;
152 HauxInitialized = true;
153 }
154 }
155 VdagC.resize(eInfo.nStates, std::vector<matrix>(e->iInfo.species.size()));
156
157 //Read in electron (spin) density if needed
158 if(e->cntrl.fixed_H)
159 { string fnamePattern = nFilenamePattern.length() ? nFilenamePattern : VFilenamePattern; //Command ensures that the pattern has a "$VAR" in it
160 #define READrhoAtom(var) \
161 { string fname = fnamePattern; \
162 size_t pos = fname.find("$VAR"); \
163 assert(pos != string::npos); \
164 fname.replace(pos,4, #var); \
165 logPrintf("Reading " #var " from file '%s' ... ", fname.c_str()); logFlush(); \
166 FILE* fp = fopen(fname.c_str(), "r"); \
167 for(matrix& m: var) m.read(fp); \
168 fclose(fp); \
169 logPrintf("done\n"); logFlush(); \
170 }
171 if(nFilenamePattern.length())
172 { readDensityArray(n, "n", fnamePattern, e);
173 if(e->exCorr.needsKEdensity()) readDensityArray(tau, "tau", fnamePattern, e);
174 if(eInfo.hasU) READrhoAtom(rhoAtom)
175 }
176 else
177 { readDensityArray(Vscloc, "Vscloc", fnamePattern, e);
178 if(e->exCorr.needsKEdensity()) readDensityArray(Vtau, "Vtau", fnamePattern, e);
179 if(eInfo.hasU) READrhoAtom(U_rhoAtom)
180 }
181 #undef READrhoAtom
182 }
183
184 //Wavefunction initialiation (bypass in dry runs and phonon supercell calculations)
185 if(skipWfnsInit)
186 { C.resize(eInfo.nStates); //skip memory allocation, but initialize array
187 logPrintf("Skipped wave function initialization.\n");
188 }
189 else
190 {
191 // Initialize ColumnBundle arrays for the electronic wave-functions:
192 logPrintf("Initializing wave functions: ");
193 init(C, eInfo.nStates, eInfo.nBands, &basis[0], &eInfo);
194
195 //Initial wave functions
196 int nBandsInited = 0;
197 if(wfnsFilename.length())
198 { logPrintf("reading from '%s'\n", wfnsFilename.c_str()); logFlush();
199 if(readConversion) readConversion->Ecut = e->cntrl.Ecut;
200 eInfo.read(C, wfnsFilename.c_str(), readConversion.get());
201 nBandsInited = (readConversion && readConversion->nBandsOld) ? readConversion->nBandsOld : eInfo.nBands;
202 isRandom = false;
203 }
204 else if(initLCAO)
205 { nBandsInited = LCAO();
206 }
207
208 //Randomize and orthogonalize any uninitialized bands:
209 if(nBandsInited < eInfo.nBands)
210 { if(nBandsInited) logPrintf("Setting upper %d bands to ", eInfo.nBands-nBandsInited);
211 logPrintf("bandwidth-limited random numbers\n"); logFlush();
212 for(int q=eInfo.qStart; q<eInfo.qStop; q++)
213 { //randomize uninitialized bands:
214 C[q].randomize(nBandsInited, eInfo.nBands);
215 //don't mix (during orthogonalization) the random columns with the init'd ones:
216 if(nBandsInited)
217 { //Ensure that the initalized bands are orthonormal:
218 ColumnBundle Cfixed = C[q].getSub(0, nBandsInited);
219 ColumnBundle OCfixed = O(Cfixed);
220 matrix ortho = invsqrt(Cfixed^OCfixed);
221 Cfixed = Cfixed * ortho;
222 OCfixed = OCfixed * ortho;
223 //Project out initalized band directions from the rest:
224 C[q] -= Cfixed * (OCfixed^C[q]);
225 C[q].setSub(0, Cfixed);
226 }
227 }
228 }
229
230 //Orthogonalize initial wavefunctions:
231 for(int q=eInfo.qStart; q<eInfo.qStop; q++)
232 { matrix CdagOC = C[q] ^ O(C[q]);
233 C[q] = C[q] * invsqrt(CdagOC);
234 iInfo.project(C[q], VdagC[q]);
235 }
236 }
237
238 //Fluid setup:
239 if(fluidParams.fluidType != FluidNone)
240 { logPrintf("----- createFluidSolver() ----- (Fluid-side solver setup)\n");
241 fluidSolver = std::shared_ptr<FluidSolver>(createFluidSolver(*e, fluidParams));
242 if(!fluidSolver) die("Failed to create fluid solver.\n");
243 if(fluidInitialStateFilename.length())
244 { logPrintf("Reading fluid state from '%s'\n", fluidInitialStateFilename.c_str()); logFlush();
245 fluidSolver->loadState(fluidInitialStateFilename.c_str());
246 }
247 }
248
249 //Citations:
250 if(!e->cntrl.scf)
251 { if(eInfo.fillingsUpdate==ElecInfo::FillingsHsub)
252 Citations::add("Total energy minimization with Auxiliary Hamiltonian",
253 "C. Freysoldt, S. Boeck, and J. Neugebauer, Phys. Rev. B 79, 241103(R) (2009)");
254 else
255 Citations::add("Total energy minimization",
256 "T.A. Arias, M.C. Payne and J.D. Joannopoulos, Phys. Rev. Lett. 69, 1077 (1992)");
257 }
258 if(!std::isnan(eInfo.mu))
259 Citations::add("Grand-canonical (fixed-potential) DFT",
260 "R. Sundararaman, W. A. Goddard III and T. A. Arias, J. Chem. Phys. 146, 114104 (2017)");
261 }
262
get_nXC() const263 ScalarFieldArray ElecVars::get_nXC() const
264 { if(e->iInfo.nCore)
265 { ScalarFieldArray nXC = clone(n);
266 int nSpins = std::min(int(nXC.size()), 2); //1 for unpolarized and 2 for polarized
267 for(int s=0; s<nSpins; s++) //note that off-diagonal components of spin-density matrix are excluded
268 nXC[s] += (1./nSpins) * e->iInfo.nCore; //add core density
269 return nXC;
270 }
271 else return n; //no cores
272 }
273
274 //Electronic density functional and gradient
EdensityAndVscloc(Energies & ener,const ExCorr * alternateExCorr)275 void ElecVars::EdensityAndVscloc(Energies& ener, const ExCorr* alternateExCorr)
276 { static StopWatch watch("EdensityAndVscloc"); watch.start();
277 const ElecInfo& eInfo = e->eInfo;
278 const IonInfo& iInfo = e->iInfo;
279
280 ScalarFieldTilde nTilde = J(get_nTot());
281
282 // Local part of pseudopotential:
283 ener.E["Eloc"] = dot(nTilde, O(iInfo.Vlocps));
284 ScalarFieldTilde VsclocTilde = clone(iInfo.Vlocps);
285
286 // Hartree term:
287 ScalarFieldTilde dH = (*e->coulomb)(nTilde); //Note: external charge and nuclear charge contribute to d_vac as well (see below)
288 ener.E["EH"] = 0.5*dot(nTilde, O(dH));
289 VsclocTilde += dH;
290
291 // External charge:
292 ener.E["Eexternal"] = 0.;
293 if(rhoExternal)
294 { ScalarFieldTilde phiExternal = (*e->coulomb)(rhoExternal);
295 ener.E["Eexternal"] += dot(nTilde + iInfo.rhoIon, O(phiExternal));
296 if(rhoExternalSelfEnergy)
297 ener.E["Eexternal"] += 0.5 * dot(rhoExternal, O(phiExternal));
298 VsclocTilde += phiExternal;
299 }
300
301 //Fluid contributions
302 ScalarFieldTilde VtauTilde;
303 if(fluidParams.fluidType != FluidNone)
304 { //Compute n considered for cavity formation (i.e-> include chargeball and partial cores)
305 ScalarFieldTilde nCavityTilde = clone(nTilde);
306 if(iInfo.nCore) nCavityTilde += J(iInfo.nCore);
307 if(iInfo.nChargeball) nCavityTilde += iInfo.nChargeball;
308
309 //Net electric charge:
310 ScalarFieldTilde rhoExplicitTilde = nTilde + iInfo.rhoIon + rhoExternal;
311 fluidSolver->set(rhoExplicitTilde, nCavityTilde);
312 // If the fluid doesn't have a gummel loop, minimize it each time:
313 if(!fluidSolver->useGummel()) fluidSolver->minimizeFluid();
314
315 // Compute the energy and accumulate gradients:
316 ener.E["A_diel"] = fluidSolver->get_Adiel_and_grad(&d_fluid, &V_cavity);
317 VsclocTilde += d_fluid;
318 VsclocTilde += V_cavity;
319
320 //Chemical-potential correction due to potential of electron in bulk fluid
321 double bulkPotential = fluidSolver->bulkPotential();
322 //Chemical-potential correction due to finite nuclear width in fluid interaction:
323 double muCorrection = fluidSolver->ionWidthMuCorrection();
324 ener.E["MuShift"] = (eInfo.nElectrons - iInfo.getZtot()) * (muCorrection - bulkPotential);
325 VsclocTilde->setGzero(muCorrection - bulkPotential + VsclocTilde->getGzero());
326 }
327
328 //Atomic density-matrix contributions: (DFT+U)
329 if(eInfo.hasU)
330 ener.E["U"] = iInfo.rhoAtom_computeU(rhoAtom, U_rhoAtom);
331
332 // Exchange and correlation, and store the real space Vscloc with the odd historic normalization factor of JdagOJ:
333 const ExCorr& exCorr = alternateExCorr ? *alternateExCorr : e->exCorr;
334 ener.E["Exc"] = exCorr(get_nXC(), &Vxc, false, &tau, &Vtau);
335
336 if(!exCorr.hasEnergy() && !e->cntrl.scf)
337 die("Potential functionals do not support total-energy minimization; use SCF instead.\n")
338 if(exCorr.orbitalDep)
339 { if(!e->cntrl.scf)
340 { if(e->cntrl.fixed_H) die("Orbital-dependent potential functionals do not support fix-density; use fix-potential instead.\n")
341 else die("Orbital-dependent potential functionals do not support total-energy minimization; use SCF instead.\n")
342 }
343 Vxc += exCorr.orbitalDep->getPotential();
344 }
345 if(VtauTilde) Vtau.resize(n.size());
346 for(unsigned s=0; s<Vscloc.size(); s++)
347 { Vscloc[s] = JdagOJ(Vxc[s]);
348 if(s<2) //Include all the spin-independent contributions along the diagonal alone
349 Vscloc[s] += Jdag(O(VsclocTilde), true);
350 //External potential contributions:
351 if(Vexternal.size())
352 { ener.E["Eexternal"] += e->gInfo.dV * dot(n[s], Vexternal[s]);
353 Vscloc[s] += JdagOJ(Vexternal[s]);
354 }
355 if(VtauTilde) Vtau[s] += I(VtauTilde);
356 }
357 e->symm.symmetrize(Vscloc);
358 if(Vtau[0]) e->symm.symmetrize(Vtau);
359 watch.stop();
360 }
361
362
363 //----- Electronic energy and (preconditioned) gradient calculation ----------
364
elecEnergyAndGrad(Energies & ener,ElecGradient * grad,ElecGradient * Kgrad,bool calc_Hsub)365 double ElecVars::elecEnergyAndGrad(Energies& ener, ElecGradient* grad, ElecGradient* Kgrad, bool calc_Hsub)
366 {
367 const ElecInfo& eInfo = e->eInfo;
368
369 //Cleanup old gradients:
370 if(grad) { grad->C.assign(eInfo.nStates, ColumnBundle()); }
371 if(Kgrad) { Kgrad->C.assign(eInfo.nStates, ColumnBundle()); }
372
373 //Determine whether Hsub and hence HC needs to be calculated:
374 bool need_Hsub = calc_Hsub || grad;
375 double mu = 0., Bz = 0.;
376
377 if(eInfo.fillingsUpdate==ElecInfo::FillingsHsub)
378 { //Update nElectrons from mu, or mu from nElectrons as appropriate:
379 if(std::isnan(eInfo.mu)) mu = eInfo.findMu(Haux_eigs, eInfo.nElectrons, Bz);
380 else { mu = eInfo.mu; ((ElecInfo&)eInfo).nElectrons = eInfo.nElectronsCalc(mu, Haux_eigs, Bz); }
381 //Compute fillings from aux hamiltonian eigenvalues:
382 for(int q=eInfo.qStart; q<eInfo.qStop; q++)
383 F[q] = eInfo.smear(eInfo.muEff(mu,Bz,q), Haux_eigs[q]);
384 //Update TS and muN:
385 eInfo.updateFillingsEnergies(Haux_eigs, ener);
386 //Report for SCF (ElecMinimizer handles for minimize):
387 if(e->cntrl.scf && n[0]) eInfo.smearReport();
388 }
389
390 //Update the density and density-dependent pieces if required:
391 n = calcDensity();
392 if(e->exCorr.needsKEdensity()) tau = KEdensity();
393 if(eInfo.hasU) e->iInfo.rhoAtom_calc(F, C, rhoAtom); //Atomic density matrix contributions for DFT+U
394 EdensityAndVscloc(ener); //Calculate density functional and its gradient
395 if(need_Hsub) e->iInfo.augmentDensityGridGrad(Vscloc); //Update Vscloc projected onto spherical functions for ultrasoft psps
396
397 //--------- Wavefunction dependent parts -----------
398
399 std::vector<ColumnBundle> HC(eInfo.nStates); //gradient w.r.t C (upto weights and fillings)
400
401 //Exact exchange if required:
402 ener.E["EXX"] = 0.;
403 if(e->exCorr.exxFactor())
404 { double aXX = e->exCorr.exxFactor();
405 double omega = e->exCorr.exxRange();
406 assert(e->exx);
407 ener.E["EXX"] = (*e->exx)(aXX, omega, F, C, need_Hsub ? &HC : 0);
408 }
409
410 //Do the single-particle contributions one state at a time to save memory (and for better cache warmth):
411 ener.E["KE"] = 0.;
412 ener.E["Enl"] = 0.;
413 for(int q=eInfo.qStart; q<e->eInfo.qStop; q++)
414 { double KEq = applyHamiltonian(q, F[q], HC[q], ener, need_Hsub);
415 if(grad) //Calculate wavefunction gradients:
416 { const QuantumNumber& qnum = eInfo.qnums[q];
417 HC[q] -= O(C[q]) * Hsub[q]; //Include orthonormality contribution
418 grad->C[q] = HC[q] * (F[q]*qnum.weight);
419 if(Kgrad)
420 { double Nq = qnum.weight*trace(F[q]);
421 double KErollover = 2. * (Nq>1e-3 ? KEq/Nq : 1.);
422 precond_inv_kinetic(HC[q], KErollover); //apply preconditioner
423 std::swap(Kgrad->C[q], HC[q]); //this frees HC[q]
424 }
425 }
426 }
427 mpiWorld->allReduce(ener.E["KE"], MPIUtil::ReduceSum);
428 mpiWorld->allReduce(ener.E["Enl"], MPIUtil::ReduceSum);
429
430 double dmuContrib = 0., dBzContrib = 0.;
431 bool Mconstrain = (eInfo.spinType==SpinZ) and std::isnan(eInfo.Bz); //whether magnetization needs to be constrained
432 if(grad and eInfo.fillingsUpdate==ElecInfo::FillingsHsub and (std::isnan(eInfo.mu) or Mconstrain)) //contribution due to N/M constraint via the mu/Bz gradient
433 { double dmuNum[2] = {0.,0.}, dmuDen[2] = {0.,0.}; //numerator and denominator of dmuContrib resolved by spin channels (if any)
434 for(int q=eInfo.qStart; q<eInfo.qStop; q++)
435 { diagMatrix fprime = eInfo.smearPrime(eInfo.muEff(mu,Bz,q), Haux_eigs[q]);
436 double w = eInfo.qnums[q].weight;
437 int sIndex = eInfo.qnums[q].index();
438 dmuNum[sIndex] += w * trace(fprime * (diag(Hsub[q])-Haux_eigs[q]));
439 dmuDen[sIndex] += w * trace(fprime);
440 }
441 mpiWorld->allReduce(dmuNum, 2, MPIUtil::ReduceSum);
442 mpiWorld->allReduce(dmuDen, 2, MPIUtil::ReduceSum);
443 if(std::isnan(eInfo.mu) and Mconstrain)
444 { //Fixed N and M (effectively independent constraints on Nup and Ndn)
445 double dmuContribUp = dmuNum[0]/dmuDen[0];
446 double dmuContribDn = dmuNum[1]/dmuDen[1];
447 dmuContrib = 0.5*(dmuContribUp + dmuContribDn);
448 dBzContrib = 0.5*(dmuContribUp - dmuContribDn);
449 }
450 else if(Mconstrain)
451 { //Fixed M only
452 dmuContrib = 0.;
453 dBzContrib = (dmuNum[0]-dmuNum[1])/(dmuDen[0]-dmuDen[1]);
454 }
455 else
456 { //Fixed N only
457 dmuContrib = (dmuNum[0]+dmuNum[1])/(dmuDen[0]+dmuDen[1]);
458 dBzContrib = 0.;
459 }
460 }
461
462 //Auxiliary hamiltonian gradient:
463 if(grad && eInfo.fillingsUpdate==ElecInfo::FillingsHsub)
464 { for(int q=eInfo.qStart; q<eInfo.qStop; q++)
465 { const QuantumNumber& qnum = eInfo.qnums[q];
466 matrix gradF0 = Hsub[q]-Haux_eigs[q]; //gradient w.r.t fillings except for constraint contributions
467 matrix gradF = gradF0 - eye(eInfo.nBands)*eInfo.muEff(dmuContrib,dBzContrib,q); //gradient w.r.t fillings
468 grad->Haux[q] = qnum.weight * dagger_symmetrize(eInfo.smearGrad(eInfo.muEff(mu,Bz,q), Haux_eigs[q], gradF));
469 if(Kgrad) //Drop the fermiPrime factors in preconditioned gradient:
470 Kgrad->Haux[q] = (-e->cntrl.subspaceRotationFactor) * gradF0;
471 }
472 }
473
474 return relevantFreeEnergy(*e);
475 }
476
477 //Latice derivative
latticeGrad() const478 matrix3<> ElecVars::latticeGrad() const
479 {
480 const matrix3<> id(1.,1.,1.); //identity
481
482 //Compute q-dependent contributions:
483 matrix3<> E_RRT;
484 for(int q=e->eInfo.qStart; q<e->eInfo.qStop; q++)
485 { E_RRT += e->eInfo.qnums[q].weight * (
486 -0.5*Lstress(C[q], F[q]) //contribution to KE stress via laplacian operator
487 - traceinner(Hsub_eigs[q]*F[q], C[q], C[q]).real() * e->gInfo.detR * id); //volume contribution to orthonormality constraint
488
489 //KE-density contribution for meta-GGAs:
490 if(e->exCorr.needsKEdensity())
491 { for(int iDir=0; iDir<3; iDir++)
492 { ColumnBundle VCi = Idag_DiagV_I(D(C[q],iDir), Vtau);
493 for(int jDir=iDir; jDir<3; jDir++)
494 { double tauStress_ij = (-e->eInfo.qnums[q].weight * e->gInfo.dV)
495 * traceinner(F[q], VCi, D(C[q],jDir)).real();
496 E_RRT(iDir,jDir) += tauStress_ij;
497 if(iDir!=jDir)
498 E_RRT(jDir,iDir) += tauStress_ij;
499 }
500 }
501 }
502 }
503 mpiWorld->allReduce(E_RRT, MPIUtil::ReduceSum);
504
505 //Add q-independent contributions:
506 //--- volume contribution in various terms
507 E_RRT += id * (e->ener.E["KE"] + e->ener.E["EH"] + e->ener.E["Exc"] + e->ener.E["EXX"]);
508 //--- Hartree
509 ScalarFieldTilde nTilde = J(get_nTot());
510 E_RRT += 0.5 * e->coulomb->latticeGradient(nTilde, nTilde);
511 //--- Exchange-correlation
512 e->exCorr(get_nXC(), 0, false, &tau, 0, &E_RRT);
513 //--- Exact exchange
514 if(e->exCorr.exxFactor())
515 { double aXX = e->exCorr.exxFactor();
516 double omega = e->exCorr.exxRange();
517 (*e->exx)(aXX, omega, F, C, 0, &E_RRT);
518 }
519 //--- Fluid:
520 if(fluidSolver)
521 { fluidSolver->get_Adiel_and_grad(0, 0, 0, &E_RRT);
522 E_RRT += id * (e->iInfo.getZtot() * fluidSolver->ionWidthMuCorrection()); //from 1/detR on mu correction
523 }
524
525 return E_RRT;
526 }
527
528 //Make phase (and degenerate-subspace rotations) of wavefunctions reproducible
fixPhase(matrix & evecs,const diagMatrix & eigs,const ColumnBundle & C)529 void fixPhase(matrix& evecs, const diagMatrix& eigs, const ColumnBundle& C)
530 { const double tol = 1e-7;
531 //Pick out the head elements:
532 const std::vector<int>& head = C.basis->head;
533 int nSpinor = C.spinorLength();
534 matrix Chead = zeroes(head.size()*nSpinor, C.nCols());
535 for(size_t n=0; n<head.size(); n++)
536 for(int s=0; s<nSpinor; s++)
537 callPref(eblas_zaxpy)(C.nCols(), 1.,
538 C.dataPref() + n + s*C.basis->nbasis, C.colLength(),
539 Chead.dataPref() + nSpinor*n + s, Chead.nRows() );
540 Chead = Chead * evecs;
541 //Hamiltonian for degeneracy breaking (some definite (and unlikely to be symmetric) diagonal in the low G head)
542 diagMatrix headH(Chead.nRows());
543 for(int n=0; n<Chead.nRows(); n++)
544 headH[n] = pow(n, M_PI);
545 //Resolve degeneracies
546 matrix degFix = eye(C.nCols());
547 bool degFound = false;
548 for(int bStart=0; bStart<C.nCols()-1;)
549 { int bStop=bStart;
550 while(bStop<eigs.nCols() && eigs[bStop]<eigs[bStart]+tol) bStop++;
551 if(bStop-bStart > 1) //degeneracy
552 { degFound = true;
553 matrix CheadSub = Chead(0,Chead.nRows(), bStart,bStop);
554 matrix degEvecs; diagMatrix degEigs;
555 (dagger(CheadSub) * headH * CheadSub).diagonalize(degEvecs, degEigs);
556 degFix.set(bStart,bStop, bStart,bStop, degEvecs);
557 }
558 bStart = bStop;
559 }
560 if(degFound)
561 { evecs = evecs*degFix;
562 Chead = Chead*degFix;
563 }
564 //Fix phase:
565 matrix phaseFix = eye(C.nCols());
566 for(int b=0; b<C.nCols(); b++)
567 { complex phase;
568 double normPrev = 0;
569 for(int n=0; n<Chead.nRows(); n++)
570 { const complex c = Chead(n,b);
571 if(c.norm() > normPrev)
572 { phase = c.conj()/c.abs();
573 normPrev = c.norm();
574 }
575 }
576 phaseFix.set(b,b, phase);
577 }
578 evecs = evecs*phaseFix;
579 }
580
setEigenvectors()581 void ElecVars::setEigenvectors()
582 { const ElecInfo& eInfo = e->eInfo;
583 logPrintf("Setting wave functions to eigenvectors of Hamiltonian\n"); logFlush();
584 for(int q=eInfo.qStart; q<eInfo.qStop; q++)
585 {
586 fixPhase(Hsub_evecs[q], Hsub_eigs[q], C[q]);
587 C[q] = C[q] * Hsub_evecs[q];
588 for(matrix& VdagCq_sp: VdagC[q])
589 if(VdagCq_sp) VdagCq_sp = VdagCq_sp * Hsub_evecs[q];
590
591 if(eInfo.fillingsUpdate==ElecInfo::FillingsHsub && !e->cntrl.scf)
592 Haux_eigs[q] = Hsub_eigs[q];
593
594 //Apply corresponding changes to Hsub:
595 Hsub[q] = Hsub_eigs[q]; //now diagonal
596 Hsub_evecs[q] = eye(eInfo.nBands);
597 }
598 }
599
KEdensity() const600 ScalarFieldArray ElecVars::KEdensity() const
601 { ScalarFieldArray tau(n.size());
602 //Compute KE density from valence electrons:
603 for(int q=e->eInfo.qStart; q<e->eInfo.qStop; q++)
604 for(int iDir=0; iDir<3; iDir++)
605 tau += (0.5*C[q].qnum->weight) * diagouterI(F[q], D(C[q],iDir), tau.size(), &e->gInfo);
606 for(ScalarField& tau_s: tau)
607 { nullToZero(tau_s, e->gInfo);
608 tau_s->allReduceData(mpiWorld, MPIUtil::ReduceSum);
609 }
610 e->symm.symmetrize(tau); //Symmetrize
611 //Add core KE density model:
612 if(e->iInfo.tauCore)
613 { int nSpins = std::min(2, int(tau.size())); //don't add to Re/Im(UpDn) in vector-spin mode
614 for(int s=0; s<nSpins; s++)
615 tau[s] += (1./nSpins) * e->iInfo.tauCore; //add core KE density
616 }
617 return tau;
618 }
619
calcDensity() const620 ScalarFieldArray ElecVars::calcDensity() const
621 { ScalarFieldArray density(n.size());
622 //Runs over all states and accumulates density to the corresponding spin channel of the total density
623 e->iInfo.augmentDensityInit();
624 for(int q=e->eInfo.qStart; q<e->eInfo.qStop; q++)
625 { density += e->eInfo.qnums[q].weight * diagouterI(F[q], C[q], density.size(), &e->gInfo);
626 e->iInfo.augmentDensitySpherical(e->eInfo.qnums[q], F[q], VdagC[q]); //pseudopotential contribution
627 }
628 e->iInfo.augmentDensityGrid(density);
629 for(ScalarField& ns: density)
630 { nullToZero(ns, e->gInfo);
631 ns->allReduceData(mpiWorld, MPIUtil::ReduceSum);
632 }
633 e->symm.symmetrize(density);
634 return density;
635 }
636
orthonormalize(int q,matrix * extraRotation)637 void ElecVars::orthonormalize(int q, matrix* extraRotation)
638 { assert(e->eInfo.isMine(q));
639 VdagC[q].clear();
640 matrix rot = invsqrt(C[q]^O(C[q], &VdagC[q])); //Compute U:
641 if(extraRotation) *extraRotation = (rot = rot * (*extraRotation)); //set rot and extraRotation to the net transformation
642 C[q] = C[q] * rot;
643 e->iInfo.project(C[q], VdagC[q], &rot); //update the atomic projections
644 }
645
applyHamiltonian(int q,const diagMatrix & Fq,ColumnBundle & HCq,Energies & ener,bool need_Hsub)646 double ElecVars::applyHamiltonian(int q, const diagMatrix& Fq, ColumnBundle& HCq, Energies& ener, bool need_Hsub)
647 { assert(C[q]); //make sure wavefunction is available for this state
648 const QuantumNumber& qnum = e->eInfo.qnums[q];
649 std::vector<matrix> HVdagCq(e->iInfo.species.size());
650
651 //Propagate grad_n (Vscloc) to HCq (which is grad_Cq upto weights and fillings) if required
652 if(need_Hsub)
653 { HCq += Idag_DiagV_I(C[q], Vscloc); //Accumulate Idag Diag(Vscloc) I C
654 e->iInfo.augmentDensitySphericalGrad(qnum, VdagC[q], HVdagCq); //Contribution via pseudopotential density augmentation
655 if(e->exCorr.needsKEdensity() && Vtau[qnum.index()]) //Contribution via orbital KE:
656 { for(int iDir=0; iDir<3; iDir++)
657 HCq -= (0.5*e->gInfo.dV) * D(Idag_DiagV_I(D(C[q],iDir), Vtau), iDir);
658 }
659 if(e->eInfo.hasU) //Contribution via atomic density matrix projections (DFT+U)
660 e->iInfo.rhoAtom_grad(C[q], U_rhoAtom, HCq);
661
662 //Exact exchange in fixed H mode (totalE mode handled above):
663 //--- note exx->setOccupied() must be set beforehand
664 if(e->exCorr.exxFactor() and e->cntrl.fixed_H)
665 { double aXX = e->exCorr.exxFactor();
666 double omega = e->exCorr.exxRange();
667 e->exx->applyHamiltonian(aXX, omega, q, C[q], HCq);
668 }
669 }
670
671 //Kinetic energy:
672 double KEq;
673 { ColumnBundle LCq = L(C[q]);
674 if(HCq) HCq += (-0.5) * LCq;
675 KEq = qnum.weight * (-0.5) * traceinner(Fq, C[q], LCq).real();
676 ener.E["KE"] += KEq;
677 }
678
679 //Nonlocal pseudopotentials:
680 ener.E["Enl"] += qnum.weight * e->iInfo.EnlAndGrad(qnum, Fq, VdagC[q], HVdagCq);
681 if(HCq) e->iInfo.projectGrad(HVdagCq, C[q], HCq);
682
683 //Compute subspace hamiltonian if needed:
684 if(need_Hsub)
685 { Hsub[q] = C[q] ^ HCq;
686 Hsub[q].diagonalize(Hsub_evecs[q], Hsub_eigs[q]);
687 }
688 return KEq;
689 }
690