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 3465 by chuckv, Tue Oct 21 16:44:00 2008 UTC vs.
Revision 3504 by gezelter, Wed May 13 22:27:29 2009 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines