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 614 by mmeineke, Tue Jul 15 17:57:04 2003 UTC vs.
Revision 707 by mmeineke, Wed Aug 20 19:42:31 2003 UTC

# Line 1 | Line 1
1 + #include <algorithm>
2   #include <cstdlib>
3   #include <iostream>
4   #include <cmath>
5 + #include <string>
6  
7   #include "SimSetup.hpp"
8 + #include "ReadWrite.hpp"
9   #include "parse_me.h"
10   #include "Integrator.hpp"
11   #include "simError.h"
# Line 14 | Line 17
17  
18   // some defines for ensemble and Forcefield  cases
19  
20 < #define NVE_ENS   0
21 < #define NVT_ENS   1
22 < #define NPTi_ENS  2
23 < #define NPTf_ENS  3
24 < #define NPTim_ENS 4
25 < #define NPTfm_ENS 5
20 > #define NVE_ENS        0
21 > #define NVT_ENS        1
22 > #define NPTi_ENS       2
23 > #define NPTf_ENS       3
24 > #define NPTim_ENS      4
25 > #define NPTfm_ENS      5
26  
24
27   #define FF_DUFF 0
28   #define FF_LJ   1
29 + #define FF_EAM  2
30  
31 + using namespace std;
32  
33   SimSetup::SimSetup(){
34 +  
35 +  isInfoArray = 0;
36 +  nInfo = 1;
37 +  
38    stamps = new MakeStamps();
39    globals = new Globals();
40    
41 +  
42   #ifdef IS_MPI
43    strcpy( checkPointMsg, "SimSetup creation successful" );
44    MPIcheckPoint();
# Line 41 | Line 50 | void SimSetup::parseFile( char* fileName ){
50    delete globals;
51   }
52  
53 + void SimSetup::setSimInfo( SimInfo* the_info, int theNinfo ) {
54 +    info = the_info;
55 +    nInfo = theNinfo;
56 +    isInfoArray = 1;
57 + }
58 +
59 +
60   void SimSetup::parseFile( char* fileName ){
61  
62   #ifdef IS_MPI
# Line 76 | Line 92 | void SimSetup::createSim( void ){
92  
93   #endif // is_mpi
94  
95 < void SimSetup::createSim( void ){
95 > void SimSetup::createSim(void){
96  
81  MakeStamps *the_stamps;
82  Globals* the_globals;
97    int i, j, k, globalAtomIndex;
98    
99    // gather all of the information from the Bass file
100 <  
100 >
101    gatherInfo();
102  
103    // creation of complex system objects
104  
105    sysObjectsCreation();
106  
93
94
95  // initialize the arrays
96
97
98
99  makeMolecules();
100  info->identArray = new int[info->n_atoms];
101  for(i=0; i<info->n_atoms; i++){
102    info->identArray[i] = the_atoms[i]->getIdent();
103  }
104  
105
107    // check on the post processing info
108 <  
108 >
109    finalInfoCheck();
110  
110
111
112
111    // initialize the system coordinates
112  
113 <  initSystemCoords();
116 <  
113 >  if( !isInfoArray ) initSystemCoords();  
114  
115    // make the output filenames
116  
117    makeOutNames();
118    
122
123  
124
125  
126
127  
128
129
119    // make the integrator
120    
121 +  makeIntegrator();
122    
133  NVT*  myNVT = NULL;
134  NPTi* myNPTi = NULL;
135  NPTf* myNPTf = NULL;
136  NPTim* myNPTim = NULL;
137  NPTfm* myNPTfm = NULL;
138
139  switch( ensembleCase ){
140
141  case NVE_ENS:
142    new NVE( info, the_ff );
143    break;
144
145  case NVT_ENS:
146    myNVT = new NVT( info, the_ff );
147    myNVT->setTargetTemp(the_globals->getTargetTemp());
148
149    if (the_globals->haveTauThermostat())
150      myNVT->setTauThermostat(the_globals->getTauThermostat());
151
152    else {
153      sprintf( painCave.errMsg,
154               "SimSetup error: If you use the NVT\n"
155               "    ensemble, you must set tauThermostat.\n");
156      painCave.isFatal = 1;
157      simError();
158    }
159    break;
160
161  case NPTi_ENS:
162    myNPTi = new NPTi( info, the_ff );
163    myNPTi->setTargetTemp( the_globals->getTargetTemp() );
164
165    if (the_globals->haveTargetPressure())
166      myNPTi->setTargetPressure(the_globals->getTargetPressure());
167    else {
168      sprintf( painCave.errMsg,
169               "SimSetup error: If you use a constant pressure\n"
170               "    ensemble, you must set targetPressure in the BASS file.\n");
171      painCave.isFatal = 1;
172      simError();
173    }
174    
175    if( the_globals->haveTauThermostat() )
176      myNPTi->setTauThermostat( the_globals->getTauThermostat() );
177    else{
178      sprintf( painCave.errMsg,
179               "SimSetup error: If you use an NPT\n"
180               "    ensemble, you must set tauThermostat.\n");
181      painCave.isFatal = 1;
182      simError();
183    }
184
185    if( the_globals->haveTauBarostat() )
186      myNPTi->setTauBarostat( the_globals->getTauBarostat() );
187    else{
188      sprintf( painCave.errMsg,
189               "SimSetup error: If you use an NPT\n"
190               "    ensemble, you must set tauBarostat.\n");
191      painCave.isFatal = 1;
192      simError();
193    }
194    break;
195
196  case NPTf_ENS:
197    myNPTf = new NPTf( info, the_ff );
198    myNPTf->setTargetTemp( the_globals->getTargetTemp());
199
200    if (the_globals->haveTargetPressure())
201      myNPTf->setTargetPressure(the_globals->getTargetPressure());
202    else {
203      sprintf( painCave.errMsg,
204               "SimSetup error: If you use a constant pressure\n"
205               "    ensemble, you must set targetPressure in the BASS file.\n");
206      painCave.isFatal = 1;
207      simError();
208    }    
209
210    if( the_globals->haveTauThermostat() )
211      myNPTf->setTauThermostat( the_globals->getTauThermostat() );
212    else{
213      sprintf( painCave.errMsg,
214               "SimSetup error: If you use an NPT\n"
215               "    ensemble, you must set tauThermostat.\n");
216      painCave.isFatal = 1;
217      simError();
218    }
219
220    if( the_globals->haveTauBarostat() )
221      myNPTf->setTauBarostat( the_globals->getTauBarostat() );
222    else{
223      sprintf( painCave.errMsg,
224               "SimSetup error: If you use an NPT\n"
225               "    ensemble, you must set tauBarostat.\n");
226      painCave.isFatal = 1;
227      simError();
228    }
229    break;
230    
231  case NPTim_ENS:
232    myNPTim = new NPTim( info, the_ff );
233    myNPTim->setTargetTemp( the_globals->getTargetTemp());
234
235    if (the_globals->haveTargetPressure())
236      myNPTim->setTargetPressure(the_globals->getTargetPressure());
237    else {
238      sprintf( painCave.errMsg,
239               "SimSetup error: If you use a constant pressure\n"
240               "    ensemble, you must set targetPressure in the BASS file.\n");
241      painCave.isFatal = 1;
242      simError();
243    }
244    
245    if( the_globals->haveTauThermostat() )
246      myNPTim->setTauThermostat( the_globals->getTauThermostat() );
247    else{
248      sprintf( painCave.errMsg,
249               "SimSetup error: If you use an NPT\n"
250               "    ensemble, you must set tauThermostat.\n");
251      painCave.isFatal = 1;
252      simError();
253    }
254
255    if( the_globals->haveTauBarostat() )
256      myNPTim->setTauBarostat( the_globals->getTauBarostat() );
257    else{
258      sprintf( painCave.errMsg,
259               "SimSetup error: If you use an NPT\n"
260               "    ensemble, you must set tauBarostat.\n");
261      painCave.isFatal = 1;
262      simError();
263    }
264    break;
265
266  case NPTfm_ENS:
267    myNPTfm = new NPTfm( info, the_ff );
268    myNPTfm->setTargetTemp( the_globals->getTargetTemp());
269
270    if (the_globals->haveTargetPressure())
271      myNPTfm->setTargetPressure(the_globals->getTargetPressure());
272    else {
273      sprintf( painCave.errMsg,
274               "SimSetup error: If you use a constant pressure\n"
275               "    ensemble, you must set targetPressure in the BASS file.\n");
276      painCave.isFatal = 1;
277      simError();
278    }
279    
280    if( the_globals->haveTauThermostat() )
281      myNPTfm->setTauThermostat( the_globals->getTauThermostat() );
282    else{
283      sprintf( painCave.errMsg,
284               "SimSetup error: If you use an NPT\n"
285               "    ensemble, you must set tauThermostat.\n");
286      painCave.isFatal = 1;
287      simError();
288    }
289
290    if( the_globals->haveTauBarostat() )
291      myNPTfm->setTauBarostat( the_globals->getTauBarostat() );
292    else{
293      sprintf( painCave.errMsg,
294               "SimSetup error: If you use an NPT\n"
295               "    ensemble, you must set tauBarostat.\n");
296      painCave.isFatal = 1;
297      simError();
298    }
299    break;
300
301  default:
302    sprintf( painCave.errMsg,
303             "SimSetup Error. Unrecognized ensemble in case statement.\n");
304    painCave.isFatal = 1;
305    simError();
306  }
307
308
123   #ifdef IS_MPI
124    mpiSim->mpiRefresh();
125   #endif
126  
127    // initialize the Fortran
128  
129 +  initFortran();
130  
316  info->refreshSim();
317  
318  if( !strcmp( info->mixingRule, "standard") ){
319    the_ff->initForceField( LB_MIXING_RULE );
320  }
321  else if( !strcmp( info->mixingRule, "explicit") ){
322    the_ff->initForceField( EXPLICIT_MIXING_RULE );
323  }
324  else{
325    sprintf( painCave.errMsg,
326             "SimSetup Error: unknown mixing rule -> \"%s\"\n",
327             info->mixingRule );
328    painCave.isFatal = 1;
329    simError();
330  }
131  
132  
333 #ifdef IS_MPI
334  strcpy( checkPointMsg,
335          "Successfully intialized the mixingRule for Fortran." );
336  MPIcheckPoint();
337 #endif // is_mpi
133   }
134  
135  
136   void SimSetup::makeMolecules( void ){
137  
138 +  int k,l;
139    int i, j, exI, exJ, tempEx, stampID, atomOffset, excludeOffset;
140 <  molInit info;
140 >  molInit molInfo;
141    DirectionalAtom* dAtom;
142    LinkedAssign* extras;
143    LinkedAssign* current_extra;
# Line 364 | Line 160 | void SimSetup::makeMolecules( void ){
160  
161    double ux, uy, uz, u, uSqr;
162    
163 <  atomOffset = 0;
368 <  excludeOffset = 0;
369 <  for(i=0; i<info->n_mol; i++){
163 >  for(k=0; k<nInfo; k++){
164      
165 <    stampID = the_molecules[i].getStampID();
165 >    the_ff->setSimInfo( &(info[k]) );
166  
167 <    info.nAtoms    = comp_stamps[stampID]->getNAtoms();
168 <    info.nBonds    = comp_stamps[stampID]->getNBonds();
169 <    info.nBends    = comp_stamps[stampID]->getNBends();
170 <    info.nTorsions = comp_stamps[stampID]->getNTorsions();
171 <    info.nExcludes = info.nBonds + info.nBends + info.nTorsions;
378 <
379 <    info.myAtoms = &the_atoms[atomOffset];
380 <    info.myExcludes = &the_excludes[excludeOffset];
381 <    info.myBonds = new Bond*[info.nBonds];
382 <    info.myBends = new Bend*[info.nBends];
383 <    info.myTorsions = new Torsion*[info.nTorsions];
167 >    atomOffset = 0;
168 >    excludeOffset = 0;
169 >    for(i=0; i<info[k].n_mol; i++){
170 >    
171 >      stampID = info[k].molecules[i].getStampID();
172  
173 <    theBonds = new bond_pair[info.nBonds];
174 <    theBends = new bend_set[info.nBends];
175 <    theTorsions = new torsion_set[info.nTorsions];
173 >      molInfo.nAtoms    = comp_stamps[stampID]->getNAtoms();
174 >      molInfo.nBonds    = comp_stamps[stampID]->getNBonds();
175 >      molInfo.nBends    = comp_stamps[stampID]->getNBends();
176 >      molInfo.nTorsions = comp_stamps[stampID]->getNTorsions();
177 >      molInfo.nExcludes = molInfo.nBonds + molInfo.nBends + molInfo.nTorsions;
178 >      
179 >      molInfo.myAtoms = &(info[k].atoms[atomOffset]);
180 >      molInfo.myExcludes = &(info[k].excludes[excludeOffset]);
181 >      molInfo.myBonds = new Bond*[molInfo.nBonds];
182 >      molInfo.myBends = new Bend*[molInfo.nBends];
183 >      molInfo.myTorsions = new Torsion*[molInfo.nTorsions];
184 >
185 >      theBonds = new bond_pair[molInfo.nBonds];
186 >      theBends = new bend_set[molInfo.nBends];
187 >      theTorsions = new torsion_set[molInfo.nTorsions];
188      
189 <    // make the Atoms
189 >      // make the Atoms
190      
191 <    for(j=0; j<info.nAtoms; j++){
192 <      
193 <      currentAtom = comp_stamps[stampID]->getAtom( j );
194 <      if( currentAtom->haveOrientation() ){
395 <        
396 <        dAtom = new DirectionalAtom(j + atomOffset);
397 <        info->n_oriented++;
398 <        info.myAtoms[j] = dAtom;
399 <        
400 <        ux = currentAtom->getOrntX();
401 <        uy = currentAtom->getOrntY();
402 <        uz = currentAtom->getOrntZ();
403 <        
404 <        uSqr = (ux * ux) + (uy * uy) + (uz * uz);
405 <        
406 <        u = sqrt( uSqr );
407 <        ux = ux / u;
408 <        uy = uy / u;
409 <        uz = uz / u;
410 <        
411 <        dAtom->setSUx( ux );
412 <        dAtom->setSUy( uy );
413 <        dAtom->setSUz( uz );
414 <      }
415 <      else{
416 <        info.myAtoms[j] = new GeneralAtom(j + atomOffset);
417 <      }
418 <      info.myAtoms[j]->setType( currentAtom->getType() );
191 >      for(j=0; j<molInfo.nAtoms; j++){
192 >  
193 >  currentAtom = comp_stamps[stampID]->getAtom( j );
194 >  if( currentAtom->haveOrientation() ){
195      
196 +    dAtom = new DirectionalAtom( (j + atomOffset),
197 +               info[k].getConfiguration() );
198 +    info[k].n_oriented++;
199 +    molInfo.myAtoms[j] = dAtom;
200 +    
201 +    ux = currentAtom->getOrntX();
202 +    uy = currentAtom->getOrntY();
203 +    uz = currentAtom->getOrntZ();
204 +    
205 +    uSqr = (ux * ux) + (uy * uy) + (uz * uz);
206 +    
207 +    u = sqrt( uSqr );
208 +    ux = ux / u;
209 +    uy = uy / u;
210 +    uz = uz / u;
211 +    
212 +    dAtom->setSUx( ux );
213 +    dAtom->setSUy( uy );
214 +    dAtom->setSUz( uz );
215 +  }
216 +  else{
217 +    molInfo.myAtoms[j] = new GeneralAtom( (j + atomOffset),
218 +            info[k].getConfiguration() );
219 +  }
220 +  molInfo.myAtoms[j]->setType( currentAtom->getType() );
221 +    
222   #ifdef IS_MPI
223        
224 <      info.myAtoms[j]->setGlobalIndex( globalIndex[j+atomOffset] );
224 >  molInfo.myAtoms[j]->setGlobalIndex( globalIndex[j+atomOffset] );
225        
226   #endif // is_mpi
227 <    }
227 >      }
228      
229      // make the bonds
230 <    for(j=0; j<info.nBonds; j++){
230 >      for(j=0; j<molInfo.nBonds; j++){
231        
232 <      currentBond = comp_stamps[stampID]->getBond( j );
233 <      theBonds[j].a = currentBond->getA() + atomOffset;
234 <      theBonds[j].b = currentBond->getB() + atomOffset;
235 <
236 <      exI = theBonds[j].a;
237 <      exJ = theBonds[j].b;
238 <
239 <      // exclude_I must always be the smaller of the pair
240 <      if( exI > exJ ){
241 <        tempEx = exI;
242 <        exI = exJ;
243 <        exJ = tempEx;
244 <      }
232 >  currentBond = comp_stamps[stampID]->getBond( j );
233 >  theBonds[j].a = currentBond->getA() + atomOffset;
234 >  theBonds[j].b = currentBond->getB() + atomOffset;
235 >  
236 >  exI = theBonds[j].a;
237 >  exJ = theBonds[j].b;
238 >  
239 >  // exclude_I must always be the smaller of the pair
240 >  if( exI > exJ ){
241 >    tempEx = exI;
242 >    exI = exJ;
243 >    exJ = tempEx;
244 >  }
245   #ifdef IS_MPI
246 <      tempEx = exI;
247 <      exI = the_atoms[tempEx]->getGlobalIndex() + 1;
248 <      tempEx = exJ;
249 <      exJ = the_atoms[tempEx]->getGlobalIndex() + 1;
250 <      
251 <      the_excludes[j+excludeOffset]->setPair( exI, exJ );
246 >  tempEx = exI;
247 >  exI = info[k].atoms[tempEx]->getGlobalIndex() + 1;
248 >  tempEx = exJ;
249 >  exJ = info[k].atoms[tempEx]->getGlobalIndex() + 1;
250 >  
251 >  info[k].excludes[j+excludeOffset]->setPair( exI, exJ );
252   #else  // isn't MPI
253 <
254 <      the_excludes[j+excludeOffset]->setPair( (exI+1), (exJ+1) );
253 >  
254 >  info[k].excludes[j+excludeOffset]->setPair( (exI+1), (exJ+1) );
255   #endif  //is_mpi
454    }
455    excludeOffset += info.nBonds;
456
457    //make the bends
458    for(j=0; j<info.nBends; j++){
459      
460      currentBend = comp_stamps[stampID]->getBend( j );
461      theBends[j].a = currentBend->getA() + atomOffset;
462      theBends[j].b = currentBend->getB() + atomOffset;
463      theBends[j].c = currentBend->getC() + atomOffset;
464          
465      if( currentBend->haveExtras() ){
466            
467        extras = currentBend->getExtras();
468        current_extra = extras;
469            
470        while( current_extra != NULL ){
471          if( !strcmp( current_extra->getlhs(), "ghostVectorSource" )){
472                
473            switch( current_extra->getType() ){
474              
475            case 0:
476              theBends[j].ghost =
477                current_extra->getInt() + atomOffset;
478              theBends[j].isGhost = 1;
479              break;
480                  
481            case 1:
482              theBends[j].ghost =
483                (int)current_extra->getDouble() + atomOffset;
484              theBends[j].isGhost = 1;
485              break;
486              
487            default:
488              sprintf( painCave.errMsg,
489                       "SimSetup Error: ghostVectorSource was neither a "
490                       "double nor an int.\n"
491                       "-->Bend[%d] in %s\n",
492                       j, comp_stamps[stampID]->getID() );
493              painCave.isFatal = 1;
494              simError();
495            }
496          }
497          
498          else{
499            
500            sprintf( painCave.errMsg,
501                     "SimSetup Error: unhandled bend assignment:\n"
502                     "    -->%s in Bend[%d] in %s\n",
503                     current_extra->getlhs(),
504                     j, comp_stamps[stampID]->getID() );
505            painCave.isFatal = 1;
506            simError();
507          }
508          
509          current_extra = current_extra->getNext();
510        }
256        }
257 <          
513 <      if( !theBends[j].isGhost ){
514 <            
515 <        exI = theBends[j].a;
516 <        exJ = theBends[j].c;
517 <      }
518 <      else{
519 <        
520 <        exI = theBends[j].a;
521 <        exJ = theBends[j].b;
522 <      }
257 >      excludeOffset += molInfo.nBonds;
258        
259 <      // exclude_I must always be the smaller of the pair
260 <      if( exI > exJ ){
261 <        tempEx = exI;
262 <        exI = exJ;
263 <        exJ = tempEx;
259 >      //make the bends
260 >      for(j=0; j<molInfo.nBends; j++){
261 >  
262 >  currentBend = comp_stamps[stampID]->getBend( j );
263 >  theBends[j].a = currentBend->getA() + atomOffset;
264 >  theBends[j].b = currentBend->getB() + atomOffset;
265 >  theBends[j].c = currentBend->getC() + atomOffset;
266 >  
267 >  if( currentBend->haveExtras() ){
268 >    
269 >    extras = currentBend->getExtras();
270 >    current_extra = extras;
271 >    
272 >    while( current_extra != NULL ){
273 >      if( !strcmp( current_extra->getlhs(), "ghostVectorSource" )){
274 >        
275 >        switch( current_extra->getType() ){
276 >    
277 >        case 0:
278 >    theBends[j].ghost =
279 >      current_extra->getInt() + atomOffset;
280 >    theBends[j].isGhost = 1;
281 >    break;
282 >    
283 >        case 1:
284 >    theBends[j].ghost =
285 >      (int)current_extra->getDouble() + atomOffset;
286 >    theBends[j].isGhost = 1;
287 >    break;
288 >    
289 >        default:
290 >    sprintf( painCave.errMsg,
291 >       "SimSetup Error: ghostVectorSource was neither a "
292 >       "double nor an int.\n"
293 >       "-->Bend[%d] in %s\n",
294 >       j, comp_stamps[stampID]->getID() );
295 >    painCave.isFatal = 1;
296 >    simError();
297 >        }
298        }
530 #ifdef IS_MPI
531      tempEx = exI;
532      exI = the_atoms[tempEx]->getGlobalIndex() + 1;
533      tempEx = exJ;
534      exJ = the_atoms[tempEx]->getGlobalIndex() + 1;
299        
300 <      the_excludes[j+excludeOffset]->setPair( exI, exJ );
301 < #else  // isn't MPI
302 <      the_excludes[j+excludeOffset]->setPair( (exI+1), (exJ+1) );
303 < #endif  //is_mpi
300 >      else{
301 >        
302 >        sprintf( painCave.errMsg,
303 >           "SimSetup Error: unhandled bend assignment:\n"
304 >           "    -->%s in Bend[%d] in %s\n",
305 >           current_extra->getlhs(),
306 >           j, comp_stamps[stampID]->getID() );
307 >        painCave.isFatal = 1;
308 >        simError();
309 >      }
310 >      
311 >      current_extra = current_extra->getNext();
312      }
313 <    excludeOffset += info.nBends;
314 <
315 <    for(j=0; j<info.nTorsions; j++){
313 >  }
314 >  
315 >  if( !theBends[j].isGhost ){
316 >    
317 >    exI = theBends[j].a;
318 >    exJ = theBends[j].c;
319 >  }
320 >  else{
321 >    
322 >    exI = theBends[j].a;
323 >    exJ = theBends[j].b;
324 >  }
325 >  
326 >  // exclude_I must always be the smaller of the pair
327 >  if( exI > exJ ){
328 >    tempEx = exI;
329 >    exI = exJ;
330 >    exJ = tempEx;
331 >  }
332 > #ifdef IS_MPI
333 >  tempEx = exI;
334 >  exI = info[k].atoms[tempEx]->getGlobalIndex() + 1;
335 >  tempEx = exJ;
336 >  exJ = info[k].atoms[tempEx]->getGlobalIndex() + 1;
337        
338 <      currentTorsion = comp_stamps[stampID]->getTorsion( j );
339 <      theTorsions[j].a = currentTorsion->getA() + atomOffset;
340 <      theTorsions[j].b = currentTorsion->getB() + atomOffset;
341 <      theTorsions[j].c = currentTorsion->getC() + atomOffset;
549 <      theTorsions[j].d = currentTorsion->getD() + atomOffset;
550 <      
551 <      exI = theTorsions[j].a;
552 <      exJ = theTorsions[j].d;
553 <
554 <      // exclude_I must always be the smaller of the pair
555 <      if( exI > exJ ){
556 <        tempEx = exI;
557 <        exI = exJ;
558 <        exJ = tempEx;
338 >  info[k].excludes[j+excludeOffset]->setPair( exI, exJ );
339 > #else  // isn't MPI
340 >  info[k].excludes[j+excludeOffset]->setPair( (exI+1), (exJ+1) );
341 > #endif  //is_mpi
342        }
343 < #ifdef IS_MPI
561 <      tempEx = exI;
562 <      exI = the_atoms[tempEx]->getGlobalIndex() + 1;
563 <      tempEx = exJ;
564 <      exJ = the_atoms[tempEx]->getGlobalIndex() + 1;
343 >      excludeOffset += molInfo.nBends;
344        
345 <      the_excludes[j+excludeOffset]->setPair( exI, exJ );
345 >      for(j=0; j<molInfo.nTorsions; j++){
346 >  
347 >  currentTorsion = comp_stamps[stampID]->getTorsion( j );
348 >  theTorsions[j].a = currentTorsion->getA() + atomOffset;
349 >  theTorsions[j].b = currentTorsion->getB() + atomOffset;
350 >  theTorsions[j].c = currentTorsion->getC() + atomOffset;
351 >  theTorsions[j].d = currentTorsion->getD() + atomOffset;
352 >  
353 >  exI = theTorsions[j].a;
354 >  exJ = theTorsions[j].d;
355 >  
356 >  // exclude_I must always be the smaller of the pair
357 >  if( exI > exJ ){
358 >    tempEx = exI;
359 >    exI = exJ;
360 >    exJ = tempEx;
361 >  }
362 > #ifdef IS_MPI
363 >  tempEx = exI;
364 >  exI = info[k].atoms[tempEx]->getGlobalIndex() + 1;
365 >  tempEx = exJ;
366 >  exJ = info[k].atoms[tempEx]->getGlobalIndex() + 1;
367 >  
368 >  info[k].excludes[j+excludeOffset]->setPair( exI, exJ );
369   #else  // isn't MPI
370 <      the_excludes[j+excludeOffset]->setPair( (exI+1), (exJ+1) );
370 >  info[k].excludes[j+excludeOffset]->setPair( (exI+1), (exJ+1) );
371   #endif  //is_mpi
372 <    }
373 <    excludeOffset += info.nTorsions;
372 >      }
373 >      excludeOffset += molInfo.nTorsions;
374 >      
375 >      
376 >      // send the arrays off to the forceField for init.
377 >      
378 >      the_ff->initializeAtoms( molInfo.nAtoms, molInfo.myAtoms );
379 >      the_ff->initializeBonds( molInfo.nBonds, molInfo.myBonds, theBonds );
380 >      the_ff->initializeBends( molInfo.nBends, molInfo.myBends, theBends );
381 >      the_ff->initializeTorsions( molInfo.nTorsions, molInfo.myTorsions, theTorsions );
382 >      
383 >      
384 >      info[k].molecules[i].initialize( molInfo );
385  
386 <    
387 <    // send the arrays off to the forceField for init.
388 <
389 <    the_ff->initializeAtoms( info.nAtoms, info.myAtoms );
390 <    the_ff->initializeBonds( info.nBonds, info.myBonds, theBonds );
391 <    the_ff->initializeBends( info.nBends, info.myBends, theBends );
579 <    the_ff->initializeTorsions( info.nTorsions, info.myTorsions, theTorsions );
580 <
581 <
582 <    the_molecules[i].initialize( info );
583 <
584 <
585 <    atomOffset += info.nAtoms;
586 <    delete[] theBonds;
587 <    delete[] theBends;
588 <    delete[] theTorsions;
386 >      
387 >      atomOffset += molInfo.nAtoms;
388 >      delete[] theBonds;
389 >      delete[] theBends;
390 >      delete[] theTorsions;
391 >    }
392    }
393 <
393 >  
394   #ifdef IS_MPI
395    sprintf( checkPointMsg, "all molecules initialized succesfully" );
396    MPIcheckPoint();
397   #endif // is_mpi
398 <
398 >  
399    // clean up the forcefield
400 +
401    the_ff->calcRcut();
402    the_ff->cleanMe();
403 <
403 >  
404   }
405  
406   void SimSetup::initFromBass( void ){
# Line 609 | Line 413 | void SimSetup::initFromBass( void ){
413    int n_extra;
414    int have_extra, done;
415  
416 +  double vel[3];
417 +  vel[0] = 0.0;
418 +  vel[1] = 0.0;
419 +  vel[2] = 0.0;
420 +
421    temp1 = (double)tot_nmol / 4.0;
422    temp2 = pow( temp1, ( 1.0 / 3.0 ) );
423    temp3 = ceil( temp2 );
# Line 618 | Line 427 | void SimSetup::initFromBass( void ){
427      have_extra =1;
428  
429      n_cells = (int)temp3 - 1;
430 <    cellx = info->boxLx / temp3;
431 <    celly = info->boxLy / temp3;
432 <    cellz = info->boxLz / temp3;
430 >    cellx = info[0].boxL[0] / temp3;
431 >    celly = info[0].boxL[1] / temp3;
432 >    cellz = info[0].boxL[2] / temp3;
433      n_extra = tot_nmol - ( 4 * n_cells * n_cells * n_cells );
434      temp1 = ((double)n_extra) / ( pow( temp3, 3.0 ) - pow( n_cells, 3.0 ) );
435      n_per_extra = (int)ceil( temp1 );
436  
437      if( n_per_extra > 4){
438        sprintf( painCave.errMsg,
439 <               "SimSetup error. There has been an error in constructing"
440 <               " the non-complete lattice.\n" );
439 >         "SimSetup error. There has been an error in constructing"
440 >         " the non-complete lattice.\n" );
441        painCave.isFatal = 1;
442        simError();
443      }
444    }
445    else{
446      n_cells = (int)temp3;
447 <    cellx = info->boxLx / temp3;
448 <    celly = info->boxLy / temp3;
449 <    cellz = info->boxLz / temp3;
447 >    cellx = info[0].boxL[0] / temp3;
448 >    celly = info[0].boxL[1] / temp3;
449 >    cellz = info[0].boxL[2] / temp3;
450    }
451  
452    current_mol = 0;
# Line 649 | Line 458 | void SimSetup::initFromBass( void ){
458      for( j=0; j < n_cells; j++ ){
459        for( k=0; k < n_cells; k++ ){
460  
461 <        makeElement( i * cellx,
462 <                     j * celly,
463 <                     k * cellz );
461 >  makeElement( i * cellx,
462 >         j * celly,
463 >         k * cellz );
464  
465 <        makeElement( i * cellx + 0.5 * cellx,
466 <                     j * celly + 0.5 * celly,
467 <                     k * cellz );
465 >  makeElement( i * cellx + 0.5 * cellx,
466 >         j * celly + 0.5 * celly,
467 >         k * cellz );
468  
469 <        makeElement( i * cellx,
470 <                     j * celly + 0.5 * celly,
471 <                     k * cellz + 0.5 * cellz );
469 >  makeElement( i * cellx,
470 >         j * celly + 0.5 * celly,
471 >         k * cellz + 0.5 * cellz );
472  
473 <        makeElement( i * cellx + 0.5 * cellx,
474 <                     j * celly,
475 <                     k * cellz + 0.5 * cellz );
473 >  makeElement( i * cellx + 0.5 * cellx,
474 >         j * celly,
475 >         k * cellz + 0.5 * cellz );
476        }
477      }
478    }
# Line 675 | Line 484 | void SimSetup::initFromBass( void ){
484      for( i=0; i < (n_cells+1) && !done; i++ ){
485        for( j=0; j < (n_cells+1) && !done; j++ ){
486  
487 <        if( i < n_cells ){
487 >  if( i < n_cells ){
488  
489 <          if( j < n_cells ){
490 <            start_ndx = n_cells;
491 <          }
492 <          else start_ndx = 0;
493 <        }
494 <        else start_ndx = 0;
489 >    if( j < n_cells ){
490 >      start_ndx = n_cells;
491 >    }
492 >    else start_ndx = 0;
493 >  }
494 >  else start_ndx = 0;
495  
496 <        for( k=start_ndx; k < (n_cells+1) && !done; k++ ){
496 >  for( k=start_ndx; k < (n_cells+1) && !done; k++ ){
497  
498 <          makeElement( i * cellx,
499 <                       j * celly,
500 <                       k * cellz );
501 <          done = ( current_mol >= tot_nmol );
498 >    makeElement( i * cellx,
499 >           j * celly,
500 >           k * cellz );
501 >    done = ( current_mol >= tot_nmol );
502  
503 <          if( !done && n_per_extra > 1 ){
504 <            makeElement( i * cellx + 0.5 * cellx,
505 <                         j * celly + 0.5 * celly,
506 <                         k * cellz );
507 <            done = ( current_mol >= tot_nmol );
508 <          }
503 >    if( !done && n_per_extra > 1 ){
504 >      makeElement( i * cellx + 0.5 * cellx,
505 >       j * celly + 0.5 * celly,
506 >       k * cellz );
507 >      done = ( current_mol >= tot_nmol );
508 >    }
509  
510 <          if( !done && n_per_extra > 2){
511 <            makeElement( i * cellx,
512 <                         j * celly + 0.5 * celly,
513 <                         k * cellz + 0.5 * cellz );
514 <            done = ( current_mol >= tot_nmol );
515 <          }
510 >    if( !done && n_per_extra > 2){
511 >      makeElement( i * cellx,
512 >       j * celly + 0.5 * celly,
513 >       k * cellz + 0.5 * cellz );
514 >      done = ( current_mol >= tot_nmol );
515 >    }
516  
517 <          if( !done && n_per_extra > 3){
518 <            makeElement( i * cellx + 0.5 * cellx,
519 <                         j * celly,
520 <                         k * cellz + 0.5 * cellz );
521 <            done = ( current_mol >= tot_nmol );
522 <          }
523 <        }
517 >    if( !done && n_per_extra > 3){
518 >      makeElement( i * cellx + 0.5 * cellx,
519 >       j * celly,
520 >       k * cellz + 0.5 * cellz );
521 >      done = ( current_mol >= tot_nmol );
522 >    }
523 >  }
524        }
525      }
526    }
527  
528 <
529 <  for( i=0; i<info->n_atoms; i++ ){
721 <    info->atoms[i]->set_vx( 0.0 );
722 <    info->atoms[i]->set_vy( 0.0 );
723 <    info->atoms[i]->set_vz( 0.0 );
528 >  for( i=0; i<info[0].n_atoms; i++ ){
529 >    info[0].atoms[i]->setVel( vel );
530    }
531   }
532  
# Line 730 | Line 536 | void SimSetup::makeElement( double x, double y, double
536    AtomStamp* current_atom;
537    DirectionalAtom* dAtom;
538    double rotMat[3][3];
539 +  double pos[3];
540  
541    for( k=0; k<comp_stamps[current_comp]->getNAtoms(); k++ ){
542  
543      current_atom = comp_stamps[current_comp]->getAtom( k );
544      if( !current_atom->havePosition() ){
545        sprintf( painCave.errMsg,
546 <               "SimSetup:initFromBass error.\n"
547 <               "\tComponent %s, atom %s does not have a position specified.\n"
548 <               "\tThe initialization routine is unable to give a start"
549 <               " position.\n",
550 <               comp_stamps[current_comp]->getID(),
551 <               current_atom->getType() );
546 >         "SimSetup:initFromBass error.\n"
547 >         "\tComponent %s, atom %s does not have a position specified.\n"
548 >         "\tThe initialization routine is unable to give a start"
549 >         " position.\n",
550 >         comp_stamps[current_comp]->getID(),
551 >         current_atom->getType() );
552        painCave.isFatal = 1;
553        simError();
554      }
555 +    
556 +    pos[0] = x + current_atom->getPosX();
557 +    pos[1] = y + current_atom->getPosY();
558 +    pos[2] = z + current_atom->getPosZ();
559 +    
560 +    info[0].atoms[current_atom_ndx]->setPos( pos );
561  
562 <    the_atoms[current_atom_ndx]->setX( x + current_atom->getPosX() );
750 <    the_atoms[current_atom_ndx]->setY( y + current_atom->getPosY() );
751 <    the_atoms[current_atom_ndx]->setZ( z + current_atom->getPosZ() );
562 >    if( info[0].atoms[current_atom_ndx]->isDirectional() ){
563  
564 <    if( the_atoms[current_atom_ndx]->isDirectional() ){
564 >      dAtom = (DirectionalAtom *)info[0].atoms[current_atom_ndx];
565  
755      dAtom = (DirectionalAtom *)the_atoms[current_atom_ndx];
756
566        rotMat[0][0] = 1.0;
567        rotMat[0][1] = 0.0;
568        rotMat[0][2] = 0.0;
# Line 784 | Line 593 | void SimSetup::gatherInfo( void ){
593  
594  
595   void SimSetup::gatherInfo( void ){
596 +  int i,j,k;
597  
598    ensembleCase = -1;
599    ffCase = -1;
600  
791  // get the stamps and globals;
792  the_stamps = stamps;
793  the_globals = globals;
794
601    // set the easy ones first
796  info->target_temp = the_globals->getTargetTemp();
797  info->dt = the_globals->getDt();
798  info->run_time = the_globals->getRunTime();
799  n_components = the_globals->getNComponents();
602  
603 +  for( i=0; i<nInfo; i++){
604 +    info[i].target_temp = globals->getTargetTemp();
605 +    info[i].dt = globals->getDt();
606 +    info[i].run_time = globals->getRunTime();
607 +  }
608 +  n_components = globals->getNComponents();
609  
610 +
611    // get the forceField
612  
613 <  strcpy( force_field, the_globals->getForceField() );
613 >  strcpy( force_field, globals->getForceField() );
614  
615    if( !strcasecmp( force_field, "DUFF" )) ffCase = FF_DUFF;
616    else if( !strcasecmp( force_field, "LJ" )) ffCase = FF_LJ;
617 +  else if( !strcasecmp( force_field, "EAM" )) ffCase = FF_EAM;
618    else{
619      sprintf( painCave.errMsg,
620 <             "SimSetup Error. Unrecognized force field -> %s\n",
621 <             force_field );
620 >       "SimSetup Error. Unrecognized force field -> %s\n",
621 >       force_field );
622      painCave.isFatal = 1;
623      simError();
624    }
625  
626    // get the ensemble
627  
628 <  strcpy( ensemble, the_globals->getEnsemble() );
628 >  strcpy( ensemble, globals->getEnsemble() );
629  
630    if( !strcasecmp( ensemble, "NVE" ))      ensembleCase = NVE_ENS;
631    else if( !strcasecmp( ensemble, "NVT" )) ensembleCase = NVT_ENS;
# Line 826 | Line 636 | void SimSetup::gatherInfo( void ){
636    else if( !strcasecmp( ensemble, "NPTfm" )) ensembleCase = NPTfm_ENS;
637    else{
638      sprintf( painCave.errMsg,
639 <             "SimSetup Warning. Unrecognized Ensemble -> %s, "
639 >       "SimSetup Warning. Unrecognized Ensemble -> %s, "
640               "reverting to NVE for this simulation.\n",
641 <             ensemble );
641 >       ensemble );
642      painCave.isFatal = 0;
643      simError();
644      strcpy( ensemble, "NVE" );
645      ensembleCase = NVE_ENS;
646    }  
647 <  strcpy( info->ensemble, ensemble );
647 >  
648 >  for(i=0; i<nInfo; i++){
649 >    
650 >    strcpy( info[i].ensemble, ensemble );
651  
652 <  // get the mixing rule
652 >    // get the mixing rule
653  
654 <  strcpy( info->mixingRule, the_globals->getMixingRule() );
655 <  info->usePBC = the_globals->getPBC();
656 <        
654 >    strcpy( info[i].mixingRule, globals->getMixingRule() );
655 >    info[i].usePBC = globals->getPBC();
656 >  }
657    
658    // get the components and calculate the tot_nMol and indvidual n_mol
659  
660 <  the_components = the_globals->getComponents();
660 >  the_components = globals->getComponents();
661    components_nmol = new int[n_components];
662  
663  
664 <  if( !the_globals->haveNMol() ){
664 >  if( !globals->haveNMol() ){
665      // we don't have the total number of molecules, so we assume it is
666      // given in each component
667  
# Line 856 | Line 669 | void SimSetup::gatherInfo( void ){
669      for( i=0; i<n_components; i++ ){
670  
671        if( !the_components[i]->haveNMol() ){
672 <        // we have a problem
673 <        sprintf( painCave.errMsg,
674 <                 "SimSetup Error. No global NMol or component NMol"
675 <                 " given. Cannot calculate the number of atoms.\n" );
676 <        painCave.isFatal = 1;
677 <        simError();
672 >  // we have a problem
673 >  sprintf( painCave.errMsg,
674 >     "SimSetup Error. No global NMol or component NMol"
675 >     " given. Cannot calculate the number of atoms.\n" );
676 >  painCave.isFatal = 1;
677 >  simError();
678        }
679  
680        tot_nmol += the_components[i]->getNMol();
# Line 870 | Line 683 | void SimSetup::gatherInfo( void ){
683    }
684    else{
685      sprintf( painCave.errMsg,
686 <             "SimSetup error.\n"
687 <             "\tSorry, the ability to specify total"
688 <             " nMols and then give molfractions in the components\n"
689 <             "\tis not currently supported."
690 <             " Please give nMol in the components.\n" );
686 >       "SimSetup error.\n"
687 >       "\tSorry, the ability to specify total"
688 >       " nMols and then give molfractions in the components\n"
689 >       "\tis not currently supported."
690 >       " Please give nMol in the components.\n" );
691      painCave.isFatal = 1;
692      simError();
693    }
694  
695    // set the status, sample, and thermal kick times
696    
697 <  if( the_globals->haveSampleTime() ){
885 <    info->sampleTime = the_globals->getSampleTime();
886 <    info->statusTime = info->sampleTime;
887 <    info->thermalTime = info->sampleTime;
888 <  }
889 <  else{
890 <    info->sampleTime = the_globals->getRunTime();
891 <    info->statusTime = info->sampleTime;
892 <    info->thermalTime = info->sampleTime;
893 <  }
697 >  for(i=0; i<nInfo; i++){
698  
699 <  if( the_globals->haveStatusTime() ){
700 <    info->statusTime = the_globals->getStatusTime();
701 <  }
702 <
703 <  if( the_globals->haveThermalTime() ){
704 <    info->thermalTime = the_globals->getThermalTime();
705 <  }
706 <
707 <  // check for the temperature set flag
708 <
905 <  if( the_globals->haveTempSet() ) info->setTemp = the_globals->getTempSet();
906 <
907 <  // get some of the tricky things that may still be in the globals
908 <
909 <  double boxVector[3];
910 <  if( the_globals->haveBox() ){
911 <    boxVector[0] = the_globals->getBox();
912 <    boxVector[1] = the_globals->getBox();
913 <    boxVector[2] = the_globals->getBox();
699 >    if( globals->haveSampleTime() ){
700 >      info[i].sampleTime = globals->getSampleTime();
701 >      info[i].statusTime = info[i].sampleTime;
702 >      info[i].thermalTime = info[i].sampleTime;
703 >    }
704 >    else{
705 >      info[i].sampleTime = globals->getRunTime();
706 >      info[i].statusTime = info[i].sampleTime;
707 >      info[i].thermalTime = info[i].sampleTime;
708 >    }
709      
710 <    info->setBox( boxVector );
711 <  }
917 <  else if( the_globals->haveDensity() ){
918 <
919 <    double vol;
920 <    vol = (double)tot_nmol / the_globals->getDensity();
921 <     boxVector[0] = pow( vol, ( 1.0 / 3.0 ) );
922 <     boxVector[1] = boxVector[0];
923 <     boxVector[2] = boxVector[0];
924 <
925 <    info->setBox( boxVector );
926 <  }
927 <  else{
928 <    if( !the_globals->haveBoxX() ){
929 <      sprintf( painCave.errMsg,
930 <               "SimSetup error, no periodic BoxX size given.\n" );
931 <      painCave.isFatal = 1;
932 <      simError();
710 >    if( globals->haveStatusTime() ){
711 >      info[i].statusTime = globals->getStatusTime();
712      }
713 <    boxVector[0] = the_globals->getBoxX();
714 <
715 <    if( !the_globals->haveBoxY() ){
937 <      sprintf( painCave.errMsg,
938 <               "SimSetup error, no periodic BoxY size given.\n" );
939 <      painCave.isFatal = 1;
940 <      simError();
713 >    
714 >    if( globals->haveThermalTime() ){
715 >      info[i].thermalTime = globals->getThermalTime();
716      }
942    boxVector[1] = the_globals->getBoxY();
717  
718 <    if( !the_globals->haveBoxZ() ){
945 <      sprintf( painCave.errMsg,
946 <               "SimSetup error, no periodic BoxZ size given.\n" );
947 <      painCave.isFatal = 1;
948 <      simError();
949 <    }
950 <    boxVector[2] = the_globals->getBoxZ();
718 >    // check for the temperature set flag
719  
720 <    info->setBox( boxVector );
720 >    if( globals->haveTempSet() ) info[i].setTemp = globals->getTempSet();
721 >    
722 >    // get some of the tricky things that may still be in the globals
723 >    
724 >    double boxVector[3];
725 >    if( globals->haveBox() ){
726 >      boxVector[0] = globals->getBox();
727 >      boxVector[1] = globals->getBox();
728 >      boxVector[2] = globals->getBox();
729 >      
730 >      info[i].setBox( boxVector );
731 >    }
732 >    else if( globals->haveDensity() ){
733 >      
734 >      double vol;
735 >      vol = (double)tot_nmol / globals->getDensity();
736 >      boxVector[0] = pow( vol, ( 1.0 / 3.0 ) );
737 >      boxVector[1] = boxVector[0];
738 >      boxVector[2] = boxVector[0];
739 >      
740 >      info[i].setBox( boxVector );
741    }
742 +    else{
743 +      if( !globals->haveBoxX() ){
744 +  sprintf( painCave.errMsg,
745 +     "SimSetup error, no periodic BoxX size given.\n" );
746 +  painCave.isFatal = 1;
747 +  simError();
748 +      }
749 +      boxVector[0] = globals->getBoxX();
750 +      
751 +      if( !globals->haveBoxY() ){
752 +  sprintf( painCave.errMsg,
753 +     "SimSetup error, no periodic BoxY size given.\n" );
754 +  painCave.isFatal = 1;
755 +  simError();
756 +      }
757 +      boxVector[1] = globals->getBoxY();
758 +      
759 +      if( !globals->haveBoxZ() ){
760 +  sprintf( painCave.errMsg,
761 +     "SimSetup error, no periodic BoxZ size given.\n" );
762 +  painCave.isFatal = 1;
763 +  simError();
764 +      }
765 +      boxVector[2] = globals->getBoxZ();
766 +      
767 +      info[i].setBox( boxVector );
768 +    }
769  
770 <
770 >  }
771      
772   #ifdef IS_MPI
773    strcpy( checkPointMsg, "Succesfully gathered all information from Bass\n" );
# Line 965 | Line 780 | void SimSetup::finalInfoCheck( void ){
780   void SimSetup::finalInfoCheck( void ){
781    int index;
782    int usesDipoles;
783 <  
783 >  int i;
784  
785 <  // check electrostatic parameters
786 <  
787 <  index = 0;
788 <  usesDipoles = 0;
789 <  while( (index < info->n_atoms) && !usesDipoles ){
790 <    usesDipoles = ((info->atoms)[index])->hasDipole();
791 <    index++;
792 <  }
793 <  
785 >  for(i=0; i<nInfo; i++){
786 >    // check electrostatic parameters
787 >    
788 >    index = 0;
789 >    usesDipoles = 0;
790 >    while( (index < info[i].n_atoms) && !usesDipoles ){
791 >      usesDipoles = (info[i].atoms[index])->hasDipole();
792 >      index++;
793 >    }
794 >    
795   #ifdef IS_MPI
796 <  int myUse = usesDipoles
797 <  MPI_Allreduce( &myUse, &UsesDipoles, 1, MPI_INT, MPI_LOR, MPI_COMM_WORLD );
796 >    int myUse = usesDipoles;
797 >    MPI_Allreduce( &myUse, &usesDipoles, 1, MPI_INT, MPI_LOR, MPI_COMM_WORLD );
798   #endif //is_mpi
983
984
985  if (the_globals->getUseRF() ) {
986    info->useReactionField = 1;
799      
800 <    if( !the_globals->haveECR() ){
801 <      sprintf( painCave.errMsg,
802 <               "SimSetup Warning: using default value of 1/2 the smallest "
803 <               "box length for the electrostaticCutoffRadius.\n"
992 <               "I hope you have a very fast processor!\n");
993 <      painCave.isFatal = 0;
994 <      simError();
995 <      double smallest;
996 <      smallest = info->boxLx;
997 <      if (info->boxLy <= smallest) smallest = info->boxLy;
998 <      if (info->boxLz <= smallest) smallest = info->boxLz;
999 <      info->ecr = 0.5 * smallest;
1000 <    } else {
1001 <      info->ecr        = the_globals->getECR();
1002 <    }
1003 <
1004 <    if( !the_globals->haveEST() ){
1005 <      sprintf( painCave.errMsg,
1006 <               "SimSetup Warning: using default value of 0.05 * the "
1007 <               "electrostaticCutoffRadius for the electrostaticSkinThickness\n"
1008 <               );
1009 <      painCave.isFatal = 0;
1010 <      simError();
1011 <      info->est = 0.05 * info->ecr;
1012 <    } else {
1013 <      info->est        = the_globals->getEST();
1014 <    }
1015 <    
1016 <    if(!the_globals->haveDielectric() ){
1017 <      sprintf( painCave.errMsg,
1018 <               "SimSetup Error: You are trying to use Reaction Field without"
1019 <               "setting a dielectric constant!\n"
1020 <               );
1021 <      painCave.isFatal = 1;
1022 <      simError();
1023 <    }
1024 <    info->dielectric = the_globals->getDielectric();  
1025 <  }
1026 <  else {
1027 <    if (usesDipoles) {
800 >    double theEcr, theEst;
801 >  
802 >    if (globals->getUseRF() ) {
803 >      info[i].useReactionField = 1;
804        
805 <      if( !the_globals->haveECR() ){
806 <        sprintf( painCave.errMsg,
807 <                 "SimSetup Warning: using default value of 1/2 the smallest "
808 <                 "box length for the electrostaticCutoffRadius.\n"
809 <                 "I hope you have a very fast processor!\n");
810 <        painCave.isFatal = 0;
811 <        simError();
812 <        double smallest;
813 <        smallest = info->boxLx;
814 <        if (info->boxLy <= smallest) smallest = info->boxLy;
815 <        if (info->boxLz <= smallest) smallest = info->boxLz;
816 <        info->ecr = 0.5 * smallest;
805 >      if( !globals->haveECR() ){
806 >  sprintf( painCave.errMsg,
807 >     "SimSetup Warning: using default value of 1/2 the smallest "
808 >     "box length for the electrostaticCutoffRadius.\n"
809 >     "I hope you have a very fast processor!\n");
810 >  painCave.isFatal = 0;
811 >  simError();
812 >  double smallest;
813 >  smallest = info[i].boxL[0];
814 >  if (info[i].boxL[1] <= smallest) smallest = info[i].boxL[1];
815 >  if (info[i].boxL[2] <= smallest) smallest = info[i].boxL[2];
816 >  theEcr = 0.5 * smallest;
817        } else {
818 <        info->ecr        = the_globals->getECR();
818 >  theEcr = globals->getECR();
819        }
820        
821 <      if( !the_globals->haveEST() ){
822 <        sprintf( painCave.errMsg,
823 <                 "SimSetup Warning: using default value of 5%% of the "
824 <                 "electrostaticCutoffRadius for the "
825 <                 "electrostaticSkinThickness\n"
826 <                 );
827 <        painCave.isFatal = 0;
828 <        simError();
1053 <        info->est = 0.05 * info->ecr;
821 >      if( !globals->haveEST() ){
822 >  sprintf( painCave.errMsg,
823 >     "SimSetup Warning: using default value of 0.05 * the "
824 >     "electrostaticCutoffRadius for the electrostaticSkinThickness\n"
825 >     );
826 >  painCave.isFatal = 0;
827 >  simError();
828 >  theEst = 0.05 * theEcr;
829        } else {
830 <        info->est        = the_globals->getEST();
830 >  theEst= globals->getEST();
831        }
832 <    }
833 <  }  
832 >      
833 >      info[i].setEcr( theEcr, theEst );
834 >      
835 >      if(!globals->haveDielectric() ){
836 >  sprintf( painCave.errMsg,
837 >     "SimSetup Error: You are trying to use Reaction Field without"
838 >     "setting a dielectric constant!\n"
839 >     );
840 >  painCave.isFatal = 1;
841 >  simError();
842 >      }
843 >      info[i].dielectric = globals->getDielectric();  
844 >    }
845 >    else {
846 >      if (usesDipoles) {
847 >  
848 >  if( !globals->haveECR() ){
849 >    sprintf( painCave.errMsg,
850 >       "SimSetup Warning: using default value of 1/2 the smallest "
851 >       "box length for the electrostaticCutoffRadius.\n"
852 >       "I hope you have a very fast processor!\n");
853 >    painCave.isFatal = 0;
854 >    simError();
855 >    double smallest;
856 >    smallest = info[i].boxL[0];
857 >    if (info[i].boxL[1] <= smallest) smallest = info[i].boxL[1];
858 >    if (info[i].boxL[2] <= smallest) smallest = info[i].boxL[2];
859 >    theEcr = 0.5 * smallest;
860 >  } else {
861 >    theEcr = globals->getECR();
862 >  }
863 >  
864 >  if( !globals->haveEST() ){
865 >    sprintf( painCave.errMsg,
866 >       "SimSetup Warning: using default value of 0.05 * the "
867 >       "electrostaticCutoffRadius for the "
868 >       "electrostaticSkinThickness\n"
869 >       );
870 >    painCave.isFatal = 0;
871 >    simError();
872 >    theEst = 0.05 * theEcr;
873 >  } else {
874 >    theEst= globals->getEST();
875 >  }
876 >  
877 >  info[i].setEcr( theEcr, theEst );
878 >      }
879 >    }  
880 >  }
881  
882   #ifdef IS_MPI
883    strcpy( checkPointMsg, "post processing checks out" );
# Line 1065 | Line 887 | void SimSetup::initSystemCoords( void ){
887   }
888  
889   void SimSetup::initSystemCoords( void ){
890 +  int i;
891 +  
892 +  char* inName;
893  
894 < if( the_globals->haveInitialConfig() ){
895 <
896 <     InitializeFromFile* fileInit;
894 >  (info[0].getConfiguration())->createArrays( info[0].n_atoms );
895 >
896 >  for(i=0; i<info[0].n_atoms; i++) info[0].atoms[i]->setCoords();
897 >  
898 >  if( globals->haveInitialConfig() ){
899 >    
900 >    InitializeFromFile* fileInit;
901   #ifdef IS_MPI // is_mpi
902 <     if( worldRank == 0 ){
902 >    if( worldRank == 0 ){
903   #endif //is_mpi
904 <   fileInit = new InitializeFromFile( the_globals->getInitialConfig() );
904 >      inName = globals->getInitialConfig();
905 >      double* tempDouble = new double[1000000];
906 >      fileInit = new InitializeFromFile( inName );
907   #ifdef IS_MPI
908 <     }else fileInit = new InitializeFromFile( NULL );
908 >    }else fileInit = new InitializeFromFile( NULL );
909   #endif
910 <   fileInit->read_xyz( info ); // default velocities on
911 <
912 <   delete fileInit;
913 < }
914 < else{
915 <
910 >    fileInit->readInit( info ); // default velocities on
911 >    
912 >    delete fileInit;
913 >  }
914 >  else{
915 >    
916   #ifdef IS_MPI
917 <
918 <  // no init from bass
919 <  
920 <  sprintf( painCave.errMsg,
921 <           "Cannot intialize a parallel simulation without an initial configuration file.\n" );
922 <  painCave.isFatal;
923 <  simError();
924 <  
917 >    
918 >    // no init from bass
919 >    
920 >    sprintf( painCave.errMsg,
921 >       "Cannot intialize a parallel simulation without an initial configuration file.\n" );
922 >    painCave.isFatal;
923 >    simError();
924 >    
925   #else
926 <
927 <  initFromBass();
928 <
929 <
926 >    
927 >    initFromBass();
928 >    
929 >    
930   #endif
931 < }
932 <
931 >  }
932 >  
933   #ifdef IS_MPI
934    strcpy( checkPointMsg, "Successfully read in the initial configuration" );
935    MPIcheckPoint();
936   #endif // is_mpi
937 <
937 >  
938   }
939  
940  
941   void SimSetup::makeOutNames( void ){
942 +  
943 +  int k;
944  
945 +  
946 +  for(k=0; k<nInfo; k++){
947 +
948   #ifdef IS_MPI
949 <  if( worldRank == 0 ){
949 >    if( worldRank == 0 ){
950   #endif // is_mpi
951 <    
952 <    if( the_globals->haveFinalConfig() ){
953 <      strcpy( info->finalName, the_globals->getFinalConfig() );
951 >      
952 >      if( globals->haveFinalConfig() ){
953 >  strcpy( info[k].finalName, globals->getFinalConfig() );
954 >      }
955 >      else{
956 >  strcpy( info[k].finalName, inFileName );
957 >  char* endTest;
958 >  int nameLength = strlen( info[k].finalName );
959 >  endTest = &(info[k].finalName[nameLength - 5]);
960 >  if( !strcmp( endTest, ".bass" ) ){
961 >    strcpy( endTest, ".eor" );
962 >  }
963 >  else if( !strcmp( endTest, ".BASS" ) ){
964 >    strcpy( endTest, ".eor" );
965 >  }
966 >  else{
967 >    endTest = &(info[k].finalName[nameLength - 4]);
968 >    if( !strcmp( endTest, ".bss" ) ){
969 >      strcpy( endTest, ".eor" );
970      }
971 +    else if( !strcmp( endTest, ".mdl" ) ){
972 +      strcpy( endTest, ".eor" );
973 +    }
974      else{
975 <      strcpy( info->finalName, inFileName );
975 >      strcat( info[k].finalName, ".eor" );
976 >    }
977 >  }
978 >      }
979 >      
980 >      // make the sample and status out names
981 >      
982 >      strcpy( info[k].sampleName, inFileName );
983        char* endTest;
984 <      int nameLength = strlen( info->finalName );
985 <      endTest = &(info->finalName[nameLength - 5]);
984 >      int nameLength = strlen( info[k].sampleName );
985 >      endTest = &(info[k].sampleName[nameLength - 5]);
986        if( !strcmp( endTest, ".bass" ) ){
987 <        strcpy( endTest, ".eor" );
987 >  strcpy( endTest, ".dump" );
988        }
989        else if( !strcmp( endTest, ".BASS" ) ){
990 <        strcpy( endTest, ".eor" );
990 >  strcpy( endTest, ".dump" );
991        }
992        else{
993 <        endTest = &(info->finalName[nameLength - 4]);
994 <        if( !strcmp( endTest, ".bss" ) ){
995 <          strcpy( endTest, ".eor" );
996 <        }
997 <        else if( !strcmp( endTest, ".mdl" ) ){
998 <          strcpy( endTest, ".eor" );
999 <        }
1000 <        else{
1001 <          strcat( info->finalName, ".eor" );
1002 <        }
993 >  endTest = &(info[k].sampleName[nameLength - 4]);
994 >  if( !strcmp( endTest, ".bss" ) ){
995 >    strcpy( endTest, ".dump" );
996 >  }
997 >  else if( !strcmp( endTest, ".mdl" ) ){
998 >    strcpy( endTest, ".dump" );
999 >  }
1000 >  else{
1001 >    strcat( info[k].sampleName, ".dump" );
1002 >  }
1003        }
1004 <    }
1005 <    
1006 <    // make the sample and status out names
1007 <    
1008 <    strcpy( info->sampleName, inFileName );
1009 <    char* endTest;
1148 <    int nameLength = strlen( info->sampleName );
1149 <    endTest = &(info->sampleName[nameLength - 5]);
1150 <    if( !strcmp( endTest, ".bass" ) ){
1151 <      strcpy( endTest, ".dump" );
1152 <    }
1153 <    else if( !strcmp( endTest, ".BASS" ) ){
1154 <      strcpy( endTest, ".dump" );
1155 <    }
1156 <    else{
1157 <      endTest = &(info->sampleName[nameLength - 4]);
1158 <      if( !strcmp( endTest, ".bss" ) ){
1159 <        strcpy( endTest, ".dump" );
1004 >      
1005 >      strcpy( info[k].statusName, inFileName );
1006 >      nameLength = strlen( info[k].statusName );
1007 >      endTest = &(info[k].statusName[nameLength - 5]);
1008 >      if( !strcmp( endTest, ".bass" ) ){
1009 >  strcpy( endTest, ".stat" );
1010        }
1011 <      else if( !strcmp( endTest, ".mdl" ) ){
1012 <        strcpy( endTest, ".dump" );
1011 >      else if( !strcmp( endTest, ".BASS" ) ){
1012 >  strcpy( endTest, ".stat" );
1013        }
1014        else{
1015 <        strcat( info->sampleName, ".dump" );
1015 >  endTest = &(info[k].statusName[nameLength - 4]);
1016 >  if( !strcmp( endTest, ".bss" ) ){
1017 >    strcpy( endTest, ".stat" );
1018 >  }
1019 >  else if( !strcmp( endTest, ".mdl" ) ){
1020 >    strcpy( endTest, ".stat" );
1021 >  }
1022 >  else{
1023 >    strcat( info[k].statusName, ".stat" );
1024 >  }
1025        }
1026 <    }
1168 <    
1169 <    strcpy( info->statusName, inFileName );
1170 <    nameLength = strlen( info->statusName );
1171 <    endTest = &(info->statusName[nameLength - 5]);
1172 <    if( !strcmp( endTest, ".bass" ) ){
1173 <      strcpy( endTest, ".stat" );
1174 <    }
1175 <    else if( !strcmp( endTest, ".BASS" ) ){
1176 <      strcpy( endTest, ".stat" );
1177 <    }
1178 <    else{
1179 <      endTest = &(info->statusName[nameLength - 4]);
1180 <      if( !strcmp( endTest, ".bss" ) ){
1181 <        strcpy( endTest, ".stat" );
1182 <      }
1183 <      else if( !strcmp( endTest, ".mdl" ) ){
1184 <        strcpy( endTest, ".stat" );
1185 <      }
1186 <      else{
1187 <        strcat( info->statusName, ".stat" );
1188 <      }
1189 <    }
1190 <    
1026 >      
1027   #ifdef IS_MPI
1028 <  }
1028 >    }
1029   #endif // is_mpi
1030 <
1030 >  }
1031   }
1032  
1033  
1034   void SimSetup::sysObjectsCreation( void ){
1035 <
1035 >  
1036 >  int i,k;
1037 >  
1038    // create the forceField
1039  
1040    createFF();
# Line 1216 | Line 1054 | void SimSetup::sysObjectsCreation( void ){
1054   #endif //is_mpi
1055    
1056    // create the atom and SRI arrays. Also initialize Molecule Stamp ID's
1057 <  
1057 >
1058    makeSysArrays();
1059  
1060 +  // make and initialize the molecules (all but atomic coordinates)
1061 +
1062 +  makeMolecules();
1063    
1064 <
1065 <
1064 >  for(k=0; k<nInfo; k++){
1065 >    info[k].identArray = new int[info[k].n_atoms];
1066 >    for(i=0; i<info[k].n_atoms; i++){
1067 >      info[k].identArray[i] = info[k].atoms[i]->getIdent();
1068 >    }
1069 >  }
1070   }
1071  
1072  
# Line 1237 | Line 1082 | void SimSetup::createFF( void ){
1082      the_ff = new LJFF();
1083      break;
1084  
1085 +  case FF_EAM:
1086 +    the_ff = new EAM_FF();
1087 +    break;
1088 +
1089    default:
1090      sprintf( painCave.errMsg,
1091 <             "SimSetup Error. Unrecognized force field in case statement.\n");
1091 >       "SimSetup Error. Unrecognized force field in case statement.\n");
1092      painCave.isFatal = 1;
1093      simError();
1094    }
# Line 1254 | Line 1103 | void SimSetup::compList( void ){
1103  
1104   void SimSetup::compList( void ){
1105  
1106 +  int i;
1107 +  char* id;
1108 +  LinkedMolStamp* headStamp = new LinkedMolStamp();
1109 +  LinkedMolStamp* currentStamp = NULL;
1110    comp_stamps = new MoleculeStamp*[n_components];
1111 <
1111 >  
1112    // make an array of molecule stamps that match the components used.
1113    // also extract the used stamps out into a separate linked list
1261
1262  info->nComponents = n_components;
1263  info->componentsNmol = components_nmol;
1264  info->compStamps = comp_stamps;
1265  info->headStamp = new LinkedMolStamp();
1114    
1115 <  char* id;
1116 <  LinkedMolStamp* headStamp = info->headStamp;
1117 <  LinkedMolStamp* currentStamp = NULL;
1115 >  for(i=0; i<nInfo; i++){
1116 >    info[i].nComponents = n_components;
1117 >    info[i].componentsNmol = components_nmol;
1118 >    info[i].compStamps = comp_stamps;
1119 >    info[i].headStamp = headStamp;
1120 >  }
1121 >  
1122 >
1123    for( i=0; i<n_components; i++ ){
1124  
1125      id = the_components[i]->getType();
# Line 1279 | Line 1132 | void SimSetup::compList( void ){
1132        
1133        // extract the component from the list;
1134        
1135 <      currentStamp = the_stamps->extractMolStamp( id );
1135 >      currentStamp = stamps->extractMolStamp( id );
1136        if( currentStamp == NULL ){
1137 <        sprintf( painCave.errMsg,
1138 <                 "SimSetup error: Component \"%s\" was not found in the "
1139 <                 "list of declared molecules\n",
1140 <                 id );
1141 <        painCave.isFatal = 1;
1142 <        simError();
1137 >  sprintf( painCave.errMsg,
1138 >     "SimSetup error: Component \"%s\" was not found in the "
1139 >     "list of declared molecules\n",
1140 >     id );
1141 >  painCave.isFatal = 1;
1142 >  simError();
1143        }
1144        
1145        headStamp->add( currentStamp );
# Line 1303 | Line 1156 | void SimSetup::calcSysValues( void ){
1156   }
1157  
1158   void SimSetup::calcSysValues( void ){
1159 <
1159 >  int i, j, k;
1160 >  
1161 >  int *molMembershipArray;
1162 >  
1163    tot_atoms = 0;
1164    tot_bonds = 0;
1165    tot_bends = 0;
# Line 1315 | Line 1171 | void SimSetup::calcSysValues( void ){
1171      tot_bends +=    components_nmol[i] * comp_stamps[i]->getNBends();
1172      tot_torsions += components_nmol[i] * comp_stamps[i]->getNTorsions();
1173    }
1174 <
1174 >  
1175    tot_SRI = tot_bonds + tot_bends + tot_torsions;
1176 <
1321 <  info->n_atoms = tot_atoms;
1322 <  info->n_bonds = tot_bonds;
1323 <  info->n_bends = tot_bends;
1324 <  info->n_torsions = tot_torsions;
1325 <  info->n_SRI = tot_SRI;
1326 <  info->n_mol = tot_nmol;
1176 >  molMembershipArray = new int[tot_atoms];
1177    
1178 <  info->molMembershipArray = new int[tot_atoms];
1178 >  for(i=0; i<nInfo; i++){
1179 >    info[i].n_atoms = tot_atoms;
1180 >    info[i].n_bonds = tot_bonds;
1181 >    info[i].n_bends = tot_bends;
1182 >    info[i].n_torsions = tot_torsions;
1183 >    info[i].n_SRI = tot_SRI;
1184 >    info[i].n_mol = tot_nmol;
1185 >    
1186 >    info[i].molMembershipArray = molMembershipArray;
1187 >  }
1188   }
1189  
1331
1190   #ifdef IS_MPI
1191  
1192   void SimSetup::mpiMolDivide( void ){
1193    
1194 +  int i, j, k;
1195    int localMol, allMol;
1196    int local_atoms, local_bonds, local_bends, local_torsions, local_SRI;
1197  
# Line 1359 | Line 1218 | void SimSetup::mpiMolDivide( void ){
1218      for( j=0; j<components_nmol[i]; j++ ){
1219        
1220        if( mol2proc[allMol] == worldRank ){
1221 <        
1222 <        local_atoms +=    comp_stamps[i]->getNAtoms();
1223 <        local_bonds +=    comp_stamps[i]->getNBonds();
1224 <        local_bends +=    comp_stamps[i]->getNBends();
1225 <        local_torsions += comp_stamps[i]->getNTorsions();
1226 <        localMol++;
1221 >  
1222 >  local_atoms +=    comp_stamps[i]->getNAtoms();
1223 >  local_bonds +=    comp_stamps[i]->getNBonds();
1224 >  local_bends +=    comp_stamps[i]->getNBends();
1225 >  local_torsions += comp_stamps[i]->getNTorsions();
1226 >  localMol++;
1227        }      
1228        for (k = 0; k < comp_stamps[i]->getNAtoms(); k++) {
1229 <        info->molMembershipArray[globalAtomIndex] = allMol;
1229 >        info[0].molMembershipArray[globalAtomIndex] = allMol;
1230          globalAtomIndex++;
1231        }
1232  
# Line 1376 | Line 1235 | void SimSetup::mpiMolDivide( void ){
1235    }
1236    local_SRI = local_bonds + local_bends + local_torsions;
1237    
1238 <  info->n_atoms = mpiSim->getMyNlocal();  
1238 >  info[0].n_atoms = mpiSim->getMyNlocal();  
1239    
1240 <  if( local_atoms != info->n_atoms ){
1240 >  if( local_atoms != info[0].n_atoms ){
1241      sprintf( painCave.errMsg,
1242 <             "SimSetup error: mpiSim's localAtom (%d) and SimSetup's"
1243 <             " localAtom (%d) are not equal.\n",
1244 <             info->n_atoms,
1245 <             local_atoms );
1242 >       "SimSetup error: mpiSim's localAtom (%d) and SimSetup's"
1243 >       " localAtom (%d) are not equal.\n",
1244 >       info[0].n_atoms,
1245 >       local_atoms );
1246      painCave.isFatal = 1;
1247      simError();
1248    }
1249  
1250 <  info->n_bonds = local_bonds;
1251 <  info->n_bends = local_bends;
1252 <  info->n_torsions = local_torsions;
1253 <  info->n_SRI = local_SRI;
1254 <  info->n_mol = localMol;
1250 >  info[0].n_bonds = local_bonds;
1251 >  info[0].n_bends = local_bends;
1252 >  info[0].n_torsions = local_torsions;
1253 >  info[0].n_SRI = local_SRI;
1254 >  info[0].n_mol = localMol;
1255  
1256    strcpy( checkPointMsg, "Passed nlocal consistency check." );
1257    MPIcheckPoint();
1258   }
1259 <  
1259 >
1260   #endif // is_mpi
1261  
1262  
1263   void SimSetup::makeSysArrays( void ){
1264 +  int i, j, k, l;
1265 +
1266 +  Atom** the_atoms;
1267 +  Molecule* the_molecules;
1268 +  Exclude** the_excludes;
1269  
1406  // create the atom and short range interaction arrays
1407
1408  Atom::createArrays(info->n_atoms);
1409  the_atoms = new Atom*[info->n_atoms];
1410  the_molecules = new Molecule[info->n_mol];
1411  int molIndex;
1412
1413  // initialize the molecule's stampID's
1414
1415 #ifdef IS_MPI
1270    
1271 +  for(l=0; l<nInfo; l++){
1272 +    
1273 +    // create the atom and short range interaction arrays
1274 +    
1275 +    the_atoms = new Atom*[info[l].n_atoms];
1276 +    the_molecules = new Molecule[info[l].n_mol];
1277 +    int molIndex;
1278  
1279 <  molIndex = 0;
1419 <  for(i=0; i<mpiSim->getTotNmol(); i++){
1279 >    // initialize the molecule's stampID's
1280      
1281 <    if(mol2proc[i] == worldRank ){
1282 <      the_molecules[molIndex].setStampID( molCompType[i] );
1283 <      the_molecules[molIndex].setMyIndex( molIndex );
1284 <      the_molecules[molIndex].setGlobalIndex( i );
1285 <      molIndex++;
1281 > #ifdef IS_MPI
1282 >    
1283 >    
1284 >    molIndex = 0;
1285 >    for(i=0; i<mpiSim->getTotNmol(); i++){
1286 >    
1287 >      if(mol2proc[i] == worldRank ){
1288 >  the_molecules[molIndex].setStampID( molCompType[i] );
1289 >  the_molecules[molIndex].setMyIndex( molIndex );
1290 >  the_molecules[molIndex].setGlobalIndex( i );
1291 >  molIndex++;
1292 >      }
1293      }
1294 +    
1295 + #else // is_mpi
1296 +    
1297 +    molIndex = 0;
1298 +    globalAtomIndex = 0;
1299 +    for(i=0; i<n_components; i++){
1300 +      for(j=0; j<components_nmol[i]; j++ ){
1301 +  the_molecules[molIndex].setStampID( i );
1302 +  the_molecules[molIndex].setMyIndex( molIndex );
1303 +  the_molecules[molIndex].setGlobalIndex( molIndex );
1304 +  for (k = 0; k < comp_stamps[i]->getNAtoms(); k++) {
1305 +    info[l].molMembershipArray[globalAtomIndex] = molIndex;
1306 +    globalAtomIndex++;
1307    }
1308 +  molIndex++;
1309 +      }
1310 +    }
1311 +    
1312 +    
1313 + #endif // is_mpi
1314  
1315 < #else // is_mpi
1316 <  
1317 <  molIndex = 0;
1318 <  globalAtomIndex = 0;
1319 <  for(i=0; i<n_components; i++){
1320 <    for(j=0; j<components_nmol[i]; j++ ){
1321 <      the_molecules[molIndex].setStampID( i );
1436 <      the_molecules[molIndex].setMyIndex( molIndex );
1437 <      the_molecules[molIndex].setGlobalIndex( molIndex );
1438 <      for (k = 0; k < comp_stamps[i]->getNAtoms(); k++) {
1439 <        info->molMembershipArray[globalAtomIndex] = molIndex;
1440 <        globalAtomIndex++;
1315 >
1316 >    if( info[l].n_SRI ){
1317 >    
1318 >      Exclude::createArray(info[l].n_SRI);
1319 >      the_excludes = new Exclude*[info[l].n_SRI];
1320 >      for( int ex=0; ex<info[l].n_SRI; ex++){
1321 >  the_excludes[ex] = new Exclude(ex);
1322        }
1323 <      molIndex++;
1323 >      info[l].globalExcludes = new int;
1324 >      info[l].n_exclude = info[l].n_SRI;
1325      }
1326 +    else{
1327 +    
1328 +      Exclude::createArray( 1 );
1329 +      the_excludes = new Exclude*;
1330 +      the_excludes[0] = new Exclude(0);
1331 +      the_excludes[0]->setPair( 0,0 );
1332 +      info[l].globalExcludes = new int;
1333 +      info[l].globalExcludes[0] = 0;
1334 +      info[l].n_exclude = 0;
1335 +    }
1336 +
1337 +    // set the arrays into the SimInfo object
1338 +
1339 +    info[l].atoms = the_atoms;
1340 +    info[l].molecules = the_molecules;
1341 +    info[l].nGlobalExcludes = 0;
1342 +    info[l].excludes = the_excludes;
1343 +
1344 +    the_ff->setSimInfo( info );
1345 +    
1346    }
1347 + }
1348 +
1349 + void SimSetup::makeIntegrator( void ){
1350 +
1351 +  int k;
1352 +
1353 +  NVT<RealIntegrator>*  myNVT = NULL;
1354 +  NPTi<RealIntegrator>* myNPTi = NULL;
1355 +  NPTf<RealIntegrator>* myNPTf = NULL;
1356 +  NPTim<RealIntegrator>* myNPTim = NULL;
1357 +  NPTfm<RealIntegrator>* myNPTfm = NULL;
1358 +        
1359 +  for(k=0; k<nInfo; k++){
1360      
1361 +    switch( ensembleCase ){
1362 +      
1363 +    case NVE_ENS:
1364 +      if (globals->haveZconstraints()){
1365 +        setupZConstraint(info[k]);
1366 +        new ZConstraint<NVE<RealIntegrator> >( &(info[k]), the_ff );
1367 +     }
1368  
1369 +     else
1370 +        new NVE<RealIntegrator>( &(info[k]), the_ff );
1371 +      break;
1372 +      
1373 +    case NVT_ENS:
1374 +      if (globals->haveZconstraints()){
1375 +        setupZConstraint(info[k]);
1376 +        myNVT = new ZConstraint<NVT<RealIntegrator> >( &(info[k]), the_ff );
1377 +      }
1378 +      else
1379 +        myNVT = new NVT<RealIntegrator>( &(info[k]), the_ff );
1380 +
1381 +        myNVT->setTargetTemp(globals->getTargetTemp());
1382 +      
1383 +        if (globals->haveTauThermostat())
1384 +          myNVT->setTauThermostat(globals->getTauThermostat());
1385 +      
1386 +        else {
1387 +          sprintf( painCave.errMsg,
1388 +                    "SimSetup error: If you use the NVT\n"
1389 +                    "    ensemble, you must set tauThermostat.\n");
1390 +          painCave.isFatal = 1;
1391 +          simError();
1392 +        }
1393 +        break;
1394 +      
1395 +    case NPTi_ENS:
1396 +      if (globals->haveZconstraints()){
1397 +             setupZConstraint(info[k]);
1398 +         myNPTi = new ZConstraint<NPTi<RealIntegrator> >( &(info[k]), the_ff );
1399 +      }
1400 +      else
1401 +        myNPTi = new NPTi<RealIntegrator>( &(info[k]), the_ff );
1402 +
1403 +      myNPTi->setTargetTemp( globals->getTargetTemp() );
1404 +          
1405 +      if (globals->haveTargetPressure())
1406 +        myNPTi->setTargetPressure(globals->getTargetPressure());
1407 +      else {
1408 +         sprintf( painCave.errMsg,
1409 +                   "SimSetup error: If you use a constant pressure\n"
1410 +                   "    ensemble, you must set targetPressure in the BASS file.\n");
1411 +         painCave.isFatal = 1;
1412 +         simError();
1413 +      }
1414 +          
1415 +      if( globals->haveTauThermostat() )
1416 +        myNPTi->setTauThermostat( globals->getTauThermostat() );
1417 +      else{
1418 +         sprintf( painCave.errMsg,
1419 +                   "SimSetup error: If you use an NPT\n"
1420 +                  "    ensemble, you must set tauThermostat.\n");
1421 +         painCave.isFatal = 1;
1422 +         simError();
1423 +      }
1424 +          
1425 +      if( globals->haveTauBarostat() )
1426 +        myNPTi->setTauBarostat( globals->getTauBarostat() );
1427 +      else{
1428 +        sprintf( painCave.errMsg,
1429 +                  "SimSetup error: If you use an NPT\n"
1430 +                  "    ensemble, you must set tauBarostat.\n");
1431 +        painCave.isFatal = 1;
1432 +        simError();
1433 +       }
1434 +       break;
1435 +      
1436 +    case NPTf_ENS:
1437 +      if (globals->haveZconstraints()){
1438 +        setupZConstraint(info[k]);
1439 +        myNPTf = new ZConstraint<NPTf<RealIntegrator> >( &(info[k]), the_ff );
1440 +      }
1441 +      else
1442 +        myNPTf = new NPTf<RealIntegrator>( &(info[k]), the_ff );
1443 +
1444 +      myNPTf->setTargetTemp( globals->getTargetTemp());
1445 +          
1446 +      if (globals->haveTargetPressure())
1447 +        myNPTf->setTargetPressure(globals->getTargetPressure());
1448 +      else {
1449 +        sprintf( painCave.errMsg,
1450 +                  "SimSetup error: If you use a constant pressure\n"
1451 +                  "    ensemble, you must set targetPressure in the BASS file.\n");
1452 +        painCave.isFatal = 1;
1453 +        simError();
1454 +      }    
1455 +          
1456 +      if( globals->haveTauThermostat() )
1457 +        myNPTf->setTauThermostat( globals->getTauThermostat() );
1458 +      else{
1459 +        sprintf( painCave.errMsg,
1460 +         "SimSetup error: If you use an NPT\n"
1461 +                   "    ensemble, you must set tauThermostat.\n");
1462 +        painCave.isFatal = 1;
1463 +        simError();
1464 +      }
1465 +          
1466 +      if( globals->haveTauBarostat() )
1467 +        myNPTf->setTauBarostat( globals->getTauBarostat() );
1468 +      else{
1469 +        sprintf( painCave.errMsg,
1470 +                  "SimSetup error: If you use an NPT\n"
1471 +                  "    ensemble, you must set tauBarostat.\n");
1472 +        painCave.isFatal = 1;
1473 +        simError();
1474 +      }
1475 +      break;
1476 +      
1477 +    case NPTim_ENS:
1478 +      if (globals->haveZconstraints()){
1479 +        setupZConstraint(info[k]);
1480 +        myNPTim = new ZConstraint<NPTim<RealIntegrator> >( &(info[k]), the_ff );
1481 +      }
1482 +      else
1483 +        myNPTim = new NPTim<RealIntegrator>( &(info[k]), the_ff );
1484 +
1485 +        myNPTim->setTargetTemp( globals->getTargetTemp());
1486 +          
1487 +      if (globals->haveTargetPressure())
1488 +        myNPTim->setTargetPressure(globals->getTargetPressure());
1489 +      else {
1490 +        sprintf( painCave.errMsg,
1491 +                  "SimSetup error: If you use a constant pressure\n"
1492 +                  "    ensemble, you must set targetPressure in the BASS file.\n");
1493 +        painCave.isFatal = 1;
1494 +        simError();
1495 +      }
1496 +          
1497 +      if( globals->haveTauThermostat() )
1498 +        myNPTim->setTauThermostat( globals->getTauThermostat() );
1499 +      else{
1500 +        sprintf( painCave.errMsg,
1501 +                  "SimSetup error: If you use an NPT\n"
1502 +                  "    ensemble, you must set tauThermostat.\n");
1503 +        painCave.isFatal = 1;
1504 +        simError();
1505 +      }
1506 +          
1507 +      if( globals->haveTauBarostat() )
1508 +        myNPTim->setTauBarostat( globals->getTauBarostat() );
1509 +      else{
1510 +        sprintf( painCave.errMsg,
1511 +                   "SimSetup error: If you use an NPT\n"
1512 +                   "    ensemble, you must set tauBarostat.\n");
1513 +        painCave.isFatal = 1;
1514 +        simError();
1515 +      }
1516 +      break;
1517 +      
1518 +    case NPTfm_ENS:
1519 +      if (globals->haveZconstraints()){
1520 +        setupZConstraint(info[k]);
1521 +        myNPTfm = new ZConstraint<NPTfm<RealIntegrator> >( &(info[k]), the_ff );
1522 +      }
1523 +      else
1524 +        myNPTfm = new NPTfm<RealIntegrator>( &(info[k]), the_ff );
1525 +
1526 +      myNPTfm->setTargetTemp( globals->getTargetTemp());
1527 +
1528 +      if (globals->haveTargetPressure())
1529 +        myNPTfm->setTargetPressure(globals->getTargetPressure());
1530 +      else {
1531 +        sprintf( painCave.errMsg,
1532 +                  "SimSetup error: If you use a constant pressure\n"
1533 +                  "    ensemble, you must set targetPressure in the BASS file.\n");
1534 +        painCave.isFatal = 1;
1535 +        simError();
1536 +      }
1537 +
1538 +      if( globals->haveTauThermostat() )
1539 +        myNPTfm->setTauThermostat( globals->getTauThermostat() );
1540 +      else{
1541 +        sprintf( painCave.errMsg,
1542 +                  "SimSetup error: If you use an NPT\n"
1543 +                  "    ensemble, you must set tauThermostat.\n");
1544 +        painCave.isFatal = 1;
1545 +        simError();
1546 +      }
1547 +
1548 +      if( globals->haveTauBarostat() )
1549 +        myNPTfm->setTauBarostat( globals->getTauBarostat() );
1550 +      else{
1551 +        sprintf( painCave.errMsg,
1552 +                  "SimSetup error: If you use an NPT\n"
1553 +                  "    ensemble, you must set tauBarostat.\n");
1554 +        painCave.isFatal = 1;
1555 +        simError();
1556 +      }
1557 +      break;
1558 +      
1559 +    default:
1560 +      sprintf( painCave.errMsg,
1561 +                 "SimSetup Error. Unrecognized ensemble in case statement.\n");
1562 +      painCave.isFatal = 1;
1563 +      simError();
1564 +    }
1565 +  }
1566 + }
1567 +
1568 + void SimSetup::initFortran( void ){
1569 +
1570 +  info[0].refreshSim();
1571 +  
1572 +  if( !strcmp( info[0].mixingRule, "standard") ){
1573 +    the_ff->initForceField( LB_MIXING_RULE );
1574 +  }
1575 +  else if( !strcmp( info[0].mixingRule, "explicit") ){
1576 +    the_ff->initForceField( EXPLICIT_MIXING_RULE );
1577 +  }
1578 +  else{
1579 +    sprintf( painCave.errMsg,
1580 +       "SimSetup Error: unknown mixing rule -> \"%s\"\n",
1581 +       info[0].mixingRule );
1582 +    painCave.isFatal = 1;
1583 +    simError();
1584 +  }
1585 +
1586 +
1587 + #ifdef IS_MPI
1588 +  strcpy( checkPointMsg,
1589 +    "Successfully intialized the mixingRule for Fortran." );
1590 +  MPIcheckPoint();
1591   #endif // is_mpi
1592  
1593 + }
1594  
1595 <  if( info->n_SRI ){
1595 > void SimSetup::setupZConstraint(SimInfo& theInfo)
1596 > {
1597 >  int nZConstraints;
1598 >  ZconStamp** zconStamp;
1599 >
1600 >  if(globals->haveZconstraintTime()){  
1601      
1602 <    Exclude::createArray(info->n_SRI);
1603 <    the_excludes = new Exclude*[info->n_SRI];
1604 <    for( int ex=0; ex<info->n_SRI; ex++) the_excludes[ex] = new Exclude(ex);
1605 <    info->globalExcludes = new int;
1606 <    info->n_exclude = info->n_SRI;
1602 >    //add sample time of z-constraint  into SimInfo's property list                    
1603 >    DoubleData* zconsTimeProp = new DoubleData();
1604 >    zconsTimeProp->setID(ZCONSTIME_ID);
1605 >    zconsTimeProp->setData(globals->getZconsTime());
1606 >    theInfo.addProperty(zconsTimeProp);
1607    }
1608    else{
1609 <    
1610 <    Exclude::createArray( 1 );
1611 <    the_excludes = new Exclude*;
1612 <    the_excludes[0] = new Exclude(0);
1613 <    the_excludes[0]->setPair( 0,0 );
1464 <    info->globalExcludes = new int;
1465 <    info->globalExcludes[0] = 0;
1466 <    info->n_exclude = 0;
1609 >    sprintf( painCave.errMsg,
1610 >       "ZConstraint error: If you use an ZConstraint\n"
1611 >       " , you must set sample time.\n");
1612 >    painCave.isFatal = 1;
1613 >    simError();      
1614    }
1615  
1616 <  // set the arrays into the SimInfo object
1616 >  //push zconsTol into siminfo, if user does not specify
1617 >  //value for zconsTol, a default value will be used
1618 >  DoubleData* zconsTol = new DoubleData();
1619 >  zconsTol->setID(ZCONSTOL_ID);
1620 >  if(globals->haveZconsTol()){
1621 >    zconsTol->setData(globals->getZconsTol());
1622 >  }
1623 >  else{
1624 >  double defaultZConsTol = 0.01;
1625 >    sprintf( painCave.errMsg,
1626 >       "ZConstraint Waring: Tolerance for z-constraint methodl is not specified\n"
1627 >       " , default value %f is used.\n", defaultZConsTol);
1628 >    painCave.isFatal = 0;
1629 >    simError();      
1630  
1631 <  info->atoms = the_atoms;
1632 <  info->molecules = the_molecules;
1633 <  info->nGlobalExcludes = 0;
1474 <  info->excludes = the_excludes;
1631 >    zconsTol->setData(defaultZConsTol);
1632 >  }
1633 >  theInfo.addProperty(zconsTol);
1634  
1635 <  the_ff->setSimInfo( info );
1635 >  //set Force Substraction Policy
1636 >  StringData* zconsForcePolicy =  new StringData();
1637 >  zconsForcePolicy->setID(ZCONSFORCEPOLICY_ID);
1638 >  
1639 >  if(globals->haveZconsForcePolicy()){
1640 >    zconsForcePolicy->setData(globals->getZconsForcePolicy());
1641 >  }  
1642 >  else{
1643 >     sprintf( painCave.errMsg,
1644 >             "ZConstraint Warning: User does not set force substraction policy, "
1645 >             "average force substraction policy is used\n");
1646 >     painCave.isFatal = 0;
1647 >     simError();
1648 >     zconsForcePolicy->setData("BYNUMBER");
1649 >  }
1650 >
1651 > theInfo.addProperty(zconsForcePolicy);
1652 >
1653 >  //Determine the name of ouput file and add it into SimInfo's property list
1654 >  //Be careful, do not use inFileName, since it is a pointer which
1655 >  //point to a string at master node, and slave nodes do not contain that string
1656 >  
1657 >  string zconsOutput(theInfo.finalName);
1658 >  
1659 >  zconsOutput = zconsOutput.substr(0, zconsOutput.rfind(".")) + ".fz";
1660 >  
1661 >  StringData* zconsFilename = new StringData();
1662 >  zconsFilename->setID(ZCONSFILENAME_ID);
1663 >  zconsFilename->setData(zconsOutput);
1664 >  
1665 >  theInfo.addProperty(zconsFilename);
1666 >  
1667 >  //setup index, pos and other parameters of z-constraint molecules
1668 >  nZConstraints = globals->getNzConstraints();
1669 >  theInfo.nZconstraints = nZConstraints;
1670  
1671 +  zconStamp = globals->getZconStamp();
1672 +  ZConsParaItem tempParaItem;
1673 +
1674 +  ZConsParaData* zconsParaData = new ZConsParaData();
1675 +  zconsParaData->setID(ZCONSPARADATA_ID);
1676 +
1677 +  for(int i = 0; i < nZConstraints; i++){
1678 +    tempParaItem.havingZPos = zconStamp[i]->haveZpos();
1679 +    tempParaItem.zPos = zconStamp[i]->getZpos();
1680 +    tempParaItem.zconsIndex = zconStamp[i]->getMolIndex();
1681 +    tempParaItem.kRatio = zconStamp[i]->getKratio();
1682 +
1683 +    zconsParaData->addItem(tempParaItem);
1684 +  }
1685 +
1686 +  //sort the parameters by index of molecules
1687 +  zconsParaData->sortByIndex();
1688 +  
1689 +  //push data into siminfo, therefore, we can retrieve later
1690 +  theInfo.addProperty(zconsParaData);
1691 +      
1692   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines