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 3473 by chuckv, Fri Nov 14 15:44:34 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      }
93 <
93 >    
94      if (!simParams->haveViscosity()) {
95 <      sprintf(painCave.errMsg, "You can't use SMIPDynamics without a viscosity!\n");
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      }
101
102
104      
105 +    dt_ = simParams->getDt();
106 +  
107 +    variance_ = 2.0 * OOPSEConstant::kb * targetTemp_ / dt_;
108  
109 <    //Compute initial hull
110 <    /*
107 <    surfaceMesh_->computeHull(localSites_);
108 <    Area0_ = surfaceMesh_->getArea();
109 <    int nTriangles = surfaceMesh_->getNMeshElements();
110 <    //    variance_ = 2.0 * OOPSEConstant::kb*simParams->getTargetTemp()/simParams->getDt();
111 <    gamma_0_ = (NumericConstant::PI * targetPressure_* targetPressure_ * Area0_ * Area0_ * simParams->getDt()) /
112 <      (4.0 * nTriangles * nTriangles* OOPSEConstant::kb*simParams->getTargetTemp());
113 <    //RealType eta0 = gamma_0/
114 <    */
115 <
116 <    // Build the hydroProp map:
117 <    std::map<std::string, HydroProp*> hydroPropMap;
118 <
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;
126 <         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;
129           integrableObject = mol->nextIntegrableObject(j)) {
130        
131        if (integrableObject->isRigidBody()) {
132          RigidBody* rb = static_cast<RigidBody*>(integrableObject);
133          if (rb->getNumAtoms() > 1) needHydroPropFile = true;
134        }
135        
136      }
137    }
138        
139
140    if (needHydroPropFile) {              
141      if (simParams->haveHydroPropFile()) {
142        hydroPropMap = parseFrictionFile(simParams->getHydroPropFile());
143      } else {              
144        sprintf( painCave.errMsg,
145                 "HydroPropFile must be set to a file name if SMIPDynamics\n"
146                 "\tis specified for rigidBodies which contain more than one atom\n"
147                 "\tTo create a HydroPropFile, run the \"Hydro\" program.\n\n"
148                 "\tFor use with SMIPD, the default viscosity in Hydro should be\n"
149                 "\tset to 1.0 because the friction and random forces will be\n"
150                 "\tdynamically re-set assuming this is true.\n");
151        painCave.severity = OOPSE_ERROR;
152        painCave.isFatal = 1;
153        simError();  
154      }      
155
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
162          std::map<std::string, HydroProp*>::iterator iter = hydroPropMap.find(integrableObject->getType());
163          if (iter != hydroPropMap.end()) {
164            hydroProps_.push_back(iter->second);
165          } else {
166            sprintf( painCave.errMsg,
167                     "Can not find resistance tensor for atom [%s]\n", integrableObject->getType().c_str());
168            painCave.severity = OOPSE_ERROR;
169            painCave.isFatal = 1;
170            simError();  
171          }        
172        }
173      }
174    } else {
175      
176      std::map<std::string, HydroProp*> hydroPropMap;
177      for (mol = info->beginMolecule(i); mol != NULL;
178           mol = info->nextMolecule(i)) {
179        for (integrableObject = mol->beginIntegrableObject(j);
180             integrableObject != NULL;
181             integrableObject = mol->nextIntegrableObject(j)) {
182          Shape* currShape = NULL;
183
184          if (integrableObject->isAtom()){
185            Atom* atom = static_cast<Atom*>(integrableObject);
186            AtomType* atomType = atom->getAtomType();
187            if (atomType->isGayBerne()) {
188              DirectionalAtomType* dAtomType = dynamic_cast<DirectionalAtomType*>(atomType);              
189              GenericData* data = dAtomType->getPropertyByName("GayBerne");
190              if (data != NULL) {
191                GayBerneParamGenericData* gayBerneData = dynamic_cast<GayBerneParamGenericData*>(data);
192                
193                if (gayBerneData != NULL) {  
194                  GayBerneParam gayBerneParam = gayBerneData->getData();
195                  currShape = new Ellipsoid(V3Zero,
196                                            gayBerneParam.GB_l / 2.0,
197                                            gayBerneParam.GB_d / 2.0,
198                                            Mat3x3d::identity());
199                } else {
200                  sprintf( painCave.errMsg,
201                           "Can not cast GenericData to GayBerneParam\n");
202                  painCave.severity = OOPSE_ERROR;
203                  painCave.isFatal = 1;
204                  simError();  
205                }
206              } else {
207                sprintf( painCave.errMsg, "Can not find Parameters for GayBerne\n");
208                painCave.severity = OOPSE_ERROR;
209                painCave.isFatal = 1;
210                simError();    
211              }
212            } else {
213              if (atomType->isLennardJones()){
214                GenericData* data = atomType->getPropertyByName("LennardJones");
215                if (data != NULL) {
216                  LJParamGenericData* ljData = dynamic_cast<LJParamGenericData*>(data);
217                  if (ljData != NULL) {
218                    LJParam ljParam = ljData->getData();
219                    currShape = new Sphere(atom->getPos(), 2.0);
220                  } else {
221                    sprintf( painCave.errMsg,
222                             "Can not cast GenericData to LJParam\n");
223                    painCave.severity = OOPSE_ERROR;
224                    painCave.isFatal = 1;
225                    simError();          
226                  }      
227                }
228              } else {
229                int aNum = etab.GetAtomicNum((atom->getType()).c_str());
230                if (aNum != 0) {
231                  currShape = new Sphere(atom->getPos(), 2.0);
232                } else {
233                  sprintf( painCave.errMsg,
234                           "Could not find atom type in default element.txt\n");
235                  painCave.severity = OOPSE_ERROR;
236                  painCave.isFatal = 1;
237                  simError();          
238                }
239              }
240            }
241          }
242          HydroProp* currHydroProp = currShape->getHydroProp(1.0,simParams->getTargetTemp());
243          std::map<std::string, HydroProp*>::iterator iter = hydroPropMap.find(integrableObject->getType());
244          if (iter != hydroPropMap.end())
245            hydroProps_.push_back(iter->second);
246          else {
247            currHydroProp->complete();
248            hydroPropMap.insert(std::map<std::string, HydroProp*>::value_type(integrableObject->getType(), currHydroProp));
249            hydroProps_.push_back(currHydroProp);
250          }
251        }
252      }
253    }
254
255    /* Compute hull first time through to get the area of t=0*/
256
257    //Build a vector of integrable objects to determine if the are surface atoms
258    for (mol = info_->beginMolecule(i); mol != NULL; mol = info_->nextMolecule(i)) {          
259      for (integrableObject = mol->beginIntegrableObject(j); integrableObject != NULL;
120             integrableObject = mol->nextIntegrableObject(j)) {  
121          localSites_.push_back(integrableObject);
122        }
123 <    }
264 <
265 <
123 >    }  
124    }  
267
268  std::map<std::string, HydroProp*> SMIPDForceManager::parseFrictionFile(const std::string& filename) {
269    std::map<std::string, HydroProp*> props;
270    std::ifstream ifs(filename.c_str());
271    if (ifs.is_open()) {
272      
273    }
274    
275    const unsigned int BufferSize = 65535;
276    char buffer[BufferSize];  
277    while (ifs.getline(buffer, BufferSize)) {
278      HydroProp* currProp = new HydroProp(buffer);
279      props.insert(std::map<std::string, HydroProp*>::value_type(currProp->getName(), currProp));
280    }
281
282    return props;
283  }
125    
126    void SMIPDForceManager::postCalculation(bool needStress){
127      SimInfo::MoleculeIterator i;
128      Molecule::IntegrableObjectIterator  j;
129      Molecule* mol;
130      StuntDouble* integrableObject;
290    RealType mass;
291    Vector3d pos;
292    Vector3d frc;
293    Mat3x3d A;
294    Mat3x3d Atrans;
295    Vector3d Tb;
296    Vector3d ji;
297    unsigned int index = 0;
298    int fdf;
299  
300    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();
308 <
309 <    
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 +    // Generate all of the necessary random forces
142 +    std::vector<Vector3d>  randNums = genTriangleForces(nTriangles, variance_);
143  
144 <
145 <     /* Compute variance for random forces */
316 <  
317 <
318 <
319 <
320 <    std::vector<RealType>  randNums = genTriangleForces(nTriangles, 1.0);
321 <
322 <    /* Loop over the mesh faces and apply random force to each of the faces*/
323 <    
324 <    
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        RealType thisArea = thisTriangle.getArea();
333      // RealType sigma_t = sqrt(NumericConstant::PI/2.0)*((targetPressure_)*thisArea) /OOPSEConstant::energyConvert;
334      // gamma_t_ = (NumericConstant::PI * targetPressure_* targetPressure_ * thisArea * thisArea * simParams->getDt()) /(4.0 * OOPSEConstant::kB*simParams->getTargetTemp());
335
336      /* Get Random Force */
154        Vector3d unitNormal = thisTriangle.getNormal();
155        unitNormal.normalize();
339      //Vector3d randomForce = -randNums[thisNumber] * sigma_t * unitNormal;
156        Vector3d centroid = thisTriangle.getCentroid();
157        Vector3d facetVel = thisTriangle.getFacetVelocity();
342      RealType hydroLength = thisTriangle.getIncircleRadius()*2.0/3.14;
158  
159 <      RealType f_normal = simParams->getViscosity()*hydroLength*1.439326479e4*OOPSEConstant::energyConvert;
345 <      RealType extPressure = -(targetPressure_ * thisArea);
346 <      RealType randomForce = randNums[thisNumber] * f_normal * OOPSEConstant::kb*simParams->getTargetTemp()/simParams->getDt();
347 <      RealType dragForce = -f_normal * dot(facetVel, unitNormal);      
348 <      Vector3d langevinForce = (extPressure + randomForce + dragForce) * unitNormal;
349 <      
350 <      //      Vector3d dragForce = - gamma_t_ * dot(facetVel, unitNormal) * unitNormal / OOPSEConstant::energyConvert;
351 <      
352 <      //std::cout << "randomForce " << randomForce << " dragForce " << dragForce <<  " hydro  " << hydroLength << std::endl;
159 >      Mat3x3d hydroTensor = thisTriangle.computeHydrodynamicTensor(viscosity_);
160  
161 +      hydroTensor *= OOPSEConstant::viscoConvert;
162 +      Mat3x3d S;
163 +      CholeskyDecomposition(hydroTensor, S);
164  
165 <      for (vertex = vertexSDs.begin(); vertex != vertexSDs.end(); ++vertex){
166 <        if ((*vertex) != NULL){
167 <          // mass = integrableObject->getMass();
358 <          Vector3d vertexForce = langevinForce/3.0;
359 <          (*vertex)->addFrc(vertexForce);
165 >      Vector3d extPressure = -unitNormal*(targetPressure_ * thisArea)/OOPSEConstant::energyConvert;      
166 >      Vector3d randomForce = S * randNums[thisFacet++];
167 >      Vector3d dragForce = -hydroTensor * facetVel;
168  
169 <          if ((*vertex)->isDirectional()){
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 +          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 367 | Line 181 | namespace oopse {
181          }  
182        }
183      }
370
371    /* Now loop over all surface particles and apply the drag*/
372    /*
373    std::vector<StuntDouble*> surfaceSDs = surfaceMesh_->getSurfaceAtoms();
374    for (vertex = surfaceSDs.begin(); vertex != surfaceSDs.end(); ++vertex){
375      integrableObject = *vertex;
376      mass = integrableObject->getMass();
377      if (integrableObject->isDirectional()){
378        
379        // preliminaries for directional objects:
380        
381        A = integrableObject->getA();
382        Atrans = A.transpose();
383        Vector3d rcrLab = Atrans * hydroProps_[index]->getCOR();  
384        //apply random force and torque at center of resistance
385        Mat3x3d I = integrableObject->getI();
386        Vector3d omegaBody;
387        
388        // What remains contains velocity explicitly, but the velocity required
389        // is at the full step: v(t + h), while we have initially the velocity
390        // at the half step: v(t + h/2).  We need to iterate to converge the
391        // friction force and friction torque vectors.
392        
393        // this is the velocity at the half-step:
184          
185 <        Vector3d vel =integrableObject->getVel();
186 <        Vector3d angMom = integrableObject->getJ();
397 <        
398 <        //estimate velocity at full-step using everything but friction forces:          
399 <        
400 <        frc = integrableObject->getFrc();
401 <        Vector3d velStep = vel + (dt2_ /mass * OOPSEConstant::energyConvert) * frc;
402 <        
403 <        Tb = integrableObject->lab2Body(integrableObject->getTrq());
404 <        Vector3d angMomStep = angMom + (dt2_ * OOPSEConstant::energyConvert) * Tb;                            
405 <        
406 <        Vector3d omegaLab;
407 <        Vector3d vcdLab;
408 <        Vector3d vcdBody;
409 <        Vector3d frictionForceBody;
410 <        Vector3d frictionForceLab(0.0);
411 <        Vector3d oldFFL;  // used to test for convergence
412 <        Vector3d frictionTorqueBody(0.0);
413 <        Vector3d oldFTB;  // used to test for convergence
414 <        Vector3d frictionTorqueLab;
415 <        RealType fdot;
416 <        RealType tdot;
185 >    veloMunge->removeComDrift();
186 >    veloMunge->removeAngularDrift();
187  
418        //iteration starts here:
419        
420        for (int k = 0; k < maxIterNum_; k++) {
421          
422          if (integrableObject->isLinear()) {
423            int linearAxis = integrableObject->linearAxis();
424            int l = (linearAxis +1 )%3;
425            int m = (linearAxis +2 )%3;
426            omegaBody[l] = angMomStep[l] /I(l, l);
427            omegaBody[m] = angMomStep[m] /I(m, m);
428            
429          } else {
430            omegaBody[0] = angMomStep[0] /I(0, 0);
431            omegaBody[1] = angMomStep[1] /I(1, 1);
432            omegaBody[2] = angMomStep[2] /I(2, 2);
433          }
434          
435          omegaLab = Atrans * omegaBody;
436          
437          // apply friction force and torque at center of resistance
438          
439          vcdLab = velStep + cross(omegaLab, rcrLab);      
440          vcdBody = A * vcdLab;
441          frictionForceBody = -(hydroProps_[index]->getXitt() * vcdBody + hydroProps_[index]->getXirt() * omegaBody);
442          oldFFL = frictionForceLab;
443          frictionForceLab = Atrans * frictionForceBody;
444          oldFTB = frictionTorqueBody;
445          frictionTorqueBody = -(hydroProps_[index]->getXitr() * vcdBody + hydroProps_[index]->getXirr() * omegaBody);
446          frictionTorqueLab = Atrans * frictionTorqueBody;
447          
448          // re-estimate velocities at full-step using friction forces:
449              
450          velStep = vel + (dt2_ / mass * OOPSEConstant::energyConvert) * (frc + frictionForceLab);
451          angMomStep = angMom + (dt2_ * OOPSEConstant::energyConvert) * (Tb + frictionTorqueBody);
452
453          // check for convergence (if the vectors have converged, fdot and tdot will both be 1.0):
454              
455          fdot = dot(frictionForceLab, oldFFL) / frictionForceLab.lengthSquare();
456          tdot = dot(frictionTorqueBody, oldFTB) / frictionTorqueBody.lengthSquare();
457          
458          if (fabs(1.0 - fdot) <= forceTolerance_ && fabs(1.0 - tdot) <= forceTolerance_)
459            break; // iteration ends here
460        }
461        
462        integrableObject->addFrc(frictionForceLab);
463        integrableObject->addTrq(frictionTorqueLab + cross(rcrLab, frictionForceLab));
464
465            
466      } else {
467        //spherical atom
468
469        // What remains contains velocity explicitly, but the velocity required
470        // is at the full step: v(t + h), while we have initially the velocity
471        // at the half step: v(t + h/2).  We need to iterate to converge the
472        // friction force vector.
473        
474        // this is the velocity at the half-step:
475        
476        Vector3d vel =integrableObject->getVel();
477        
478        //estimate velocity at full-step using everything but friction forces:          
479        
480        frc = integrableObject->getFrc();
481        Vector3d velStep = vel + (dt2_ / mass * OOPSEConstant::energyConvert) * frc;
482        
483        Vector3d frictionForce(0.0);
484        Vector3d oldFF;  // used to test for convergence
485        RealType fdot;
486        
487        //iteration starts here:
488        
489        for (int k = 0; k < maxIterNum_; k++) {
490          
491          oldFF = frictionForce;                            
492          frictionForce = -hydroProps_[index]->getXitt() * velStep;
493          //frictionForce = -gamma_t*velStep;
494          // re-estimate velocities at full-step using friction forces:
495          
496          velStep = vel + (dt2_ / mass * OOPSEConstant::energyConvert) * (frc + frictionForce);
497          
498          // check for convergence (if the vector has converged, fdot will be 1.0):
499          
500          fdot = dot(frictionForce, oldFF) / frictionForce.lengthSquare();
501          
502          if (fabs(1.0 - fdot) <= forceTolerance_)
503            break; // iteration ends here
504        }
505        
506        integrableObject->addFrc(frictionForce);
507        
508        
509      }
510  
511      
512  }
513    */
188      Snapshot* currSnapshot = info_->getSnapshotManager()->getCurrentSnapshot();
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      
522    Vector<RealType, 6> Z;
523    Vector<RealType, 6> generalForce;
524    
525
526    Z[0] = randNumGen_.randNorm(0, variance);
527    Z[1] = randNumGen_.randNorm(0, variance);
528    Z[2] = randNumGen_.randNorm(0, variance);
529    Z[3] = randNumGen_.randNorm(0, variance);
530    Z[4] = randNumGen_.randNorm(0, variance);
531    Z[5] = randNumGen_.randNorm(0, variance);
532    
533    generalForce = hydroProps_[index]->getS()*Z;
534    
535    force[0] = generalForce[0];
536    force[1] = generalForce[1];
537    force[2] = generalForce[2];
538    torque[0] = generalForce[3];
539    torque[1] = generalForce[4];
540    torque[2] = generalForce[5];
541    
542 }
543  std::vector<RealType> SMIPDForceManager::genTriangleForces(int nTriangles, RealType variance) {
544
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 <
550 <
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));    
209 <        gaussRand[i] = 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 <  
572 <    for (int i = 0; i < nTriangles; i++) {
573 <      gaussRand[i] = gaussRand[i] * variance;
574 <    }
575 <  
228 >    
229      return gaussRand;
230    }
578
579
580
581
582
231   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines