ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/branches/new_design/OOPSE-3.0/src/brains/SimInfo.cpp
Revision: 1824
Committed: Thu Dec 2 03:12:25 2004 UTC (19 years, 7 months ago) by tim
File size: 25650 byte(s)
Log Message:
replace misuse of using namespace std in header files

File Contents

# Content
1 /*
2 * Copyright (C) 2000-2004 Object Oriented Parallel Simulation Engine (OOPSE) project
3 *
4 * Contact: oopse@oopse.org
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public License
8 * as published by the Free Software Foundation; either version 2.1
9 * of the License, or (at your option) any later version.
10 * All we ask is that proper credit is given for our work, which includes
11 * - but is not limited to - adding the above copyright notice to the beginning
12 * of your source code files, and to any copyright notice that you may distribute
13 * with programs based on this work.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 *
24 */
25
26 /**
27 * @file SimInfo.cpp
28 * @author tlin
29 * @date 11/02/2004
30 * @version 1.0
31 */
32
33 #include <algorithm>
34 #include <set>
35 #include "brains/SimInfo.hpp"
36 #include "primitives/Molecule.hpp"
37 #include "UseTheForce/doForces_interface.h"
38 #include "UseTheForce/notifyCutoffs_interface.h"
39 #include "utils/MemoryUtils.hpp"
40 #include "utils/simError.h"
41
42 namespace oopse {
43
44 SimInfo::SimInfo(std::vector<std::pair<MoleculeStamp*, int> >& molStampPairs,
45 ForceField* ff, Globals* globals) :
46 forceField_(ff), globals_(globals), nAtoms_(0), nBonds_(0),
47 nBends_(0), nTorsions_(0), nRigidBodies_(0), nIntegrableObjects_(0),
48 nCutoffGroups_(0), nConstraints_(0), nZconstraint_(0), sman_(NULL),
49 fortranInitialized_(false) {
50
51 std::vector<std::pair<MoleculeStamp*, int> >::iterator i;
52 MoleculeStamp* molStamp;
53 int nMolWithSameStamp;
54 int nCutoffAtoms; // number of atoms belong to cutoff groups
55 int nGroups; //total cutoff groups defined in meta-data file
56 CutoffGroupStamp* cgStamp;
57 int nAtomsInGroups;
58 int nCutoffGroupsInStamp;
59
60 RigidBodyStamp* rbStamp;
61 int nAtomsInRigidBodies;
62 int nRigidBodiesInStamp;
63 int nRigidAtoms;
64 int nRigidBodies;
65
66 nGlobalAtoms_ = 0;
67
68 nGroups = 0;
69 nCutoffAtoms = 0;
70 nRigidBodies = 0;
71
72 for (i = molStampPairs.begin(); i !=molStampPairs.end(); ++i) {
73 molStamp = i->first;
74 nMolWithSameStamp = i->second;
75
76 addMoleculeStamp(molStamp, nMolWithSameStamp);
77
78 //calculate atoms in molecules
79 nGlobalAtoms_ += molStamp->getNAtoms() *nMolWithSameStamp;
80
81
82 //calculate atoms in cutoff groups
83 nAtomsInGroups = 0;
84 nCutoffGroupsInStamp = molStamp->getNCutoffGroups();
85
86 for (int j=0; j < nCutoffGroupsInStamp; j++) {
87 cgStamp = molStamp->getCutoffGroup(j);
88 nAtomsInGroups += cgStamp->getNMembers();
89 }
90
91 nGroups += nCutoffGroupsInStamp * nMolWithSameStamp;
92 nCutoffAtoms += nAtomsInGroups * nMolWithSameStamp;
93
94 //calculate atoms in rigid bodies
95 nAtomsInRigidBodies = 0;
96 nRigidBodiesInStamp = molStamp->getNCutoffGroups();
97
98 for (int j=0; j < nRigidBodiesInStamp; j++) {
99 rbStamp = molStamp->getRigidBody(j);
100 nRigidBodiesInStamp += rbStamp->getNMembers();
101 }
102
103 nRigidBodies += nRigidBodiesInStamp * nMolWithSameStamp;
104 nRigidAtoms += nAtomsInRigidBodies * nMolWithSameStamp;
105
106 }
107
108 //every free atom (atom does not belong to cutoff groups) is a cutoff group
109 //therefore the total number of cutoff groups in the system is equal to
110 //the total number of atoms minus number of atoms belong to cutoff group defined in meta-data
111 //file plus the number of cutoff groups defined in meta-data file
112 nGlobalCutoffGroups_ = nGlobalAtoms_ - nCutoffAtoms + nGroups;
113
114 //every free atom (atom does not belong to rigid bodies) is a rigid body
115 //therefore the total number of cutoff groups in the system is equal to
116 //the total number of atoms minus number of atoms belong to rigid body defined in meta-data
117 //file plus the number of rigid bodies defined in meta-data file
118 nGlobalIntegrableObjects_ = nGlobalAtoms_ - nRigidAtoms + nRigidBodies;
119
120 //initialize globalGroupMembership_, every element of this array will be 0
121 globalGroupMembership_.insert(globalGroupMembership_.end(), nGlobalAtoms_, 0);
122
123 nGlobalMols_ = molStampIds_.size();
124
125 #ifdef IS_MPI
126 molToProcMap_.resize(nGlobalMols_);
127 #endif
128
129 }
130
131 SimInfo::~SimInfo() {
132 //MemoryUtils::deleteVectorOfPointer(molecules_);
133
134 MemoryUtils::deleteVectorOfPointer(moleculeStamps_);
135
136 delete sman_;
137 delete globals_;
138 delete forceField_;
139
140 }
141
142
143 bool SimInfo::addMolecule(Molecule* mol) {
144 MoleculeIterator i;
145
146 i = molecules_.find(mol->getGlobalIndex());
147 if (i != molecules_.end() ) {
148
149 molecules_.insert(make_pair(mol->getGlobalIndex(), mol));
150
151 nAtoms_ += mol->getNAtoms();
152 nBonds_ += mol->getNBonds();
153 nBends_ += mol->getNBends();
154 nTorsions_ += mol->getNTorsions();
155 nRigidBodies_ += mol->getNRigidBodies();
156 nIntegrableObjects_ += mol->getNIntegrableObjects();
157 nCutoffGroups_ += mol->getNCutoffGroups();
158 nConstraints_ += mol->getNConstraints();
159
160 return true;
161 } else {
162 return false;
163 }
164 }
165
166 bool SimInfo::removeMolecule(Molecule* mol) {
167 MoleculeIterator i;
168 i = molecules_.find(mol->getGlobalIndex());
169
170 if (i != molecules_.end() ) {
171
172 assert(mol == i->second);
173
174 nAtoms_ -= mol->getNAtoms();
175 nBonds_ -= mol->getNBonds();
176 nBends_ -= mol->getNBends();
177 nTorsions_ -= mol->getNTorsions();
178 nRigidBodies_ -= mol->getNRigidBodies();
179 nIntegrableObjects_ -= mol->getNIntegrableObjects();
180 nCutoffGroups_ -= mol->getNCutoffGroups();
181 nConstraints_ -= mol->getNConstraints();
182
183 molecules_.erase(mol->getGlobalIndex());
184
185 delete mol;
186
187 return true;
188 } else {
189 return false;
190 }
191
192
193 }
194
195
196 Molecule* SimInfo::beginMolecule(MoleculeIterator& i) {
197 i = molecules_.begin();
198 return i == molecules_.end() ? NULL : i->second;
199 }
200
201 Molecule* SimInfo::nextMolecule(MoleculeIterator& i) {
202 ++i;
203 return i == molecules_.end() ? NULL : i->second;
204 }
205
206
207 void SimInfo::calcNdf() {
208 int ndf_local;
209 MoleculeIterator i;
210 std::vector<StuntDouble*>::iterator j;
211 Molecule* mol;
212 StuntDouble* integrableObject;
213
214 ndf_local = 0;
215
216 for (mol = beginMolecule(i); mol != NULL; mol = nextMolecule(i)) {
217 for (integrableObject = mol->beginIntegrableObject(j); integrableObject != NULL;
218 integrableObject = mol->nextIntegrableObject(j)) {
219
220 ndf_local += 3;
221
222 if (integrableObject->isDirectional()) {
223 if (integrableObject->isLinear()) {
224 ndf_local += 2;
225 } else {
226 ndf_local += 3;
227 }
228 }
229
230 }//end for (integrableObject)
231 }// end for (mol)
232
233 // n_constraints is local, so subtract them on each processor
234 ndf_local -= nConstraints_;
235
236 #ifdef IS_MPI
237 MPI_Allreduce(&ndf_local,&ndf_,1,MPI_INT,MPI_SUM, MPI_COMM_WORLD);
238 #else
239 ndf_ = ndf_local;
240 #endif
241
242 // nZconstraints_ is global, as are the 3 COM translations for the
243 // entire system:
244 ndf_ = ndf_ - 3 - nZconstraint_;
245
246 }
247
248 void SimInfo::calcNdfRaw() {
249 int ndfRaw_local;
250
251 MoleculeIterator i;
252 std::vector<StuntDouble*>::iterator j;
253 Molecule* mol;
254 StuntDouble* integrableObject;
255
256 // Raw degrees of freedom that we have to set
257 ndfRaw_local = 0;
258
259 for (mol = beginMolecule(i); mol != NULL; mol = nextMolecule(i)) {
260 for (integrableObject = mol->beginIntegrableObject(j); integrableObject != NULL;
261 integrableObject = mol->nextIntegrableObject(j)) {
262
263 ndfRaw_local += 3;
264
265 if (integrableObject->isDirectional()) {
266 if (integrableObject->isLinear()) {
267 ndfRaw_local += 2;
268 } else {
269 ndfRaw_local += 3;
270 }
271 }
272
273 }
274 }
275
276 #ifdef IS_MPI
277 MPI_Allreduce(&ndfRaw_local,&ndfRaw_,1,MPI_INT,MPI_SUM, MPI_COMM_WORLD);
278 #else
279 ndfRaw_ = ndfRaw_local;
280 #endif
281 }
282
283 void SimInfo::calcNdfTrans() {
284 int ndfTrans_local;
285
286 ndfTrans_local = 3 * nIntegrableObjects_ - nConstraints_;
287
288
289 #ifdef IS_MPI
290 MPI_Allreduce(&ndfTrans_local,&ndfTrans_,1,MPI_INT,MPI_SUM, MPI_COMM_WORLD);
291 #else
292 ndfTrans_ = ndfTrans_local;
293 #endif
294
295 ndfTrans_ = ndfTrans_ - 3 - nZconstraint_;
296
297 }
298
299 void SimInfo::addExcludePairs(Molecule* mol) {
300 std::vector<Bond*>::iterator bondIter;
301 std::vector<Bend*>::iterator bendIter;
302 std::vector<Torsion*>::iterator torsionIter;
303 Bond* bond;
304 Bend* bend;
305 Torsion* torsion;
306 int a;
307 int b;
308 int c;
309 int d;
310
311 for (bond= mol->beginBond(bondIter); bond != NULL; bond = mol->nextBond(bondIter)) {
312 a = bond->getAtomA()->getGlobalIndex();
313 b = bond->getAtomB()->getGlobalIndex();
314 exclude_.addPair(a, b);
315 }
316
317 for (bend= mol->beginBend(bendIter); bend != NULL; bend = mol->nextBend(bendIter)) {
318 a = bend->getAtomA()->getGlobalIndex();
319 b = bend->getAtomB()->getGlobalIndex();
320 c = bend->getAtomC()->getGlobalIndex();
321
322 exclude_.addPair(a, b);
323 exclude_.addPair(a, c);
324 exclude_.addPair(b, c);
325 }
326
327 for (torsion= mol->beginTorsion(torsionIter); torsion != NULL; torsion = mol->nextTorsion(torsionIter)) {
328 a = torsion->getAtomA()->getGlobalIndex();
329 b = torsion->getAtomB()->getGlobalIndex();
330 c = torsion->getAtomC()->getGlobalIndex();
331 d = torsion->getAtomD()->getGlobalIndex();
332
333 exclude_.addPair(a, b);
334 exclude_.addPair(a, c);
335 exclude_.addPair(a, d);
336 exclude_.addPair(b, c);
337 exclude_.addPair(b, d);
338 exclude_.addPair(c, d);
339 }
340
341
342 }
343
344 void SimInfo::removeExcludePairs(Molecule* mol) {
345 std::vector<Bond*>::iterator bondIter;
346 std::vector<Bend*>::iterator bendIter;
347 std::vector<Torsion*>::iterator torsionIter;
348 Bond* bond;
349 Bend* bend;
350 Torsion* torsion;
351 int a;
352 int b;
353 int c;
354 int d;
355
356 for (bond= mol->beginBond(bondIter); bond != NULL; bond = mol->nextBond(bondIter)) {
357 a = bond->getAtomA()->getGlobalIndex();
358 b = bond->getAtomB()->getGlobalIndex();
359 exclude_.removePair(a, b);
360 }
361
362 for (bend= mol->beginBend(bendIter); bend != NULL; bend = mol->nextBend(bendIter)) {
363 a = bend->getAtomA()->getGlobalIndex();
364 b = bend->getAtomB()->getGlobalIndex();
365 c = bend->getAtomC()->getGlobalIndex();
366
367 exclude_.removePair(a, b);
368 exclude_.removePair(a, c);
369 exclude_.removePair(b, c);
370 }
371
372 for (torsion= mol->beginTorsion(torsionIter); torsion != NULL; torsion = mol->nextTorsion(torsionIter)) {
373 a = torsion->getAtomA()->getGlobalIndex();
374 b = torsion->getAtomB()->getGlobalIndex();
375 c = torsion->getAtomC()->getGlobalIndex();
376 d = torsion->getAtomD()->getGlobalIndex();
377
378 exclude_.removePair(a, b);
379 exclude_.removePair(a, c);
380 exclude_.removePair(a, d);
381 exclude_.removePair(b, c);
382 exclude_.removePair(b, d);
383 exclude_.removePair(c, d);
384 }
385
386 }
387
388
389 void SimInfo::addMoleculeStamp(MoleculeStamp* molStamp, int nmol) {
390 int curStampId;
391
392 //index from 0
393 curStampId = molStampIds_.size();
394
395 moleculeStamps_.push_back(molStamp);
396 molStampIds_.insert(molStampIds_.end(), nmol, curStampId);
397 }
398
399 void SimInfo::update() {
400
401 setupSimType();
402
403 #ifdef IS_MPI
404 setupFortranParallel();
405 #endif
406
407 setupFortranSim();
408
409 //setup fortran force field
410 /** @deprecate */
411 int isError = 0;
412 initFortranFF( &fInfo_.SIM_uses_RF , &isError );
413 if(isError){
414 sprintf( painCave.errMsg,
415 "ForceField error: There was an error initializing the forceField in fortran.\n" );
416 painCave.isFatal = 1;
417 simError();
418 }
419
420
421 setupCutoff();
422
423 calcNdf();
424 calcNdfRaw();
425 calcNdfTrans();
426
427 fortranInitialized_ = true;
428 }
429
430 std::set<AtomType*> SimInfo::getUniqueAtomTypes() {
431 SimInfo::MoleculeIterator mi;
432 Molecule* mol;
433 Molecule::AtomIterator ai;
434 Atom* atom;
435 std::set<AtomType*> atomTypes;
436
437 for(mol = beginMolecule(mi); mol != NULL; mol = nextMolecule(mi)) {
438
439 for(atom = mol->beginAtom(ai); atom != NULL; atom = mol->nextAtom(ai)) {
440 atomTypes.insert(atom->getAtomType());
441 }
442
443 }
444
445 return atomTypes;
446 }
447
448 void SimInfo::setupSimType() {
449 std::set<AtomType*>::iterator i;
450 std::set<AtomType*> atomTypes;
451 atomTypes = getUniqueAtomTypes();
452
453 int useLennardJones = 0;
454 int useElectrostatic = 0;
455 int useEAM = 0;
456 int useCharge = 0;
457 int useDirectional = 0;
458 int useDipole = 0;
459 int useGayBerne = 0;
460 int useSticky = 0;
461 int useShape = 0;
462 int useFLARB = 0; //it is not in AtomType yet
463 int useDirectionalAtom = 0;
464 int useElectrostatics = 0;
465 //usePBC and useRF are from globals
466 bool usePBC = globals_->getPBC();
467 bool useRF = globals_->getUseRF();
468
469 //loop over all of the atom types
470 for (i = atomTypes.begin(); i != atomTypes.end(); ++i) {
471 useLennardJones |= (*i)->isLennardJones();
472 useElectrostatic |= (*i)->isElectrostatic();
473 useEAM |= (*i)->isEAM();
474 useCharge |= (*i)->isCharge();
475 useDirectional |= (*i)->isDirectional();
476 useDipole |= (*i)->isDipole();
477 useGayBerne |= (*i)->isGayBerne();
478 useSticky |= (*i)->isSticky();
479 useShape |= (*i)->isShape();
480 }
481
482 if (useSticky || useDipole || useGayBerne || useShape) {
483 useDirectionalAtom = 1;
484 }
485
486 if (useCharge || useDipole) {
487 useElectrostatics = 1;
488 }
489
490 #ifdef IS_MPI
491 int temp;
492
493 temp = usePBC;
494 MPI_Allreduce(&temp, &usePBC, 1, MPI_INT, MPI_LOR, MPI_COMM_WORLD);
495
496 temp = useDirectionalAtom;
497 MPI_Allreduce(&temp, &useDirectionalAtom, 1, MPI_INT, MPI_LOR, MPI_COMM_WORLD);
498
499 temp = useLennardJones;
500 MPI_Allreduce(&temp, &useLennardJones, 1, MPI_INT, MPI_LOR, MPI_COMM_WORLD);
501
502 temp = useElectrostatics;
503 MPI_Allreduce(&temp, &useElectrostatics, 1, MPI_INT, MPI_LOR, MPI_COMM_WORLD);
504
505 temp = useCharge;
506 MPI_Allreduce(&temp, &useCharge, 1, MPI_INT, MPI_LOR, MPI_COMM_WORLD);
507
508 temp = useDipole;
509 MPI_Allreduce(&temp, &useDipole, 1, MPI_INT, MPI_LOR, MPI_COMM_WORLD);
510
511 temp = useSticky;
512 MPI_Allreduce(&temp, &useSticky, 1, MPI_INT, MPI_LOR, MPI_COMM_WORLD);
513
514 temp = useGayBerne;
515 MPI_Allreduce(&temp, &useGayBerne, 1, MPI_INT, MPI_LOR, MPI_COMM_WORLD);
516
517 temp = useEAM;
518 MPI_Allreduce(&temp, &useEAM, 1, MPI_INT, MPI_LOR, MPI_COMM_WORLD);
519
520 temp = useShape;
521 MPI_Allreduce(&temp, &useShape, 1, MPI_INT, MPI_LOR, MPI_COMM_WORLD);
522
523 temp = useFLARB;
524 MPI_Allreduce(&temp, &useFLARB, 1, MPI_INT, MPI_LOR, MPI_COMM_WORLD);
525
526 temp = useRF;
527 MPI_Allreduce(&temp, &useRF, 1, MPI_INT, MPI_LOR, MPI_COMM_WORLD);
528
529 #endif
530
531 fInfo_.SIM_uses_PBC = usePBC;
532 fInfo_.SIM_uses_DirectionalAtoms = useDirectionalAtom;
533 fInfo_.SIM_uses_LennardJones = useLennardJones;
534 fInfo_.SIM_uses_Electrostatics = useElectrostatics;
535 fInfo_.SIM_uses_Charges = useCharge;
536 fInfo_.SIM_uses_Dipoles = useDipole;
537 fInfo_.SIM_uses_Sticky = useSticky;
538 fInfo_.SIM_uses_GayBerne = useGayBerne;
539 fInfo_.SIM_uses_EAM = useEAM;
540 fInfo_.SIM_uses_Shapes = useShape;
541 fInfo_.SIM_uses_FLARB = useFLARB;
542 fInfo_.SIM_uses_RF = useRF;
543
544 if( fInfo_.SIM_uses_Dipoles && fInfo_.SIM_uses_RF) {
545
546 if (globals_->haveDielectric()) {
547 fInfo_.dielect = globals_->getDielectric();
548 } else {
549 sprintf(painCave.errMsg,
550 "SimSetup Error: No Dielectric constant was set.\n"
551 "\tYou are trying to use Reaction Field without"
552 "\tsetting a dielectric constant!\n");
553 painCave.isFatal = 1;
554 simError();
555 }
556
557 } else {
558 fInfo_.dielect = 0.0;
559 }
560
561 }
562
563 void SimInfo::setupFortranSim() {
564 int isError;
565 int nExclude;
566 std::vector<int> fortranGlobalGroupMembership;
567
568 nExclude = exclude_.getSize();
569 isError = 0;
570
571 //globalGroupMembership_ is filled by SimCreator
572 for (int i = 0; i < nGlobalAtoms_; i++) {
573 fortranGlobalGroupMembership.push_back(globalGroupMembership_[i] + 1);
574 }
575
576 //calculate mass ratio of cutoff group
577 std::vector<double> mfact;
578 SimInfo::MoleculeIterator mi;
579 Molecule* mol;
580 Molecule::CutoffGroupIterator ci;
581 CutoffGroup* cg;
582 Molecule::AtomIterator ai;
583 Atom* atom;
584 double totalMass;
585
586 //to avoid memory reallocation, reserve enough space for mfact
587 mfact.reserve(getNCutoffGroups());
588
589 for(mol = beginMolecule(mi); mol != NULL; mol = nextMolecule(mi)) {
590 for (cg = mol->beginCutoffGroup(ci); cg != NULL; cg = mol->nextCutoffGroup(ci)) {
591
592 totalMass = cg->getMass();
593 for(atom = cg->beginAtom(ai); atom != NULL; atom = cg->nextAtom(ai)) {
594 mfact.push_back(atom->getMass()/totalMass);
595 }
596
597 }
598 }
599
600 //fill ident array of local atoms (it is actually ident of AtomType, it is so confusing !!!)
601 std::vector<int> identArray;
602
603 //to avoid memory reallocation, reserve enough space identArray
604 identArray.reserve(getNAtoms());
605
606 for(mol = beginMolecule(mi); mol != NULL; mol = nextMolecule(mi)) {
607 for(atom = mol->beginAtom(ai); atom != NULL; atom = mol->nextAtom(ai)) {
608 identArray.push_back(atom->getIdent());
609 }
610 }
611
612 //fill molMembershipArray
613 //molMembershipArray is filled by SimCreator
614 std::vector<int> molMembershipArray(nGlobalAtoms_);
615 for (int i = 0; i < nGlobalAtoms_; i++) {
616 molMembershipArray.push_back(globalMolMembership_[i] + 1);
617 }
618
619 //setup fortran simulation
620 //gloalExcludes and molMembershipArray should go away (They are never used)
621 //why the hell fortran need to know molecule?
622 //OOPSE = Object-Obfuscated Parallel Simulation Engine
623 int nGlobalExcludes = 0;
624 int* globalExcludes = NULL;
625 int* excludeList = exclude_.getExcludeList();
626 setFortranSim( &fInfo_, &nGlobalAtoms_, &nAtoms_, &identArray[0], &nExclude, excludeList ,
627 &nGlobalExcludes, globalExcludes, &molMembershipArray[0],
628 &mfact[0], &nCutoffGroups_, &fortranGlobalGroupMembership[0], &isError);
629
630 if( isError ){
631
632 sprintf( painCave.errMsg,
633 "There was an error setting the simulation information in fortran.\n" );
634 painCave.isFatal = 1;
635 painCave.severity = OOPSE_ERROR;
636 simError();
637 }
638
639 #ifdef IS_MPI
640 sprintf( checkPointMsg,
641 "succesfully sent the simulation information to fortran.\n");
642 MPIcheckPoint();
643 #endif // is_mpi
644 }
645
646
647 #ifdef IS_MPI
648 void SimInfo::setupFortranParallel() {
649
650 //SimInfo is responsible for creating localToGlobalAtomIndex and localToGlobalGroupIndex
651 std::vector<int> localToGlobalAtomIndex(getNAtoms(), 0);
652 std::vector<int> localToGlobalCutoffGroupIndex;
653 SimInfo::MoleculeIterator mi;
654 Molecule::AtomIterator ai;
655 Molecule::CutoffGroupIterator ci;
656 Molecule* mol;
657 Atom* atom;
658 CutoffGroup* cg;
659 mpiSimData parallelData;
660 int isError;
661
662 for (mol = beginMolecule(mi); mol != NULL; mol = nextMolecule(mi)) {
663
664 //local index(index in DataStorge) of atom is important
665 for (atom = mol->beginAtom(ai); atom != NULL; atom = mol->nextAtom(ai)) {
666 localToGlobalAtomIndex[atom->getLocalIndex()] = atom->getGlobalIndex() + 1;
667 }
668
669 //local index of cutoff group is trivial, it only depends on the order of travesing
670 for (cg = mol->beginCutoffGroup(ci); cg != NULL; cg = mol->nextCutoffGroup(ci)) {
671 localToGlobalCutoffGroupIndex.push_back(cg->getGlobalIndex() + 1);
672 }
673
674 }
675
676 //fill up mpiSimData struct
677 parallelData.nMolGlobal = getNGlobalMolecules();
678 parallelData.nMolLocal = getNMolecules();
679 parallelData.nAtomsGlobal = getNGlobalAtoms();
680 parallelData.nAtomsLocal = getNAtoms();
681 parallelData.nGroupsGlobal = getNGlobalCutoffGroups();
682 parallelData.nGroupsLocal = getNCutoffGroups();
683 parallelData.myNode = worldRank;
684 MPI_Comm_size(MPI_COMM_WORLD, &(parallelData->nProcessors));
685
686 //pass mpiSimData struct and index arrays to fortran
687 setFsimParallel(parallelData, &(parallelData->nAtomsLocal),
688 &localToGlobalAtomIndex[0], &(parallelData->nGroupsLocal),
689 &localToGlobalCutoffGroupIndex[0], &isError);
690
691 if (isError) {
692 sprintf(painCave.errMsg,
693 "mpiRefresh errror: fortran didn't like something we gave it.\n");
694 painCave.isFatal = 1;
695 simError();
696 }
697
698 sprintf(checkPointMsg, " mpiRefresh successful.\n");
699 MPIcheckPoint();
700
701
702 }
703
704 #endif
705
706 double SimInfo::calcMaxCutoffRadius() {
707
708
709 std::set<AtomType*> atomTypes;
710 std::set<AtomType*>::iterator i;
711 std::vector<double> cutoffRadius;
712
713 //get the unique atom types
714 atomTypes = getUniqueAtomTypes();
715
716 //query the max cutoff radius among these atom types
717 for (i = atomTypes.begin(); i != atomTypes.end(); ++i) {
718 cutoffRadius.push_back(forceField_->getRcutFromAtomType(*i));
719 }
720
721 double maxCutoffRadius = *(std::max_element(cutoffRadius.begin(), cutoffRadius.end()));
722 #ifdef IS_MPI
723 //pick the max cutoff radius among the processors
724 #endif
725
726 return maxCutoffRadius;
727 }
728
729 void SimInfo::setupCutoff() {
730 double rcut_; //cutoff radius
731 double rsw_; //switching radius
732
733 if (fInfo_.SIM_uses_Charges | fInfo_.SIM_uses_Dipoles | fInfo_.SIM_uses_RF) {
734
735 if (!globals_->haveRcut()){
736 sprintf(painCave.errMsg,
737 "SimCreator Warning: No value was set for the cutoffRadius.\n"
738 "\tOOPSE will use a default value of 15.0 angstroms"
739 "\tfor the cutoffRadius.\n");
740 painCave.isFatal = 0;
741 simError();
742 rcut_ = 15.0;
743 } else{
744 rcut_ = globals_->getRcut();
745 }
746
747 if (!globals_->haveRsw()){
748 sprintf(painCave.errMsg,
749 "SimCreator Warning: No value was set for switchingRadius.\n"
750 "\tOOPSE will use a default value of\n"
751 "\t0.95 * cutoffRadius for the switchingRadius\n");
752 painCave.isFatal = 0;
753 simError();
754 rsw_ = 0.95 * rcut_;
755 } else{
756 rsw_ = globals_->getRsw();
757 }
758
759 } else {
760 // if charge, dipole or reaction field is not used and the cutofff radius is not specified in
761 //meta-data file, the maximum cutoff radius calculated from forcefiled will be used
762
763 if (globals_->haveRcut()) {
764 rcut_ = globals_->getRcut();
765 } else {
766 //set cutoff radius to the maximum cutoff radius based on atom types in the whole system
767 rcut_ = calcMaxCutoffRadius();
768 }
769
770 if (globals_->haveRsw()) {
771 rsw_ = globals_->getRsw();
772 } else {
773 rsw_ = rcut_;
774 }
775
776 }
777
778 double rnblist = rcut_ + 1; // skin of neighbor list
779
780 //Pass these cutoff radius etc. to fortran. This function should be called once and only once
781 notifyFortranCutoffs(&rcut_, &rsw_, &rnblist);
782 }
783
784 void SimInfo::addProperty(GenericData* genData) {
785 properties_.addProperty(genData);
786 }
787
788 void SimInfo::removeProperty(const std::string& propName) {
789 properties_.removeProperty(propName);
790 }
791
792 void SimInfo::clearProperties() {
793 properties_.clearProperties();
794 }
795
796 std::vector<std::string> SimInfo::getPropertyNames() {
797 return properties_.getPropertyNames();
798 }
799
800 std::vector<GenericData*> SimInfo::getProperties() {
801 return properties_.getProperties();
802 }
803
804 GenericData* SimInfo::getPropertyByName(const std::string& propName) {
805 return properties_.getPropertyByName(propName);
806 }
807
808 void SimInfo::setSnapshotManager(SnapshotManager* sman) {
809 sman_ = sman;
810
811 Molecule* mol;
812 RigidBody* rb;
813 Atom* atom;
814 SimInfo::MoleculeIterator mi;
815 Molecule::RigidBodyIterator rbIter;
816 Molecule::AtomIterator atomIter;;
817
818 for (mol = beginMolecule(mi); mol != NULL; mol = nextMolecule(mi)) {
819
820 for (atom = mol->beginAtom(atomIter); atom != NULL; atom = mol->nextAtom(atomIter)) {
821 atom->setSnapshotManager(sman_);
822 }
823
824 for (rb = mol->beginRigidBody(rbIter); rb != NULL; rb = mol->nextRigidBody(rbIter)) {
825 rb->setSnapshotManager(sman_);
826 }
827 }
828
829 }
830
831 std::ostream& operator <<(ostream& o, SimInfo& info) {
832
833 return o;
834 }
835
836 }//end namespace oopse