ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-4/src/applications/randomBuilder/randomBuilder.cpp
Revision: 3039
Committed: Tue Oct 10 14:52:20 2006 UTC (17 years, 9 months ago) by gezelter
File size: 11318 byte(s)
Log Message:
nearly complete rewrite of randomBuilder

File Contents

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