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 3480 by chuckv, Tue Nov 25 16:32:47 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) {
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();
61
59      
63    
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, "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();
# Line 74 | Line 72 | namespace oopse {
72      }
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 <      /* Convert pressure from atm -> amu/(fs^2*Ang)*/
82 <      targetPressure_ = simParams->getTargetPressure()/OOPSEConstant::pressureConvert;
81 >      // Convert pressure from atm -> amu/(fs^2*Ang)
82 >      targetPressure_ = simParams->getTargetPressure() /
83 >        OOPSEConstant::pressureConvert;
84      }
86
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      }
104 <
104 >    
105      dt_ = simParams->getDt();
106 +  
107 +    variance_ = 2.0 * OOPSEConstant::kb * targetTemp_ / dt_;
108  
109 <    
110 <
109 <    //Compute initial hull
110 <    /*
111 <    surfaceMesh_->computeHull(localSites_);
112 <    Area0_ = surfaceMesh_->getArea();
113 <    int nTriangles = surfaceMesh_->getNMeshElements();
114 <    //    variance_ = 2.0 * OOPSEConstant::kb*simParams->getTargetTemp()/simParams->getDt();
115 <    gamma_0_ = (NumericConstant::PI * targetPressure_* targetPressure_ * Area0_ * Area0_ * simParams->getDt()) /
116 <      (4.0 * nTriangles * nTriangles* OOPSEConstant::kb*simParams->getTargetTemp());
117 <    //RealType eta0 = gamma_0/
118 <    */
119 <
120 <
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  
116 <    
117 <
118 <    /* Compute hull first time through to get the area of t=0*/
119 <
130 <    //Build a vector of integrable objects to determine if the are surface atoms
131 <    for (mol = info_->beginMolecule(i); mol != NULL; mol = info_->nextMolecule(i)) {          
132 <      for (integrableObject = mol->beginIntegrableObject(j); integrableObject != NULL;
116 >    for (mol = info_->beginMolecule(i); mol != NULL;
117 >         mol = info_->nextMolecule(i)) {          
118 >      for (integrableObject = mol->beginIntegrableObject(j);
119 >           integrableObject != NULL;
120             integrableObject = mol->nextIntegrableObject(j)) {  
121          localSites_.push_back(integrableObject);
122        }
123 <    }
137 <
138 <
123 >    }  
124    }  
140
141  std::map<std::string, HydroProp*> SMIPDForceManager::parseFrictionFile(const std::string& filename) {
142    std::map<std::string, HydroProp*> props;
143    std::ifstream ifs(filename.c_str());
144    if (ifs.is_open()) {
145      
146    }
147    
148    const unsigned int BufferSize = 65535;
149    char buffer[BufferSize];  
150    while (ifs.getline(buffer, BufferSize)) {
151      HydroProp* currProp = new HydroProp(buffer);
152      props.insert(std::map<std::string, HydroProp*>::value_type(currProp->getName(), currProp));
153    }
154
155    return props;
156  }
125    
126    void SMIPDForceManager::postCalculation(bool needStress){
127      SimInfo::MoleculeIterator i;
128      Molecule::IntegrableObjectIterator  j;
129      Molecule* mol;
130      StuntDouble* integrableObject;
163    RealType mass;
164    Vector3d pos;
165    Vector3d frc;
166    Mat3x3d A;
167    Mat3x3d Atrans;
168    Vector3d Tb;
169    Vector3d ji;
170    unsigned int index = 0;
171    int fdf;
172  
173    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();
181 <
182 <    
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 */
189 <    std::vector<RealType>  randNums = genTriangleForces(nTriangles, 1.0);
190 <
191 <    /* 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;
152        std::vector<StuntDouble*> vertexSDs = thisTriangle.getVertices();
153        RealType thisArea = thisTriangle.getArea();
200      // RealType sigma_t = sqrt(NumericConstant::PI/2.0)*((targetPressure_)*thisArea) /OOPSEConstant::energyConvert;
201      // gamma_t_ = (NumericConstant::PI * targetPressure_* targetPressure_ * thisArea * thisArea * simParams->getDt()) /(4.0 * OOPSEConstant::kB*simParams->getTargetTemp());
202
203      /* Get Random Force */
154        Vector3d unitNormal = thisTriangle.getNormal();
155        unitNormal.normalize();
206      //Vector3d randomForce = -randNums[thisNumber] * sigma_t * unitNormal;
156        Vector3d centroid = thisTriangle.getCentroid();
157        Vector3d facetVel = thisTriangle.getFacetVelocity();
209      RealType hydroLength = thisTriangle.getIncircleRadius()*2.0/NumericConstant::PI;
158  
159 <      RealType f_normal = viscosity_*hydroLength*OOPSEConstant::viscoConvert;
212 <      RealType extPressure = -(targetPressure_ * thisArea)/OOPSEConstant::energyConvert;
213 <      RealType randomForce = randNums[thisNumber++] * sqrt(2.0 * f_normal * OOPSEConstant::kb*targetTemp_/dt_);
159 >      Mat3x3d hydroTensor = thisTriangle.computeHydrodynamicTensor(viscosity_);
160  
161 <      RealType dragForce = -f_normal * dot(facetVel, unitNormal);
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) * unitNormal;
219 <      
220 <      //      Vector3d dragForce = - gamma_t_ * dot(facetVel, unitNormal) * unitNormal / OOPSEConstant::energyConvert;
221 <      
222 <      // std::cout << " " << randomForce << " " << f_normal <<   std::endl;
169 >      Vector3d langevinForce = (extPressure + randomForce + dragForce);
170  
171 <      /* Apply triangle force to stuntdouble vertices */
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);
230 <
231 <          if ((*vertex)->isDirectional()){
232 <
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 237 | Line 181 | namespace oopse {
181          }  
182        }
183      }
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 <  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      
249    Vector<RealType, 6> Z;
250    Vector<RealType, 6> generalForce;
251    
252
253    Z[0] = randNumGen_.randNorm(0, variance);
254    Z[1] = randNumGen_.randNorm(0, variance);
255    Z[2] = randNumGen_.randNorm(0, variance);
256    Z[3] = randNumGen_.randNorm(0, variance);
257    Z[4] = randNumGen_.randNorm(0, variance);
258    Z[5] = randNumGen_.randNorm(0, variance);
259    
260    generalForce = hydroProps_[index]->getS()*Z;
261    
262    force[0] = generalForce[0];
263    force[1] = generalForce[1];
264    force[2] = generalForce[2];
265    torque[0] = generalForce[3];
266    torque[1] = generalForce[4];
267    torque[2] = generalForce[5];
268    
269 }
270  std::vector<RealType> SMIPDForceManager::genTriangleForces(int nTriangles, RealType variance) {
271
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);
276 <
201 >    std::fill(gaussRand.begin(), gaussRand.end(), V3Zero);
202      
278
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 <  
300 <    for (int i = 0; i < nTriangles; i++) {
301 <      gaussRand[i] = gaussRand[i] * variance;
302 <    }
303 <  
228 >    
229      return gaussRand;
230    }
306
307
231   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines