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: 1739
Committed: Mon Nov 15 18:02:15 2004 UTC (19 years, 8 months ago) by tim
File size: 24455 byte(s)
Log Message:
finish DumpReader, DumpWriter.Next Step is LJFF and integrators

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