ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/mdtools/interface_implementation/SimSetup.cpp
Revision: 195
Committed: Thu Dec 5 18:53:40 2002 UTC (21 years, 6 months ago) by chuckv
File size: 19251 byte(s)
Log Message:
Added divideLabor.

File Contents

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