ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/branches/new_design/OOPSE-2.0/src/brains/SimInfo.cpp
(Generate patch)

Comparing:
trunk/OOPSE-2.0/src/brains/SimInfo.cpp (file contents), Revision 1490 by gezelter, Fri Sep 24 04:16:43 2004 UTC vs.
branches/new_design/OOPSE-2.0/src/brains/SimInfo.cpp (file contents), Revision 1733 by tim, Fri Nov 12 06:19:04 2004 UTC

# Line 1 | Line 1
1 < #include <stdlib.h>
2 < #include <string.h>
3 < #include <math.h>
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 < #include <iostream>
27 < using namespace std;
26 > /**
27 > * @file SimInfo.cpp
28 > * @author    tlin
29 > * @date  11/02/2004
30 > * @version 1.0
31 > */
32  
33 < #include "SimInfo.hpp"
9 < #define __C
10 < #include "fSimulation.h"
11 < #include "simError.h"
33 > #include <algorithm>
34  
35 < #include "fortranWrappers.hpp"
35 > #include "brains/SimInfo.hpp"
36 > #include "utils/MemoryUtils.hpp"
37  
38 < #include "MatVec3.h"
38 > namespace oopse {
39  
40 < #ifdef IS_MPI
41 < #include "mpiSimulation.hpp"
42 < #endif
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  
46 < inline double roundMe( double x ){
47 <  return ( x >= 0 ) ? floor( x + 0.5 ) : ceil( x - 0.5 );
48 < }
49 <          
50 < inline double min( double a, double b ){
51 <  return (a < b ) ? a : b;
52 < }
46 >    std::vector<std::pair<MoleculeStamp*, int> >::iterator i;
47 >    int nCutoffAtoms; // number of atoms belong to cutoff groups
48 >    int ngroups;          //total cutoff groups defined in meta-data file
49 >    MoleculeStamp* molStamp;
50 >    int nMolWithSameStamp;
51 >    CutoffGroupStamp* cgStamp;
52 >    int nAtomsIngroups;
53 >    int nCutoffGroupsInStamp;    
54  
55 < SimInfo* currentInfo;
55 >    nGlobalAtoms_ =  0;
56 >    ngroups = 0;
57 >    
58 >    for (i = molStampPairs.begin(); i !=molStampPairs.end(); ++i) {
59 >        molStamp = i->first;
60 >        nMolWithSameStamp = i->second;
61 >        
62 >        addMoleculeStamp(molStamp, nMolWithSameStamp);
63 >        
64 >        nGlobalAtoms_ += molStamp->getNAtoms() *nMolWithSameStamp;  
65 >        
66 >        nAtomsIngroups = 0;
67 >        nCutoffGroupsInStamp = molStamp->getNCutoffGroups();
68 >        
69 >        for (int j=0; j < nCutoffGroupsInStamp; j++) {
70 >            cgStamp = molStamp->getCutoffGroup(j);
71 >            nAtomsIngroups += cgStamp->getNMembers();
72 >        }
73  
74 < SimInfo::SimInfo(){
74 >        ngroups += *nMolWithSameStamp;
75 >        nCutoffAtoms += nAtomsIngroups * nMolWithSameStamp;                
76 >    }
77  
78 <  n_constraints = 0;
79 <  nZconstraints = 0;
80 <  n_oriented = 0;
81 <  n_dipoles = 0;
82 <  ndf = 0;
38 <  ndfRaw = 0;
39 <  nZconstraints = 0;
40 <  the_integrator = NULL;
41 <  setTemp = 0;
42 <  thermalTime = 0.0;
43 <  currentTime = 0.0;
44 <  rCut = 0.0;
45 <  rSw = 0.0;
78 >    //every free atom (atom does not belong to cutoff groups) is a cutoff group
79 >    //therefore the total number of cutoff groups in the system is equal to
80 >    //the total number of atoms minus number of atoms belong to cutoff group defined in meta-data
81 >    //file plus the number of cutoff groups defined in meta-data file
82 >    nGlobalCutoffGroups_ = nGlobalAtoms_ - nCutoffAtoms + ngroups;
83  
84 <  haveRcut = 0;
85 <  haveRsw = 0;
49 <  boxIsInit = 0;
50 <  
51 <  resetTime = 1e99;
84 >    //initialize globalGroupMembership_, every element of this array will be 0
85 >    globalGroupMembership_.insert(globalGroupMembership_.end(), nGlobalAtoms_, 0);
86  
87 <  orthoRhombic = 0;
54 <  orthoTolerance = 1E-6;
55 <  useInitXSstate = true;
87 >    nGlobalMols_ = molStampIds_.size();
88  
89 <  usePBC = 0;
90 <  useLJ = 0;
91 <  useSticky = 0;
92 <  useCharges = 0;
93 <  useDipoles = 0;
62 <  useReactionField = 0;
63 <  useGB = 0;
64 <  useEAM = 0;
65 <  useSolidThermInt = 0;
66 <  useLiquidThermInt = 0;
89 > #ifdef IS_MPI    
90 >    molToProcMap_.resize(nGlobalMols_);
91 > #endif
92 >    
93 > }
94  
95 <  haveCutoffGroups = false;
95 > SimInfo::~SimInfo() {
96 >    //MemoryUtils::deleteVectorOfPointer(molecules_);
97  
98 <  excludes = Exclude::Instance();
98 >    MemoryUtils::deleteVectorOfPointer(moleculeStamps_);
99 >    
100 >    delete sman_;
101 >    delete globals_;
102 >    delete forceField_;
103  
104 <  myConfiguration = new SimState();
104 > }
105  
74  has_minimizer = false;
75  the_minimizer =NULL;
106  
107 <  ngroup = 0;
107 > bool SimInfo::addMolecule(Molecule* mol) {
108 >    MoleculeIterator i;
109  
110 <  wrapMeSimInfo( this );
111 < }
110 >    i = molecules_.find(mol->getGlobalIndex());
111 >    if (i != molecules_.end() ) {
112  
113 +        molecules_.insert(make_pair(mol->getGlobalIndex(), mol));
114 +        
115 +        nAtoms_ += mol->getNAtoms();
116 +        nBonds_ += mol->getNBonds();
117 +        nBends_ += mol->getNBends();
118 +        nTorsions_ += mol->getNTorsions();
119 +        nRigidBodies_ += mol->getNRigidBodies();
120 +        nIntegrableObjects_ += mol->getNIntegrableObjects();
121 +        nCutoffGroups_ += mol->getNCutoffGroups();
122 +        nConstraints_ += mol->getNConstraints();
123  
124 < SimInfo::~SimInfo(){
124 >        return true;
125 >    } else {
126 >        return false;
127 >    }
128 > }
129  
130 <  delete myConfiguration;
130 > bool SimInfo::removeMolecule(Molecule* mol) {
131 >    MoleculeIterator i;
132 >    i = molecules_.find(mol->getGlobalIndex());
133  
134 <  map<string, GenericData*>::iterator i;
88 <  
89 <  for(i = properties.begin(); i != properties.end(); i++)
90 <    delete (*i).second;
134 >    if (i != molecules_.end() ) {
135  
136 < }
136 >        assert(mol == i->second);
137 >        
138 >        nAtoms_ -= mol->getNAtoms();
139 >        nBonds_ -= mol->getNBonds();
140 >        nBends_ -= mol->getNBends();
141 >        nTorsions_ -= mol->getNTorsions();
142 >        nRigidBodies_ -= mol->getNRigidBodies();
143 >        nIntegrableObjects_ -= mol->getNIntegrableObjects();
144 >        nCutoffGroups_ -= mol->getNCutoffGroups();
145 >        nConstraints_ -= mol->getNConstraints();
146  
147 < void SimInfo::setBox(double newBox[3]) {
95 <  
96 <  int i, j;
97 <  double tempMat[3][3];
147 >        molecules_.erase(mol->getGlobalIndex());
148  
149 <  for(i=0; i<3; i++)
150 <    for (j=0; j<3; j++) tempMat[i][j] = 0.0;;
149 >        delete mol;
150 >        
151 >        return true;
152 >    } else {
153 >        return false;
154 >    }
155  
102  tempMat[0][0] = newBox[0];
103  tempMat[1][1] = newBox[1];
104  tempMat[2][2] = newBox[2];
156  
157 <  setBoxM( tempMat );
157 > }    
158  
159 +        
160 + Molecule* SimInfo::beginMolecule(MoleculeIterator& i) {
161 +    i = molecules_.begin();
162 +    return i == molecules_.end() ? NULL : *i;
163 + }    
164 +
165 + Molecule* SimInfo::nextMolecule(MoleculeIterator& i) {
166 +    ++i;
167 +    return i == molecules_.end() ? NULL : *i;    
168   }
169  
110 void SimInfo::setBoxM( double theBox[3][3] ){
111  
112  int i, j;
113  double FortranHmat[9]; // to preserve compatibility with Fortran the
114                         // ordering in the array is as follows:
115                         // [ 0 3 6 ]
116                         // [ 1 4 7 ]
117                         // [ 2 5 8 ]
118  double FortranHmatInv[9]; // the inverted Hmat (for Fortran);
170  
171 <  if( !boxIsInit ) boxIsInit = 1;
171 > void SimInfo::calcNdf() {
172 >    int ndf_local;
173 >    MoleculeIterator i;
174 >    std::vector<StuntDouble*>::iterator j;
175 >    Molecule* mol;
176 >    StuntDouble* integrableObject;
177  
178 <  for(i=0; i < 3; i++)
179 <    for (j=0; j < 3; j++) Hmat[i][j] = theBox[i][j];
180 <  
181 <  calcBoxL();
182 <  calcHmatInv();
178 >    ndf_local = 0;
179 >    
180 >    for (mol = beginMolecule(i); mol != NULL; mol = nextMolecule(i)) {
181 >        for (integrableObject = mol->beginIntegrableObject(j); integrableObject != NULL;
182 >               integrableObject = mol->nextIntegrableObject(j)) {
183  
184 <  for(i=0; i < 3; i++) {
129 <    for (j=0; j < 3; j++) {
130 <      FortranHmat[3*j + i] = Hmat[i][j];
131 <      FortranHmatInv[3*j + i] = HmatInv[i][j];
132 <    }
133 <  }
184 >            ndf_local += 3;
185  
186 <  setFortranBoxSize(FortranHmat, FortranHmatInv, &orthoRhombic);
187 <
188 < }
189 <
186 >            if (integrableObject->isDirectional()) {
187 >                if (integrableObject->isLinear()) {
188 >                    ndf_local += 2;
189 >                } else {
190 >                    ndf_local += 3;
191 >                }
192 >            }
193 >            
194 >        }//end for (integrableObject)
195 >    }// end for (mol)
196 >    
197 >    // n_constraints is local, so subtract them on each processor
198 >    ndf_local -= nConstraints_;
199  
200 < void SimInfo::getBoxM (double theBox[3][3]) {
200 > #ifdef IS_MPI
201 >    MPI_Allreduce(&ndf_local,&ndf_,1,MPI_INT,MPI_SUM, MPI_COMM_WORLD);
202 > #else
203 >    ndf_ = ndf_local;
204 > #endif
205  
206 <  int i, j;
207 <  for(i=0; i<3; i++)
208 <    for (j=0; j<3; j++) theBox[i][j] = Hmat[i][j];
206 >    // nZconstraints_ is global, as are the 3 COM translations for the
207 >    // entire system:
208 >    ndf_ = ndf_ - 3 - nZconstraints_;
209 >
210   }
211  
212 + void SimInfo::calcNdfRaw() {
213 +    int ndfRaw_local;
214  
215 < void SimInfo::scaleBox(double scale) {
216 <  double theBox[3][3];
217 <  int i, j;
215 >    MoleculeIterator i;
216 >    std::vector<StuntDouble*>::iterator j;
217 >    Molecule* mol;
218 >    StuntDouble* integrableObject;
219  
220 <  // cerr << "Scaling box by " << scale << "\n";
220 >    // Raw degrees of freedom that we have to set
221 >    ndfRaw_local = 0;
222 >    
223 >    for (mol = beginMolecule(i); mol != NULL; mol = nextMolecule(i)) {
224 >        for (integrableObject = mol->beginIntegrableObject(j); integrableObject != NULL;
225 >               integrableObject = mol->nextIntegrableObject(j)) {
226  
227 <  for(i=0; i<3; i++)
155 <    for (j=0; j<3; j++) theBox[i][j] = Hmat[i][j]*scale;
227 >            ndfRaw_local += 3;
228  
229 <  setBoxM(theBox);
230 <
229 >            if (integrableObject->isDirectional()) {
230 >                if (integrableObject->isLinear()) {
231 >                    ndfRaw_local += 2;
232 >                } else {
233 >                    ndfRaw_local += 3;
234 >                }
235 >            }
236 >            
237 >        }
238 >    }
239 >    
240 > #ifdef IS_MPI
241 >    MPI_Allreduce(&ndfRaw_local,&ndfRaw_,1,MPI_INT,MPI_SUM, MPI_COMM_WORLD);
242 > #else
243 >    ndfRaw_ = ndfRaw_local;
244 > #endif
245   }
246  
247 < void SimInfo::calcHmatInv( void ) {
248 <  
163 <  int oldOrtho;
164 <  int i,j;
165 <  double smallDiag;
166 <  double tol;
167 <  double sanity[3][3];
247 > void SimInfo::calcNdfTrans() {
248 >    int ndfTrans_local;
249  
250 <  invertMat3( Hmat, HmatInv );
250 >    ndfTrans_local = 3 * nIntegrableObjects_ - nConstraints_;
251  
171  // check to see if Hmat is orthorhombic
172  
173  oldOrtho = orthoRhombic;
252  
253 <  smallDiag = fabs(Hmat[0][0]);
254 <  if(smallDiag > fabs(Hmat[1][1])) smallDiag = fabs(Hmat[1][1]);
255 <  if(smallDiag > fabs(Hmat[2][2])) smallDiag = fabs(Hmat[2][2]);
256 <  tol = smallDiag * orthoTolerance;
253 > #ifdef IS_MPI
254 >    MPI_Allreduce(&ndfTrans_local,&ndfTrans_,1,MPI_INT,MPI_SUM, MPI_COMM_WORLD);
255 > #else
256 >    ndfTrans_ = ndfTrans_local;
257 > #endif
258  
259 <  orthoRhombic = 1;
260 <  
261 <  for (i = 0; i < 3; i++ ) {
183 <    for (j = 0 ; j < 3; j++) {
184 <      if (i != j) {
185 <        if (orthoRhombic) {
186 <          if ( fabs(Hmat[i][j]) >= tol) orthoRhombic = 0;
187 <        }        
188 <      }
189 <    }
190 <  }
259 >    ndfTrans_ = ndfTrans_ - 3 - nZconstraints_;
260 >
261 > }
262  
263 <  if( oldOrtho != orthoRhombic ){
263 > void SimInfo::addExcludePairs(Molecule* mol) {
264 >    std::vector<Bond*>::iterator bondIter;
265 >    std::vector<Bend*>::iterator bendIter;
266 >    std::vector<Torsion*>::iterator torsionIter;
267 >    Bond* bond;
268 >    Bend* bend;
269 >    Torsion* torsion;
270 >    int a;
271 >    int b;
272 >    int c;
273 >    int d;
274      
275 <    if( orthoRhombic ) {
276 <      sprintf( painCave.errMsg,
277 <               "OOPSE is switching from the default Non-Orthorhombic\n"
278 <               "\tto the faster Orthorhombic periodic boundary computations.\n"
198 <               "\tThis is usually a good thing, but if you wan't the\n"
199 <               "\tNon-Orthorhombic computations, make the orthoBoxTolerance\n"
200 <               "\tvariable ( currently set to %G ) smaller.\n",
201 <               orthoTolerance);
202 <      painCave.severity = OOPSE_INFO;
203 <      simError();
275 >    for (bond= mol->beginBond(bondIter); bond != NULL; bond = mol->nextBond(bondIter)) {
276 >        a = bond->getAtomA()->getGlobalIndex();
277 >        b = bond->getAtomB()->getGlobalIndex();        
278 >        exclude_.addPair(a, b);
279      }
205    else {
206      sprintf( painCave.errMsg,
207               "OOPSE is switching from the faster Orthorhombic to the more\n"
208               "\tflexible Non-Orthorhombic periodic boundary computations.\n"
209               "\tThis is usually because the box has deformed under\n"
210               "\tNPTf integration. If you wan't to live on the edge with\n"
211               "\tthe Orthorhombic computations, make the orthoBoxTolerance\n"
212               "\tvariable ( currently set to %G ) larger.\n",
213               orthoTolerance);
214      painCave.severity = OOPSE_WARNING;
215      simError();
216    }
217  }
218 }
280  
281 < void SimInfo::calcBoxL( void ){
281 >    for (bend= mol->beginBend(bendIter); bend != NULL; bend = mol->nextBend(bendIter)) {
282 >        a = bend->getAtomA()->getGlobalIndex();
283 >        b = bend->getAtomB()->getGlobalIndex();        
284 >        c = bend->getAtomC()->getGlobalIndex();
285  
286 <  double dx, dy, dz, dsq;
286 >        exclude_.addPair(a, b);
287 >        exclude_.addPair(a, c);
288 >        exclude_.addPair(b, c);        
289 >    }
290  
291 <  // boxVol = Determinant of Hmat
291 >    for (torsion= mol->beginTorsion(torsionIter); torsion != NULL; torsion = mol->nextBond(torsionIter)) {
292 >        a = torsion->getAtomA()->getGlobalIndex();
293 >        b = torsion->getAtomB()->getGlobalIndex();        
294 >        c = torsion->getAtomC()->getGlobalIndex();        
295 >        d = torsion->getAtomD()->getGlobalIndex();        
296  
297 <  boxVol = matDet3( Hmat );
297 >        exclude_.addPair(a, b);
298 >        exclude_.addPair(a, c);
299 >        exclude_.addPair(a, d);
300 >        exclude_.addPair(b, c);
301 >        exclude_.addPair(b, d);
302 >        exclude_.addPair(c, d);        
303 >    }
304  
305 <  // boxLx
306 <  
230 <  dx = Hmat[0][0]; dy = Hmat[1][0]; dz = Hmat[2][0];
231 <  dsq = dx*dx + dy*dy + dz*dz;
232 <  boxL[0] = sqrt( dsq );
233 <  //maxCutoff = 0.5 * boxL[0];
305 >    
306 > }
307  
308 <  // boxLy
309 <  
310 <  dx = Hmat[0][1]; dy = Hmat[1][1]; dz = Hmat[2][1];
311 <  dsq = dx*dx + dy*dy + dz*dz;
312 <  boxL[1] = sqrt( dsq );
313 <  //if( (0.5 * boxL[1]) < maxCutoff ) maxCutoff = 0.5 * boxL[1];
308 > void SimInfo::removeExcludePairs(Molecule* mol) {
309 >    std::vector<Bond*>::iterator bondIter;
310 >    std::vector<Bend*>::iterator bendIter;
311 >    std::vector<Torsion*>::iterator torsionIter;
312 >    Bond* bond;
313 >    Bend* bend;
314 >    Torsion* torsion;
315 >    int a;
316 >    int b;
317 >    int c;
318 >    int d;
319 >    
320 >    for (bond= mol->beginBond(bondIter); bond != NULL; bond = mol->nextBond(bondIter)) {
321 >        a = bond->getAtomA()->getGlobalIndex();
322 >        b = bond->getAtomB()->getGlobalIndex();        
323 >        exclude_.removePair(a, b);
324 >    }
325  
326 +    for (bend= mol->beginBend(bendIter); bend != NULL; bend = mol->nextBend(bendIter)) {
327 +        a = bend->getAtomA()->getGlobalIndex();
328 +        b = bend->getAtomB()->getGlobalIndex();        
329 +        c = bend->getAtomC()->getGlobalIndex();
330  
331 <  // boxLz
332 <  
333 <  dx = Hmat[0][2]; dy = Hmat[1][2]; dz = Hmat[2][2];
334 <  dsq = dx*dx + dy*dy + dz*dz;
247 <  boxL[2] = sqrt( dsq );
248 <  //if( (0.5 * boxL[2]) < maxCutoff ) maxCutoff = 0.5 * boxL[2];
331 >        exclude_.removePair(a, b);
332 >        exclude_.removePair(a, c);
333 >        exclude_.removePair(b, c);        
334 >    }
335  
336 <  //calculate the max cutoff
337 <  maxCutoff =  calcMaxCutOff();
338 <  
339 <  checkCutOffs();
336 >    for (torsion= mol->beginTorsion(torsionIter); torsion != NULL; torsion = mol->nextBond(torsionIter)) {
337 >        a = torsion->getAtomA()->getGlobalIndex();
338 >        b = torsion->getAtomB()->getGlobalIndex();        
339 >        c = torsion->getAtomC()->getGlobalIndex();        
340 >        d = torsion->getAtomD()->getGlobalIndex();        
341  
342 +        exclude_.removePair(a, b);
343 +        exclude_.removePair(a, c);
344 +        exclude_.removePair(a, d);
345 +        exclude_.removePair(b, c);
346 +        exclude_.removePair(b, d);
347 +        exclude_.removePair(c, d);        
348 +    }
349 +
350   }
351  
352  
353 < double SimInfo::calcMaxCutOff(){
353 > void SimInfo::addMoleculeStamp(MoleculeStamp* molStamp, int nmol) {
354 >    int curStampId;
355  
356 <  double ri[3], rj[3], rk[3];
357 <  double rij[3], rjk[3], rki[3];
262 <  double minDist;
356 >    //index from 0
357 >    curStampId = molStampIds_.size();
358  
359 <  ri[0] = Hmat[0][0];
360 <  ri[1] = Hmat[1][0];
361 <  ri[2] = Hmat[2][0];
359 >    moleculeStamps_.push_back(molStamp);
360 >    molStampIds_.insert(molStampIds_.end(), nmol, curStampId)
361 > }
362  
363 <  rj[0] = Hmat[0][1];
269 <  rj[1] = Hmat[1][1];
270 <  rj[2] = Hmat[2][1];
363 > void SimInfo::update() {
364  
365 <  rk[0] = Hmat[0][2];
366 <  rk[1] = Hmat[1][2];
367 <  rk[2] = Hmat[2][2];
275 <    
276 <  crossProduct3(ri, rj, rij);
277 <  distXY = dotProduct3(rk,rij) / norm3(rij);
365 > #ifdef IS_MPI
366 >    setupFortranParallel();
367 > #endif
368  
369 <  crossProduct3(rj,rk, rjk);
280 <  distYZ = dotProduct3(ri,rjk) / norm3(rjk);
369 >    setupFortranSim();
370  
371 <  crossProduct3(rk,ri, rki);
372 <  distZX = dotProduct3(rj,rki) / norm3(rki);
373 <
285 <  minDist = min(min(distXY, distYZ), distZX);
286 <  return minDist/2;
287 <  
371 >    calcNdf();
372 >    calcNdfRaw();
373 >    calcNdfTrans();
374   }
375  
376 < void SimInfo::wrapVector( double thePos[3] ){
377 <
378 <  int i;
379 <  double scaled[3];
380 <
381 <  if( !orthoRhombic ){
382 <    // calc the scaled coordinates.
383 <  
384 <
385 <    matVecMul3(HmatInv, thePos, scaled);
386 <    
387 <    for(i=0; i<3; i++)
388 <      scaled[i] -= roundMe(scaled[i]);
389 <    
390 <    // calc the wrapped real coordinates from the wrapped scaled coordinates
391 <    
306 <    matVecMul3(Hmat, scaled, thePos);
307 <
308 <  }
309 <  else{
310 <    // calc the scaled coordinates.
311 <    
312 <    for(i=0; i<3; i++)
313 <      scaled[i] = thePos[i]*HmatInv[i][i];
314 <    
315 <    // wrap the scaled coordinates
316 <    
317 <    for(i=0; i<3; i++)
318 <      scaled[i] -= roundMe(scaled[i]);
319 <    
320 <    // calc the wrapped real coordinates from the wrapped scaled coordinates
321 <    
322 <    for(i=0; i<3; i++)
323 <      thePos[i] = scaled[i]*Hmat[i][i];
324 <  }
325 <    
376 > std::set<AtomType*> SimInfo::getUniqueAtomTypes() {
377 >    typename SimInfo::MoleculeIterator mi;
378 >    Molecule* mol;
379 >    typename Molecule::AtomIterator ai;
380 >    Atom* atom;
381 >    std::set<AtomType*> atomTypes;
382 >
383 >    for(mol = beginMolecule(mi); mol != NULL; mol = nextMolecule(mi)) {
384 >
385 >        for(atom = mol->beginAtom(ai); atom != NULL; atom = mol->nextAtom(ai)) {
386 >            atomTypes.insert(atom->getAtomType());
387 >        }
388 >        
389 >    }
390 >
391 >    return atomTypes;        
392   }
393  
394 + void SimInfo::setupSimType() {
395 +    std::set<AtomType*>::iterator i;
396 +    std::set<AtomType*> atomTypes;
397 +    atomTypes = getUniqueAtomTypes();
398 +    
399 +    int useLennardJones = 0;
400 +    int useElectrostatic = 0;
401 +    int useEAM = 0;
402 +    int useCharge = 0;
403 +    int useDirectional = 0;
404 +    int useDipole = 0;
405 +    int useGayBerne = 0;
406 +    int useSticky = 0;
407 +    int useShape = 0;
408 +    int useFLARB = 0; //it is not in AtomType yet
409 +    int useDirectionalAtom = 0;    
410 +    int useElectrostatics = 0;
411 +    //usePBC and useRF are from globals
412 +    bool usePBC = globals_->getPBC();
413 +    bool useRF = globals_->getUseRF();
414  
415 < int SimInfo::getNDF(){
416 <  int ndf_local;
415 >    //loop over all of the atom types
416 >    for (i = atomTypes.begin(); i != atomTypes.end(); ++i) {
417 >        useLennardJones |= i->isLennardJones();
418 >        useElectrostatic |= i->isElectrostatic();
419 >        useEAM |= i->isEAM();
420 >        useCharge |= i->isCharge();
421 >        useDirectional |= i->isDirectional();
422 >        useDipole |= i->isDipole();
423 >        useGayBerne |= i->isGayBerne();
424 >        useSticky |= i->isSticky();
425 >        useShape |= i->isShape();
426 >    }
427  
428 <  ndf_local = 0;
429 <  
334 <  for(int i = 0; i < integrableObjects.size(); i++){
335 <    ndf_local += 3;
336 <    if (integrableObjects[i]->isDirectional()) {
337 <      if (integrableObjects[i]->isLinear())
338 <        ndf_local += 2;
339 <      else
340 <        ndf_local += 3;
428 >    if (useSticky || useDipole || useGayBerne || useShape) {
429 >        useDirectionalAtom = 1;
430      }
342  }
431  
432 <  // n_constraints is local, so subtract them on each processor:
432 >    if (useCharge || useDipole) {
433 >        useElectrostatics = 1;
434 >    }
435  
436 <  ndf_local -= n_constraints;
436 > #ifdef IS_MPI    
437 >    int temp;
438  
439 < #ifdef IS_MPI
440 <  MPI_Allreduce(&ndf_local,&ndf,1,MPI_INT,MPI_SUM, MPI_COMM_WORLD);
350 < #else
351 <  ndf = ndf_local;
352 < #endif
439 >    temp = usePBC;
440 >    MPI_Allreduce(&temp, &usePBC, 1, MPI_INT, MPI_LOR, MPI_COMM_WORLD);    
441  
442 <  // nZconstraints is global, as are the 3 COM translations for the
443 <  // entire system:
442 >    temp = useDirectionalAtom;
443 >    MPI_Allreduce(&temp, &useDirectionalAtom, 1, MPI_INT, MPI_LOR, MPI_COMM_WORLD);    
444  
445 <  ndf = ndf - 3 - nZconstraints;
445 >    temp = useLennardJones;
446 >    MPI_Allreduce(&temp, &useLennardJones, 1, MPI_INT, MPI_LOR, MPI_COMM_WORLD);    
447  
448 <  return ndf;
449 < }
448 >    temp = useElectrostatics;
449 >    MPI_Allreduce(&temp, &useElectrostatics, 1, MPI_INT, MPI_LOR, MPI_COMM_WORLD);    
450  
451 < int SimInfo::getNDFraw() {
452 <  int ndfRaw_local;
451 >    temp = useCharge;
452 >    MPI_Allreduce(&temp, &useCharge, 1, MPI_INT, MPI_LOR, MPI_COMM_WORLD);    
453  
454 <  // Raw degrees of freedom that we have to set
455 <  ndfRaw_local = 0;
454 >    temp = useDipole;
455 >    MPI_Allreduce(&temp, &useDipole, 1, MPI_INT, MPI_LOR, MPI_COMM_WORLD);    
456  
457 <  for(int i = 0; i < integrableObjects.size(); i++){
458 <    ndfRaw_local += 3;
370 <    if (integrableObjects[i]->isDirectional()) {
371 <       if (integrableObjects[i]->isLinear())
372 <        ndfRaw_local += 2;
373 <      else
374 <        ndfRaw_local += 3;
375 <    }
376 <  }
377 <    
378 < #ifdef IS_MPI
379 <  MPI_Allreduce(&ndfRaw_local,&ndfRaw,1,MPI_INT,MPI_SUM, MPI_COMM_WORLD);
380 < #else
381 <  ndfRaw = ndfRaw_local;
382 < #endif
457 >    temp = useSticky;
458 >    MPI_Allreduce(&temp, &useSticky, 1, MPI_INT, MPI_LOR, MPI_COMM_WORLD);    
459  
460 <  return ndfRaw;
461 < }
460 >    temp = useGayBerne;
461 >    MPI_Allreduce(&temp, &useGayBerne, 1, MPI_INT, MPI_LOR, MPI_COMM_WORLD);    
462  
463 < int SimInfo::getNDFtranslational() {
464 <  int ndfTrans_local;
463 >    temp = useEAM;
464 >    MPI_Allreduce(&temp, &useEAM, 1, MPI_INT, MPI_LOR, MPI_COMM_WORLD);    
465  
466 <  ndfTrans_local = 3 * integrableObjects.size() - n_constraints;
466 >    temp = useShape;
467 >    MPI_Allreduce(&temp, &useShape, 1, MPI_INT, MPI_LOR, MPI_COMM_WORLD);  
468  
469 +    temp = useFLARB;
470 +    MPI_Allreduce(&temp, &useFLARB, 1, MPI_INT, MPI_LOR, MPI_COMM_WORLD);    
471  
472 < #ifdef IS_MPI
473 <  MPI_Allreduce(&ndfTrans_local,&ndfTrans,1,MPI_INT,MPI_SUM, MPI_COMM_WORLD);
474 < #else
396 <  ndfTrans = ndfTrans_local;
472 >    temp = useRF;
473 >    MPI_Allreduce(&temp, &useRF, 1, MPI_INT, MPI_LOR, MPI_COMM_WORLD);    
474 >    
475   #endif
476  
477 <  ndfTrans = ndfTrans - 3 - nZconstraints;
477 >    fInfo_.SIM_uses_PBC = usePBC;    
478 >    fInfo_.SIM_uses_DirectionalAtoms = useDirectionalAtom;
479 >    fInfo_.SIM_uses_LennardJones = useLennardJones;
480 >    fInfo_.SIM_uses_Electrostatics = useElectrostatics;    
481 >    fInfo_.SIM_uses_Charges = useCharge;
482 >    fInfo_.SIM_uses_Dipoles = useDipole;
483 >    fInfo_.SIM_uses_Sticky = useSticky;
484 >    fInfo_.SIM_uses_GayBerne = useGayBerne;
485 >    fInfo_.SIM_uses_EAM = useEAM;
486 >    fInfo_.SIM_uses_Shapes = useShape;
487 >    fInfo_.SIM_uses_FLARB = useFLARB;
488 >    fInfo_.SIM_uses_RF = useRF;
489  
490 <  return ndfTrans;
490 >    if( fInfo_.SIM_uses_Dipoles && fInfo_.SIM_uses_RF) {
491 >        fInfo_.dielect = dielectric;
492 >    } else {
493 >        fInfo_.dielect = 0.0;
494 >    }
495 >
496   }
497  
498 < int SimInfo::getTotIntegrableObjects() {
499 <  int nObjs_local;
500 <  int nObjs;
498 > void SimInfo::setupFortranSim() {
499 >    int isError;
500 >    int nExclude;
501 >    std::vector<int> fortranGlobalGroupMembership;
502 >    
503 >    nExclude = exclude_.getSize();
504 >    isError = 0;
505  
506 <  nObjs_local =  integrableObjects.size();
506 >    //globalGroupMembership_ is filled by SimCreator    
507 >    for (int i = 0; i < nGlobalAtoms_; i++) {
508 >        fortranGlobalGroupMembership.push_back(globalGroupMembership_[i] + 1);
509 >    }
510  
511 +    //calculate mass ratio of cutoff group
512 +    std::vector<double> mfact;
513 +    typename SimInfo::MoleculeIterator mi;
514 +    Molecule* mol;
515 +    typename Molecule::CutoffGroupIterator ci;
516 +    CutoffGroup* cg;
517 +    typename Molecule::AtomIterator ai;
518 +    Atom* atom;
519 +    double totalMass;
520  
521 < #ifdef IS_MPI
522 <  MPI_Allreduce(&nObjs_local,&nObjs,1,MPI_INT,MPI_SUM, MPI_COMM_WORLD);
523 < #else
524 <  nObjs = nObjs_local;
525 < #endif
521 >    //to avoid memory reallocation, reserve enough space for mfact
522 >    mfact.reserve(getNCutoffGroups());
523 >    
524 >    for(mol = beginMolecule(mi); mol != NULL; mol = nextMolecule(mi)) {        
525 >        for (cg = mol->beginCutoffGroup(ci); cg != NULL; cg = mol->nextCutoffGroup(ci)) {
526  
527 +            totalMass = cg->getMass();
528 +            for(atom = cg->beginAtom(ai); atom != NULL; atom = cg->nextAtom(ai)) {
529 +                        mfact.push_back(atom->getMass()/totalMass);
530 +            }
531  
532 <  return nObjs;
533 < }
532 >        }      
533 >    }
534  
535 < void SimInfo::refreshSim(){
535 >    //fill ident array of local atoms (it is actually ident of AtomType, it is so confusing !!!)
536 >    std::vector<int> identArray;
537  
538 <  simtype fInfo;
539 <  int isError;
540 <  int n_global;
541 <  int* excl;
538 >    //to avoid memory reallocation, reserve enough space identArray
539 >    identArray.reserve(getNAtoms());
540 >    
541 >    for(mol = beginMolecule(mi); mol != NULL; mol = nextMolecule(mi)) {        
542 >        for(atom = mol->beginAtom(ai); atom != NULL; atom = mol->nextAtom(ai)) {
543 >            identArray.push_back(atom->getIdent());
544 >        }
545 >    }    
546  
547 <  fInfo.dielect = 0.0;
547 >    //setup fortran simulation
548 >    //gloalExcludes and molMembershipArray should go away (They are never used)
549 >    //why the hell fortran need to know molecule?
550 >    //OOPSE = Object-Obfuscated Parallel Simulation Engine
551 >    
552 >    setFortranSim( &fInfo_, &nGlobalAtoms_, &nAtoms_, &identArray[0], &nExclude, exclude_->getExcludeList(),
553 >                  &nGlobalExcludes, globalExcludes, molMembershipArray,
554 >                  &mfact[0], &nCutoffGroups_, &fortranGlobalGroupMembership[0], &isError);
555  
556 <  if( useDipoles ){
431 <    if( useReactionField )fInfo.dielect = dielectric;
432 <  }
556 >    if( isError ){
557  
558 <  fInfo.SIM_uses_PBC = usePBC;
559 <  //fInfo.SIM_uses_LJ = 0;
560 <  fInfo.SIM_uses_LJ = useLJ;
561 <  fInfo.SIM_uses_sticky = useSticky;
562 <  //fInfo.SIM_uses_sticky = 0;
563 <  fInfo.SIM_uses_charges = useCharges;
440 <  fInfo.SIM_uses_dipoles = useDipoles;
441 <  //fInfo.SIM_uses_dipoles = 0;
442 <  fInfo.SIM_uses_RF = useReactionField;
443 <  //fInfo.SIM_uses_RF = 0;
444 <  fInfo.SIM_uses_GB = useGB;
445 <  fInfo.SIM_uses_EAM = useEAM;
558 >        sprintf( painCave.errMsg,
559 >                 "There was an error setting the simulation information in fortran.\n" );
560 >        painCave.isFatal = 1;
561 >        painCave.severity = OOPSE_ERROR;
562 >        simError();
563 >    }
564  
447  n_exclude = excludes->getSize();
448  excl = excludes->getFortranArray();
449  
565   #ifdef IS_MPI
566 <  n_global = mpiSim->getNAtomsGlobal();
567 < #else
568 <  n_global = n_atoms;
454 < #endif
455 <  
456 <  isError = 0;
457 <  
458 <  getFortranGroupArrays(this, FglobalGroupMembership, mfact);
459 <  //it may not be a good idea to pass the address of first element in vector
460 <  //since c++ standard does not require vector to be stored continuously in meomory
461 <  //Most of the compilers will organize the memory of vector continuously
462 <  setFsimulation( &fInfo, &n_global, &n_atoms, identArray, &n_exclude, excl,
463 <                  &nGlobalExcludes, globalExcludes, molMembershipArray,
464 <                  &mfact[0], &ngroup, &FglobalGroupMembership[0], &isError);
465 <
466 <  if( isError ){
467 <    
468 <    sprintf( painCave.errMsg,
469 <             "There was an error setting the simulation information in fortran.\n" );
470 <    painCave.isFatal = 1;
471 <    painCave.severity = OOPSE_ERROR;
472 <    simError();
473 <  }
474 <  
475 < #ifdef IS_MPI
476 <  sprintf( checkPointMsg,
477 <           "succesfully sent the simulation information to fortran.\n");
478 <  MPIcheckPoint();
566 >    sprintf( checkPointMsg,
567 >       "succesfully sent the simulation information to fortran.\n");
568 >    MPIcheckPoint();
569   #endif // is_mpi
480  
481  this->ndf = this->getNDF();
482  this->ndfRaw = this->getNDFraw();
483  this->ndfTrans = this->getNDFtranslational();
570   }
571  
486 void SimInfo::setDefaultRcut( double theRcut ){
487  
488  haveRcut = 1;
489  rCut = theRcut;
490  rList = rCut + 1.0;
491  
492  notifyFortranCutOffs( &rCut, &rSw, &rList );
493 }
572  
573 < void SimInfo::setDefaultRcut( double theRcut, double theRsw ){
573 > #ifdef IS_MPI
574 > void SimInfo::setupFortranParallel() {
575 >    
576 >    //SimInfo is responsible for creating localToGlobalAtomIndex and localToGlobalGroupIndex
577 >    std::vector<int> localToGlobalAtomIndex(getNAtoms(), 0);
578 >    std::vector<int> localToGlobalCutoffGroupIndex;
579 >    typename SimInfo::MoleculeIterator mi;
580 >    typename Molecule::AtomIterator ai;
581 >    typename Molecule::CutoffGroupIterator ci;
582 >    Molecule* mol;
583 >    Atom* atom;
584 >    CutoffGroup* cg;
585 >    mpiSimData parallelData;
586 >    int isError;
587  
588 <  rSw = theRsw;
498 <  setDefaultRcut( theRcut );
499 < }
588 >    for (mol = beginMolecule(mi); mol != NULL; mol  = nextMolecule(mi)) {
589  
590 +        //local index(index in DataStorge) of atom is important
591 +        for (atom = mol->beginAtom(ai); atom != NULL; atom = mol->nextAtom(ai)) {
592 +            localToGlobalAtomIndex[atom->getLocalIndex()] = atom->getGlobalIndex() + 1;
593 +        }
594  
595 < void SimInfo::checkCutOffs( void ){
596 <  
597 <  if( boxIsInit ){
598 <    
599 <    //we need to check cutOffs against the box
600 <    
508 <    if( rCut > maxCutoff ){
509 <      sprintf( painCave.errMsg,
510 <               "cutoffRadius is too large for the current periodic box.\n"
511 <               "\tCurrent Value of cutoffRadius = %G at time %G\n "
512 <               "\tThis is larger than half of at least one of the\n"
513 <               "\tperiodic box vectors.  Right now, the Box matrix is:\n"
514 <               "\n"
515 <               "\t[ %G %G %G ]\n"
516 <               "\t[ %G %G %G ]\n"
517 <               "\t[ %G %G %G ]\n",
518 <               rCut, currentTime,
519 <               Hmat[0][0], Hmat[0][1], Hmat[0][2],
520 <               Hmat[1][0], Hmat[1][1], Hmat[1][2],
521 <               Hmat[2][0], Hmat[2][1], Hmat[2][2]);
522 <      painCave.severity = OOPSE_ERROR;
523 <      painCave.isFatal = 1;
524 <      simError();
525 <    }    
526 <  } else {
527 <    // initialize this stuff before using it, OK?
528 <    sprintf( painCave.errMsg,
529 <             "Trying to check cutoffs without a box.\n"
530 <             "\tOOPSE should have better programmers than that.\n" );
531 <    painCave.severity = OOPSE_ERROR;
532 <    painCave.isFatal = 1;
533 <    simError();      
534 <  }
535 <  
536 < }
595 >        //local index of cutoff group is trivial, it only depends on the order of travesing
596 >        for (cg = mol->beginCutoffGroup(ci); cg != NULL; cg = mol->nextCutoffGroup(ci)) {
597 >            localToGlobalCutoffGroupIndex.push_back(cg->getGlobalIndex() + 1);
598 >        }        
599 >        
600 >    }
601  
602 < void SimInfo::addProperty(GenericData* prop){
602 >    //fill up mpiSimData struct
603 >    parallelData.nMolGlobal = getNGlobalMolecules();
604 >    parallelData.nMolLocal = getNMolecules();
605 >    parallelData.nAtomsGlobal = getNGlobalAtoms();
606 >    parallelData.nAtomsLocal = getNAtoms();
607 >    parallelData.nGroupsGlobal = getNGlobalCutoffGroups();
608 >    parallelData.nGroupsLocal = getNCutoffGroups();
609 >    parallelData.myNode = worldRank;
610 >    MPI_Comm_size(MPI_COMM_WORLD, &(parallelData->nProcessors));
611  
612 <  map<string, GenericData*>::iterator result;
613 <  result = properties.find(prop->getID());
614 <  
615 <  //we can't simply use  properties[prop->getID()] = prop,
544 <  //it will cause memory leak if we already contain a propery which has the same name of prop
545 <  
546 <  if(result != properties.end()){
547 <    
548 <    delete (*result).second;
549 <    (*result).second = prop;
550 <      
551 <  }
552 <  else{
612 >    //pass mpiSimData struct and index arrays to fortran
613 >    setFsimParallel(parallelData, &(parallelData->nAtomsLocal),
614 >                    &localToGlobalAtomIndex[0],  &(parallelData->nGroupsLocal),
615 >                    &localToGlobalCutoffGroupIndex[0], &isError);
616  
617 <    properties[prop->getID()] = prop;
617 >    if (isError) {
618 >        sprintf(painCave.errMsg,
619 >                "mpiRefresh errror: fortran didn't like something we gave it.\n");
620 >        painCave.isFatal = 1;
621 >        simError();
622 >    }
623  
624 <  }
625 <    
558 < }
624 >    sprintf(checkPointMsg, " mpiRefresh successful.\n");
625 >    MPIcheckPoint();
626  
627 < GenericData* SimInfo::getProperty(const string& propName){
561 <
562 <  map<string, GenericData*>::iterator result;
563 <  
564 <  //string lowerCaseName = ();
565 <  
566 <  result = properties.find(propName);
567 <  
568 <  if(result != properties.end())
569 <    return (*result).second;  
570 <  else  
571 <    return NULL;  
627 >
628   }
629  
630 + #endif
631  
632 < void SimInfo::getFortranGroupArrays(SimInfo* info,
633 <                                    vector<int>& FglobalGroupMembership,
634 <                                    vector<double>& mfact){
578 <  
579 <  Molecule* myMols;
580 <  Atom** myAtoms;
581 <  int numAtom;
582 <  double mtot;
583 <  int numMol;
584 <  int numCutoffGroups;
585 <  CutoffGroup* myCutoffGroup;
586 <  vector<CutoffGroup*>::iterator iterCutoff;
587 <  Atom* cutoffAtom;
588 <  vector<Atom*>::iterator iterAtom;
589 <  int atomIndex;
590 <  double totalMass;
591 <  
592 <  mfact.clear();
593 <  FglobalGroupMembership.clear();
594 <  
632 > void SimInfo::addProperty(GenericData* genData) {
633 >    properties_.addProperty(genData);  
634 > }
635  
636 <  // Fix the silly fortran indexing problem
637 < #ifdef IS_MPI
638 <  numAtom = mpiSim->getNAtomsGlobal();
599 < #else
600 <  numAtom = n_atoms;
601 < #endif
602 <  for (int i = 0; i < numAtom; i++)
603 <    FglobalGroupMembership.push_back(globalGroupMembership[i] + 1);
604 <  
636 > void SimInfo::removeProperty(const std::string& propName) {
637 >    properties_.removeProperty(propName);  
638 > }
639  
640 <  myMols = info->molecules;
641 <  numMol = info->n_mol;
642 <  for(int i  = 0; i < numMol; i++){
609 <    numCutoffGroups = myMols[i].getNCutoffGroups();
610 <    for(myCutoffGroup =myMols[i].beginCutoffGroup(iterCutoff);
611 <        myCutoffGroup != NULL;
612 <        myCutoffGroup =myMols[i].nextCutoffGroup(iterCutoff)){
640 > void SimInfo::clearProperties() {
641 >    properties_.clearProperties();
642 > }
643  
644 <      totalMass = myCutoffGroup->getMass();
644 > std::vector<std::string> SimInfo::getPropertyNames() {
645 >    return properties_.getPropertyNames();  
646 > }
647        
648 <      for(cutoffAtom = myCutoffGroup->beginAtom(iterAtom);
649 <          cutoffAtom != NULL;
650 <          cutoffAtom = myCutoffGroup->nextAtom(iterAtom)){
619 <        mfact.push_back(cutoffAtom->getMass()/totalMass);
620 <      }  
621 <    }
622 <  }
648 > std::vector<GenericData*> SimInfo::getProperties() {
649 >    return properties_.getProperties();
650 > }
651  
652 + GenericData* SimInfo::getPropertyByName(const std::string& propName) {
653 +    return properties_.getPropertyByName(propName);
654   }
655 +
656 +
657 + std::ostream& operator <<(ostream& o, SimInfo& info) {
658 +
659 +    return o;
660 + }
661 +
662 + }//end namespace oopse

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines