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 378 by mmeineke, Fri Mar 21 17:42:12 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 +  // initialize the Fortran
125 +
126 +  initFortran();
127 +
128 +
129 +
130 + }
131 +
132 +
133 + void SimSetup::makeMolecules( void ){
134 +
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 +  bond_pair* theBonds;
146 +  bend_set* theBends;
147 +  torsion_set* theTorsions;
148 +
149    
150 +  //init the forceField paramters
151  
152 <  // 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];
152 >  the_ff->readParams();
153  
154 <  if( !the_globals->haveNMol() ){
155 <    // we don't have the total number of molecules, so we assume it is
117 <    // given in each component
154 >  
155 >  // init the atoms
156  
157 <    tot_nmol = 0;
158 <    for( i=0; i<n_components; i++ ){
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 >    stampID = the_molecules[i].getStampID();
164  
165 <      if( !the_components[i]->haveNMol() ){
166 <        // we have a problem
167 <        sprintf( painCave.errMsg,
168 <                 "SimSetup Error. No global NMol or component NMol"
169 <                 " given. Cannot calculate the number of atoms.\n" );
127 <        painCave.isFatal = 1;
128 <        simError();
129 <      }
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 <      tot_nmol += the_components[i]->getNMol();
172 <      components_nmol[i] = the_components[i]->getNMol();
173 <    }
174 <  }
175 <  else{
176 <    sprintf( painCave.errMsg,
177 <             "SimSetup error.\n"
178 <             "\tSorry, the ability to specify total"
179 <             " 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();
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 <    //     tot_nmol = the_globals->getNMol();
183 >    for(j=0; j<molInfo.nAtoms; j++){
184 >      
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 >      else{
208 >        molInfo.myAtoms[j] = new GeneralAtom(j + atomOffset);
209 >      }
210 >      molInfo.myAtoms[j]->setType( currentAtom->getType() );
211      
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  }
159
212   #ifdef IS_MPI
213 <  strcpy( checkPointMsg, "Have the number of components" );
214 <  MPIcheckPoint();
213 >      
214 >      molInfo.myAtoms[j]->setGlobalIndex( globalIndex[j+atomOffset] );
215 >      
216   #endif // is_mpi
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 <  // make an array of molecule stamps that match the components used.
227 <  // also extract the used stamps out into a separate linked list
226 >      exI = theBonds[j].a;
227 >      exJ = theBonds[j].b;
228  
229 <  simnfo->nComponents = n_components;
230 <  simnfo->componentsNmol = components_nmol;
231 <  simnfo->compStamps = comp_stamps;
232 <  simnfo->headStamp = new LinkedMolStamp();
233 <  
234 <  char* id;
235 <  LinkedMolStamp* headStamp = simnfo->headStamp;
236 <  LinkedMolStamp* currentStamp = NULL;
237 <  for( i=0; i<n_components; i++ ){
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 <    id = the_components[i]->getType();
245 <    comp_stamps[i] = NULL;
246 <    
247 <    // check to make sure the component isn't already in the list
244 >      the_excludes[j+excludeOffset]->setPair( (exI+1), (exJ+1) );
245 > #endif  //is_mpi
246 >    }
247 >    excludeOffset += molInfo.nBonds;
248  
249 <    comp_stamps[i] = headStamp->match( id );
250 <    if( comp_stamps[i] == NULL ){
249 >    //make the bends
250 >    for(j=0; j<molInfo.nBends; j++){
251        
252 <      // extract the component from the list;
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 <      currentStamp = the_stamps->extractMolStamp( id );
317 <      if( currentStamp == NULL ){
318 <        sprintf( painCave.errMsg,
319 <                 "SimSetup error: Component \"%s\" was not found in the "
320 <                 "list of declared molecules\n",
193 <                 id );
194 <        painCave.isFatal = 1;
195 <        simError();
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 <      headStamp->add( currentStamp );
329 <      comp_stamps[i] = headStamp->match( id );
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 <  }
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 <  strcpy( checkPointMsg, "Component stamps successfully extracted\n" );
354 <  MPIcheckPoint();
355 < #endif // is_mpi
356 <  
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  
209
210
211  // caclulate the number of atoms, bonds, bends and torsions
212
213  tot_atoms = 0;
214  tot_bonds = 0;
215  tot_bends = 0;
216  tot_torsions = 0;
217  for( i=0; i<n_components; i++ ){
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 <  
235 < #ifdef IS_MPI
374 >    the_molecules[i].initialize( molInfo );
375  
237  // divide the molecules among processors here.
238  
239  mpiSim = new mpiSimulation( simnfo );
240  
241  
376  
377 <  globalIndex = mpiSim->divideLabor();
378 <
379 <
380 <
247 <  // set up the local variables
248 <  
249 <  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++ ){
259 <
260 <    for( j=0; j<components_nmol[i]; j++ ){
261 <      
262 <      if( mpiSim->getMyMolStart() <= allMol &&
263 <          allMol <= mpiSim->getMyMolEnd() ){
264 <        
265 <        local_atoms +=    comp_stamps[i]->getNAtoms();
266 <        local_bonds +=    comp_stamps[i]->getNBonds();
267 <        local_bends +=    comp_stamps[i]->getNBends();
268 <        local_torsions += comp_stamps[i]->getNTorsions();
269 <        localMol++;
270 <      }      
271 <      allMol++;
272 <    }
377 >    atomOffset += molInfo.nAtoms;
378 >    delete[] theBonds;
379 >    delete[] theBends;
380 >    delete[] theTorsions;
381    }
274  local_SRI = local_bonds + local_bends + local_torsions;
275  
382  
383 <  simnfo->n_atoms = mpiSim->getMyNlocal();  
384 <  
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();
287 <  }
288 <
289 <  simnfo->n_bonds = local_bonds;
290 <  simnfo->n_bends = local_bends;
291 <  simnfo->n_torsions = local_torsions;
292 <  simnfo->n_SRI = local_SRI;
293 <  simnfo->n_mol = localMol;
294 <
295 <  strcpy( checkPointMsg, "Passed nlocal consistency check." );
383 > #ifdef IS_MPI
384 >  sprintf( checkPointMsg, "all molecules initialized succesfully" );
385    MPIcheckPoint();
297  
298  
386   #endif // is_mpi
300  
387  
388 <  // create the atom and short range interaction arrays
388 >  // clean up the forcefield
389 >  the_ff->calcRcut();
390 >  the_ff->cleanMe();
391  
392 <  Atom::createArrays(simnfo->n_atoms);
305 <  the_atoms = new Atom*[simnfo->n_atoms];
306 <  the_molecules = new Molecule[simnfo->n_mol];
392 > }
393  
394 + void SimSetup::initFromBass( void ){
395  
396 <  if( simnfo->n_SRI ){
397 <    the_sris = new SRI*[simnfo->n_SRI];
398 <    the_excludes = new int[2 * simnfo->n_SRI];
399 <    simnfo->globalExcludes = new int;
400 <    simnfo->n_exclude = tot_SRI;
401 <  }
402 <  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;
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 <    simnfo->n_exclude = 1;
405 <  }
404 >  temp1 = (double)tot_nmol / 4.0;
405 >  temp2 = pow( temp1, ( 1.0 / 3.0 ) );
406 >  temp3 = ceil( temp2 );
407  
408 <  // set the arrays into the SimInfo object
408 >  have_extra =0;
409 >  if( temp2 < temp3 ){ // we have a non-complete lattice
410 >    have_extra =1;
411  
412 <  simnfo->atoms = the_atoms;
413 <  simnfo->sr_interactions = the_sris;
414 <  simnfo->nGlobalExcludes = 0;
415 <  simnfo->excludes = the_excludes;
416 <
417 <
418 <  // get some of the tricky things that may still be in the globals
419 <
420 <  if( simnfo->n_dipoles ){
337 <
338 <    if( !the_globals->haveRRF() ){
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, system has dipoles, but no rRF was set.\n");
422 >               "SimSetup error. There has been an error in constructing"
423 >               " the non-complete lattice.\n" );
424        painCave.isFatal = 1;
425        simError();
426      }
427 <    if( !the_globals->haveDielectric() ){
427 >  }
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 >  current_mol = 0;
436 >  current_comp_mol = 0;
437 >  current_comp = 0;
438 >  current_atom_ndx = 0;
439 >
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 >        makeElement( i * cellx,
445 >                     j * celly,
446 >                     k * cellz );
447 >
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 >        makeElement( i * cellx + 0.5 * cellx,
457 >                     j * celly,
458 >                     k * cellz + 0.5 * cellz );
459 >      }
460 >    }
461 >  }
462 >
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 >
511 >
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 >  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 Error, system has dipoles, but no"
532 <               " dielectric was set.\n" );
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 <    simnfo->rRF        = the_globals->getRRF();
542 <    simnfo->dielectric = the_globals->getDielectric();
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 < #ifdef IS_MPI
568 <  strcpy( checkPointMsg, "rRf and dielectric check out" );
569 <  MPIcheckPoint();
570 < #endif // is_mpi
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  
406  // initialize the arrays
758  
759 <  the_ff->setSimInfo( simnfo );
759 > void SimSetup::finalInfoCheck( void ){
760 >  int index;
761 >  int usesDipoles;
762 >  
763  
764 <  makeAtoms();
411 <  simnfo->identArray = new int[simnfo->n_atoms];
412 <  for(i=0; i<simnfo->n_atoms; i++){
413 <    simnfo->identArray[i] = the_atoms[i]->getIdent();
414 <  }
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 ){
421 <    makeBends();
422 <  }
778 >  double theEcr, theEst;
779  
780 <  if( tot_torsions ){
781 <    makeTorsions();
782 <  }
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"
787 >               "I hope you have a very fast processor!\n");
788 >      painCave.isFatal = 0;
789 >      simError();
790 >      double 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 >      theEcr = globals->getECR();
797 >    }
798  
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 +      theEst = 0.05 * theEcr;
807 +    } else {
808 +      theEst= globals->getEST();
809 +    }
810  
811 +    info->setEcr( theEcr, theEst );
812 +    
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"
817 +               );
818 +      painCave.isFatal = 1;
819 +      simError();
820 +    }
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 +        theEcr = globals->getECR();
840 +      }
841 +      
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 +        theEst= globals->getEST();
853 +      }
854  
855 +      info->setEcr( theEcr, theEst );
856 +    }
857 +  }  
858  
859 + #ifdef IS_MPI
860 +  strcpy( checkPointMsg, "post processing checks out" );
861 +  MPIcheckPoint();
862 + #endif // is_mpi
863  
864 + }
865  
866 < if( the_globals->haveInitialConfig() ){
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 468 | Line 903 | void SimSetup::createSim( void ){
903    MPIcheckPoint();
904   #endif // is_mpi
905  
906 + }
907  
472  
473
474  
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 493 | 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 501 | 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 519 | 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 527 | 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 541 | 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 549 | 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
995 <  
562 <  if( the_globals->haveSampleTime() ){
563 <    simnfo->sampleTime = the_globals->getSampleTime();
564 <    simnfo->statusTime = simnfo->sampleTime;
565 <    simnfo->thermalTime = simnfo->sampleTime;
566 <  }
567 <  else{
568 <    simnfo->sampleTime = the_globals->getRunTime();
569 <    simnfo->statusTime = simnfo->sampleTime;
570 <    simnfo->thermalTime = simnfo->sampleTime;
571 <  }
993 >
994 > }
995 >
996  
997 <  if( the_globals->haveStatusTime() ){
574 <    simnfo->statusTime = the_globals->getStatusTime();
575 <  }
997 > void SimSetup::sysObjectsCreation( void ){
998  
999 <  if( the_globals->haveThermalTime() ){
578 <    simnfo->thermalTime = the_globals->getThermalTime();
579 <  }
999 >  int i;
1000  
1001 <  // check for the temperature set flag
1001 >  // create the forceField
1002  
1003 <  if( the_globals->haveTempSet() ) simnfo->setTemp = the_globals->getTempSet();
1003 >  createFF();
1004  
1005 +  // extract componentList
1006  
1007 < //   // make the longe range forces and the integrator
1007 >  compList();
1008  
1009 < //   new AllLong( simnfo );
1009 >  // calc the number of atoms, bond, bends, and torsions
1010  
1011 <  if( !strcmp( force_field, "TraPPE" ) ) new Verlet( *simnfo, the_ff );
591 <  if( !strcmp( force_field, "DipoleTest" ) ) new Symplectic( simnfo, the_ff );
592 <  if( !strcmp( force_field, "TraPPE_Ex" ) ) new Symplectic( simnfo, the_ff );
593 <  if( !strcmp( force_field, "LJ" ) ) new Verlet( *simnfo, the_ff );
1011 >  calcSysValues();
1012  
1013 <
1014 <
597 <  // initialize the Fortran
1013 > #ifdef IS_MPI
1014 >  // divide the molecules among the processors
1015    
1016 <  simnfo->refreshSim();
1016 >  mpiMolDivide();
1017 > #endif //is_mpi
1018    
1019 <  if( !strcmp( simnfo->mixingRule, "standard") ){
1020 <    the_ff->initForceField( LB_MIXING_RULE );
1019 >  // create the atom and SRI arrays. Also initialize Molecule Stamp ID's
1020 >  
1021 >  makeSysArrays();
1022 >
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 <  else if( !strcmp( simnfo->mixingRule, "explicit") ){
1031 <    the_ff->initForceField( EXPLICIT_MIXING_RULE );
1032 <  }
1033 <  else{
1030 >  
1031 >
1032 >
1033 > }
1034 >
1035 >
1036 > void SimSetup::createFF( void ){
1037 >
1038 >  switch( ffCase ){
1039 >
1040 >  case FF_DUFF:
1041 >    the_ff = new DUFF();
1042 >    break;
1043 >
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 >  default:
1053      sprintf( painCave.errMsg,
1054 <             "SimSetup Error: unknown mixing rule -> \"%s\"\n",
610 <             simnfo->mixingRule );
1054 >             "SimSetup Error. Unrecognized force field in case statement.\n");
1055      painCave.isFatal = 1;
1056      simError();
1057    }
1058  
615
1059   #ifdef IS_MPI
1060 <  strcpy( checkPointMsg,
618 <          "Successfully intialized the mixingRule for Fortran." );
1060 >  strcpy( checkPointMsg, "ForceField creation successful" );
1061    MPIcheckPoint();
1062   #endif // is_mpi
1063 +
1064   }
1065  
623 void SimSetup::makeAtoms( void ){
1066  
1067 <  int i, j, k, index;
626 <  double ux, uy, uz, uSqr, u;
627 <  AtomStamp* current_atom;
1067 > void SimSetup::compList( void ){
1068  
1069 <  DirectionalAtom* dAtom;
630 <  int molIndex, molStart, molEnd, nMemb, lMolIndex;
1069 >  int i;
1070  
1071 <  lMolIndex = 0;
633 <  molIndex = 0;
634 <  index = 0;
635 <  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 <          
648 <          current_atom = comp_stamps[i]->getAtom( k );
649 <          if( current_atom->haveOrientation() ){
650 <            
651 <            dAtom = new DirectionalAtom(index);
652 <            simnfo->n_oriented++;
653 <            the_atoms[index] = dAtom;
654 <            
655 <            ux = current_atom->getOrntX();
656 <            uy = current_atom->getOrntY();
657 <            uz = current_atom->getOrntZ();
658 <            
659 <            uSqr = (ux * ux) + (uy * uy) + (uz * uz);
660 <            
661 <            u = sqrt( uSqr );
662 <            ux = ux / u;
663 <            uy = uy / u;
664 <            uz = uz / u;
665 <            
666 <            dAtom->setSUx( ux );
667 <            dAtom->setSUy( uy );
668 <            dAtom->setSUz( uz );
669 <          }
670 <          else{
671 <            the_atoms[index] = new GeneralAtom(index);
672 <          }
673 <          the_atoms[index]->setType( current_atom->getType() );
674 <          the_atoms[index]->setIndex( index );
675 <          
676 <          // increment the index and repeat;
677 <          index++;
678 <        }
679 <        
680 <        molEnd = index -1;
681 <        the_molecules[lMolIndex].setNMembers( nMemb );
682 <        the_molecules[lMolIndex].setStartAtom( molStart );
683 <        the_molecules[lMolIndex].setEndAtom( molEnd );
684 <        the_molecules[lMolIndex].setStampID( i );
685 <        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        }
689 #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();
701 < #endif //IS_MPI
702 <          
703 <  the_ff->initializeAtoms();
1116 >
1117   }
1118  
1119 < void SimSetup::makeBonds( void ){
1119 > void SimSetup::calcSysValues( void ){
1120 >  int i, j, k;
1121  
708  int i, j, k, index, offset, molIndex, exI, exJ, tempEx;
709  bond_pair* the_bonds;
710  BondStamp* current_bond;
1122  
1123 <  the_bonds = new bond_pair[tot_bonds];
1124 <  index = 0;
1125 <  offset = 0;
1126 <  molIndex = 0;
716 <
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;
730 <          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  
732          exI = the_bonds[index].a;
733          exJ = the_bonds[index].b;
734
735          // exclude_I must always be the smaller of the pair
736          if( exI > exJ ){
737            tempEx = exI;
738            exI = exJ;
739            exJ = tempEx;
740          }
1147  
742          
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;
753 <          the_excludes[index*2 + 1] = exJ + 1;
754 <          // fortran index from 1 (hence the +1 in the indexing)
755 < #endif  //is_mpi
756 <          
757 <          // increment the index and repeat;
758 <          index++;
759 <        }
760 <        offset += comp_stamps[i]->getNAtoms();
761 <        
762 < #ifdef IS_MPI
763 <      }
764 < #endif //is_mpi
765 <      
766 <      molIndex++;
767 <    }      
768 <  }
1156 >  mpiSim = new mpiSimulation( info );
1157 >  
1158 >  globalIndex = mpiSim->divideLabor();
1159  
1160 <  the_ff->initializeBonds( the_bonds );
771 < }
772 <
773 < void SimSetup::makeBends( void ){
774 <
775 <  int i, j, k, index, offset, molIndex, exI, exJ, tempEx;
776 <  bend_set* the_bends;
777 <  BendStamp* current_bend;
778 <  LinkedAssign* extras;
779 <  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];
783 <  index = 0;
784 <  offset = 0;
785 <  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
791 <      if( mpiSim->getMyMolStart() <= molIndex &&
792 <          molIndex <= mpiSim->getMyMolEnd() ){
793 < #endif // is_mpi        
794 <
795 <        for( k=0; k<comp_stamps[i]->getNBends(); k++ ){
796 <          
797 <          current_bend = comp_stamps[i]->getBend( k );
798 <          the_bends[index].a = current_bend->getA() + offset;
799 <          the_bends[index].b = current_bend->getB() + offset;
800 <          the_bends[index].c = current_bend->getC() + offset;
801 <          
802 <          if( current_bend->haveExtras() ){
803 <            
804 <            extras = current_bend->getExtras();
805 <            current_extra = extras;
806 <            
807 <            while( current_extra != NULL ){
808 <              if( !strcmp( current_extra->getlhs(), "ghostVectorSource" )){
809 <                
810 <                switch( current_extra->getType() ){
811 <                  
812 <                case 0:
813 <                  the_bends[index].ghost =
814 <                    current_extra->getInt() + offset;
815 <                  the_bends[index].isGhost = 1;
816 <                  break;
817 <                  
818 <                case 1:
819 <                  the_bends[index].ghost =
820 <                    (int)current_extra->getDouble() + offset;
821 <                  the_bends[index].isGhost = 1;
822 <                  break;
823 <                  
824 <                default:
825 <                  sprintf( painCave.errMsg,
826 <                           "SimSetup Error: ghostVectorSource was neiter a "
827 <                           "double nor an int.\n"
828 <                           "-->Bend[%d] in %s\n",
829 <                           k, comp_stamps[i]->getID() );
830 <                  painCave.isFatal = 1;
831 <                  simError();
832 <                }
833 <              }
834 <              
835 <              else{
836 <                
837 <                sprintf( painCave.errMsg,
838 <                         "SimSetup Error: unhandled bend assignment:\n"
839 <                         "    -->%s in Bend[%d] in %s\n",
840 <                         current_extra->getlhs(),
841 <                         k, comp_stamps[i]->getID() );
842 <                painCave.isFatal = 1;
843 <                simError();
844 <              }
845 <              
846 <              current_extra = current_extra->getNext();
847 <            }
848 <          }
849 <          
850 <          if( !the_bends[index].isGhost ){
851 <            
852 <            exI = the_bends[index].a;
853 <            exJ = the_bends[index].c;
854 <          }
855 <          else{
856 <            
857 <            exI = the_bends[index].a;
858 <            exJ = the_bends[index].b;
859 <          }
860 <          
861 <          // exclude_I must always be the smaller of the pair
862 <          if( exI > exJ ){
863 <            tempEx = exI;
864 <            exI = exJ;
865 <            exJ = tempEx;
866 <          }
867 <
868 <
869 < #ifdef IS_MPI
870 <
871 <          the_excludes[(index + tot_bonds)*2] =    
872 <            the_atoms[exI]->getGlobalIndex() + 1;
873 <          the_excludes[(index + tot_bonds)*2 + 1] =
874 <            the_atoms[exJ]->getGlobalIndex() + 1;
875 <          
876 < #else  // isn't MPI
877 <          
878 <          the_excludes[(index + tot_bonds)*2] =     exI + 1;
879 <          the_excludes[(index + tot_bonds)*2 + 1] = exJ + 1;
880 <          // fortran index from 1 (hence the +1 in the indexing)
881 < #endif  //is_mpi
882 <          
883 <          
884 <          // increment the index and repeat;
885 <          index++;
886 <        }
887 <        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        }
891 #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  
904  the_ff->initializeBends( the_bends );
905 }
1220  
1221 < void SimSetup::makeTorsions( void ){
1221 > void SimSetup::makeSysArrays( void ){
1222 >  int i, j, k;
1223  
909  int i, j, k, index, offset, molIndex, exI, exJ, tempEx;
910  torsion_set* the_torsions;
911  TorsionStamp* current_torsion;
1224  
1225 <  the_torsions = new torsion_set[tot_torsions];
914 <  index = 0;
915 <  offset = 0;
916 <  molIndex = 0;
917 <  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
922 <      if( mpiSim->getMyMolStart() <= molIndex &&
923 <          molIndex <= mpiSim->getMyMolEnd() ){
924 < #endif // is_mpi        
1232 >  // initialize the molecule's stampID's
1233  
926      for( k=0; k<comp_stamps[i]->getNTorsions(); k++ ){
927
928        current_torsion = comp_stamps[i]->getTorsion( k );
929        the_torsions[index].a = current_torsion->getA() + offset;
930        the_torsions[index].b = current_torsion->getB() + offset;
931        the_torsions[index].c = current_torsion->getC() + offset;
932        the_torsions[index].d = current_torsion->getD() + offset;
933
934        exI = the_torsions[index].a;
935        exJ = the_torsions[index].d;
936
937        
938        // exclude_I must always be the smaller of the pair
939        if( exI > exJ ){
940          tempEx = exI;
941          exI = exJ;
942          exJ = tempEx;
943        }
944
945
1234   #ifdef IS_MPI
1235 <        
948 <        the_excludes[(index + tot_bonds + tot_bends)*2] =    
949 <          the_atoms[exI]->getGlobalIndex() + 1;
950 <        the_excludes[(index + tot_bonds + tot_bends)*2 + 1] =
951 <          the_atoms[exJ]->getGlobalIndex() + 1;
952 <        
953 < #else  // isn't MPI
954 <        
955 <        the_excludes[(index + tot_bonds + tot_bends)*2] =     exI + 1;
956 <        the_excludes[(index + tot_bonds + tot_bends)*2 + 1] = exJ + 1;
957 <        // fortran indexes from 1 (hence the +1 in the indexing)
958 < #endif  //is_mpi
959 <        
1235 >  
1236  
1237 <        // increment the index and repeat;
1238 <        index++;
1239 <      }
1240 <      offset += comp_stamps[i]->getNAtoms();
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 < #ifdef IS_MPI
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        }
968 #endif //is_mpi      
969
1261        molIndex++;
1262      }
1263    }
1264 +    
1265  
1266 <  the_ff->initializeTorsions( the_torsions );
975 < }
1266 > #endif // is_mpi
1267  
977 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;
986 <
987 <  temp1 = (double)tot_nmol / 4.0;
988 <  temp2 = pow( temp1, ( 1.0 / 3.0 ) );
989 <  temp3 = ceil( temp2 );
990 <
991 <  have_extra =0;
992 <  if( temp2 < temp3 ){ // we have a non-complete lattice
993 <    have_extra =1;
994 <
995 <    n_cells = (int)temp3 - 1;
996 <    cellx = simnfo->box_x / temp3;
997 <    celly = simnfo->box_y / temp3;
998 <    cellz = simnfo->box_z / temp3;
999 <    n_extra = tot_nmol - ( 4 * n_cells * n_cells * n_cells );
1000 <    temp1 = ((double)n_extra) / ( pow( temp3, 3.0 ) - pow( n_cells, 3.0 ) );
1001 <    n_per_extra = (int)ceil( temp1 );
1002 <
1003 <    if( n_per_extra > 4){
1004 <      sprintf( painCave.errMsg,
1005 <               "SimSetup error. There has been an error in constructing"
1006 <               " the non-complete lattice.\n" );
1007 <      painCave.isFatal = 1;
1008 <      simError();
1009 <    }
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;
1019 <  current_comp_mol = 0;
1020 <  current_comp = 0;
1021 <  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,
1028 <                     j * celly,
1029 <                     k * cellz );
1295 >  the_ff->setSimInfo( info );
1296  
1297 <        makeElement( i * cellx + 0.5 * cellx,
1032 <                     j * celly + 0.5 * celly,
1033 <                     k * cellz );
1297 > }
1298  
1299 <        makeElement( i * cellx,
1036 <                     j * celly + 0.5 * celly,
1037 <                     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 <    }
1044 <  }
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 ){
1047 <    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;
1057 <          }
1058 <          else start_ndx = 0;
1059 <        }
1060 <        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 );
1067 <          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){
1084 <            makeElement( i * cellx + 0.5 * cellx,
1085 <                         j * celly,
1086 <                         k * cellz + 0.5 * cellz );
1087 <            done = ( current_mol >= tot_nmol );
1088 <          }
1089 <        }
1090 <      }
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"
1116 <               "\tThe initialization routine is unable to give a start"
1117 <               " position.\n",
1118 <               comp_stamps[current_comp]->getID(),
1119 <               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;
1137 <      rotMat[1][1] = 1.0;
1138 <      rotMat[1][2] = 0.0;
1476 > }
1477  
1478 <      rotMat[2][0] = 0.0;
1141 <      rotMat[2][1] = 0.0;
1142 <      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  
1150  current_mol++;
1151  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  
1155    current_comp_mol = 0;
1156    current_comp++;
1157  }
1503   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines