ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE_old/src/mdtools/libmdCode/SimSetup.cpp
Revision: 363
Committed: Tue Mar 18 21:27:53 2003 UTC (21 years, 5 months ago) by mmeineke
File size: 26720 byte(s)
Log Message:
 last little changes before compiling and debuging

File Contents

# User Rev Content
1 mmeineke 270 #include <cstdlib>
2     #include <iostream>
3     #include <cmath>
4    
5     #include "SimSetup.hpp"
6     #include "parse_me.h"
7     #include "Integrator.hpp"
8     #include "simError.h"
9    
10     #ifdef IS_MPI
11     #include "mpiBASS.h"
12     #include "mpiSimulation.hpp"
13     #endif
14    
15     SimSetup::SimSetup(){
16     stamps = new MakeStamps();
17     globals = new Globals();
18    
19     #ifdef IS_MPI
20     strcpy( checkPointMsg, "SimSetup creation successful" );
21     MPIcheckPoint();
22     #endif // IS_MPI
23     }
24    
25     SimSetup::~SimSetup(){
26     delete stamps;
27     delete globals;
28     }
29    
30     void SimSetup::parseFile( char* fileName ){
31    
32     #ifdef IS_MPI
33     if( worldRank == 0 ){
34     #endif // is_mpi
35    
36     inFileName = fileName;
37     set_interface_stamps( stamps, globals );
38    
39     #ifdef IS_MPI
40     mpiEventInit();
41     #endif
42    
43     yacc_BASS( fileName );
44    
45     #ifdef IS_MPI
46     throwMPIEvent(NULL);
47     }
48     else receiveParse();
49     #endif
50    
51     }
52    
53     #ifdef IS_MPI
54     void SimSetup::receiveParse(void){
55    
56     set_interface_stamps( stamps, globals );
57     mpiEventInit();
58     MPIcheckPoint();
59     mpiEventLoop();
60    
61     }
62    
63     #endif // is_mpi
64    
65     void SimSetup::createSim( void ){
66    
67     MakeStamps *the_stamps;
68     Globals* the_globals;
69     int i, j;
70    
71     // get the stamps and globals;
72     the_stamps = stamps;
73     the_globals = globals;
74    
75     // 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();
79    
80     // get the ones we know are there, yet still may need some work.
81     n_components = the_globals->getNComponents();
82     strcpy( force_field, the_globals->getForceField() );
83     strcpy( ensemble, the_globals->getEnsemble() );
84 chuckv 290 strcpy( simnfo->ensemble, ensemble );
85 mmeineke 270
86 chuckv 290 strcpy( simnfo->mixingRule, the_globals->getMixingRule() );
87     simnfo->usePBC = the_globals->getPBC();
88    
89    
90    
91 mmeineke 270 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     }
102    
103     #ifdef IS_MPI
104     strcpy( checkPointMsg, "ForceField creation successful" );
105     MPIcheckPoint();
106     #endif // is_mpi
107    
108 chuckv 290
109    
110 mmeineke 270 // 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];
114    
115     if( !the_globals->haveNMol() ){
116     // we don't have the total number of molecules, so we assume it is
117     // given in each component
118    
119     tot_nmol = 0;
120     for( i=0; i<n_components; i++ ){
121    
122     if( !the_components[i]->haveNMol() ){
123     // we have a problem
124     sprintf( painCave.errMsg,
125     "SimSetup Error. No global NMol or component NMol"
126     " given. Cannot calculate the number of atoms.\n" );
127     painCave.isFatal = 1;
128     simError();
129     }
130    
131     tot_nmol += the_components[i]->getNMol();
132     components_nmol[i] = the_components[i]->getNMol();
133     }
134     }
135     else{
136     sprintf( painCave.errMsg,
137     "SimSetup error.\n"
138     "\tSorry, the ability to specify total"
139     " nMols and then give molfractions in the components\n"
140     "\tis not currently supported."
141     " Please give nMol in the components.\n" );
142     painCave.isFatal = 1;
143     simError();
144    
145    
146     // tot_nmol = the_globals->getNMol();
147    
148     // //we have the total number of molecules, now we check for molfractions
149     // for( i=0; i<n_components; i++ ){
150    
151     // if( !the_components[i]->haveMolFraction() ){
152    
153     // if( !the_components[i]->haveNMol() ){
154     // //we have a problem
155     // std::cerr << "SimSetup error. Neither molFraction nor "
156     // << " nMol was given in component
157    
158     }
159    
160     #ifdef IS_MPI
161     strcpy( checkPointMsg, "Have the number of components" );
162     MPIcheckPoint();
163     #endif // is_mpi
164    
165     // make an array of molecule stamps that match the components used.
166     // also extract the used stamps out into a separate linked list
167    
168     simnfo->nComponents = n_components;
169     simnfo->componentsNmol = components_nmol;
170     simnfo->compStamps = comp_stamps;
171     simnfo->headStamp = new LinkedMolStamp();
172    
173     char* id;
174     LinkedMolStamp* headStamp = simnfo->headStamp;
175     LinkedMolStamp* currentStamp = NULL;
176     for( i=0; i<n_components; i++ ){
177    
178     id = the_components[i]->getType();
179     comp_stamps[i] = NULL;
180    
181     // check to make sure the component isn't already in the list
182    
183     comp_stamps[i] = headStamp->match( id );
184     if( comp_stamps[i] == NULL ){
185    
186     // extract the component from the list;
187    
188     currentStamp = the_stamps->extractMolStamp( id );
189     if( currentStamp == NULL ){
190     sprintf( painCave.errMsg,
191     "SimSetup error: Component \"%s\" was not found in the "
192     "list of declared molecules\n",
193     id );
194     painCave.isFatal = 1;
195     simError();
196     }
197    
198     headStamp->add( currentStamp );
199     comp_stamps[i] = headStamp->match( id );
200     }
201     }
202    
203     #ifdef IS_MPI
204     strcpy( checkPointMsg, "Component stamps successfully extracted\n" );
205     MPIcheckPoint();
206     #endif // is_mpi
207    
208    
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++ ){
218    
219     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     }
224    
225     tot_SRI = tot_bonds + tot_bends + tot_torsions;
226    
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;
233    
234    
235     #ifdef IS_MPI
236    
237     // divide the molecules among processors here.
238    
239     mpiSim = new mpiSimulation( simnfo );
240    
241    
242    
243     globalIndex = mpiSim->divideLabor();
244    
245    
246    
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     }
273     }
274     local_SRI = local_bonds + local_bends + local_torsions;
275    
276    
277     simnfo->n_atoms = mpiSim->getMyNlocal();
278    
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." );
296     MPIcheckPoint();
297    
298    
299     #endif // is_mpi
300    
301    
302     // create the atom and short range interaction arrays
303    
304     Atom::createArrays(simnfo->n_atoms);
305     the_atoms = new Atom*[simnfo->n_atoms];
306     the_molecules = new Molecule[simnfo->n_mol];
307    
308    
309     if( simnfo->n_SRI ){
310     the_sris = new SRI*[simnfo->n_SRI];
311 mmeineke 362 the_excludes = new int[2 * simnfo->n_SRI];
312     simnfo->globalExcludes = new int;
313 mmeineke 270 }
314 mmeineke 362 else{
315     the_excludes = new int;
316     simnfo->globalExcludes = new int;
317     }
318 mmeineke 270
319     // set the arrays into the SimInfo object
320    
321     simnfo->atoms = the_atoms;
322     simnfo->sr_interactions = the_sris;
323     simnfo->n_exclude = tot_SRI;
324 mmeineke 362 simnfo->nGlobalExcludes = 0;
325 mmeineke 270 simnfo->excludes = the_excludes;
326    
327    
328     // get some of the tricky things that may still be in the globals
329    
330     if( simnfo->n_dipoles ){
331    
332     if( !the_globals->haveRRF() ){
333     sprintf( painCave.errMsg,
334     "SimSetup Error, system has dipoles, but no rRF was set.\n");
335     painCave.isFatal = 1;
336     simError();
337     }
338     if( !the_globals->haveDielectric() ){
339     sprintf( painCave.errMsg,
340     "SimSetup Error, system has dipoles, but no"
341     " dielectric was set.\n" );
342     painCave.isFatal = 1;
343     simError();
344     }
345    
346     simnfo->rRF = the_globals->getRRF();
347     simnfo->dielectric = the_globals->getDielectric();
348     }
349    
350     #ifdef IS_MPI
351     strcpy( checkPointMsg, "rRf and dielectric check out" );
352     MPIcheckPoint();
353     #endif // is_mpi
354    
355     if( the_globals->haveBox() ){
356     simnfo->box_x = the_globals->getBox();
357     simnfo->box_y = the_globals->getBox();
358     simnfo->box_z = the_globals->getBox();
359     }
360     else if( the_globals->haveDensity() ){
361    
362     double vol;
363     vol = (double)tot_nmol / the_globals->getDensity();
364     simnfo->box_x = pow( vol, ( 1.0 / 3.0 ) );
365     simnfo->box_y = simnfo->box_x;
366     simnfo->box_z = simnfo->box_x;
367     }
368     else{
369     if( !the_globals->haveBoxX() ){
370     sprintf( painCave.errMsg,
371     "SimSetup error, no periodic BoxX size given.\n" );
372     painCave.isFatal = 1;
373     simError();
374     }
375     simnfo->box_x = the_globals->getBoxX();
376    
377     if( !the_globals->haveBoxY() ){
378     sprintf( painCave.errMsg,
379     "SimSetup error, no periodic BoxY size given.\n" );
380     painCave.isFatal = 1;
381     simError();
382     }
383     simnfo->box_y = the_globals->getBoxY();
384    
385     if( !the_globals->haveBoxZ() ){
386     sprintf( painCave.errMsg,
387     "SimSetup error, no periodic BoxZ size given.\n" );
388     painCave.isFatal = 1;
389     simError();
390     }
391     simnfo->box_z = the_globals->getBoxZ();
392     }
393    
394     #ifdef IS_MPI
395     strcpy( checkPointMsg, "Box size set up" );
396     MPIcheckPoint();
397     #endif // is_mpi
398    
399    
400     // initialize the arrays
401    
402     the_ff->setSimInfo( simnfo );
403    
404     makeAtoms();
405 mmeineke 362 simnfo->identArray = new int[simnfo->n_atoms];
406     for(i=0; i<simnfo->n_atoms; i++){
407     simnfo->identArray[i] = the_atoms[i]->getIdent();
408     }
409    
410 mmeineke 270 if( tot_bonds ){
411     makeBonds();
412     }
413    
414     if( tot_bends ){
415     makeBends();
416     }
417    
418     if( tot_torsions ){
419     makeTorsions();
420     }
421    
422    
423    
424    
425    
426    
427     if( the_globals->haveInitialConfig() ){
428    
429     InitializeFromFile* fileInit;
430     #ifdef IS_MPI // is_mpi
431     if( worldRank == 0 ){
432     #endif //is_mpi
433     fileInit = new InitializeFromFile( the_globals->getInitialConfig() );
434     #ifdef IS_MPI
435     }else fileInit = new InitializeFromFile( NULL );
436     #endif
437     fileInit->read_xyz( simnfo ); // default velocities on
438    
439     delete fileInit;
440     }
441     else{
442    
443     #ifdef IS_MPI
444    
445     // no init from bass
446    
447     sprintf( painCave.errMsg,
448     "Cannot intialize a parallel simulation without an initial configuration file.\n" );
449     painCave.isFatal;
450     simError();
451    
452     #else
453    
454     initFromBass();
455    
456    
457     #endif
458     }
459    
460     #ifdef IS_MPI
461     strcpy( checkPointMsg, "Successfully read in the initial configuration" );
462     MPIcheckPoint();
463     #endif // is_mpi
464    
465    
466    
467    
468    
469    
470    
471     #ifdef IS_MPI
472     if( worldRank == 0 ){
473     #endif // is_mpi
474    
475     if( the_globals->haveFinalConfig() ){
476     strcpy( simnfo->finalName, the_globals->getFinalConfig() );
477     }
478     else{
479     strcpy( simnfo->finalName, inFileName );
480     char* endTest;
481     int nameLength = strlen( simnfo->finalName );
482     endTest = &(simnfo->finalName[nameLength - 5]);
483     if( !strcmp( endTest, ".bass" ) ){
484     strcpy( endTest, ".eor" );
485     }
486     else if( !strcmp( endTest, ".BASS" ) ){
487     strcpy( endTest, ".eor" );
488     }
489     else{
490     endTest = &(simnfo->finalName[nameLength - 4]);
491     if( !strcmp( endTest, ".bss" ) ){
492     strcpy( endTest, ".eor" );
493     }
494     else if( !strcmp( endTest, ".mdl" ) ){
495     strcpy( endTest, ".eor" );
496     }
497     else{
498     strcat( simnfo->finalName, ".eor" );
499     }
500     }
501     }
502    
503     // make the sample and status out names
504    
505     strcpy( simnfo->sampleName, inFileName );
506     char* endTest;
507     int nameLength = strlen( simnfo->sampleName );
508     endTest = &(simnfo->sampleName[nameLength - 5]);
509     if( !strcmp( endTest, ".bass" ) ){
510     strcpy( endTest, ".dump" );
511     }
512     else if( !strcmp( endTest, ".BASS" ) ){
513     strcpy( endTest, ".dump" );
514     }
515     else{
516     endTest = &(simnfo->sampleName[nameLength - 4]);
517     if( !strcmp( endTest, ".bss" ) ){
518     strcpy( endTest, ".dump" );
519     }
520     else if( !strcmp( endTest, ".mdl" ) ){
521     strcpy( endTest, ".dump" );
522     }
523     else{
524     strcat( simnfo->sampleName, ".dump" );
525     }
526     }
527    
528     strcpy( simnfo->statusName, inFileName );
529     nameLength = strlen( simnfo->statusName );
530     endTest = &(simnfo->statusName[nameLength - 5]);
531     if( !strcmp( endTest, ".bass" ) ){
532     strcpy( endTest, ".stat" );
533     }
534     else if( !strcmp( endTest, ".BASS" ) ){
535     strcpy( endTest, ".stat" );
536     }
537     else{
538     endTest = &(simnfo->statusName[nameLength - 4]);
539     if( !strcmp( endTest, ".bss" ) ){
540     strcpy( endTest, ".stat" );
541     }
542     else if( !strcmp( endTest, ".mdl" ) ){
543     strcpy( endTest, ".stat" );
544     }
545     else{
546     strcat( simnfo->statusName, ".stat" );
547     }
548     }
549    
550     #ifdef IS_MPI
551     }
552     #endif // is_mpi
553    
554     // set the status, sample, and themal kick times
555    
556     if( the_globals->haveSampleTime() ){
557     simnfo->sampleTime = the_globals->getSampleTime();
558     simnfo->statusTime = simnfo->sampleTime;
559     simnfo->thermalTime = simnfo->sampleTime;
560     }
561     else{
562     simnfo->sampleTime = the_globals->getRunTime();
563     simnfo->statusTime = simnfo->sampleTime;
564     simnfo->thermalTime = simnfo->sampleTime;
565     }
566    
567     if( the_globals->haveStatusTime() ){
568     simnfo->statusTime = the_globals->getStatusTime();
569     }
570    
571     if( the_globals->haveThermalTime() ){
572     simnfo->thermalTime = the_globals->getThermalTime();
573     }
574    
575     // check for the temperature set flag
576    
577     if( the_globals->haveTempSet() ) simnfo->setTemp = the_globals->getTempSet();
578    
579    
580     // // make the longe range forces and the integrator
581    
582     // new AllLong( simnfo );
583    
584     if( !strcmp( force_field, "TraPPE" ) ) new Verlet( *simnfo, the_ff );
585     if( !strcmp( force_field, "DipoleTest" ) ) new Symplectic( simnfo, the_ff );
586     if( !strcmp( force_field, "TraPPE_Ex" ) ) new Symplectic( simnfo, the_ff );
587     if( !strcmp( force_field, "LJ" ) ) new Verlet( *simnfo, the_ff );
588    
589 mmeineke 362
590    
591     // initialize the Fortran
592    
593     simnfo->refreshSim();
594    
595     if( !stcmp( simnfo->mixingRule, "standard") ){
596     the_ff->initForceField( LB_MIXING_RULE );
597     }
598     else if( !stcmp( simnfo->mixingRule, "explicit") ){
599     the_ff->initForceField( EXPLICIT_MIXING_RULE );
600     }
601     else{
602     sprintf( painCave.errMsg,
603     "SimSetup Error: unknown mixing rule -> \"%s\"\n",
604     simnfo->mixingRule );
605     painCave.isFatal = 1;
606     simError();
607     }
608    
609    
610     #ifdef IS_MPI
611     strcpy( checkPointMsg,
612     "Successfully intialized the mixingRule for Fortran." );
613     MPIcheckPoint();
614     #endif // is_mpi
615 mmeineke 270 }
616    
617     void SimSetup::makeAtoms( void ){
618    
619     int i, j, k, index;
620     double ux, uy, uz, uSqr, u;
621     AtomStamp* current_atom;
622 mmeineke 363
623 mmeineke 270 DirectionalAtom* dAtom;
624     int molIndex, molStart, molEnd, nMemb, lMolIndex;
625    
626     lMolIndex = 0;
627     molIndex = 0;
628     index = 0;
629     for( i=0; i<n_components; i++ ){
630    
631     for( j=0; j<components_nmol[i]; j++ ){
632    
633     #ifdef IS_MPI
634     if( mpiSim->getMyMolStart() <= molIndex &&
635     molIndex <= mpiSim->getMyMolEnd() ){
636     #endif // is_mpi
637    
638     molStart = index;
639     nMemb = comp_stamps[i]->getNAtoms();
640     for( k=0; k<comp_stamps[i]->getNAtoms(); k++ ){
641    
642     current_atom = comp_stamps[i]->getAtom( k );
643     if( current_atom->haveOrientation() ){
644    
645     dAtom = new DirectionalAtom(index);
646     simnfo->n_oriented++;
647     the_atoms[index] = dAtom;
648    
649     ux = current_atom->getOrntX();
650     uy = current_atom->getOrntY();
651     uz = current_atom->getOrntZ();
652    
653     uSqr = (ux * ux) + (uy * uy) + (uz * uz);
654    
655     u = sqrt( uSqr );
656     ux = ux / u;
657     uy = uy / u;
658     uz = uz / u;
659    
660     dAtom->setSUx( ux );
661     dAtom->setSUy( uy );
662     dAtom->setSUz( uz );
663     }
664     else{
665     the_atoms[index] = new GeneralAtom(index);
666     }
667     the_atoms[index]->setType( current_atom->getType() );
668     the_atoms[index]->setIndex( index );
669    
670     // increment the index and repeat;
671     index++;
672     }
673    
674     molEnd = index -1;
675     the_molecules[lMolIndex].setNMembers( nMemb );
676     the_molecules[lMolIndex].setStartAtom( molStart );
677     the_molecules[lMolIndex].setEndAtom( molEnd );
678     the_molecules[lMolIndex].setStampID( i );
679     lMolIndex++;
680    
681     #ifdef IS_MPI
682     }
683     #endif //is_mpi
684    
685     molIndex++;
686     }
687     }
688    
689     #ifdef IS_MPI
690     for( i=0; i<mpiSim->getMyNlocal(); i++ ) the_atoms[i]->setGlobalIndex( globalIndex[i] );
691    
692     delete[] globalIndex;
693    
694     mpiSim->mpiRefresh();
695     #endif //IS_MPI
696    
697     the_ff->initializeAtoms();
698     }
699    
700     void SimSetup::makeBonds( void ){
701    
702     int i, j, k, index, offset, molIndex;
703     bond_pair* the_bonds;
704     BondStamp* current_bond;
705    
706     the_bonds = new bond_pair[tot_bonds];
707     index = 0;
708     offset = 0;
709     molIndex = 0;
710    
711     for( i=0; i<n_components; i++ ){
712    
713     for( j=0; j<components_nmol[i]; j++ ){
714    
715     #ifdef IS_MPI
716     if( mpiSim->getMyMolStart() <= molIndex &&
717     molIndex <= mpiSim->getMyMolEnd() ){
718     #endif // is_mpi
719    
720     for( k=0; k<comp_stamps[i]->getNBonds(); k++ ){
721    
722     current_bond = comp_stamps[i]->getBond( k );
723     the_bonds[index].a = current_bond->getA() + offset;
724     the_bonds[index].b = current_bond->getB() + offset;
725 mmeineke 362
726     exI = the_bonds[index].a;
727     exJ = the_bonds[index].b;
728    
729     // exclude_I must always be the smaller of the pair
730     if( exI > exJ ){
731     tempEx = exI;
732     exI = exJ;
733     exJ = tempEx;
734     }
735    
736 mmeineke 270
737 mmeineke 362 #ifdef IS_MPI
738    
739     the_excludes[index*2] =
740     the_atoms[exI]->getGlobalIndex() + 1;
741     the_excludes[index*2 + 1] =
742     the_atoms[exJ]->getGlobalIndex() + 1;
743    
744     #else // isn't MPI
745 mmeineke 270
746 mmeineke 362 the_excludes[index*2] = exI + 1;
747     the_excludes[index*2 + 1] = exJ + 1;
748     // fortran index from 1 (hence the +1 in the indexing)
749     #endif //is_mpi
750    
751 mmeineke 270 // increment the index and repeat;
752     index++;
753     }
754     offset += comp_stamps[i]->getNAtoms();
755    
756     #ifdef IS_MPI
757     }
758     #endif //is_mpi
759    
760     molIndex++;
761     }
762     }
763    
764     the_ff->initializeBonds( the_bonds );
765     }
766    
767     void SimSetup::makeBends( void ){
768    
769 mmeineke 362 int i, j, k, index, offset, molIndex, exI, exJ;
770 mmeineke 270 bend_set* the_bends;
771     BendStamp* current_bend;
772 mmeineke 308 LinkedAssign* extras;
773     LinkedAssign* current_extra;
774    
775 mmeineke 270
776     the_bends = new bend_set[tot_bends];
777     index = 0;
778     offset = 0;
779     molIndex = 0;
780     for( i=0; i<n_components; i++ ){
781    
782     for( j=0; j<components_nmol[i]; j++ ){
783    
784     #ifdef IS_MPI
785     if( mpiSim->getMyMolStart() <= molIndex &&
786     molIndex <= mpiSim->getMyMolEnd() ){
787     #endif // is_mpi
788    
789     for( k=0; k<comp_stamps[i]->getNBends(); k++ ){
790    
791     current_bend = comp_stamps[i]->getBend( k );
792     the_bends[index].a = current_bend->getA() + offset;
793     the_bends[index].b = current_bend->getB() + offset;
794     the_bends[index].c = current_bend->getC() + offset;
795    
796 mmeineke 348 if( current_bend->haveExtras() ){
797 mmeineke 308
798     extras = current_bend->getExtras();
799     current_extra = extras;
800    
801     while( current_extra != NULL ){
802     if( !strcmp( current_extra->getlhs(), "ghostVectorSource" )){
803    
804     switch( current_extra->getType() ){
805    
806     case 0:
807 mmeineke 311 the_bends[index].ghost =
808     current_extra->getInt() + offset;
809 mmeineke 308 the_bends[index].isGhost = 1;
810     break;
811    
812     case 1:
813 mmeineke 311 the_bends[index].ghost =
814     (int)current_extra->getDouble() + offset;
815 mmeineke 308 the_bends[index].isGhost = 1;
816     break;
817    
818     default:
819     sprintf( painCave.errMsg,
820     "SimSetup Error: ghostVectorSource was neiter a "
821     "double nor an int.\n"
822     "-->Bend[%d] in %s\n",
823     k, comp_stamps[i]->getID() );
824     painCave.isFatal = 1;
825     simError();
826     }
827     }
828    
829     else{
830    
831     sprintf( painCave.errMsg,
832     "SimSetup Error: unhandled bend assignment:\n"
833     " -->%s in Bend[%d] in %s\n",
834     current_extra->getlhs(),
835     k, comp_stamps[i]->getID() );
836     painCave.isFatal = 1;
837     simError();
838     }
839    
840 mmeineke 348 current_extra = current_extra->getNext();
841 mmeineke 308 }
842     }
843 mmeineke 270
844 mmeineke 308 if( !the_bends[index].isGhost ){
845    
846 mmeineke 362 exI = the_bends[index].a;
847     exJ = the_bends[index].c;
848 mmeineke 308 }
849     else{
850    
851 mmeineke 362 exI = the_bends[index].a;
852     exJ = the_bends[index].b;
853 mmeineke 308 }
854    
855 mmeineke 362 // exclude_I must always be the smaller of the pair
856     if( exI > exJ ){
857     tempEx = exI;
858     exI = exJ;
859     exJ = tempEx;
860     }
861    
862    
863     #ifdef IS_MPI
864    
865     the_excludes[(index + tot_bonds)*2] =
866     the_atoms[exI]->getGlobalIndex() + 1;
867     the_excludes[(index + tot_bonds)*2 + 1] =
868     the_atoms[exJ]->getGlobalIndex() + 1;
869    
870     #else // isn't MPI
871    
872     the_excludes[(index + tot_bonds)*2] = exI + 1;
873     the_excludes[(index + tot_bonds)*2 + 1] = exJ + 1;
874     // fortran index from 1 (hence the +1 in the indexing)
875     #endif //is_mpi
876    
877    
878 mmeineke 270 // increment the index and repeat;
879     index++;
880     }
881     offset += comp_stamps[i]->getNAtoms();
882    
883     #ifdef IS_MPI
884     }
885     #endif //is_mpi
886    
887     molIndex++;
888     }
889     }
890    
891 mmeineke 308 #ifdef IS_MPI
892     sprintf( checkPointMsg,
893     "Successfully created the bends list.\n" );
894     MPIcheckPoint();
895     #endif // is_mpi
896    
897    
898 mmeineke 270 the_ff->initializeBends( the_bends );
899     }
900    
901     void SimSetup::makeTorsions( void ){
902    
903 mmeineke 362 int i, j, k, index, offset, molIndex, exI, exJ, tempEx;
904 mmeineke 270 torsion_set* the_torsions;
905     TorsionStamp* current_torsion;
906    
907     the_torsions = new torsion_set[tot_torsions];
908     index = 0;
909     offset = 0;
910     molIndex = 0;
911     for( i=0; i<n_components; i++ ){
912    
913     for( j=0; j<components_nmol[i]; j++ ){
914    
915     #ifdef IS_MPI
916     if( mpiSim->getMyMolStart() <= molIndex &&
917     molIndex <= mpiSim->getMyMolEnd() ){
918     #endif // is_mpi
919    
920     for( k=0; k<comp_stamps[i]->getNTorsions(); k++ ){
921    
922     current_torsion = comp_stamps[i]->getTorsion( k );
923     the_torsions[index].a = current_torsion->getA() + offset;
924     the_torsions[index].b = current_torsion->getB() + offset;
925     the_torsions[index].c = current_torsion->getC() + offset;
926     the_torsions[index].d = current_torsion->getD() + offset;
927    
928 mmeineke 362 exI = the_torsions[index].a;
929     exJ = the_torsions[index].d;
930 mmeineke 270
931 mmeineke 362
932     // exclude_I must always be the smaller of the pair
933     if( exI > exJ ){
934     tempEx = exI;
935     exI = exJ;
936     exJ = tempEx;
937     }
938    
939    
940     #ifdef IS_MPI
941    
942     the_excludes[(index + tot_bonds + tot_bends)*2] =
943     the_atoms[exI]->getGlobalIndex() + 1;
944     the_excludes[(index + tot_bonds + tot_bends)*2 + 1] =
945     the_atoms[exJ]->getGlobalIndex() + 1;
946    
947     #else // isn't MPI
948    
949     the_excludes[(index + tot_bonds + tot_bends)*2] = exI + 1;
950     the_excludes[(index + tot_bonds + tot_bends)*2 + 1] = exJ + 1;
951     // fortran indexes from 1 (hence the +1 in the indexing)
952     #endif //is_mpi
953    
954    
955 mmeineke 270 // increment the index and repeat;
956     index++;
957     }
958     offset += comp_stamps[i]->getNAtoms();
959    
960     #ifdef IS_MPI
961     }
962     #endif //is_mpi
963    
964     molIndex++;
965     }
966     }
967    
968     the_ff->initializeTorsions( the_torsions );
969     }
970    
971     void SimSetup::initFromBass( void ){
972    
973     int i, j, k;
974     int n_cells;
975     double cellx, celly, cellz;
976     double temp1, temp2, temp3;
977     int n_per_extra;
978     int n_extra;
979     int have_extra, done;
980    
981     temp1 = (double)tot_nmol / 4.0;
982     temp2 = pow( temp1, ( 1.0 / 3.0 ) );
983     temp3 = ceil( temp2 );
984    
985     have_extra =0;
986     if( temp2 < temp3 ){ // we have a non-complete lattice
987     have_extra =1;
988    
989     n_cells = (int)temp3 - 1;
990     cellx = simnfo->box_x / temp3;
991     celly = simnfo->box_y / temp3;
992     cellz = simnfo->box_z / temp3;
993     n_extra = tot_nmol - ( 4 * n_cells * n_cells * n_cells );
994     temp1 = ((double)n_extra) / ( pow( temp3, 3.0 ) - pow( n_cells, 3.0 ) );
995     n_per_extra = (int)ceil( temp1 );
996    
997     if( n_per_extra > 4){
998     sprintf( painCave.errMsg,
999     "SimSetup error. There has been an error in constructing"
1000     " the non-complete lattice.\n" );
1001     painCave.isFatal = 1;
1002     simError();
1003     }
1004     }
1005     else{
1006     n_cells = (int)temp3;
1007     cellx = simnfo->box_x / temp3;
1008     celly = simnfo->box_y / temp3;
1009     cellz = simnfo->box_z / temp3;
1010     }
1011    
1012     current_mol = 0;
1013     current_comp_mol = 0;
1014     current_comp = 0;
1015     current_atom_ndx = 0;
1016    
1017     for( i=0; i < n_cells ; i++ ){
1018     for( j=0; j < n_cells; j++ ){
1019     for( k=0; k < n_cells; k++ ){
1020    
1021     makeElement( i * cellx,
1022     j * celly,
1023     k * cellz );
1024    
1025     makeElement( i * cellx + 0.5 * cellx,
1026     j * celly + 0.5 * celly,
1027     k * cellz );
1028    
1029     makeElement( i * cellx,
1030     j * celly + 0.5 * celly,
1031     k * cellz + 0.5 * cellz );
1032    
1033     makeElement( i * cellx + 0.5 * cellx,
1034     j * celly,
1035     k * cellz + 0.5 * cellz );
1036     }
1037     }
1038     }
1039    
1040     if( have_extra ){
1041     done = 0;
1042    
1043     int start_ndx;
1044     for( i=0; i < (n_cells+1) && !done; i++ ){
1045     for( j=0; j < (n_cells+1) && !done; j++ ){
1046    
1047     if( i < n_cells ){
1048    
1049     if( j < n_cells ){
1050     start_ndx = n_cells;
1051     }
1052     else start_ndx = 0;
1053     }
1054     else start_ndx = 0;
1055    
1056     for( k=start_ndx; k < (n_cells+1) && !done; k++ ){
1057    
1058     makeElement( i * cellx,
1059     j * celly,
1060     k * cellz );
1061     done = ( current_mol >= tot_nmol );
1062    
1063     if( !done && n_per_extra > 1 ){
1064     makeElement( i * cellx + 0.5 * cellx,
1065     j * celly + 0.5 * celly,
1066     k * cellz );
1067     done = ( current_mol >= tot_nmol );
1068     }
1069    
1070     if( !done && n_per_extra > 2){
1071     makeElement( i * cellx,
1072     j * celly + 0.5 * celly,
1073     k * cellz + 0.5 * cellz );
1074     done = ( current_mol >= tot_nmol );
1075     }
1076    
1077     if( !done && n_per_extra > 3){
1078     makeElement( i * cellx + 0.5 * cellx,
1079     j * celly,
1080     k * cellz + 0.5 * cellz );
1081     done = ( current_mol >= tot_nmol );
1082     }
1083     }
1084     }
1085     }
1086     }
1087    
1088    
1089     for( i=0; i<simnfo->n_atoms; i++ ){
1090     simnfo->atoms[i]->set_vx( 0.0 );
1091     simnfo->atoms[i]->set_vy( 0.0 );
1092     simnfo->atoms[i]->set_vz( 0.0 );
1093     }
1094     }
1095    
1096     void SimSetup::makeElement( double x, double y, double z ){
1097    
1098     int k;
1099     AtomStamp* current_atom;
1100     DirectionalAtom* dAtom;
1101     double rotMat[3][3];
1102    
1103     for( k=0; k<comp_stamps[current_comp]->getNAtoms(); k++ ){
1104    
1105     current_atom = comp_stamps[current_comp]->getAtom( k );
1106     if( !current_atom->havePosition() ){
1107     sprintf( painCave.errMsg,
1108     "SimSetup:initFromBass error.\n"
1109     "\tComponent %s, atom %s does not have a position specified.\n"
1110     "\tThe initialization routine is unable to give a start"
1111     " position.\n",
1112     comp_stamps[current_comp]->getID(),
1113     current_atom->getType() );
1114     painCave.isFatal = 1;
1115     simError();
1116     }
1117    
1118     the_atoms[current_atom_ndx]->setX( x + current_atom->getPosX() );
1119     the_atoms[current_atom_ndx]->setY( y + current_atom->getPosY() );
1120     the_atoms[current_atom_ndx]->setZ( z + current_atom->getPosZ() );
1121    
1122     if( the_atoms[current_atom_ndx]->isDirectional() ){
1123    
1124     dAtom = (DirectionalAtom *)the_atoms[current_atom_ndx];
1125    
1126     rotMat[0][0] = 1.0;
1127     rotMat[0][1] = 0.0;
1128     rotMat[0][2] = 0.0;
1129    
1130     rotMat[1][0] = 0.0;
1131     rotMat[1][1] = 1.0;
1132     rotMat[1][2] = 0.0;
1133    
1134     rotMat[2][0] = 0.0;
1135     rotMat[2][1] = 0.0;
1136     rotMat[2][2] = 1.0;
1137    
1138     dAtom->setA( rotMat );
1139     }
1140    
1141     current_atom_ndx++;
1142     }
1143    
1144     current_mol++;
1145     current_comp_mol++;
1146    
1147     if( current_comp_mol >= components_nmol[current_comp] ){
1148    
1149     current_comp_mol = 0;
1150     current_comp++;
1151     }
1152     }