1 /*-------------------------------------------------------------------
2 Copyright 2011 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 #include <commands/command.h>
21 #include <electronic/Everything.h>
22 
23 //! @file elec_misc.cpp Miscellaneous properties of the electronic system
24 
25 struct CommandElecCutoff : public Command
26 {
CommandElecCutoffCommandElecCutoff27 	CommandElecCutoff() : Command("elec-cutoff", "jdftx/Electronic/Parameters")
28 	{
29 		format = "<Ecut> [<EcutRho>=0]";
30 		comments = "Electronic planewave cutoff in Hartree. Optionally specify charge density cutoff\n"
31 			"<EcutRho> in hartrees. If unspecified or zero, EcutRho is taken to be 4*Ecut.";
32 		hasDefault = true;
33 	}
34 
processCommandElecCutoff35 	void process(ParamList& pl, Everything& e)
36 	{	pl.get(e.cntrl.Ecut, 20., "Ecut");
37 		pl.get(e.cntrl.EcutRho, 0., "EcutRho");
38 		if(e.cntrl.EcutRho && e.cntrl.EcutRho < 4*e.cntrl.Ecut)
39 			throw string("<EcutRho> must be at least 4 <Ecut>");
40 	}
41 
printStatusCommandElecCutoff42 	void printStatus(Everything& e, int iRep)
43 	{	logPrintf("%lg", e.cntrl.Ecut);
44 		if(e.cntrl.EcutRho)
45 			logPrintf(" %lg", e.cntrl.EcutRho);
46 	}
47 }
48 commandElecCutoff;
49 
50 //-------------------------------------------------------------------------------------------------
51 
52 struct CommandFftbox : public Command
53 {
CommandFftboxCommandFftbox54 	CommandFftbox() : Command("fftbox", "jdftx/Electronic/Parameters")
55 	{
56 		format = "<S0> <S1> <S2>";
57 		comments = "Manually override the real space grid dimensions used for scalar fields.\n"
58 		 "(The default values are calculated based on the EcutRho setting from elec-cutoff).";
59 	}
60 
processCommandFftbox61 	void process(ParamList& pl, Everything& e)
62 	{	pl.get(e.gInfo.S[0], 0, "S0", true);
63 		pl.get(e.gInfo.S[1], 0, "S1", true);
64 		pl.get(e.gInfo.S[2], 0, "S2", true);
65 	}
66 
printStatusCommandFftbox67 	void printStatus(Everything& e, int iRep)
68 	{	logPrintf("%d %d %d", e.gInfo.S[0], e.gInfo.S[1], e.gInfo.S[2]);
69 	}
70 }
71 commandFftbox;
72 
73 //-------------------------------------------------------------------------------------------------
74 
75 struct CommandElecNbands : public Command
76 {
CommandElecNbandsCommandElecNbands77 	CommandElecNbands() : Command("elec-n-bands", "jdftx/Electronic/Parameters")
78 	{
79 		format = "<n>";
80 		comments = "Manually specify the number of bands.\n\n"
81 			"(Default: set nBands assuming insulator, or in calculations with\n"
82 			"fermi-fillings, set equal to total number of atomic orbitals.)";
83 	}
84 
processCommandElecNbands85 	void process(ParamList& pl, Everything& e)
86 	{	pl.get(e.eInfo.nBands, 0, "n", true);
87 		if(e.eInfo.nBands<=0) throw string("<n> must be positive.\n");
88 	}
89 
printStatusCommandElecNbands90 	void printStatus(Everything& e, int iRep)
91 	{	logPrintf("%d", e.eInfo.nBands);
92 	}
93 }
94 commandElecNbands;
95 
96 //-------------------------------------------------------------------------------------------------
97 
98 struct CommandDavidsonBandRatio : public Command
99 {
CommandDavidsonBandRatioCommandDavidsonBandRatio100 	CommandDavidsonBandRatio() : Command("davidson-band-ratio", "jdftx/Electronic/Optimization")
101 	{
102 		format = "[<ratio>=1.1]";
103 		comments =
104 			"Ratio of number of bands in the Davidson working set to the\n"
105 			"number of actual bands in the calculation. Increasing this\n"
106 			"number should improve eigen-problem convergence at the\n"
107 			"expense of increased memory requirements.";
108 		hasDefault = true;
109 	}
110 
processCommandDavidsonBandRatio111 	void process(ParamList& pl, Everything& e)
112 	{	pl.get(e.cntrl.davidsonBandRatio, 1.1, "ratio");
113 		if(e.cntrl.davidsonBandRatio < 1.)
114 			throw string("<ratio> must be at least 1");
115 	}
116 
printStatusCommandDavidsonBandRatio117 	void printStatus(Everything& e, int iRep)
118 	{	logPrintf("%lg", e.cntrl.davidsonBandRatio);
119 	}
120 }
121 commandDavidsonBandRatio;
122 
123 //-------------------------------------------------------------------------------------------------
124 
125 struct CommandLcaoParams : public Command
126 {
CommandLcaoParamsCommandLcaoParams127 	CommandLcaoParams() : Command("lcao-params", "jdftx/Initialization")
128 	{
129 		format = "[<nIter>=-1] [<Ediff>=1e-6] [<smeaingWidth>=1e-3]";
130 		comments = "Control LCAO wavefunction initialization:\n"
131 			"+ <nIter>: maximum subspace iterations in LCAO (negative => auto-select)\n"
132 			"+ <Ediff>: energy-difference convergence threshold for subspace iteration\n"
133 			"+ <smearingWidth>: smearing width for the subspace iteration for constant fillings calculations.\n"
134 			"   If present, the smearing width from elec-smearing overrides this.\n";
135 		hasDefault = true;
136 	}
137 
processCommandLcaoParams138 	void process(ParamList& pl, Everything& e)
139 	{	pl.get(e.eVars.lcaoIter, -1, "nIter");
140 		pl.get(e.eVars.lcaoTol, 1e-6, "Ediff");
141 		pl.get(e.eInfo.smearingWidth, 1e-3, "smearingWidth");
142 		if(e.eInfo.smearingWidth<=0) throw string("<smearingWidth> must be positive.\n");
143 	}
144 
printStatusCommandLcaoParams145 	void printStatus(Everything& e, int iRep)
146 	{	logPrintf("%d %lg %lg", e.eVars.lcaoIter, e.eVars.lcaoTol, e.eInfo.smearingWidth);
147 	}
148 }
149 commandLcaoParams;
150 
151 //-------------------------------------------------------------------------------------------------
152 
153 EnumStringMap<SpinType> spinMap
154 (	SpinNone,   "no-spin",
155 	SpinZ,      "z-spin",
156 	SpinVector, "vector-spin",
157 	SpinOrbit,  "spin-orbit"
158 );
159 
160 EnumStringMap<SpinType> spinDescMap
161 (	SpinNone,   "Unpolarized calculation",
162 	SpinZ,      "Spin-polarized calculation",
163 	SpinVector, "Non-collinear magnetism (supports spin-orbit coupling)",
164 	SpinOrbit,  "Non-collinear without magnetization, to allow for spin-orbit"
165 );
166 
167 struct CommandSpintype : public Command
168 {
CommandSpintypeCommandSpintype169 	CommandSpintype() : Command("spintype", "jdftx/Electronic/Parameters")
170 	{
171 		format = "<type>=" + spinMap.optionList();
172 		comments = "Select spin-polarization type:"
173 			+ addDescriptions(spinMap.optionList(), linkDescription(spinMap, spinDescMap));
174 		hasDefault = true;
175 	}
176 
processCommandSpintype177 	void process(ParamList& pl, Everything& e)
178 	{	pl.get(e.eInfo.spinType, SpinNone, spinMap, "type");
179 	}
180 
printStatusCommandSpintype181 	void printStatus(Everything& e, int iRep)
182 	{	fputs(spinMap.getString(e.eInfo.spinType), globalLog);
183 	}
184 }
185 commandSpintype;
186 
187 //-------------------------------------------------------------------------------------------------
188 
189 //Base class for fix-electron-density and fix-electron-potential
190 struct CommandFixElectronHamiltonian : public Command
191 {
CommandFixElectronHamiltonianCommandFixElectronHamiltonian192     CommandFixElectronHamiltonian(string name) : Command("fix-electron-"+name, "jdftx/Electronic/Optimization")
193 	{
194 		format = "<filenamePattern>";
195 		comments = "Perform band structure calculations at fixed electron " + name + "\n"
196 			"(or spin " + name + ") read from the specified <filenamePattern>.\n"
197 			"This pattern must include $VAR which will be replaced by the appropriate\n"
198 			"variable names accounting for spin-polarization (same as used for dump).\n"
199 			"Meta-GGA calculations will also require the corresponding kinetic " + name + ".";
200 
201 		require("spintype");
202 		forbid("elec-ex-corr-compare");
203 		forbid("electronic-scf");
204 		forbid("vibrations");
205 		forbid("dump-only");
206 		forbid("target-mu");
207 		forbid("target-Bz");
208 	}
209 
processCommonCommandFixElectronHamiltonian210 	void processCommon(ParamList& pl, Everything& e, string& targetFilenamePattern)
211 	{	pl.get(targetFilenamePattern, string(), "filenamePattern", true);
212 		if(targetFilenamePattern.find("$VAR") == string::npos)
213 			throw string("<filenamePattern> must contain $VAR");
214 		e.cntrl.fixed_H = true;
215 	}
216 
printStatusCommonCommandFixElectronHamiltonian217 	void printStatusCommon(Everything& e, int iRep, const string& targetFilenamePattern)
218 	{	logPrintf("%s", targetFilenamePattern.c_str());
219 	}
220 };
221 
222 struct CommandFixElectronDensity : public CommandFixElectronHamiltonian
CommandFixElectronDensityCommandFixElectronDensity223 {   CommandFixElectronDensity() : CommandFixElectronHamiltonian("density") { forbid("fix-electron-potential"); }
224 	void process(ParamList& pl, Everything& e) { processCommon(pl, e, e.eVars.nFilenamePattern); }
225 	void printStatus(Everything& e, int iRep) { printStatusCommon(e, iRep, e.eVars.nFilenamePattern); }
226 }
227 commandFixElectronDensity;
228 
229 struct CommandFixElectronPotential : public CommandFixElectronHamiltonian
CommandFixElectronPotentialCommandFixElectronPotential230 {   CommandFixElectronPotential() : CommandFixElectronHamiltonian("potential") { forbid("fix-electron-density"); }
231 	void process(ParamList& pl, Everything& e) { processCommon(pl, e, e.eVars.VFilenamePattern); }
232 	void printStatus(Everything& e, int iRep) { printStatusCommon(e, iRep, e.eVars.VFilenamePattern); }
233 }
234 commandFixElectronPotential;
235 
236 //-------------------------------------------------------------------------------------------------
237 
238 struct CommandConvergeEmptyStates : public Command
239 {
CommandConvergeEmptyStatesCommandConvergeEmptyStates240 	CommandConvergeEmptyStates() : Command("converge-empty-states", "jdftx/Electronic/Optimization")
241 	{
242 		format = "yes|no";
243 		comments = "Whether to converge empty states after each electronic optimization (default no).\n"
244 			"Not required unless empty states are used in post-processing and need to be accurate.\n"
245 			"This is a shortcut to running a bandstructure calculation after a total energy\n"
246 			"or SCF calculation, and helps simplify workflow for DOS, polarizability, wannier\n"
247 			"and electron-phonon matrix element calculations.";
248 	}
249 
processCommandConvergeEmptyStates250 	void process(ParamList& pl, Everything& e)
251 	{	pl.get(e.cntrl.convergeEmptyStates, false, boolMap, "shouldConverge", true);
252 	}
253 
printStatusCommandConvergeEmptyStates254 	void printStatus(Everything& e, int iRep)
255 	{	logPrintf("%s", boolMap.getString(e.cntrl.convergeEmptyStates));
256 	}
257 }
258 commandConvergeEmptyStates;
259 
260 //-------------------------------------------------------------------------------------------------
261 
262 struct CommandWavefunctionDrag : public Command
263 {
CommandWavefunctionDragCommandWavefunctionDrag264 	CommandWavefunctionDrag() : Command("wavefunction-drag", "jdftx/Ionic/Optimization")
265 	{
266 		format = "yes|no";
267 		comments =
268 			"Drag wavefunctions when ions are moved using atomic orbital projections (yes by default).";
269 	}
270 
processCommandWavefunctionDrag271 	void process(ParamList& pl, Everything& e)
272 	{	pl.get(e.cntrl.dragWavefunctions, true, boolMap, "shouldDrag", true);
273 	}
274 
printStatusCommandWavefunctionDrag275 	void printStatus(Everything& e, int iRep)
276 	{	logPrintf("%s", boolMap.getString(e.cntrl.dragWavefunctions));
277 	}
278 }
279 commandWavefunctionDrag;
280 
281 //-------------------------------------------------------------------------------------------------
282 
283 struct CommandCacheProjectors : public Command
284 {
CommandCacheProjectorsCommandCacheProjectors285 	CommandCacheProjectors() : Command("cache-projectors", "jdftx/Miscellaneous")
286 	{
287 		format = "yes|no";
288 		comments =
289 			"Cache nonlocal-pseudopotential projectors (yes by default); turn off to save memory.";
290 	}
291 
processCommandCacheProjectors292 	void process(ParamList& pl, Everything& e)
293 	{	pl.get(e.cntrl.cacheProjectors, true, boolMap, "shouldCache", true);
294 	}
295 
printStatusCommandCacheProjectors296 	void printStatus(Everything& e, int iRep)
297 	{	logPrintf("%s", boolMap.getString(e.cntrl.cacheProjectors));
298 	}
299 }
300 commandCacheProjectors;
301 
302 //-------------------------------------------------------------------------------------------------
303 
304 struct CommandBasis : public Command
305 {
CommandBasisCommandBasis306 	CommandBasis() : Command("basis", "jdftx/Electronic/Parameters")
307 	{
308 		format = "<kdep>=" + kdepMap.optionList();
309 		comments = "Basis set at each k-point (default), or single basis set at gamma point";
310 		hasDefault = true;
311 	}
312 
processCommandBasis313 	void process(ParamList& pl, Everything& e)
314 	{	pl.get(e.cntrl.basisKdep, BasisKpointDep, kdepMap, "kdep");
315 	}
316 
printStatusCommandBasis317 	void printStatus(Everything& e, int iRep)
318 	{	fputs(kdepMap.getString(e.cntrl.basisKdep), globalLog);
319 	}
320 }
321 commandBasis;
322 
323 
324 //-------------------------------------------------------------------------------------------------
325 
326 static EnumStringMap<ElecEigenAlgo> elecEigenMap(ElecEigenCG, "CG", ElecEigenDavidson, "Davidson");
327 
328 struct CommandElecEigenAlgo : public Command
329 {
CommandElecEigenAlgoCommandElecEigenAlgo330     CommandElecEigenAlgo() : Command("elec-eigen-algo", "jdftx/Electronic/Optimization")
331 	{
332 		format = "<algo>=" + elecEigenMap.optionList();
333 		comments = "Selects eigenvalue algorithm for band-structure calculations or inner loop of SCF.";
334 		hasDefault = true;
335 	}
336 
processCommandElecEigenAlgo337 	void process(ParamList& pl, Everything& e)
338 	{	pl.get(e.cntrl.elecEigenAlgo, ElecEigenDavidson, elecEigenMap, "algo");
339 	}
340 
printStatusCommandElecEigenAlgo341 	void printStatus(Everything& e, int iRep)
342 	{	fputs(elecEigenMap.getString(e.cntrl.elecEigenAlgo), globalLog);
343 	}
344 }
345 commandElecEigenAlgo;
346 
347 //-------------------------------------------------------------------------------------------------
348 
349 struct CommandRhoExternal : public Command
350 {
CommandRhoExternalCommandRhoExternal351 	CommandRhoExternal() : Command("rhoExternal", "jdftx/Coulomb interactions")
352 	{
353 		format = "<filename> [<includeSelfEnergy>=yes|no]";
354 		comments =
355 			"Include an external charge density [electrons/bohr^3] (real space binary)\n"
356 			"which interacts electrostatically with the electrons, nuclei and fluid.\n"
357 			"\n"
358 			"If <includeSelfEnergy>=yes (default no), then the Coulomb self-energy\n"
359 			"of rhoExternal is included in the output energy.";
360 	}
361 
processCommandRhoExternal362 	void process(ParamList& pl, Everything& e)
363 	{	pl.get(e.eVars.rhoExternalFilename, string(), "filename", true);
364 		pl.get(e.eVars.rhoExternalSelfEnergy, false, boolMap, "includeSelfEnergy");
365 	}
366 
printStatusCommandRhoExternal367 	void printStatus(Everything& e, int iRep)
368 	{	logPrintf("%s %s", e.eVars.rhoExternalFilename.c_str(), boolMap.getString(e.eVars.rhoExternalSelfEnergy));
369 	}
370 }
371 commandRhoExternal;
372 
373 //-------------------------------------------------------------------------------------------------
374 
375 struct CommandVexternal : public Command
376 {
CommandVexternalCommandVexternal377 	CommandVexternal() : Command("Vexternal", "jdftx/Electronic/Parameters")
378 	{
379 		format = "<filename> | <filenameUp> <filenameDn>";
380 		comments =
381 			"Include an external potential (in hartrees) for the electrons\n"
382 			"(real space binary). Specify two files if V is spin-polarized.";
383 	}
384 
processCommandVexternal385 	void process(ParamList& pl, Everything& e)
386 	{	e.eVars.VexternalFilename.resize(1);
387 		pl.get(e.eVars.VexternalFilename[0], string(), "filename", true);
388 		//Check if a second file has been specified:
389 		string filenameDn;
390 		pl.get(filenameDn, string(), "filenameDn");
391 		if(filenameDn.length())
392 			e.eVars.VexternalFilename.push_back(filenameDn);
393 	}
394 
printStatusCommandVexternal395 	void printStatus(Everything& e, int iRep)
396 	{	for(const string& filename: e.eVars.VexternalFilename)
397 			logPrintf("%s ", filename.c_str());
398 	}
399 }
400 commandVexternal;
401 
402 //-------------------------------------------------------------------------------------------------
403 
404 struct CommandBoxPotential : public Command
405 {
CommandBoxPotentialCommandBoxPotential406 	CommandBoxPotential() : Command("box-potential", "jdftx/Electronic/Parameters")
407 	{
408 		format = "xmin xmax ymin ymax zmin zmax Vin Vout [<convolve_radius>=0.1]";
409 		comments =
410 			"Include an step-function shaped external potential (in hartrees) for the electrons";
411 
412 		allowMultiple = true;
413 	}
414 
processCommandBoxPotential415 	void process(ParamList& pl, Everything& e)
416 	{	ElecVars::BoxPotential bP;
417 		const char* dirNames[3] = { "x", "y", "z" };
418 		for(int k=0; k<3; k++)
419 		{	pl.get(bP.min[k], 0., dirNames[k]+string("min"), true);
420 			pl.get(bP.max[k], 0., dirNames[k]+string("max"), true);
421 			if(bP.max[k]<bP.min[k])
422 				throw(string("max must be smaller than min for each dimension"));
423 		}
424 		pl.get(bP.Vin, 0., "Vin", true);
425 		pl.get(bP.Vout, 0., "Vout", true);
426 		pl.get(bP.convolve_radius, 0.2, "convolve_radius", false);
427 		e.eVars.boxPot.push_back(bP);
428 	}
429 
printStatusCommandBoxPotential430 	void printStatus(Everything& e, int iRep)
431 	{	const ElecVars::BoxPotential& bP = e.eVars.boxPot[iRep];
432 		logPrintf("%.5g %.5g %.5g %.5g %.5g %.5g    %.5g %.5g  %.5g",
433 			 bP.min[0], bP.max[0], bP.min[1], bP.max[1], bP.min[2], bP.max[2],
434 			 bP.Vin, bP.Vout, bP.convolve_radius);
435 	}
436 }
437 commandBoxPot;
438 
439 //-------------------------------------------------------------------------------------------------
440 
441 struct CommandElectricField : public Command
442 {
CommandElectricFieldCommandElectricField443 	CommandElectricField() : Command("electric-field", "jdftx/Electronic/Parameters")
444 	{
445 		format = "<Ex> <Ey> <Ez>";
446 		comments =
447 			"Apply an external electric field (in Cartesian coordinates, atomic\n"
448 			"units [Eh/e/a_0] and electron-is-positive sign convention).\n\n"
449 			"In truncated directions, the field will be applied as a ramp potential,\n"
450 			"and for periodic directions, it will be applied as a plane wave with\n"
451 			"the smallest commensurate wave vector and amplitude set by peak field.\n\n"
452 			"Coulomb truncation, if any, must be in embedded mode (command coulomb-truncation-embed).\n"
453 			"Symmetries will be automatically reduced to account for this field.";
454 	}
455 
processCommandElectricField456 	void process(ParamList& pl, Everything& e)
457 	{	pl.get(e.coulombParams.Efield[0], 0., "Ex", true);
458 		pl.get(e.coulombParams.Efield[1], 0., "Ey", true);
459 		pl.get(e.coulombParams.Efield[2], 0., "Ez", true);
460 	}
461 
printStatusCommandElectricField462 	void printStatus(Everything& e, int iRep)
463 	{	for(int k=0; k<3; k++) logPrintf("%lg ", e.coulombParams.Efield[k]);
464 	}
465 }
466 commandElectricField;
467