ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-2.0/src/applications/simpleBuilder/simpleBuilder.cpp
Revision: 1674
Committed: Thu Oct 28 19:06:59 2004 UTC (19 years, 8 months ago) by tim
File size: 7128 byte(s)
Log Message:
STL next_permutation like next_combination is working

File Contents

# User Rev Content
1 tim 1501 #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 tim 1674 #include "math/Vector3.hpp"
17 tim 1501 #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, 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     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, ny, nz;
43     double Hmat[3][3];
44     MoLocator *locator;
45     vector<Vector3d> latticePos;
46     vector<Vector3d> latticeOrt;
47     int numMolPerCell;
48     int curMolIndex;
49     DumpWriter* writer;
50    
51     // parse command line arguments
52     if (cmdline_parser (argc, argv, &args_info) != 0)
53     exit(1) ;
54    
55     density = args_info.density_arg;
56    
57     //get lattice type
58     latticeType = UpperCase(args_info.latticetype_arg);
59     if(!LatticeFactory::getInstance()->hasLatticeCreator(latticeType)){
60     cerr << latticeType << " is an invalid lattice type" << endl;
61     cerr << LatticeFactory::getInstance()->toString() << endl;
62     exit(1);
63     }
64    
65     //get the number of unit cell
66     nx = args_info.nx_arg;
67     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     ny = args_info.ny_arg;
73     if(ny <= 0){
74     cerr << "The number of unit cell in l direction must be greater than 0" << endl;
75     exit(1);
76     }
77    
78     nz = args_info.nz_arg;
79     if(nz <= 0){
80     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     if (args_info.inputs_num)
86     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     oldSimSetup = new SimSetup();
102     if(oldSimSetup == NULL){
103     cerr << "error in creating SimSetup" << endl;
104     exit(1);
105     }
106    
107     oldSimSetup->suspendInit();
108     oldSimSetup->setSimInfo(oldInfo );
109     oldSimSetup->parseFile(&inputFileName[0] );
110     oldSimSetup->createSim();
111    
112     if(oldInfo->nComponents >=2){
113     cerr << "can not build the system with more than two components" << endl;
114     exit(1);
115     }
116    
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     //creat lattice
122     simpleLat = LatticeFactory::getInstance()->createLattice(latticeType);
123     if(simpleLat == NULL){
124     cerr << "Error in creating lattice" << endl;
125     exit(1);
126     }
127    
128     numMolPerCell = simpleLat->getNumSitesPerCell();
129    
130     //calculate lattice constant (in Angstrom)
131     latticeConstant = pow(rhoConvertConst * numMolPerCell * mass /density, 1.0/3.0);
132    
133     //set lattice constant
134     lc.push_back(latticeConstant);
135     simpleLat->setLatticeConstant(lc);
136    
137     //calculate the total number of molecules
138     numMol = nx * ny * nz * numMolPerCell;
139    
140     if (oldInfo->n_mol != numMol){
141    
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     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     }
151    
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     //allocat memory for storing pos, vel and etc
160     oldInfo->getConfiguration()->createArrays(oldInfo->n_atoms);
161     for (int i = 0; i < oldInfo->n_atoms; i++)
162     oldInfo->atoms[i]->setCoords();
163    
164     //creat Molocator
165     locator = new MoLocator(oldInfo->compStamps[0], oldSimSetup->getForceField());
166    
167     //fill Hmat
168     Hmat[0][0] = nx * latticeConstant;
169     Hmat[0][1] = 0.0;
170     Hmat[0][2] = 0.0;
171    
172     Hmat[1][0] = 0.0;
173     Hmat[1][1] = ny * latticeConstant;
174     Hmat[1][2] = 0.0;
175    
176     Hmat[2][0] = 0.0;
177     Hmat[2][1] = 0.0;
178     Hmat[2][2] = nz * latticeConstant ;
179    
180     //set Hmat
181     oldInfo->setBoxM(Hmat);
182    
183     //place the molecules
184    
185     curMolIndex = 0;
186    
187     //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    
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     //get the position of the cell sites
196     simpleLat->getLatticePointsPos(latticePos, i, j, k);
197    
198     for(int l = 0; l < numMolPerCell; l++)
199     locator->placeMol(latticePos[l], latticeOrt[l], &(oldInfo->molecules[curMolIndex++]));
200     }
201     }
202     }
203    
204     //create dumpwriter and write out the coordinates
205     oldInfo->finalName = outInitFileName;
206     writer = new DumpWriter( oldInfo );
207     if(writer == NULL){
208     cerr << "error in creating DumpWriter" << endl;
209     exit(1);
210     }
211     writer->writeFinal(0);
212     cout << "new initial configuration file: " << outInitFileName <<" is generated." << endl;
213     //delete objects
214    
215     //delete oldInfo and oldSimSetup
216     if(oldInfo != NULL)
217     delete oldInfo;
218    
219     if(oldSimSetup != NULL)
220     delete oldSimSetup;
221    
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     oldMdFile.open(oldMdFileName.c_str());
235     newMdFile.open(newMdFileName.c_str());
236    
237     oldMdFile.getline(buffer, MAXLEN);
238     while(!oldMdFile.eof()){
239    
240     //correct molecule number
241     if(strstr(buffer, "nMol") !=NULL){
242     sprintf(buffer, "\t\tnMol = %d;", numMol);
243     newMdFile << buffer << endl;
244     }
245     else
246     newMdFile << buffer << endl;
247    
248     oldMdFile.getline(buffer, MAXLEN);
249     }
250    
251     oldMdFile.close();
252     newMdFile.close();
253    
254     }
255    
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     }