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

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines