| 1 | chuckv | 653 | /* | 
| 2 |  |  | * Copyright (c) 2005 The University of Notre Dame. All Rights Reserved. | 
| 3 |  |  | * | 
| 4 |  |  | * The University of Notre Dame grants you ("Licensee") a | 
| 5 |  |  | * non-exclusive, royalty free, license to use, modify and | 
| 6 |  |  | * redistribute this software in source and binary code form, provided | 
| 7 |  |  | * that the following conditions are met: | 
| 8 |  |  | * | 
| 9 | gezelter | 1390 | * 1. Redistributions of source code must retain the above copyright | 
| 10 | chuckv | 653 | *    notice, this list of conditions and the following disclaimer. | 
| 11 |  |  | * | 
| 12 | gezelter | 1390 | * 2. Redistributions in binary form must reproduce the above copyright | 
| 13 | chuckv | 653 | *    notice, this list of conditions and the following disclaimer in the | 
| 14 |  |  | *    documentation and/or other materials provided with the | 
| 15 |  |  | *    distribution. | 
| 16 |  |  | * | 
| 17 |  |  | * This software is provided "AS IS," without a warranty of any | 
| 18 |  |  | * kind. All express or implied conditions, representations and | 
| 19 |  |  | * warranties, including any implied warranty of merchantability, | 
| 20 |  |  | * fitness for a particular purpose or non-infringement, are hereby | 
| 21 |  |  | * excluded.  The University of Notre Dame and its licensors shall not | 
| 22 |  |  | * be liable for any damages suffered by licensee as a result of | 
| 23 |  |  | * using, modifying or distributing the software or its | 
| 24 |  |  | * derivatives. In no event will the University of Notre Dame or its | 
| 25 |  |  | * licensors be liable for any lost revenue, profit or data, or for | 
| 26 |  |  | * direct, indirect, special, consequential, incidental or punitive | 
| 27 |  |  | * damages, however caused and regardless of the theory of liability, | 
| 28 |  |  | * arising out of the use of or inability to use software, even if the | 
| 29 |  |  | * University of Notre Dame has been advised of the possibility of | 
| 30 |  |  | * such damages. | 
| 31 | gezelter | 1390 | * | 
| 32 |  |  | * SUPPORT OPEN SCIENCE!  If you use OpenMD or its source code in your | 
| 33 |  |  | * research, please cite the appropriate papers when you publish your | 
| 34 |  |  | * work.  Good starting points are: | 
| 35 |  |  | * | 
| 36 |  |  | * [1]  Meineke, et al., J. Comp. Chem. 26, 252-271 (2005). | 
| 37 |  |  | * [2]  Fennell & Gezelter, J. Chem. Phys. 124, 234104 (2006). | 
| 38 |  |  | * [3]  Sun, Lin & Gezelter, J. Chem. Phys. 128, 24107 (2008). | 
| 39 |  |  | * [4]  Vardeman & Gezelter, in progress (2009). | 
| 40 | chuckv | 653 | */ | 
| 41 |  |  |  | 
| 42 |  |  | #include <cstdlib> | 
| 43 |  |  | #include <cstdio> | 
| 44 |  |  | #include <cstring> | 
| 45 |  |  | #include <cmath> | 
| 46 |  |  | #include <iostream> | 
| 47 |  |  | #include <string> | 
| 48 |  |  | #include <map> | 
| 49 |  |  | #include <fstream> | 
| 50 | chuckv | 911 | #include <algorithm> | 
| 51 | chuckv | 653 |  | 
| 52 |  |  | #include "config.h" | 
| 53 | chuckv | 911 | #include "shapedLatticeSpherical.hpp" | 
| 54 | chuckv | 653 | #include "nanoparticleBuilderCmd.h" | 
| 55 |  |  | #include "lattice/LatticeFactory.hpp" | 
| 56 |  |  | #include "utils/MoLocator.hpp" | 
| 57 |  |  | #include "lattice/Lattice.hpp" | 
| 58 |  |  | #include "brains/Register.hpp" | 
| 59 |  |  | #include "brains/SimInfo.hpp" | 
| 60 |  |  | #include "brains/SimCreator.hpp" | 
| 61 |  |  | #include "io/DumpWriter.hpp" | 
| 62 |  |  | #include "math/Vector3.hpp" | 
| 63 |  |  | #include "math/SquareMatrix3.hpp" | 
| 64 |  |  | #include "utils/StringUtils.hpp" | 
| 65 |  |  |  | 
| 66 |  |  | using namespace std; | 
| 67 | gezelter | 1390 | using namespace OpenMD; | 
| 68 | chuckv | 653 | void createMdFile(const std::string&oldMdFileName, | 
| 69 |  |  | const std::string&newMdFileName, | 
| 70 | chuckv | 1069 | std::vector<int> numMol); | 
| 71 | chuckv | 653 |  | 
| 72 |  |  | int main(int argc, char *argv []) { | 
| 73 |  |  |  | 
| 74 |  |  | //register force fields | 
| 75 |  |  | registerForceFields(); | 
| 76 |  |  | registerLattice(); | 
| 77 |  |  |  | 
| 78 |  |  | gengetopt_args_info args_info; | 
| 79 |  |  | std::string latticeType; | 
| 80 |  |  | std::string inputFileName; | 
| 81 | chuckv | 1069 | std::string outputFileName; | 
| 82 | chuckv | 653 |  | 
| 83 | chuckv | 911 | MoLocator* locator; | 
| 84 |  |  | int nComponents; | 
| 85 | chuckv | 653 | double latticeConstant; | 
| 86 |  |  | std::vector<double> lc; | 
| 87 | gezelter | 1075 |  | 
| 88 | gezelter | 1077 | RealType particleRadius; | 
| 89 | chuckv | 653 |  | 
| 90 |  |  | Mat3x3d hmat; | 
| 91 |  |  | std::vector<Vector3d> latticePos; | 
| 92 |  |  | std::vector<Vector3d> latticeOrt; | 
| 93 | chuckv | 1069 |  | 
| 94 | chuckv | 653 | DumpWriter *writer; | 
| 95 |  |  |  | 
| 96 | chuckv | 875 | // Parse Command Line Arguments | 
| 97 | chuckv | 653 | if (cmdline_parser(argc, argv, &args_info) != 0) | 
| 98 |  |  | exit(1); | 
| 99 | gezelter | 1070 |  | 
| 100 | chuckv | 653 | /* get lattice type */ | 
| 101 | chuckv | 1069 | latticeType = "FCC"; | 
| 102 |  |  |  | 
| 103 | chuckv | 653 | /* get input file name */ | 
| 104 |  |  | if (args_info.inputs_num) | 
| 105 |  |  | inputFileName = args_info.inputs[0]; | 
| 106 |  |  | else { | 
| 107 | gezelter | 1077 | sprintf(painCave.errMsg, "No input .md file name was specified " | 
| 108 | gezelter | 1075 | "on the command line"); | 
| 109 | chuckv | 1069 | painCave.isFatal = 1; | 
| 110 | chuckv | 653 | cmdline_parser_print_help(); | 
| 111 | chuckv | 1069 | simError(); | 
| 112 | chuckv | 653 | } | 
| 113 |  |  |  | 
| 114 |  |  | /* parse md file and set up the system */ | 
| 115 |  |  | SimCreator oldCreator; | 
| 116 |  |  | SimInfo* oldInfo = oldCreator.createSim(inputFileName, false); | 
| 117 |  |  |  | 
| 118 | gezelter | 1077 | latticeConstant = args_info.latticeConstant_arg; | 
| 119 | chuckv | 653 | particleRadius = args_info.radius_arg; | 
| 120 | chuckv | 911 | Globals* simParams = oldInfo->getSimParams(); | 
| 121 | chuckv | 653 |  | 
| 122 | chuckv | 911 | /* Create nanoparticle */ | 
| 123 | gezelter | 1070 | shapedLatticeSpherical nanoParticle(latticeConstant, latticeType, | 
| 124 |  |  | particleRadius); | 
| 125 | chuckv | 918 |  | 
| 126 | chuckv | 911 | /* Build a lattice and get lattice points for this lattice constant */ | 
| 127 | gezelter | 1070 | vector<Vector3d> sites = nanoParticle.getSites(); | 
| 128 |  |  | vector<Vector3d> orientations = nanoParticle.getOrientations(); | 
| 129 | gezelter | 1077 | std::vector<int> vacancyTargets; | 
| 130 |  |  | vector<bool> isVacancy; | 
| 131 |  |  |  | 
| 132 |  |  | Vector3d myLoc; | 
| 133 |  |  | RealType myR; | 
| 134 |  |  |  | 
| 135 |  |  | for (int i = 0; i < sites.size(); i++) | 
| 136 |  |  | isVacancy.push_back(false); | 
| 137 | chuckv | 1069 |  | 
| 138 | gezelter | 1077 | if (args_info.vacancyPercent_given) { | 
| 139 |  |  | if (args_info.vacancyPercent_arg < 0.0 || args_info.vacancyPercent_arg > 100.0) { | 
| 140 |  |  | sprintf(painCave.errMsg, "vacancyPercent was set to a non-sensical value."); | 
| 141 |  |  | painCave.isFatal = 1; | 
| 142 |  |  | simError(); | 
| 143 |  |  | } else { | 
| 144 |  |  | RealType vF = args_info.vacancyPercent_arg / 100.0; | 
| 145 |  |  | RealType vIR; | 
| 146 |  |  | RealType vOR; | 
| 147 |  |  | if (args_info.vacancyInnerRadius_given) { | 
| 148 |  |  | vIR = args_info.vacancyInnerRadius_arg; | 
| 149 |  |  | } else { | 
| 150 |  |  | vIR = 0.0; | 
| 151 |  |  | } | 
| 152 |  |  | if (args_info.vacancyOuterRadius_given) { | 
| 153 |  |  | vOR = args_info.vacancyOuterRadius_arg; | 
| 154 |  |  | } else { | 
| 155 |  |  | vOR = particleRadius; | 
| 156 |  |  | } | 
| 157 |  |  | if (vIR >= 0.0 && vOR <= particleRadius && vOR >= vIR) { | 
| 158 |  |  |  | 
| 159 |  |  | for (int i = 0; i < sites.size(); i++) { | 
| 160 |  |  | myLoc = sites[i]; | 
| 161 |  |  | myR = myLoc.length(); | 
| 162 |  |  | if (myR >= vIR && myR <= vOR) { | 
| 163 |  |  | vacancyTargets.push_back(i); | 
| 164 |  |  | } | 
| 165 |  |  | } | 
| 166 |  |  | std::random_shuffle(vacancyTargets.begin(), vacancyTargets.end()); | 
| 167 |  |  |  | 
| 168 |  |  | int nTargets = vacancyTargets.size(); | 
| 169 |  |  | vacancyTargets.resize((int)(vF * nTargets)); | 
| 170 |  |  |  | 
| 171 |  |  |  | 
| 172 |  |  | sprintf(painCave.errMsg, "Removing %d atoms from randomly-selected\n" | 
| 173 | gezelter | 1390 | "\tsites between %lf and %lf.", (int) vacancyTargets.size(), | 
| 174 | gezelter | 1077 | vIR, vOR); | 
| 175 |  |  | painCave.isFatal = 0; | 
| 176 |  |  | simError(); | 
| 177 | chuckv | 1069 |  | 
| 178 | gezelter | 1077 | isVacancy.clear(); | 
| 179 |  |  | for (int i = 0; i < sites.size(); i++) { | 
| 180 |  |  | bool vac = false; | 
| 181 |  |  | for (int j = 0; j < vacancyTargets.size(); j++) { | 
| 182 |  |  | if (i == vacancyTargets[j]) vac = true; | 
| 183 |  |  | } | 
| 184 |  |  | isVacancy.push_back(vac); | 
| 185 |  |  | } | 
| 186 |  |  |  | 
| 187 |  |  | } else { | 
| 188 |  |  | sprintf(painCave.errMsg, "Something is strange about the vacancy\n" | 
| 189 |  |  | "\tinner or outer radii.  Check their values."); | 
| 190 |  |  | painCave.isFatal = 1; | 
| 191 |  |  | simError(); | 
| 192 |  |  | } | 
| 193 |  |  | } | 
| 194 |  |  | } | 
| 195 |  |  |  | 
| 196 | chuckv | 911 | /* Get number of lattice sites */ | 
| 197 | gezelter | 1077 | int nSites = sites.size() - vacancyTargets.size(); | 
| 198 | chuckv | 1069 |  | 
| 199 |  |  | std::vector<Component*> components = simParams->getComponents(); | 
| 200 |  |  | std::vector<RealType> molFractions; | 
| 201 | gezelter | 1075 | std::vector<RealType> shellRadii; | 
| 202 | chuckv | 1069 | std::vector<RealType> molecularMasses; | 
| 203 |  |  | std::vector<int> nMol; | 
| 204 | gezelter | 1075 | std::map<int, int> componentFromSite; | 
| 205 | chuckv | 1069 | nComponents = components.size(); | 
| 206 |  |  |  | 
| 207 | gezelter | 1077 | if (args_info.molFraction_given && args_info.shellRadius_given) { | 
| 208 |  |  | sprintf(painCave.errMsg, "Specify either molFraction or shellRadius " | 
| 209 | gezelter | 1075 | "arguments, but not both!"); | 
| 210 |  |  | painCave.isFatal = 1; | 
| 211 |  |  | simError(); | 
| 212 |  |  | } | 
| 213 |  |  |  | 
| 214 |  |  | if (nComponents == 1) { | 
| 215 | chuckv | 1069 | molFractions.push_back(1.0); | 
| 216 | gezelter | 1075 | shellRadii.push_back(particleRadius); | 
| 217 |  |  | } else if (args_info.molFraction_given) { | 
| 218 |  |  | if ((int)args_info.molFraction_given == nComponents) { | 
| 219 |  |  | for (int i = 0; i < nComponents; i++) { | 
| 220 |  |  | molFractions.push_back(args_info.molFraction_arg[i]); | 
| 221 |  |  | } | 
| 222 |  |  | } else if ((int)args_info.molFraction_given == nComponents-1) { | 
| 223 |  |  | RealType remainingFraction = 1.0; | 
| 224 |  |  | for (int i = 0; i < nComponents-1; i++) { | 
| 225 |  |  | molFractions.push_back(args_info.molFraction_arg[i]); | 
| 226 |  |  | remainingFraction -= molFractions[i]; | 
| 227 |  |  | } | 
| 228 |  |  | molFractions.push_back(remainingFraction); | 
| 229 |  |  | } else { | 
| 230 |  |  | sprintf(painCave.errMsg, "nanoparticleBuilder can't figure out molFractions " | 
| 231 |  |  | "for all of the components in the <MetaData> block."); | 
| 232 | chuckv | 1069 | painCave.isFatal = 1; | 
| 233 |  |  | simError(); | 
| 234 |  |  | } | 
| 235 | gezelter | 1077 | } else if ((int)args_info.shellRadius_given) { | 
| 236 |  |  | if ((int)args_info.shellRadius_given == nComponents) { | 
| 237 | gezelter | 1075 | for (int i = 0; i < nComponents; i++) { | 
| 238 | gezelter | 1077 | shellRadii.push_back(args_info.shellRadius_arg[i]); | 
| 239 | gezelter | 1075 | } | 
| 240 | gezelter | 1077 | } else if ((int)args_info.shellRadius_given == nComponents-1) { | 
| 241 | gezelter | 1075 | for (int i = 0; i < nComponents-1; i++) { | 
| 242 | gezelter | 1077 | shellRadii.push_back(args_info.shellRadius_arg[i]); | 
| 243 | gezelter | 1075 | } | 
| 244 |  |  | shellRadii.push_back(particleRadius); | 
| 245 |  |  | } else { | 
| 246 | gezelter | 1077 | sprintf(painCave.errMsg, "nanoparticleBuilder can't figure out the\n" | 
| 247 |  |  | "\tshell radii for all of the components in the <MetaData> block."); | 
| 248 | chuckv | 1069 | painCave.isFatal = 1; | 
| 249 |  |  | simError(); | 
| 250 |  |  | } | 
| 251 | gezelter | 1075 | } else { | 
| 252 | gezelter | 1077 | sprintf(painCave.errMsg, "You have a multi-component <MetaData> block,\n" | 
| 253 |  |  | "\tbut have not specified either molFraction or shellRadius arguments."); | 
| 254 | chuckv | 1069 | painCave.isFatal = 1; | 
| 255 |  |  | simError(); | 
| 256 |  |  | } | 
| 257 | gezelter | 1075 |  | 
| 258 |  |  | if (args_info.molFraction_given) { | 
| 259 |  |  | RealType totalFraction = 0.0; | 
| 260 |  |  |  | 
| 261 |  |  | /* Do some simple sanity checking*/ | 
| 262 |  |  |  | 
| 263 |  |  | for (int i = 0; i < nComponents; i++) { | 
| 264 |  |  | if (molFractions.at(i) < 0.0) { | 
| 265 |  |  | sprintf(painCave.errMsg, "One of the requested molFractions was" | 
| 266 |  |  | " less than zero!"); | 
| 267 |  |  | painCave.isFatal = 1; | 
| 268 |  |  | simError(); | 
| 269 |  |  | } | 
| 270 |  |  | if (molFractions.at(i) > 1.0) { | 
| 271 |  |  | sprintf(painCave.errMsg, "One of the requested molFractions was" | 
| 272 |  |  | " greater than one!"); | 
| 273 |  |  | painCave.isFatal = 1; | 
| 274 |  |  | simError(); | 
| 275 |  |  | } | 
| 276 |  |  | totalFraction += molFractions.at(i); | 
| 277 |  |  | } | 
| 278 |  |  | if (abs(totalFraction - 1.0) > 1e-6) { | 
| 279 |  |  | sprintf(painCave.errMsg, "The sum of molFractions was not close enough to 1.0"); | 
| 280 |  |  | painCave.isFatal = 1; | 
| 281 |  |  | simError(); | 
| 282 |  |  | } | 
| 283 |  |  |  | 
| 284 |  |  | int remaining = nSites; | 
| 285 |  |  | for (int i=0; i < nComponents-1; i++) { | 
| 286 |  |  | nMol.push_back(int((RealType)nSites * molFractions.at(i))); | 
| 287 |  |  | remaining -= nMol.at(i); | 
| 288 |  |  | } | 
| 289 |  |  | nMol.push_back(remaining); | 
| 290 |  |  |  | 
| 291 |  |  | // recompute actual mol fractions and perform final sanity check: | 
| 292 |  |  |  | 
| 293 |  |  | int totalMolecules = 0; | 
| 294 |  |  | for (int i=0; i < nComponents; i++) { | 
| 295 |  |  | molFractions[i] = (RealType)(nMol.at(i))/(RealType)nSites; | 
| 296 |  |  | totalMolecules += nMol.at(i); | 
| 297 |  |  | } | 
| 298 |  |  |  | 
| 299 |  |  | if (totalMolecules != nSites) { | 
| 300 |  |  | sprintf(painCave.errMsg, "Computed total number of molecules is not equal " | 
| 301 |  |  | "to the number of lattice sites!"); | 
| 302 |  |  | painCave.isFatal = 1; | 
| 303 |  |  | simError(); | 
| 304 |  |  | } | 
| 305 |  |  | } else { | 
| 306 | chuckv | 1069 |  | 
| 307 | gezelter | 1075 | for (int i = 0; i < shellRadii.size(); i++) { | 
| 308 |  |  | if (shellRadii.at(i) > particleRadius + 1e-6 ) { | 
| 309 |  |  | sprintf(painCave.errMsg, "One of the shellRadius values exceeds the particle Radius."); | 
| 310 |  |  | painCave.isFatal = 1; | 
| 311 |  |  | simError(); | 
| 312 |  |  | } | 
| 313 |  |  | if (shellRadii.at(i) <= 0.0 ) { | 
| 314 |  |  | sprintf(painCave.errMsg, "One of the shellRadius values is smaller than zero!"); | 
| 315 |  |  | painCave.isFatal = 1; | 
| 316 |  |  | simError(); | 
| 317 |  |  | } | 
| 318 |  |  | } | 
| 319 | chuckv | 1069 | } | 
| 320 | gezelter | 1077 |  | 
| 321 |  |  | vector<int> ids; | 
| 322 | gezelter | 1075 | if ((int)args_info.molFraction_given){ | 
| 323 |  |  | sprintf(painCave.errMsg, "Creating a randomized spherical nanoparticle."); | 
| 324 |  |  | painCave.isFatal = 0; | 
| 325 |  |  | simError(); | 
| 326 | gezelter | 1077 | /* Random particle is the default case*/ | 
| 327 |  |  |  | 
| 328 |  |  | for (int i = 0; i < sites.size(); i++) | 
| 329 |  |  | if (!isVacancy[i]) ids.push_back(i); | 
| 330 |  |  |  | 
| 331 | chuckv | 1069 | std::random_shuffle(ids.begin(), ids.end()); | 
| 332 | gezelter | 1077 |  | 
| 333 | gezelter | 1075 | } else{ | 
| 334 |  |  | sprintf(painCave.errMsg, "Creating a core-shell spherical nanoparticle."); | 
| 335 |  |  | painCave.isFatal = 0; | 
| 336 |  |  | simError(); | 
| 337 | chuckv | 653 |  | 
| 338 | gezelter | 1075 | RealType smallestSoFar; | 
| 339 |  |  | int myComponent = -1; | 
| 340 |  |  | nMol.clear(); | 
| 341 |  |  | nMol.resize(nComponents); | 
| 342 |  |  |  | 
| 343 |  |  | for (int i = 0; i < sites.size(); i++) { | 
| 344 |  |  | myLoc = sites[i]; | 
| 345 |  |  | myR = myLoc.length(); | 
| 346 | gezelter | 1077 | smallestSoFar = particleRadius; | 
| 347 |  |  | if (!isVacancy[i]) { | 
| 348 |  |  | for (int j = 0; j < nComponents; j++) { | 
| 349 |  |  | if (myR <= shellRadii[j]) { | 
| 350 |  |  | if (shellRadii[j] <= smallestSoFar) { | 
| 351 |  |  | smallestSoFar = shellRadii[j]; | 
| 352 |  |  | myComponent = j; | 
| 353 |  |  | } | 
| 354 | gezelter | 1075 | } | 
| 355 |  |  | } | 
| 356 | gezelter | 1077 | componentFromSite[i] = myComponent; | 
| 357 |  |  | nMol[myComponent]++; | 
| 358 | gezelter | 1075 | } | 
| 359 | gezelter | 1077 | } | 
| 360 |  |  | } | 
| 361 | chuckv | 949 |  | 
| 362 | chuckv | 1069 | outputFileName = args_info.output_arg; | 
| 363 | gezelter | 1077 |  | 
| 364 | gezelter | 1075 | //creat new .md file on fly which corrects the number of molecule | 
| 365 | chuckv | 1069 | createMdFile(inputFileName, outputFileName, nMol); | 
| 366 | chuckv | 653 |  | 
| 367 |  |  | if (oldInfo != NULL) | 
| 368 |  |  | delete oldInfo; | 
| 369 |  |  |  | 
| 370 | chuckv | 949 | SimCreator newCreator; | 
| 371 | chuckv | 1069 | SimInfo* NewInfo = newCreator.createSim(outputFileName, false); | 
| 372 | gezelter | 1075 |  | 
| 373 | chuckv | 911 | // Place molecules | 
| 374 | chuckv | 653 | Molecule* mol; | 
| 375 |  |  | SimInfo::MoleculeIterator mi; | 
| 376 |  |  | mol = NewInfo->beginMolecule(mi); | 
| 377 | gezelter | 1077 |  | 
| 378 | chuckv | 949 | int l = 0; | 
| 379 | gezelter | 1077 | int whichSite = 0; | 
| 380 | chuckv | 1069 |  | 
| 381 |  |  | for (int i = 0; i < nComponents; i++){ | 
| 382 |  |  | locator = new MoLocator(NewInfo->getMoleculeStamp(i), | 
| 383 |  |  | NewInfo->getForceField()); | 
| 384 | gezelter | 1077 |  | 
| 385 |  |  | if (!args_info.molFraction_given) { | 
| 386 | gezelter | 1075 | for (int n = 0; n < sites.size(); n++) { | 
| 387 | gezelter | 1077 | if (!isVacancy[n]) { | 
| 388 |  |  | if (componentFromSite[n] == i) { | 
| 389 |  |  | mol = NewInfo->getMoleculeByGlobalIndex(l); | 
| 390 |  |  | locator->placeMol(sites[n], orientations[n], mol); | 
| 391 |  |  | l++; | 
| 392 |  |  | } | 
| 393 | gezelter | 1075 | } | 
| 394 |  |  | } | 
| 395 |  |  | } else { | 
| 396 |  |  | for (int n = 0; n < nMol.at(i); n++) { | 
| 397 |  |  | mol = NewInfo->getMoleculeByGlobalIndex(l); | 
| 398 |  |  | locator->placeMol(sites[ids[l]], orientations[ids[l]], mol); | 
| 399 |  |  | l++; | 
| 400 |  |  | } | 
| 401 | chuckv | 1069 | } | 
| 402 | gezelter | 1077 | } | 
| 403 | chuckv | 653 |  | 
| 404 |  |  | //fill Hmat | 
| 405 | gezelter | 1075 | hmat(0, 0)=  10.0*particleRadius; | 
| 406 | chuckv | 653 | hmat(0, 1) = 0.0; | 
| 407 |  |  | hmat(0, 2) = 0.0; | 
| 408 |  |  |  | 
| 409 |  |  | hmat(1, 0) = 0.0; | 
| 410 | gezelter | 1075 | hmat(1, 1) =  10.0*particleRadius; | 
| 411 | chuckv | 653 | hmat(1, 2) = 0.0; | 
| 412 |  |  |  | 
| 413 |  |  | hmat(2, 0) = 0.0; | 
| 414 |  |  | hmat(2, 1) = 0.0; | 
| 415 | gezelter | 1075 | hmat(2, 2) =  10.0*particleRadius; | 
| 416 | chuckv | 653 |  | 
| 417 |  |  | //set Hmat | 
| 418 |  |  | NewInfo->getSnapshotManager()->getCurrentSnapshot()->setHmat(hmat); | 
| 419 |  |  |  | 
| 420 |  |  |  | 
| 421 |  |  | //create dumpwriter and write out the coordinates | 
| 422 | gezelter | 1070 | writer = new DumpWriter(NewInfo, outputFileName); | 
| 423 | chuckv | 653 |  | 
| 424 |  |  | if (writer == NULL) { | 
| 425 | gezelter | 1077 | sprintf(painCave.errMsg, "Error in creating dumpwriter object "); | 
| 426 | gezelter | 1075 | painCave.isFatal = 1; | 
| 427 |  |  | simError(); | 
| 428 | chuckv | 653 | } | 
| 429 |  |  |  | 
| 430 |  |  | writer->writeDump(); | 
| 431 | chuckv | 1069 |  | 
| 432 |  |  | // deleting the writer will put the closing at the end of the dump file | 
| 433 | gezelter | 1070 |  | 
| 434 | chuckv | 1069 | delete writer; | 
| 435 |  |  |  | 
| 436 |  |  | // cleanup a by calling sim error..... | 
| 437 | gezelter | 1390 | sprintf(painCave.errMsg, "A new OpenMD file called \"%s\" has been " | 
| 438 | chuckv | 1069 | "generated.\n", outputFileName.c_str()); | 
| 439 |  |  | painCave.isFatal = 0; | 
| 440 |  |  | simError(); | 
| 441 | chuckv | 653 | return 0; | 
| 442 |  |  | } | 
| 443 |  |  |  | 
| 444 | gezelter | 1075 | void createMdFile(const std::string&oldMdFileName, | 
| 445 |  |  | const std::string&newMdFileName, | 
| 446 | chuckv | 1069 | std::vector<int> nMol) { | 
| 447 | chuckv | 653 | ifstream oldMdFile; | 
| 448 |  |  | ofstream newMdFile; | 
| 449 |  |  | const int MAXLEN = 65535; | 
| 450 |  |  | char buffer[MAXLEN]; | 
| 451 |  |  |  | 
| 452 |  |  | //create new .md file based on old .md file | 
| 453 |  |  | oldMdFile.open(oldMdFileName.c_str()); | 
| 454 |  |  | newMdFile.open(newMdFileName.c_str()); | 
| 455 |  |  | oldMdFile.getline(buffer, MAXLEN); | 
| 456 | gezelter | 1077 |  | 
| 457 | chuckv | 911 | int i = 0; | 
| 458 | chuckv | 653 | while (!oldMdFile.eof()) { | 
| 459 | gezelter | 1077 |  | 
| 460 | chuckv | 653 | //correct molecule number | 
| 461 |  |  | if (strstr(buffer, "nMol") != NULL) { | 
| 462 | chuckv | 1069 | if(i<nMol.size()){ | 
| 463 | gezelter | 1077 | sprintf(buffer, "\tnMol = %i;", nMol.at(i)); | 
| 464 | chuckv | 949 | newMdFile << buffer << std::endl; | 
| 465 |  |  | i++; | 
| 466 |  |  | } | 
| 467 | chuckv | 653 | } else | 
| 468 |  |  | newMdFile << buffer << std::endl; | 
| 469 |  |  |  | 
| 470 |  |  | oldMdFile.getline(buffer, MAXLEN); | 
| 471 |  |  | } | 
| 472 |  |  |  | 
| 473 |  |  | oldMdFile.close(); | 
| 474 |  |  | newMdFile.close(); | 
| 475 | gezelter | 1077 |  | 
| 476 |  |  | if (i != nMol.size()) { | 
| 477 |  |  | sprintf(painCave.errMsg, "Couldn't replace the correct number of nMol\n" | 
| 478 |  |  | "\tstatements in component blocks.  Make sure that all\n" | 
| 479 |  |  | "\tcomponents in the template file have nMol=1"); | 
| 480 |  |  | painCave.isFatal = 1; | 
| 481 |  |  | simError(); | 
| 482 |  |  | } | 
| 483 |  |  |  | 
| 484 | chuckv | 653 | } | 
| 485 |  |  |  |