ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-4/src/applications/nanoparticleBuilder/nanoparticleBuilder.cpp
Revision: 3044
Committed: Fri Oct 13 20:16:59 2006 UTC (17 years, 10 months ago) by chuckv
File size: 10881 byte(s)
Log Message:
Changed nanoparticle builder for new dump syntax.

File Contents

# User Rev Content
1 chuckv 2352 /*
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     * 1. Acknowledgement of the program authors must be made in any
10     * publication of scientific results based in part on use of the
11     * program. An acceptable form of acknowledgement is citation of
12     * the article in which the program was described (Matthew
13     * A. Meineke, Charles F. Vardeman II, Teng Lin, Christopher
14     * J. Fennell and J. Daniel Gezelter, "OOPSE: An Object-Oriented
15     * Parallel Simulation Engine for Molecular Dynamics,"
16     * J. Comput. Chem. 26, pp. 252-271 (2005))
17     *
18     * 2. Redistributions of source code must retain the above copyright
19     * notice, this list of conditions and the following disclaimer.
20     *
21     * 3. Redistributions in binary form must reproduce the above copyright
22     * notice, this list of conditions and the following disclaimer in the
23     * documentation and/or other materials provided with the
24     * distribution.
25     *
26     * This software is provided "AS IS," without a warranty of any
27     * kind. All express or implied conditions, representations and
28     * warranties, including any implied warranty of merchantability,
29     * fitness for a particular purpose or non-infringement, are hereby
30     * excluded. The University of Notre Dame and its licensors shall not
31     * be liable for any damages suffered by licensee as a result of
32     * using, modifying or distributing the software or its
33     * derivatives. In no event will the University of Notre Dame or its
34     * licensors be liable for any lost revenue, profit or data, or for
35     * direct, indirect, special, consequential, incidental or punitive
36     * damages, however caused and regardless of the theory of liability,
37     * arising out of the use of or inability to use software, even if the
38     * University of Notre Dame has been advised of the possibility of
39     * such damages.
40     */
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 2657 #include <algorithm>
51 chuckv 2352
52     #include "config.h"
53 chuckv 2657 #include "shapedLatticeSpherical.hpp"
54 chuckv 2352 #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     using namespace oopse;
68     void createMdFile(const std::string&oldMdFileName,
69     const std::string&newMdFileName,
70 chuckv 3044 std::vector<int> numMol);
71 chuckv 2352
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     std::string outPrefix;
82 chuckv 3044 std::string outputFileName;
83 chuckv 2352 std::string outInitFileName;
84    
85    
86    
87     Lattice *simpleLat;
88 chuckv 2657 MoLocator* locator;
89     int* numMol;
90     int nComponents;
91 chuckv 2352 double latticeConstant;
92     std::vector<double> lc;
93 chuckv 3044 double mass;
94    
95 chuckv 2352 const double rhoConvertConst = 1.661;
96     double density;
97 chuckv 2657 double particleRadius;
98 chuckv 2352
99    
100    
101     Mat3x3d hmat;
102     std::vector<Vector3d> latticePos;
103     std::vector<Vector3d> latticeOrt;
104     int numMolPerCell;
105     int nShells; /* Number of shells in nanoparticle*/
106 chuckv 3044
107 chuckv 2352
108     DumpWriter *writer;
109    
110 chuckv 2574 // Parse Command Line Arguments
111 chuckv 2352 if (cmdline_parser(argc, argv, &args_info) != 0)
112     exit(1);
113    
114    
115    
116     /* get lattice type */
117 chuckv 3044 latticeType = "FCC";
118    
119 chuckv 2352 /* get input file name */
120     if (args_info.inputs_num)
121     inputFileName = args_info.inputs[0];
122     else {
123 chuckv 3044 sprintf(painCave.errMsg, "No input .md file name was specified"
124     "on the command line");
125     painCave.isFatal = 1;
126 chuckv 2352 cmdline_parser_print_help();
127 chuckv 3044 simError();
128 chuckv 2352 }
129    
130     /* parse md file and set up the system */
131     SimCreator oldCreator;
132     SimInfo* oldInfo = oldCreator.createSim(inputFileName, false);
133    
134    
135     latticeConstant = args_info.latticeCnst_arg;
136     particleRadius = args_info.radius_arg;
137 chuckv 2657 Globals* simParams = oldInfo->getSimParams();
138 chuckv 2352
139 chuckv 3044
140 chuckv 2352 /* create Molocators */
141     locator = new MoLocator(oldInfo->getMoleculeStamp(0), oldInfo->getForceField());
142    
143 chuckv 2657 /* Create nanoparticle */
144     shapedLatticeSpherical nanoParticle(latticeConstant,latticeType,particleRadius);
145 chuckv 2672
146 chuckv 2657 /* Build a lattice and get lattice points for this lattice constant */
147 chuckv 3044 vector<Vector3d> sites = nanoParticle.getPoints();
148     vector<Vector3d> orientations = nanoParticle.getPointsOrt();
149    
150     std::cout <<"nSites: " << sites.size() << std::endl;
151    
152 chuckv 2657 /* Get number of lattice sites */
153 chuckv 3044 int nSites = sites.size();
154 chuckv 2657
155 chuckv 3044
156    
157    
158     std::vector<Component*> components = simParams->getComponents();
159     std::vector<RealType> molFractions;
160     std::vector<RealType> molecularMasses;
161     std::vector<int> nMol;
162     nComponents = components.size();
163 chuckv 2352
164 chuckv 3044
165    
166     if (nComponents == 1) {
167     molFractions.push_back(1.0);
168     } else {
169     if (args_info.molFraction_given == nComponents) {
170     for (int i = 0; i < nComponents; i++) {
171     molFractions.push_back(args_info.molFraction_arg[i]);
172     }
173     } else if (args_info.molFraction_given == nComponents-1) {
174     RealType remainingFraction = 1.0;
175     for (int i = 0; i < nComponents-1; i++) {
176     molFractions.push_back(args_info.molFraction_arg[i]);
177     remainingFraction -= molFractions[i];
178     }
179     molFractions.push_back(remainingFraction);
180     } else {
181     sprintf(painCave.errMsg, "nanoparticleBuilder can't figure out molFractions "
182     "for all of the components in the <MetaData> block.");
183     painCave.isFatal = 1;
184     simError();
185     }
186     }
187    
188     RealType totalFraction = 0.0;
189    
190     /* Do some simple sanity checking*/
191    
192    
193    
194     for (int i = 0; i < nComponents; i++) {
195     if (molFractions.at(i) < 0.0) {
196     sprintf(painCave.errMsg, "One of the requested molFractions was"
197     " less than zero!");
198     painCave.isFatal = 1;
199     simError();
200     }
201     if (molFractions.at(i) > 1.0) {
202     sprintf(painCave.errMsg, "One of the requested molFractions was"
203     " greater than one!");
204     painCave.isFatal = 1;
205     simError();
206     }
207     totalFraction += molFractions.at(i);
208     }
209     if (abs(totalFraction - 1.0) > 1e-6) {
210     sprintf(painCave.errMsg, "The sum of molFractions was not close enough to 1.0");
211     painCave.isFatal = 1;
212     simError();
213     }
214    
215     int remaining = nSites;
216     for (int i=0; i < nComponents-1; i++) {
217     nMol.push_back(int((RealType)nSites * molFractions.at(i)));
218     remaining -= nMol.at(i);
219     }
220     nMol.push_back(remaining);
221    
222    
223    
224     // recompute actual mol fractions and perform final sanity check:
225    
226     int totalMolecules = 0;
227     RealType totalMass = 0.0;
228     for (int i=0; i < nComponents; i++) {
229     molFractions[i] = (RealType)(nMol.at(i))/(RealType)nSites;
230     totalMolecules += nMol.at(i);
231     molecularMasses.push_back(getMolMass(oldInfo->getMoleculeStamp(i),
232     oldInfo->getForceField()));
233     totalMass += (RealType)(nMol.at(i)) * molecularMasses.at(i);
234     }
235     RealType avgMass = totalMass / (RealType) totalMolecules;
236    
237     if (totalMolecules != nSites) {
238     sprintf(painCave.errMsg, "Computed total number of molecules is not equal "
239     "to the number of lattice sites!");
240     painCave.isFatal = 1;
241     simError();
242     }
243    
244    
245    
246    
247     vector<int> ids;
248     for (int i = 0; i < sites.size(); i++) ids.push_back(i);
249 chuckv 2352 /* Random particle is the default case*/
250     if (!args_info.ShellRadius_given){
251 chuckv 2737 /* do the iPod thing, Shuffle da vector */
252 chuckv 3044 std::random_shuffle(ids.begin(), ids.end());
253 chuckv 2352 } else{ /*Handle core-shell with multiple components.*/
254     std::cout << "Creating a core-shell nanoparticle." << std::endl;
255     if (nComponents != args_info.ShellRadius_given + 1){
256 chuckv 3044 sprintf(painCave.errMsg, "Number of .md components "
257     "does not match the number of shell radius specifications");
258     painCave.isFatal = 1;
259     simError();
260 chuckv 2657 }
261 chuckv 2352
262     }
263    
264 chuckv 2737
265 chuckv 2352
266 chuckv 2737
267 chuckv 3044 outputFileName = args_info.output_arg;
268    
269 chuckv 2737
270 chuckv 3044 //creat new .md file on fly which corrects the number of molecule
271     createMdFile(inputFileName, outputFileName, nMol);
272 chuckv 2352
273     if (oldInfo != NULL)
274     delete oldInfo;
275    
276    
277     // We need to read in new siminfo object.
278     //parse md file and set up the system
279     //SimCreator NewCreator;
280 chuckv 2737 SimCreator newCreator;
281 chuckv 3044 SimInfo* NewInfo = newCreator.createSim(outputFileName, false);
282 chuckv 2352
283    
284 chuckv 2657 // Place molecules
285 chuckv 2352 Molecule* mol;
286     SimInfo::MoleculeIterator mi;
287     mol = NewInfo->beginMolecule(mi);
288 chuckv 2737 int l = 0;
289 chuckv 3044
290     for (int i = 0; i < nComponents; i++){
291     locator = new MoLocator(NewInfo->getMoleculeStamp(i),
292     NewInfo->getForceField());
293     for (int n = 0; n < nMol.at(i); n++) {
294     mol = NewInfo->getMoleculeByGlobalIndex(l);
295     locator->placeMol(sites[ids[l]], orientations[ids[l]], mol);
296     l++;
297     }
298 chuckv 2657 }
299 chuckv 2352
300 chuckv 3044
301    
302 chuckv 2352 //fill Hmat
303 chuckv 3044 hmat(0, 0)= 2.0*particleRadius;
304 chuckv 2352 hmat(0, 1) = 0.0;
305     hmat(0, 2) = 0.0;
306    
307     hmat(1, 0) = 0.0;
308 chuckv 3044 hmat(1, 1) = 2.0*particleRadius;
309 chuckv 2352 hmat(1, 2) = 0.0;
310    
311     hmat(2, 0) = 0.0;
312     hmat(2, 1) = 0.0;
313 chuckv 3044 hmat(2, 2) = 2.0*particleRadius;
314 chuckv 2352
315     //set Hmat
316     NewInfo->getSnapshotManager()->getCurrentSnapshot()->setHmat(hmat);
317    
318    
319     //create dumpwriter and write out the coordinates
320 chuckv 3044 writer = new DumpWriter(NewInfo,outputFileName);
321 chuckv 2352
322     if (writer == NULL) {
323 chuckv 3044 sprintf(painCave.errMsg, "Error in creating dumpwrite object ");
324     painCave.isFatal = 1;
325     simError();
326 chuckv 2352 }
327    
328     writer->writeDump();
329     std::cout << "new initial configuration file: " << outInitFileName
330     << " is generated." << std::endl;
331 chuckv 3044
332    
333     // deleting the writer will put the closing at the end of the dump file
334     delete writer;
335    
336     // cleanup a by calling sim error.....
337     sprintf(painCave.errMsg, "A new OOPSE MD file called \"%s\" has been "
338     "generated.\n", outputFileName.c_str());
339     painCave.isFatal = 0;
340     simError();
341 chuckv 2352 return 0;
342     }
343    
344     void createMdFile(const std::string&oldMdFileName, const std::string&newMdFileName,
345 chuckv 3044 std::vector<int> nMol) {
346 chuckv 2352 ifstream oldMdFile;
347     ofstream newMdFile;
348     const int MAXLEN = 65535;
349     char buffer[MAXLEN];
350    
351     //create new .md file based on old .md file
352     oldMdFile.open(oldMdFileName.c_str());
353     newMdFile.open(newMdFileName.c_str());
354    
355     oldMdFile.getline(buffer, MAXLEN);
356 chuckv 2657
357     int i = 0;
358 chuckv 2352 while (!oldMdFile.eof()) {
359    
360     //correct molecule number
361     if (strstr(buffer, "nMol") != NULL) {
362 chuckv 3044 if(i<nMol.size()){
363     sprintf(buffer, "\tnMol = %i;", nMol.at(i));
364 chuckv 2737 newMdFile << buffer << std::endl;
365     i++;
366     }
367 chuckv 2352 } else
368     newMdFile << buffer << std::endl;
369    
370     oldMdFile.getline(buffer, MAXLEN);
371     }
372    
373     oldMdFile.close();
374     newMdFile.close();
375     }
376