ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/branches/new_design/OOPSE-3.0/src/applications/simpleBuilder/simpleBuilder.cpp
Revision: 1770
Committed: Tue Nov 23 17:53:43 2004 UTC (19 years, 9 months ago) by tim
File size: 7826 byte(s)
Log Message:
add Electrostatic AtomType Section Parser

File Contents

# User Rev Content
1 tim 1770 #include <cstdlib>
2     #include <cstdio>
3     #include <cstring>
4     #include <cmath>
5     #include <iostream>
6     #include <string>
7     #include <map>
8     #include <fstream>
9    
10     #include "io/Globals.hpp"
11     #include "brains/SimInfo.hpp"
12     #include "brains/SimSetup.hpp"
13     #include "applications/simpleBuilder/simpleBuilderCmd.h"
14     #include "utils/StringUtils.hpp"
15     #include "applications/simpleBuilder/LatticeFactory.hpp"
16     #include "math/Vector3.hpp"
17     #include "applications/simpleBuilder/MoLocator.hpp"
18     #include "applications/simpleBuilder/Lattice.hpp"
19    
20     using namespace std;
21    
22     void createMdFile(const string&oldMdFileName, const string&newMdFileName,
23     int numMol);
24     double getMolMass(MoleculeStamp * molStamp, ForceFields * myFF);
25    
26     int main(int argc, char *argv []) {
27     gengetopt_args_info args_info;
28     string latticeType;
29     string inputFileName;
30     string outPrefix;
31     string outMdFileName;
32     string outInitFileName;
33     SimInfo *oldInfo;
34     SimSetup *oldSimSetup;
35     BaseLattice *simpleLat;
36     int numMol;
37     double latticeConstant;
38     vector < double > lc;
39     double mass;
40     const double rhoConvertConst = 1.661;
41     double density;
42     int nx,
43     ny,
44     nz;
45     double Hmat[3][3];
46     MoLocator *locator;
47     vector < Vector3d > latticePos;
48     vector < Vector3d > latticeOrt;
49     int numMolPerCell;
50     int curMolIndex;
51     DumpWriter *writer;
52    
53     // parse command line arguments
54     if (cmdline_parser(argc, argv, &args_info) != 0)
55     exit(1);
56    
57     density = args_info.density_arg;
58    
59     //get lattice type
60     latticeType = UpperCase(args_info.latticetype_arg);
61    
62     if (!LatticeFactory::getInstance()->hasLatticeCreator(latticeType)) {
63     cerr << latticeType << " is an invalid lattice type" << endl;
64     cerr << LatticeFactory::getInstance()->toString() << endl;
65     exit(1);
66     }
67    
68     //get the number of unit cell
69     nx = args_info.nx_arg;
70    
71     if (nx <= 0) {
72     cerr << "The number of unit cell in h direction must be greater than 0"
73     << endl;
74     exit(1);
75     }
76    
77     ny = args_info.ny_arg;
78    
79     if (ny <= 0) {
80     cerr << "The number of unit cell in l direction must be greater than 0"
81     << endl;
82     exit(1);
83     }
84    
85     nz = args_info.nz_arg;
86    
87     if (nz <= 0) {
88     cerr << "The number of unit cell in k direction must be greater than 0"
89     << endl;
90     exit(1);
91     }
92    
93     //get input file name
94     if (args_info.inputs_num)
95     inputFileName = args_info.inputs[0];
96     else {
97     cerr << "You must specify a input file name.\n" << endl;
98     cmdline_parser_print_help();
99     exit(1);
100     }
101    
102     //parse md file and set up the system
103     oldInfo = new SimInfo;
104    
105     if (oldInfo == NULL) {
106     cerr << "error in creating SimInfo" << endl;
107     exit(1);
108     }
109    
110     oldSimSetup = new SimSetup();
111    
112     if (oldSimSetup == NULL) {
113     cerr << "error in creating SimSetup" << endl;
114     exit(1);
115     }
116    
117     oldSimSetup->suspendInit();
118     oldSimSetup->setSimInfo(oldInfo);
119     oldSimSetup->parseFile(&inputFileName[0]);
120     oldSimSetup->createSim();
121    
122     if (oldInfo->nComponents >= 2) {
123     cerr << "can not build the system with more than two components"
124     << endl;
125     exit(1);
126     }
127    
128     //get mass of molecule.
129     //Due to the design of OOPSE, given atom type, we have to query forcefiled to get the mass
130     mass = getMolMass(oldInfo->compStamps[0], oldSimSetup->getForceField());
131    
132     //creat lattice
133     simpleLat = LatticeFactory::getInstance()->createLattice(latticeType);
134    
135     if (simpleLat == NULL) {
136     cerr << "Error in creating lattice" << endl;
137     exit(1);
138     }
139    
140     numMolPerCell = simpleLat->getNumSitesPerCell();
141    
142     //calculate lattice constant (in Angstrom)
143     latticeConstant = pow(rhoConvertConst * numMolPerCell * mass / density,
144     1.0 / 3.0);
145    
146     //set lattice constant
147     lc.push_back(latticeConstant);
148     simpleLat->setLatticeConstant(lc);
149    
150     //calculate the total number of molecules
151     numMol = nx * ny * nz * numMolPerCell;
152    
153     if (oldInfo->n_mol != numMol) {
154     outPrefix = getPrefix(inputFileName.c_str()) + "_" + latticeType;
155     outMdFileName = outPrefix + ".md";
156    
157     //creat new .md file on fly which corrects the number of molecule
158     createMdFile(inputFileName, outMdFileName, numMol);
159     cerr
160     << "SimpleBuilder Error: the number of molecule and the density are not matched"
161     << endl;
162     cerr << "A new .md file: " << outMdFileName
163     << " is generated, use it to rerun the simpleBuilder" << endl;
164     exit(1);
165     }
166    
167     //determine the output file names
168     if (args_info.output_given)
169     outInitFileName = args_info.output_arg;
170     else
171     outInitFileName = getPrefix(inputFileName.c_str()) + ".in";
172    
173     //allocat memory for storing pos, vel and etc
174     oldInfo->getConfiguration()->createArrays(oldInfo->n_atoms);
175    
176     for(int i = 0; i < oldInfo->n_atoms; i++)
177     oldInfo->atoms[i]->setCoords();
178    
179     //creat Molocator
180     locator = new MoLocator(oldInfo->compStamps[0],
181     oldSimSetup->getForceField());
182    
183     //fill Hmat
184     Hmat[0][0] = nx * latticeConstant;
185     Hmat[0][1] = 0.0;
186     Hmat[0][2] = 0.0;
187    
188     Hmat[1][0] = 0.0;
189     Hmat[1][1] = ny * latticeConstant;
190     Hmat[1][2] = 0.0;
191    
192     Hmat[2][0] = 0.0;
193     Hmat[2][1] = 0.0;
194     Hmat[2][2] = nz * latticeConstant;
195    
196     //set Hmat
197     oldInfo->setBoxM(Hmat);
198    
199     //place the molecules
200    
201     curMolIndex = 0;
202    
203     //get the orientation of the cell sites
204     //for the same type of molecule in same lattice, it will not change
205     latticeOrt = simpleLat->getLatticePointsOrt();
206    
207     for(int i = 0; i < nx; i++) {
208     for(int j = 0; j < ny; j++) {
209     for(int k = 0; k < nz; k++) {
210    
211     //get the position of the cell sites
212     simpleLat->getLatticePointsPos(latticePos, i, j, k);
213    
214     for(int l = 0; l < numMolPerCell; l++)
215     locator->placeMol(latticePos[l], latticeOrt[l],
216     &(oldInfo->molecules[curMolIndex++]));
217     }
218     }
219     }
220    
221     //create dumpwriter and write out the coordinates
222     oldInfo->finalName = outInitFileName;
223     writer = new DumpWriter(oldInfo);
224    
225     if (writer == NULL) {
226     cerr << "error in creating DumpWriter" << endl;
227     exit(1);
228     }
229    
230     writer->writeFinal(0);
231     cout << "new initial configuration file: " << outInitFileName
232     << " is generated." << endl;
233    
234     //delete objects
235    
236     //delete oldInfo and oldSimSetup
237     if (oldInfo != NULL)
238     delete oldInfo;
239    
240     if (oldSimSetup != NULL)
241     delete oldSimSetup;
242    
243     if (writer != NULL)
244     delete writer;
245    
246     return 0;
247     }
248    
249     void createMdFile(const string&oldMdFileName, const string&newMdFileName,
250     int numMol) {
251     ifstream oldMdFile;
252     ofstream newMdFile;
253     const int MAXLEN = 65535;
254     char buffer[MAXLEN];
255    
256     //create new .md file based on old .md file
257     oldMdFile.open(oldMdFileName.c_str());
258     newMdFile.open(newMdFileName.c_str());
259    
260     oldMdFile.getline(buffer, MAXLEN);
261    
262     while (!oldMdFile.eof()) {
263    
264     //correct molecule number
265     if (strstr(buffer, "nMol") != NULL) {
266     sprintf(buffer, "\t\tnMol = %d;", numMol);
267     newMdFile << buffer << endl;
268     } else
269     newMdFile << buffer << endl;
270    
271     oldMdFile.getline(buffer, MAXLEN);
272     }
273    
274     oldMdFile.close();
275     newMdFile.close();
276     }
277    
278     double getMolMass(MoleculeStamp *molStamp, ForceFields *myFF) {
279     int nAtoms;
280     AtomStamp *currAtomStamp;
281     double totMass;
282    
283     totMass = 0;
284     nAtoms = molStamp->getNAtoms();
285    
286     for(size_t i = 0; i < nAtoms; i++) {
287     currAtomStamp = molStamp->getAtom(i);
288     totMass += myFF->getAtomTypeMass(currAtomStamp->getType());
289     }
290    
291     return totMass;
292     }