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

# Content
1 /* 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 * @version $Id: randomBuilder.cpp,v 1.4 2006-10-10 02:44:13 gezelter Exp $
46 *
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 int components, int* numMol);
77
78 int main(int argc, char *argv []) {
79
80 // register force fields
81 registerForceFields();
82 registerLattice();
83
84 gengetopt_args_info args_info;
85 std::string latticeType;
86 std::string inputFileName;
87 std::string outputFileName;
88 Lattice *simpleLat;
89 int* numMol;
90 RealType latticeConstant;
91 std::vector<RealType> lc;
92 RealType mass;
93 const RealType rhoConvertConst = 1.661;
94 RealType density;
95 int nx, ny, nz;
96 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 //get the number of unit cells in each direction:
123
124 nx = args_info.nx_arg;
125
126 if (nx <= 0) {
127 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 }
132
133 ny = args_info.ny_arg;
134
135 if (ny <= 0) {
136 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 }
141
142 nz = args_info.nz_arg;
143
144 if (nz <= 0) {
145 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 }
150
151 //get input file name
152 if (args_info.inputs_num)
153 inputFileName = args_info.inputs[0];
154 else {
155 sprintf(painCave.errMsg, "No input .md file name was specified "
156 "on the command line");
157 painCave.isFatal = 1;
158 simError();
159 }
160
161 //parse md file and set up the system
162
163 SimCreator oldCreator;
164 SimInfo* oldInfo = oldCreator.createSim(inputFileName, false);
165 Globals* simParams = oldInfo->getSimParams();
166
167 int nComponents =simParams->getNComponents();
168 if (oldInfo->getNMoleculeStamp() > 2) {
169 sprintf(painCave.errMsg, "randomBuilder can't yet build a system with "
170 "more than two components.");
171 painCave.isFatal = 1;
172 simError();
173 }
174
175 //get mass of molecule.
176
177 mass = getMolMass(oldInfo->getMoleculeStamp(0), oldInfo->getForceField());
178
179 // Create the lattice
180
181 simpleLat = LatticeFactory::getInstance()->createLattice(latticeType);
182
183 if (simpleLat == NULL) {
184 sprintf(painCave.errMsg, "Error in creating lattice.");
185 painCave.isFatal = 1;
186 simError();
187 }
188
189 numMolPerCell = simpleLat->getNumSitesPerCell();
190
191 // Calculate lattice constant (in Angstroms)
192
193 latticeConstant = pow(rhoConvertConst * numMolPerCell * mass / density,
194 (RealType)(1.0 / 3.0));
195
196 // Set the lattice constant
197
198 lc.push_back(latticeConstant);
199 simpleLat->setLatticeConstant(lc);
200
201 // Calculate the total number of molecules
202
203 int totMol = nx * ny * nz * numMolPerCell;
204
205 // 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
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 // Get the position of the cell sites
219
220 simpleLat->getLatticePointsPos(latticePos, i, j, k);
221
222 for(int l = 0; l < numMolPerCell; l++) {
223 sites.push_back(latticePos[l]);
224 orientations.push_back(latticeOrt[l]);
225 }
226 }
227 }
228 }
229
230 int numSites = sites.size();
231
232 numMol = new int[nComponents];
233 if (nComponents != args_info.molFraction_given && nComponents != 1){
234 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 }
240 int totComponents = 0;
241 for (int i = 0;i<nComponents-1;i++){
242 numMol[i] = int((RealType)numSites * args_info.molFraction_arg[i]);
243 std::cout<<numMol[i]<<std::endl;
244 totComponents += numMol[i];
245 }
246 numMol[nComponents-1] = numSites - totComponents;
247
248 outputFileName = args_info.output_arg;
249
250 // create a new .md file on the fly which corrects the number of molecules
251
252 createMdFile(inputFileName, outputFileName, nComponents, numMol);
253
254 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 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 // Set Hmat
278
279 newInfo->getSnapshotManager()->getCurrentSnapshot()->setHmat(hmat);
280
281 // place the molecules
282
283 curMolIndex = 0;
284
285 // Randomize a vector of ints:
286
287 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
291 Molecule* mol;
292 int l = 0;
293 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 }
302
303 // Create DumpWriter and write out the coordinates
304
305 writer = new DumpWriter(newInfo, outputFileName);
306
307 if (writer == NULL) {
308 sprintf(painCave.errMsg, "error in creating DumpWriter");
309 painCave.isFatal = 1;
310 simError();
311 }
312
313 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 return 0;
324 }
325
326 void createMdFile(const std::string&oldMdFileName,
327 const std::string&newMdFileName,
328 int components, int* numMol) {
329 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
336 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 sprintf(buffer, "\tnMol = %i;", numMol[i]);
348 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