ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-4/src/applications/randomBuilder/randomBuilder.cpp
Revision: 3036
Committed: Tue Oct 10 02:44:13 2006 UTC (17 years, 8 months ago) by gezelter
File size: 10017 byte(s)
Log Message:
fixing bugs in 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 3036 * @version $Id: randomBuilder.cpp,v 1.4 2006-10-10 02:44:13 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 3036 int components, int* numMol);
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     int* numMol;
90 tim 2759 RealType latticeConstant;
91     std::vector<RealType> lc;
92     RealType mass;
93     const RealType rhoConvertConst = 1.661;
94     RealType density;
95 gezelter 3036 int nx, ny, nz;
96 chuckv 2738 Mat3x3d hmat;
97     MoLocator *locator;
98     std::vector<Vector3d> latticePos;
99     std::vector<Vector3d> latticeOrt;
100     int numMolPerCell;
101     int curMolIndex;
102     DumpWriter *writer;
103    
104     // parse command line arguments
105     if (cmdline_parser(argc, argv, &args_info) != 0)
106     exit(1);
107    
108     density = args_info.density_arg;
109    
110     //get lattice type
111     latticeType = UpperCase(args_info.latticetype_arg);
112    
113     simpleLat = LatticeFactory::getInstance()->createLattice(latticeType);
114    
115     if (simpleLat == NULL) {
116     sprintf(painCave.errMsg, "Lattice Factory can not create %s lattice\n",
117     latticeType.c_str());
118     painCave.isFatal = 1;
119     simError();
120     }
121    
122 gezelter 3036 //get the number of unit cells in each direction:
123    
124 chuckv 2738 nx = args_info.nx_arg;
125    
126     if (nx <= 0) {
127 gezelter 3036 sprintf(painCave.errMsg, "The number of unit cells in the x direction "
128     "must be greater than 0.");
129     painCave.isFatal = 1;
130     simError();
131 chuckv 2738 }
132    
133     ny = args_info.ny_arg;
134    
135     if (ny <= 0) {
136 gezelter 3036 sprintf(painCave.errMsg, "The number of unit cells in the y direction "
137     "must be greater than 0.");
138     painCave.isFatal = 1;
139     simError();
140 chuckv 2738 }
141    
142     nz = args_info.nz_arg;
143    
144     if (nz <= 0) {
145 gezelter 3036 sprintf(painCave.errMsg, "The number of unit cells in the z direction "
146     "must be greater than 0.");
147     painCave.isFatal = 1;
148     simError();
149 chuckv 2738 }
150    
151     //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     int nComponents =simParams->getNComponents();
168 gezelter 3035 if (oldInfo->getNMoleculeStamp() > 2) {
169 gezelter 3036 sprintf(painCave.errMsg, "randomBuilder can't yet build a system with "
170     "more than two components.");
171     painCave.isFatal = 1;
172     simError();
173 chuckv 2738 }
174    
175     //get mass of molecule.
176    
177     mass = getMolMass(oldInfo->getMoleculeStamp(0), oldInfo->getForceField());
178    
179 gezelter 3036 // Create the lattice
180    
181 chuckv 2738 simpleLat = LatticeFactory::getInstance()->createLattice(latticeType);
182    
183     if (simpleLat == NULL) {
184 gezelter 3036 sprintf(painCave.errMsg, "Error in creating lattice.");
185     painCave.isFatal = 1;
186     simError();
187 chuckv 2738 }
188    
189     numMolPerCell = simpleLat->getNumSitesPerCell();
190    
191 gezelter 3036 // Calculate lattice constant (in Angstroms)
192    
193 chuckv 2738 latticeConstant = pow(rhoConvertConst * numMolPerCell * mass / density,
194 tim 2759 (RealType)(1.0 / 3.0));
195 chuckv 2738
196 gezelter 3036 // Set the lattice constant
197    
198 chuckv 2738 lc.push_back(latticeConstant);
199     simpleLat->setLatticeConstant(lc);
200    
201 gezelter 3036 // Calculate the total number of molecules
202    
203 chuckv 2738 int totMol = nx * ny * nz * numMolPerCell;
204    
205 gezelter 3036 // Calculate the lattice sites and fill the lattice vector.
206    
207     // Get the standard orientations of the cell sites
208    
209     latticeOrt = simpleLat->getLatticePointsOrt();
210    
211     vector<Vector3d> sites;
212     vector<Vector3d> orientations;
213 chuckv 2738
214     for(int i = 0; i < nx; i++) {
215     for(int j = 0; j < ny; j++) {
216     for(int k = 0; k < nz; k++) {
217    
218 gezelter 3036 // Get the position of the cell sites
219    
220 chuckv 2738 simpleLat->getLatticePointsPos(latticePos, i, j, k);
221    
222     for(int l = 0; l < numMolPerCell; l++) {
223 gezelter 3036 sites.push_back(latticePos[l]);
224     orientations.push_back(latticeOrt[l]);
225 chuckv 2738 }
226     }
227     }
228     }
229    
230 gezelter 3036 int numSites = sites.size();
231 chuckv 2738
232     numMol = new int[nComponents];
233     if (nComponents != args_info.molFraction_given && nComponents != 1){
234 gezelter 3036 sprintf(painCave.errMsg, "There needs to be the same number of "
235     "molFraction arguments as there are components in the "
236     "<MetaData> block.");
237     painCave.isFatal = 1;
238     simError();
239 chuckv 2738 }
240     int totComponents = 0;
241 gezelter 3036 for (int i = 0;i<nComponents-1;i++){
242 tim 2759 numMol[i] = int((RealType)numSites * args_info.molFraction_arg[i]);
243 chuckv 2738 std::cout<<numMol[i]<<std::endl;
244     totComponents += numMol[i];
245     }
246     numMol[nComponents-1] = numSites - totComponents;
247    
248 gezelter 3036 outputFileName = args_info.output_arg;
249 chuckv 2738
250 gezelter 3036 // create a new .md file on the fly which corrects the number of molecules
251 chuckv 2738
252 gezelter 3036 createMdFile(inputFileName, outputFileName, nComponents, numMol);
253 chuckv 2738
254 gezelter 3036 if (oldInfo != NULL)
255     delete oldInfo;
256    
257     // We need to read in the new SimInfo object, then Parse the
258     // md file and set up the system
259    
260     SimCreator newCreator;
261     SimInfo* newInfo = newCreator.createSim(outputFileName, false);
262    
263     // fill Hmat
264    
265     hmat(0, 0) = nx * latticeConstant;
266 chuckv 2738 hmat(0, 1) = 0.0;
267     hmat(0, 2) = 0.0;
268    
269     hmat(1, 0) = 0.0;
270     hmat(1, 1) = ny * latticeConstant;
271     hmat(1, 2) = 0.0;
272    
273     hmat(2, 0) = 0.0;
274     hmat(2, 1) = 0.0;
275     hmat(2, 2) = nz * latticeConstant;
276    
277 gezelter 3036 // Set Hmat
278 chuckv 2738
279 gezelter 3036 newInfo->getSnapshotManager()->getCurrentSnapshot()->setHmat(hmat);
280 chuckv 2738
281 gezelter 3036 // place the molecules
282    
283 chuckv 2738 curMolIndex = 0;
284    
285 gezelter 3036 // Randomize a vector of ints:
286 chuckv 2738
287 gezelter 3036 vector<int> ids;
288     for (int i = 0; i < sites.size(); i++) ids.push_back(i);
289     std::random_shuffle(ids.begin(), ids.end());
290 chuckv 2738
291     Molecule* mol;
292     int l = 0;
293 gezelter 3036 for (int i = 0; i < nComponents; i++){
294     locator = new MoLocator(newInfo->getMoleculeStamp(i),
295     newInfo->getForceField());
296     for (int n = 0; n < numMol[i]; n++) {
297     mol = newInfo->getMoleculeByGlobalIndex(l);
298     locator->placeMol(sites[ids[l]], orientations[ids[l]], mol);
299     l++;
300     }
301 chuckv 2738 }
302 gezelter 3036
303     // Create DumpWriter and write out the coordinates
304 chuckv 2738
305 gezelter 3036 writer = new DumpWriter(newInfo, outputFileName);
306 chuckv 2738
307     if (writer == NULL) {
308 gezelter 3036 sprintf(painCave.errMsg, "error in creating DumpWriter");
309     painCave.isFatal = 1;
310     simError();
311 chuckv 2738 }
312    
313 gezelter 3036 writer->writeDump();
314    
315     // deleting the writer will put the closing at the end of the dump file.
316    
317     delete writer;
318    
319     sprintf(painCave.errMsg, "A new OOPSE MD file called \"%s\" has been "
320     "generated.", outputFileName.c_str());
321     painCave.isFatal = 0;
322     simError();
323 chuckv 2738 return 0;
324     }
325    
326 gezelter 3036 void createMdFile(const std::string&oldMdFileName,
327     const std::string&newMdFileName,
328     int components, int* numMol) {
329 chuckv 2738 ifstream oldMdFile;
330     ofstream newMdFile;
331     const int MAXLEN = 65535;
332     char buffer[MAXLEN];
333    
334     //create new .md file based on old .md file
335 gezelter 3036
336 chuckv 2738 oldMdFile.open(oldMdFileName.c_str());
337     newMdFile.open(newMdFileName.c_str());
338    
339     oldMdFile.getline(buffer, MAXLEN);
340    
341     int i = 0;
342     while (!oldMdFile.eof()) {
343    
344     //correct molecule number
345     if (strstr(buffer, "nMol") != NULL) {
346     if(i<components){
347 gezelter 3036 sprintf(buffer, "\tnMol = %i;", numMol[i]);
348 chuckv 2738 newMdFile << buffer << std::endl;
349     i++;
350     }
351     } else
352     newMdFile << buffer << std::endl;
353    
354     oldMdFile.getline(buffer, MAXLEN);
355     }
356    
357     oldMdFile.close();
358     newMdFile.close();
359     }
360