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 3463 by chuckv, Thu Oct 16 18:25:36 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();
59      
62    
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();
81 >      // Convert pressure from atm -> amu/(fs^2*Ang)
82 >      targetPressure_ = simParams->getTargetPressure() /
83 >        OOPSEConstant::pressureConvert;
84      }
84
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 +    
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 <
110 <    // Build the hydroProp map:
96 <    std::map<std::string, HydroProp*> hydroPropMap;
97 <
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;
105 <         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;
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(simParams->getViscosity(),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;
120             integrableObject = mol->nextIntegrableObject(j)) {  
121          localSites_.push_back(integrableObject);
122        }
123 <    }
243 <
244 <    surfaceMesh_->computeHull(localSites_);
245 <    Area0_ = surfaceMesh_->getArea();
246 <    variance_ = 2.0 * OOPSEConstant::kb*simParams->getTargetTemp()/simParams->getDt();
247 <    
123 >    }  
124    }  
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  }
125    
126    void SMIPDForceManager::postCalculation(bool needStress){
127      SimInfo::MoleculeIterator i;
128      Molecule::IntegrableObjectIterator  j;
129      Molecule* mol;
130      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;
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();
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 <     /* Compute variance for random forces */
142 <    
143 <     RealType TD_variance = sqrt(2.0*NumericConstant::PI)*((targetPressure_/OOPSEConstant::pressureConvert)*area/nSurfaceSDs)
144 <       /OOPSEConstant::energyConvert;
145 <    
146 <    std::vector<Triangle*> sMesh = surfaceMesh_->getMesh();
297 <    std::vector<RealType>  randNums = genTriangleForces(sMesh.size(),TD_variance);
298 <    
299 <    /* Loop over the mesh faces and apply random force to each of the faces*/
300 <    
301 <    
302 <    std::vector<Triangle*>::iterator face;
141 >    // Generate all of the necessary random forces
142 >    std::vector<Vector3d>  randNums = genTriangleForces(nTriangles, variance_);
143 >
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 <      
154 <      /* Get Random Force */
311 <      Vector3d unitNormal = thisTriangle->getNormal();
151 >      Triangle thisTriangle = *face;
152 >      std::vector<StuntDouble*> vertexSDs = thisTriangle.getVertices();
153 >      RealType thisArea = thisTriangle.getArea();
154 >      Vector3d unitNormal = thisTriangle.getNormal();
155        unitNormal.normalize();
156 <      Vector3d randomForce = -randNums[thisNumber] * unitNormal;
157 <      Vector3d centroid = thisTriangle->getCentroid();
156 >      Vector3d centroid = thisTriangle.getCentroid();
157 >      Vector3d facetVel = thisTriangle.getFacetVelocity();
158  
159 <      for (vertex = vertexSDs.begin(); vertex != vertexSDs.end(); ++vertex){
159 >      Mat3x3d hydroTensor = thisTriangle.computeHydrodynamicTensor(viscosity_);
160  
161 <         // mass = integrableObject->getMass();
162 <        Vector3d vertexForce = randomForce/3.0;
163 <        (*vertex)->addFrc(vertexForce);
321 <        if (integrableObject->isDirectional()){
322 <          Vector3d vertexPos = (*vertex)->getPos();
323 <          Vector3d vertexCentroidVector = vertexPos - centroid;
324 <          (*vertex)->addTrq(cross(vertexCentroidVector,vertexForce));
325 <        }
326 <          
327 <      }
328 <    }
161 >      hydroTensor *= OOPSEConstant::viscoConvert;
162 >      Mat3x3d S;
163 >      CholeskyDecomposition(hydroTensor, S);
164  
165 <    /* Now loop over all surface particles and apply the drag*/
165 >      Vector3d extPressure = -unitNormal*(targetPressure_ * thisArea)/OOPSEConstant::energyConvert;      
166 >      Vector3d randomForce = S * randNums[thisFacet++];
167 >      Vector3d dragForce = -hydroTensor * facetVel;
168  
169 <    std::vector<StuntDouble*> surfaceSDs = surfaceMesh_->getSurfaceAtoms();
333 <    for (vertex = surfaceSDs.begin(); vertex != surfaceSDs.end(); ++vertex){
334 <      integrableObject = *vertex;
335 <      mass = integrableObject->getMass();
336 <      if (integrableObject->isDirectional()){
337 <        
338 <        // preliminaries for directional objects:
339 <        
340 <        A = integrableObject->getA();
341 <        Atrans = A.transpose();
342 <        Vector3d rcrLab = Atrans * hydroProps_[index]->getCOR();  
343 <        //apply random force and torque at center of resistance
169 >      Vector3d langevinForce = (extPressure + randomForce + dragForce);
170  
171 <        Vector3d randomForceBody;
172 <        Vector3d randomTorqueBody;
173 <        genRandomForceAndTorque(randomForceBody, randomTorqueBody, index, variance_);
174 <        Vector3d randomForceLab = Atrans * randomForceBody;
175 <        Vector3d randomTorqueLab = Atrans * randomTorqueBody;
176 <        integrableObject->addFrc(randomForceLab);            
177 <        integrableObject->addTrq(randomTorqueLab + cross(rcrLab, randomForceLab ));            
178 <        
179 <
354 <        
355 <        Mat3x3d I = integrableObject->getI();
356 <        Vector3d omegaBody;
357 <        
358 <        // What remains contains velocity explicitly, but the velocity required
359 <        // is at the full step: v(t + h), while we have initially the velocity
360 <        // at the half step: v(t + h/2).  We need to iterate to converge the
361 <        // friction force and friction torque vectors.
362 <        
363 <        // this is the velocity at the half-step:
364 <        
365 <        Vector3d vel =integrableObject->getVel();
366 <        Vector3d angMom = integrableObject->getJ();
367 <        
368 <        //estimate velocity at full-step using everything but friction forces:          
369 <        
370 <        frc = integrableObject->getFrc();
371 <        Vector3d velStep = vel + (dt2_ /mass * OOPSEConstant::energyConvert) * frc;
372 <        
373 <        Tb = integrableObject->lab2Body(integrableObject->getTrq());
374 <        Vector3d angMomStep = angMom + (dt2_ * OOPSEConstant::energyConvert) * Tb;                            
375 <        
376 <        Vector3d omegaLab;
377 <        Vector3d vcdLab;
378 <        Vector3d vcdBody;
379 <        Vector3d frictionForceBody;
380 <        Vector3d frictionForceLab(0.0);
381 <        Vector3d oldFFL;  // used to test for convergence
382 <        Vector3d frictionTorqueBody(0.0);
383 <        Vector3d oldFTB;  // used to test for convergence
384 <        Vector3d frictionTorqueLab;
385 <        RealType fdot;
386 <        RealType tdot;
387 <
388 <        //iteration starts here:
389 <        
390 <        for (int k = 0; k < maxIterNum_; k++) {
391 <          
392 <          if (integrableObject->isLinear()) {
393 <            int linearAxis = integrableObject->linearAxis();
394 <            int l = (linearAxis +1 )%3;
395 <            int m = (linearAxis +2 )%3;
396 <            omegaBody[l] = angMomStep[l] /I(l, l);
397 <            omegaBody[m] = angMomStep[m] /I(m, m);
398 <            
399 <          } else {
400 <            omegaBody[0] = angMomStep[0] /I(0, 0);
401 <            omegaBody[1] = angMomStep[1] /I(1, 1);
402 <            omegaBody[2] = angMomStep[2] /I(2, 2);
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));
180            }
181 <          
405 <          omegaLab = Atrans * omegaBody;
406 <          
407 <          // apply friction force and torque at center of resistance
408 <          
409 <          vcdLab = velStep + cross(omegaLab, rcrLab);      
410 <          vcdBody = A * vcdLab;
411 <          frictionForceBody = -(hydroProps_[index]->getXitt() * vcdBody + hydroProps_[index]->getXirt() * omegaBody);
412 <          oldFFL = frictionForceLab;
413 <          frictionForceLab = Atrans * frictionForceBody;
414 <          oldFTB = frictionTorqueBody;
415 <          frictionTorqueBody = -(hydroProps_[index]->getXitr() * vcdBody + hydroProps_[index]->getXirr() * omegaBody);
416 <          frictionTorqueLab = Atrans * frictionTorqueBody;
417 <          
418 <          // re-estimate velocities at full-step using friction forces:
419 <              
420 <          velStep = vel + (dt2_ / mass * OOPSEConstant::energyConvert) * (frc + frictionForceLab);
421 <          angMomStep = angMom + (dt2_ * OOPSEConstant::energyConvert) * (Tb + frictionTorqueBody);
422 <
423 <          // check for convergence (if the vectors have converged, fdot and tdot will both be 1.0):
424 <              
425 <          fdot = dot(frictionForceLab, oldFFL) / frictionForceLab.lengthSquare();
426 <          tdot = dot(frictionTorqueBody, oldFTB) / frictionTorqueBody.lengthSquare();
427 <          
428 <          if (fabs(1.0 - fdot) <= forceTolerance_ && fabs(1.0 - tdot) <= forceTolerance_)
429 <            break; // iteration ends here
430 <        }
431 <        
432 <        integrableObject->addFrc(frictionForceLab);
433 <        integrableObject->addTrq(frictionTorqueLab + cross(rcrLab, frictionForceLab));
434 <
435 <            
436 <      } else {
437 <        //spherical atom
438 <
439 <        Vector3d randomForce;
440 <        Vector3d randomTorque;
441 <        genRandomForceAndTorque(randomForce, randomTorque, index, variance_);
442 <        integrableObject->addFrc(randomForce);  
443 <        
444 <        // What remains contains velocity explicitly, but the velocity required
445 <        // is at the full step: v(t + h), while we have initially the velocity
446 <        // at the half step: v(t + h/2).  We need to iterate to converge the
447 <        // friction force vector.
448 <        
449 <        // this is the velocity at the half-step:
450 <        
451 <        Vector3d vel =integrableObject->getVel();
452 <        
453 <        //estimate velocity at full-step using everything but friction forces:          
454 <        
455 <        frc = integrableObject->getFrc();
456 <        Vector3d velStep = vel + (dt2_ / mass * OOPSEConstant::energyConvert) * frc;
457 <        
458 <        Vector3d frictionForce(0.0);
459 <        Vector3d oldFF;  // used to test for convergence
460 <        RealType fdot;
461 <        
462 <        //iteration starts here:
463 <        
464 <        for (int k = 0; k < maxIterNum_; k++) {
465 <          
466 <          oldFF = frictionForce;                            
467 <          frictionForce = -hydroProps_[index]->getXitt() * velStep;
468 <          
469 <          // re-estimate velocities at full-step using friction forces:
470 <          
471 <          velStep = vel + (dt2_ / mass * OOPSEConstant::energyConvert) * (frc + frictionForce);
472 <          
473 <          // check for convergence (if the vector has converged, fdot will be 1.0):
474 <          
475 <          fdot = dot(frictionForce, oldFF) / frictionForce.lengthSquare();
476 <          
477 <          if (fabs(1.0 - fdot) <= forceTolerance_)
478 <            break; // iteration ends here
479 <        }
480 <        
481 <        integrableObject->addFrc(frictionForce);
482 <        
483 <        
181 >        }  
182        }
183 <      
184 <      
185 <    }
183 >    }
184 >        
185 >    veloMunge->removeComDrift();
186 >    veloMunge->removeAngularDrift();
187 >
188      Snapshot* currSnapshot = info_->getSnapshotManager()->getCurrentSnapshot();
189 <    currSnapshot->setVolume(surfaceMesh_->getVolume());
490 <    
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      
497    Vector<RealType, 6> Z;
498    Vector<RealType, 6> generalForce;
499    
500
501    Z[0] = randNumGen_.randNorm(0, variance);
502    Z[1] = randNumGen_.randNorm(0, variance);
503    Z[2] = randNumGen_.randNorm(0, variance);
504    Z[3] = randNumGen_.randNorm(0, variance);
505    Z[4] = randNumGen_.randNorm(0, variance);
506    Z[5] = randNumGen_.randNorm(0, variance);
507    
508    generalForce = hydroProps_[index]->getS()*Z;
509    
510    force[0] = generalForce[0];
511    force[1] = generalForce[1];
512    force[2] = generalForce[2];
513    torque[0] = generalForce[3];
514    torque[1] = generalForce[4];
515    torque[2] = generalForce[5];
516    
517 }
518  std::vector<RealType> SMIPDForceManager::genTriangleForces(int nTriangles, RealType variance) {
519
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 <
525 <
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 <
546 <    for (int i = 0; i < nTriangles; i++) {
547 <      gaussRand[i] = gaussRand[i] * variance;
548 <    }
549 <
228 >    
229      return gaussRand;
230    }
552
553
554
555
556
231   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines