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

# 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 #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 }