ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-4/src/integrators/LDForceManager.cpp
Revision: 2767
Committed: Wed May 24 16:18:00 2006 UTC (18 years, 1 month ago) by tim
File size: 18371 byte(s)
Log Message:
fix a bug in parsing HydroProp file

File Contents

# User Rev Content
1 tim 2611 /*
2     * Copyright (c) 2005 The University of Notre Dame. All Rights Reserved.
3     *
4     * The University of Notre Dame grants you ("Licensee") a
5     * non-exclusive, royalty free, license to use, modify and
6     * redistribute this software in source and binary code form, provided
7     * that the following conditions are met:
8     *
9     * 1. Acknowledgement of the program authors must be made in any
10     * publication of scientific results based in part on use of the
11     * program. An acceptable form of acknowledgement is citation of
12     * the article in which the program was described (Matthew
13     * A. Meineke, Charles F. Vardeman II, Teng Lin, Christopher
14     * J. Fennell and J. Daniel Gezelter, "OOPSE: An Object-Oriented
15     * Parallel Simulation Engine for Molecular Dynamics,"
16     * J. Comput. Chem. 26, pp. 252-271 (2005))
17     *
18     * 2. Redistributions of source code must retain the above copyright
19     * notice, this list of conditions and the following disclaimer.
20     *
21     * 3. Redistributions in binary form must reproduce the above copyright
22     * notice, this list of conditions and the following disclaimer in the
23     * documentation and/or other materials provided with the
24     * distribution.
25     *
26     * This software is provided "AS IS," without a warranty of any
27     * kind. All express or implied conditions, representations and
28     * warranties, including any implied warranty of merchantability,
29     * fitness for a particular purpose or non-infringement, are hereby
30     * excluded. The University of Notre Dame and its licensors shall not
31     * be liable for any damages suffered by licensee as a result of
32     * using, modifying or distributing the software or its
33     * derivatives. In no event will the University of Notre Dame or its
34     * licensors be liable for any lost revenue, profit or data, or for
35     * direct, indirect, special, consequential, incidental or punitive
36     * damages, however caused and regardless of the theory of liability,
37     * arising out of the use of or inability to use software, even if the
38     * University of Notre Dame has been advised of the possibility of
39     * such damages.
40     */
41     #include <fstream>
42     #include "integrators/LDForceManager.hpp"
43     #include "math/CholeskyDecomposition.hpp"
44 tim 2632 #include "utils/OOPSEConstant.hpp"
45 gezelter 2752 #include "hydrodynamics/Sphere.hpp"
46     #include "hydrodynamics/Ellipsoid.hpp"
47     #include "openbabel/mol.hpp"
48    
49     using namespace OpenBabel;
50 tim 2611 namespace oopse {
51    
52     LDForceManager::LDForceManager(SimInfo* info) : ForceManager(info){
53     Globals* simParams = info->getSimParams();
54 gezelter 2752
55 gezelter 2733 sphericalBoundaryConditions_ = false;
56     if (simParams->getUseSphericalBoundaryConditions()) {
57     sphericalBoundaryConditions_ = true;
58     if (simParams->haveLangevinBufferRadius()) {
59     langevinBufferRadius_ = simParams->getLangevinBufferRadius();
60     } else {
61     sprintf( painCave.errMsg,
62     "langevinBufferRadius must be specified "
63     "when useSphericalBoundaryConditions is turned on.\n");
64     painCave.severity = OOPSE_ERROR;
65     painCave.isFatal = 1;
66     simError();
67     }
68    
69     if (simParams->haveFrozenBufferRadius()) {
70     frozenBufferRadius_ = simParams->getFrozenBufferRadius();
71     } else {
72     sprintf( painCave.errMsg,
73     "frozenBufferRadius must be specified "
74     "when useSphericalBoundaryConditions is turned on.\n");
75     painCave.severity = OOPSE_ERROR;
76     painCave.isFatal = 1;
77     simError();
78     }
79 tim 2611
80 gezelter 2733 if (frozenBufferRadius_ < langevinBufferRadius_) {
81     sprintf( painCave.errMsg,
82     "frozenBufferRadius has been set smaller than the "
83     "langevinBufferRadius. This is probably an error.\n");
84     painCave.severity = OOPSE_WARNING;
85     painCave.isFatal = 0;
86     simError();
87     }
88     }
89 gezelter 2752
90     // Build the hydroProp map:
91     std::map<std::string, HydroProp> hydroPropMap;
92    
93 tim 2611 Molecule* mol;
94     StuntDouble* integrableObject;
95 gezelter 2752 SimInfo::MoleculeIterator i;
96     Molecule::IntegrableObjectIterator j;
97     bool needHydroPropFile = false;
98    
99     for (mol = info->beginMolecule(i); mol != NULL;
100     mol = info->nextMolecule(i)) {
101     for (integrableObject = mol->beginIntegrableObject(j);
102     integrableObject != NULL;
103 gezelter 2733 integrableObject = mol->nextIntegrableObject(j)) {
104 gezelter 2752
105     if (integrableObject->isRigidBody()) {
106     RigidBody* rb = static_cast<RigidBody*>(integrableObject);
107     if (rb->getNumAtoms() > 1) needHydroPropFile = true;
108 gezelter 2733 }
109    
110     }
111 tim 2611 }
112 gezelter 2752
113    
114     if (needHydroPropFile) {
115     if (simParams->haveHydroPropFile()) {
116     hydroPropMap = parseFrictionFile(simParams->getHydroPropFile());
117     } else {
118     sprintf( painCave.errMsg,
119     "HydroPropFile must be set to a file name if Langevin\n"
120     "\tDynamics is specified for rigidBodies which contain more\n"
121     "\tthan one atom. To create a HydroPropFile, run \"Hydro\".\n");
122     painCave.severity = OOPSE_ERROR;
123     painCave.isFatal = 1;
124     simError();
125     }
126 tim 2767
127     for (mol = info->beginMolecule(i); mol != NULL;
128     mol = info->nextMolecule(i)) {
129     for (integrableObject = mol->beginIntegrableObject(j);
130     integrableObject != NULL;
131     integrableObject = mol->nextIntegrableObject(j)) {
132    
133     std::map<std::string, HydroProp>::iterator iter = hydroPropMap.find(integrableObject->getType());
134     if (iter != hydroPropMap.end()) {
135     hydroProps_.push_back(iter->second);
136     } else {
137     sprintf( painCave.errMsg,
138     "Can not find resistance tensor for atom [%s]\n", integrableObject->getType().c_str());
139     painCave.severity = OOPSE_ERROR;
140     painCave.isFatal = 1;
141     simError();
142     }
143     }
144 gezelter 2752 }
145     } else {
146    
147     std::map<std::string, HydroProp> hydroPropMap;
148     for (mol = info->beginMolecule(i); mol != NULL;
149     mol = info->nextMolecule(i)) {
150     for (integrableObject = mol->beginIntegrableObject(j);
151     integrableObject != NULL;
152     integrableObject = mol->nextIntegrableObject(j)) {
153     Shape* currShape = NULL;
154     if (integrableObject->isDirectionalAtom()) {
155     DirectionalAtom* dAtom = static_cast<DirectionalAtom*>(integrableObject);
156     AtomType* atomType = dAtom->getAtomType();
157     if (atomType->isGayBerne()) {
158     DirectionalAtomType* dAtomType = dynamic_cast<DirectionalAtomType*>(atomType);
159    
160     GenericData* data = dAtomType->getPropertyByName("GayBerne");
161     if (data != NULL) {
162     GayBerneParamGenericData* gayBerneData = dynamic_cast<GayBerneParamGenericData*>(data);
163    
164     if (gayBerneData != NULL) {
165     GayBerneParam gayBerneParam = gayBerneData->getData();
166     currShape = new Ellipsoid(V3Zero,
167     gayBerneParam.GB_sigma/2.0,
168     gayBerneParam.GB_l2b_ratio*gayBerneParam.GB_sigma/2.0,
169     Mat3x3d::identity());
170     } else {
171     sprintf( painCave.errMsg,
172     "Can not cast GenericData to GayBerneParam\n");
173     painCave.severity = OOPSE_ERROR;
174     painCave.isFatal = 1;
175     simError();
176     }
177     } else {
178     sprintf( painCave.errMsg, "Can not find Parameters for GayBerne\n");
179     painCave.severity = OOPSE_ERROR;
180     painCave.isFatal = 1;
181     simError();
182     }
183     }
184     } else {
185     Atom* atom = static_cast<Atom*>(integrableObject);
186     AtomType* atomType = atom->getAtomType();
187     if (atomType->isLennardJones()){
188     GenericData* data = atomType->getPropertyByName("LennardJones");
189     if (data != NULL) {
190     LJParamGenericData* ljData = dynamic_cast<LJParamGenericData*>(data);
191    
192     if (ljData != NULL) {
193     LJParam ljParam = ljData->getData();
194     currShape = new Sphere(atom->getPos(), ljParam.sigma/2.0);
195     } else {
196     sprintf( painCave.errMsg,
197     "Can not cast GenericData to LJParam\n");
198     painCave.severity = OOPSE_ERROR;
199     painCave.isFatal = 1;
200     simError();
201     }
202     }
203     } else {
204     int obanum = etab.GetAtomicNum((atom->getType()).c_str());
205     if (obanum != 0) {
206     currShape = new Sphere(atom->getPos(), etab.GetVdwRad(obanum));
207     } else {
208     sprintf( painCave.errMsg,
209     "Could not find atom type in default element.txt\n");
210     painCave.severity = OOPSE_ERROR;
211     painCave.isFatal = 1;
212     simError();
213     }
214     }
215     }
216     HydroProps currHydroProp = currShape->getHydroProps(simParams->getViscosity(),simParams->getTargetTemp());
217     std::map<std::string, HydroProp>::iterator iter = hydroPropMap.find(integrableObject->getType());
218     if (iter != hydroPropMap.end())
219     hydroProps_.push_back(iter->second);
220     else {
221     HydroProp myProp;
222     myProp.cor = V3Zero;
223     for (int i1 = 0; i1 < 3; i1++) {
224     for (int j1 = 0; j1 < 3; j1++) {
225     myProp.Xirtt(i1,j1) = currHydroProp.Xi(i1,j1);
226     myProp.Xirrt(i1,j1) = currHydroProp.Xi(i1,j1+3);
227     myProp.Xirtr(i1,j1) = currHydroProp.Xi(i1+3,j1);
228     myProp.Xirrr(i1,j1) = currHydroProp.Xi(i1+3,j1+3);
229     }
230     }
231     CholeskyDecomposition(currHydroProp.Xi, myProp.S);
232     hydroPropMap.insert(std::map<std::string, HydroProp>::value_type(integrableObject->getType(), myProp));
233     hydroProps_.push_back(myProp);
234     }
235     }
236     }
237     }
238 tim 2632 variance_ = 2.0 * OOPSEConstant::kb*simParams->getTargetTemp()/simParams->getDt();
239 tim 2611 }
240 gezelter 2752
241    
242    
243    
244    
245 tim 2611 std::map<std::string, HydroProp> LDForceManager::parseFrictionFile(const std::string& filename) {
246     std::map<std::string, HydroProp> props;
247     std::ifstream ifs(filename.c_str());
248     if (ifs.is_open()) {
249 gezelter 2733
250 tim 2611 }
251 gezelter 2733
252 tim 2611 const unsigned int BufferSize = 65535;
253     char buffer[BufferSize];
254     while (ifs.getline(buffer, BufferSize)) {
255 gezelter 2733 StringTokenizer tokenizer(buffer);
256     HydroProp currProp;
257     if (tokenizer.countTokens() >= 40) {
258     std::string atomName = tokenizer.nextToken();
259     currProp.cor[0] = tokenizer.nextTokenAsDouble();
260     currProp.cor[1] = tokenizer.nextTokenAsDouble();
261     currProp.cor[2] = tokenizer.nextTokenAsDouble();
262    
263     currProp.Xirtt(0,0) = tokenizer.nextTokenAsDouble();
264     currProp.Xirtt(0,1) = tokenizer.nextTokenAsDouble();
265     currProp.Xirtt(0,2) = tokenizer.nextTokenAsDouble();
266     currProp.Xirtt(1,0) = tokenizer.nextTokenAsDouble();
267     currProp.Xirtt(1,1) = tokenizer.nextTokenAsDouble();
268     currProp.Xirtt(1,2) = tokenizer.nextTokenAsDouble();
269     currProp.Xirtt(2,0) = tokenizer.nextTokenAsDouble();
270     currProp.Xirtt(2,1) = tokenizer.nextTokenAsDouble();
271     currProp.Xirtt(2,2) = tokenizer.nextTokenAsDouble();
272    
273     currProp.Xirrt(0,0) = tokenizer.nextTokenAsDouble();
274     currProp.Xirrt(0,1) = tokenizer.nextTokenAsDouble();
275     currProp.Xirrt(0,2) = tokenizer.nextTokenAsDouble();
276     currProp.Xirrt(1,0) = tokenizer.nextTokenAsDouble();
277     currProp.Xirrt(1,1) = tokenizer.nextTokenAsDouble();
278     currProp.Xirrt(1,2) = tokenizer.nextTokenAsDouble();
279     currProp.Xirrt(2,0) = tokenizer.nextTokenAsDouble();
280     currProp.Xirrt(2,1) = tokenizer.nextTokenAsDouble();
281     currProp.Xirrt(2,2) = tokenizer.nextTokenAsDouble();
282    
283     currProp.Xirtr(0,0) = tokenizer.nextTokenAsDouble();
284     currProp.Xirtr(0,1) = tokenizer.nextTokenAsDouble();
285     currProp.Xirtr(0,2) = tokenizer.nextTokenAsDouble();
286     currProp.Xirtr(1,0) = tokenizer.nextTokenAsDouble();
287     currProp.Xirtr(1,1) = tokenizer.nextTokenAsDouble();
288     currProp.Xirtr(1,2) = tokenizer.nextTokenAsDouble();
289     currProp.Xirtr(2,0) = tokenizer.nextTokenAsDouble();
290     currProp.Xirtr(2,1) = tokenizer.nextTokenAsDouble();
291     currProp.Xirtr(2,2) = tokenizer.nextTokenAsDouble();
292    
293     currProp.Xirrr(0,0) = tokenizer.nextTokenAsDouble();
294     currProp.Xirrr(0,1) = tokenizer.nextTokenAsDouble();
295     currProp.Xirrr(0,2) = tokenizer.nextTokenAsDouble();
296     currProp.Xirrr(1,0) = tokenizer.nextTokenAsDouble();
297     currProp.Xirrr(1,1) = tokenizer.nextTokenAsDouble();
298     currProp.Xirrr(1,2) = tokenizer.nextTokenAsDouble();
299     currProp.Xirrr(2,0) = tokenizer.nextTokenAsDouble();
300     currProp.Xirrr(2,1) = tokenizer.nextTokenAsDouble();
301     currProp.Xirrr(2,2) = tokenizer.nextTokenAsDouble();
302    
303 tim 2759 SquareMatrix<RealType, 6> Xir;
304 gezelter 2733 Xir.setSubMatrix(0, 0, currProp.Xirtt);
305     Xir.setSubMatrix(0, 3, currProp.Xirrt);
306     Xir.setSubMatrix(3, 0, currProp.Xirtr);
307     Xir.setSubMatrix(3, 3, currProp.Xirrr);
308     CholeskyDecomposition(Xir, currProp.S);
309    
310     props.insert(std::map<std::string, HydroProp>::value_type(atomName, currProp));
311     }
312 tim 2611 }
313 gezelter 2733
314 tim 2611 return props;
315     }
316    
317     void LDForceManager::postCalculation() {
318     SimInfo::MoleculeIterator i;
319     Molecule::IntegrableObjectIterator j;
320     Molecule* mol;
321     StuntDouble* integrableObject;
322     Vector3d vel;
323     Vector3d pos;
324     Vector3d frc;
325     Mat3x3d A;
326 tim 2632 Mat3x3d Atrans;
327 tim 2611 Vector3d Tb;
328     Vector3d ji;
329 tim 2759 RealType mass;
330 tim 2611 unsigned int index = 0;
331 gezelter 2733 bool doLangevinForces;
332     bool freezeMolecule;
333     int fdf;
334    
335     fdf = 0;
336 tim 2611 for (mol = info_->beginMolecule(i); mol != NULL; mol = info_->nextMolecule(i)) {
337 gezelter 2766
338     doLangevinForces = true;
339     freezeMolecule = false;
340    
341 gezelter 2733 if (sphericalBoundaryConditions_) {
342    
343     Vector3d molPos = mol->getCom();
344 tim 2759 RealType molRad = molPos.length();
345 gezelter 2733
346     doLangevinForces = false;
347    
348     if (molRad > langevinBufferRadius_) {
349     doLangevinForces = true;
350     freezeMolecule = false;
351     }
352     if (molRad > frozenBufferRadius_) {
353     doLangevinForces = false;
354     freezeMolecule = true;
355     }
356     }
357    
358 gezelter 2752 for (integrableObject = mol->beginIntegrableObject(j); integrableObject != NULL;
359     integrableObject = mol->nextIntegrableObject(j)) {
360 gezelter 2733
361 gezelter 2752 if (freezeMolecule)
362     fdf += integrableObject->freeze();
363    
364     if (doLangevinForces) {
365 tim 2611 vel =integrableObject->getVel();
366     if (integrableObject->isDirectional()){
367 gezelter 2733 //calculate angular velocity in lab frame
368     Mat3x3d I = integrableObject->getI();
369     Vector3d angMom = integrableObject->getJ();
370     Vector3d omega;
371    
372     if (integrableObject->isLinear()) {
373     int linearAxis = integrableObject->linearAxis();
374     int l = (linearAxis +1 )%3;
375     int m = (linearAxis +2 )%3;
376     omega[l] = angMom[l] /I(l, l);
377     omega[m] = angMom[m] /I(m, m);
378    
379     } else {
380     omega[0] = angMom[0] /I(0, 0);
381     omega[1] = angMom[1] /I(1, 1);
382     omega[2] = angMom[2] /I(2, 2);
383     }
384    
385     //apply friction force and torque at center of resistance
386     A = integrableObject->getA();
387     Atrans = A.transpose();
388     Vector3d rcr = Atrans * hydroProps_[index].cor;
389     Vector3d vcdLab = vel + cross(omega, rcr);
390     Vector3d vcdBody = A* vcdLab;
391     Vector3d frictionForceBody = -(hydroProps_[index].Xirtt * vcdBody + hydroProps_[index].Xirrt * omega);
392     Vector3d frictionForceLab = Atrans*frictionForceBody;
393     integrableObject->addFrc(frictionForceLab);
394     Vector3d frictionTorqueBody = - (hydroProps_[index].Xirtr * vcdBody + hydroProps_[index].Xirrr * omega);
395     Vector3d frictionTorqueLab = Atrans*frictionTorqueBody;
396     integrableObject->addTrq(frictionTorqueLab+ cross(rcr, frictionForceLab));
397    
398     //apply random force and torque at center of resistance
399     Vector3d randomForceBody;
400     Vector3d randomTorqueBody;
401     genRandomForceAndTorque(randomForceBody, randomTorqueBody, index, variance_);
402     Vector3d randomForceLab = Atrans*randomForceBody;
403     Vector3d randomTorqueLab = Atrans* randomTorqueBody;
404     integrableObject->addFrc(randomForceLab);
405     integrableObject->addTrq(randomTorqueLab + cross(rcr, randomForceLab ));
406    
407 tim 2611 } else {
408 gezelter 2733 //spherical atom
409     Vector3d frictionForce = -(hydroProps_[index].Xirtt *vel);
410     Vector3d randomForce;
411     Vector3d randomTorque;
412     genRandomForceAndTorque(randomForce, randomTorque, index, variance_);
413    
414     integrableObject->addFrc(frictionForce+randomForce);
415 tim 2611 }
416 gezelter 2752 }
417 gezelter 2733
418 gezelter 2752 ++index;
419 tim 2611
420     }
421 gezelter 2752 }
422 gezelter 2733 info_->setFdf(fdf);
423    
424     ForceManager::postCalculation();
425 tim 2611 }
426    
427 tim 2759 void LDForceManager::genRandomForceAndTorque(Vector3d& force, Vector3d& torque, unsigned int index, RealType variance) {
428 tim 2632
429 tim 2634
430 tim 2759 Vector<RealType, 6> Z;
431     Vector<RealType, 6> generalForce;
432 tim 2632
433    
434 tim 2611 Z[0] = randNumGen_.randNorm(0, variance);
435     Z[1] = randNumGen_.randNorm(0, variance);
436     Z[2] = randNumGen_.randNorm(0, variance);
437     Z[3] = randNumGen_.randNorm(0, variance);
438     Z[4] = randNumGen_.randNorm(0, variance);
439     Z[5] = randNumGen_.randNorm(0, variance);
440 tim 2632
441    
442 tim 2634 generalForce = hydroProps_[index].S*Z;
443 tim 2632
444 tim 2611 force[0] = generalForce[0];
445     force[1] = generalForce[1];
446     force[2] = generalForce[2];
447     torque[0] = generalForce[3];
448     torque[1] = generalForce[4];
449     torque[2] = generalForce[5];
450    
451     }
452    
453     }

Properties

Name Value
svn:executable *