ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-4/src/integrators/SMIPDForceManager.cpp
(Generate patch)

Comparing trunk/OOPSE-4/src/integrators/SMIPDForceManager.cpp (file contents):
Revision 3459 by chuckv, Tue Oct 7 17:12:48 2008 UTC vs.
Revision 3517 by gezelter, Thu Jul 23 18:49:45 2009 UTC

# Line 41 | Line 41
41   #include <fstream>
42   #include <iostream>
43   #include "integrators/SMIPDForceManager.hpp"
44 #include "math/CholeskyDecomposition.hpp"
44   #include "utils/OOPSEConstant.hpp"
46 #include "hydrodynamics/Sphere.hpp"
47 #include "hydrodynamics/Ellipsoid.hpp"
48 #include "utils/ElementsTable.hpp"
45   #include "math/ConvexHull.hpp"
46   #include "math/Triangle.hpp"
47  
52
48   namespace oopse {
49  
50 <  SMIPDForceManager::SMIPDForceManager(SimInfo* info) : ForceManager(info), forceTolerance_(1e-6), maxIterNum_(4) {
50 >  SMIPDForceManager::SMIPDForceManager(SimInfo* info) : ForceManager(info) {
51 >
52      simParams = info->getSimParams();
53      veloMunge = new Velocitizer(info);
54      
55      // Create Hull, Convex Hull for now, other options later.
56 +    
57      surfaceMesh_ = new ConvexHull();
58      
62    
59      /* Check that the simulation has target pressure and target
60 <       temperature set*/
61 <
60 >       temperature set */
61 >    
62      if (!simParams->haveTargetTemp()) {
63 <      sprintf(painCave.errMsg, "You can't use the SMIPDynamics integrator without a targetTemp!\n");
63 >      sprintf(painCave.errMsg,
64 >              "SMIPDynamics error: You can't use the SMIPD integrator\n"
65 >              "\twithout a targetTemp (K)!\n");      
66        painCave.isFatal = 1;
67        painCave.severity = OOPSE_ERROR;
68        simError();
69      } else {
70        targetTemp_ = simParams->getTargetTemp();
71      }
72 <
72 >    
73      if (!simParams->haveTargetPressure()) {
74 <      sprintf(painCave.errMsg, "SMIPDynamics error: You can't use the SMIPD integrator\n"
75 <              "   without a targetPressure!\n");
76 <      
74 >      sprintf(painCave.errMsg,
75 >              "SMIPDynamics error: You can't use the SMIPD integrator\n"
76 >              "\twithout a targetPressure (atm)!\n");      
77        painCave.isFatal = 1;
78        simError();
79      } else {
80 <      targetPressure_ = simParams->getTargetPressure();
80 >      // Convert pressure from atm -> amu/(fs^2*Ang)
81 >      targetPressure_ = simParams->getTargetPressure() /
82 >        OOPSEConstant::pressureConvert;
83      }
84
84    
85      if (simParams->getUsePeriodicBoundaryConditions()) {
86 <      sprintf(painCave.errMsg, "SMIPDynamics error: You can't use the SMIPD integrator\n"
87 <              "   with periodic boundary conditions !\n");
88 <      
86 >      sprintf(painCave.errMsg,
87 >              "SMIPDynamics error: You can't use the SMIPD integrator\n"
88 >              "\twith periodic boundary conditions!\n");    
89        painCave.isFatal = 1;
90        simError();
91      }
92 +    
93 +    if (!simParams->haveThermalConductivity()) {
94 +      sprintf(painCave.errMsg,
95 +              "SMIPDynamics error: You can't use the SMIPD integrator\n"
96 +              "\twithout a thermalConductivity (W m^-1 K^-1)!\n");
97 +      painCave.isFatal = 1;
98 +      painCave.severity = OOPSE_ERROR;
99 +      simError();
100 +    }else{
101 +      thermalConductivity_ = simParams->getThermalConductivity() *
102 +        OOPSEConstant::thermalConductivityConvert;
103 +    }
104  
105 +    if (!simParams->haveThermalLength()) {
106 +      sprintf(painCave.errMsg,
107 +              "SMIPDynamics error: You can't use the SMIPD integrator\n"
108 +              "\twithout a thermalLength (Angstroms)!\n");
109 +      painCave.isFatal = 1;
110 +      painCave.severity = OOPSE_ERROR;
111 +      simError();
112 +    }else{
113 +      thermalLength_ = simParams->getThermalLength();
114 +    }
115 +    
116 +    dt_ = simParams->getDt();
117 +  
118 +    variance_ = 2.0 * OOPSEConstant::kb * targetTemp_ / dt_;
119  
120 <    // Build the hydroProp map:
121 <    std::map<std::string, HydroProp*> hydroPropMap;
97 <
120 >    // Build a vector of integrable objects to determine if the are
121 >    // surface atoms
122      Molecule* mol;
123      StuntDouble* integrableObject;
124      SimInfo::MoleculeIterator i;
125 <    Molecule::IntegrableObjectIterator  j;              
126 <    bool needHydroPropFile = false;
127 <    
128 <    for (mol = info->beginMolecule(i); mol != NULL;
105 <         mol = info->nextMolecule(i)) {
125 >    Molecule::IntegrableObjectIterator  j;
126 >
127 >    for (mol = info_->beginMolecule(i); mol != NULL;
128 >         mol = info_->nextMolecule(i)) {          
129        for (integrableObject = mol->beginIntegrableObject(j);
130             integrableObject != NULL;
108           integrableObject = mol->nextIntegrableObject(j)) {
109        
110        if (integrableObject->isRigidBody()) {
111          RigidBody* rb = static_cast<RigidBody*>(integrableObject);
112          if (rb->getNumAtoms() > 1) needHydroPropFile = true;
113        }
114        
115      }
116    }
117        
118
119    if (needHydroPropFile) {              
120      if (simParams->haveHydroPropFile()) {
121        hydroPropMap = parseFrictionFile(simParams->getHydroPropFile());
122      } else {              
123        sprintf( painCave.errMsg,
124                 "HydroPropFile must be set to a file name if SMIPDynamics\n"
125                 "\tis specified for rigidBodies which contain more than one atom\n"
126                 "\tTo create a HydroPropFile, run the \"Hydro\" program.\n\n"
127                 "\tFor use with SMIPD, the default viscosity in Hydro should be\n"
128                 "\tset to 1.0 because the friction and random forces will be\n"
129                 "\tdynamically re-set assuming this is true.\n");
130        painCave.severity = OOPSE_ERROR;
131        painCave.isFatal = 1;
132        simError();  
133      }      
134
135      for (mol = info->beginMolecule(i); mol != NULL;
136           mol = info->nextMolecule(i)) {
137        for (integrableObject = mol->beginIntegrableObject(j);
138             integrableObject != NULL;
139             integrableObject = mol->nextIntegrableObject(j)) {
140
141          std::map<std::string, HydroProp*>::iterator iter = hydroPropMap.find(integrableObject->getType());
142          if (iter != hydroPropMap.end()) {
143            hydroProps_.push_back(iter->second);
144          } else {
145            sprintf( painCave.errMsg,
146                     "Can not find resistance tensor for atom [%s]\n", integrableObject->getType().c_str());
147            painCave.severity = OOPSE_ERROR;
148            painCave.isFatal = 1;
149            simError();  
150          }        
151        }
152      }
153    } else {
154      
155      std::map<std::string, HydroProp*> hydroPropMap;
156      for (mol = info->beginMolecule(i); mol != NULL;
157           mol = info->nextMolecule(i)) {
158        for (integrableObject = mol->beginIntegrableObject(j);
159             integrableObject != NULL;
160             integrableObject = mol->nextIntegrableObject(j)) {
161          Shape* currShape = NULL;
162
163          if (integrableObject->isAtom()){
164            Atom* atom = static_cast<Atom*>(integrableObject);
165            AtomType* atomType = atom->getAtomType();
166            if (atomType->isGayBerne()) {
167              DirectionalAtomType* dAtomType = dynamic_cast<DirectionalAtomType*>(atomType);              
168              GenericData* data = dAtomType->getPropertyByName("GayBerne");
169              if (data != NULL) {
170                GayBerneParamGenericData* gayBerneData = dynamic_cast<GayBerneParamGenericData*>(data);
171                
172                if (gayBerneData != NULL) {  
173                  GayBerneParam gayBerneParam = gayBerneData->getData();
174                  currShape = new Ellipsoid(V3Zero,
175                                            gayBerneParam.GB_l / 2.0,
176                                            gayBerneParam.GB_d / 2.0,
177                                            Mat3x3d::identity());
178                } else {
179                  sprintf( painCave.errMsg,
180                           "Can not cast GenericData to GayBerneParam\n");
181                  painCave.severity = OOPSE_ERROR;
182                  painCave.isFatal = 1;
183                  simError();  
184                }
185              } else {
186                sprintf( painCave.errMsg, "Can not find Parameters for GayBerne\n");
187                painCave.severity = OOPSE_ERROR;
188                painCave.isFatal = 1;
189                simError();    
190              }
191            } else {
192              if (atomType->isLennardJones()){
193                GenericData* data = atomType->getPropertyByName("LennardJones");
194                if (data != NULL) {
195                  LJParamGenericData* ljData = dynamic_cast<LJParamGenericData*>(data);
196                  if (ljData != NULL) {
197                    LJParam ljParam = ljData->getData();
198                    currShape = new Sphere(atom->getPos(), ljParam.sigma/2.0);
199                  } else {
200                    sprintf( painCave.errMsg,
201                             "Can not cast GenericData to LJParam\n");
202                    painCave.severity = OOPSE_ERROR;
203                    painCave.isFatal = 1;
204                    simError();          
205                  }      
206                }
207              } else {
208                int aNum = etab.GetAtomicNum((atom->getType()).c_str());
209                if (aNum != 0) {
210                  currShape = new Sphere(atom->getPos(), etab.GetVdwRad(aNum));
211                } else {
212                  sprintf( painCave.errMsg,
213                           "Could not find atom type in default element.txt\n");
214                  painCave.severity = OOPSE_ERROR;
215                  painCave.isFatal = 1;
216                  simError();          
217                }
218              }
219            }
220          }
221          HydroProp* currHydroProp = currShape->getHydroProp(1.0,simParams->getTargetTemp());
222          std::map<std::string, HydroProp*>::iterator iter = hydroPropMap.find(integrableObject->getType());
223          if (iter != hydroPropMap.end())
224            hydroProps_.push_back(iter->second);
225          else {
226            currHydroProp->complete();
227            hydroPropMap.insert(std::map<std::string, HydroProp*>::value_type(integrableObject->getType(), currHydroProp));
228            hydroProps_.push_back(currHydroProp);
229          }
230        }
231      }
232    }
233
234    /* Compute hull first time through to get the area of t=0*/
235
236    /* Build a vector of integrable objects to determine if the are surface atoms */
237    for (mol = info_->beginMolecule(i); mol != NULL; mol = info_->nextMolecule(i)) {          
238      for (integrableObject = mol->beginIntegrableObject(j); integrableObject != NULL;
131             integrableObject = mol->nextIntegrableObject(j)) {  
132          localSites_.push_back(integrableObject);
133        }
134 <    }
243 <
244 <    surfaceMesh_->computeHull(localSites_);
245 <    Area0_ = surfaceMesh_->getArea();
246 <    //variance_ = 2.0 * OOPSEConstant::kb*simParams->getTargetTemp()/simParams->getDt();
247 <    
134 >    }  
135    }  
249
250  std::map<std::string, HydroProp*> SMIPDForceManager::parseFrictionFile(const std::string& filename) {
251    std::map<std::string, HydroProp*> props;
252    std::ifstream ifs(filename.c_str());
253    if (ifs.is_open()) {
254      
255    }
256    
257    const unsigned int BufferSize = 65535;
258    char buffer[BufferSize];  
259    while (ifs.getline(buffer, BufferSize)) {
260      HydroProp* currProp = new HydroProp(buffer);
261      props.insert(std::map<std::string, HydroProp*>::value_type(currProp->getName(), currProp));
262    }
263
264    return props;
265  }
136    
137    void SMIPDForceManager::postCalculation(bool needStress){
138      SimInfo::MoleculeIterator i;
139      Molecule::IntegrableObjectIterator  j;
140      Molecule* mol;
141      StuntDouble* integrableObject;
272    RealType mass;
273    Vector3d pos;
274    Vector3d frc;
275    Mat3x3d A;
276    Mat3x3d Atrans;
277    Vector3d Tb;
278    Vector3d ji;
279    unsigned int index = 0;
280    int fdf;
281  
282    fdf = 0;
142    
143 <    /*Compute surface Mesh*/
143 >    // Compute surface Mesh
144 >
145      surfaceMesh_->computeHull(localSites_);
146  
147 <    /* Get area and number of surface stunt doubles and compute new variance */
148 <     RealType area = surfaceMesh_->getArea();
149 <     int nSurfaceSDs = surfaceMesh_->getNs();
150 <
151 <     /* Compute variance for random forces */
152 <    
153 <     variance_ = sqrt(2.0*NumericConstant::PI)*((targetPressure_/OOPSEConstant::pressureConvert)*area/nSurfaceSDs);
154 <    
155 <    std::vector<Triangle*> sMesh = surfaceMesh_->getMesh();
156 <    std::vector<RealType>  randNums = genTriangleForces(sMesh.size(),variance_);
157 <    
158 <    /* Loop over the mesh faces and apply random force to each of the faces*/
299 <    
300 <    
301 <    std::vector<Triangle*>::iterator face;
147 >    // Get total area and number of surface stunt doubles
148 >    RealType area = surfaceMesh_->getArea();
149 >    int nSurfaceSDs = surfaceMesh_->getNs();
150 >    std::vector<Triangle> sMesh = surfaceMesh_->getMesh();
151 >    int nTriangles = sMesh.size();
152 >
153 >    // Generate all of the necessary random forces
154 >    std::vector<RealType>  randNums = genTriangleForces(nTriangles, variance_);
155 >
156 >    // Loop over the mesh faces and apply external pressure to each
157 >    // of the faces
158 >    std::vector<Triangle>::iterator face;
159      std::vector<StuntDouble*>::iterator vertex;
160 <    int thisNumber = 0;
160 >    int thisFacet = 0;
161      for (face = sMesh.begin(); face != sMesh.end(); ++face){
162      
163 <      Triangle* thisTriangle = *face;
164 <      std::vector<StuntDouble*> vertexSDs = thisTriangle->getVertices();
165 <      
166 <      /* Get Random Force */
310 <      Vector3d unitNormal = thisTriangle->getNormal();
163 >      Triangle thisTriangle = *face;
164 >      std::vector<StuntDouble*> vertexSDs = thisTriangle.getVertices();
165 >      RealType thisArea = thisTriangle.getArea();
166 >      Vector3d unitNormal = thisTriangle.getNormal();
167        unitNormal.normalize();
168 <      Vector3d randomForce = -randNums[thisNumber] * unitNormal;
168 >      Vector3d centroid = thisTriangle.getCentroid();
169 >      Vector3d facetVel = thisTriangle.getFacetVelocity();
170 >      RealType thisMass = thisTriangle.getFacetMass();
171 >
172 >      // gamma is the drag coefficient normal to the face of the triangle      
173 >      RealType gamma = thermalConductivity_ * thisMass * thisArea
174 >        / (2.0 * thermalLength_ * OOPSEConstant::kB);
175        
176 <      for (vertex = vertexSDs.begin(); vertex != vertexSDs.end(); ++vertex){
176 >      RealType extPressure = - (targetPressure_ * thisArea) /
177 >        OOPSEConstant::energyConvert;
178  
179 <         // mass = integrableObject->getMass();
179 >      RealType randomForce = randNums[thisFacet++] * sqrt(gamma);
180 >      RealType dragForce = -gamma * dot(facetVel, unitNormal);
181  
182 <                    (*vertex)->addFrc(randomForce/3.0);          
183 <      }
184 <    }
185 <
186 <    /* Now loop over all surface particles and apply the drag*/
187 <
188 <    std::vector<StuntDouble*> surfaceSDs = surfaceMesh_->getSurfaceAtoms();
189 <    for (vertex = surfaceSDs.begin(); vertex != surfaceSDs.end(); ++vertex){
190 <      integrableObject = *vertex;
191 <      mass = integrableObject->getMass();
192 <      if (integrableObject->isDirectional()){
193 <        
330 <        // preliminaries for directional objects:
331 <        
332 <        A = integrableObject->getA();
333 <        Atrans = A.transpose();
334 <        Vector3d rcrLab = Atrans * hydroProps_[index]->getCOR();  
335 <
336 <        
337 <        Mat3x3d I = integrableObject->getI();
338 <        Vector3d omegaBody;
339 <        
340 <        // What remains contains velocity explicitly, but the velocity required
341 <        // is at the full step: v(t + h), while we have initially the velocity
342 <        // at the half step: v(t + h/2).  We need to iterate to converge the
343 <        // friction force and friction torque vectors.
344 <        
345 <        // this is the velocity at the half-step:
346 <        
347 <        Vector3d vel =integrableObject->getVel();
348 <        Vector3d angMom = integrableObject->getJ();
349 <        
350 <        //estimate velocity at full-step using everything but friction forces:          
351 <        
352 <        frc = integrableObject->getFrc();
353 <        Vector3d velStep = vel + (dt2_ /mass * OOPSEConstant::energyConvert) * frc;
354 <        
355 <        Tb = integrableObject->lab2Body(integrableObject->getTrq());
356 <        Vector3d angMomStep = angMom + (dt2_ * OOPSEConstant::energyConvert) * Tb;                            
357 <        
358 <        Vector3d omegaLab;
359 <        Vector3d vcdLab;
360 <        Vector3d vcdBody;
361 <        Vector3d frictionForceBody;
362 <        Vector3d frictionForceLab(0.0);
363 <        Vector3d oldFFL;  // used to test for convergence
364 <        Vector3d frictionTorqueBody(0.0);
365 <        Vector3d oldFTB;  // used to test for convergence
366 <        Vector3d frictionTorqueLab;
367 <        RealType fdot;
368 <        RealType tdot;
369 <
370 <        //iteration starts here:
371 <        
372 <        for (int k = 0; k < maxIterNum_; k++) {
373 <          
374 <          if (integrableObject->isLinear()) {
375 <            int linearAxis = integrableObject->linearAxis();
376 <            int l = (linearAxis +1 )%3;
377 <            int m = (linearAxis +2 )%3;
378 <            omegaBody[l] = angMomStep[l] /I(l, l);
379 <            omegaBody[m] = angMomStep[m] /I(m, m);
380 <            
381 <          } else {
382 <            omegaBody[0] = angMomStep[0] /I(0, 0);
383 <            omegaBody[1] = angMomStep[1] /I(1, 1);
384 <            omegaBody[2] = angMomStep[2] /I(2, 2);
182 >      Vector3d langevinForce = (extPressure + randomForce + dragForce) *
183 >        unitNormal;
184 >      
185 >      // Apply triangle force to stuntdouble vertices
186 >      for (vertex = vertexSDs.begin(); vertex != vertexSDs.end(); ++vertex){
187 >        if ((*vertex) != NULL){
188 >          Vector3d vertexForce = langevinForce / 3.0;
189 >          (*vertex)->addFrc(vertexForce);          
190 >          if ((*vertex)->isDirectional()){          
191 >            Vector3d vertexPos = (*vertex)->getPos();
192 >            Vector3d vertexCentroidVector = vertexPos - centroid;
193 >            (*vertex)->addTrq(cross(vertexCentroidVector,vertexForce));
194            }
195 <          
387 <          omegaLab = Atrans * omegaBody;
388 <          
389 <          // apply friction force and torque at center of resistance
390 <          
391 <          vcdLab = velStep + cross(omegaLab, rcrLab);      
392 <          vcdBody = A * vcdLab;
393 <          frictionForceBody = -(hydroProps_[index]->getXitt() * vcdBody + hydroProps_[index]->getXirt() * omegaBody);
394 <          oldFFL = frictionForceLab;
395 <          frictionForceLab = Atrans * frictionForceBody;
396 <          oldFTB = frictionTorqueBody;
397 <          frictionTorqueBody = -(hydroProps_[index]->getXitr() * vcdBody + hydroProps_[index]->getXirr() * omegaBody);
398 <          frictionTorqueLab = Atrans * frictionTorqueBody;
399 <          
400 <          // re-estimate velocities at full-step using friction forces:
401 <              
402 <          velStep = vel + (dt2_ / mass * OOPSEConstant::energyConvert) * (frc + frictionForceLab);
403 <          angMomStep = angMom + (dt2_ * OOPSEConstant::energyConvert) * (Tb + frictionTorqueBody);
404 <
405 <          // check for convergence (if the vectors have converged, fdot and tdot will both be 1.0):
406 <              
407 <          fdot = dot(frictionForceLab, oldFFL) / frictionForceLab.lengthSquare();
408 <          tdot = dot(frictionTorqueBody, oldFTB) / frictionTorqueBody.lengthSquare();
409 <          
410 <          if (fabs(1.0 - fdot) <= forceTolerance_ && fabs(1.0 - tdot) <= forceTolerance_)
411 <            break; // iteration ends here
412 <        }
413 <        
414 <        integrableObject->addFrc(frictionForceLab);
415 <        integrableObject->addTrq(frictionTorqueLab + cross(rcrLab, frictionForceLab));
416 <
417 <            
418 <      } else {
419 <        //spherical atom
420 <
421 <        
422 <        // What remains contains velocity explicitly, but the velocity required
423 <        // is at the full step: v(t + h), while we have initially the velocity
424 <        // at the half step: v(t + h/2).  We need to iterate to converge the
425 <        // friction force vector.
426 <        
427 <        // this is the velocity at the half-step:
428 <        
429 <        Vector3d vel =integrableObject->getVel();
430 <        
431 <        //estimate velocity at full-step using everything but friction forces:          
432 <        
433 <        frc = integrableObject->getFrc();
434 <        Vector3d velStep = vel + (dt2_ / mass * OOPSEConstant::energyConvert) * frc;
435 <        
436 <        Vector3d frictionForce(0.0);
437 <        Vector3d oldFF;  // used to test for convergence
438 <        RealType fdot;
439 <        
440 <        //iteration starts here:
441 <        
442 <        for (int k = 0; k < maxIterNum_; k++) {
443 <          
444 <          oldFF = frictionForce;                            
445 <          frictionForce = -hydroProps_[index]->getXitt() * velStep;
446 <          
447 <          // re-estimate velocities at full-step using friction forces:
448 <          
449 <          velStep = vel + (dt2_ / mass * OOPSEConstant::energyConvert) * (frc + frictionForce);
450 <          
451 <          // check for convergence (if the vector has converged, fdot will be 1.0):
452 <          
453 <          fdot = dot(frictionForce, oldFF) / frictionForce.lengthSquare();
454 <          
455 <          if (fabs(1.0 - fdot) <= forceTolerance_)
456 <            break; // iteration ends here
457 <        }
458 <        
459 <        integrableObject->addFrc(frictionForce);
460 <        
461 <        
195 >        }  
196        }
197 <      
464 <      
465 <    }
466 <    Snapshot* currSnapshot = info_->getSnapshotManager()->getCurrentSnapshot();
467 <    currSnapshot->setVolume(surfaceMesh_->getVolume());
197 >    }
198      
199 +    veloMunge->removeComDrift();
200 +    veloMunge->removeAngularDrift();
201 +    
202 +    Snapshot* currSnapshot = info_->getSnapshotManager()->getCurrentSnapshot();
203 +    currSnapshot->setVolume(surfaceMesh_->getVolume());    
204      ForceManager::postCalculation(needStress);  
205    }
206 <
207 <  void SMIPDForceManager::genRandomForceAndTorque(Vector3d& force, Vector3d& torque, unsigned int index, RealType variance) {
208 <
206 >  
207 >  
208 >  std::vector<RealType> SMIPDForceManager::genTriangleForces(int nTriangles,
209 >                                                             RealType variance)
210 >  {
211      
475    Vector<RealType, 6> Z;
476    Vector<RealType, 6> generalForce;
477    
478
479    Z[0] = randNumGen_.randNorm(0, variance);
480    Z[1] = randNumGen_.randNorm(0, variance);
481    Z[2] = randNumGen_.randNorm(0, variance);
482    Z[3] = randNumGen_.randNorm(0, variance);
483    Z[4] = randNumGen_.randNorm(0, variance);
484    Z[5] = randNumGen_.randNorm(0, variance);
485    
486    generalForce = hydroProps_[index]->getS()*Z;
487    
488    force[0] = generalForce[0];
489    force[1] = generalForce[1];
490    force[2] = generalForce[2];
491    torque[0] = generalForce[3];
492    torque[1] = generalForce[4];
493    torque[2] = generalForce[5];
494    
495 }
496  std::vector<RealType> SMIPDForceManager::genTriangleForces(int nTriangles, RealType variance) {
497
212      // zero fill the random vector before starting:
213      std::vector<RealType> gaussRand;
214      gaussRand.resize(nTriangles);
215      std::fill(gaussRand.begin(), gaussRand.end(), 0.0);
216 <
503 <
216 >    
217   #ifdef IS_MPI
218      if (worldRank == 0) {
219   #endif
220        for (int i = 0; i < nTriangles; i++) {
221 <        gaussRand[i] = fabs(randNumGen_.randNorm(0.0, 1.0));    
221 >        gaussRand[i] = randNumGen_.randNorm(0.0, variance);
222        }
223   #ifdef IS_MPI
224      }
225   #endif
226 <
226 >    
227      // push these out to the other processors
228 <
228 >    
229   #ifdef IS_MPI
230      if (worldRank == 0) {
231 <      MPI_Bcast(&gaussRand[0], nTriangles, MPI_REAL, 0, MPI_COMM_WORLD);
231 >      MPI::COMM_WORLD.Bcast(&gaussRand[0], nTriangles, MPI::REALTYPE, 0);
232      } else {
233 <      MPI_Bcast(&gaussRand[0], nTriangles, MPI_REAL, 0, MPI_COMM_WORLD);
233 >      MPI::COMM_WORLD.Bcast(&gaussRand[0], nTriangles, MPI::REALTYPE, 0);
234      }
235   #endif
236 <
524 <    for (int i = 0; i < nTriangles; i++) {
525 <      gaussRand[i] = gaussRand[i] * variance;
526 <    }
527 <
236 >    
237      return gaussRand;
238    }
530
239   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines