ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/branches/development/src/applications/randomBuilder/randomBuilder.cpp
Revision: 1725
Committed: Sat May 26 18:13:43 2012 UTC (12 years, 11 months ago) by gezelter
File size: 11554 byte(s)
Log Message:
Individual ForceField classes have been removed (they were essentially
all duplicates anyway).  

ForceField has moved to brains, and since only one force field is in
play at any time, the ForceFieldFactory and Register methods have been
removed.  


File Contents

# User Rev Content
1 chuckv 950 /* Copyright (c) 2006 The University of Notre Dame. All Rights Reserved.
2     *
3     * The University of Notre Dame grants you ("Licensee") a
4     * non-exclusive, royalty free, license to use, modify and
5     * redistribute this software in source and binary code form, provided
6     * that the following conditions are met:
7     *
8 gezelter 1390 * 1. Redistributions of source code must retain the above copyright
9 chuckv 950 * notice, this list of conditions and the following disclaimer.
10     *
11 gezelter 1390 * 2. Redistributions in binary form must reproduce the above copyright
12 chuckv 950 * notice, this list of conditions and the following disclaimer in the
13     * documentation and/or other materials provided with the
14     * distribution.
15     *
16     * This software is provided "AS IS," without a warranty of any
17     * kind. All express or implied conditions, representations and
18     * warranties, including any implied warranty of merchantability,
19     * fitness for a particular purpose or non-infringement, are hereby
20     * excluded. The University of Notre Dame and its licensors shall not
21     * be liable for any damages suffered by licensee as a result of
22     * using, modifying or distributing the software or its
23     * derivatives. In no event will the University of Notre Dame or its
24     * licensors be liable for any lost revenue, profit or data, or for
25     * direct, indirect, special, consequential, incidental or punitive
26     * damages, however caused and regardless of the theory of liability,
27     * arising out of the use of or inability to use software, even if the
28     * University of Notre Dame has been advised of the possibility of
29     * such damages.
30     *
31 gezelter 1390 * SUPPORT OPEN SCIENCE! If you use OpenMD or its source code in your
32     * research, please cite the appropriate papers when you publish your
33     * work. Good starting points are:
34     *
35     * [1] Meineke, et al., J. Comp. Chem. 26, 252-271 (2005).
36     * [2] Fennell & Gezelter, J. Chem. Phys. 124, 234104 (2006).
37     * [3] Sun, Lin & Gezelter, J. Chem. Phys. 128, 24107 (2008).
38 gezelter 1665 * [4] Kuang & Gezelter, J. Chem. Phys. 133, 164101 (2010).
39     * [4] , Stocker & Gezelter, J. Chem. Theory Comput. 7, 834 (2011). *
40 chuckv 950 *
41     * randomBuilder.cpp
42     *
43     * Created by Charles F. Vardeman II on 10 Apr 2006.
44     * @author Charles F. Vardeman II
45 gezelter 1442 * @version $Id$
46 chuckv 950 *
47     */
48    
49    
50     #include <cstdlib>
51     #include <cstdio>
52     #include <cstring>
53     #include <cmath>
54     #include <iostream>
55     #include <string>
56     #include <map>
57     #include <fstream>
58    
59     #include "applications/randomBuilder/randomBuilderCmd.h"
60     #include "lattice/LatticeFactory.hpp"
61     #include "utils/MoLocator.hpp"
62     #include "lattice/Lattice.hpp"
63     #include "brains/Register.hpp"
64     #include "brains/SimInfo.hpp"
65     #include "brains/SimCreator.hpp"
66     #include "io/DumpWriter.hpp"
67     #include "math/Vector3.hpp"
68     #include "math/SquareMatrix3.hpp"
69     #include "utils/StringUtils.hpp"
70    
71     using namespace std;
72 gezelter 1390 using namespace OpenMD;
73 chuckv 950
74     void createMdFile(const std::string&oldMdFileName,
75     const std::string&newMdFileName,
76 gezelter 1065 std::vector<int> nMol);
77 chuckv 950
78     int main(int argc, char *argv []) {
79    
80     registerLattice();
81    
82     gengetopt_args_info args_info;
83     std::string latticeType;
84     std::string inputFileName;
85 gezelter 1062 std::string outputFileName;
86 chuckv 950 Lattice *simpleLat;
87 tim 963 RealType latticeConstant;
88     std::vector<RealType> lc;
89     const RealType rhoConvertConst = 1.661;
90     RealType density;
91 gezelter 1062 int nx, ny, nz;
92 chuckv 950 Mat3x3d hmat;
93     MoLocator *locator;
94     std::vector<Vector3d> latticePos;
95     std::vector<Vector3d> latticeOrt;
96 gezelter 1065 int nMolPerCell;
97 chuckv 950 DumpWriter *writer;
98    
99     // parse command line arguments
100     if (cmdline_parser(argc, argv, &args_info) != 0)
101     exit(1);
102    
103     density = args_info.density_arg;
104    
105     //get lattice type
106 gezelter 1067 latticeType = "FCC";
107 chuckv 950
108     simpleLat = LatticeFactory::getInstance()->createLattice(latticeType);
109    
110     if (simpleLat == NULL) {
111     sprintf(painCave.errMsg, "Lattice Factory can not create %s lattice\n",
112     latticeType.c_str());
113     painCave.isFatal = 1;
114     simError();
115     }
116 gezelter 1065 nMolPerCell = simpleLat->getNumSitesPerCell();
117 chuckv 950
118 gezelter 1062 //get the number of unit cells in each direction:
119    
120 chuckv 950 nx = args_info.nx_arg;
121    
122     if (nx <= 0) {
123 gezelter 1062 sprintf(painCave.errMsg, "The number of unit cells in the x direction "
124     "must be greater than 0.");
125     painCave.isFatal = 1;
126     simError();
127 chuckv 950 }
128    
129     ny = args_info.ny_arg;
130    
131     if (ny <= 0) {
132 gezelter 1062 sprintf(painCave.errMsg, "The number of unit cells in the y direction "
133     "must be greater than 0.");
134     painCave.isFatal = 1;
135     simError();
136 chuckv 950 }
137    
138     nz = args_info.nz_arg;
139    
140     if (nz <= 0) {
141 gezelter 1062 sprintf(painCave.errMsg, "The number of unit cells in the z direction "
142     "must be greater than 0.");
143     painCave.isFatal = 1;
144     simError();
145 chuckv 950 }
146    
147 gezelter 1065 int nSites = nMolPerCell * nx * ny * nz;
148    
149 chuckv 950 //get input file name
150     if (args_info.inputs_num)
151     inputFileName = args_info.inputs[0];
152     else {
153 gezelter 1062 sprintf(painCave.errMsg, "No input .md file name was specified "
154     "on the command line");
155     painCave.isFatal = 1;
156     simError();
157 chuckv 950 }
158    
159     //parse md file and set up the system
160 gezelter 1062
161 chuckv 950 SimCreator oldCreator;
162     SimInfo* oldInfo = oldCreator.createSim(inputFileName, false);
163     Globals* simParams = oldInfo->getSimParams();
164    
165 gezelter 1065 // Calculate lattice constant (in Angstroms)
166    
167     std::vector<Component*> components = simParams->getComponents();
168     std::vector<RealType> molFractions;
169     std::vector<RealType> molecularMasses;
170     std::vector<int> nMol;
171     int nComponents = components.size();
172    
173     if (nComponents == 1) {
174     molFractions.push_back(1.0);
175     } else {
176     if (args_info.molFraction_given == nComponents) {
177     for (int i = 0; i < nComponents; i++) {
178     molFractions.push_back(args_info.molFraction_arg[i]);
179     }
180     } else if (args_info.molFraction_given == nComponents-1) {
181     RealType remainingFraction = 1.0;
182     for (int i = 0; i < nComponents-1; i++) {
183     molFractions.push_back(args_info.molFraction_arg[i]);
184     remainingFraction -= molFractions[i];
185     }
186     molFractions.push_back(remainingFraction);
187     } else {
188     sprintf(painCave.errMsg, "randomBuilder can't figure out molFractions "
189     "for all of the components in the <MetaData> block.");
190     painCave.isFatal = 1;
191     simError();
192     }
193     }
194    
195     // do some sanity checking:
196    
197     RealType totalFraction = 0.0;
198    
199     for (int i = 0; i < nComponents; i++) {
200     if (molFractions.at(i) < 0.0) {
201     sprintf(painCave.errMsg, "One of the requested molFractions was"
202     " less than zero!");
203     painCave.isFatal = 1;
204     simError();
205     }
206     if (molFractions.at(i) > 1.0) {
207     sprintf(painCave.errMsg, "One of the requested molFractions was"
208     " greater than one!");
209     painCave.isFatal = 1;
210     simError();
211     }
212     totalFraction += molFractions.at(i);
213     }
214     if (abs(totalFraction - 1.0) > 1e-6) {
215     sprintf(painCave.errMsg, "The sum of molFractions was not close enough to 1.0");
216 gezelter 1062 painCave.isFatal = 1;
217     simError();
218 chuckv 950 }
219    
220 gezelter 1065 int remaining = nSites;
221     for (int i=0; i < nComponents-1; i++) {
222     nMol.push_back(int((RealType)nSites * molFractions.at(i)));
223     remaining -= nMol.at(i);
224     }
225     nMol.push_back(remaining);
226 chuckv 950
227 gezelter 1065 // recompute actual mol fractions and perform final sanity check:
228 chuckv 950
229 gezelter 1065 int totalMolecules = 0;
230     RealType totalMass = 0.0;
231     for (int i=0; i < nComponents; i++) {
232     molFractions[i] = (RealType)(nMol.at(i))/(RealType)nSites;
233     totalMolecules += nMol.at(i);
234     molecularMasses.push_back(getMolMass(oldInfo->getMoleculeStamp(i),
235     oldInfo->getForceField()));
236     totalMass += (RealType)(nMol.at(i)) * molecularMasses.at(i);
237     }
238     RealType avgMass = totalMass / (RealType) totalMolecules;
239 gezelter 1062
240 gezelter 1065 if (totalMolecules != nSites) {
241     sprintf(painCave.errMsg, "Computed total number of molecules is not equal "
242     "to the number of lattice sites!");
243 gezelter 1062 painCave.isFatal = 1;
244     simError();
245 chuckv 950 }
246 gezelter 1065
247     latticeConstant = pow(rhoConvertConst * nMolPerCell * avgMass / density,
248 tim 963 (RealType)(1.0 / 3.0));
249 gezelter 1065
250 gezelter 1062 // Set the lattice constant
251 gezelter 1065
252 chuckv 950 lc.push_back(latticeConstant);
253     simpleLat->setLatticeConstant(lc);
254 gezelter 1065
255 gezelter 1062 // Calculate the lattice sites and fill the lattice vector.
256    
257     // Get the standard orientations of the cell sites
258    
259     latticeOrt = simpleLat->getLatticePointsOrt();
260    
261     vector<Vector3d> sites;
262     vector<Vector3d> orientations;
263 chuckv 950
264     for(int i = 0; i < nx; i++) {
265     for(int j = 0; j < ny; j++) {
266     for(int k = 0; k < nz; k++) {
267    
268 gezelter 1062 // Get the position of the cell sites
269    
270 chuckv 950 simpleLat->getLatticePointsPos(latticePos, i, j, k);
271    
272 gezelter 1065 for(int l = 0; l < nMolPerCell; l++) {
273 gezelter 1062 sites.push_back(latticePos[l]);
274     orientations.push_back(latticeOrt[l]);
275 chuckv 950 }
276     }
277     }
278     }
279    
280 gezelter 1062 outputFileName = args_info.output_arg;
281 chuckv 950
282 gezelter 1062 // create a new .md file on the fly which corrects the number of molecules
283 chuckv 950
284 gezelter 1065 createMdFile(inputFileName, outputFileName, nMol);
285 chuckv 950
286 gezelter 1062 if (oldInfo != NULL)
287     delete oldInfo;
288    
289     // We need to read in the new SimInfo object, then Parse the
290     // md file and set up the system
291    
292     SimCreator newCreator;
293     SimInfo* newInfo = newCreator.createSim(outputFileName, false);
294    
295     // fill Hmat
296    
297     hmat(0, 0) = nx * latticeConstant;
298 chuckv 950 hmat(0, 1) = 0.0;
299     hmat(0, 2) = 0.0;
300    
301     hmat(1, 0) = 0.0;
302     hmat(1, 1) = ny * latticeConstant;
303     hmat(1, 2) = 0.0;
304    
305     hmat(2, 0) = 0.0;
306     hmat(2, 1) = 0.0;
307     hmat(2, 2) = nz * latticeConstant;
308    
309 gezelter 1062 // Set Hmat
310 chuckv 950
311 gezelter 1062 newInfo->getSnapshotManager()->getCurrentSnapshot()->setHmat(hmat);
312 chuckv 950
313 gezelter 1062 // place the molecules
314    
315     // Randomize a vector of ints:
316 chuckv 950
317 gezelter 1062 vector<int> ids;
318     for (int i = 0; i < sites.size(); i++) ids.push_back(i);
319     std::random_shuffle(ids.begin(), ids.end());
320 chuckv 950
321     Molecule* mol;
322     int l = 0;
323 gezelter 1062 for (int i = 0; i < nComponents; i++){
324     locator = new MoLocator(newInfo->getMoleculeStamp(i),
325     newInfo->getForceField());
326 gezelter 1065 for (int n = 0; n < nMol.at(i); n++) {
327 gezelter 1062 mol = newInfo->getMoleculeByGlobalIndex(l);
328     locator->placeMol(sites[ids[l]], orientations[ids[l]], mol);
329     l++;
330     }
331 chuckv 950 }
332 gezelter 1062
333     // Create DumpWriter and write out the coordinates
334 chuckv 950
335 gezelter 1062 writer = new DumpWriter(newInfo, outputFileName);
336 chuckv 950
337     if (writer == NULL) {
338 gezelter 1062 sprintf(painCave.errMsg, "error in creating DumpWriter");
339     painCave.isFatal = 1;
340     simError();
341 chuckv 950 }
342    
343 gezelter 1062 writer->writeDump();
344    
345     // deleting the writer will put the closing at the end of the dump file.
346    
347     delete writer;
348    
349 gezelter 1390 sprintf(painCave.errMsg, "A new OpenMD file called \"%s\" has been "
350 gezelter 1065 "generated.\n", outputFileName.c_str());
351 gezelter 1062 painCave.isFatal = 0;
352     simError();
353 chuckv 950 return 0;
354     }
355    
356 gezelter 1062 void createMdFile(const std::string&oldMdFileName,
357     const std::string&newMdFileName,
358 gezelter 1065 std::vector<int> nMol) {
359 chuckv 950 ifstream oldMdFile;
360     ofstream newMdFile;
361     const int MAXLEN = 65535;
362     char buffer[MAXLEN];
363    
364     //create new .md file based on old .md file
365 gezelter 1062
366 chuckv 950 oldMdFile.open(oldMdFileName.c_str());
367     newMdFile.open(newMdFileName.c_str());
368    
369     oldMdFile.getline(buffer, MAXLEN);
370    
371     int i = 0;
372     while (!oldMdFile.eof()) {
373    
374     //correct molecule number
375     if (strstr(buffer, "nMol") != NULL) {
376 gezelter 1065 if(i<nMol.size()){
377     sprintf(buffer, "\tnMol = %i;", nMol.at(i));
378 chuckv 950 newMdFile << buffer << std::endl;
379     i++;
380     }
381     } else
382     newMdFile << buffer << std::endl;
383    
384     oldMdFile.getline(buffer, MAXLEN);
385     }
386    
387     oldMdFile.close();
388     newMdFile.close();
389 gezelter 1077
390     if (i != nMol.size()) {
391     sprintf(painCave.errMsg, "Couldn't replace the correct number of nMol\n"
392     "\tstatements in component blocks. Make sure that all\n"
393     "\tcomponents in the template file have nMol=1");
394     painCave.isFatal = 1;
395     simError();
396     }
397    
398 chuckv 950 }
399    

Properties

Name Value
svn:keywords Author Id Revision Date