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 EnumStringMap<GridInfo::LatticeType> lattTypeMap 24 ( GridInfo::Triclinic, "Triclinic", 25 GridInfo::Monoclinic, "Monoclinic", 26 GridInfo::Orthorhombic, "Orthorhombic", 27 GridInfo::Tetragonal, "Tetragonal", 28 GridInfo::Rhombohedral, "Rhombohedral", 29 GridInfo::Hexagonal, "Hexagonal", 30 GridInfo::Cubic, "Cubic" 31 ); 32 33 EnumStringMap<GridInfo::LatticeModification> lattModMap 34 ( GridInfo::BodyCentered, "Body-Centered", 35 GridInfo::BaseCentered, "Base-Centered", 36 GridInfo::FaceCentered, "Face-Centered" 37 ); 38 39 struct CommandLattice : public Command 40 { CommandLatticeCommandLattice41 CommandLattice() : Command("lattice", "jdftx/Ionic/Geometry") 42 { 43 format = " [<modification>] <lattice> <parameters...>\n" 44 "\t| \\\n\t<R00> <R01> <R02> \\\n\t<R10> <R11> <R12> \\\n\t<R20> <R21> <R22>"; 45 comments = "Specify lattice by name and parameters, or explicitly using lattice vectors.\n" 46 "\n" 47 "The options for the first syntax ([<modification>] <lattice> <parameters...> scheme) are:\n" 48 "+ Triclinic <a> <b> <c> <alpha> <beta> <gamma>\n" 49 "+ [Base-Centered] Monoclinic <a> <b> <c> <beta>\n" 50 "+ [Base|Body|Face-Centered] Orthorhombic <a> <b> <c>\n" 51 "+ [Body-Centered] Tetragonal <a> <c>\n" 52 "+ Rhombohedral <a> <alpha>\n" 53 "+ Hexagonal <a> <c>\n" 54 "+ [Body|Face-Centered] Cubic <a>\n" 55 "where lengths <a>,<b>,<c> are in bohrs and angles <alpha>,<beta,<gamma> are in degrees.\n" 56 "\n" 57 "Alternately, the second syntax directly specifies the transformation\n" 58 "matrix from lattice to Cartesian coordinates. Therefore, the columns\n" 59 "of this 3x3 matrix are the lattice vectors in bohrs.\n" 60 "\n" 61 "NOTE: other DFT codes may specify lattice vectors in rows;\n" 62 "confirm that you switch them to columns if porting an input file to JDFTx."; 63 } 64 processCommandLattice65 void process(ParamList& pl, Everything& e) 66 { GridInfo& g = e.gInfo; 67 //Check for named lattice specification: 68 try { pl.get(g.latticeModification, GridInfo::Simple, lattModMap, "modification", true); } catch(string) { pl.rewind(); } //no modification 69 try { pl.get(g.latticeType, GridInfo::Manual, lattTypeMap, "type", true); } catch(string) { pl.rewind(); } //Not a named lattice 70 //Read parameters: 71 g.alpha = 90.; 72 g.beta = 90.; 73 g.gamma = 90.; 74 switch(g.latticeType) 75 { 76 case GridInfo::Manual: 77 { for(int j=0; j<3; j++) for(int k=0; k<3; k++) 78 { ostringstream oss; oss << "R" << j << k; 79 try 80 { pl.get(g.R(j,k), 0.0, oss.str(), true); 81 } 82 catch(string) 83 { if(j==0 && k<2) throw string("First two parameters match neither <R00> <R01> ..., nor valid [<modification>] <lattice> ..."); 84 else throw; //propagate Rjk parse error 85 } 86 } 87 break; 88 } 89 case GridInfo::Triclinic: 90 { pl.get(g.a, 0., "a", true); 91 pl.get(g.b, 0., "b", true); 92 pl.get(g.c, 0., "c", true); 93 pl.get(g.alpha, 0., "alpha", true); 94 pl.get(g.beta, 0., "beta", true); 95 pl.get(g.gamma, 0., "gamma", true); 96 break; 97 } 98 case GridInfo::Monoclinic: 99 { pl.get(g.a, 0., "a", true); 100 pl.get(g.b, 0., "b", true); 101 pl.get(g.c, 0., "c", true); 102 pl.get(g.beta, 0., "beta", true); 103 break; 104 } 105 case GridInfo::Orthorhombic: 106 { pl.get(g.a, 0., "a", true); 107 pl.get(g.b, 0., "b", true); 108 pl.get(g.c, 0., "c", true); 109 break; 110 } 111 case GridInfo::Tetragonal: 112 { pl.get(g.a, 0., "a", true); 113 g.b = g.a; 114 pl.get(g.c, 0., "c", true); 115 break; 116 } 117 case GridInfo::Rhombohedral: 118 { pl.get(g.a, 0., "a", true); 119 g.b = g.a; 120 g.c = g.a; 121 pl.get(g.alpha, 0., "alpha", true); 122 g.beta = g.alpha; 123 g.gamma = g.alpha; 124 break; 125 } 126 case GridInfo::Hexagonal: 127 { pl.get(g.a, 0., "a", true); 128 g.b = g.a; 129 pl.get(g.c, 0., "c", true); 130 g.gamma = 120.; 131 break; 132 } 133 case GridInfo::Cubic: 134 { pl.get(g.a, 0., "a", true); 135 g.b = g.a; 136 g.c = g.a; 137 break; 138 } 139 } 140 //Check parameters and compute the lattice vectors: 141 if(g.latticeType != GridInfo::Manual) 142 g.setLatticeVectors(); 143 } 144 printStatusCommandLattice145 void printStatus(Everything& e, int iRep) 146 { const GridInfo& g = e.gInfo; 147 if(g.latticeType == GridInfo::Manual) 148 { matrix3<> Runscaled; 149 for(int k=0; k<3; k++) 150 Runscaled.set_col(k, (1./g.lattScale[k]) * g.R.column(k)); 151 for(int j=0; j<3; j++) 152 { logPrintf(" \\\n\t"); 153 for(int k=0; k<3; k++) 154 logPrintf("%20.15lf ", Runscaled(j,k)); 155 } 156 } 157 else 158 { if(g.latticeModification != GridInfo::Simple) 159 logPrintf("%s ", lattModMap.getString(g.latticeModification)); 160 logPrintf("%s ", lattTypeMap.getString(g.latticeType)); 161 switch(g.latticeType) 162 { case GridInfo::Manual: break; //never encountered 163 case GridInfo::Triclinic: logPrintf("%lg %lg %lg %lg %lg %lg", g.a, g.b, g.c, g.alpha, g.beta, g.gamma); break; 164 case GridInfo::Monoclinic: logPrintf("%lg %lg %lg %lg", g.a, g.b, g.c, g.beta); break; 165 case GridInfo::Orthorhombic: logPrintf("%lg %lg %lg", g.a, g.b, g.c); break; 166 case GridInfo::Tetragonal: logPrintf("%lg %lg", g.a, g.c); break; 167 case GridInfo::Rhombohedral: logPrintf("%lg %lg", g.a, g.alpha); break; 168 case GridInfo::Hexagonal: logPrintf("%lg %lg", g.a, g.c); break; 169 case GridInfo::Cubic: logPrintf("%lg", g.a); break; 170 } 171 } 172 } 173 } 174 commandLattice; 175 176 177 struct CommandLattScale : public Command 178 { CommandLattScaleCommandLattScale179 CommandLattScale() : Command("latt-scale", "jdftx/Ionic/Geometry") 180 { 181 format = "<s0> <s1> <s2>"; 182 comments = "Scale lattice vector i by factor <si>. This may be convenient\n" 183 "for unit conversions, or specifying lattice vectors of supercells."; 184 hasDefault = true; 185 186 require("lattice"); 187 } 188 processCommandLattScale189 void process(ParamList& pl, Everything& e) 190 { //check if any parameters have been specified: 191 string key; pl.get(key, string(), ""); pl.rewind(); 192 if(!key.length()) { e.gInfo.lattScale = vector3<>(1.,1.,1.); return; } 193 //Read parameters: 194 for(int k=0; k<3; k++) 195 { ostringstream oss; oss << "s" << k; 196 pl.get(e.gInfo.lattScale[k], 1., oss.str(), true); 197 e.gInfo.R.set_col(k, e.gInfo.lattScale[k] * e.gInfo.R.column(k)); 198 } 199 } 200 printStatusCommandLattScale201 void printStatus(Everything& e, int iRep) 202 { for(int k=0; k<3; k++) logPrintf("%lg ", e.gInfo.lattScale[k]); 203 } 204 } 205 commandLattScale; 206 207 208 struct CommandLattMoveScale : public Command 209 { CommandLattMoveScaleCommandLattMoveScale210 CommandLattMoveScale() : Command("latt-move-scale", "jdftx/Ionic/Optimization") 211 { 212 format = "<s0> <s1> <s2>"; 213 comments = "Preconditioning factor for each lattice vector (must be commensurate with symmetries).\n" 214 "Note that setting the factor for a direction to zero prevents it from being optimized,\n" 215 "which could especially be useful for lattice optimization of 1D and 2D systems."; 216 hasDefault = true; 217 } 218 processCommandLattMoveScale219 void process(ParamList& pl, Everything& e) 220 { vector3<>& s = e.cntrl.lattMoveScale; 221 pl.get(s[0], 1., "s0"); 222 pl.get(s[1], 1., "s1"); 223 pl.get(s[2], 1., "s2"); 224 } 225 printStatusCommandLattMoveScale226 void printStatus(Everything& e, int iRep) 227 { const vector3<>& s = e.cntrl.lattMoveScale; 228 logPrintf("%lg %lg %lg", s[0], s[1], s[2]); 229 } 230 } 231 commandLattMoveScale; 232 233 EnumStringMap<CoordsType> coordsMap( 234 CoordsLattice, "Lattice", 235 CoordsCartesian, "Cartesian" ); 236 237 struct CommandCoordsType : public Command 238 { CommandCoordsTypeCommandCoordsType239 CommandCoordsType() : Command("coords-type", "jdftx/Ionic/Geometry") 240 { 241 format = "<coords>=" + coordsMap.optionList(); 242 comments = "Coordinate system used in specifying ion positions (default: Lattice).\n" 243 "+ Lattice coordinates correspond to fractional coordinates in terms of the\n" 244 " lattice vectors, which is usually more convenient for periodic systems.\n" 245 "+ Cartesian coordinates specify absolute atom positions in bohr units,\n" 246 " which is usually more convenient for non-periodic systems like molecules.\n" 247 "\n" 248 "NOTE: other DFT codes may specify Cartesian coordinates in Angstroms;\n" 249 "confirm that you switch them to bohrs if porting an input file to JDFTx."; 250 hasDefault = true; 251 } 252 processCommandCoordsType253 void process(ParamList& pl, Everything& e) 254 { pl.get(e.iInfo.coordsType, CoordsLattice, coordsMap, "coords"); 255 } 256 printStatusCommandCoordsType257 void printStatus(Everything& e, int iRep) 258 { fputs(coordsMap.getString(e.iInfo.coordsType), globalLog); 259 } 260 } 261 commandCoordsType; 262