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

Comparing trunk/OOPSE-4/src/applications/randomBuilder/randomBuilder.cpp (file contents):
Revision 3035 by gezelter, Mon Oct 9 22:16:44 2006 UTC vs.
Revision 3039 by gezelter, Tue Oct 10 14:52:20 2006 UTC

# Line 42 | Line 42
42   *
43   *  Created by Charles F. Vardeman II on 10 Apr 2006.
44   *  @author  Charles F. Vardeman II
45 < *  @version $Id: randomBuilder.cpp,v 1.3 2006-10-09 22:16:44 gezelter Exp $
45 > *  @version $Id: randomBuilder.cpp,v 1.5 2006-10-10 14:52:20 gezelter Exp $
46   *
47   */
48  
# Line 73 | Line 73 | void createMdFile(const std::string&oldMdFileName,
73  
74   void createMdFile(const std::string&oldMdFileName,
75                    const std::string&newMdFileName,
76 <                  int components,int* numMol);
76 >                  std::vector<int> nMol);
77  
78   int main(int argc, char *argv []) {
79  
80 <  //register force fields
80 >  // register force fields
81    registerForceFields();
82    registerLattice();
83      
84    gengetopt_args_info args_info;
85    std::string latticeType;
86    std::string inputFileName;
87 <  std::string outPrefix;
88 <  std::string outMdFileName;
87 >  std::string outputFileName;
88    Lattice *simpleLat;
90  int* numMol;
89    RealType latticeConstant;
90    std::vector<RealType> lc;
93  RealType mass;
91    const RealType rhoConvertConst = 1.661;
92    RealType density;
93 <  int nx,
97 <    ny,
98 <    nz;
93 >  int nx, ny, nz;
94    Mat3x3d hmat;
95    MoLocator *locator;
96    std::vector<Vector3d> latticePos;
97    std::vector<Vector3d> latticeOrt;
98 <  int numMolPerCell;
104 <  int curMolIndex;
98 >  int nMolPerCell;
99    DumpWriter *writer;
100  
101    // parse command line arguments
# Line 121 | Line 115 | int main(int argc, char *argv []) {
115      painCave.isFatal = 1;
116      simError();
117    }
118 +  nMolPerCell = simpleLat->getNumSitesPerCell();
119  
120 <  //get the number of unit cell
120 >  //get the number of unit cells in each direction:
121 >
122    nx = args_info.nx_arg;
123  
124    if (nx <= 0) {
125 <    std::cerr << "The number of unit cell in h direction must be greater than 0" << std::endl;
126 <    exit(1);
125 >    sprintf(painCave.errMsg, "The number of unit cells in the x direction "
126 >            "must be greater than 0.");
127 >    painCave.isFatal = 1;
128 >    simError();
129    }
130  
131    ny = args_info.ny_arg;
132  
133    if (ny <= 0) {
134 <    std::cerr << "The number of unit cell in l direction must be greater than 0" << std::endl;
135 <    exit(1);
134 >    sprintf(painCave.errMsg, "The number of unit cells in the y direction "
135 >            "must be greater than 0.");
136 >    painCave.isFatal = 1;
137 >    simError();
138    }
139  
140    nz = args_info.nz_arg;
141  
142    if (nz <= 0) {
143 <    std::cerr << "The number of unit cell in k direction must be greater than 0" << std::endl;
144 <    exit(1);
143 >    sprintf(painCave.errMsg, "The number of unit cells in the z direction "
144 >            "must be greater than 0.");
145 >    painCave.isFatal = 1;
146 >    simError();
147    }
148  
149 +  int nSites = nMolPerCell * nx * ny * nz;
150 +
151    //get input file name
152    if (args_info.inputs_num)
153      inputFileName = args_info.inputs[0];
154    else {
155 <    std::cerr << "You must specify a input file name.\n" << std::endl;
156 <    cmdline_parser_print_help();
157 <    exit(1);
155 >    sprintf(painCave.errMsg, "No input .md file name was specified "
156 >            "on the command line");
157 >    painCave.isFatal = 1;
158 >    simError();
159    }
160  
161    //parse md file and set up the system
162 +
163    SimCreator oldCreator;
164    SimInfo* oldInfo = oldCreator.createSim(inputFileName, false);
165    Globals* simParams = oldInfo->getSimParams();
166  
167 <  int nComponents =simParams->getNComponents();
162 <  if (oldInfo->getNMoleculeStamp() > 2) {
163 <    std::cerr << "can not build the system with more than two components"
164 <              << std::endl;
165 <    exit(1);
166 <  }
167 >  // Calculate lattice constant (in Angstroms)
168  
169 <  //get mass of molecule.
169 >  std::vector<Component*> components = simParams->getComponents();
170 >  std::vector<RealType> molFractions;
171 >  std::vector<RealType> molecularMasses;
172 >  std::vector<int> nMol;
173 >  int nComponents = components.size();
174  
175 <  mass = getMolMass(oldInfo->getMoleculeStamp(0), oldInfo->getForceField());
175 >  if (nComponents == 1) {
176 >    molFractions.push_back(1.0);    
177 >  } else {
178 >    if (args_info.molFraction_given == nComponents) {
179 >      for (int i = 0; i < nComponents; i++) {
180 >        molFractions.push_back(args_info.molFraction_arg[i]);
181 >      }
182 >    } else if (args_info.molFraction_given == nComponents-1) {
183 >      RealType remainingFraction = 1.0;
184 >      for (int i = 0; i < nComponents-1; i++) {
185 >        molFractions.push_back(args_info.molFraction_arg[i]);
186 >        remainingFraction -= molFractions[i];
187 >      }
188 >      molFractions.push_back(remainingFraction);
189 >    } else {    
190 >      sprintf(painCave.errMsg, "randomBuilder can't figure out molFractions "
191 >              "for all of the components in the <MetaData> block.");
192 >      painCave.isFatal = 1;
193 >      simError();
194 >    }
195 >  }
196  
197 <  //creat lattice
198 <  simpleLat = LatticeFactory::getInstance()->createLattice(latticeType);
197 >  // do some sanity checking:
198 >  
199 >  RealType totalFraction = 0.0;
200  
201 <  if (simpleLat == NULL) {
202 <    std::cerr << "Error in creating lattice" << std::endl;
203 <    exit(1);
201 >  for (int i = 0; i < nComponents; i++) {
202 >    if (molFractions.at(i) < 0.0) {
203 >      sprintf(painCave.errMsg, "One of the requested molFractions was"
204 >              " less than zero!");
205 >      painCave.isFatal = 1;
206 >      simError();
207 >    }
208 >    if (molFractions.at(i) > 1.0) {
209 >      sprintf(painCave.errMsg, "One of the requested molFractions was"
210 >              " greater than one!");
211 >      painCave.isFatal = 1;
212 >      simError();
213 >    }
214 >    totalFraction += molFractions.at(i);
215    }
216 +  if (abs(totalFraction - 1.0) > 1e-6) {
217 +    sprintf(painCave.errMsg, "The sum of molFractions was not close enough to 1.0");
218 +    painCave.isFatal = 1;
219 +    simError();
220 +  }
221  
222 <  numMolPerCell = simpleLat->getNumSitesPerCell();
222 >  int remaining = nSites;
223 >  for (int i=0; i < nComponents-1; i++) {    
224 >    nMol.push_back(int((RealType)nSites * molFractions.at(i)));
225 >    remaining -= nMol.at(i);
226 >  }
227 >  nMol.push_back(remaining);
228  
229 <  //calculate lattice constant (in Angstrom)
183 <  latticeConstant = pow(rhoConvertConst * numMolPerCell * mass / density,
184 <                        (RealType)(1.0 / 3.0));
229 >  // recompute actual mol fractions and perform final sanity check:
230  
231 <  //set lattice constant
231 >  int totalMolecules = 0;
232 >  RealType totalMass = 0.0;
233 >  for (int i=0; i < nComponents; i++) {
234 >    molFractions[i] = (RealType)(nMol.at(i))/(RealType)nSites;
235 >    totalMolecules += nMol.at(i);
236 >    molecularMasses.push_back(getMolMass(oldInfo->getMoleculeStamp(i),
237 >                                         oldInfo->getForceField()));
238 >    totalMass += (RealType)(nMol.at(i)) * molecularMasses.at(i);
239 >  }
240 >  RealType avgMass = totalMass / (RealType) totalMolecules;
241 >
242 >  if (totalMolecules != nSites) {
243 >    sprintf(painCave.errMsg, "Computed total number of molecules is not equal "
244 >            "to the number of lattice sites!");
245 >    painCave.isFatal = 1;
246 >    simError();
247 >  }
248 >    
249 >  latticeConstant = pow(rhoConvertConst * nMolPerCell * avgMass / density,
250 >                        (RealType)(1.0 / 3.0));
251 >  
252 >  // Set the lattice constant
253 >  
254    lc.push_back(latticeConstant);
255    simpleLat->setLatticeConstant(lc);
256 +  
257 +  // Calculate the lattice sites and fill the lattice vector.
258  
259 <  //calculate the total number of molecules
191 <  int totMol = nx * ny * nz * numMolPerCell;
259 >  // Get the standard orientations of the cell sites
260  
261 <  // Calculate the lattice sites and fill lattice vector.
262 <  vector<Vector3d> latticeSites;
261 >  latticeOrt = simpleLat->getLatticePointsOrt();
262 >
263 >  vector<Vector3d> sites;
264 >  vector<Vector3d> orientations;
265    
266    for(int i = 0; i < nx; i++) {
267      for(int j = 0; j < ny; j++) {
268        for(int k = 0; k < nz; k++) {
269  
270 <        //get the position of the cell sites
270 >        // Get the position of the cell sites
271 >
272          simpleLat->getLatticePointsPos(latticePos, i, j, k);
273  
274 <        for(int l = 0; l < numMolPerCell; l++) {
275 <          latticeSites.push_back(latticePos[l]);
274 >        for(int l = 0; l < nMolPerCell; l++) {
275 >          sites.push_back(latticePos[l]);
276 >          orientations.push_back(latticeOrt[l]);
277          }
278        }
279      }
280    }
281 +  
282 +  outputFileName = args_info.output_arg;
283  
284 <  int numSites = latticeSites.size();
284 >  // create a new .md file on the fly which corrects the number of molecules
285  
286 <  numMol = new int[nComponents];
213 <  if (nComponents != args_info.molFraction_given && nComponents != 1){
214 <    std::cerr << "Number of components does not equal molFraction occurances." << std::endl;
215 <    exit(1);
216 <  }
217 <  int totComponents = 0;
218 <  for (int i = 0;i<nComponents-1;i++){ /* Figure out Percent for each component */
219 <    numMol[i] = int((RealType)numSites * args_info.molFraction_arg[i]);
220 <    std::cout<<numMol[i]<<std::endl;
221 <    totComponents += numMol[i];
222 <  }
223 <  numMol[nComponents-1] = numSites - totComponents;
224 <  
286 >  createMdFile(inputFileName, outputFileName, nMol);
287  
288 <  outPrefix = getPrefix(inputFileName.c_str()) + "_" + latticeType;
289 <  outMdFileName = outPrefix + ".md";
288 >  if (oldInfo != NULL)
289 >    delete oldInfo;
290  
291 <  //creat new .md file on fly which corrects the number of molecule    
292 <  createMdFile(inputFileName, outMdFileName, nComponents, numMol);
291 >  // We need to read in the new SimInfo object, then Parse the
292 >  // md file and set up the system
293  
294 <  //fill Hmat
295 <  hmat(0, 0)= nx * latticeConstant;
294 >  SimCreator newCreator;
295 >  SimInfo* newInfo = newCreator.createSim(outputFileName, false);
296 >
297 >  // fill Hmat
298 >
299 >  hmat(0, 0) = nx * latticeConstant;
300    hmat(0, 1) = 0.0;
301    hmat(0, 2) = 0.0;
302  
# Line 242 | Line 308 | int main(int argc, char *argv []) {
308    hmat(2, 1) = 0.0;
309    hmat(2, 2) = nz * latticeConstant;
310  
311 <  //set Hmat
246 <  oldInfo->getSnapshotManager()->getCurrentSnapshot()->setHmat(hmat);
311 >  // Set Hmat
312  
313 <  //place the molecules
313 >  newInfo->getSnapshotManager()->getCurrentSnapshot()->setHmat(hmat);
314  
315 <  curMolIndex = 0;
315 >  // place the molecules
316  
317 <  //get the orientation of the cell sites
253 <  //for the same type of molecule in same lattice, it will not change
254 <  latticeOrt = simpleLat->getLatticePointsOrt();
317 >  // Randomize a vector of ints:
318  
319 <
320 <  /* Randomize position vector */
321 <  std::random_shuffle(latticeSites.begin(), latticeSites.end());
319 >  vector<int> ids;
320 >  for (int i = 0; i < sites.size(); i++) ids.push_back(i);
321 >  std::random_shuffle(ids.begin(), ids.end());
322  
260  if (oldInfo != NULL)
261    delete oldInfo;
262
263  // We need to read in new siminfo object.    
264  // parse md file and set up the system
265
266  SimCreator newCreator;
267  SimInfo* newInfo = newCreator.createSim(outMdFileName, false);
268  
269  /* create Molocators */
270  locator = new MoLocator(newInfo->getMoleculeStamp(0), newInfo->getForceField());
271  
272  
273  
323    Molecule* mol;
275  SimInfo::MoleculeIterator mi;
276  mol = newInfo->beginMolecule(mi);
324    int l = 0;
325 <  for (mol = newInfo->beginMolecule(mi); mol != NULL; mol = newInfo->nextMolecule(mi)) {
326 <    locator->placeMol(latticeSites[l], latticeOrt[l], mol);
327 <    l++;
325 >  for (int i = 0; i < nComponents; i++){
326 >    locator = new MoLocator(newInfo->getMoleculeStamp(i),
327 >                            newInfo->getForceField());
328 >    for (int n = 0; n < nMol.at(i); n++) {
329 >      mol = newInfo->getMoleculeByGlobalIndex(l);
330 >      locator->placeMol(sites[ids[l]], orientations[ids[l]], mol);
331 >      l++;
332 >    }
333    }
334 +  
335 +  // Create DumpWriter and write out the coordinates
336  
337 <  //create dumpwriter and write out the coordinates
284 <  newInfo->setFinalConfigFileName(outMdFileName);
285 <  writer = new DumpWriter(newInfo);
337 >  writer = new DumpWriter(newInfo, outputFileName);
338  
339    if (writer == NULL) {
340 <    std::cerr << "error in creating DumpWriter" << std::endl;
341 <    exit(1);
340 >    sprintf(painCave.errMsg, "error in creating DumpWriter");
341 >    painCave.isFatal = 1;
342 >    simError();
343    }
344  
345 <  writer->writeEor();
346 <  std::cout << "new OOPSE MD file: " << outMdFileName
347 <            << " has been generated." << std::endl;
345 >  writer->writeDump();
346 >
347 >  // deleting the writer will put the closing at the end of the dump file.
348 >
349 >  delete writer;
350 >
351 >  sprintf(painCave.errMsg, "A new OOPSE MD file called \"%s\" has been "
352 >          "generated.\n", outputFileName.c_str());
353 >  painCave.isFatal = 0;
354 >  simError();
355    return 0;
356   }
357  
358 < void createMdFile(const std::string&oldMdFileName, const std::string&newMdFileName,
359 <                  int components,int* numMol) {
358 > void createMdFile(const std::string&oldMdFileName,
359 >                  const std::string&newMdFileName,
360 >                  std::vector<int> nMol) {
361    ifstream oldMdFile;
362    ofstream newMdFile;
363    const int MAXLEN = 65535;
364    char buffer[MAXLEN];
365    
366    //create new .md file based on old .md file
367 +
368    oldMdFile.open(oldMdFileName.c_str());
369    newMdFile.open(newMdFileName.c_str());
370    
# Line 313 | Line 375 | void createMdFile(const std::string&oldMdFileName, con
375      
376      //correct molecule number
377      if (strstr(buffer, "nMol") != NULL) {
378 <      if(i<components){
379 <        sprintf(buffer, "\tnMol = %i;", numMol[i]);                            
378 >      if(i<nMol.size()){
379 >        sprintf(buffer, "\tnMol = %i;", nMol.at(i));
380          newMdFile << buffer << std::endl;
381          i++;
382        }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines