ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/mdtools/interface_implementation/SimSetup.cpp
Revision: 164
Committed: Tue Nov 5 22:04:46 2002 UTC (21 years, 8 months ago) by mmeineke
File size: 17405 byte(s)
Log Message:
*** empty log message ***

File Contents

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