ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libmdtools/SimSetup.cpp
Revision: 435
Committed: Fri Mar 28 19:33:37 2003 UTC (21 years, 3 months ago) by mmeineke
File size: 27960 byte(s)
Log Message:
fixed a bug where the Excludes were not being created properly

File Contents

# Content
1 #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 strcpy( simnfo->ensemble, ensemble );
85
86 strcpy( simnfo->mixingRule, the_globals->getMixingRule() );
87 simnfo->usePBC = the_globals->getPBC();
88
89
90
91 if( !strcmp( force_field, "TraPPE_Ex" ) ) the_ff = new TraPPE_ExFF();
92 else if( !strcmp( force_field, "LJ" ) ) the_ff = new LJ_FF();
93 else{
94 sprintf( painCave.errMsg,
95 "SimSetup Error. Unrecognized force field -> %s\n",
96 force_field );
97 painCave.isFatal = 1;
98 simError();
99 }
100
101 #ifdef IS_MPI
102 strcpy( checkPointMsg, "ForceField creation successful" );
103 MPIcheckPoint();
104 #endif // is_mpi
105
106
107
108 // 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
113 if( !the_globals->haveNMol() ){
114 // we don't have the total number of molecules, so we assume it is
115 // given in each component
116
117 tot_nmol = 0;
118 for( i=0; i<n_components; i++ ){
119
120 if( !the_components[i]->haveNMol() ){
121 // we have a problem
122 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 }
128
129 tot_nmol += the_components[i]->getNMol();
130 components_nmol[i] = the_components[i]->getNMol();
131 }
132 }
133 else{
134 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
158 #ifdef IS_MPI
159 strcpy( checkPointMsg, "Have the number of components" );
160 MPIcheckPoint();
161 #endif // is_mpi
162
163 // make an array of molecule stamps that match the components used.
164 // also extract the used stamps out into a separate linked list
165
166 simnfo->nComponents = n_components;
167 simnfo->componentsNmol = components_nmol;
168 simnfo->compStamps = comp_stamps;
169 simnfo->headStamp = new LinkedMolStamp();
170
171 char* id;
172 LinkedMolStamp* headStamp = simnfo->headStamp;
173 LinkedMolStamp* currentStamp = NULL;
174 for( i=0; i<n_components; i++ ){
175
176 id = the_components[i]->getType();
177 comp_stamps[i] = NULL;
178
179 // check to make sure the component isn't already in the list
180
181 comp_stamps[i] = headStamp->match( id );
182 if( comp_stamps[i] == NULL ){
183
184 // extract the component from the list;
185
186 currentStamp = the_stamps->extractMolStamp( id );
187 if( currentStamp == NULL ){
188 sprintf( painCave.errMsg,
189 "SimSetup error: Component \"%s\" was not found in the "
190 "list of declared molecules\n",
191 id );
192 painCave.isFatal = 1;
193 simError();
194 }
195
196 headStamp->add( currentStamp );
197 comp_stamps[i] = headStamp->match( id );
198 }
199 }
200
201 #ifdef IS_MPI
202 strcpy( checkPointMsg, "Component stamps successfully extracted\n" );
203 MPIcheckPoint();
204 #endif // is_mpi
205
206
207
208
209 // caclulate the number of atoms, bonds, bends and torsions
210
211 tot_atoms = 0;
212 tot_bonds = 0;
213 tot_bends = 0;
214 tot_torsions = 0;
215 for( i=0; i<n_components; i++ ){
216
217 tot_atoms += components_nmol[i] * comp_stamps[i]->getNAtoms();
218 tot_bonds += components_nmol[i] * comp_stamps[i]->getNBonds();
219 tot_bends += components_nmol[i] * comp_stamps[i]->getNBends();
220 tot_torsions += components_nmol[i] * comp_stamps[i]->getNTorsions();
221 }
222
223 tot_SRI = tot_bonds + tot_bends + tot_torsions;
224
225 simnfo->n_atoms = tot_atoms;
226 simnfo->n_bonds = tot_bonds;
227 simnfo->n_bends = tot_bends;
228 simnfo->n_torsions = tot_torsions;
229 simnfo->n_SRI = tot_SRI;
230 simnfo->n_mol = tot_nmol;
231
232
233 #ifdef IS_MPI
234
235 // divide the molecules among processors here.
236
237 mpiSim = new mpiSimulation( simnfo );
238
239
240
241 globalIndex = mpiSim->divideLabor();
242
243 // set up the local variables
244
245 int localMol, allMol;
246 int local_atoms, local_bonds, local_bends, local_torsions, local_SRI;
247
248 int* mol2proc = mpiSim->getMolToProcMap();
249 int* molCompType = mpiSim->getMolComponentType();
250
251 allMol = 0;
252 localMol = 0;
253 local_atoms = 0;
254 local_bonds = 0;
255 local_bends = 0;
256 local_torsions = 0;
257 for( i=0; i<n_components; i++ ){
258
259 for( j=0; j<components_nmol[i]; j++ ){
260
261 if( mol2proc[j] == worldRank ){
262
263 local_atoms += comp_stamps[i]->getNAtoms();
264 local_bonds += comp_stamps[i]->getNBonds();
265 local_bends += comp_stamps[i]->getNBends();
266 local_torsions += comp_stamps[i]->getNTorsions();
267 localMol++;
268 }
269 allMol++;
270 }
271 }
272 local_SRI = local_bonds + local_bends + local_torsions;
273
274
275 simnfo->n_atoms = mpiSim->getMyNlocal();
276
277 if( local_atoms != simnfo->n_atoms ){
278 sprintf( painCave.errMsg,
279 "SimSetup error: mpiSim's localAtom (%d) and SimSetup's"
280 " localAtom (%d) are not equal.\n",
281 simnfo->n_atoms,
282 local_atoms );
283 painCave.isFatal = 1;
284 simError();
285 }
286
287 simnfo->n_bonds = local_bonds;
288 simnfo->n_bends = local_bends;
289 simnfo->n_torsions = local_torsions;
290 simnfo->n_SRI = local_SRI;
291 simnfo->n_mol = localMol;
292
293 strcpy( checkPointMsg, "Passed nlocal consistency check." );
294 MPIcheckPoint();
295
296
297 #endif // is_mpi
298
299
300 // create the atom and short range interaction arrays
301
302 Atom::createArrays(simnfo->n_atoms);
303 the_atoms = new Atom*[simnfo->n_atoms];
304 the_molecules = new Molecule[simnfo->n_mol];
305 int molIndex;
306
307 // initialize the molecule's stampID's
308
309 #ifdef IS_MPI
310
311
312 molIndex = 0;
313 for(i=0; i<mpiSim->getTotNmol(); i++){
314
315 if(mol2proc[i] == worldRank ){
316 the_molecules[molIndex].setStampID( molCompType[i] );
317 molIndex++;
318 }
319 }
320
321 #else // is_mpi
322
323 molIndex = 0;
324 for(i=0; i<n_components; i++){
325 for(j=0; j<components_nmol[i]; j++ ){
326 the_molecules[molIndex].setStampID( i );
327 molIndex++;
328 }
329 }
330
331
332 #endif // is_mpi
333
334
335 if( simnfo->n_SRI ){
336
337 std::cerr << "n_SRI = " << simnfo->n_SRI << "\n";
338
339 Exclude::createArray(simnfo->n_SRI);
340 the_excludes = new Exclude*[simnfo->n_SRI];
341 for( int ex=0; ex<simnfo->n_SRI; ex++) the_excludes[ex] = new Exclude(ex);
342 simnfo->globalExcludes = new int;
343 simnfo->n_exclude = tot_SRI;
344 }
345 else{
346
347 Exclude::createArray( 1 );
348 the_excludes = new Exclude*;
349 the_excludes[0] = new Exclude(0);
350 the_excludes[0]->setPair( 0,0 );
351 simnfo->globalExcludes = new int;
352 simnfo->globalExcludes[0] = 0;
353 simnfo->n_exclude = 0;
354 }
355
356 // set the arrays into the SimInfo object
357
358 simnfo->atoms = the_atoms;
359 simnfo->molecules = the_molecules;
360 simnfo->nGlobalExcludes = 0;
361 simnfo->excludes = the_excludes;
362
363
364 // get some of the tricky things that may still be in the globals
365
366
367 if( the_globals->haveBox() ){
368 simnfo->box_x = the_globals->getBox();
369 simnfo->box_y = the_globals->getBox();
370 simnfo->box_z = the_globals->getBox();
371 }
372 else if( the_globals->haveDensity() ){
373
374 double vol;
375 vol = (double)tot_nmol / the_globals->getDensity();
376 simnfo->box_x = pow( vol, ( 1.0 / 3.0 ) );
377 simnfo->box_y = simnfo->box_x;
378 simnfo->box_z = simnfo->box_x;
379 }
380 else{
381 if( !the_globals->haveBoxX() ){
382 sprintf( painCave.errMsg,
383 "SimSetup error, no periodic BoxX size given.\n" );
384 painCave.isFatal = 1;
385 simError();
386 }
387 simnfo->box_x = the_globals->getBoxX();
388
389 if( !the_globals->haveBoxY() ){
390 sprintf( painCave.errMsg,
391 "SimSetup error, no periodic BoxY size given.\n" );
392 painCave.isFatal = 1;
393 simError();
394 }
395 simnfo->box_y = the_globals->getBoxY();
396
397 if( !the_globals->haveBoxZ() ){
398 sprintf( painCave.errMsg,
399 "SimSetup error, no periodic BoxZ size given.\n" );
400 painCave.isFatal = 1;
401 simError();
402 }
403 simnfo->box_z = the_globals->getBoxZ();
404 }
405
406 #ifdef IS_MPI
407 strcpy( checkPointMsg, "Box size set up" );
408 MPIcheckPoint();
409 #endif // is_mpi
410
411
412 // initialize the arrays
413
414 the_ff->setSimInfo( simnfo );
415
416 makeMolecules();
417 simnfo->identArray = new int[simnfo->n_atoms];
418 for(i=0; i<simnfo->n_atoms; i++){
419 simnfo->identArray[i] = the_atoms[i]->getIdent();
420 }
421
422 if (the_globals->getUseRF() ) {
423 simnfo->useReactionField = 1;
424
425 if( !the_globals->haveECR() ){
426 sprintf( painCave.errMsg,
427 "SimSetup Warning: using default value of 1/2 the smallest "
428 "box length for the electrostaticCutoffRadius.\n"
429 "I hope you have a very fast processor!\n");
430 painCave.isFatal = 0;
431 simError();
432 double smallest;
433 smallest = simnfo->box_x;
434 if (simnfo->box_y <= smallest) smallest = simnfo->box_y;
435 if (simnfo->box_z <= smallest) smallest = simnfo->box_z;
436 simnfo->ecr = 0.5 * smallest;
437 } else {
438 simnfo->ecr = the_globals->getECR();
439 }
440
441 if( !the_globals->haveEST() ){
442 sprintf( painCave.errMsg,
443 "SimSetup Warning: using default value of 0.05 * the "
444 "electrostaticCutoffRadius for the electrostaticSkinThickness\n"
445 );
446 painCave.isFatal = 0;
447 simError();
448 simnfo->est = 0.05 * simnfo->ecr;
449 } else {
450 simnfo->est = the_globals->getEST();
451 }
452
453 if(!the_globals->haveDielectric() ){
454 sprintf( painCave.errMsg,
455 "SimSetup Error: You are trying to use Reaction Field without"
456 "setting a dielectric constant!\n"
457 );
458 painCave.isFatal = 1;
459 simError();
460 }
461 simnfo->dielectric = the_globals->getDielectric();
462 } else {
463 if (simnfo->n_dipoles) {
464
465 if( !the_globals->haveECR() ){
466 sprintf( painCave.errMsg,
467 "SimSetup Warning: using default value of 1/2 the smallest"
468 "box length for the electrostaticCutoffRadius.\n"
469 "I hope you have a very fast processor!\n");
470 painCave.isFatal = 0;
471 simError();
472 double smallest;
473 smallest = simnfo->box_x;
474 if (simnfo->box_y <= smallest) smallest = simnfo->box_y;
475 if (simnfo->box_z <= smallest) smallest = simnfo->box_z;
476 simnfo->ecr = 0.5 * smallest;
477 } else {
478 simnfo->ecr = the_globals->getECR();
479 }
480
481 if( !the_globals->haveEST() ){
482 sprintf( painCave.errMsg,
483 "SimSetup Warning: using default value of 5% of the"
484 "electrostaticCutoffRadius for the "
485 "electrostaticSkinThickness\n"
486 );
487 painCave.isFatal = 0;
488 simError();
489 simnfo->est = 0.05 * simnfo->ecr;
490 } else {
491 simnfo->est = the_globals->getEST();
492 }
493 }
494 }
495
496 #ifdef IS_MPI
497 strcpy( checkPointMsg, "electrostatic parameters check out" );
498 MPIcheckPoint();
499 #endif // is_mpi
500
501 if( the_globals->haveInitialConfig() ){
502
503 InitializeFromFile* fileInit;
504 #ifdef IS_MPI // is_mpi
505 if( worldRank == 0 ){
506 #endif //is_mpi
507 fileInit = new InitializeFromFile( the_globals->getInitialConfig() );
508 #ifdef IS_MPI
509 }else fileInit = new InitializeFromFile( NULL );
510 #endif
511 fileInit->read_xyz( simnfo ); // default velocities on
512
513 delete fileInit;
514 }
515 else{
516
517 #ifdef IS_MPI
518
519 // no init from bass
520
521 sprintf( painCave.errMsg,
522 "Cannot intialize a parallel simulation without an initial configuration file.\n" );
523 painCave.isFatal;
524 simError();
525
526 #else
527
528 initFromBass();
529
530
531 #endif
532 }
533
534 #ifdef IS_MPI
535 strcpy( checkPointMsg, "Successfully read in the initial configuration" );
536 MPIcheckPoint();
537 #endif // is_mpi
538
539
540
541
542
543
544
545 #ifdef IS_MPI
546 if( worldRank == 0 ){
547 #endif // is_mpi
548
549 if( the_globals->haveFinalConfig() ){
550 strcpy( simnfo->finalName, the_globals->getFinalConfig() );
551 }
552 else{
553 strcpy( simnfo->finalName, inFileName );
554 char* endTest;
555 int nameLength = strlen( simnfo->finalName );
556 endTest = &(simnfo->finalName[nameLength - 5]);
557 if( !strcmp( endTest, ".bass" ) ){
558 strcpy( endTest, ".eor" );
559 }
560 else if( !strcmp( endTest, ".BASS" ) ){
561 strcpy( endTest, ".eor" );
562 }
563 else{
564 endTest = &(simnfo->finalName[nameLength - 4]);
565 if( !strcmp( endTest, ".bss" ) ){
566 strcpy( endTest, ".eor" );
567 }
568 else if( !strcmp( endTest, ".mdl" ) ){
569 strcpy( endTest, ".eor" );
570 }
571 else{
572 strcat( simnfo->finalName, ".eor" );
573 }
574 }
575 }
576
577 // make the sample and status out names
578
579 strcpy( simnfo->sampleName, inFileName );
580 char* endTest;
581 int nameLength = strlen( simnfo->sampleName );
582 endTest = &(simnfo->sampleName[nameLength - 5]);
583 if( !strcmp( endTest, ".bass" ) ){
584 strcpy( endTest, ".dump" );
585 }
586 else if( !strcmp( endTest, ".BASS" ) ){
587 strcpy( endTest, ".dump" );
588 }
589 else{
590 endTest = &(simnfo->sampleName[nameLength - 4]);
591 if( !strcmp( endTest, ".bss" ) ){
592 strcpy( endTest, ".dump" );
593 }
594 else if( !strcmp( endTest, ".mdl" ) ){
595 strcpy( endTest, ".dump" );
596 }
597 else{
598 strcat( simnfo->sampleName, ".dump" );
599 }
600 }
601
602 strcpy( simnfo->statusName, inFileName );
603 nameLength = strlen( simnfo->statusName );
604 endTest = &(simnfo->statusName[nameLength - 5]);
605 if( !strcmp( endTest, ".bass" ) ){
606 strcpy( endTest, ".stat" );
607 }
608 else if( !strcmp( endTest, ".BASS" ) ){
609 strcpy( endTest, ".stat" );
610 }
611 else{
612 endTest = &(simnfo->statusName[nameLength - 4]);
613 if( !strcmp( endTest, ".bss" ) ){
614 strcpy( endTest, ".stat" );
615 }
616 else if( !strcmp( endTest, ".mdl" ) ){
617 strcpy( endTest, ".stat" );
618 }
619 else{
620 strcat( simnfo->statusName, ".stat" );
621 }
622 }
623
624 #ifdef IS_MPI
625 }
626 #endif // is_mpi
627
628 // set the status, sample, and themal kick times
629
630 if( the_globals->haveSampleTime() ){
631 simnfo->sampleTime = the_globals->getSampleTime();
632 simnfo->statusTime = simnfo->sampleTime;
633 simnfo->thermalTime = simnfo->sampleTime;
634 }
635 else{
636 simnfo->sampleTime = the_globals->getRunTime();
637 simnfo->statusTime = simnfo->sampleTime;
638 simnfo->thermalTime = simnfo->sampleTime;
639 }
640
641 if( the_globals->haveStatusTime() ){
642 simnfo->statusTime = the_globals->getStatusTime();
643 }
644
645 if( the_globals->haveThermalTime() ){
646 simnfo->thermalTime = the_globals->getThermalTime();
647 }
648
649 // check for the temperature set flag
650
651 if( the_globals->haveTempSet() ) simnfo->setTemp = the_globals->getTempSet();
652
653
654 // // make the longe range forces and the integrator
655
656 // new AllLong( simnfo );
657
658 if( !strcmp( force_field, "TraPPE_Ex" ) ) new Symplectic( simnfo, the_ff );
659 if( !strcmp( force_field, "LJ" ) ) new Verlet( *simnfo, the_ff );
660
661 #ifdef IS_MPI
662 mpiSim->mpiRefresh();
663 #endif
664
665 // initialize the Fortran
666
667
668 simnfo->refreshSim();
669
670 if( !strcmp( simnfo->mixingRule, "standard") ){
671 the_ff->initForceField( LB_MIXING_RULE );
672 }
673 else if( !strcmp( simnfo->mixingRule, "explicit") ){
674 the_ff->initForceField( EXPLICIT_MIXING_RULE );
675 }
676 else{
677 sprintf( painCave.errMsg,
678 "SimSetup Error: unknown mixing rule -> \"%s\"\n",
679 simnfo->mixingRule );
680 painCave.isFatal = 1;
681 simError();
682 }
683
684
685 #ifdef IS_MPI
686 strcpy( checkPointMsg,
687 "Successfully intialized the mixingRule for Fortran." );
688 MPIcheckPoint();
689 #endif // is_mpi
690 }
691
692
693 void SimSetup::makeMolecules( void ){
694
695 int i, j, exI, exJ, tempEx, stampID, atomOffset, excludeOffset;
696 molInit info;
697 DirectionalAtom* dAtom;
698 LinkedAssign* extras;
699 LinkedAssign* current_extra;
700 AtomStamp* currentAtom;
701 BondStamp* currentBond;
702 BendStamp* currentBend;
703 TorsionStamp* currentTorsion;
704
705 bond_pair* theBonds;
706 bend_set* theBends;
707 torsion_set* theTorsions;
708
709
710 //init the forceField paramters
711
712 the_ff->readParams();
713
714
715 // init the atoms
716
717 double ux, uy, uz, u, uSqr;
718
719 atomOffset = 0;
720 excludeOffset = 0;
721 for(i=0; i<simnfo->n_mol; i++){
722
723 stampID = the_molecules[i].getStampID();
724
725 info.nAtoms = comp_stamps[stampID]->getNAtoms();
726 info.nBonds = comp_stamps[stampID]->getNBonds();
727 info.nBends = comp_stamps[stampID]->getNBends();
728 info.nTorsions = comp_stamps[stampID]->getNTorsions();
729 info.nExcludes = info.nBonds + info.nBends + info.nTorsions;
730
731 info.myAtoms = &the_atoms[atomOffset];
732 info.myExcludes = &the_excludes[excludeOffset];
733 info.myBonds = new Bond*[info.nBonds];
734 info.myBends = new Bend*[info.nBends];
735 info.myTorsions = new Torsion*[info.nTorsions];
736
737 theBonds = new bond_pair[info.nBonds];
738 theBends = new bend_set[info.nBends];
739 theTorsions = new torsion_set[info.nTorsions];
740
741 // make the Atoms
742
743 for(j=0; j<info.nAtoms; j++){
744
745 currentAtom = comp_stamps[stampID]->getAtom( j );
746 if( currentAtom->haveOrientation() ){
747
748 dAtom = new DirectionalAtom(j + atomOffset);
749 simnfo->n_oriented++;
750 info.myAtoms[j] = dAtom;
751
752 ux = currentAtom->getOrntX();
753 uy = currentAtom->getOrntY();
754 uz = currentAtom->getOrntZ();
755
756 uSqr = (ux * ux) + (uy * uy) + (uz * uz);
757
758 u = sqrt( uSqr );
759 ux = ux / u;
760 uy = uy / u;
761 uz = uz / u;
762
763 dAtom->setSUx( ux );
764 dAtom->setSUy( uy );
765 dAtom->setSUz( uz );
766 }
767 else{
768 info.myAtoms[j] = new GeneralAtom(j + atomOffset);
769 }
770 info.myAtoms[j]->setType( currentAtom->getType() );
771
772 #ifdef IS_MPI
773
774 info.myAtoms[j]->setGlobalIndex( globalIndex[j+atomOffset] );
775
776 #endif // is_mpi
777 }
778
779 // make the bonds
780 for(j=0; j<info.nBonds; j++){
781
782 currentBond = comp_stamps[stampID]->getBond( j );
783 theBonds[j].a = currentBond->getA() + atomOffset;
784 theBonds[j].b = currentBond->getB() + atomOffset;
785
786 exI = theBonds[j].a;
787 exJ = theBonds[j].b;
788
789 // exclude_I must always be the smaller of the pair
790 if( exI > exJ ){
791 tempEx = exI;
792 exI = exJ;
793 exJ = tempEx;
794 }
795 #ifdef IS_MPI
796 tempEx = exI;
797 exI = the_atoms[tempEx]->getGlobalIndex() + 1;
798 tempEx = exJ;
799 exJ = the_atoms[tempEx]->getGlobalIndex() + 1;
800
801 the_excludes[j+excludeOffset]->setPair( exI, exJ );
802 #else // isn't MPI
803
804 the_excludes[j+excludeOffset]->setPair( (exI+1), (exJ+1) );
805 #endif //is_mpi
806 }
807 excludeOffset += info.nBonds;
808
809 //make the bends
810 for(j=0; j<info.nBends; j++){
811
812 currentBend = comp_stamps[stampID]->getBend( j );
813 theBends[j].a = currentBend->getA() + atomOffset;
814 theBends[j].b = currentBend->getB() + atomOffset;
815 theBends[j].c = currentBend->getC() + atomOffset;
816
817 if( currentBend->haveExtras() ){
818
819 extras = currentBend->getExtras();
820 current_extra = extras;
821
822 while( current_extra != NULL ){
823 if( !strcmp( current_extra->getlhs(), "ghostVectorSource" )){
824
825 switch( current_extra->getType() ){
826
827 case 0:
828 theBends[j].ghost =
829 current_extra->getInt() + atomOffset;
830 theBends[j].isGhost = 1;
831 break;
832
833 case 1:
834 theBends[j].ghost =
835 (int)current_extra->getDouble() + atomOffset;
836 theBends[j].isGhost = 1;
837 break;
838
839 default:
840 sprintf( painCave.errMsg,
841 "SimSetup Error: ghostVectorSource was neither a "
842 "double nor an int.\n"
843 "-->Bend[%d] in %s\n",
844 j, comp_stamps[stampID]->getID() );
845 painCave.isFatal = 1;
846 simError();
847 }
848 }
849
850 else{
851
852 sprintf( painCave.errMsg,
853 "SimSetup Error: unhandled bend assignment:\n"
854 " -->%s in Bend[%d] in %s\n",
855 current_extra->getlhs(),
856 j, comp_stamps[stampID]->getID() );
857 painCave.isFatal = 1;
858 simError();
859 }
860
861 current_extra = current_extra->getNext();
862 }
863 }
864
865 if( !theBends[j].isGhost ){
866
867 exI = theBends[j].a;
868 exJ = theBends[j].c;
869 }
870 else{
871
872 exI = theBends[j].a;
873 exJ = theBends[j].b;
874 }
875
876 // exclude_I must always be the smaller of the pair
877 if( exI > exJ ){
878 tempEx = exI;
879 exI = exJ;
880 exJ = tempEx;
881 }
882 #ifdef IS_MPI
883 tempEx = exI;
884 exI = the_atoms[tempEx]->getGlobalIndex() + 1;
885 tempEx = exJ;
886 exJ = the_atoms[tempEx]->getGlobalIndex() + 1;
887
888 the_excludes[j+excludeOffset]->setPair( exI, exJ );
889 #else // isn't MPI
890 the_excludes[j+excludeOffset]->setPair( (exI+1), (exJ+1) );
891 #endif //is_mpi
892 }
893 excludeOffset += info.nBends;
894
895 for(j=0; j<info.nTorsions; j++){
896
897 currentTorsion = comp_stamps[stampID]->getTorsion( j );
898 theTorsions[j].a = currentTorsion->getA() + atomOffset;
899 theTorsions[j].b = currentTorsion->getB() + atomOffset;
900 theTorsions[j].c = currentTorsion->getC() + atomOffset;
901 theTorsions[j].d = currentTorsion->getD() + atomOffset;
902
903 exI = theTorsions[j].a;
904 exJ = theTorsions[j].d;
905
906 // exclude_I must always be the smaller of the pair
907 if( exI > exJ ){
908 tempEx = exI;
909 exI = exJ;
910 exJ = tempEx;
911 }
912 #ifdef IS_MPI
913 tempEx = exI;
914 exI = the_atoms[tempEx]->getGlobalIndex() + 1;
915 tempEx = exJ;
916 exJ = the_atoms[tempEx]->getGlobalIndex() + 1;
917
918 the_excludes[j+excludeOffset]->setPair( exI, exJ );
919 #else // isn't MPI
920 the_excludes[j+excludeOffset]->setPair( (exI+1), (exJ+1) );
921 #endif //is_mpi
922 }
923 excludeOffset += info.nTorsions;
924
925
926 // send the arrays off to the forceField for init.
927
928 the_ff->initializeAtoms( info.nAtoms, info.myAtoms );
929 the_ff->initializeBonds( info.nBonds, info.myBonds, theBonds );
930 the_ff->initializeBends( info.nBends, info.myBends, theBends );
931 the_ff->initializeTorsions( info.nTorsions, info.myTorsions, theTorsions );
932
933
934 the_molecules[i].initialize( info );
935 atomOffset += info.nAtoms;
936 delete[] theBonds;
937 delete[] theBends;
938 delete[] theTorsions;
939 }
940
941 #ifdef IS_MPI
942 sprintf( checkPointMsg, "all molecules initialized succesfully" );
943 MPIcheckPoint();
944 #endif // is_mpi
945
946 // clean up the forcefield
947 the_ff->calcRcut();
948 the_ff->cleanMe();
949
950 }
951
952 void SimSetup::initFromBass( void ){
953
954 int i, j, k;
955 int n_cells;
956 double cellx, celly, cellz;
957 double temp1, temp2, temp3;
958 int n_per_extra;
959 int n_extra;
960 int have_extra, done;
961
962 temp1 = (double)tot_nmol / 4.0;
963 temp2 = pow( temp1, ( 1.0 / 3.0 ) );
964 temp3 = ceil( temp2 );
965
966 have_extra =0;
967 if( temp2 < temp3 ){ // we have a non-complete lattice
968 have_extra =1;
969
970 n_cells = (int)temp3 - 1;
971 cellx = simnfo->box_x / temp3;
972 celly = simnfo->box_y / temp3;
973 cellz = simnfo->box_z / temp3;
974 n_extra = tot_nmol - ( 4 * n_cells * n_cells * n_cells );
975 temp1 = ((double)n_extra) / ( pow( temp3, 3.0 ) - pow( n_cells, 3.0 ) );
976 n_per_extra = (int)ceil( temp1 );
977
978 if( n_per_extra > 4){
979 sprintf( painCave.errMsg,
980 "SimSetup error. There has been an error in constructing"
981 " the non-complete lattice.\n" );
982 painCave.isFatal = 1;
983 simError();
984 }
985 }
986 else{
987 n_cells = (int)temp3;
988 cellx = simnfo->box_x / temp3;
989 celly = simnfo->box_y / temp3;
990 cellz = simnfo->box_z / temp3;
991 }
992
993 current_mol = 0;
994 current_comp_mol = 0;
995 current_comp = 0;
996 current_atom_ndx = 0;
997
998 for( i=0; i < n_cells ; i++ ){
999 for( j=0; j < n_cells; j++ ){
1000 for( k=0; k < n_cells; k++ ){
1001
1002 makeElement( i * cellx,
1003 j * celly,
1004 k * cellz );
1005
1006 makeElement( i * cellx + 0.5 * cellx,
1007 j * celly + 0.5 * celly,
1008 k * cellz );
1009
1010 makeElement( i * cellx,
1011 j * celly + 0.5 * celly,
1012 k * cellz + 0.5 * cellz );
1013
1014 makeElement( i * cellx + 0.5 * cellx,
1015 j * celly,
1016 k * cellz + 0.5 * cellz );
1017 }
1018 }
1019 }
1020
1021 if( have_extra ){
1022 done = 0;
1023
1024 int start_ndx;
1025 for( i=0; i < (n_cells+1) && !done; i++ ){
1026 for( j=0; j < (n_cells+1) && !done; j++ ){
1027
1028 if( i < n_cells ){
1029
1030 if( j < n_cells ){
1031 start_ndx = n_cells;
1032 }
1033 else start_ndx = 0;
1034 }
1035 else start_ndx = 0;
1036
1037 for( k=start_ndx; k < (n_cells+1) && !done; k++ ){
1038
1039 makeElement( i * cellx,
1040 j * celly,
1041 k * cellz );
1042 done = ( current_mol >= tot_nmol );
1043
1044 if( !done && n_per_extra > 1 ){
1045 makeElement( i * cellx + 0.5 * cellx,
1046 j * celly + 0.5 * celly,
1047 k * cellz );
1048 done = ( current_mol >= tot_nmol );
1049 }
1050
1051 if( !done && n_per_extra > 2){
1052 makeElement( i * cellx,
1053 j * celly + 0.5 * celly,
1054 k * cellz + 0.5 * cellz );
1055 done = ( current_mol >= tot_nmol );
1056 }
1057
1058 if( !done && n_per_extra > 3){
1059 makeElement( i * cellx + 0.5 * cellx,
1060 j * celly,
1061 k * cellz + 0.5 * cellz );
1062 done = ( current_mol >= tot_nmol );
1063 }
1064 }
1065 }
1066 }
1067 }
1068
1069
1070 for( i=0; i<simnfo->n_atoms; i++ ){
1071 simnfo->atoms[i]->set_vx( 0.0 );
1072 simnfo->atoms[i]->set_vy( 0.0 );
1073 simnfo->atoms[i]->set_vz( 0.0 );
1074 }
1075 }
1076
1077 void SimSetup::makeElement( double x, double y, double z ){
1078
1079 int k;
1080 AtomStamp* current_atom;
1081 DirectionalAtom* dAtom;
1082 double rotMat[3][3];
1083
1084 for( k=0; k<comp_stamps[current_comp]->getNAtoms(); k++ ){
1085
1086 current_atom = comp_stamps[current_comp]->getAtom( k );
1087 if( !current_atom->havePosition() ){
1088 sprintf( painCave.errMsg,
1089 "SimSetup:initFromBass error.\n"
1090 "\tComponent %s, atom %s does not have a position specified.\n"
1091 "\tThe initialization routine is unable to give a start"
1092 " position.\n",
1093 comp_stamps[current_comp]->getID(),
1094 current_atom->getType() );
1095 painCave.isFatal = 1;
1096 simError();
1097 }
1098
1099 the_atoms[current_atom_ndx]->setX( x + current_atom->getPosX() );
1100 the_atoms[current_atom_ndx]->setY( y + current_atom->getPosY() );
1101 the_atoms[current_atom_ndx]->setZ( z + current_atom->getPosZ() );
1102
1103 if( the_atoms[current_atom_ndx]->isDirectional() ){
1104
1105 dAtom = (DirectionalAtom *)the_atoms[current_atom_ndx];
1106
1107 rotMat[0][0] = 1.0;
1108 rotMat[0][1] = 0.0;
1109 rotMat[0][2] = 0.0;
1110
1111 rotMat[1][0] = 0.0;
1112 rotMat[1][1] = 1.0;
1113 rotMat[1][2] = 0.0;
1114
1115 rotMat[2][0] = 0.0;
1116 rotMat[2][1] = 0.0;
1117 rotMat[2][2] = 1.0;
1118
1119 dAtom->setA( rotMat );
1120 }
1121
1122 current_atom_ndx++;
1123 }
1124
1125 current_mol++;
1126 current_comp_mol++;
1127
1128 if( current_comp_mol >= components_nmol[current_comp] ){
1129
1130 current_comp_mol = 0;
1131 current_comp++;
1132 }
1133 }