ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-3.0/src/applications/nanoparticleBuilder/nanoparticleBuilder.cpp
Revision: 2352
Committed: Tue Oct 11 21:57:22 2005 UTC (18 years, 9 months ago) by chuckv
File size: 10207 byte(s)
Log Message:
Added code for nanoparticle builder to cvs.

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    
51     #include "config.h"
52    
53     #include "nanoparticleBuilderCmd.h"
54     #include "sphericalNanoparticle.hpp"
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     int numMol);
71    
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     std::string outMdFileName;
83     std::string outInitFileName;
84    
85    
86    
87     Lattice *simpleLat;
88     int numMol;
89     double latticeConstant;
90     std::vector<double> lc;
91     double mass;
92     const double rhoConvertConst = 1.661;
93     double density;
94    
95    
96    
97     Mat3x3d hmat;
98     MoLocator *locator;
99     sphericalNanoparticle *nanoparticle;
100     std::vector<Vector3d> latticePos;
101     std::vector<Vector3d> latticeOrt;
102     int numMolPerCell;
103     int nShells; /* Number of shells in nanoparticle*/
104     int numSites;
105    
106     DumpWriter *writer;
107    
108     // parse command line arguments
109     if (cmdline_parser(argc, argv, &args_info) != 0)
110     exit(1);
111    
112    
113    
114     /* get lattice type */
115     latticeType = UpperCase(args_info.latticetype_arg);
116    
117     /* get input file name */
118     if (args_info.inputs_num)
119     inputFileName = args_info.inputs[0];
120     else {
121     std::cerr << "You must specify a input file name.\n" << std::endl;
122     cmdline_parser_print_help();
123     exit(1);
124     }
125    
126     /* parse md file and set up the system */
127     SimCreator oldCreator;
128     SimInfo* oldInfo = oldCreator.createSim(inputFileName, false);
129    
130     nShells = 0;
131     if (args_info.coreShellRadius_given){
132     nShells = args_info.coreShellRadius_given;
133     }
134    
135     nComponents = oldInfo->getNMoleculeStamp();
136    
137     /* Check to see if we have enough components to build that many shells. */
138     if (nShells){
139     if (oldInfo->getNMoleculeStamp() != nShells) {
140     std::cerr << "Not enough components present in MD file to build specified number of shells"
141     << std::endl;
142     exit(1);
143     }
144     }
145    
146    
147     //creat lattice
148     simpleLat = LatticeFactory::getInstance()->createLattice(latticeType);
149    
150     if (simpleLat == NULL) {
151     std::cerr << "Error in creating lattice" << std::endl;
152     exit(1);
153     }
154    
155     numMolPerCell = simpleLat->getNumSitesPerCell();
156    
157     /*calculate lattice constant (in Angstrom)
158     latticeConstant = pow(rhoConvertConst * numMolPerCell * mass / density,
159     1.0 / 3.0);*/
160    
161     latticeConstant = args_info.latticeCnst_arg;
162     particleRadius = args_info.radius_arg;
163     particleDiameter = 2.0 * particleRadius;
164    
165     /* set lattice constant */
166     lc.push_back(latticeConstant);
167     simpleLat->setLatticeConstant(lc);
168    
169    
170     /*determine the output file names*/
171     if (args_info.output_given)
172     outInitFileName = args_info.output_arg;
173     else
174     outInitFileName = getPrefix(inputFileName.c_str()) + ".in";
175    
176    
177    
178    
179    
180    
181     /* create Molocators */
182     locator = new MoLocator(oldInfo->getMoleculeStamp(0), oldInfo->getForceField());
183    
184     /* create a new spherical nanoparticle */
185     nanoparticle = new sphericalNanoparticle(particleRadius,latticeConstant);
186     /* Build a nanoparticle to see how many sites are there */
187     numSites = new int[nComponents]
188     nanoparticle.getNMol(numSites);
189    
190     numMol = new int[nComponents];
191     /* Random particle is the default case*/
192     if (!args_info.ShellRadius_given){
193     std::cout << "Creating a random nanoparticle" << std::endl;
194     /* Check to see if we have enough components */
195     if (nComponents != args_info.molFraction_given + 1){
196     std::cerr << "Number of components does not equal molFraction occurances." << std::endl;
197     exit 1;
198     }
199     int totComponents = 0;
200     for (int i = 0;i<nComponents-2;i++){ /* Figure out Percent for each component */
201     numMol[i] = int((double)numSites * args_info.molFraction_arg[i]);
202     totComponents += numMol[i];
203     }
204     numMol[nComponents-1] = numSites - totComponents;
205    
206     } else{ /*Handle core-shell with multiple components.*/
207     std::cout << "Creating a core-shell nanoparticle." << std::endl;
208     if (nComponents != args_info.ShellRadius_given + 1){
209     std::cerr << "Number of components does not equal ShellRadius occurances." << std::endl;
210     exit 1;
211     }
212    
213    
214    
215     }
216    
217     //get the orientation of the cell sites
218     //for the same type of molecule in same lattice, it will not change
219     latticeOrt = simpleLat->getLatticePointsOrt();
220    
221    
222    
223     // needed for writing out new md file.
224    
225     outPrefix = getPrefix(inputFileName.c_str()) + "_" + latticeType;
226     outMdFileName = outPrefix + ".md";
227    
228     //creat new .md file on fly which corrects the number of molecule
229     createMdFile(inputFileName, outMdFileName, numcomponents,numMol);
230    
231     if (oldInfo != NULL)
232     delete oldInfo;
233    
234    
235     // We need to read in new siminfo object.
236     //parse md file and set up the system
237     //SimCreator NewCreator;
238    
239     SimInfo* NewInfo = oldCreator.createSim(outMdFileName, false);
240    
241     // This was so much fun the first time, lets do it again.
242    
243     Molecule* mol;
244     SimInfo::MoleculeIterator mi;
245     mol = NewInfo->beginMolecule(mi);
246    
247    
248     for(int i = -nx; i < nx; i++) {
249     for(int j = -ny; j < ny; j++) {
250     for(int k = -nz; k < nz; k++) {
251    
252     //get the position of the cell sites
253     simpleLat->getLatticePointsPos(latticePos, i, j, k);
254    
255     for(int l = 0; l < numMolPerCell; l++) {
256     #ifdef HAVE_CGAL
257     if (myGeometry->isInsidePolyhedron(latticePos[l][0],latticePos[l][1],latticePos[l][2])){
258     #endif
259     if (mol != NULL) {
260     locator->placeMol(latticePos[l], latticeOrt[l], mol);
261     } else {
262     std::cerr<<"Error in placing molecule " << std::endl;
263     }
264     mol = NewInfo->nextMolecule(mi);
265     #ifdef HAVE_CGAL
266     }
267     #endif
268     }
269     }
270     }
271     }
272    
273    
274    
275     //fill Hmat
276     hmat(0, 0)= nx * latticeConstant;
277     hmat(0, 1) = 0.0;
278     hmat(0, 2) = 0.0;
279    
280     hmat(1, 0) = 0.0;
281     hmat(1, 1) = ny * latticeConstant;
282     hmat(1, 2) = 0.0;
283    
284     hmat(2, 0) = 0.0;
285     hmat(2, 1) = 0.0;
286     hmat(2, 2) = nz * latticeConstant;
287    
288     //set Hmat
289     NewInfo->getSnapshotManager()->getCurrentSnapshot()->setHmat(hmat);
290    
291    
292     //create dumpwriter and write out the coordinates
293     NewInfo->setFinalConfigFileName(outInitFileName);
294     writer = new DumpWriter(NewInfo);
295    
296     if (writer == NULL) {
297     std::cerr << "error in creating DumpWriter" << std::endl;
298     exit(1);
299     }
300    
301     writer->writeDump();
302     std::cout << "new initial configuration file: " << outInitFileName
303     << " is generated." << std::endl;
304    
305     //delete objects
306    
307     //delete oldInfo and oldSimSetup
308    
309     if (NewInfo != NULL)
310     delete NewInfo;
311    
312     if (writer != NULL)
313     delete writer;
314     delete simpleLat;
315     cmdline_parser_free(&args_info);
316     return 0;
317     }
318    
319     void createMdFile(const std::string&oldMdFileName, const std::string&newMdFileName,
320     int components,int &nummol) {
321     ifstream oldMdFile;
322     ofstream newMdFile;
323     const int MAXLEN = 65535;
324     char buffer[MAXLEN];
325    
326     //create new .md file based on old .md file
327     oldMdFile.open(oldMdFileName.c_str());
328     newMdFile.open(newMdFileName.c_str());
329    
330     oldMdFile.getline(buffer, MAXLEN);
331    
332     while (!oldMdFile.eof()) {
333    
334     //correct molecule number
335     if (strstr(buffer, "nMol") != NULL) {
336     sprintf(buffer, "\tnMol = %i;", numMol);
337     newMdFile << buffer << std::endl;
338     } else
339     newMdFile << buffer << std::endl;
340    
341     oldMdFile.getline(buffer, MAXLEN);
342     }
343    
344     oldMdFile.close();
345     newMdFile.close();
346     }
347