ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-4/src/applications/simpleBuilder/simpleBuilder.cpp
(Generate patch)

Comparing trunk/OOPSE-4/src/applications/simpleBuilder/simpleBuilder.cpp (file contents):
Revision 1501 by tim, Tue Sep 28 23:24:25 2004 UTC vs.
Revision 2181 by tim, Tue Apr 12 21:58:09 2005 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines