ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-1.0/utils/sysbuilder/simpleBuilder.cpp
Revision: 1435
Committed: Thu Jul 29 18:16:16 2004 UTC (19 years, 11 months ago) by tim
File size: 7241 byte(s)
Log Message:
working version of simpleBuilder

File Contents

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