ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/branches/new_design/OOPSE-2.0/src/brains/SimInfo.cpp
Revision: 1738
Committed: Sat Nov 13 05:08:12 2004 UTC (19 years, 8 months ago) by tim
File size: 23297 byte(s)
Log Message:
refactory, refactory, refactory

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