ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libmdtools/SimSetup.cpp
(Generate patch)

Comparing trunk/OOPSE/libmdtools/SimSetup.cpp (file contents):
Revision 394 by gezelter, Mon Mar 24 21:55:34 2003 UTC vs.
Revision 656 by mmeineke, Tue Jul 29 16:32:37 2003 UTC

# Line 12 | Line 12 | SimSetup::SimSetup(){
12   #include "mpiSimulation.hpp"
13   #endif
14  
15 + // some defines for ensemble and Forcefield  cases
16 +
17 + #define NVE_ENS   0
18 + #define NVT_ENS   1
19 + #define NPTi_ENS  2
20 + #define NPTf_ENS  3
21 + #define NPTim_ENS 4
22 + #define NPTfm_ENS 5
23 +
24 +
25 + #define FF_DUFF 0
26 + #define FF_LJ   1
27 + #define FF_EAM  2
28 +
29   SimSetup::SimSetup(){
30 +  
31 +  isInfoArray = 0;
32 +  nInfo = 1;
33 +  
34    stamps = new MakeStamps();
35    globals = new Globals();
36    
37 +  
38   #ifdef IS_MPI
39    strcpy( checkPointMsg, "SimSetup creation successful" );
40    MPIcheckPoint();
# Line 27 | Line 46 | void SimSetup::parseFile( char* fileName ){
46    delete globals;
47   }
48  
49 + void SimSetup::setSimInfo( SimInfo* the_info, int theNinfo ) {
50 +    info = the_info;
51 +    nInfo = theNinfo;
52 +    isInfoArray = 1;
53 +  }
54 +
55 +
56   void SimSetup::parseFile( char* fileName ){
57  
58   #ifdef IS_MPI
# Line 64 | Line 90 | void SimSetup::createSim( void ){
90  
91   void SimSetup::createSim( void ){
92  
93 <  MakeStamps *the_stamps;
94 <  Globals* the_globals;
95 <  int i, j;
93 >  int i, j, k, globalAtomIndex;
94 >  
95 >  // gather all of the information from the Bass file
96 >  
97 >  gatherInfo();
98  
99 <  // get the stamps and globals;
72 <  the_stamps = stamps;
73 <  the_globals = globals;
99 >  // creation of complex system objects
100  
101 <  // set the easy ones first
76 <  simnfo->target_temp = the_globals->getTargetTemp();
77 <  simnfo->dt = the_globals->getDt();
78 <  simnfo->run_time = the_globals->getRunTime();
101 >  sysObjectsCreation();
102  
103 <  // get the ones we know are there, yet still may need some work.
104 <  n_components = the_globals->getNComponents();
105 <  strcpy( force_field, the_globals->getForceField() );
83 <  strcpy( ensemble, the_globals->getEnsemble() );
84 <  strcpy( simnfo->ensemble, ensemble );
103 >  // check on the post processing info
104 >  
105 >  finalInfoCheck();
106  
107 <  strcpy( simnfo->mixingRule, the_globals->getMixingRule() );
87 <  simnfo->usePBC = the_globals->getPBC();
88 <          
107 >  // initialize the system coordinates
108  
109 +  initSystemCoords();
110 +  
111  
112 <  if( !strcmp( force_field, "TraPPE" ) ) the_ff = new TraPPEFF();
92 <  else if( !strcmp( force_field, "DipoleTest" ) ) the_ff = new DipoleTestFF();
93 <  else if( !strcmp( force_field, "TraPPE_Ex" ) ) the_ff = new TraPPE_ExFF();
94 <  else if( !strcmp( force_field, "LJ" ) ) the_ff = new LJ_FF();
95 <  else{
96 <    sprintf( painCave.errMsg,
97 <             "SimSetup Error. Unrecognized force field -> %s\n",
98 <             force_field );
99 <    painCave.isFatal = 1;
100 <    simError();
101 <  }
112 >  // make the output filenames
113  
114 +  makeOutNames();
115 +  
116 +  // make the integrator
117 +  
118 +  makeIntegrator();
119 +  
120   #ifdef IS_MPI
121 <  strcpy( checkPointMsg, "ForceField creation successful" );
122 <  MPIcheckPoint();
106 < #endif // is_mpi
121 >  mpiSim->mpiRefresh();
122 > #endif
123  
124 <  
124 >  // initialize the Fortran
125  
126 <  // get the components and calculate the tot_nMol and indvidual n_mol
111 <  the_components = the_globals->getComponents();
112 <  components_nmol = new int[n_components];
113 <  comp_stamps = new MoleculeStamp*[n_components];
126 >  initFortran();
127  
115  if( !the_globals->haveNMol() ){
116    // we don't have the total number of molecules, so we assume it is
117    // given in each component
128  
119    tot_nmol = 0;
120    for( i=0; i<n_components; i++ ){
129  
130 <      if( !the_components[i]->haveNMol() ){
123 <        // we have a problem
124 <        sprintf( painCave.errMsg,
125 <                 "SimSetup Error. No global NMol or component NMol"
126 <                 " given. Cannot calculate the number of atoms.\n" );
127 <        painCave.isFatal = 1;
128 <        simError();
129 <      }
130 > }
131  
131      tot_nmol += the_components[i]->getNMol();
132      components_nmol[i] = the_components[i]->getNMol();
133    }
134  }
135  else{
136    sprintf( painCave.errMsg,
137             "SimSetup error.\n"
138             "\tSorry, the ability to specify total"
139             " nMols and then give molfractions in the components\n"
140             "\tis not currently supported."
141             " Please give nMol in the components.\n" );
142    painCave.isFatal = 1;
143    simError();
144    
145    
146    //     tot_nmol = the_globals->getNMol();
147    
148    //   //we have the total number of molecules, now we check for molfractions
149    //     for( i=0; i<n_components; i++ ){
150    
151    //       if( !the_components[i]->haveMolFraction() ){
152    
153    //  if( !the_components[i]->haveNMol() ){
154    //    //we have a problem
155    //    std::cerr << "SimSetup error. Neither molFraction nor "
156    //              << " nMol was given in component
157    
158  }
132  
133 < #ifdef IS_MPI
161 <  strcpy( checkPointMsg, "Have the number of components" );
162 <  MPIcheckPoint();
163 < #endif // is_mpi
133 > void SimSetup::makeMolecules( void ){
134  
135 <  // make an array of molecule stamps that match the components used.
136 <  // also extract the used stamps out into a separate linked list
135 >  int i, j, exI, exJ, tempEx, stampID, atomOffset, excludeOffset;
136 >  molInit molInfo;
137 >  DirectionalAtom* dAtom;
138 >  LinkedAssign* extras;
139 >  LinkedAssign* current_extra;
140 >  AtomStamp* currentAtom;
141 >  BondStamp* currentBond;
142 >  BendStamp* currentBend;
143 >  TorsionStamp* currentTorsion;
144  
145 <  simnfo->nComponents = n_components;
146 <  simnfo->componentsNmol = components_nmol;
147 <  simnfo->compStamps = comp_stamps;
148 <  simnfo->headStamp = new LinkedMolStamp();
145 >  bond_pair* theBonds;
146 >  bend_set* theBends;
147 >  torsion_set* theTorsions;
148 >
149    
150 <  char* id;
174 <  LinkedMolStamp* headStamp = simnfo->headStamp;
175 <  LinkedMolStamp* currentStamp = NULL;
176 <  for( i=0; i<n_components; i++ ){
150 >  //init the forceField paramters
151  
152 <    id = the_components[i]->getType();
153 <    comp_stamps[i] = NULL;
152 >  the_ff->readParams();
153 >
154 >  
155 >  // init the atoms
156 >
157 >  double ux, uy, uz, u, uSqr;
158 >  
159 >  atomOffset = 0;
160 >  excludeOffset = 0;
161 >  for(i=0; i<info->n_mol; i++){
162      
163 <    // check to make sure the component isn't already in the list
163 >    stampID = the_molecules[i].getStampID();
164  
165 <    comp_stamps[i] = headStamp->match( id );
166 <    if( comp_stamps[i] == NULL ){
165 >    molInfo.nAtoms    = comp_stamps[stampID]->getNAtoms();
166 >    molInfo.nBonds    = comp_stamps[stampID]->getNBonds();
167 >    molInfo.nBends    = comp_stamps[stampID]->getNBends();
168 >    molInfo.nTorsions = comp_stamps[stampID]->getNTorsions();
169 >    molInfo.nExcludes = molInfo.nBonds + molInfo.nBends + molInfo.nTorsions;
170 >
171 >    molInfo.myAtoms = &the_atoms[atomOffset];
172 >    molInfo.myExcludes = &the_excludes[excludeOffset];
173 >    molInfo.myBonds = new Bond*[molInfo.nBonds];
174 >    molInfo.myBends = new Bend*[molInfo.nBends];
175 >    molInfo.myTorsions = new Torsion*[molInfo.nTorsions];
176 >
177 >    theBonds = new bond_pair[molInfo.nBonds];
178 >    theBends = new bend_set[molInfo.nBends];
179 >    theTorsions = new torsion_set[molInfo.nTorsions];
180 >    
181 >    // make the Atoms
182 >    
183 >    for(j=0; j<molInfo.nAtoms; j++){
184        
185 <      // extract the component from the list;
186 <      
187 <      currentStamp = the_stamps->extractMolStamp( id );
188 <      if( currentStamp == NULL ){
189 <        sprintf( painCave.errMsg,
190 <                 "SimSetup error: Component \"%s\" was not found in the "
191 <                 "list of declared molecules\n",
192 <                 id );
193 <        painCave.isFatal = 1;
194 <        simError();
185 >      currentAtom = comp_stamps[stampID]->getAtom( j );
186 >      if( currentAtom->haveOrientation() ){
187 >        
188 >        dAtom = new DirectionalAtom(j + atomOffset);
189 >        info->n_oriented++;
190 >        molInfo.myAtoms[j] = dAtom;
191 >        
192 >        ux = currentAtom->getOrntX();
193 >        uy = currentAtom->getOrntY();
194 >        uz = currentAtom->getOrntZ();
195 >        
196 >        uSqr = (ux * ux) + (uy * uy) + (uz * uz);
197 >        
198 >        u = sqrt( uSqr );
199 >        ux = ux / u;
200 >        uy = uy / u;
201 >        uz = uz / u;
202 >        
203 >        dAtom->setSUx( ux );
204 >        dAtom->setSUy( uy );
205 >        dAtom->setSUz( uz );
206        }
207 <      
208 <      headStamp->add( currentStamp );
209 <      comp_stamps[i] = headStamp->match( id );
210 <    }
211 <  }
202 <
207 >      else{
208 >        molInfo.myAtoms[j] = new GeneralAtom(j + atomOffset);
209 >      }
210 >      molInfo.myAtoms[j]->setType( currentAtom->getType() );
211 >    
212   #ifdef IS_MPI
213 <  strcpy( checkPointMsg, "Component stamps successfully extracted\n" );
214 <  MPIcheckPoint();
213 >      
214 >      molInfo.myAtoms[j]->setGlobalIndex( globalIndex[j+atomOffset] );
215 >      
216   #endif // is_mpi
217 <  
217 >    }
218 >    
219 >    // make the bonds
220 >    for(j=0; j<molInfo.nBonds; j++){
221 >      
222 >      currentBond = comp_stamps[stampID]->getBond( j );
223 >      theBonds[j].a = currentBond->getA() + atomOffset;
224 >      theBonds[j].b = currentBond->getB() + atomOffset;
225  
226 +      exI = theBonds[j].a;
227 +      exJ = theBonds[j].b;
228  
229 +      // exclude_I must always be the smaller of the pair
230 +      if( exI > exJ ){
231 +        tempEx = exI;
232 +        exI = exJ;
233 +        exJ = tempEx;
234 +      }
235 + #ifdef IS_MPI
236 +      tempEx = exI;
237 +      exI = the_atoms[tempEx]->getGlobalIndex() + 1;
238 +      tempEx = exJ;
239 +      exJ = the_atoms[tempEx]->getGlobalIndex() + 1;
240 +      
241 +      the_excludes[j+excludeOffset]->setPair( exI, exJ );
242 + #else  // isn't MPI
243  
244 <  // caclulate the number of atoms, bonds, bends and torsions
244 >      the_excludes[j+excludeOffset]->setPair( (exI+1), (exJ+1) );
245 > #endif  //is_mpi
246 >    }
247 >    excludeOffset += molInfo.nBonds;
248  
249 <  tot_atoms = 0;
250 <  tot_bonds = 0;
251 <  tot_bends = 0;
252 <  tot_torsions = 0;
253 <  for( i=0; i<n_components; i++ ){
249 >    //make the bends
250 >    for(j=0; j<molInfo.nBends; j++){
251 >      
252 >      currentBend = comp_stamps[stampID]->getBend( j );
253 >      theBends[j].a = currentBend->getA() + atomOffset;
254 >      theBends[j].b = currentBend->getB() + atomOffset;
255 >      theBends[j].c = currentBend->getC() + atomOffset;
256 >          
257 >      if( currentBend->haveExtras() ){
258 >            
259 >        extras = currentBend->getExtras();
260 >        current_extra = extras;
261 >            
262 >        while( current_extra != NULL ){
263 >          if( !strcmp( current_extra->getlhs(), "ghostVectorSource" )){
264 >                
265 >            switch( current_extra->getType() ){
266 >              
267 >            case 0:
268 >              theBends[j].ghost =
269 >                current_extra->getInt() + atomOffset;
270 >              theBends[j].isGhost = 1;
271 >              break;
272 >                  
273 >            case 1:
274 >              theBends[j].ghost =
275 >                (int)current_extra->getDouble() + atomOffset;
276 >              theBends[j].isGhost = 1;
277 >              break;
278 >              
279 >            default:
280 >              sprintf( painCave.errMsg,
281 >                       "SimSetup Error: ghostVectorSource was neither a "
282 >                       "double nor an int.\n"
283 >                       "-->Bend[%d] in %s\n",
284 >                       j, comp_stamps[stampID]->getID() );
285 >              painCave.isFatal = 1;
286 >              simError();
287 >            }
288 >          }
289 >          
290 >          else{
291 >            
292 >            sprintf( painCave.errMsg,
293 >                     "SimSetup Error: unhandled bend assignment:\n"
294 >                     "    -->%s in Bend[%d] in %s\n",
295 >                     current_extra->getlhs(),
296 >                     j, comp_stamps[stampID]->getID() );
297 >            painCave.isFatal = 1;
298 >            simError();
299 >          }
300 >          
301 >          current_extra = current_extra->getNext();
302 >        }
303 >      }
304 >          
305 >      if( !theBends[j].isGhost ){
306 >            
307 >        exI = theBends[j].a;
308 >        exJ = theBends[j].c;
309 >      }
310 >      else{
311 >        
312 >        exI = theBends[j].a;
313 >        exJ = theBends[j].b;
314 >      }
315 >      
316 >      // exclude_I must always be the smaller of the pair
317 >      if( exI > exJ ){
318 >        tempEx = exI;
319 >        exI = exJ;
320 >        exJ = tempEx;
321 >      }
322 > #ifdef IS_MPI
323 >      tempEx = exI;
324 >      exI = the_atoms[tempEx]->getGlobalIndex() + 1;
325 >      tempEx = exJ;
326 >      exJ = the_atoms[tempEx]->getGlobalIndex() + 1;
327 >      
328 >      the_excludes[j+excludeOffset]->setPair( exI, exJ );
329 > #else  // isn't MPI
330 >      the_excludes[j+excludeOffset]->setPair( (exI+1), (exJ+1) );
331 > #endif  //is_mpi
332 >    }
333 >    excludeOffset += molInfo.nBends;
334 >
335 >    for(j=0; j<molInfo.nTorsions; j++){
336 >      
337 >      currentTorsion = comp_stamps[stampID]->getTorsion( j );
338 >      theTorsions[j].a = currentTorsion->getA() + atomOffset;
339 >      theTorsions[j].b = currentTorsion->getB() + atomOffset;
340 >      theTorsions[j].c = currentTorsion->getC() + atomOffset;
341 >      theTorsions[j].d = currentTorsion->getD() + atomOffset;
342 >      
343 >      exI = theTorsions[j].a;
344 >      exJ = theTorsions[j].d;
345 >
346 >      // exclude_I must always be the smaller of the pair
347 >      if( exI > exJ ){
348 >        tempEx = exI;
349 >        exI = exJ;
350 >        exJ = tempEx;
351 >      }
352 > #ifdef IS_MPI
353 >      tempEx = exI;
354 >      exI = the_atoms[tempEx]->getGlobalIndex() + 1;
355 >      tempEx = exJ;
356 >      exJ = the_atoms[tempEx]->getGlobalIndex() + 1;
357 >      
358 >      the_excludes[j+excludeOffset]->setPair( exI, exJ );
359 > #else  // isn't MPI
360 >      the_excludes[j+excludeOffset]->setPair( (exI+1), (exJ+1) );
361 > #endif  //is_mpi
362 >    }
363 >    excludeOffset += molInfo.nTorsions;
364 >
365      
366 <    tot_atoms +=    components_nmol[i] * comp_stamps[i]->getNAtoms();
220 <    tot_bonds +=    components_nmol[i] * comp_stamps[i]->getNBonds();
221 <    tot_bends +=    components_nmol[i] * comp_stamps[i]->getNBends();
222 <    tot_torsions += components_nmol[i] * comp_stamps[i]->getNTorsions();
223 <  }
366 >    // send the arrays off to the forceField for init.
367  
368 <  tot_SRI = tot_bonds + tot_bends + tot_torsions;
368 >    the_ff->initializeAtoms( molInfo.nAtoms, molInfo.myAtoms );
369 >    the_ff->initializeBonds( molInfo.nBonds, molInfo.myBonds, theBonds );
370 >    the_ff->initializeBends( molInfo.nBends, molInfo.myBends, theBends );
371 >    the_ff->initializeTorsions( molInfo.nTorsions, molInfo.myTorsions, theTorsions );
372  
227  simnfo->n_atoms = tot_atoms;
228  simnfo->n_bonds = tot_bonds;
229  simnfo->n_bends = tot_bends;
230  simnfo->n_torsions = tot_torsions;
231  simnfo->n_SRI = tot_SRI;
232  simnfo->n_mol = tot_nmol;
373  
374 <  
374 >    the_molecules[i].initialize( molInfo );
375 >
376 >
377 >    atomOffset += molInfo.nAtoms;
378 >    delete[] theBonds;
379 >    delete[] theBends;
380 >    delete[] theTorsions;
381 >  }
382 >
383   #ifdef IS_MPI
384 +  sprintf( checkPointMsg, "all molecules initialized succesfully" );
385 +  MPIcheckPoint();
386 + #endif // is_mpi
387  
388 <  // divide the molecules among processors here.
389 <  
390 <  mpiSim = new mpiSimulation( simnfo );
240 <  
241 <  
388 >  // clean up the forcefield
389 >  the_ff->calcRcut();
390 >  the_ff->cleanMe();
391  
392 <  globalIndex = mpiSim->divideLabor();
392 > }
393  
394 + void SimSetup::initFromBass( void ){
395  
396 +  int i, j, k;
397 +  int n_cells;
398 +  double cellx, celly, cellz;
399 +  double temp1, temp2, temp3;
400 +  int n_per_extra;
401 +  int n_extra;
402 +  int have_extra, done;
403  
404 <  // set up the local variables
405 <  
406 <  int localMol, allMol;
250 <  int local_atoms, local_bonds, local_bends, local_torsions, local_SRI;
251 <  
252 <  allMol = 0;
253 <  localMol = 0;
254 <  local_atoms = 0;
255 <  local_bonds = 0;
256 <  local_bends = 0;
257 <  local_torsions = 0;
258 <  for( i=0; i<n_components; i++ ){
404 >  temp1 = (double)tot_nmol / 4.0;
405 >  temp2 = pow( temp1, ( 1.0 / 3.0 ) );
406 >  temp3 = ceil( temp2 );
407  
408 <    for( j=0; j<components_nmol[i]; j++ ){
409 <      
410 <      if( mpiSim->getMyMolStart() <= allMol &&
411 <          allMol <= mpiSim->getMyMolEnd() ){
412 <        
413 <        local_atoms +=    comp_stamps[i]->getNAtoms();
414 <        local_bonds +=    comp_stamps[i]->getNBonds();
415 <        local_bends +=    comp_stamps[i]->getNBends();
416 <        local_torsions += comp_stamps[i]->getNTorsions();
417 <        localMol++;
418 <      }      
419 <      allMol++;
408 >  have_extra =0;
409 >  if( temp2 < temp3 ){ // we have a non-complete lattice
410 >    have_extra =1;
411 >
412 >    n_cells = (int)temp3 - 1;
413 >    cellx = info->boxL[0] / temp3;
414 >    celly = info->boxL[1] / temp3;
415 >    cellz = info->boxL[2] / temp3;
416 >    n_extra = tot_nmol - ( 4 * n_cells * n_cells * n_cells );
417 >    temp1 = ((double)n_extra) / ( pow( temp3, 3.0 ) - pow( n_cells, 3.0 ) );
418 >    n_per_extra = (int)ceil( temp1 );
419 >
420 >    if( n_per_extra > 4){
421 >      sprintf( painCave.errMsg,
422 >               "SimSetup error. There has been an error in constructing"
423 >               " the non-complete lattice.\n" );
424 >      painCave.isFatal = 1;
425 >      simError();
426      }
427    }
428 <  local_SRI = local_bonds + local_bends + local_torsions;
429 <  
430 <
431 <  simnfo->n_atoms = mpiSim->getMyNlocal();  
432 <  
279 <  if( local_atoms != simnfo->n_atoms ){
280 <    sprintf( painCave.errMsg,
281 <             "SimSetup error: mpiSim's localAtom (%d) and SimSetup's"
282 <             " localAtom (%d) are note equal.\n",
283 <             simnfo->n_atoms,
284 <             local_atoms );
285 <    painCave.isFatal = 1;
286 <    simError();
428 >  else{
429 >    n_cells = (int)temp3;
430 >    cellx = info->boxL[0] / temp3;
431 >    celly = info->boxL[1] / temp3;
432 >    cellz = info->boxL[2] / temp3;
433    }
434  
435 <  simnfo->n_bonds = local_bonds;
436 <  simnfo->n_bends = local_bends;
437 <  simnfo->n_torsions = local_torsions;
438 <  simnfo->n_SRI = local_SRI;
293 <  simnfo->n_mol = localMol;
435 >  current_mol = 0;
436 >  current_comp_mol = 0;
437 >  current_comp = 0;
438 >  current_atom_ndx = 0;
439  
440 <  strcpy( checkPointMsg, "Passed nlocal consistency check." );
441 <  MPIcheckPoint();
442 <  
298 <  
299 < #endif // is_mpi
300 <  
440 >  for( i=0; i < n_cells ; i++ ){
441 >    for( j=0; j < n_cells; j++ ){
442 >      for( k=0; k < n_cells; k++ ){
443  
444 <  // create the atom and short range interaction arrays
444 >        makeElement( i * cellx,
445 >                     j * celly,
446 >                     k * cellz );
447  
448 <  Atom::createArrays(simnfo->n_atoms);
449 <  the_atoms = new Atom*[simnfo->n_atoms];
450 <  the_molecules = new Molecule[simnfo->n_mol];
448 >        makeElement( i * cellx + 0.5 * cellx,
449 >                     j * celly + 0.5 * celly,
450 >                     k * cellz );
451  
452 +        makeElement( i * cellx,
453 +                     j * celly + 0.5 * celly,
454 +                     k * cellz + 0.5 * cellz );
455  
456 <  if( simnfo->n_SRI ){
457 <    the_sris = new SRI*[simnfo->n_SRI];
458 <    the_excludes = new int[2 * simnfo->n_SRI];
459 <    simnfo->globalExcludes = new int;
460 <    simnfo->n_exclude = tot_SRI;
456 >        makeElement( i * cellx + 0.5 * cellx,
457 >                     j * celly,
458 >                     k * cellz + 0.5 * cellz );
459 >      }
460 >    }
461    }
315  else{
316    
317    the_excludes = new int[2];
318    the_excludes[0] = 0;
319    the_excludes[1] = 0;
320    simnfo->globalExcludes = new int;
321    simnfo->globalExcludes[0] = 0;
462  
463 <    simnfo->n_exclude = 1;
463 >  if( have_extra ){
464 >    done = 0;
465 >
466 >    int start_ndx;
467 >    for( i=0; i < (n_cells+1) && !done; i++ ){
468 >      for( j=0; j < (n_cells+1) && !done; j++ ){
469 >
470 >        if( i < n_cells ){
471 >
472 >          if( j < n_cells ){
473 >            start_ndx = n_cells;
474 >          }
475 >          else start_ndx = 0;
476 >        }
477 >        else start_ndx = 0;
478 >
479 >        for( k=start_ndx; k < (n_cells+1) && !done; k++ ){
480 >
481 >          makeElement( i * cellx,
482 >                       j * celly,
483 >                       k * cellz );
484 >          done = ( current_mol >= tot_nmol );
485 >
486 >          if( !done && n_per_extra > 1 ){
487 >            makeElement( i * cellx + 0.5 * cellx,
488 >                         j * celly + 0.5 * celly,
489 >                         k * cellz );
490 >            done = ( current_mol >= tot_nmol );
491 >          }
492 >
493 >          if( !done && n_per_extra > 2){
494 >            makeElement( i * cellx,
495 >                         j * celly + 0.5 * celly,
496 >                         k * cellz + 0.5 * cellz );
497 >            done = ( current_mol >= tot_nmol );
498 >          }
499 >
500 >          if( !done && n_per_extra > 3){
501 >            makeElement( i * cellx + 0.5 * cellx,
502 >                         j * celly,
503 >                         k * cellz + 0.5 * cellz );
504 >            done = ( current_mol >= tot_nmol );
505 >          }
506 >        }
507 >      }
508 >    }
509    }
510  
326  // set the arrays into the SimInfo object
511  
512 <  simnfo->atoms = the_atoms;
513 <  simnfo->sr_interactions = the_sris;
514 <  simnfo->nGlobalExcludes = 0;
515 <  simnfo->excludes = the_excludes;
512 >  for( i=0; i<info->n_atoms; i++ ){
513 >    info->atoms[i]->set_vx( 0.0 );
514 >    info->atoms[i]->set_vy( 0.0 );
515 >    info->atoms[i]->set_vz( 0.0 );
516 >  }
517 > }
518  
519 + void SimSetup::makeElement( double x, double y, double z ){
520  
521 <  // get some of the tricky things that may still be in the globals
521 >  int k;
522 >  AtomStamp* current_atom;
523 >  DirectionalAtom* dAtom;
524 >  double rotMat[3][3];
525  
526 +  for( k=0; k<comp_stamps[current_comp]->getNAtoms(); k++ ){
527 +
528 +    current_atom = comp_stamps[current_comp]->getAtom( k );
529 +    if( !current_atom->havePosition() ){
530 +      sprintf( painCave.errMsg,
531 +               "SimSetup:initFromBass error.\n"
532 +               "\tComponent %s, atom %s does not have a position specified.\n"
533 +               "\tThe initialization routine is unable to give a start"
534 +               " position.\n",
535 +               comp_stamps[current_comp]->getID(),
536 +               current_atom->getType() );
537 +      painCave.isFatal = 1;
538 +      simError();
539 +    }
540 +
541 +    the_atoms[current_atom_ndx]->setX( x + current_atom->getPosX() );
542 +    the_atoms[current_atom_ndx]->setY( y + current_atom->getPosY() );
543 +    the_atoms[current_atom_ndx]->setZ( z + current_atom->getPosZ() );
544 +
545 +    if( the_atoms[current_atom_ndx]->isDirectional() ){
546 +
547 +      dAtom = (DirectionalAtom *)the_atoms[current_atom_ndx];
548 +
549 +      rotMat[0][0] = 1.0;
550 +      rotMat[0][1] = 0.0;
551 +      rotMat[0][2] = 0.0;
552 +
553 +      rotMat[1][0] = 0.0;
554 +      rotMat[1][1] = 1.0;
555 +      rotMat[1][2] = 0.0;
556 +
557 +      rotMat[2][0] = 0.0;
558 +      rotMat[2][1] = 0.0;
559 +      rotMat[2][2] = 1.0;
560 +
561 +      dAtom->setA( rotMat );
562 +    }
563 +
564 +    current_atom_ndx++;
565 +  }
566 +
567 +  current_mol++;
568 +  current_comp_mol++;
569 +
570 +  if( current_comp_mol >= components_nmol[current_comp] ){
571 +
572 +    current_comp_mol = 0;
573 +    current_comp++;
574 +  }
575 + }
576 +
577 +
578 + void SimSetup::gatherInfo( void ){
579 +  int i,j,k;
580 +
581 +  ensembleCase = -1;
582 +  ffCase = -1;
583 +
584 +  // get the stamps and globals;
585 +  stamps = stamps;
586 +  globals = globals;
587 +
588 +  // set the easy ones first
589 +  info->target_temp = globals->getTargetTemp();
590 +  info->dt = globals->getDt();
591 +  info->run_time = globals->getRunTime();
592 +  n_components = globals->getNComponents();
593 +
594 +
595 +  // get the forceField
596 +
597 +  strcpy( force_field, globals->getForceField() );
598 +
599 +  if( !strcasecmp( force_field, "DUFF" )) ffCase = FF_DUFF;
600 +  else if( !strcasecmp( force_field, "LJ" )) ffCase = FF_LJ;
601 +  else if( !strcasecmp( force_field, "EAM" )) ffCase = FF_EAM;
602 +  else{
603 +    sprintf( painCave.errMsg,
604 +             "SimSetup Error. Unrecognized force field -> %s\n",
605 +             force_field );
606 +    painCave.isFatal = 1;
607 +    simError();
608 +  }
609 +
610 +  // get the ensemble
611 +
612 +  strcpy( ensemble, globals->getEnsemble() );
613 +
614 +  if( !strcasecmp( ensemble, "NVE" ))      ensembleCase = NVE_ENS;
615 +  else if( !strcasecmp( ensemble, "NVT" )) ensembleCase = NVT_ENS;
616 +  else if( !strcasecmp( ensemble, "NPTi" ) || !strcasecmp( ensemble, "NPT") )
617 +    ensembleCase = NPTi_ENS;
618 +  else if( !strcasecmp( ensemble, "NPTf" )) ensembleCase = NPTf_ENS;
619 +  else if( !strcasecmp( ensemble, "NPTim" )) ensembleCase = NPTim_ENS;
620 +  else if( !strcasecmp( ensemble, "NPTfm" )) ensembleCase = NPTfm_ENS;
621 +  else{
622 +    sprintf( painCave.errMsg,
623 +             "SimSetup Warning. Unrecognized Ensemble -> %s, "
624 +             "reverting to NVE for this simulation.\n",
625 +             ensemble );
626 +    painCave.isFatal = 0;
627 +    simError();
628 +    strcpy( ensemble, "NVE" );
629 +    ensembleCase = NVE_ENS;
630 +  }  
631 +  strcpy( info->ensemble, ensemble );
632 +
633 +  // get the mixing rule
634 +
635 +  strcpy( info->mixingRule, globals->getMixingRule() );
636 +  info->usePBC = globals->getPBC();
637 +        
638    
639 <  if( the_globals->haveBox() ){
640 <    simnfo->box_x = the_globals->getBox();
641 <    simnfo->box_y = the_globals->getBox();
642 <    simnfo->box_z = the_globals->getBox();
639 >  // get the components and calculate the tot_nMol and indvidual n_mol
640 >
641 >  the_components = globals->getComponents();
642 >  components_nmol = new int[n_components];
643 >
644 >
645 >  if( !globals->haveNMol() ){
646 >    // we don't have the total number of molecules, so we assume it is
647 >    // given in each component
648 >
649 >    tot_nmol = 0;
650 >    for( i=0; i<n_components; i++ ){
651 >
652 >      if( !the_components[i]->haveNMol() ){
653 >        // we have a problem
654 >        sprintf( painCave.errMsg,
655 >                 "SimSetup Error. No global NMol or component NMol"
656 >                 " given. Cannot calculate the number of atoms.\n" );
657 >        painCave.isFatal = 1;
658 >        simError();
659 >      }
660 >
661 >      tot_nmol += the_components[i]->getNMol();
662 >      components_nmol[i] = the_components[i]->getNMol();
663 >    }
664    }
665 <  else if( the_globals->haveDensity() ){
665 >  else{
666 >    sprintf( painCave.errMsg,
667 >             "SimSetup error.\n"
668 >             "\tSorry, the ability to specify total"
669 >             " nMols and then give molfractions in the components\n"
670 >             "\tis not currently supported."
671 >             " Please give nMol in the components.\n" );
672 >    painCave.isFatal = 1;
673 >    simError();
674 >  }
675  
676 +  // set the status, sample, and thermal kick times
677 +  
678 +  if( globals->haveSampleTime() ){
679 +    info->sampleTime = globals->getSampleTime();
680 +    info->statusTime = info->sampleTime;
681 +    info->thermalTime = info->sampleTime;
682 +  }
683 +  else{
684 +    info->sampleTime = globals->getRunTime();
685 +    info->statusTime = info->sampleTime;
686 +    info->thermalTime = info->sampleTime;
687 +  }
688 +
689 +  if( globals->haveStatusTime() ){
690 +    info->statusTime = globals->getStatusTime();
691 +  }
692 +
693 +  if( globals->haveThermalTime() ){
694 +    info->thermalTime = globals->getThermalTime();
695 +  }
696 +
697 +  // check for the temperature set flag
698 +
699 +  if( globals->haveTempSet() ) info->setTemp = globals->getTempSet();
700 +
701 +  // get some of the tricky things that may still be in the globals
702 +
703 +  double boxVector[3];
704 +  if( globals->haveBox() ){
705 +    boxVector[0] = globals->getBox();
706 +    boxVector[1] = globals->getBox();
707 +    boxVector[2] = globals->getBox();
708 +    
709 +    info->setBox( boxVector );
710 +  }
711 +  else if( globals->haveDensity() ){
712 +
713      double vol;
714 <    vol = (double)tot_nmol / the_globals->getDensity();
715 <    simnfo->box_x = pow( vol, ( 1.0 / 3.0 ) );
716 <    simnfo->box_y = simnfo->box_x;
717 <    simnfo->box_z = simnfo->box_x;
714 >    vol = (double)tot_nmol / globals->getDensity();
715 >     boxVector[0] = pow( vol, ( 1.0 / 3.0 ) );
716 >     boxVector[1] = boxVector[0];
717 >     boxVector[2] = boxVector[0];
718 >
719 >    info->setBox( boxVector );
720    }
721    else{
722 <    if( !the_globals->haveBoxX() ){
722 >    if( !globals->haveBoxX() ){
723        sprintf( painCave.errMsg,
724                 "SimSetup error, no periodic BoxX size given.\n" );
725        painCave.isFatal = 1;
726        simError();
727      }
728 <    simnfo->box_x = the_globals->getBoxX();
728 >    boxVector[0] = globals->getBoxX();
729  
730 <    if( !the_globals->haveBoxY() ){
730 >    if( !globals->haveBoxY() ){
731        sprintf( painCave.errMsg,
732                 "SimSetup error, no periodic BoxY size given.\n" );
733        painCave.isFatal = 1;
734        simError();
735      }
736 <    simnfo->box_y = the_globals->getBoxY();
736 >    boxVector[1] = globals->getBoxY();
737  
738 <    if( !the_globals->haveBoxZ() ){
738 >    if( !globals->haveBoxZ() ){
739        sprintf( painCave.errMsg,
740                 "SimSetup error, no periodic BoxZ size given.\n" );
741        painCave.isFatal = 1;
742        simError();
743      }
744 <    simnfo->box_z = the_globals->getBoxZ();
744 >    boxVector[2] = globals->getBoxZ();
745 >
746 >    info->setBox( boxVector );
747    }
748  
749 +
750 +    
751   #ifdef IS_MPI
752 <  strcpy( checkPointMsg, "Box size set up" );
752 >  strcpy( checkPointMsg, "Succesfully gathered all information from Bass\n" );
753    MPIcheckPoint();
754   #endif // is_mpi
755  
756 + }
757  
382  // initialize the arrays
758  
759 <  the_ff->setSimInfo( simnfo );
759 > void SimSetup::finalInfoCheck( void ){
760 >  int index;
761 >  int usesDipoles;
762 >  
763  
764 <  makeAtoms();
387 <  simnfo->identArray = new int[simnfo->n_atoms];
388 <  for(i=0; i<simnfo->n_atoms; i++){
389 <    simnfo->identArray[i] = the_atoms[i]->getIdent();
390 <  }
764 >  // check electrostatic parameters
765    
766 <  if( tot_bonds ){
767 <    makeBonds();
766 >  index = 0;
767 >  usesDipoles = 0;
768 >  while( (index < info->n_atoms) && !usesDipoles ){
769 >    usesDipoles = ((info->atoms)[index])->hasDipole();
770 >    index++;
771    }
772 +  
773 + #ifdef IS_MPI
774 +  int myUse = usesDipoles;
775 +  MPI_Allreduce( &myUse, &usesDipoles, 1, MPI_INT, MPI_LOR, MPI_COMM_WORLD );
776 + #endif //is_mpi
777  
778 <  if( tot_bends ){
397 <    makeBends();
398 <  }
778 >  double theEcr, theEst;
779  
780 <  if( tot_torsions ){
781 <    makeTorsions();
782 <  }
783 <
404 <
405 <  if (the_globals->getUseRF() ) {
406 <    simnfo->useReactionField = 1;
407 <  
408 <    if( !the_globals->haveECR() ){
780 >  if (globals->getUseRF() ) {
781 >    info->useReactionField = 1;
782 >    
783 >    if( !globals->haveECR() ){
784        sprintf( painCave.errMsg,
785                 "SimSetup Warning: using default value of 1/2 the smallest "
786                 "box length for the electrostaticCutoffRadius.\n"
# Line 413 | Line 788 | void SimSetup::createSim( void ){
788        painCave.isFatal = 0;
789        simError();
790        double smallest;
791 <      smallest = simnfo->box_x;
792 <      if (simnfo->box_y <= smallest) smallest = simnfo->box_y;
793 <      if (simnfo->box_z <= smallest) smallest = simnfo->box_z;
794 <      simnfo->ecr = 0.5 * smallest;
791 >      smallest = info->boxL[0];
792 >      if (info->boxL[1] <= smallest) smallest = info->boxL[1];
793 >      if (info->boxL[2] <= smallest) smallest = info->boxL[2];
794 >      theEcr = 0.5 * smallest;
795      } else {
796 <      simnfo->ecr        = the_globals->getECR();
796 >      theEcr = globals->getECR();
797      }
798  
799 <    if( !the_globals->haveEST() ){
799 >    if( !globals->haveEST() ){
800        sprintf( painCave.errMsg,
801                 "SimSetup Warning: using default value of 0.05 * the "
802                 "electrostaticCutoffRadius for the electrostaticSkinThickness\n"
803                 );
804        painCave.isFatal = 0;
805        simError();
806 <      simnfo->est = 0.05 * simnfo->ecr;
806 >      theEst = 0.05 * theEcr;
807      } else {
808 <      simnfo->est        = the_globals->getEST();
808 >      theEst= globals->getEST();
809      }
810 +
811 +    info->setEcr( theEcr, theEst );
812      
813 <    if(!the_globals->haveDielectric() ){
813 >    if(!globals->haveDielectric() ){
814        sprintf( painCave.errMsg,
815                 "SimSetup Error: You are trying to use Reaction Field without"
816                 "setting a dielectric constant!\n"
# Line 441 | Line 818 | void SimSetup::createSim( void ){
818        painCave.isFatal = 1;
819        simError();
820      }
821 <    simnfo->dielectric = the_globals->getDielectric();  
822 <  } else {
823 <    if (simnfo->n_dipoles) {
824 <      
825 <      if( !the_globals->haveECR() ){
826 <        sprintf( painCave.errMsg,
827 <                 "SimSetup Warning: using default value of 1/2 the smallest"
828 <                 "box length for the electrostaticCutoffRadius.\n"
829 <                 "I hope you have a very fast processor!\n");
830 <        painCave.isFatal = 0;
831 <        simError();
832 <        double smallest;
833 <        smallest = simnfo->box_x;
834 <        if (simnfo->box_y <= smallest) smallest = simnfo->box_y;
835 <        if (simnfo->box_z <= smallest) smallest = simnfo->box_z;
836 <        simnfo->ecr = 0.5 * smallest;
821 >    info->dielectric = globals->getDielectric();  
822 >  }
823 >  else {
824 >    if (usesDipoles) {
825 >      
826 >      if( !globals->haveECR() ){
827 >        sprintf( painCave.errMsg,
828 >                 "SimSetup Warning: using default value of 1/2 the smallest "
829 >                 "box length for the electrostaticCutoffRadius.\n"
830 >                 "I hope you have a very fast processor!\n");
831 >        painCave.isFatal = 0;
832 >        simError();
833 >        double smallest;
834 >        smallest = info->boxL[0];
835 >        if (info->boxL[1] <= smallest) smallest = info->boxL[1];
836 >        if (info->boxL[2] <= smallest) smallest = info->boxL[2];
837 >        theEcr = 0.5 * smallest;
838        } else {
839 <        simnfo->ecr        = the_globals->getECR();
839 >        theEcr = globals->getECR();
840        }
841        
842 <      if( !the_globals->haveEST() ){
843 <        sprintf( painCave.errMsg,
844 <                 "SimSetup Warning: using default value of 5% of the"
845 <                 "electrostaticCutoffRadius for the "
846 <                 "electrostaticSkinThickness\n"
847 <                 );
848 <        painCave.isFatal = 0;
849 <        simError();
850 <        simnfo->est = 0.05 * simnfo->ecr;
842 >      if( !globals->haveEST() ){
843 >        sprintf( painCave.errMsg,
844 >                 "SimSetup Warning: using default value of 0.05 * the "
845 >                 "electrostaticCutoffRadius for the "
846 >                 "electrostaticSkinThickness\n"
847 >                 );
848 >        painCave.isFatal = 0;
849 >        simError();
850 >        theEst = 0.05 * theEcr;
851        } else {
852 <        simnfo->est        = the_globals->getEST();
852 >        theEst= globals->getEST();
853        }
854 +
855 +      info->setEcr( theEcr, theEst );
856      }
857    }  
858  
859   #ifdef IS_MPI
860 <  strcpy( checkPointMsg, "electrostatic parameters check out" );
860 >  strcpy( checkPointMsg, "post processing checks out" );
861    MPIcheckPoint();
862   #endif // is_mpi
863  
864 < if( the_globals->haveInitialConfig() ){
864 > }
865 >
866 > void SimSetup::initSystemCoords( void ){
867 >
868 > if( globals->haveInitialConfig() ){
869  
870       InitializeFromFile* fileInit;
871   #ifdef IS_MPI // is_mpi
872       if( worldRank == 0 ){
873   #endif //is_mpi
874 <   fileInit = new InitializeFromFile( the_globals->getInitialConfig() );
874 >   fileInit = new InitializeFromFile( globals->getInitialConfig() );
875   #ifdef IS_MPI
876       }else fileInit = new InitializeFromFile( NULL );
877   #endif
878 <   fileInit->read_xyz( simnfo ); // default velocities on
878 >   fileInit->readInit( info ); // default velocities on
879  
880     delete fileInit;
881   }
# Line 519 | Line 903 | void SimSetup::createSim( void ){
903    MPIcheckPoint();
904   #endif // is_mpi
905  
906 + }
907  
523  
524
525  
908  
909 <  
909 > void SimSetup::makeOutNames( void ){
910 >
911   #ifdef IS_MPI
912    if( worldRank == 0 ){
913   #endif // is_mpi
914      
915 <    if( the_globals->haveFinalConfig() ){
916 <      strcpy( simnfo->finalName, the_globals->getFinalConfig() );
915 >    if( globals->haveFinalConfig() ){
916 >      strcpy( info->finalName, globals->getFinalConfig() );
917      }
918      else{
919 <      strcpy( simnfo->finalName, inFileName );
919 >      strcpy( info->finalName, inFileName );
920        char* endTest;
921 <      int nameLength = strlen( simnfo->finalName );
922 <      endTest = &(simnfo->finalName[nameLength - 5]);
921 >      int nameLength = strlen( info->finalName );
922 >      endTest = &(info->finalName[nameLength - 5]);
923        if( !strcmp( endTest, ".bass" ) ){
924          strcpy( endTest, ".eor" );
925        }
# Line 544 | Line 927 | void SimSetup::createSim( void ){
927          strcpy( endTest, ".eor" );
928        }
929        else{
930 <        endTest = &(simnfo->finalName[nameLength - 4]);
930 >        endTest = &(info->finalName[nameLength - 4]);
931          if( !strcmp( endTest, ".bss" ) ){
932            strcpy( endTest, ".eor" );
933          }
# Line 552 | Line 935 | void SimSetup::createSim( void ){
935            strcpy( endTest, ".eor" );
936          }
937          else{
938 <          strcat( simnfo->finalName, ".eor" );
938 >          strcat( info->finalName, ".eor" );
939          }
940        }
941      }
942      
943      // make the sample and status out names
944      
945 <    strcpy( simnfo->sampleName, inFileName );
945 >    strcpy( info->sampleName, inFileName );
946      char* endTest;
947 <    int nameLength = strlen( simnfo->sampleName );
948 <    endTest = &(simnfo->sampleName[nameLength - 5]);
947 >    int nameLength = strlen( info->sampleName );
948 >    endTest = &(info->sampleName[nameLength - 5]);
949      if( !strcmp( endTest, ".bass" ) ){
950        strcpy( endTest, ".dump" );
951      }
# Line 570 | Line 953 | void SimSetup::createSim( void ){
953        strcpy( endTest, ".dump" );
954      }
955      else{
956 <      endTest = &(simnfo->sampleName[nameLength - 4]);
956 >      endTest = &(info->sampleName[nameLength - 4]);
957        if( !strcmp( endTest, ".bss" ) ){
958          strcpy( endTest, ".dump" );
959        }
# Line 578 | Line 961 | void SimSetup::createSim( void ){
961          strcpy( endTest, ".dump" );
962        }
963        else{
964 <        strcat( simnfo->sampleName, ".dump" );
964 >        strcat( info->sampleName, ".dump" );
965        }
966      }
967      
968 <    strcpy( simnfo->statusName, inFileName );
969 <    nameLength = strlen( simnfo->statusName );
970 <    endTest = &(simnfo->statusName[nameLength - 5]);
968 >    strcpy( info->statusName, inFileName );
969 >    nameLength = strlen( info->statusName );
970 >    endTest = &(info->statusName[nameLength - 5]);
971      if( !strcmp( endTest, ".bass" ) ){
972        strcpy( endTest, ".stat" );
973      }
# Line 592 | Line 975 | void SimSetup::createSim( void ){
975        strcpy( endTest, ".stat" );
976      }
977      else{
978 <      endTest = &(simnfo->statusName[nameLength - 4]);
978 >      endTest = &(info->statusName[nameLength - 4]);
979        if( !strcmp( endTest, ".bss" ) ){
980          strcpy( endTest, ".stat" );
981        }
# Line 600 | Line 983 | void SimSetup::createSim( void ){
983          strcpy( endTest, ".stat" );
984        }
985        else{
986 <        strcat( simnfo->statusName, ".stat" );
986 >        strcat( info->statusName, ".stat" );
987        }
988      }
989      
990   #ifdef IS_MPI
991    }
992   #endif // is_mpi
993 <  
994 <  // set the status, sample, and themal kick times
993 >
994 > }
995 >
996 >
997 > void SimSetup::sysObjectsCreation( void ){
998 >
999 >  int i;
1000 >
1001 >  // create the forceField
1002 >
1003 >  createFF();
1004 >
1005 >  // extract componentList
1006 >
1007 >  compList();
1008 >
1009 >  // calc the number of atoms, bond, bends, and torsions
1010 >
1011 >  calcSysValues();
1012 >
1013 > #ifdef IS_MPI
1014 >  // divide the molecules among the processors
1015    
1016 <  if( the_globals->haveSampleTime() ){
1017 <    simnfo->sampleTime = the_globals->getSampleTime();
1018 <    simnfo->statusTime = simnfo->sampleTime;
1019 <    simnfo->thermalTime = simnfo->sampleTime;
1020 <  }
1021 <  else{
619 <    simnfo->sampleTime = the_globals->getRunTime();
620 <    simnfo->statusTime = simnfo->sampleTime;
621 <    simnfo->thermalTime = simnfo->sampleTime;
622 <  }
1016 >  mpiMolDivide();
1017 > #endif //is_mpi
1018 >  
1019 >  // create the atom and SRI arrays. Also initialize Molecule Stamp ID's
1020 >  
1021 >  makeSysArrays();
1022  
1023 <  if( the_globals->haveStatusTime() ){
1024 <    simnfo->statusTime = the_globals->getStatusTime();
1023 >  // make and initialize the molecules (all but atomic coordinates)
1024 >  
1025 >  makeMolecules();
1026 >  info->identArray = new int[info->n_atoms];
1027 >  for(i=0; i<info->n_atoms; i++){
1028 >    info->identArray[i] = the_atoms[i]->getIdent();
1029    }
1030 +  
1031  
628  if( the_globals->haveThermalTime() ){
629    simnfo->thermalTime = the_globals->getThermalTime();
630  }
1032  
1033 <  // check for the temperature set flag
1033 > }
1034  
634  if( the_globals->haveTempSet() ) simnfo->setTemp = the_globals->getTempSet();
1035  
1036 + void SimSetup::createFF( void ){
1037  
1038 < //   // make the longe range forces and the integrator
1038 >  switch( ffCase ){
1039  
1040 < //   new AllLong( simnfo );
1040 >  case FF_DUFF:
1041 >    the_ff = new DUFF();
1042 >    break;
1043  
1044 <  if( !strcmp( force_field, "TraPPE" ) ) new Verlet( *simnfo, the_ff );
1045 <  if( !strcmp( force_field, "DipoleTest" ) ) new Symplectic( simnfo, the_ff );
1046 <  if( !strcmp( force_field, "TraPPE_Ex" ) ) new Symplectic( simnfo, the_ff );
644 <  if( !strcmp( force_field, "LJ" ) ) new Verlet( *simnfo, the_ff );
1044 >  case FF_LJ:
1045 >    the_ff = new LJFF();
1046 >    break;
1047  
1048 +  case FF_EAM:
1049 +    the_ff = new EAM_FF();
1050 +    break;
1051  
1052 <
648 <  // initialize the Fortran
649 <  
650 <  simnfo->refreshSim();
651 <  
652 <  if( !strcmp( simnfo->mixingRule, "standard") ){
653 <    the_ff->initForceField( LB_MIXING_RULE );
654 <  }
655 <  else if( !strcmp( simnfo->mixingRule, "explicit") ){
656 <    the_ff->initForceField( EXPLICIT_MIXING_RULE );
657 <  }
658 <  else{
1052 >  default:
1053      sprintf( painCave.errMsg,
1054 <             "SimSetup Error: unknown mixing rule -> \"%s\"\n",
661 <             simnfo->mixingRule );
1054 >             "SimSetup Error. Unrecognized force field in case statement.\n");
1055      painCave.isFatal = 1;
1056      simError();
1057    }
1058  
666
1059   #ifdef IS_MPI
1060 <  strcpy( checkPointMsg,
669 <          "Successfully intialized the mixingRule for Fortran." );
1060 >  strcpy( checkPointMsg, "ForceField creation successful" );
1061    MPIcheckPoint();
1062   #endif // is_mpi
1063 +
1064   }
1065  
674 void SimSetup::makeAtoms( void ){
1066  
1067 <  int i, j, k, index;
677 <  double ux, uy, uz, uSqr, u;
678 <  AtomStamp* current_atom;
1067 > void SimSetup::compList( void ){
1068  
1069 <  DirectionalAtom* dAtom;
681 <  int molIndex, molStart, molEnd, nMemb, lMolIndex;
1069 >  int i;
1070  
1071 <  lMolIndex = 0;
684 <  molIndex = 0;
685 <  index = 0;
686 <  for( i=0; i<n_components; i++ ){
1071 >  comp_stamps = new MoleculeStamp*[n_components];
1072  
1073 <    for( j=0; j<components_nmol[i]; j++ ){
1073 >  // make an array of molecule stamps that match the components used.
1074 >  // also extract the used stamps out into a separate linked list
1075  
1076 < #ifdef IS_MPI
1077 <      if( mpiSim->getMyMolStart() <= molIndex &&
1078 <          molIndex <= mpiSim->getMyMolEnd() ){
1079 < #endif // is_mpi        
1076 >  info->nComponents = n_components;
1077 >  info->componentsNmol = components_nmol;
1078 >  info->compStamps = comp_stamps;
1079 >  info->headStamp = new LinkedMolStamp();
1080 >  
1081 >  char* id;
1082 >  LinkedMolStamp* headStamp = info->headStamp;
1083 >  LinkedMolStamp* currentStamp = NULL;
1084 >  for( i=0; i<n_components; i++ ){
1085  
1086 <        molStart = index;
1087 <        nMemb = comp_stamps[i]->getNAtoms();
1088 <        for( k=0; k<comp_stamps[i]->getNAtoms(); k++ ){
1089 <          
699 <          current_atom = comp_stamps[i]->getAtom( k );
700 <          if( current_atom->haveOrientation() ){
701 <            
702 <            dAtom = new DirectionalAtom(index);
703 <            simnfo->n_oriented++;
704 <            the_atoms[index] = dAtom;
705 <            
706 <            ux = current_atom->getOrntX();
707 <            uy = current_atom->getOrntY();
708 <            uz = current_atom->getOrntZ();
709 <            
710 <            uSqr = (ux * ux) + (uy * uy) + (uz * uz);
711 <            
712 <            u = sqrt( uSqr );
713 <            ux = ux / u;
714 <            uy = uy / u;
715 <            uz = uz / u;
716 <            
717 <            dAtom->setSUx( ux );
718 <            dAtom->setSUy( uy );
719 <            dAtom->setSUz( uz );
720 <          }
721 <          else{
722 <            the_atoms[index] = new GeneralAtom(index);
723 <          }
724 <          the_atoms[index]->setType( current_atom->getType() );
725 <          the_atoms[index]->setIndex( index );
726 <          
727 <          // increment the index and repeat;
728 <          index++;
729 <        }
730 <        
731 <        molEnd = index -1;
732 <        the_molecules[lMolIndex].setNMembers( nMemb );
733 <        the_molecules[lMolIndex].setStartAtom( molStart );
734 <        the_molecules[lMolIndex].setEndAtom( molEnd );
735 <        the_molecules[lMolIndex].setStampID( i );
736 <        lMolIndex++;
1086 >    id = the_components[i]->getType();
1087 >    comp_stamps[i] = NULL;
1088 >    
1089 >    // check to make sure the component isn't already in the list
1090  
1091 < #ifdef IS_MPI
1091 >    comp_stamps[i] = headStamp->match( id );
1092 >    if( comp_stamps[i] == NULL ){
1093 >      
1094 >      // extract the component from the list;
1095 >      
1096 >      currentStamp = stamps->extractMolStamp( id );
1097 >      if( currentStamp == NULL ){
1098 >        sprintf( painCave.errMsg,
1099 >                 "SimSetup error: Component \"%s\" was not found in the "
1100 >                 "list of declared molecules\n",
1101 >                 id );
1102 >        painCave.isFatal = 1;
1103 >        simError();
1104        }
740 #endif //is_mpi
1105        
1106 <      molIndex++;
1106 >      headStamp->add( currentStamp );
1107 >      comp_stamps[i] = headStamp->match( id );
1108      }
1109    }
1110  
1111   #ifdef IS_MPI
1112 <    for( i=0; i<mpiSim->getMyNlocal(); i++ ) the_atoms[i]->setGlobalIndex( globalIndex[i] );
1113 <    
1114 <    delete[] globalIndex;
1112 >  strcpy( checkPointMsg, "Component stamps successfully extracted\n" );
1113 >  MPIcheckPoint();
1114 > #endif // is_mpi
1115  
1116 <    mpiSim->mpiRefresh();
752 < #endif //IS_MPI
753 <          
754 <  the_ff->initializeAtoms();
1116 >
1117   }
1118  
1119 < void SimSetup::makeBonds( void ){
1119 > void SimSetup::calcSysValues( void ){
1120 >  int i, j, k;
1121  
759  int i, j, k, index, offset, molIndex, exI, exJ, tempEx;
760  bond_pair* the_bonds;
761  BondStamp* current_bond;
1122  
1123 <  the_bonds = new bond_pair[tot_bonds];
1124 <  index = 0;
1125 <  offset = 0;
1126 <  molIndex = 0;
767 <
1123 >  tot_atoms = 0;
1124 >  tot_bonds = 0;
1125 >  tot_bends = 0;
1126 >  tot_torsions = 0;
1127    for( i=0; i<n_components; i++ ){
1128 +    
1129 +    tot_atoms +=    components_nmol[i] * comp_stamps[i]->getNAtoms();
1130 +    tot_bonds +=    components_nmol[i] * comp_stamps[i]->getNBonds();
1131 +    tot_bends +=    components_nmol[i] * comp_stamps[i]->getNBends();
1132 +    tot_torsions += components_nmol[i] * comp_stamps[i]->getNTorsions();
1133 +  }
1134  
1135 <    for( j=0; j<components_nmol[i]; j++ ){
1135 >  tot_SRI = tot_bonds + tot_bends + tot_torsions;
1136  
1137 < #ifdef IS_MPI
1138 <      if( mpiSim->getMyMolStart() <= molIndex &&
1139 <          molIndex <= mpiSim->getMyMolEnd() ){
1140 < #endif // is_mpi        
1141 <        
1142 <        for( k=0; k<comp_stamps[i]->getNBonds(); k++ ){
1143 <          
1144 <          current_bond = comp_stamps[i]->getBond( k );
1145 <          the_bonds[index].a = current_bond->getA() + offset;
781 <          the_bonds[index].b = current_bond->getB() + offset;
1137 >  info->n_atoms = tot_atoms;
1138 >  info->n_bonds = tot_bonds;
1139 >  info->n_bends = tot_bends;
1140 >  info->n_torsions = tot_torsions;
1141 >  info->n_SRI = tot_SRI;
1142 >  info->n_mol = tot_nmol;
1143 >  
1144 >  info->molMembershipArray = new int[tot_atoms];
1145 > }
1146  
783          exI = the_bonds[index].a;
784          exJ = the_bonds[index].b;
1147  
786          // exclude_I must always be the smaller of the pair
787          if( exI > exJ ){
788            tempEx = exI;
789            exI = exJ;
790            exJ = tempEx;
791          }
792
793          
1148   #ifdef IS_MPI
1149  
1150 <          the_excludes[index*2] =    
1151 <            the_atoms[exI]->getGlobalIndex() + 1;
1152 <          the_excludes[index*2 + 1] =
1153 <            the_atoms[exJ]->getGlobalIndex() + 1;
1150 > void SimSetup::mpiMolDivide( void ){
1151 >  
1152 >  int i, j, k;
1153 >  int localMol, allMol;
1154 >  int local_atoms, local_bonds, local_bends, local_torsions, local_SRI;
1155  
1156 < #else  // isn't MPI
1157 <          
1158 <          the_excludes[index*2] =     exI + 1;
804 <          the_excludes[index*2 + 1] = exJ + 1;
805 <          // fortran index from 1 (hence the +1 in the indexing)
806 < #endif  //is_mpi
807 <          
808 <          // increment the index and repeat;
809 <          index++;
810 <        }
811 <        offset += comp_stamps[i]->getNAtoms();
812 <        
813 < #ifdef IS_MPI
814 <      }
815 < #endif //is_mpi
816 <      
817 <      molIndex++;
818 <    }      
819 <  }
1156 >  mpiSim = new mpiSimulation( info );
1157 >  
1158 >  globalIndex = mpiSim->divideLabor();
1159  
1160 <  the_ff->initializeBonds( the_bonds );
822 < }
823 <
824 < void SimSetup::makeBends( void ){
825 <
826 <  int i, j, k, index, offset, molIndex, exI, exJ, tempEx;
827 <  bend_set* the_bends;
828 <  BendStamp* current_bend;
829 <  LinkedAssign* extras;
830 <  LinkedAssign* current_extra;
1160 >  // set up the local variables
1161    
1162 +  mol2proc = mpiSim->getMolToProcMap();
1163 +  molCompType = mpiSim->getMolComponentType();
1164 +  
1165 +  allMol = 0;
1166 +  localMol = 0;
1167 +  local_atoms = 0;
1168 +  local_bonds = 0;
1169 +  local_bends = 0;
1170 +  local_torsions = 0;
1171 +  globalAtomIndex = 0;
1172  
1173 <  the_bends = new bend_set[tot_bends];
834 <  index = 0;
835 <  offset = 0;
836 <  molIndex = 0;
1173 >
1174    for( i=0; i<n_components; i++ ){
1175  
1176      for( j=0; j<components_nmol[i]; j++ ){
1177 <
1178 < #ifdef IS_MPI
842 <      if( mpiSim->getMyMolStart() <= molIndex &&
843 <          molIndex <= mpiSim->getMyMolEnd() ){
844 < #endif // is_mpi        
845 <
846 <        for( k=0; k<comp_stamps[i]->getNBends(); k++ ){
847 <          
848 <          current_bend = comp_stamps[i]->getBend( k );
849 <          the_bends[index].a = current_bend->getA() + offset;
850 <          the_bends[index].b = current_bend->getB() + offset;
851 <          the_bends[index].c = current_bend->getC() + offset;
852 <          
853 <          if( current_bend->haveExtras() ){
854 <            
855 <            extras = current_bend->getExtras();
856 <            current_extra = extras;
857 <            
858 <            while( current_extra != NULL ){
859 <              if( !strcmp( current_extra->getlhs(), "ghostVectorSource" )){
860 <                
861 <                switch( current_extra->getType() ){
862 <                  
863 <                case 0:
864 <                  the_bends[index].ghost =
865 <                    current_extra->getInt() + offset;
866 <                  the_bends[index].isGhost = 1;
867 <                  break;
868 <                  
869 <                case 1:
870 <                  the_bends[index].ghost =
871 <                    (int)current_extra->getDouble() + offset;
872 <                  the_bends[index].isGhost = 1;
873 <                  break;
874 <                  
875 <                default:
876 <                  sprintf( painCave.errMsg,
877 <                           "SimSetup Error: ghostVectorSource was neiter a "
878 <                           "double nor an int.\n"
879 <                           "-->Bend[%d] in %s\n",
880 <                           k, comp_stamps[i]->getID() );
881 <                  painCave.isFatal = 1;
882 <                  simError();
883 <                }
884 <              }
885 <              
886 <              else{
887 <                
888 <                sprintf( painCave.errMsg,
889 <                         "SimSetup Error: unhandled bend assignment:\n"
890 <                         "    -->%s in Bend[%d] in %s\n",
891 <                         current_extra->getlhs(),
892 <                         k, comp_stamps[i]->getID() );
893 <                painCave.isFatal = 1;
894 <                simError();
895 <              }
896 <              
897 <              current_extra = current_extra->getNext();
898 <            }
899 <          }
900 <          
901 <          if( !the_bends[index].isGhost ){
902 <            
903 <            exI = the_bends[index].a;
904 <            exJ = the_bends[index].c;
905 <          }
906 <          else{
907 <            
908 <            exI = the_bends[index].a;
909 <            exJ = the_bends[index].b;
910 <          }
911 <          
912 <          // exclude_I must always be the smaller of the pair
913 <          if( exI > exJ ){
914 <            tempEx = exI;
915 <            exI = exJ;
916 <            exJ = tempEx;
917 <          }
918 <
919 <
920 < #ifdef IS_MPI
921 <
922 <          the_excludes[(index + tot_bonds)*2] =    
923 <            the_atoms[exI]->getGlobalIndex() + 1;
924 <          the_excludes[(index + tot_bonds)*2 + 1] =
925 <            the_atoms[exJ]->getGlobalIndex() + 1;
926 <          
927 < #else  // isn't MPI
928 <          
929 <          the_excludes[(index + tot_bonds)*2] =     exI + 1;
930 <          the_excludes[(index + tot_bonds)*2 + 1] = exJ + 1;
931 <          // fortran index from 1 (hence the +1 in the indexing)
932 < #endif  //is_mpi
933 <          
934 <          
935 <          // increment the index and repeat;
936 <          index++;
937 <        }
938 <        offset += comp_stamps[i]->getNAtoms();
1177 >      
1178 >      if( mol2proc[allMol] == worldRank ){
1179          
1180 < #ifdef IS_MPI
1180 >        local_atoms +=    comp_stamps[i]->getNAtoms();
1181 >        local_bonds +=    comp_stamps[i]->getNBonds();
1182 >        local_bends +=    comp_stamps[i]->getNBends();
1183 >        local_torsions += comp_stamps[i]->getNTorsions();
1184 >        localMol++;
1185 >      }      
1186 >      for (k = 0; k < comp_stamps[i]->getNAtoms(); k++) {
1187 >        info->molMembershipArray[globalAtomIndex] = allMol;
1188 >        globalAtomIndex++;
1189        }
942 #endif //is_mpi
1190  
1191 <      molIndex++;
1191 >      allMol++;      
1192      }
1193    }
1194 +  local_SRI = local_bonds + local_bends + local_torsions;
1195 +  
1196 +  info->n_atoms = mpiSim->getMyNlocal();  
1197 +  
1198 +  if( local_atoms != info->n_atoms ){
1199 +    sprintf( painCave.errMsg,
1200 +             "SimSetup error: mpiSim's localAtom (%d) and SimSetup's"
1201 +             " localAtom (%d) are not equal.\n",
1202 +             info->n_atoms,
1203 +             local_atoms );
1204 +    painCave.isFatal = 1;
1205 +    simError();
1206 +  }
1207  
1208 < #ifdef IS_MPI
1209 <  sprintf( checkPointMsg,
1210 <           "Successfully created the bends list.\n" );
1208 >  info->n_bonds = local_bonds;
1209 >  info->n_bends = local_bends;
1210 >  info->n_torsions = local_torsions;
1211 >  info->n_SRI = local_SRI;
1212 >  info->n_mol = localMol;
1213 >
1214 >  strcpy( checkPointMsg, "Passed nlocal consistency check." );
1215    MPIcheckPoint();
1216 < #endif // is_mpi
1216 > }
1217    
1218 + #endif // is_mpi
1219  
955  the_ff->initializeBends( the_bends );
956 }
1220  
1221 < void SimSetup::makeTorsions( void ){
1221 > void SimSetup::makeSysArrays( void ){
1222 >  int i, j, k;
1223  
960  int i, j, k, index, offset, molIndex, exI, exJ, tempEx;
961  torsion_set* the_torsions;
962  TorsionStamp* current_torsion;
1224  
1225 <  the_torsions = new torsion_set[tot_torsions];
965 <  index = 0;
966 <  offset = 0;
967 <  molIndex = 0;
968 <  for( i=0; i<n_components; i++ ){
1225 >  // create the atom and short range interaction arrays
1226  
1227 <    for( j=0; j<components_nmol[i]; j++ ){
1227 >  Atom::createArrays(info->n_atoms);
1228 >  the_atoms = new Atom*[info->n_atoms];
1229 >  the_molecules = new Molecule[info->n_mol];
1230 >  int molIndex;
1231  
1232 < #ifdef IS_MPI
973 <      if( mpiSim->getMyMolStart() <= molIndex &&
974 <          molIndex <= mpiSim->getMyMolEnd() ){
975 < #endif // is_mpi        
1232 >  // initialize the molecule's stampID's
1233  
1234 <      for( k=0; k<comp_stamps[i]->getNTorsions(); k++ ){
1234 > #ifdef IS_MPI
1235 >  
1236  
1237 <        current_torsion = comp_stamps[i]->getTorsion( k );
1238 <        the_torsions[index].a = current_torsion->getA() + offset;
1239 <        the_torsions[index].b = current_torsion->getB() + offset;
1240 <        the_torsions[index].c = current_torsion->getC() + offset;
1241 <        the_torsions[index].d = current_torsion->getD() + offset;
1237 >  molIndex = 0;
1238 >  for(i=0; i<mpiSim->getTotNmol(); i++){
1239 >    
1240 >    if(mol2proc[i] == worldRank ){
1241 >      the_molecules[molIndex].setStampID( molCompType[i] );
1242 >      the_molecules[molIndex].setMyIndex( molIndex );
1243 >      the_molecules[molIndex].setGlobalIndex( i );
1244 >      molIndex++;
1245 >    }
1246 >  }
1247  
1248 <        exI = the_torsions[index].a;
1249 <        exJ = the_torsions[index].d;
1250 <
1251 <        
1252 <        // exclude_I must always be the smaller of the pair
1253 <        if( exI > exJ ){
1254 <          tempEx = exI;
1255 <          exI = exJ;
1256 <          exJ = tempEx;
1257 <        }
1258 <
1259 <
997 < #ifdef IS_MPI
998 <        
999 <        the_excludes[(index + tot_bonds + tot_bends)*2] =    
1000 <          the_atoms[exI]->getGlobalIndex() + 1;
1001 <        the_excludes[(index + tot_bonds + tot_bends)*2 + 1] =
1002 <          the_atoms[exJ]->getGlobalIndex() + 1;
1003 <        
1004 < #else  // isn't MPI
1005 <        
1006 <        the_excludes[(index + tot_bonds + tot_bends)*2] =     exI + 1;
1007 <        the_excludes[(index + tot_bonds + tot_bends)*2 + 1] = exJ + 1;
1008 <        // fortran indexes from 1 (hence the +1 in the indexing)
1009 < #endif  //is_mpi
1010 <        
1011 <
1012 <        // increment the index and repeat;
1013 <        index++;
1248 > #else // is_mpi
1249 >  
1250 >  molIndex = 0;
1251 >  globalAtomIndex = 0;
1252 >  for(i=0; i<n_components; i++){
1253 >    for(j=0; j<components_nmol[i]; j++ ){
1254 >      the_molecules[molIndex].setStampID( i );
1255 >      the_molecules[molIndex].setMyIndex( molIndex );
1256 >      the_molecules[molIndex].setGlobalIndex( molIndex );
1257 >      for (k = 0; k < comp_stamps[i]->getNAtoms(); k++) {
1258 >        info->molMembershipArray[globalAtomIndex] = molIndex;
1259 >        globalAtomIndex++;
1260        }
1015      offset += comp_stamps[i]->getNAtoms();
1016
1017 #ifdef IS_MPI
1018      }
1019 #endif //is_mpi      
1020
1261        molIndex++;
1262      }
1263    }
1264 +    
1265  
1266 <  the_ff->initializeTorsions( the_torsions );
1026 < }
1266 > #endif // is_mpi
1267  
1028 void SimSetup::initFromBass( void ){
1268  
1269 <  int i, j, k;
1270 <  int n_cells;
1271 <  double cellx, celly, cellz;
1272 <  double temp1, temp2, temp3;
1273 <  int n_per_extra;
1274 <  int n_extra;
1275 <  int have_extra, done;
1037 <
1038 <  temp1 = (double)tot_nmol / 4.0;
1039 <  temp2 = pow( temp1, ( 1.0 / 3.0 ) );
1040 <  temp3 = ceil( temp2 );
1041 <
1042 <  have_extra =0;
1043 <  if( temp2 < temp3 ){ // we have a non-complete lattice
1044 <    have_extra =1;
1045 <
1046 <    n_cells = (int)temp3 - 1;
1047 <    cellx = simnfo->box_x / temp3;
1048 <    celly = simnfo->box_y / temp3;
1049 <    cellz = simnfo->box_z / temp3;
1050 <    n_extra = tot_nmol - ( 4 * n_cells * n_cells * n_cells );
1051 <    temp1 = ((double)n_extra) / ( pow( temp3, 3.0 ) - pow( n_cells, 3.0 ) );
1052 <    n_per_extra = (int)ceil( temp1 );
1053 <
1054 <    if( n_per_extra > 4){
1055 <      sprintf( painCave.errMsg,
1056 <               "SimSetup error. There has been an error in constructing"
1057 <               " the non-complete lattice.\n" );
1058 <      painCave.isFatal = 1;
1059 <      simError();
1060 <    }
1269 >  if( info->n_SRI ){
1270 >    
1271 >    Exclude::createArray(info->n_SRI);
1272 >    the_excludes = new Exclude*[info->n_SRI];
1273 >    for( int ex=0; ex<info->n_SRI; ex++) the_excludes[ex] = new Exclude(ex);
1274 >    info->globalExcludes = new int;
1275 >    info->n_exclude = info->n_SRI;
1276    }
1277    else{
1278 <    n_cells = (int)temp3;
1279 <    cellx = simnfo->box_x / temp3;
1280 <    celly = simnfo->box_y / temp3;
1281 <    cellz = simnfo->box_z / temp3;
1278 >    
1279 >    Exclude::createArray( 1 );
1280 >    the_excludes = new Exclude*;
1281 >    the_excludes[0] = new Exclude(0);
1282 >    the_excludes[0]->setPair( 0,0 );
1283 >    info->globalExcludes = new int;
1284 >    info->globalExcludes[0] = 0;
1285 >    info->n_exclude = 0;
1286    }
1287  
1288 <  current_mol = 0;
1070 <  current_comp_mol = 0;
1071 <  current_comp = 0;
1072 <  current_atom_ndx = 0;
1288 >  // set the arrays into the SimInfo object
1289  
1290 <  for( i=0; i < n_cells ; i++ ){
1291 <    for( j=0; j < n_cells; j++ ){
1292 <      for( k=0; k < n_cells; k++ ){
1290 >  info->atoms = the_atoms;
1291 >  info->molecules = the_molecules;
1292 >  info->nGlobalExcludes = 0;
1293 >  info->excludes = the_excludes;
1294  
1295 <        makeElement( i * cellx,
1079 <                     j * celly,
1080 <                     k * cellz );
1295 >  the_ff->setSimInfo( info );
1296  
1297 <        makeElement( i * cellx + 0.5 * cellx,
1083 <                     j * celly + 0.5 * celly,
1084 <                     k * cellz );
1297 > }
1298  
1299 <        makeElement( i * cellx,
1087 <                     j * celly + 0.5 * celly,
1088 <                     k * cellz + 0.5 * cellz );
1299 > void SimSetup::makeIntegrator( void ){
1300  
1301 <        makeElement( i * cellx + 0.5 * cellx,
1302 <                     j * celly,
1303 <                     k * cellz + 0.5 * cellz );
1304 <      }
1305 <    }
1095 <  }
1301 >  NVT<RealIntegrator>*  myNVT = NULL;
1302 >  NPTi<RealIntegrator>* myNPTi = NULL;
1303 >  NPTf<RealIntegrator>* myNPTf = NULL;
1304 >  NPTim<RealIntegrator>* myNPTim = NULL;
1305 >  NPTfm<RealIntegrator>* myNPTfm = NULL;
1306  
1307 <  if( have_extra ){
1098 <    done = 0;
1307 >  switch( ensembleCase ){
1308  
1309 <    int start_ndx;
1310 <    for( i=0; i < (n_cells+1) && !done; i++ ){
1311 <      for( j=0; j < (n_cells+1) && !done; j++ ){
1309 >  case NVE_ENS:
1310 >    new NVE<RealIntegrator>( info, the_ff );
1311 >    break;
1312  
1313 <        if( i < n_cells ){
1313 >  case NVT_ENS:
1314 >    myNVT = new NVT<RealIntegrator>( info, the_ff );
1315 >    myNVT->setTargetTemp(globals->getTargetTemp());
1316  
1317 <          if( j < n_cells ){
1318 <            start_ndx = n_cells;
1108 <          }
1109 <          else start_ndx = 0;
1110 <        }
1111 <        else start_ndx = 0;
1317 >    if (globals->haveTauThermostat())
1318 >      myNVT->setTauThermostat(globals->getTauThermostat());
1319  
1320 <        for( k=start_ndx; k < (n_cells+1) && !done; k++ ){
1320 >    else {
1321 >      sprintf( painCave.errMsg,
1322 >               "SimSetup error: If you use the NVT\n"
1323 >               "    ensemble, you must set tauThermostat.\n");
1324 >      painCave.isFatal = 1;
1325 >      simError();
1326 >    }
1327 >    break;
1328  
1329 <          makeElement( i * cellx,
1330 <                       j * celly,
1331 <                       k * cellz );
1118 <          done = ( current_mol >= tot_nmol );
1329 >  case NPTi_ENS:
1330 >    myNPTi = new NPTi<RealIntegrator>( info, the_ff );
1331 >    myNPTi->setTargetTemp( globals->getTargetTemp() );
1332  
1333 <          if( !done && n_per_extra > 1 ){
1334 <            makeElement( i * cellx + 0.5 * cellx,
1335 <                         j * celly + 0.5 * celly,
1336 <                         k * cellz );
1337 <            done = ( current_mol >= tot_nmol );
1338 <          }
1333 >    if (globals->haveTargetPressure())
1334 >      myNPTi->setTargetPressure(globals->getTargetPressure());
1335 >    else {
1336 >      sprintf( painCave.errMsg,
1337 >               "SimSetup error: If you use a constant pressure\n"
1338 >               "    ensemble, you must set targetPressure in the BASS file.\n");
1339 >      painCave.isFatal = 1;
1340 >      simError();
1341 >    }
1342 >    
1343 >    if( globals->haveTauThermostat() )
1344 >      myNPTi->setTauThermostat( globals->getTauThermostat() );
1345 >    else{
1346 >      sprintf( painCave.errMsg,
1347 >               "SimSetup error: If you use an NPT\n"
1348 >               "    ensemble, you must set tauThermostat.\n");
1349 >      painCave.isFatal = 1;
1350 >      simError();
1351 >    }
1352  
1353 <          if( !done && n_per_extra > 2){
1354 <            makeElement( i * cellx,
1355 <                         j * celly + 0.5 * celly,
1356 <                         k * cellz + 0.5 * cellz );
1357 <            done = ( current_mol >= tot_nmol );
1358 <          }
1359 <
1360 <          if( !done && n_per_extra > 3){
1135 <            makeElement( i * cellx + 0.5 * cellx,
1136 <                         j * celly,
1137 <                         k * cellz + 0.5 * cellz );
1138 <            done = ( current_mol >= tot_nmol );
1139 <          }
1140 <        }
1141 <      }
1353 >    if( globals->haveTauBarostat() )
1354 >      myNPTi->setTauBarostat( globals->getTauBarostat() );
1355 >    else{
1356 >      sprintf( painCave.errMsg,
1357 >               "SimSetup error: If you use an NPT\n"
1358 >               "    ensemble, you must set tauBarostat.\n");
1359 >      painCave.isFatal = 1;
1360 >      simError();
1361      }
1362 <  }
1362 >    break;
1363  
1364 +  case NPTf_ENS:
1365 +    myNPTf = new NPTf<RealIntegrator>( info, the_ff );
1366 +    myNPTf->setTargetTemp( globals->getTargetTemp());
1367  
1368 <  for( i=0; i<simnfo->n_atoms; i++ ){
1369 <    simnfo->atoms[i]->set_vx( 0.0 );
1370 <    simnfo->atoms[i]->set_vy( 0.0 );
1371 <    simnfo->atoms[i]->set_vz( 0.0 );
1372 <  }
1373 < }
1368 >    if (globals->haveTargetPressure())
1369 >      myNPTf->setTargetPressure(globals->getTargetPressure());
1370 >    else {
1371 >      sprintf( painCave.errMsg,
1372 >               "SimSetup error: If you use a constant pressure\n"
1373 >               "    ensemble, you must set targetPressure in the BASS file.\n");
1374 >      painCave.isFatal = 1;
1375 >      simError();
1376 >    }    
1377  
1378 < void SimSetup::makeElement( double x, double y, double z ){
1378 >    if( globals->haveTauThermostat() )
1379 >      myNPTf->setTauThermostat( globals->getTauThermostat() );
1380 >    else{
1381 >      sprintf( painCave.errMsg,
1382 >               "SimSetup error: If you use an NPT\n"
1383 >               "    ensemble, you must set tauThermostat.\n");
1384 >      painCave.isFatal = 1;
1385 >      simError();
1386 >    }
1387  
1388 <  int k;
1389 <  AtomStamp* current_atom;
1390 <  DirectionalAtom* dAtom;
1391 <  double rotMat[3][3];
1388 >    if( globals->haveTauBarostat() )
1389 >      myNPTf->setTauBarostat( globals->getTauBarostat() );
1390 >    else{
1391 >      sprintf( painCave.errMsg,
1392 >               "SimSetup error: If you use an NPT\n"
1393 >               "    ensemble, you must set tauBarostat.\n");
1394 >      painCave.isFatal = 1;
1395 >      simError();
1396 >    }
1397 >    break;
1398 >    
1399 >  case NPTim_ENS:
1400 >    myNPTim = new NPTim<RealIntegrator>( info, the_ff );
1401 >    myNPTim->setTargetTemp( globals->getTargetTemp());
1402  
1403 <  for( k=0; k<comp_stamps[current_comp]->getNAtoms(); k++ ){
1403 >    if (globals->haveTargetPressure())
1404 >      myNPTim->setTargetPressure(globals->getTargetPressure());
1405 >    else {
1406 >      sprintf( painCave.errMsg,
1407 >               "SimSetup error: If you use a constant pressure\n"
1408 >               "    ensemble, you must set targetPressure in the BASS file.\n");
1409 >      painCave.isFatal = 1;
1410 >      simError();
1411 >    }
1412 >    
1413 >    if( globals->haveTauThermostat() )
1414 >      myNPTim->setTauThermostat( globals->getTauThermostat() );
1415 >    else{
1416 >      sprintf( painCave.errMsg,
1417 >               "SimSetup error: If you use an NPT\n"
1418 >               "    ensemble, you must set tauThermostat.\n");
1419 >      painCave.isFatal = 1;
1420 >      simError();
1421 >    }
1422  
1423 <    current_atom = comp_stamps[current_comp]->getAtom( k );
1424 <    if( !current_atom->havePosition() ){
1423 >    if( globals->haveTauBarostat() )
1424 >      myNPTim->setTauBarostat( globals->getTauBarostat() );
1425 >    else{
1426        sprintf( painCave.errMsg,
1427 <               "SimSetup:initFromBass error.\n"
1428 <               "\tComponent %s, atom %s does not have a position specified.\n"
1167 <               "\tThe initialization routine is unable to give a start"
1168 <               " position.\n",
1169 <               comp_stamps[current_comp]->getID(),
1170 <               current_atom->getType() );
1427 >               "SimSetup error: If you use an NPT\n"
1428 >               "    ensemble, you must set tauBarostat.\n");
1429        painCave.isFatal = 1;
1430        simError();
1431      }
1432 +    break;
1433  
1434 <    the_atoms[current_atom_ndx]->setX( x + current_atom->getPosX() );
1435 <    the_atoms[current_atom_ndx]->setY( y + current_atom->getPosY() );
1436 <    the_atoms[current_atom_ndx]->setZ( z + current_atom->getPosZ() );
1434 >  case NPTfm_ENS:
1435 >    myNPTfm = new NPTfm<RealIntegrator>( info, the_ff );
1436 >    myNPTfm->setTargetTemp( globals->getTargetTemp());
1437  
1438 <    if( the_atoms[current_atom_ndx]->isDirectional() ){
1438 >    if (globals->haveTargetPressure())
1439 >      myNPTfm->setTargetPressure(globals->getTargetPressure());
1440 >    else {
1441 >      sprintf( painCave.errMsg,
1442 >               "SimSetup error: If you use a constant pressure\n"
1443 >               "    ensemble, you must set targetPressure in the BASS file.\n");
1444 >      painCave.isFatal = 1;
1445 >      simError();
1446 >    }
1447 >    
1448 >    if( globals->haveTauThermostat() )
1449 >      myNPTfm->setTauThermostat( globals->getTauThermostat() );
1450 >    else{
1451 >      sprintf( painCave.errMsg,
1452 >               "SimSetup error: If you use an NPT\n"
1453 >               "    ensemble, you must set tauThermostat.\n");
1454 >      painCave.isFatal = 1;
1455 >      simError();
1456 >    }
1457  
1458 <      dAtom = (DirectionalAtom *)the_atoms[current_atom_ndx];
1458 >    if( globals->haveTauBarostat() )
1459 >      myNPTfm->setTauBarostat( globals->getTauBarostat() );
1460 >    else{
1461 >      sprintf( painCave.errMsg,
1462 >               "SimSetup error: If you use an NPT\n"
1463 >               "    ensemble, you must set tauBarostat.\n");
1464 >      painCave.isFatal = 1;
1465 >      simError();
1466 >    }
1467 >    break;
1468  
1469 <      rotMat[0][0] = 1.0;
1470 <      rotMat[0][1] = 0.0;
1471 <      rotMat[0][2] = 0.0;
1469 >  default:
1470 >    sprintf( painCave.errMsg,
1471 >             "SimSetup Error. Unrecognized ensemble in case statement.\n");
1472 >    painCave.isFatal = 1;
1473 >    simError();
1474 >  }
1475  
1476 <      rotMat[1][0] = 0.0;
1188 <      rotMat[1][1] = 1.0;
1189 <      rotMat[1][2] = 0.0;
1476 > }
1477  
1478 <      rotMat[2][0] = 0.0;
1192 <      rotMat[2][1] = 0.0;
1193 <      rotMat[2][2] = 1.0;
1478 > void SimSetup::initFortran( void ){
1479  
1480 <      dAtom->setA( rotMat );
1481 <    }
1482 <
1483 <    current_atom_ndx++;
1480 >  info->refreshSim();
1481 >  
1482 >  if( !strcmp( info->mixingRule, "standard") ){
1483 >    the_ff->initForceField( LB_MIXING_RULE );
1484    }
1485 +  else if( !strcmp( info->mixingRule, "explicit") ){
1486 +    the_ff->initForceField( EXPLICIT_MIXING_RULE );
1487 +  }
1488 +  else{
1489 +    sprintf( painCave.errMsg,
1490 +             "SimSetup Error: unknown mixing rule -> \"%s\"\n",
1491 +             info->mixingRule );
1492 +    painCave.isFatal = 1;
1493 +    simError();
1494 +  }
1495  
1201  current_mol++;
1202  current_comp_mol++;
1496  
1497 <  if( current_comp_mol >= components_nmol[current_comp] ){
1497 > #ifdef IS_MPI
1498 >  strcpy( checkPointMsg,
1499 >          "Successfully intialized the mixingRule for Fortran." );
1500 >  MPIcheckPoint();
1501 > #endif // is_mpi
1502  
1206    current_comp_mol = 0;
1207    current_comp++;
1208  }
1503   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines