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, 7 months ago) by tim
File size: 23297 byte(s)
Log Message:
refactory, refactory, refactory

File Contents

# User Rev Content
1 tim 1710 /*
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 gezelter 1490
26 tim 1710 /**
27     * @file SimInfo.cpp
28     * @author tlin
29     * @date 11/02/2004
30     * @version 1.0
31     */
32 gezelter 1490
33 tim 1710 #include <algorithm>
34    
35 tim 1492 #include "brains/SimInfo.hpp"
36 tim 1710 #include "utils/MemoryUtils.hpp"
37 gezelter 1490
38 tim 1710 namespace oopse {
39 gezelter 1490
40 tim 1733 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 tim 1738 nCutoffGroups_(0), nConstraints_(0), nZConstraint_(0), sman_(NULL),
45     fortranInitialized_(false) {
46 gezelter 1490
47 tim 1733 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 gezelter 1490 }
95    
96 tim 1710 SimInfo::~SimInfo() {
97 tim 1726 //MemoryUtils::deleteVectorOfPointer(molecules_);
98 tim 1733
99     MemoryUtils::deleteVectorOfPointer(moleculeStamps_);
100    
101 tim 1710 delete sman_;
102 tim 1733 delete globals_;
103     delete forceField_;
104 gezelter 1490
105     }
106    
107    
108 tim 1710 bool SimInfo::addMolecule(Molecule* mol) {
109 tim 1726 MoleculeIterator i;
110 tim 1733
111     i = molecules_.find(mol->getGlobalIndex());
112 tim 1710 if (i != molecules_.end() ) {
113 gezelter 1490
114 tim 1726 molecules_.insert(make_pair(mol->getGlobalIndex(), mol));
115    
116 tim 1710 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 gezelter 1490
125 tim 1710 return true;
126     } else {
127     return false;
128 gezelter 1490 }
129     }
130    
131 tim 1710 bool SimInfo::removeMolecule(Molecule* mol) {
132 tim 1726 MoleculeIterator i;
133 tim 1733 i = molecules_.find(mol->getGlobalIndex());
134 gezelter 1490
135 tim 1710 if (i != molecules_.end() ) {
136 tim 1726
137 tim 1733 assert(mol == i->second);
138    
139 tim 1710 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 gezelter 1490
148 tim 1726 molecules_.erase(mol->getGlobalIndex());
149    
150     delete mol;
151    
152 tim 1710 return true;
153     } else {
154     return false;
155 gezelter 1490 }
156    
157    
158 tim 1710 }
159 gezelter 1490
160 tim 1710
161 tim 1726 Molecule* SimInfo::beginMolecule(MoleculeIterator& i) {
162 tim 1710 i = molecules_.begin();
163 tim 1738 return i == molecules_.end() ? NULL : i->second;
164 tim 1710 }
165 gezelter 1490
166 tim 1726 Molecule* SimInfo::nextMolecule(MoleculeIterator& i) {
167 tim 1710 ++i;
168 tim 1738 return i == molecules_.end() ? NULL : i->second;
169 gezelter 1490 }
170    
171    
172 tim 1722 void SimInfo::calcNdf() {
173 tim 1710 int ndf_local;
174 tim 1726 MoleculeIterator i;
175 tim 1710 std::vector<StuntDouble*>::iterator j;
176     Molecule* mol;
177     StuntDouble* integrableObject;
178 gezelter 1490
179 tim 1710 ndf_local = 0;
180 gezelter 1490
181 tim 1710 for (mol = beginMolecule(i); mol != NULL; mol = nextMolecule(i)) {
182     for (integrableObject = mol->beginIntegrableObject(j); integrableObject != NULL;
183     integrableObject = mol->nextIntegrableObject(j)) {
184 gezelter 1490
185 tim 1710 ndf_local += 3;
186 gezelter 1490
187 tim 1710 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 gezelter 1490
198 tim 1710 // n_constraints is local, so subtract them on each processor
199     ndf_local -= nConstraints_;
200 gezelter 1490
201     #ifdef IS_MPI
202 tim 1710 MPI_Allreduce(&ndf_local,&ndf_,1,MPI_INT,MPI_SUM, MPI_COMM_WORLD);
203 gezelter 1490 #else
204 tim 1710 ndf_ = ndf_local;
205 gezelter 1490 #endif
206    
207 tim 1733 // nZconstraints_ is global, as are the 3 COM translations for the
208 tim 1710 // entire system:
209 tim 1733 ndf_ = ndf_ - 3 - nZconstraints_;
210 gezelter 1490
211     }
212    
213 tim 1722 void SimInfo::calcNdfRaw() {
214 tim 1710 int ndfRaw_local;
215 gezelter 1490
216 tim 1726 MoleculeIterator i;
217 tim 1710 std::vector<StuntDouble*>::iterator j;
218     Molecule* mol;
219     StuntDouble* integrableObject;
220 gezelter 1490
221 tim 1710 // Raw degrees of freedom that we have to set
222     ndfRaw_local = 0;
223 gezelter 1490
224 tim 1710 for (mol = beginMolecule(i); mol != NULL; mol = nextMolecule(i)) {
225     for (integrableObject = mol->beginIntegrableObject(j); integrableObject != NULL;
226     integrableObject = mol->nextIntegrableObject(j)) {
227 gezelter 1490
228 tim 1710 ndfRaw_local += 3;
229 gezelter 1490
230 tim 1710 if (integrableObject->isDirectional()) {
231     if (integrableObject->isLinear()) {
232     ndfRaw_local += 2;
233     } else {
234     ndfRaw_local += 3;
235     }
236     }
237    
238     }
239     }
240    
241 gezelter 1490 #ifdef IS_MPI
242 tim 1710 MPI_Allreduce(&ndfRaw_local,&ndfRaw_,1,MPI_INT,MPI_SUM, MPI_COMM_WORLD);
243 gezelter 1490 #else
244 tim 1710 ndfRaw_ = ndfRaw_local;
245 gezelter 1490 #endif
246     }
247    
248 tim 1722 void SimInfo::calcNdfTrans() {
249 tim 1710 int ndfTrans_local;
250 gezelter 1490
251 tim 1710 ndfTrans_local = 3 * nIntegrableObjects_ - nConstraints_;
252 gezelter 1490
253    
254     #ifdef IS_MPI
255 tim 1710 MPI_Allreduce(&ndfTrans_local,&ndfTrans_,1,MPI_INT,MPI_SUM, MPI_COMM_WORLD);
256 gezelter 1490 #else
257 tim 1710 ndfTrans_ = ndfTrans_local;
258 gezelter 1490 #endif
259    
260 tim 1733 ndfTrans_ = ndfTrans_ - 3 - nZconstraints_;
261 gezelter 1490
262     }
263    
264 tim 1719 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 gezelter 1490
282 tim 1719 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 tim 1725 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 tim 1727 void SimInfo::update() {
365    
366 tim 1738 setupSimType();
367    
368 tim 1733 #ifdef IS_MPI
369     setupFortranParallel();
370     #endif
371 tim 1727
372 tim 1733 setupFortranSim();
373    
374 tim 1738 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 tim 1733 calcNdf();
388     calcNdfRaw();
389     calcNdfTrans();
390 tim 1738
391     fortranInitialized_ = true;
392 tim 1733 }
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 tim 1727
417 tim 1733 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 tim 1735 //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 tim 1733 //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 tim 1727 //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 tim 1733 //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 tim 1727 parallelData.myNode = worldRank;
635     MPI_Comm_size(MPI_COMM_WORLD, &(parallelData->nProcessors));
636 tim 1733
637     //pass mpiSimData struct and index arrays to fortran
638     setFsimParallel(parallelData, &(parallelData->nAtomsLocal),
639 tim 1727 &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 tim 1733 #endif
656    
657 tim 1735 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 tim 1738 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 tim 1733 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 tim 1725 std::ostream& operator <<(ostream& o, SimInfo& info) {
761    
762     return o;
763     }
764    
765 tim 1710 }//end namespace oopse