ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/branches/development/src/brains/SimInfo.cpp
Revision: 1544
Committed: Fri Mar 18 19:31:52 2011 UTC (14 years, 1 month ago) by gezelter
File size: 40466 byte(s)
Log Message:
More modifications for paralllel rewrite

File Contents

# User Rev Content
1 gezelter 507 /*
2 gezelter 246 * Copyright (c) 2005 The University of Notre Dame. All Rights Reserved.
3     *
4     * The University of Notre Dame grants you ("Licensee") a
5     * non-exclusive, royalty free, license to use, modify and
6     * redistribute this software in source and binary code form, provided
7     * that the following conditions are met:
8     *
9 gezelter 1390 * 1. Redistributions of source code must retain the above copyright
10 gezelter 246 * notice, this list of conditions and the following disclaimer.
11     *
12 gezelter 1390 * 2. Redistributions in binary form must reproduce the above copyright
13 gezelter 246 * notice, this list of conditions and the following disclaimer in the
14     * documentation and/or other materials provided with the
15     * distribution.
16     *
17     * This software is provided "AS IS," without a warranty of any
18     * kind. All express or implied conditions, representations and
19     * warranties, including any implied warranty of merchantability,
20     * fitness for a particular purpose or non-infringement, are hereby
21     * excluded. The University of Notre Dame and its licensors shall not
22     * be liable for any damages suffered by licensee as a result of
23     * using, modifying or distributing the software or its
24     * derivatives. In no event will the University of Notre Dame or its
25     * licensors be liable for any lost revenue, profit or data, or for
26     * direct, indirect, special, consequential, incidental or punitive
27     * damages, however caused and regardless of the theory of liability,
28     * arising out of the use of or inability to use software, even if the
29     * University of Notre Dame has been advised of the possibility of
30     * such damages.
31 gezelter 1390 *
32     * SUPPORT OPEN SCIENCE! If you use OpenMD or its source code in your
33     * research, please cite the appropriate papers when you publish your
34     * work. Good starting points are:
35     *
36     * [1] Meineke, et al., J. Comp. Chem. 26, 252-271 (2005).
37     * [2] Fennell & Gezelter, J. Chem. Phys. 124, 234104 (2006).
38     * [3] Sun, Lin & Gezelter, J. Chem. Phys. 128, 24107 (2008).
39     * [4] Vardeman & Gezelter, in progress (2009).
40 gezelter 246 */
41    
42     /**
43     * @file SimInfo.cpp
44     * @author tlin
45     * @date 11/02/2004
46     * @version 1.0
47     */
48 gezelter 2
49 gezelter 246 #include <algorithm>
50     #include <set>
51 tim 749 #include <map>
52 gezelter 2
53 tim 3 #include "brains/SimInfo.hpp"
54 gezelter 246 #include "math/Vector3.hpp"
55     #include "primitives/Molecule.hpp"
56 tim 1024 #include "primitives/StuntDouble.hpp"
57 chuckv 1095 #include "UseTheForce/DarkSide/neighborLists_interface.h"
58 gezelter 1536 #include "UseTheForce/doForces_interface.h"
59 gezelter 246 #include "utils/MemoryUtils.hpp"
60 tim 3 #include "utils/simError.h"
61 tim 316 #include "selection/SelectionManager.hpp"
62 chuckv 834 #include "io/ForceFieldOptions.hpp"
63     #include "UseTheForce/ForceField.hpp"
64 gezelter 1530 #include "nonbonded/SwitchingFunction.hpp"
65 gezelter 2
66 gezelter 246 #ifdef IS_MPI
67     #include "UseTheForce/mpiComponentPlan.h"
68     #include "UseTheForce/DarkSide/simParallel_interface.h"
69     #endif
70 gezelter 2
71 gezelter 1528 using namespace std;
72 gezelter 1390 namespace OpenMD {
73 tim 749
74 tim 770 SimInfo::SimInfo(ForceField* ff, Globals* simParams) :
75     forceField_(ff), simParams_(simParams),
76 gezelter 945 ndf_(0), fdf_local(0), ndfRaw_(0), ndfTrans_(0), nZconstraint_(0),
77 gezelter 507 nGlobalMols_(0), nGlobalAtoms_(0), nGlobalCutoffGroups_(0),
78     nGlobalIntegrableObjects_(0), nGlobalRigidBodies_(0),
79 gezelter 1277 nAtoms_(0), nBonds_(0), nBends_(0), nTorsions_(0), nInversions_(0),
80     nRigidBodies_(0), nIntegrableObjects_(0), nCutoffGroups_(0),
81     nConstraints_(0), sman_(NULL), fortranInitialized_(false),
82 gezelter 1528 calcBoxDipole_(false), useAtomicVirial_(true) {
83    
84     MoleculeStamp* molStamp;
85     int nMolWithSameStamp;
86     int nCutoffAtoms = 0; // number of atoms belong to cutoff groups
87     int nGroups = 0; //total cutoff groups defined in meta-data file
88     CutoffGroupStamp* cgStamp;
89     RigidBodyStamp* rbStamp;
90     int nRigidAtoms = 0;
91    
92     vector<Component*> components = simParams->getComponents();
93    
94     for (vector<Component*>::iterator i = components.begin(); i !=components.end(); ++i) {
95     molStamp = (*i)->getMoleculeStamp();
96     nMolWithSameStamp = (*i)->getNMol();
97 tim 770
98 gezelter 1528 addMoleculeStamp(molStamp, nMolWithSameStamp);
99    
100     //calculate atoms in molecules
101     nGlobalAtoms_ += molStamp->getNAtoms() *nMolWithSameStamp;
102    
103     //calculate atoms in cutoff groups
104     int nAtomsInGroups = 0;
105     int nCutoffGroupsInStamp = molStamp->getNCutoffGroups();
106    
107     for (int j=0; j < nCutoffGroupsInStamp; j++) {
108     cgStamp = molStamp->getCutoffGroupStamp(j);
109     nAtomsInGroups += cgStamp->getNMembers();
110 gezelter 507 }
111 gezelter 1528
112     nGroups += nCutoffGroupsInStamp * nMolWithSameStamp;
113    
114     nCutoffAtoms += nAtomsInGroups * nMolWithSameStamp;
115    
116     //calculate atoms in rigid bodies
117     int nAtomsInRigidBodies = 0;
118     int nRigidBodiesInStamp = molStamp->getNRigidBodies();
119    
120     for (int j=0; j < nRigidBodiesInStamp; j++) {
121     rbStamp = molStamp->getRigidBodyStamp(j);
122     nAtomsInRigidBodies += rbStamp->getNMembers();
123     }
124    
125     nGlobalRigidBodies_ += nRigidBodiesInStamp * nMolWithSameStamp;
126     nRigidAtoms += nAtomsInRigidBodies * nMolWithSameStamp;
127    
128     }
129    
130     //every free atom (atom does not belong to cutoff groups) is a cutoff
131     //group therefore the total number of cutoff groups in the system is
132     //equal to the total number of atoms minus number of atoms belong to
133     //cutoff group defined in meta-data file plus the number of cutoff
134     //groups defined in meta-data file
135 gezelter 1540 std::cerr << "nGA = " << nGlobalAtoms_ << "\n";
136     std::cerr << "nCA = " << nCutoffAtoms << "\n";
137     std::cerr << "nG = " << nGroups << "\n";
138    
139 gezelter 1528 nGlobalCutoffGroups_ = nGlobalAtoms_ - nCutoffAtoms + nGroups;
140 gezelter 1540
141     std::cerr << "nGCG = " << nGlobalCutoffGroups_ << "\n";
142 gezelter 1528
143     //every free atom (atom does not belong to rigid bodies) is an
144     //integrable object therefore the total number of integrable objects
145     //in the system is equal to the total number of atoms minus number of
146     //atoms belong to rigid body defined in meta-data file plus the number
147     //of rigid bodies defined in meta-data file
148     nGlobalIntegrableObjects_ = nGlobalAtoms_ - nRigidAtoms
149     + nGlobalRigidBodies_;
150    
151     nGlobalMols_ = molStampIds_.size();
152     molToProcMap_.resize(nGlobalMols_);
153     }
154 chrisfen 645
155 gezelter 507 SimInfo::~SimInfo() {
156 gezelter 1528 map<int, Molecule*>::iterator i;
157 tim 398 for (i = molecules_.begin(); i != molecules_.end(); ++i) {
158 gezelter 507 delete i->second;
159 tim 398 }
160     molecules_.clear();
161 tim 490
162 gezelter 246 delete sman_;
163     delete simParams_;
164     delete forceField_;
165 gezelter 507 }
166 gezelter 2
167    
168 gezelter 507 bool SimInfo::addMolecule(Molecule* mol) {
169 gezelter 246 MoleculeIterator i;
170 gezelter 1528
171 gezelter 246 i = molecules_.find(mol->getGlobalIndex());
172     if (i == molecules_.end() ) {
173 gezelter 1528
174     molecules_.insert(make_pair(mol->getGlobalIndex(), mol));
175    
176 gezelter 507 nAtoms_ += mol->getNAtoms();
177     nBonds_ += mol->getNBonds();
178     nBends_ += mol->getNBends();
179     nTorsions_ += mol->getNTorsions();
180 gezelter 1277 nInversions_ += mol->getNInversions();
181 gezelter 507 nRigidBodies_ += mol->getNRigidBodies();
182     nIntegrableObjects_ += mol->getNIntegrableObjects();
183     nCutoffGroups_ += mol->getNCutoffGroups();
184     nConstraints_ += mol->getNConstraintPairs();
185 gezelter 1528
186 gezelter 1287 addInteractionPairs(mol);
187 gezelter 1528
188 gezelter 507 return true;
189 gezelter 246 } else {
190 gezelter 507 return false;
191 gezelter 246 }
192 gezelter 507 }
193 gezelter 1528
194 gezelter 507 bool SimInfo::removeMolecule(Molecule* mol) {
195 gezelter 246 MoleculeIterator i;
196     i = molecules_.find(mol->getGlobalIndex());
197 gezelter 2
198 gezelter 246 if (i != molecules_.end() ) {
199 gezelter 2
200 gezelter 507 assert(mol == i->second);
201 gezelter 246
202 gezelter 507 nAtoms_ -= mol->getNAtoms();
203     nBonds_ -= mol->getNBonds();
204     nBends_ -= mol->getNBends();
205     nTorsions_ -= mol->getNTorsions();
206 gezelter 1277 nInversions_ -= mol->getNInversions();
207 gezelter 507 nRigidBodies_ -= mol->getNRigidBodies();
208     nIntegrableObjects_ -= mol->getNIntegrableObjects();
209     nCutoffGroups_ -= mol->getNCutoffGroups();
210     nConstraints_ -= mol->getNConstraintPairs();
211 gezelter 2
212 gezelter 1287 removeInteractionPairs(mol);
213 gezelter 507 molecules_.erase(mol->getGlobalIndex());
214 gezelter 2
215 gezelter 507 delete mol;
216 gezelter 246
217 gezelter 507 return true;
218 gezelter 246 } else {
219 gezelter 507 return false;
220 gezelter 246 }
221 gezelter 507 }
222 gezelter 246
223    
224 gezelter 507 Molecule* SimInfo::beginMolecule(MoleculeIterator& i) {
225 gezelter 246 i = molecules_.begin();
226     return i == molecules_.end() ? NULL : i->second;
227 gezelter 507 }
228 gezelter 246
229 gezelter 507 Molecule* SimInfo::nextMolecule(MoleculeIterator& i) {
230 gezelter 246 ++i;
231     return i == molecules_.end() ? NULL : i->second;
232 gezelter 507 }
233 gezelter 2
234    
235 gezelter 507 void SimInfo::calcNdf() {
236 gezelter 246 int ndf_local;
237     MoleculeIterator i;
238 gezelter 1528 vector<StuntDouble*>::iterator j;
239 gezelter 246 Molecule* mol;
240     StuntDouble* integrableObject;
241 gezelter 2
242 gezelter 246 ndf_local = 0;
243    
244     for (mol = beginMolecule(i); mol != NULL; mol = nextMolecule(i)) {
245 gezelter 507 for (integrableObject = mol->beginIntegrableObject(j); integrableObject != NULL;
246     integrableObject = mol->nextIntegrableObject(j)) {
247 gezelter 2
248 gezelter 507 ndf_local += 3;
249 gezelter 2
250 gezelter 507 if (integrableObject->isDirectional()) {
251     if (integrableObject->isLinear()) {
252     ndf_local += 2;
253     } else {
254     ndf_local += 3;
255     }
256     }
257 gezelter 246
258 tim 770 }
259     }
260 gezelter 246
261     // n_constraints is local, so subtract them on each processor
262     ndf_local -= nConstraints_;
263    
264     #ifdef IS_MPI
265     MPI_Allreduce(&ndf_local,&ndf_,1,MPI_INT,MPI_SUM, MPI_COMM_WORLD);
266     #else
267     ndf_ = ndf_local;
268     #endif
269    
270     // nZconstraints_ is global, as are the 3 COM translations for the
271     // entire system:
272     ndf_ = ndf_ - 3 - nZconstraint_;
273    
274 gezelter 507 }
275 gezelter 2
276 gezelter 945 int SimInfo::getFdf() {
277     #ifdef IS_MPI
278     MPI_Allreduce(&fdf_local,&fdf_,1,MPI_INT,MPI_SUM, MPI_COMM_WORLD);
279     #else
280     fdf_ = fdf_local;
281     #endif
282     return fdf_;
283     }
284    
285 gezelter 507 void SimInfo::calcNdfRaw() {
286 gezelter 246 int ndfRaw_local;
287 gezelter 2
288 gezelter 246 MoleculeIterator i;
289 gezelter 1528 vector<StuntDouble*>::iterator j;
290 gezelter 246 Molecule* mol;
291     StuntDouble* integrableObject;
292    
293     // Raw degrees of freedom that we have to set
294     ndfRaw_local = 0;
295    
296     for (mol = beginMolecule(i); mol != NULL; mol = nextMolecule(i)) {
297 gezelter 507 for (integrableObject = mol->beginIntegrableObject(j); integrableObject != NULL;
298     integrableObject = mol->nextIntegrableObject(j)) {
299 gezelter 246
300 gezelter 507 ndfRaw_local += 3;
301 gezelter 246
302 gezelter 507 if (integrableObject->isDirectional()) {
303     if (integrableObject->isLinear()) {
304     ndfRaw_local += 2;
305     } else {
306     ndfRaw_local += 3;
307     }
308     }
309 gezelter 246
310 gezelter 507 }
311 gezelter 246 }
312    
313     #ifdef IS_MPI
314     MPI_Allreduce(&ndfRaw_local,&ndfRaw_,1,MPI_INT,MPI_SUM, MPI_COMM_WORLD);
315     #else
316     ndfRaw_ = ndfRaw_local;
317     #endif
318 gezelter 507 }
319 gezelter 2
320 gezelter 507 void SimInfo::calcNdfTrans() {
321 gezelter 246 int ndfTrans_local;
322 gezelter 2
323 gezelter 246 ndfTrans_local = 3 * nIntegrableObjects_ - nConstraints_;
324 gezelter 2
325    
326 gezelter 246 #ifdef IS_MPI
327     MPI_Allreduce(&ndfTrans_local,&ndfTrans_,1,MPI_INT,MPI_SUM, MPI_COMM_WORLD);
328     #else
329     ndfTrans_ = ndfTrans_local;
330     #endif
331 gezelter 2
332 gezelter 246 ndfTrans_ = ndfTrans_ - 3 - nZconstraint_;
333    
334 gezelter 507 }
335 gezelter 2
336 gezelter 1287 void SimInfo::addInteractionPairs(Molecule* mol) {
337     ForceFieldOptions& options_ = forceField_->getForceFieldOptions();
338 gezelter 1528 vector<Bond*>::iterator bondIter;
339     vector<Bend*>::iterator bendIter;
340     vector<Torsion*>::iterator torsionIter;
341     vector<Inversion*>::iterator inversionIter;
342 gezelter 246 Bond* bond;
343     Bend* bend;
344     Torsion* torsion;
345 gezelter 1277 Inversion* inversion;
346 gezelter 246 int a;
347     int b;
348     int c;
349     int d;
350 tim 749
351 gezelter 1287 // atomGroups can be used to add special interaction maps between
352     // groups of atoms that are in two separate rigid bodies.
353     // However, most site-site interactions between two rigid bodies
354     // are probably not special, just the ones between the physically
355     // bonded atoms. Interactions *within* a single rigid body should
356     // always be excluded. These are done at the bottom of this
357     // function.
358    
359 gezelter 1528 map<int, set<int> > atomGroups;
360 tim 749 Molecule::RigidBodyIterator rbIter;
361     RigidBody* rb;
362     Molecule::IntegrableObjectIterator ii;
363     StuntDouble* integrableObject;
364 gezelter 246
365 gezelter 1287 for (integrableObject = mol->beginIntegrableObject(ii);
366     integrableObject != NULL;
367     integrableObject = mol->nextIntegrableObject(ii)) {
368    
369 tim 749 if (integrableObject->isRigidBody()) {
370 gezelter 1287 rb = static_cast<RigidBody*>(integrableObject);
371 gezelter 1528 vector<Atom*> atoms = rb->getAtoms();
372     set<int> rigidAtoms;
373 gezelter 1287 for (int i = 0; i < static_cast<int>(atoms.size()); ++i) {
374     rigidAtoms.insert(atoms[i]->getGlobalIndex());
375     }
376     for (int i = 0; i < static_cast<int>(atoms.size()); ++i) {
377 gezelter 1528 atomGroups.insert(map<int, set<int> >::value_type(atoms[i]->getGlobalIndex(), rigidAtoms));
378 gezelter 1287 }
379 tim 749 } else {
380 gezelter 1528 set<int> oneAtomSet;
381 tim 749 oneAtomSet.insert(integrableObject->getGlobalIndex());
382 gezelter 1528 atomGroups.insert(map<int, set<int> >::value_type(integrableObject->getGlobalIndex(), oneAtomSet));
383 tim 749 }
384     }
385 gezelter 1287
386     for (bond= mol->beginBond(bondIter); bond != NULL;
387     bond = mol->nextBond(bondIter)) {
388 tim 749
389 gezelter 1287 a = bond->getAtomA()->getGlobalIndex();
390     b = bond->getAtomB()->getGlobalIndex();
391 tim 749
392 gezelter 1287 if (options_.havevdw12scale() || options_.haveelectrostatic12scale()) {
393     oneTwoInteractions_.addPair(a, b);
394     } else {
395     excludedInteractions_.addPair(a, b);
396     }
397 gezelter 246 }
398 gezelter 2
399 gezelter 1287 for (bend= mol->beginBend(bendIter); bend != NULL;
400     bend = mol->nextBend(bendIter)) {
401    
402 gezelter 507 a = bend->getAtomA()->getGlobalIndex();
403     b = bend->getAtomB()->getGlobalIndex();
404     c = bend->getAtomC()->getGlobalIndex();
405 gezelter 1287
406     if (options_.havevdw12scale() || options_.haveelectrostatic12scale()) {
407     oneTwoInteractions_.addPair(a, b);
408     oneTwoInteractions_.addPair(b, c);
409     } else {
410     excludedInteractions_.addPair(a, b);
411     excludedInteractions_.addPair(b, c);
412     }
413 gezelter 2
414 gezelter 1287 if (options_.havevdw13scale() || options_.haveelectrostatic13scale()) {
415     oneThreeInteractions_.addPair(a, c);
416     } else {
417     excludedInteractions_.addPair(a, c);
418     }
419 gezelter 246 }
420 gezelter 2
421 gezelter 1287 for (torsion= mol->beginTorsion(torsionIter); torsion != NULL;
422     torsion = mol->nextTorsion(torsionIter)) {
423    
424 gezelter 507 a = torsion->getAtomA()->getGlobalIndex();
425     b = torsion->getAtomB()->getGlobalIndex();
426     c = torsion->getAtomC()->getGlobalIndex();
427 gezelter 1287 d = torsion->getAtomD()->getGlobalIndex();
428 cli2 1290
429 gezelter 1287 if (options_.havevdw12scale() || options_.haveelectrostatic12scale()) {
430     oneTwoInteractions_.addPair(a, b);
431     oneTwoInteractions_.addPair(b, c);
432     oneTwoInteractions_.addPair(c, d);
433     } else {
434     excludedInteractions_.addPair(a, b);
435     excludedInteractions_.addPair(b, c);
436     excludedInteractions_.addPair(c, d);
437     }
438 gezelter 2
439 gezelter 1287 if (options_.havevdw13scale() || options_.haveelectrostatic13scale()) {
440     oneThreeInteractions_.addPair(a, c);
441     oneThreeInteractions_.addPair(b, d);
442     } else {
443     excludedInteractions_.addPair(a, c);
444     excludedInteractions_.addPair(b, d);
445     }
446 tim 749
447 gezelter 1287 if (options_.havevdw14scale() || options_.haveelectrostatic14scale()) {
448     oneFourInteractions_.addPair(a, d);
449     } else {
450     excludedInteractions_.addPair(a, d);
451     }
452 gezelter 2 }
453    
454 gezelter 1277 for (inversion= mol->beginInversion(inversionIter); inversion != NULL;
455     inversion = mol->nextInversion(inversionIter)) {
456 gezelter 1287
457 gezelter 1277 a = inversion->getAtomA()->getGlobalIndex();
458     b = inversion->getAtomB()->getGlobalIndex();
459     c = inversion->getAtomC()->getGlobalIndex();
460     d = inversion->getAtomD()->getGlobalIndex();
461    
462 gezelter 1287 if (options_.havevdw12scale() || options_.haveelectrostatic12scale()) {
463     oneTwoInteractions_.addPair(a, b);
464     oneTwoInteractions_.addPair(a, c);
465     oneTwoInteractions_.addPair(a, d);
466     } else {
467     excludedInteractions_.addPair(a, b);
468     excludedInteractions_.addPair(a, c);
469     excludedInteractions_.addPair(a, d);
470     }
471 gezelter 1277
472 gezelter 1287 if (options_.havevdw13scale() || options_.haveelectrostatic13scale()) {
473     oneThreeInteractions_.addPair(b, c);
474     oneThreeInteractions_.addPair(b, d);
475     oneThreeInteractions_.addPair(c, d);
476     } else {
477     excludedInteractions_.addPair(b, c);
478     excludedInteractions_.addPair(b, d);
479     excludedInteractions_.addPair(c, d);
480     }
481 gezelter 1277 }
482    
483 gezelter 1287 for (rb = mol->beginRigidBody(rbIter); rb != NULL;
484     rb = mol->nextRigidBody(rbIter)) {
485 gezelter 1528 vector<Atom*> atoms = rb->getAtoms();
486 gezelter 1287 for (int i = 0; i < static_cast<int>(atoms.size()) -1 ; ++i) {
487     for (int j = i + 1; j < static_cast<int>(atoms.size()); ++j) {
488 gezelter 507 a = atoms[i]->getGlobalIndex();
489     b = atoms[j]->getGlobalIndex();
490 gezelter 1287 excludedInteractions_.addPair(a, b);
491 gezelter 507 }
492     }
493 tim 430 }
494    
495 gezelter 507 }
496 gezelter 246
497 gezelter 1287 void SimInfo::removeInteractionPairs(Molecule* mol) {
498     ForceFieldOptions& options_ = forceField_->getForceFieldOptions();
499 gezelter 1528 vector<Bond*>::iterator bondIter;
500     vector<Bend*>::iterator bendIter;
501     vector<Torsion*>::iterator torsionIter;
502     vector<Inversion*>::iterator inversionIter;
503 gezelter 246 Bond* bond;
504     Bend* bend;
505     Torsion* torsion;
506 gezelter 1277 Inversion* inversion;
507 gezelter 246 int a;
508     int b;
509     int c;
510     int d;
511 tim 749
512 gezelter 1528 map<int, set<int> > atomGroups;
513 tim 749 Molecule::RigidBodyIterator rbIter;
514     RigidBody* rb;
515     Molecule::IntegrableObjectIterator ii;
516     StuntDouble* integrableObject;
517 gezelter 246
518 gezelter 1287 for (integrableObject = mol->beginIntegrableObject(ii);
519     integrableObject != NULL;
520     integrableObject = mol->nextIntegrableObject(ii)) {
521    
522 tim 749 if (integrableObject->isRigidBody()) {
523 gezelter 1287 rb = static_cast<RigidBody*>(integrableObject);
524 gezelter 1528 vector<Atom*> atoms = rb->getAtoms();
525     set<int> rigidAtoms;
526 gezelter 1287 for (int i = 0; i < static_cast<int>(atoms.size()); ++i) {
527     rigidAtoms.insert(atoms[i]->getGlobalIndex());
528     }
529     for (int i = 0; i < static_cast<int>(atoms.size()); ++i) {
530 gezelter 1528 atomGroups.insert(map<int, set<int> >::value_type(atoms[i]->getGlobalIndex(), rigidAtoms));
531 gezelter 1287 }
532 tim 749 } else {
533 gezelter 1528 set<int> oneAtomSet;
534 tim 749 oneAtomSet.insert(integrableObject->getGlobalIndex());
535 gezelter 1528 atomGroups.insert(map<int, set<int> >::value_type(integrableObject->getGlobalIndex(), oneAtomSet));
536 tim 749 }
537     }
538    
539 gezelter 1287 for (bond= mol->beginBond(bondIter); bond != NULL;
540     bond = mol->nextBond(bondIter)) {
541    
542     a = bond->getAtomA()->getGlobalIndex();
543     b = bond->getAtomB()->getGlobalIndex();
544 tim 749
545 gezelter 1287 if (options_.havevdw12scale() || options_.haveelectrostatic12scale()) {
546     oneTwoInteractions_.removePair(a, b);
547     } else {
548     excludedInteractions_.removePair(a, b);
549     }
550 gezelter 2 }
551 gezelter 246
552 gezelter 1287 for (bend= mol->beginBend(bendIter); bend != NULL;
553     bend = mol->nextBend(bendIter)) {
554    
555 gezelter 507 a = bend->getAtomA()->getGlobalIndex();
556     b = bend->getAtomB()->getGlobalIndex();
557     c = bend->getAtomC()->getGlobalIndex();
558 gezelter 1287
559     if (options_.havevdw12scale() || options_.haveelectrostatic12scale()) {
560     oneTwoInteractions_.removePair(a, b);
561     oneTwoInteractions_.removePair(b, c);
562     } else {
563     excludedInteractions_.removePair(a, b);
564     excludedInteractions_.removePair(b, c);
565     }
566 gezelter 246
567 gezelter 1287 if (options_.havevdw13scale() || options_.haveelectrostatic13scale()) {
568     oneThreeInteractions_.removePair(a, c);
569     } else {
570     excludedInteractions_.removePair(a, c);
571     }
572 gezelter 2 }
573 gezelter 246
574 gezelter 1287 for (torsion= mol->beginTorsion(torsionIter); torsion != NULL;
575     torsion = mol->nextTorsion(torsionIter)) {
576    
577 gezelter 507 a = torsion->getAtomA()->getGlobalIndex();
578     b = torsion->getAtomB()->getGlobalIndex();
579     c = torsion->getAtomC()->getGlobalIndex();
580 gezelter 1287 d = torsion->getAtomD()->getGlobalIndex();
581    
582     if (options_.havevdw12scale() || options_.haveelectrostatic12scale()) {
583     oneTwoInteractions_.removePair(a, b);
584     oneTwoInteractions_.removePair(b, c);
585     oneTwoInteractions_.removePair(c, d);
586     } else {
587     excludedInteractions_.removePair(a, b);
588     excludedInteractions_.removePair(b, c);
589     excludedInteractions_.removePair(c, d);
590     }
591 gezelter 246
592 gezelter 1287 if (options_.havevdw13scale() || options_.haveelectrostatic13scale()) {
593     oneThreeInteractions_.removePair(a, c);
594     oneThreeInteractions_.removePair(b, d);
595     } else {
596     excludedInteractions_.removePair(a, c);
597     excludedInteractions_.removePair(b, d);
598     }
599 tim 749
600 gezelter 1287 if (options_.havevdw14scale() || options_.haveelectrostatic14scale()) {
601     oneFourInteractions_.removePair(a, d);
602     } else {
603     excludedInteractions_.removePair(a, d);
604     }
605     }
606 tim 749
607 gezelter 1287 for (inversion= mol->beginInversion(inversionIter); inversion != NULL;
608     inversion = mol->nextInversion(inversionIter)) {
609 tim 749
610 gezelter 1277 a = inversion->getAtomA()->getGlobalIndex();
611     b = inversion->getAtomB()->getGlobalIndex();
612     c = inversion->getAtomC()->getGlobalIndex();
613     d = inversion->getAtomD()->getGlobalIndex();
614    
615 gezelter 1287 if (options_.havevdw12scale() || options_.haveelectrostatic12scale()) {
616     oneTwoInteractions_.removePair(a, b);
617     oneTwoInteractions_.removePair(a, c);
618     oneTwoInteractions_.removePair(a, d);
619     } else {
620     excludedInteractions_.removePair(a, b);
621     excludedInteractions_.removePair(a, c);
622     excludedInteractions_.removePair(a, d);
623     }
624 gezelter 1277
625 gezelter 1287 if (options_.havevdw13scale() || options_.haveelectrostatic13scale()) {
626     oneThreeInteractions_.removePair(b, c);
627     oneThreeInteractions_.removePair(b, d);
628     oneThreeInteractions_.removePair(c, d);
629     } else {
630     excludedInteractions_.removePair(b, c);
631     excludedInteractions_.removePair(b, d);
632     excludedInteractions_.removePair(c, d);
633     }
634 gezelter 1277 }
635    
636 gezelter 1287 for (rb = mol->beginRigidBody(rbIter); rb != NULL;
637     rb = mol->nextRigidBody(rbIter)) {
638 gezelter 1528 vector<Atom*> atoms = rb->getAtoms();
639 gezelter 1287 for (int i = 0; i < static_cast<int>(atoms.size()) -1 ; ++i) {
640     for (int j = i + 1; j < static_cast<int>(atoms.size()); ++j) {
641 gezelter 507 a = atoms[i]->getGlobalIndex();
642     b = atoms[j]->getGlobalIndex();
643 gezelter 1287 excludedInteractions_.removePair(a, b);
644 gezelter 507 }
645     }
646 tim 430 }
647 gezelter 1287
648 gezelter 507 }
649 gezelter 1287
650    
651 gezelter 507 void SimInfo::addMoleculeStamp(MoleculeStamp* molStamp, int nmol) {
652 gezelter 246 int curStampId;
653 gezelter 1287
654 gezelter 246 //index from 0
655     curStampId = moleculeStamps_.size();
656 gezelter 2
657 gezelter 246 moleculeStamps_.push_back(molStamp);
658     molStampIds_.insert(molStampIds_.end(), nmol, curStampId);
659 gezelter 507 }
660 gezelter 2
661 gezelter 1530
662     /**
663     * update
664     *
665 gezelter 1535 * Performs the global checks and variable settings after the
666     * objects have been created.
667 gezelter 1530 *
668     */
669 gezelter 1535 void SimInfo::update() {
670 gezelter 1530 setupSimVariables();
671 gezelter 246 calcNdf();
672     calcNdfRaw();
673     calcNdfTrans();
674 gezelter 507 }
675 gezelter 1528
676 gezelter 1535 /**
677     * getSimulatedAtomTypes
678     *
679     * Returns an STL set of AtomType* that are actually present in this
680     * simulation. Must query all processors to assemble this information.
681     *
682     */
683 gezelter 1528 set<AtomType*> SimInfo::getSimulatedAtomTypes() {
684 gezelter 246 SimInfo::MoleculeIterator mi;
685     Molecule* mol;
686     Molecule::AtomIterator ai;
687     Atom* atom;
688 gezelter 1528 set<AtomType*> atomTypes;
689    
690 gezelter 1529 for(mol = beginMolecule(mi); mol != NULL; mol = nextMolecule(mi)) {
691 gezelter 507 for(atom = mol->beginAtom(ai); atom != NULL; atom = mol->nextAtom(ai)) {
692     atomTypes.insert(atom->getAtomType());
693 gezelter 1529 }
694     }
695 gezelter 2
696 gezelter 1535 #ifdef IS_MPI
697    
698     // loop over the found atom types on this processor, and add their
699     // numerical idents to a vector:
700    
701     vector<int> foundTypes;
702     set<AtomType*>::iterator i;
703     for (i = atomTypes.begin(); i != atomTypes.end(); ++i)
704     foundTypes.push_back( (*i)->getIdent() );
705    
706     // count_local holds the number of found types on this processor
707     int count_local = foundTypes.size();
708    
709     // count holds the total number of found types on all processors
710     // (some will be redundant with the ones found locally):
711     int count;
712     MPI::COMM_WORLD.Allreduce(&count_local, &count, 1, MPI::INT, MPI::SUM);
713    
714     // create a vector to hold the globally found types, and resize it:
715     vector<int> ftGlobal;
716     ftGlobal.resize(count);
717     vector<int> counts;
718    
719     int nproc = MPI::COMM_WORLD.Get_size();
720     counts.resize(nproc);
721     vector<int> disps;
722     disps.resize(nproc);
723    
724     // now spray out the foundTypes to all the other processors:
725 gezelter 2
726 gezelter 1535 MPI::COMM_WORLD.Allgatherv(&foundTypes[0], count_local, MPI::INT,
727     &ftGlobal[0], &counts[0], &disps[0], MPI::INT);
728 gezelter 1126
729 gezelter 1535 // foundIdents is a stl set, so inserting an already found ident
730     // will have no effect.
731     set<int> foundIdents;
732     vector<int>::iterator j;
733     for (j = ftGlobal.begin(); j != ftGlobal.end(); ++j)
734     foundIdents.insert((*j));
735 gezelter 1528
736 gezelter 1535 // now iterate over the foundIdents and get the actual atom types
737     // that correspond to these:
738     set<int>::iterator it;
739     for (it = foundIdents.begin(); it != foundIdents.end(); ++it)
740     atomTypes.insert( forceField_->getAtomType((*it)) );
741    
742     #endif
743 gezelter 1530
744 gezelter 1535 return atomTypes;
745 gezelter 1528 }
746 chrisfen 611
747 gezelter 1534 void SimInfo::setupSimVariables() {
748     useAtomicVirial_ = simParams_->getUseAtomicVirial();
749     // we only call setAccumulateBoxDipole if the accumulateBoxDipole parameter is true
750     calcBoxDipole_ = false;
751     if ( simParams_->haveAccumulateBoxDipole() )
752     if ( simParams_->getAccumulateBoxDipole() ) {
753     calcBoxDipole_ = true;
754     }
755    
756 gezelter 1528 set<AtomType*>::iterator i;
757     set<AtomType*> atomTypes;
758 gezelter 1534 atomTypes = getSimulatedAtomTypes();
759 gezelter 1528 int usesElectrostatic = 0;
760     int usesMetallic = 0;
761     int usesDirectional = 0;
762 gezelter 246 //loop over all of the atom types
763     for (i = atomTypes.begin(); i != atomTypes.end(); ++i) {
764 gezelter 1528 usesElectrostatic |= (*i)->isElectrostatic();
765     usesMetallic |= (*i)->isMetal();
766     usesDirectional |= (*i)->isDirectional();
767 gezelter 246 }
768 gezelter 2
769 gezelter 246 #ifdef IS_MPI
770     int temp;
771 gezelter 1528 temp = usesDirectional;
772     MPI_Allreduce(&temp, &usesDirectionalAtoms_, 1, MPI_INT, MPI_LOR, MPI_COMM_WORLD);
773 gezelter 2
774 gezelter 1528 temp = usesMetallic;
775     MPI_Allreduce(&temp, &usesMetallicAtoms_, 1, MPI_INT, MPI_LOR, MPI_COMM_WORLD);
776 gezelter 2
777 gezelter 1528 temp = usesElectrostatic;
778     MPI_Allreduce(&temp, &usesElectrostaticAtoms_, 1, MPI_INT, MPI_LOR, MPI_COMM_WORLD);
779 gezelter 2 #endif
780 gezelter 1528 fInfo_.SIM_uses_PBC = usesPeriodicBoundaries_;
781     fInfo_.SIM_uses_DirectionalAtoms = usesDirectionalAtoms_;
782     fInfo_.SIM_uses_MetallicAtoms = usesMetallicAtoms_;
783     fInfo_.SIM_requires_SkipCorrection = usesElectrostaticAtoms_;
784     fInfo_.SIM_requires_SelfCorrection = usesElectrostaticAtoms_;
785     fInfo_.SIM_uses_AtomicVirial = usesAtomicVirial_;
786 gezelter 507 }
787 gezelter 2
788 gezelter 1535 void SimInfo::setupFortran() {
789 gezelter 246 int isError;
790 gezelter 1287 int nExclude, nOneTwo, nOneThree, nOneFour;
791 gezelter 1528 vector<int> fortranGlobalGroupMembership;
792 gezelter 246
793     isError = 0;
794 gezelter 2
795 gezelter 246 //globalGroupMembership_ is filled by SimCreator
796     for (int i = 0; i < nGlobalAtoms_; i++) {
797 gezelter 507 fortranGlobalGroupMembership.push_back(globalGroupMembership_[i] + 1);
798 gezelter 246 }
799 gezelter 2
800 gezelter 246 //calculate mass ratio of cutoff group
801 gezelter 1528 vector<RealType> mfact;
802 gezelter 246 SimInfo::MoleculeIterator mi;
803     Molecule* mol;
804     Molecule::CutoffGroupIterator ci;
805     CutoffGroup* cg;
806     Molecule::AtomIterator ai;
807     Atom* atom;
808 tim 963 RealType totalMass;
809 gezelter 246
810     //to avoid memory reallocation, reserve enough space for mfact
811     mfact.reserve(getNCutoffGroups());
812 gezelter 2
813 gezelter 246 for(mol = beginMolecule(mi); mol != NULL; mol = nextMolecule(mi)) {
814 gezelter 507 for (cg = mol->beginCutoffGroup(ci); cg != NULL; cg = mol->nextCutoffGroup(ci)) {
815 gezelter 2
816 gezelter 507 totalMass = cg->getMass();
817     for(atom = cg->beginAtom(ai); atom != NULL; atom = cg->nextAtom(ai)) {
818 chrisfen 645 // Check for massless groups - set mfact to 1 if true
819     if (totalMass != 0)
820     mfact.push_back(atom->getMass()/totalMass);
821     else
822     mfact.push_back( 1.0 );
823 gezelter 507 }
824     }
825 gezelter 246 }
826 gezelter 2
827 gezelter 1544 // Build the identArray_
828 gezelter 2
829 gezelter 1544 identArray_.clear();
830     identArray_.reserve(getNAtoms());
831 gezelter 246 for(mol = beginMolecule(mi); mol != NULL; mol = nextMolecule(mi)) {
832 gezelter 507 for(atom = mol->beginAtom(ai); atom != NULL; atom = mol->nextAtom(ai)) {
833 gezelter 1544 identArray_.push_back(atom->getIdent());
834 gezelter 507 }
835 gezelter 246 }
836 gezelter 2
837 gezelter 246 //fill molMembershipArray
838     //molMembershipArray is filled by SimCreator
839 gezelter 1528 vector<int> molMembershipArray(nGlobalAtoms_);
840 gezelter 246 for (int i = 0; i < nGlobalAtoms_; i++) {
841 gezelter 507 molMembershipArray[i] = globalMolMembership_[i] + 1;
842 gezelter 246 }
843    
844     //setup fortran simulation
845 gezelter 1287
846     nExclude = excludedInteractions_.getSize();
847     nOneTwo = oneTwoInteractions_.getSize();
848     nOneThree = oneThreeInteractions_.getSize();
849     nOneFour = oneFourInteractions_.getSize();
850    
851     int* excludeList = excludedInteractions_.getPairList();
852     int* oneTwoList = oneTwoInteractions_.getPairList();
853     int* oneThreeList = oneThreeInteractions_.getPairList();
854     int* oneFourList = oneFourInteractions_.getPairList();
855    
856 gezelter 1241 setFortranSim( &fInfo_, &nGlobalAtoms_, &nAtoms_, &identArray[0],
857 gezelter 1287 &nExclude, excludeList,
858     &nOneTwo, oneTwoList,
859     &nOneThree, oneThreeList,
860     &nOneFour, oneFourList,
861 gezelter 1241 &molMembershipArray[0], &mfact[0], &nCutoffGroups_,
862     &fortranGlobalGroupMembership[0], &isError);
863    
864 gezelter 246 if( isError ){
865 gezelter 1241
866 gezelter 507 sprintf( painCave.errMsg,
867     "There was an error setting the simulation information in fortran.\n" );
868     painCave.isFatal = 1;
869 gezelter 1390 painCave.severity = OPENMD_ERROR;
870 gezelter 507 simError();
871 gezelter 246 }
872 gezelter 1241
873    
874 gezelter 246 sprintf( checkPointMsg,
875 gezelter 507 "succesfully sent the simulation information to fortran.\n");
876 gezelter 1241
877     errorCheckPoint();
878    
879 chuckv 1095 // Setup number of neighbors in neighbor list if present
880     if (simParams_->haveNeighborListNeighbors()) {
881 chuckv 1121 int nlistNeighbors = simParams_->getNeighborListNeighbors();
882     setNeighbors(&nlistNeighbors);
883 chuckv 1095 }
884    
885 gezelter 1241 #ifdef IS_MPI
886 gezelter 1535 //SimInfo is responsible for creating localToGlobalAtomIndex and
887     //localToGlobalGroupIndex
888 gezelter 1528 vector<int> localToGlobalAtomIndex(getNAtoms(), 0);
889     vector<int> localToGlobalCutoffGroupIndex;
890 gezelter 246 mpiSimData parallelData;
891 gezelter 2
892 gezelter 246 for (mol = beginMolecule(mi); mol != NULL; mol = nextMolecule(mi)) {
893 gezelter 2
894 gezelter 507 //local index(index in DataStorge) of atom is important
895     for (atom = mol->beginAtom(ai); atom != NULL; atom = mol->nextAtom(ai)) {
896     localToGlobalAtomIndex[atom->getLocalIndex()] = atom->getGlobalIndex() + 1;
897     }
898 gezelter 2
899 gezelter 507 //local index of cutoff group is trivial, it only depends on the order of travesing
900     for (cg = mol->beginCutoffGroup(ci); cg != NULL; cg = mol->nextCutoffGroup(ci)) {
901     localToGlobalCutoffGroupIndex.push_back(cg->getGlobalIndex() + 1);
902     }
903 gezelter 246
904     }
905 gezelter 2
906 gezelter 246 //fill up mpiSimData struct
907     parallelData.nMolGlobal = getNGlobalMolecules();
908     parallelData.nMolLocal = getNMolecules();
909     parallelData.nAtomsGlobal = getNGlobalAtoms();
910     parallelData.nAtomsLocal = getNAtoms();
911     parallelData.nGroupsGlobal = getNGlobalCutoffGroups();
912     parallelData.nGroupsLocal = getNCutoffGroups();
913     parallelData.myNode = worldRank;
914     MPI_Comm_size(MPI_COMM_WORLD, &(parallelData.nProcessors));
915 gezelter 2
916 gezelter 246 //pass mpiSimData struct and index arrays to fortran
917     setFsimParallel(&parallelData, &(parallelData.nAtomsLocal),
918     &localToGlobalAtomIndex[0], &(parallelData.nGroupsLocal),
919     &localToGlobalCutoffGroupIndex[0], &isError);
920 gezelter 2
921 gezelter 246 if (isError) {
922 gezelter 507 sprintf(painCave.errMsg,
923     "mpiRefresh errror: fortran didn't like something we gave it.\n");
924     painCave.isFatal = 1;
925     simError();
926 gezelter 246 }
927 gezelter 2
928 gezelter 246 sprintf(checkPointMsg, " mpiRefresh successful.\n");
929 gezelter 1241 errorCheckPoint();
930     #endif
931 gezelter 1536
932     initFortranFF(&isError);
933     if (isError) {
934     sprintf(painCave.errMsg,
935     "initFortranFF errror: fortran didn't like something we gave it.\n");
936     painCave.isFatal = 1;
937     simError();
938     }
939 gezelter 1535 fortranInitialized_ = true;
940 gezelter 507 }
941 chrisfen 143
942 gezelter 507 void SimInfo::addProperty(GenericData* genData) {
943 gezelter 246 properties_.addProperty(genData);
944 gezelter 507 }
945 gezelter 2
946 gezelter 1528 void SimInfo::removeProperty(const string& propName) {
947 gezelter 246 properties_.removeProperty(propName);
948 gezelter 507 }
949 gezelter 2
950 gezelter 507 void SimInfo::clearProperties() {
951 gezelter 246 properties_.clearProperties();
952 gezelter 507 }
953 gezelter 2
954 gezelter 1528 vector<string> SimInfo::getPropertyNames() {
955 gezelter 246 return properties_.getPropertyNames();
956 gezelter 507 }
957 gezelter 246
958 gezelter 1528 vector<GenericData*> SimInfo::getProperties() {
959 gezelter 246 return properties_.getProperties();
960 gezelter 507 }
961 gezelter 2
962 gezelter 1528 GenericData* SimInfo::getPropertyByName(const string& propName) {
963 gezelter 246 return properties_.getPropertyByName(propName);
964 gezelter 507 }
965 gezelter 2
966 gezelter 507 void SimInfo::setSnapshotManager(SnapshotManager* sman) {
967 tim 432 if (sman_ == sman) {
968 gezelter 507 return;
969 tim 432 }
970     delete sman_;
971 gezelter 246 sman_ = sman;
972 gezelter 2
973 gezelter 246 Molecule* mol;
974     RigidBody* rb;
975     Atom* atom;
976 gezelter 1540 CutoffGroup* cg;
977 gezelter 246 SimInfo::MoleculeIterator mi;
978     Molecule::RigidBodyIterator rbIter;
979 gezelter 1540 Molecule::AtomIterator atomIter;
980     Molecule::CutoffGroupIterator cgIter;
981 gezelter 246
982     for (mol = beginMolecule(mi); mol != NULL; mol = nextMolecule(mi)) {
983    
984 gezelter 507 for (atom = mol->beginAtom(atomIter); atom != NULL; atom = mol->nextAtom(atomIter)) {
985     atom->setSnapshotManager(sman_);
986     }
987 gezelter 246
988 gezelter 507 for (rb = mol->beginRigidBody(rbIter); rb != NULL; rb = mol->nextRigidBody(rbIter)) {
989     rb->setSnapshotManager(sman_);
990     }
991 gezelter 1540
992     for (cg = mol->beginCutoffGroup(cgIter); cg != NULL; cg = mol->nextCutoffGroup(cgIter)) {
993     cg->setSnapshotManager(sman_);
994     }
995 gezelter 246 }
996 gezelter 2
997 gezelter 507 }
998 gezelter 2
999 gezelter 507 Vector3d SimInfo::getComVel(){
1000 gezelter 246 SimInfo::MoleculeIterator i;
1001     Molecule* mol;
1002 gezelter 2
1003 gezelter 246 Vector3d comVel(0.0);
1004 tim 963 RealType totalMass = 0.0;
1005 gezelter 2
1006 gezelter 246
1007     for (mol = beginMolecule(i); mol != NULL; mol = nextMolecule(i)) {
1008 tim 963 RealType mass = mol->getMass();
1009 gezelter 507 totalMass += mass;
1010     comVel += mass * mol->getComVel();
1011 gezelter 246 }
1012 gezelter 2
1013 gezelter 246 #ifdef IS_MPI
1014 tim 963 RealType tmpMass = totalMass;
1015 gezelter 246 Vector3d tmpComVel(comVel);
1016 tim 963 MPI_Allreduce(&tmpMass,&totalMass,1,MPI_REALTYPE,MPI_SUM, MPI_COMM_WORLD);
1017     MPI_Allreduce(tmpComVel.getArrayPointer(), comVel.getArrayPointer(),3,MPI_REALTYPE,MPI_SUM, MPI_COMM_WORLD);
1018 gezelter 246 #endif
1019    
1020     comVel /= totalMass;
1021    
1022     return comVel;
1023 gezelter 507 }
1024 gezelter 2
1025 gezelter 507 Vector3d SimInfo::getCom(){
1026 gezelter 246 SimInfo::MoleculeIterator i;
1027     Molecule* mol;
1028 gezelter 2
1029 gezelter 246 Vector3d com(0.0);
1030 tim 963 RealType totalMass = 0.0;
1031 gezelter 246
1032     for (mol = beginMolecule(i); mol != NULL; mol = nextMolecule(i)) {
1033 tim 963 RealType mass = mol->getMass();
1034 gezelter 507 totalMass += mass;
1035     com += mass * mol->getCom();
1036 gezelter 246 }
1037 gezelter 2
1038     #ifdef IS_MPI
1039 tim 963 RealType tmpMass = totalMass;
1040 gezelter 246 Vector3d tmpCom(com);
1041 tim 963 MPI_Allreduce(&tmpMass,&totalMass,1,MPI_REALTYPE,MPI_SUM, MPI_COMM_WORLD);
1042     MPI_Allreduce(tmpCom.getArrayPointer(), com.getArrayPointer(),3,MPI_REALTYPE,MPI_SUM, MPI_COMM_WORLD);
1043 gezelter 2 #endif
1044    
1045 gezelter 246 com /= totalMass;
1046 gezelter 2
1047 gezelter 246 return com;
1048 gezelter 2
1049 gezelter 507 }
1050 gezelter 246
1051 gezelter 1528 ostream& operator <<(ostream& o, SimInfo& info) {
1052 gezelter 246
1053     return o;
1054 gezelter 507 }
1055 chuckv 555
1056    
1057     /*
1058     Returns center of mass and center of mass velocity in one function call.
1059     */
1060    
1061     void SimInfo::getComAll(Vector3d &com, Vector3d &comVel){
1062     SimInfo::MoleculeIterator i;
1063     Molecule* mol;
1064    
1065    
1066 tim 963 RealType totalMass = 0.0;
1067 chuckv 555
1068 gezelter 246
1069 chuckv 555 for (mol = beginMolecule(i); mol != NULL; mol = nextMolecule(i)) {
1070 tim 963 RealType mass = mol->getMass();
1071 chuckv 555 totalMass += mass;
1072     com += mass * mol->getCom();
1073     comVel += mass * mol->getComVel();
1074     }
1075    
1076     #ifdef IS_MPI
1077 tim 963 RealType tmpMass = totalMass;
1078 chuckv 555 Vector3d tmpCom(com);
1079     Vector3d tmpComVel(comVel);
1080 tim 963 MPI_Allreduce(&tmpMass,&totalMass,1,MPI_REALTYPE,MPI_SUM, MPI_COMM_WORLD);
1081     MPI_Allreduce(tmpCom.getArrayPointer(), com.getArrayPointer(),3,MPI_REALTYPE,MPI_SUM, MPI_COMM_WORLD);
1082     MPI_Allreduce(tmpComVel.getArrayPointer(), comVel.getArrayPointer(),3,MPI_REALTYPE,MPI_SUM, MPI_COMM_WORLD);
1083 chuckv 555 #endif
1084    
1085     com /= totalMass;
1086     comVel /= totalMass;
1087     }
1088    
1089     /*
1090     Return intertia tensor for entire system and angular momentum Vector.
1091 chuckv 557
1092    
1093     [ Ixx -Ixy -Ixz ]
1094 gezelter 1505 J =| -Iyx Iyy -Iyz |
1095 chuckv 557 [ -Izx -Iyz Izz ]
1096 chuckv 555 */
1097    
1098     void SimInfo::getInertiaTensor(Mat3x3d &inertiaTensor, Vector3d &angularMomentum){
1099    
1100    
1101 tim 963 RealType xx = 0.0;
1102     RealType yy = 0.0;
1103     RealType zz = 0.0;
1104     RealType xy = 0.0;
1105     RealType xz = 0.0;
1106     RealType yz = 0.0;
1107 chuckv 555 Vector3d com(0.0);
1108     Vector3d comVel(0.0);
1109    
1110     getComAll(com, comVel);
1111    
1112     SimInfo::MoleculeIterator i;
1113     Molecule* mol;
1114    
1115     Vector3d thisq(0.0);
1116     Vector3d thisv(0.0);
1117    
1118 tim 963 RealType thisMass = 0.0;
1119 chuckv 555
1120    
1121    
1122    
1123     for (mol = beginMolecule(i); mol != NULL; mol = nextMolecule(i)) {
1124    
1125     thisq = mol->getCom()-com;
1126     thisv = mol->getComVel()-comVel;
1127     thisMass = mol->getMass();
1128     // Compute moment of intertia coefficients.
1129     xx += thisq[0]*thisq[0]*thisMass;
1130     yy += thisq[1]*thisq[1]*thisMass;
1131     zz += thisq[2]*thisq[2]*thisMass;
1132    
1133     // compute products of intertia
1134     xy += thisq[0]*thisq[1]*thisMass;
1135     xz += thisq[0]*thisq[2]*thisMass;
1136     yz += thisq[1]*thisq[2]*thisMass;
1137    
1138     angularMomentum += cross( thisq, thisv ) * thisMass;
1139    
1140     }
1141    
1142    
1143     inertiaTensor(0,0) = yy + zz;
1144     inertiaTensor(0,1) = -xy;
1145     inertiaTensor(0,2) = -xz;
1146     inertiaTensor(1,0) = -xy;
1147 chuckv 557 inertiaTensor(1,1) = xx + zz;
1148 chuckv 555 inertiaTensor(1,2) = -yz;
1149     inertiaTensor(2,0) = -xz;
1150     inertiaTensor(2,1) = -yz;
1151     inertiaTensor(2,2) = xx + yy;
1152    
1153     #ifdef IS_MPI
1154     Mat3x3d tmpI(inertiaTensor);
1155     Vector3d tmpAngMom;
1156 tim 963 MPI_Allreduce(tmpI.getArrayPointer(), inertiaTensor.getArrayPointer(),9,MPI_REALTYPE,MPI_SUM, MPI_COMM_WORLD);
1157     MPI_Allreduce(tmpAngMom.getArrayPointer(), angularMomentum.getArrayPointer(),3,MPI_REALTYPE,MPI_SUM, MPI_COMM_WORLD);
1158 chuckv 555 #endif
1159    
1160     return;
1161     }
1162    
1163     //Returns the angular momentum of the system
1164     Vector3d SimInfo::getAngularMomentum(){
1165    
1166     Vector3d com(0.0);
1167     Vector3d comVel(0.0);
1168     Vector3d angularMomentum(0.0);
1169    
1170     getComAll(com,comVel);
1171    
1172     SimInfo::MoleculeIterator i;
1173     Molecule* mol;
1174    
1175 chuckv 557 Vector3d thisr(0.0);
1176     Vector3d thisp(0.0);
1177 chuckv 555
1178 tim 963 RealType thisMass;
1179 chuckv 555
1180     for (mol = beginMolecule(i); mol != NULL; mol = nextMolecule(i)) {
1181 chuckv 557 thisMass = mol->getMass();
1182     thisr = mol->getCom()-com;
1183     thisp = (mol->getComVel()-comVel)*thisMass;
1184 chuckv 555
1185 chuckv 557 angularMomentum += cross( thisr, thisp );
1186    
1187 chuckv 555 }
1188    
1189     #ifdef IS_MPI
1190     Vector3d tmpAngMom;
1191 tim 963 MPI_Allreduce(tmpAngMom.getArrayPointer(), angularMomentum.getArrayPointer(),3,MPI_REALTYPE,MPI_SUM, MPI_COMM_WORLD);
1192 chuckv 555 #endif
1193    
1194     return angularMomentum;
1195     }
1196    
1197 tim 1024 StuntDouble* SimInfo::getIOIndexToIntegrableObject(int index) {
1198     return IOIndexToIntegrableObject.at(index);
1199     }
1200    
1201 gezelter 1528 void SimInfo::setIOIndexToIntegrableObject(const vector<StuntDouble*>& v) {
1202 tim 1024 IOIndexToIntegrableObject= v;
1203     }
1204    
1205 chuckv 1103 /* Returns the Volume of the simulation based on a ellipsoid with semi-axes
1206     based on the radius of gyration V=4/3*Pi*R_1*R_2*R_3
1207     where R_i are related to the principle inertia moments R_i = sqrt(C*I_i/N), this reduces to
1208     V = 4/3*Pi*(C/N)^3/2*sqrt(det(I)). See S.E. Baltazar et. al. Comp. Mat. Sci. 37 (2006) 526-536.
1209     */
1210     void SimInfo::getGyrationalVolume(RealType &volume){
1211     Mat3x3d intTensor;
1212     RealType det;
1213     Vector3d dummyAngMom;
1214     RealType sysconstants;
1215     RealType geomCnst;
1216    
1217     geomCnst = 3.0/2.0;
1218     /* Get the inertial tensor and angular momentum for free*/
1219     getInertiaTensor(intTensor,dummyAngMom);
1220    
1221     det = intTensor.determinant();
1222     sysconstants = geomCnst/(RealType)nGlobalIntegrableObjects_;
1223     volume = 4.0/3.0*NumericConstant::PI*pow(sysconstants,3.0/2.0)*sqrt(det);
1224     return;
1225     }
1226    
1227     void SimInfo::getGyrationalVolume(RealType &volume, RealType &detI){
1228     Mat3x3d intTensor;
1229     Vector3d dummyAngMom;
1230     RealType sysconstants;
1231     RealType geomCnst;
1232    
1233     geomCnst = 3.0/2.0;
1234     /* Get the inertial tensor and angular momentum for free*/
1235     getInertiaTensor(intTensor,dummyAngMom);
1236    
1237     detI = intTensor.determinant();
1238     sysconstants = geomCnst/(RealType)nGlobalIntegrableObjects_;
1239     volume = 4.0/3.0*NumericConstant::PI*pow(sysconstants,3.0/2.0)*sqrt(detI);
1240     return;
1241     }
1242 tim 1024 /*
1243 gezelter 1528 void SimInfo::setStuntDoubleFromGlobalIndex(vector<StuntDouble*> v) {
1244 tim 1024 assert( v.size() == nAtoms_ + nRigidBodies_);
1245     sdByGlobalIndex_ = v;
1246     }
1247    
1248     StuntDouble* SimInfo::getStuntDoubleFromGlobalIndex(int index) {
1249     //assert(index < nAtoms_ + nRigidBodies_);
1250     return sdByGlobalIndex_.at(index);
1251     }
1252     */
1253 gezelter 1528 int SimInfo::getNGlobalConstraints() {
1254     int nGlobalConstraints;
1255     #ifdef IS_MPI
1256     MPI_Allreduce(&nConstraints_, &nGlobalConstraints, 1, MPI_INT, MPI_SUM,
1257     MPI_COMM_WORLD);
1258     #else
1259     nGlobalConstraints = nConstraints_;
1260     #endif
1261     return nGlobalConstraints;
1262     }
1263    
1264 gezelter 1390 }//end namespace OpenMD
1265 gezelter 246

Properties

Name Value
svn:keywords Author Id Revision Date