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 3481 by gezelter, Wed Nov 26 14:26:17 2008 UTC vs.
Revision 3504 by gezelter, Wed May 13 22:27:29 2009 UTC

# Line 41 | Line 41
41   #include <fstream>
42   #include <iostream>
43   #include "integrators/SMIPDForceManager.hpp"
44 + #include "math/CholeskyDecomposition.hpp"
45   #include "utils/OOPSEConstant.hpp"
46   #include "math/ConvexHull.hpp"
47   #include "math/Triangle.hpp"
48  
49   namespace oopse {
50 <  
50 >
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      
60      /* Check that the simulation has target pressure and target
61 <       temperature set*/
61 >       temperature set */
62      
63      if (!simParams->haveTargetTemp()) {
64        sprintf(painCave.errMsg,
# Line 104 | Line 106 | namespace oopse {
106    
107      variance_ = 2.0 * OOPSEConstant::kb * targetTemp_ / dt_;
108  
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;              
114 >    Molecule::IntegrableObjectIterator  j;
115  
112    // Build a vector of integrable objects to determine if the are
113    // surface atoms
114
116      for (mol = info_->beginMolecule(i); mol != NULL;
117           mol = info_->nextMolecule(i)) {          
118        for (integrableObject = mol->beginIntegrableObject(j);
# Line 121 | Line 122 | namespace oopse {
122        }
123      }  
124    }  
125 <  
125 >  
126    void SMIPDForceManager::postCalculation(bool needStress){
127      SimInfo::MoleculeIterator i;
128      Molecule::IntegrableObjectIterator  j;
129      Molecule* mol;
130      StuntDouble* integrableObject;
131 <  
131 >  
132      // Compute surface Mesh
133      surfaceMesh_->computeHull(localSites_);
134 <    
134 >
135      // Get total area and number of surface stunt doubles
136      RealType area = surfaceMesh_->getArea();
137 <    int nSurfaceSDs = surfaceMesh_->getNs();        
137 >    int nSurfaceSDs = surfaceMesh_->getNs();
138      std::vector<Triangle> sMesh = surfaceMesh_->getMesh();
139      int nTriangles = sMesh.size();
140 <        
140 >
141      // Generate all of the necessary random forces
142 <    std::vector<RealType>  randNums = genTriangleForces(nTriangles, variance_);
142 >    std::vector<Vector3d>  randNums = genTriangleForces(nTriangles, variance_);
143  
144 <    // Loop over the mesh faces and apply random force to each of the faces
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;
# Line 151 | Line 153 | namespace oopse {
153        RealType thisArea = thisTriangle.getArea();
154        Vector3d unitNormal = thisTriangle.getNormal();
155        unitNormal.normalize();
154
156        Vector3d centroid = thisTriangle.getCentroid();
157        Vector3d facetVel = thisTriangle.getFacetVelocity();
157      RealType hydroLength = thisTriangle.getIncircleRadius() * 2.0 /
158        NumericConstant::PI;
159      
160      // gamma is the drag coefficient normal to the face of the triangle      
161      RealType gamma = viscosity_ * hydroLength *
162        OOPSEConstant::viscoConvert;
158  
159 <      RealType extPressure = - (targetPressure_ * thisArea) /
165 <        OOPSEConstant::energyConvert;
159 >      Mat3x3d hydroTensor = thisTriangle.computeHydrodynamicTensor(viscosity_);
160  
161 <      RealType randomForce = randNums[thisNumber++] * sqrt(gamma);
162 <      RealType dragForce = -gamma * dot(facetVel, unitNormal);
161 >      hydroTensor *= OOPSEConstant::viscoConvert;
162 >      Mat3x3d S;
163 >      CholeskyDecomposition(hydroTensor, S);
164  
165 <      Vector3d langevinForce = (extPressure + randomForce + dragForce) * unitNormal;
166 <      
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) {
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()) {
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 182 | Line 181 | namespace oopse {
181          }  
182        }
183      }
184 <    
184 >        
185 >    veloMunge->removeComDrift();
186 >    veloMunge->removeAngularDrift();
187 >
188      Snapshot* currSnapshot = info_->getSnapshotManager()->getCurrentSnapshot();
189      currSnapshot->setVolume(surfaceMesh_->getVolume());    
190      ForceManager::postCalculation(needStress);  
191    }
192  
193 <  std::vector<RealType> SMIPDForceManager::genTriangleForces(int nTriangles,
194 <                                                             RealType variance) {
195 <
193 >  
194 >  std::vector<Vector3d> SMIPDForceManager::genTriangleForces(int nTriangles,
195 >                                                             RealType variance)
196 >  {
197 >    
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 <  
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] = randNumGen_.randNorm(0.0, variance);
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_REALTYPE, 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_REALTYPE, 0, MPI_COMM_WORLD);
225 >      MPI_Bcast(&gaussRand[0], nTriangles*3, MPI_REALTYPE, 0, MPI_COMM_WORLD);
226      }
227   #endif
228 <  
228 >    
229      return gaussRand;
230    }
231   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines