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 3550 by gezelter, Wed Oct 21 02:49:43 2009 UTC

# Line 1 | Line 1
1   /*
2 < * Copyright (c) 2008 The University of Notre Dame. All Rights Reserved.
2 > * Copyright (c) 2008, 2009 The University of Notre Dame. All Rights Reserved.
3   *
4   * The University of Notre Dame grants you ("Licensee") a
5   * non-exclusive, royalty free, license to use, modify and
# 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      surfaceMesh_->computeHull(localSites_);
145  
146 <    /* Get area and number of surface stunt doubles and compute new variance */
147 <     RealType area = surfaceMesh_->getArea();
148 <     int nSurfaceSDs = surfaceMesh_->getNs();
149 <
150 <     /* Compute variance for random forces */
151 <    
152 <     variance_ = sqrt(2.0*NumericConstant::PI)*((targetPressure_/OOPSEConstant::pressureConvert)*area/nSurfaceSDs);
153 <    
154 <    std::vector<Triangle*> sMesh = surfaceMesh_->getMesh();
155 <    std::vector<RealType>  randNums = genTriangleForces(sMesh.size(),variance_);
156 <    
298 <    /* Loop over the mesh faces and apply random force to each of the faces*/
299 <    
300 <    
301 <    std::vector<Triangle*>::iterator face;
146 >    // Get total area and number of surface stunt doubles
147 >    RealType area = surfaceMesh_->getArea();
148 >    std::vector<Triangle> sMesh = surfaceMesh_->getMesh();
149 >    int nTriangles = sMesh.size();
150 >
151 >    // Generate all of the necessary random forces
152 >    std::vector<RealType>  randNums = genTriangleForces(nTriangles, variance_);
153 >
154 >    // Loop over the mesh faces and apply external pressure to each
155 >    // of the faces
156 >    std::vector<Triangle>::iterator face;
157      std::vector<StuntDouble*>::iterator vertex;
158 <    int thisNumber = 0;
158 >    int thisFacet = 0;
159      for (face = sMesh.begin(); face != sMesh.end(); ++face){
160 <    
161 <      Triangle* thisTriangle = *face;
162 <      std::vector<StuntDouble*> vertexSDs = thisTriangle->getVertices();
163 <      
309 <      /* Get Random Force */
310 <      Vector3d unitNormal = thisTriangle->getNormal();
160 >      Triangle thisTriangle = *face;
161 >      std::vector<StuntDouble*> vertexSDs = thisTriangle.getVertices();
162 >      RealType thisArea = thisTriangle.getArea();
163 >      Vector3d unitNormal = thisTriangle.getNormal();
164        unitNormal.normalize();
165 <      Vector3d randomForce = -randNums[thisNumber] * unitNormal;
166 <      
167 <      for (vertex = vertexSDs.begin(); vertex != vertexSDs.end(); ++vertex){
165 >      Vector3d centroid = thisTriangle.getCentroid();
166 >      Vector3d facetVel = thisTriangle.getFacetVelocity();
167 >      RealType thisMass = thisTriangle.getFacetMass();
168  
169 <         // mass = integrableObject->getMass();
169 >      // gamma is the drag coefficient normal to the face of the triangle      
170 >      RealType gamma = thermalConductivity_ * thisMass * thisArea
171 >        / (2.0 * thermalLength_ * OOPSEConstant::kB);
172  
173 <                    (*vertex)->addFrc(randomForce/3.0);          
174 <      }
175 <    }
173 >      RealType extPressure = - (targetPressure_ * thisArea) /
174 >        OOPSEConstant::energyConvert;
175 >      RealType randomForce = randNums[thisFacet++] * sqrt(gamma);
176 >      RealType dragForce = -gamma * dot(facetVel, unitNormal);
177  
178 <    /* Now loop over all surface particles and apply the drag*/
179 <
324 <    std::vector<StuntDouble*> surfaceSDs = surfaceMesh_->getSurfaceAtoms();
325 <    for (vertex = surfaceSDs.begin(); vertex != surfaceSDs.end(); ++vertex){
326 <      integrableObject = *vertex;
327 <      mass = integrableObject->getMass();
328 <      if (integrableObject->isDirectional()){
329 <        
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);
385 <          }
386 <          
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 <        
462 <      }
178 >      Vector3d langevinForce = (extPressure + randomForce + dragForce) *
179 >        unitNormal;
180        
181 <      
182 <    }
183 <    Snapshot* currSnapshot = info_->getSnapshotManager()->getCurrentSnapshot();
184 <    currSnapshot->setVolume(surfaceMesh_->getVolume());
181 >      // Apply triangle force to stuntdouble vertices
182 >      for (vertex = vertexSDs.begin(); vertex != vertexSDs.end(); ++vertex){
183 >        if ((*vertex) != NULL){
184 >          Vector3d vertexForce = langevinForce / 3.0;
185 >          (*vertex)->addFrc(vertexForce);          
186 >        }  
187 >      }
188 >    }
189      
190 +    veloMunge->removeComDrift();
191 +    veloMunge->removeAngularDrift();
192 +    
193 +    Snapshot* currSnapshot = info_->getSnapshotManager()->getCurrentSnapshot();
194 +    currSnapshot->setVolume(surfaceMesh_->getVolume());    
195      ForceManager::postCalculation(needStress);  
196    }
197 <
198 <  void SMIPDForceManager::genRandomForceAndTorque(Vector3d& force, Vector3d& torque, unsigned int index, RealType variance) {
199 <
197 >  
198 >  
199 >  std::vector<RealType> SMIPDForceManager::genTriangleForces(int nTriangles,
200 >                                                             RealType variance)
201 >  {
202      
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
203      // zero fill the random vector before starting:
204      std::vector<RealType> gaussRand;
205      gaussRand.resize(nTriangles);
206      std::fill(gaussRand.begin(), gaussRand.end(), 0.0);
207 <
503 <
207 >    
208   #ifdef IS_MPI
209      if (worldRank == 0) {
210   #endif
211        for (int i = 0; i < nTriangles; i++) {
212 <        gaussRand[i] = fabs(randNumGen_.randNorm(0.0, 1.0));    
212 >        gaussRand[i] = randNumGen_.randNorm(0.0, variance);
213        }
214   #ifdef IS_MPI
215      }
216   #endif
217 <
217 >    
218      // push these out to the other processors
219 <
219 >    
220   #ifdef IS_MPI
221      if (worldRank == 0) {
222 <      MPI_Bcast(&gaussRand[0], nTriangles, MPI_REAL, 0, MPI_COMM_WORLD);
222 >      MPI::COMM_WORLD.Bcast(&gaussRand[0], nTriangles, MPI::REALTYPE, 0);
223      } else {
224 <      MPI_Bcast(&gaussRand[0], nTriangles, MPI_REAL, 0, MPI_COMM_WORLD);
224 >      MPI::COMM_WORLD.Bcast(&gaussRand[0], nTriangles, MPI::REALTYPE, 0);
225      }
226   #endif
227 <
524 <    for (int i = 0; i < nTriangles; i++) {
525 <      gaussRand[i] = gaussRand[i] * variance;
526 <    }
527 <
227 >    
228      return gaussRand;
229    }
530
230   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines