ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE_old/src/mdtools/libmdCode/SimSetup.cpp
Revision: 270
Committed: Fri Feb 14 17:08:46 2003 UTC (21 years, 6 months ago) by mmeineke
File size: 22847 byte(s)
Log Message:
added libmdCode and a couple help scripts

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 "LRI.hpp"
8     #include "Integrator.hpp"
9     #include "simError.h"
10    
11     #ifdef IS_MPI
12     #include "mpiBASS.h"
13     #include "mpiSimulation.hpp"
14     #endif
15    
16     SimSetup::SimSetup(){
17     stamps = new MakeStamps();
18     globals = new Globals();
19    
20     #ifdef IS_MPI
21     strcpy( checkPointMsg, "SimSetup creation successful" );
22     MPIcheckPoint();
23     #endif // IS_MPI
24     }
25    
26     SimSetup::~SimSetup(){
27     delete stamps;
28     delete globals;
29     }
30    
31     void SimSetup::parseFile( char* fileName ){
32    
33     #ifdef IS_MPI
34     if( worldRank == 0 ){
35     #endif // is_mpi
36    
37     inFileName = fileName;
38     set_interface_stamps( stamps, globals );
39    
40     #ifdef IS_MPI
41     mpiEventInit();
42     #endif
43    
44     yacc_BASS( fileName );
45    
46     #ifdef IS_MPI
47     throwMPIEvent(NULL);
48     }
49     else receiveParse();
50     #endif
51    
52     }
53    
54     #ifdef IS_MPI
55     void SimSetup::receiveParse(void){
56    
57     set_interface_stamps( stamps, globals );
58     mpiEventInit();
59     MPIcheckPoint();
60     mpiEventLoop();
61    
62     }
63    
64     #endif // is_mpi
65    
66     void SimSetup::createSim( void ){
67    
68     MakeStamps *the_stamps;
69     Globals* the_globals;
70     int i, j;
71    
72     // get the stamps and globals;
73     the_stamps = stamps;
74     the_globals = globals;
75    
76     // set the easy ones first
77     simnfo->target_temp = the_globals->getTargetTemp();
78     simnfo->dt = the_globals->getDt();
79     simnfo->run_time = the_globals->getRunTime();
80    
81     // get the ones we know are there, yet still may need some work.
82     n_components = the_globals->getNComponents();
83     strcpy( force_field, the_globals->getForceField() );
84     strcpy( ensemble, the_globals->getEnsemble() );
85    
86     if( !strcmp( force_field, "TraPPE" ) ) the_ff = new TraPPEFF();
87     else if( !strcmp( force_field, "DipoleTest" ) ) the_ff = new DipoleTestFF();
88     else if( !strcmp( force_field, "TraPPE_Ex" ) ) the_ff = new TraPPE_ExFF();
89     else if( !strcmp( force_field, "LJ" ) ) the_ff = new LJ_FF();
90     else{
91     sprintf( painCave.errMsg,
92     "SimSetup Error. Unrecognized force field -> %s\n",
93     force_field );
94     painCave.isFatal = 1;
95     simError();
96     }
97    
98     #ifdef IS_MPI
99     strcpy( checkPointMsg, "ForceField creation successful" );
100     MPIcheckPoint();
101     #endif // is_mpi
102    
103     // get the components and calculate the tot_nMol and indvidual n_mol
104     the_components = the_globals->getComponents();
105     components_nmol = new int[n_components];
106     comp_stamps = new MoleculeStamp*[n_components];
107    
108     if( !the_globals->haveNMol() ){
109     // we don't have the total number of molecules, so we assume it is
110     // given in each component
111    
112     tot_nmol = 0;
113     for( i=0; i<n_components; i++ ){
114    
115     if( !the_components[i]->haveNMol() ){
116     // we have a problem
117     sprintf( painCave.errMsg,
118     "SimSetup Error. No global NMol or component NMol"
119     " given. Cannot calculate the number of atoms.\n" );
120     painCave.isFatal = 1;
121     simError();
122     }
123    
124     tot_nmol += the_components[i]->getNMol();
125     components_nmol[i] = the_components[i]->getNMol();
126     }
127     }
128     else{
129     sprintf( painCave.errMsg,
130     "SimSetup error.\n"
131     "\tSorry, the ability to specify total"
132     " nMols and then give molfractions in the components\n"
133     "\tis not currently supported."
134     " Please give nMol in the components.\n" );
135     painCave.isFatal = 1;
136     simError();
137    
138    
139     // tot_nmol = the_globals->getNMol();
140    
141     // //we have the total number of molecules, now we check for molfractions
142     // for( i=0; i<n_components; i++ ){
143    
144     // if( !the_components[i]->haveMolFraction() ){
145    
146     // if( !the_components[i]->haveNMol() ){
147     // //we have a problem
148     // std::cerr << "SimSetup error. Neither molFraction nor "
149     // << " nMol was given in component
150    
151     }
152    
153     #ifdef IS_MPI
154     strcpy( checkPointMsg, "Have the number of components" );
155     MPIcheckPoint();
156     #endif // is_mpi
157    
158     // make an array of molecule stamps that match the components used.
159     // also extract the used stamps out into a separate linked list
160    
161     simnfo->nComponents = n_components;
162     simnfo->componentsNmol = components_nmol;
163     simnfo->compStamps = comp_stamps;
164     simnfo->headStamp = new LinkedMolStamp();
165    
166     char* id;
167     LinkedMolStamp* headStamp = simnfo->headStamp;
168     LinkedMolStamp* currentStamp = NULL;
169     for( i=0; i<n_components; i++ ){
170    
171     id = the_components[i]->getType();
172     comp_stamps[i] = NULL;
173    
174     // check to make sure the component isn't already in the list
175    
176     comp_stamps[i] = headStamp->match( id );
177     if( comp_stamps[i] == NULL ){
178    
179     // extract the component from the list;
180    
181     currentStamp = the_stamps->extractMolStamp( id );
182     if( currentStamp == NULL ){
183     sprintf( painCave.errMsg,
184     "SimSetup error: Component \"%s\" was not found in the "
185     "list of declared molecules\n",
186     id );
187     painCave.isFatal = 1;
188     simError();
189     }
190    
191     headStamp->add( currentStamp );
192     comp_stamps[i] = headStamp->match( id );
193     }
194     }
195    
196     #ifdef IS_MPI
197     strcpy( checkPointMsg, "Component stamps successfully extracted\n" );
198     MPIcheckPoint();
199     #endif // is_mpi
200    
201    
202    
203    
204     // caclulate the number of atoms, bonds, bends and torsions
205    
206     tot_atoms = 0;
207     tot_bonds = 0;
208     tot_bends = 0;
209     tot_torsions = 0;
210     for( i=0; i<n_components; i++ ){
211    
212     tot_atoms += components_nmol[i] * comp_stamps[i]->getNAtoms();
213     tot_bonds += components_nmol[i] * comp_stamps[i]->getNBonds();
214     tot_bends += components_nmol[i] * comp_stamps[i]->getNBends();
215     tot_torsions += components_nmol[i] * comp_stamps[i]->getNTorsions();
216     }
217    
218     tot_SRI = tot_bonds + tot_bends + tot_torsions;
219    
220     simnfo->n_atoms = tot_atoms;
221     simnfo->n_bonds = tot_bonds;
222     simnfo->n_bends = tot_bends;
223     simnfo->n_torsions = tot_torsions;
224     simnfo->n_SRI = tot_SRI;
225     simnfo->n_mol = tot_nmol;
226    
227    
228     #ifdef IS_MPI
229    
230     // divide the molecules among processors here.
231    
232     mpiSim = new mpiSimulation( simnfo );
233    
234    
235    
236     globalIndex = mpiSim->divideLabor();
237    
238    
239    
240     // set up the local variables
241    
242     int localMol, allMol;
243     int local_atoms, local_bonds, local_bends, local_torsions, local_SRI;
244    
245     allMol = 0;
246     localMol = 0;
247     local_atoms = 0;
248     local_bonds = 0;
249     local_bends = 0;
250     local_torsions = 0;
251     for( i=0; i<n_components; i++ ){
252    
253     for( j=0; j<components_nmol[i]; j++ ){
254    
255     if( mpiSim->getMyMolStart() <= allMol &&
256     allMol <= mpiSim->getMyMolEnd() ){
257    
258     local_atoms += comp_stamps[i]->getNAtoms();
259     local_bonds += comp_stamps[i]->getNBonds();
260     local_bends += comp_stamps[i]->getNBends();
261     local_torsions += comp_stamps[i]->getNTorsions();
262     localMol++;
263     }
264     allMol++;
265     }
266     }
267     local_SRI = local_bonds + local_bends + local_torsions;
268    
269    
270     simnfo->n_atoms = mpiSim->getMyNlocal();
271    
272     if( local_atoms != simnfo->n_atoms ){
273     sprintf( painCave.errMsg,
274     "SimSetup error: mpiSim's localAtom (%d) and SimSetup's"
275     " localAtom (%d) are note equal.\n",
276     simnfo->n_atoms,
277     local_atoms );
278     painCave.isFatal = 1;
279     simError();
280     }
281    
282     simnfo->n_bonds = local_bonds;
283     simnfo->n_bends = local_bends;
284     simnfo->n_torsions = local_torsions;
285     simnfo->n_SRI = local_SRI;
286     simnfo->n_mol = localMol;
287    
288     strcpy( checkPointMsg, "Passed nlocal consistency check." );
289     MPIcheckPoint();
290    
291    
292     #endif // is_mpi
293    
294    
295     // create the atom and short range interaction arrays
296    
297     Atom::createArrays(simnfo->n_atoms);
298     the_atoms = new Atom*[simnfo->n_atoms];
299     the_molecules = new Molecule[simnfo->n_mol];
300    
301    
302     if( simnfo->n_SRI ){
303     the_sris = new SRI*[simnfo->n_SRI];
304     the_excludes = new ex_pair[simnfo->n_SRI];
305     }
306    
307     // set the arrays into the SimInfo object
308    
309     simnfo->atoms = the_atoms;
310     simnfo->sr_interactions = the_sris;
311     simnfo->n_exclude = tot_SRI;
312     simnfo->excludes = the_excludes;
313    
314    
315     // get some of the tricky things that may still be in the globals
316    
317     if( simnfo->n_dipoles ){
318    
319     if( !the_globals->haveRRF() ){
320     sprintf( painCave.errMsg,
321     "SimSetup Error, system has dipoles, but no rRF was set.\n");
322     painCave.isFatal = 1;
323     simError();
324     }
325     if( !the_globals->haveDielectric() ){
326     sprintf( painCave.errMsg,
327     "SimSetup Error, system has dipoles, but no"
328     " dielectric was set.\n" );
329     painCave.isFatal = 1;
330     simError();
331     }
332    
333     simnfo->rRF = the_globals->getRRF();
334     simnfo->dielectric = the_globals->getDielectric();
335     }
336    
337     #ifdef IS_MPI
338     strcpy( checkPointMsg, "rRf and dielectric check out" );
339     MPIcheckPoint();
340     #endif // is_mpi
341    
342     if( the_globals->haveBox() ){
343     simnfo->box_x = the_globals->getBox();
344     simnfo->box_y = the_globals->getBox();
345     simnfo->box_z = the_globals->getBox();
346     }
347     else if( the_globals->haveDensity() ){
348    
349     double vol;
350     vol = (double)tot_nmol / the_globals->getDensity();
351     simnfo->box_x = pow( vol, ( 1.0 / 3.0 ) );
352     simnfo->box_y = simnfo->box_x;
353     simnfo->box_z = simnfo->box_x;
354     }
355     else{
356     if( !the_globals->haveBoxX() ){
357     sprintf( painCave.errMsg,
358     "SimSetup error, no periodic BoxX size given.\n" );
359     painCave.isFatal = 1;
360     simError();
361     }
362     simnfo->box_x = the_globals->getBoxX();
363    
364     if( !the_globals->haveBoxY() ){
365     sprintf( painCave.errMsg,
366     "SimSetup error, no periodic BoxY size given.\n" );
367     painCave.isFatal = 1;
368     simError();
369     }
370     simnfo->box_y = the_globals->getBoxY();
371    
372     if( !the_globals->haveBoxZ() ){
373     sprintf( painCave.errMsg,
374     "SimSetup error, no periodic BoxZ size given.\n" );
375     painCave.isFatal = 1;
376     simError();
377     }
378     simnfo->box_z = the_globals->getBoxZ();
379     }
380    
381     #ifdef IS_MPI
382     strcpy( checkPointMsg, "Box size set up" );
383     MPIcheckPoint();
384     #endif // is_mpi
385    
386    
387     // initialize the arrays
388    
389     the_ff->setSimInfo( simnfo );
390    
391     makeAtoms();
392     //
393     if( tot_bonds ){
394     makeBonds();
395     }
396    
397     if( tot_bends ){
398     makeBends();
399     }
400    
401     if( tot_torsions ){
402     makeTorsions();
403     }
404    
405    
406    
407    
408    
409    
410     if( the_globals->haveInitialConfig() ){
411    
412     InitializeFromFile* fileInit;
413     #ifdef IS_MPI // is_mpi
414     if( worldRank == 0 ){
415     #endif //is_mpi
416     fileInit = new InitializeFromFile( the_globals->getInitialConfig() );
417     #ifdef IS_MPI
418     }else fileInit = new InitializeFromFile( NULL );
419     #endif
420     fileInit->read_xyz( simnfo ); // default velocities on
421    
422     delete fileInit;
423     }
424     else{
425    
426     #ifdef IS_MPI
427    
428     // no init from bass
429    
430     sprintf( painCave.errMsg,
431     "Cannot intialize a parallel simulation without an initial configuration file.\n" );
432     painCave.isFatal;
433     simError();
434    
435     #else
436    
437     initFromBass();
438    
439    
440     #endif
441     }
442    
443     #ifdef IS_MPI
444     strcpy( checkPointMsg, "Successfully read in the initial configuration" );
445     MPIcheckPoint();
446     #endif // is_mpi
447    
448    
449    
450    
451    
452    
453    
454     #ifdef IS_MPI
455     if( worldRank == 0 ){
456     #endif // is_mpi
457    
458     if( the_globals->haveFinalConfig() ){
459     strcpy( simnfo->finalName, the_globals->getFinalConfig() );
460     }
461     else{
462     strcpy( simnfo->finalName, inFileName );
463     char* endTest;
464     int nameLength = strlen( simnfo->finalName );
465     endTest = &(simnfo->finalName[nameLength - 5]);
466     if( !strcmp( endTest, ".bass" ) ){
467     strcpy( endTest, ".eor" );
468     }
469     else if( !strcmp( endTest, ".BASS" ) ){
470     strcpy( endTest, ".eor" );
471     }
472     else{
473     endTest = &(simnfo->finalName[nameLength - 4]);
474     if( !strcmp( endTest, ".bss" ) ){
475     strcpy( endTest, ".eor" );
476     }
477     else if( !strcmp( endTest, ".mdl" ) ){
478     strcpy( endTest, ".eor" );
479     }
480     else{
481     strcat( simnfo->finalName, ".eor" );
482     }
483     }
484     }
485    
486     // make the sample and status out names
487    
488     strcpy( simnfo->sampleName, inFileName );
489     char* endTest;
490     int nameLength = strlen( simnfo->sampleName );
491     endTest = &(simnfo->sampleName[nameLength - 5]);
492     if( !strcmp( endTest, ".bass" ) ){
493     strcpy( endTest, ".dump" );
494     }
495     else if( !strcmp( endTest, ".BASS" ) ){
496     strcpy( endTest, ".dump" );
497     }
498     else{
499     endTest = &(simnfo->sampleName[nameLength - 4]);
500     if( !strcmp( endTest, ".bss" ) ){
501     strcpy( endTest, ".dump" );
502     }
503     else if( !strcmp( endTest, ".mdl" ) ){
504     strcpy( endTest, ".dump" );
505     }
506     else{
507     strcat( simnfo->sampleName, ".dump" );
508     }
509     }
510    
511     strcpy( simnfo->statusName, inFileName );
512     nameLength = strlen( simnfo->statusName );
513     endTest = &(simnfo->statusName[nameLength - 5]);
514     if( !strcmp( endTest, ".bass" ) ){
515     strcpy( endTest, ".stat" );
516     }
517     else if( !strcmp( endTest, ".BASS" ) ){
518     strcpy( endTest, ".stat" );
519     }
520     else{
521     endTest = &(simnfo->statusName[nameLength - 4]);
522     if( !strcmp( endTest, ".bss" ) ){
523     strcpy( endTest, ".stat" );
524     }
525     else if( !strcmp( endTest, ".mdl" ) ){
526     strcpy( endTest, ".stat" );
527     }
528     else{
529     strcat( simnfo->statusName, ".stat" );
530     }
531     }
532    
533     #ifdef IS_MPI
534     }
535     #endif // is_mpi
536    
537     // set the status, sample, and themal kick times
538    
539     if( the_globals->haveSampleTime() ){
540     simnfo->sampleTime = the_globals->getSampleTime();
541     simnfo->statusTime = simnfo->sampleTime;
542     simnfo->thermalTime = simnfo->sampleTime;
543     }
544     else{
545     simnfo->sampleTime = the_globals->getRunTime();
546     simnfo->statusTime = simnfo->sampleTime;
547     simnfo->thermalTime = simnfo->sampleTime;
548     }
549    
550     if( the_globals->haveStatusTime() ){
551     simnfo->statusTime = the_globals->getStatusTime();
552     }
553    
554     if( the_globals->haveThermalTime() ){
555     simnfo->thermalTime = the_globals->getThermalTime();
556     }
557    
558     // check for the temperature set flag
559    
560     if( the_globals->haveTempSet() ) simnfo->setTemp = the_globals->getTempSet();
561    
562    
563     // // make the longe range forces and the integrator
564    
565     // new AllLong( simnfo );
566    
567     if( !strcmp( force_field, "TraPPE" ) ) new Verlet( *simnfo, the_ff );
568     if( !strcmp( force_field, "DipoleTest" ) ) new Symplectic( simnfo, the_ff );
569     if( !strcmp( force_field, "TraPPE_Ex" ) ) new Symplectic( simnfo, the_ff );
570     if( !strcmp( force_field, "LJ" ) ) new Verlet( *simnfo, the_ff );
571    
572     }
573    
574     void SimSetup::makeAtoms( void ){
575    
576     int i, j, k, index;
577     double ux, uy, uz, uSqr, u;
578     AtomStamp* current_atom;
579     DirectionalAtom* dAtom;
580     int molIndex, molStart, molEnd, nMemb, lMolIndex;
581    
582     lMolIndex = 0;
583     molIndex = 0;
584     index = 0;
585     for( i=0; i<n_components; i++ ){
586    
587     for( j=0; j<components_nmol[i]; j++ ){
588    
589     #ifdef IS_MPI
590     if( mpiSim->getMyMolStart() <= molIndex &&
591     molIndex <= mpiSim->getMyMolEnd() ){
592     #endif // is_mpi
593    
594     molStart = index;
595     nMemb = comp_stamps[i]->getNAtoms();
596     for( k=0; k<comp_stamps[i]->getNAtoms(); k++ ){
597    
598     current_atom = comp_stamps[i]->getAtom( k );
599     if( current_atom->haveOrientation() ){
600    
601     dAtom = new DirectionalAtom(index);
602     simnfo->n_oriented++;
603     the_atoms[index] = dAtom;
604    
605     ux = current_atom->getOrntX();
606     uy = current_atom->getOrntY();
607     uz = current_atom->getOrntZ();
608    
609     uSqr = (ux * ux) + (uy * uy) + (uz * uz);
610    
611     u = sqrt( uSqr );
612     ux = ux / u;
613     uy = uy / u;
614     uz = uz / u;
615    
616     dAtom->setSUx( ux );
617     dAtom->setSUy( uy );
618     dAtom->setSUz( uz );
619     }
620     else{
621     the_atoms[index] = new GeneralAtom(index);
622     }
623     the_atoms[index]->setType( current_atom->getType() );
624     the_atoms[index]->setIndex( index );
625    
626     // increment the index and repeat;
627     index++;
628     }
629    
630     molEnd = index -1;
631     the_molecules[lMolIndex].setNMembers( nMemb );
632     the_molecules[lMolIndex].setStartAtom( molStart );
633     the_molecules[lMolIndex].setEndAtom( molEnd );
634     the_molecules[lMolIndex].setStampID( i );
635     lMolIndex++;
636    
637     #ifdef IS_MPI
638     }
639     #endif //is_mpi
640    
641     molIndex++;
642     }
643     }
644    
645     #ifdef IS_MPI
646     for( i=0; i<mpiSim->getMyNlocal(); i++ ) the_atoms[i]->setGlobalIndex( globalIndex[i] );
647    
648     delete[] globalIndex;
649    
650     mpiSim->mpiRefresh();
651     #endif //IS_MPI
652    
653     the_ff->initializeAtoms();
654     }
655    
656     void SimSetup::makeBonds( void ){
657    
658     int i, j, k, index, offset, molIndex;
659     bond_pair* the_bonds;
660     BondStamp* current_bond;
661    
662     the_bonds = new bond_pair[tot_bonds];
663     index = 0;
664     offset = 0;
665     molIndex = 0;
666    
667     for( i=0; i<n_components; i++ ){
668    
669     for( j=0; j<components_nmol[i]; j++ ){
670    
671     #ifdef IS_MPI
672     if( mpiSim->getMyMolStart() <= molIndex &&
673     molIndex <= mpiSim->getMyMolEnd() ){
674     #endif // is_mpi
675    
676     for( k=0; k<comp_stamps[i]->getNBonds(); k++ ){
677    
678     current_bond = comp_stamps[i]->getBond( k );
679     the_bonds[index].a = current_bond->getA() + offset;
680     the_bonds[index].b = current_bond->getB() + offset;
681    
682     the_excludes[index].i = the_bonds[index].a;
683     the_excludes[index].j = the_bonds[index].b;
684    
685     // increment the index and repeat;
686     index++;
687     }
688     offset += comp_stamps[i]->getNAtoms();
689    
690     #ifdef IS_MPI
691     }
692     #endif //is_mpi
693    
694     molIndex++;
695     }
696     }
697    
698     the_ff->initializeBonds( the_bonds );
699     }
700    
701     void SimSetup::makeBends( void ){
702    
703     int i, j, k, index, offset, molIndex;
704     bend_set* the_bends;
705     BendStamp* current_bend;
706    
707     the_bends = new bend_set[tot_bends];
708     index = 0;
709     offset = 0;
710     molIndex = 0;
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]->getNBends(); k++ ){
721    
722     current_bend = comp_stamps[i]->getBend( k );
723     the_bends[index].a = current_bend->getA() + offset;
724     the_bends[index].b = current_bend->getB() + offset;
725     the_bends[index].c = current_bend->getC() + offset;
726    
727     the_excludes[index + tot_bonds].i = the_bends[index].a;
728     the_excludes[index + tot_bonds].j = the_bends[index].c;
729    
730     // increment the index and repeat;
731     index++;
732     }
733     offset += comp_stamps[i]->getNAtoms();
734    
735     #ifdef IS_MPI
736     }
737     #endif //is_mpi
738    
739     molIndex++;
740     }
741     }
742    
743     the_ff->initializeBends( the_bends );
744     }
745    
746     void SimSetup::makeTorsions( void ){
747    
748     int i, j, k, index, offset, molIndex;
749     torsion_set* the_torsions;
750     TorsionStamp* current_torsion;
751    
752     the_torsions = new torsion_set[tot_torsions];
753     index = 0;
754     offset = 0;
755     molIndex = 0;
756     for( i=0; i<n_components; i++ ){
757    
758     for( j=0; j<components_nmol[i]; j++ ){
759    
760     #ifdef IS_MPI
761     if( mpiSim->getMyMolStart() <= molIndex &&
762     molIndex <= mpiSim->getMyMolEnd() ){
763     #endif // is_mpi
764    
765     for( k=0; k<comp_stamps[i]->getNTorsions(); k++ ){
766    
767     current_torsion = comp_stamps[i]->getTorsion( k );
768     the_torsions[index].a = current_torsion->getA() + offset;
769     the_torsions[index].b = current_torsion->getB() + offset;
770     the_torsions[index].c = current_torsion->getC() + offset;
771     the_torsions[index].d = current_torsion->getD() + offset;
772    
773     the_excludes[index + tot_bonds + tot_bends].i = the_torsions[index].a;
774     the_excludes[index + tot_bonds + tot_bends].j = the_torsions[index].d;
775    
776     // increment the index and repeat;
777     index++;
778     }
779     offset += comp_stamps[i]->getNAtoms();
780    
781     #ifdef IS_MPI
782     }
783     #endif //is_mpi
784    
785     molIndex++;
786     }
787     }
788    
789     the_ff->initializeTorsions( the_torsions );
790     }
791    
792     void SimSetup::initFromBass( void ){
793    
794     int i, j, k;
795     int n_cells;
796     double cellx, celly, cellz;
797     double temp1, temp2, temp3;
798     int n_per_extra;
799     int n_extra;
800     int have_extra, done;
801    
802     temp1 = (double)tot_nmol / 4.0;
803     temp2 = pow( temp1, ( 1.0 / 3.0 ) );
804     temp3 = ceil( temp2 );
805    
806     have_extra =0;
807     if( temp2 < temp3 ){ // we have a non-complete lattice
808     have_extra =1;
809    
810     n_cells = (int)temp3 - 1;
811     cellx = simnfo->box_x / temp3;
812     celly = simnfo->box_y / temp3;
813     cellz = simnfo->box_z / temp3;
814     n_extra = tot_nmol - ( 4 * n_cells * n_cells * n_cells );
815     temp1 = ((double)n_extra) / ( pow( temp3, 3.0 ) - pow( n_cells, 3.0 ) );
816     n_per_extra = (int)ceil( temp1 );
817    
818     if( n_per_extra > 4){
819     sprintf( painCave.errMsg,
820     "SimSetup error. There has been an error in constructing"
821     " the non-complete lattice.\n" );
822     painCave.isFatal = 1;
823     simError();
824     }
825     }
826     else{
827     n_cells = (int)temp3;
828     cellx = simnfo->box_x / temp3;
829     celly = simnfo->box_y / temp3;
830     cellz = simnfo->box_z / temp3;
831     }
832    
833     current_mol = 0;
834     current_comp_mol = 0;
835     current_comp = 0;
836     current_atom_ndx = 0;
837    
838     for( i=0; i < n_cells ; i++ ){
839     for( j=0; j < n_cells; j++ ){
840     for( k=0; k < n_cells; k++ ){
841    
842     makeElement( i * cellx,
843     j * celly,
844     k * cellz );
845    
846     makeElement( i * cellx + 0.5 * cellx,
847     j * celly + 0.5 * celly,
848     k * cellz );
849    
850     makeElement( i * cellx,
851     j * celly + 0.5 * celly,
852     k * cellz + 0.5 * cellz );
853    
854     makeElement( i * cellx + 0.5 * cellx,
855     j * celly,
856     k * cellz + 0.5 * cellz );
857     }
858     }
859     }
860    
861     if( have_extra ){
862     done = 0;
863    
864     int start_ndx;
865     for( i=0; i < (n_cells+1) && !done; i++ ){
866     for( j=0; j < (n_cells+1) && !done; j++ ){
867    
868     if( i < n_cells ){
869    
870     if( j < n_cells ){
871     start_ndx = n_cells;
872     }
873     else start_ndx = 0;
874     }
875     else start_ndx = 0;
876    
877     for( k=start_ndx; k < (n_cells+1) && !done; k++ ){
878    
879     makeElement( i * cellx,
880     j * celly,
881     k * cellz );
882     done = ( current_mol >= tot_nmol );
883    
884     if( !done && n_per_extra > 1 ){
885     makeElement( i * cellx + 0.5 * cellx,
886     j * celly + 0.5 * celly,
887     k * cellz );
888     done = ( current_mol >= tot_nmol );
889     }
890    
891     if( !done && n_per_extra > 2){
892     makeElement( i * cellx,
893     j * celly + 0.5 * celly,
894     k * cellz + 0.5 * cellz );
895     done = ( current_mol >= tot_nmol );
896     }
897    
898     if( !done && n_per_extra > 3){
899     makeElement( i * cellx + 0.5 * cellx,
900     j * celly,
901     k * cellz + 0.5 * cellz );
902     done = ( current_mol >= tot_nmol );
903     }
904     }
905     }
906     }
907     }
908    
909    
910     for( i=0; i<simnfo->n_atoms; i++ ){
911     simnfo->atoms[i]->set_vx( 0.0 );
912     simnfo->atoms[i]->set_vy( 0.0 );
913     simnfo->atoms[i]->set_vz( 0.0 );
914     }
915     }
916    
917     void SimSetup::makeElement( double x, double y, double z ){
918    
919     int k;
920     AtomStamp* current_atom;
921     DirectionalAtom* dAtom;
922     double rotMat[3][3];
923    
924     for( k=0; k<comp_stamps[current_comp]->getNAtoms(); k++ ){
925    
926     current_atom = comp_stamps[current_comp]->getAtom( k );
927     if( !current_atom->havePosition() ){
928     sprintf( painCave.errMsg,
929     "SimSetup:initFromBass error.\n"
930     "\tComponent %s, atom %s does not have a position specified.\n"
931     "\tThe initialization routine is unable to give a start"
932     " position.\n",
933     comp_stamps[current_comp]->getID(),
934     current_atom->getType() );
935     painCave.isFatal = 1;
936     simError();
937     }
938    
939     the_atoms[current_atom_ndx]->setX( x + current_atom->getPosX() );
940     the_atoms[current_atom_ndx]->setY( y + current_atom->getPosY() );
941     the_atoms[current_atom_ndx]->setZ( z + current_atom->getPosZ() );
942    
943     if( the_atoms[current_atom_ndx]->isDirectional() ){
944    
945     dAtom = (DirectionalAtom *)the_atoms[current_atom_ndx];
946    
947     rotMat[0][0] = 1.0;
948     rotMat[0][1] = 0.0;
949     rotMat[0][2] = 0.0;
950    
951     rotMat[1][0] = 0.0;
952     rotMat[1][1] = 1.0;
953     rotMat[1][2] = 0.0;
954    
955     rotMat[2][0] = 0.0;
956     rotMat[2][1] = 0.0;
957     rotMat[2][2] = 1.0;
958    
959     dAtom->setA( rotMat );
960     }
961    
962     current_atom_ndx++;
963     }
964    
965     current_mol++;
966     current_comp_mol++;
967    
968     if( current_comp_mol >= components_nmol[current_comp] ){
969    
970     current_comp_mol = 0;
971     current_comp++;
972     }
973     }