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

File Contents

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