1 /*------------------------------------------------------------------- 2 Copyright 2012 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 EnumStringMap<CoulombParams::ExchangeRegularization> exRegMethodMap 24 ( CoulombParams::None, "None", 25 CoulombParams::AuxiliaryFunction, "AuxiliaryFunction", 26 CoulombParams::ProbeChargeEwald, "ProbeChargeEwald", 27 CoulombParams::SphericalTruncated, "SphericalTruncated", 28 CoulombParams::WignerSeitzTruncated, "WignerSeitzTruncated" 29 ); 30 31 EnumStringMap<CoulombParams::Geometry> truncationTypeMap 32 ( CoulombParams::Periodic, "Periodic", 33 CoulombParams::Slab, "Slab", 34 CoulombParams::Cylindrical, "Cylindrical", 35 CoulombParams::Wire, "Wire", 36 CoulombParams::Isolated, "Isolated", 37 CoulombParams::Spherical, "Spherical" 38 ); 39 40 EnumStringMap<int> truncationDirMap 41 ( 0, "100", 42 1, "010", 43 2, "001" 44 ); 45 46 struct CommandCoulombInteraction : public Command 47 { CommandCoulombInteractionCommandCoulombInteraction48 CommandCoulombInteraction() : Command("coulomb-interaction", "jdftx/Coulomb interactions") 49 { 50 format = "<truncationType> [<args> ...]"; 51 comments = 52 "Optionally truncate the coulomb interaction. The available <truncationType>'s\n" 53 "and the corresponding arguments are:\n" 54 "\n+ Periodic\n\n" 55 " Standard periodic (untruncated) coulomb interaction (Default)\n" 56 "\n+ Slab <dir>=" + truncationDirMap.optionList() + "\n\n" 57 " Truncate coulomb interaction along the specified lattice direction.\n" 58 " The other two lattice directions must be orthogonal to this one.\n" 59 " Useful for slab-like geometries.\n" 60 "\n+ Cylindrical <dir>=" + truncationDirMap.optionList() + " [<Rc>=0]\n\n" 61 " Truncate coulomb interaction on a cylinder of radius <Rc> bohrs\n" 62 " with axis along specified lattice direction. The other two lattice\n" 63 " directions must be orthogonal to this one. Rc=0 is understood to be\n" 64 " the in-radius of the 2D Wigner-Seitz cell perpendicular to <dir>.\n" 65 "\n+ Wire <dir>=" + truncationDirMap.optionList() + "\n\n" 66 " Truncate coulomb interaction on the 2D Wigner-Seitz cell in the plane\n" 67 " perpendicular to <dir>. The other two lattice directions must be\n" 68 " orthogonal to this one. Useful for wire-like geometries.\n" 69 "\n+ Isolated\n\n" 70 " Truncate coulomb interaction on the 3D Wigner-Seitz cell.\n" 71 "\n+ Spherical [<Rc>=0]\n\n" 72 " Truncate coulomb interaction on a sphere of radius <Rc> bohrs.\n" 73 " Rc=0 is understood to be the in-radius of the Wigner-Seitz cell.\n" 74 "\n" 75 "For all the truncated modes, the charge density must be confined to a\n" 76 "maximum separation of L/2 in each truncated direction, where L is the\n" 77 "length of the unit cell in that direction or 2 Rc for Spherical and\n" 78 "Cylindrical modes. The center of the charge density is not important\n" 79 "and may cross unit cell boundaries."; 80 hasDefault = true; 81 } 82 processCommandCoulombInteraction83 void process(ParamList& pl, Everything& e) 84 { CoulombParams& cp = e.coulombParams; 85 pl.get(cp.geometry, CoulombParams::Periodic, truncationTypeMap, "truncationType"); 86 if(cp.geometry==CoulombParams::Periodic) return; //no parameters 87 //Get direction for the partially periodic modes: 88 if(cp.geometry==CoulombParams::Slab 89 || cp.geometry==CoulombParams::Wire 90 || cp.geometry==CoulombParams::Cylindrical) 91 pl.get(cp.iDir, 0, truncationDirMap, "dir", true); 92 //Get optional radius for the cylindrical/spherical modes: 93 if(cp.geometry==CoulombParams::Cylindrical 94 || cp.geometry==CoulombParams::Spherical) 95 pl.get(cp.Rc, 0., "Rc"); 96 } 97 printStatusCommandCoulombInteraction98 void printStatus(Everything& e, int iRep) 99 { CoulombParams& cp = e.coulombParams; 100 logPrintf("%s", truncationTypeMap.getString(cp.geometry)); 101 if(cp.geometry==CoulombParams::Periodic) return; //no parameters 102 //Print direction for the partially periodic modes: 103 if(cp.geometry==CoulombParams::Slab 104 || cp.geometry==CoulombParams::Wire 105 || cp.geometry==CoulombParams::Cylindrical) 106 logPrintf(" %s", truncationDirMap.getString(cp.iDir)); 107 //Print optional radius for the cylindrical/spherical modes: 108 if(cp.geometry==CoulombParams::Cylindrical 109 || cp.geometry==CoulombParams::Spherical) 110 logPrintf(" %lg", cp.Rc); 111 } 112 } 113 commandCoulombInteraction; 114 115 116 struct CommandCoulombTruncationEmbed : public Command 117 { CommandCoulombTruncationEmbedCommandCoulombTruncationEmbed118 CommandCoulombTruncationEmbed() : Command("coulomb-truncation-embed", "jdftx/Coulomb interactions") 119 { 120 format = "<c0> <c1> <c2>"; 121 comments = 122 "Compute truncated Coulomb interaction in a double-sized box (doubled only\n" 123 "along truncated directions). This relaxes the L/2 localization constraint\n" 124 "otherwise required by truncated potentials (see command coulomb-interaction),\n" 125 "but breaks translational invariance and requires the specification of a center.\n" 126 "\n" 127 "Coordinate system for center (<c0> <c1> <c2>) is as specified by coords-type.\n" 128 "\n" 129 "Default: not enabled; coulomb-interaction employs translationally invariant scheme"; 130 131 hasDefault = false; 132 require("coulomb-interaction"); 133 //Dependencies due to coordinate system option: 134 require("latt-scale"); 135 require("coords-type"); 136 } 137 processCommandCoulombTruncationEmbed138 void process(ParamList& pl, Everything& e) 139 { e.coulombParams.embed = true; 140 vector3<>& c = e.coulombParams.embedCenter; 141 pl.get(c[0], 0., "c0", true); 142 pl.get(c[1], 0., "c1", true); 143 pl.get(c[2], 0., "c2", true); 144 if(e.iInfo.coordsType==CoordsCartesian) c = inv(e.gInfo.R) * c; //Transform coordinates if necessary 145 if(e.coulombParams.geometry==CoulombParams::Periodic) 146 e.coulombParams.embed = false; //No embedding, just use to specify center 147 } 148 printStatusCommandCoulombTruncationEmbed149 void printStatus(Everything& e, int iRep) 150 { vector3<> c = e.coulombParams.embedCenter; 151 if(e.iInfo.coordsType==CoordsCartesian) c = e.gInfo.R * c; //Print in coordinate system chosen by user 152 logPrintf("%lg %lg %lg", c[0], c[1], c[2]); 153 } 154 } 155 commandCoulombTruncationEmbed; 156 157 158 struct CommandCoulombTruncationIonMargin : public Command 159 { CommandCoulombTruncationIonMarginCommandCoulombTruncationIonMargin160 CommandCoulombTruncationIonMargin() : Command("coulomb-truncation-ion-margin", "jdftx/Coulomb interactions") 161 { 162 format = "<margin>"; 163 comments = 164 "Extra margin (in bohrs) around the ions, when checking localization constraints\n" 165 "for truncated Coulomb potentials (see command coulomb-interaction). Set to a typical\n" 166 "distance from nuclei where the electron density becomes negligible, so as to\n" 167 "ensure the electron density satisfies those localization constraints.\n" 168 "(Default: 5 bohrs, minimum allowed: 1 bohr)"; 169 hasDefault = false; 170 } 171 processCommandCoulombTruncationIonMargin172 void process(ParamList& pl, Everything& e) 173 { pl.get(e.coulombParams.ionMargin, 0., "margin", true); 174 if(e.coulombParams.ionMargin < 1.) throw string("<margin> must be at least 1 bohr."); 175 } 176 printStatusCommandCoulombTruncationIonMargin177 void printStatus(Everything& e, int iRep) 178 { logPrintf("%lg", e.coulombParams.ionMargin); 179 } 180 } 181 commandCoulombTruncationIonMargin; 182 183 184 struct CommandExchangeRegularization : public Command 185 { CommandExchangeRegularizationCommandExchangeRegularization186 CommandExchangeRegularization() : Command("exchange-regularization", "jdftx/Coulomb interactions") 187 { 188 format = "<method>=" + exRegMethodMap.optionList(); 189 comments = 190 "Regularization / singularity correction method for exact exchange.\n" 191 "The allowed methods and defaults depend on the setting of <geometry>\n" 192 "in command coulomb-interaction\n" 193 "\n+ None\n\n" 194 " No singularity correction: default and only option for non-periodic\n" 195 " systems with no G=0 singularity (<geometry> = Spherical / Isolated).\n" 196 " This is allowed for fully or partially periodic systems, but is not\n" 197 " recommended due to extremely poor convergence with number of k-points.\n" 198 "\n+ AuxiliaryFunction\n\n" 199 " G=0 modification based on numerical integrals of an auxiliary\n" 200 " function, as described in Ref. \\cite AuxFunc-Carrier\n" 201 " Allowed for 3D/2D/1D periodic systems.\n" 202 "\n+ ProbeChargeEwald\n\n" 203 " G=0 modification based on the Ewald sum of a single point charge\n" 204 " per k-point sampled supercell. Valid for 3D/2D/1D periodic systems.\n" 205 "\n+ SphericalTruncated\n\n" 206 " Truncate exchange kernel on a sphere whose volume equals the k-point\n" 207 " sampled supercell, as in Ref. \\cite SphericalTruncation.\n" 208 " Allowed for any (partially) periodic <geometry>, but is recommended\n" 209 " only when the k-point sampled supercell is roughly isotropic.\n" 210 "\n+ WignerSeitzTruncated\n\n" 211 " Truncate exchange kernel on the Wigner-Seitz cell of the k-point\n" 212 " sampled supercell, as in Ref. \\cite TruncatedEXX.\n" 213 " Default for any (partially) periodic <geometry>."; 214 hasDefault = true; 215 require("coulomb-interaction"); 216 }; 217 processCommandExchangeRegularization218 void process(ParamList& pl, Everything& e) 219 { CoulombParams& cp = e.coulombParams; 220 //Select default regularization based on geometry: 221 bool isIsolated = cp.geometry==CoulombParams::Isolated 222 || cp.geometry==CoulombParams::Spherical; 223 cp.exchangeRegularization = isIsolated 224 ? CoulombParams::None 225 : CoulombParams::WignerSeitzTruncated; 226 pl.get(cp.exchangeRegularization, cp.exchangeRegularization, exRegMethodMap, "method"); 227 //Check compatibility of regularization with geometry: 228 if(isIsolated && cp.exchangeRegularization!=CoulombParams::None) 229 throw string("exchange-regularization <method> must be None for non-periodic" 230 " coulomb-interaction <geometry> = Spherical or Isolated"); 231 } 232 printStatusCommandExchangeRegularization233 void printStatus(Everything& e, int iRep) 234 { logPrintf("%s", exRegMethodMap.getString(e.coulombParams.exchangeRegularization)); 235 } 236 } 237 commandCoulombParams; 238