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