ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libmdtools/Roll.cpp
Revision: 1254
Committed: Wed Jun 9 16:16:33 2004 UTC (20 years, 10 months ago) by tim
File size: 7204 byte(s)
Log Message:
1. adding some useful math classes(Mat3x3d, Vector3d, Quaternion, Euler3)
 these classes use anonymous union and struct to support
 double[3], double[3][3] and double[4]
2. adding roll constraint algorithm

File Contents

# Content
1 #include <cmath>
2 #include "Mat3x3d.hpp"
3 #include "Roll.hpp"
4 #include "SimInfo.hpp"
5
6
7 ////////////////////////////////////////////////////////////////////////////////
8 //Implementation of DCRollAFunctor
9 ////////////////////////////////////////////////////////////////////////////////
10 int DCRollAFunctor::operator()(ConstraintRigidBody* consRB1, ConstraintRigidBody* consRB2){
11 Vector3d posA;
12 Vector3d posB;
13 Vector3d oldPosA;
14 Vector3d oldPosB;
15 Vector3d velA;
16 Vector3d velB;
17 Vector3d pab;
18 Vector3d tempPab;
19 Vector3d rab;
20 Vector3d rma;
21 Vector3d rmb;
22 Vector3d consForce;
23 Vector3d bondDirUnitVec;
24 double dx, dy, dz;
25 double rpab;
26 double rabsq, pabsq, rpabsq;
27 double diffsq;
28 double gab;
29 double dt;
30 double dt2;
31 double rijcDotInvMassVec;
32
33
34 const int conRBMaxIter = 10;
35
36 dt = info->dt;
37 dt2 = dt * dt;
38
39 consRB1->getOldAtomPos(oldPosA.vec);
40 consRB2->getOldAtomPos(oldPosB.vec);
41
42
43 for(int i=0 ; i < conRBMaxIter; i++){
44 consRB1->getCurAtomPos(posA.vec);
45 consRB2->getCurAtomPos(posB.vec);
46
47 pab = posA - posB;
48
49 //periodic boundary condition
50
51 info->wrapVector(pab.vec);
52
53 pabsq = dotProduct(pab, pab);
54
55 rabsq = curPair->getBondLength2();
56 diffsq = rabsq - pabsq;
57
58 if (fabs(diffsq) > (consTolerance * rabsq * 2)){
59 rab = oldPosA - oldPosB;
60 info->wrapVector(rab.vec);
61
62 rpab = dotProduct(rab, pab);
63
64 rpabsq = rpab * rpab;
65
66
67 //if (rpabsq < (rabsq * -diffsq)){
68 // return consFail;
69 //}
70
71 bondDirUnitVec = pab;
72 bondDirUnitVec.normalize();
73
74 getEffInvMassVec(consRB1, bondDirUnitVec, rma);
75
76 getEffInvMassVec(consRB2, -bondDirUnitVec, rmb);
77
78 rijcDotInvMassVec = dotProduct(pab, rma + rmb);
79
80 consForce = diffsq /(2 * dt * dt * rijcDotInvMassVec) * bondDirUnitVec;
81 //integrate consRB1 using constraint force;
82 integrate(consRB1,consForce);
83
84 //integrate consRB2 using constraint force;
85 integrate(consRB2, -consForce);
86
87 }
88 else{
89 if (i ==0)
90 return consAlready;
91 else
92 return consSuccess;
93 }
94 }
95
96 return consExceedMaxIter;
97
98 }
99
100 void DCRollAFunctor::getEffInvMassVec(ConstraintRigidBody* consRB, const Vector3d& bondDir, Vector3d& invMassVec){
101 double invMass;
102 Vector3d tempVec1;
103 Vector3d tempVec2;
104 Vector3d refCoor;
105 Vector3d refCrossBond;
106 Mat3x3d IBody;
107 Mat3x3d IFrame;
108 Mat3x3d invIBody;
109 Mat3x3d invIFrame;
110 Mat3x3d a;
111 Mat3x3d aTrans;
112
113 invMass = 1.0 / consRB ->getMass();
114
115 invMassVec = invMass * bondDir;
116
117 consRB->getRefCoor(refCoor.vec);
118 consRB->getA(a.element);
119 consRB->getI(IBody.element);
120
121 aTrans = a.transpose();
122 invIBody = IBody.inverse();
123
124 IFrame = aTrans * invIBody * a;
125
126 refCrossBond = crossProduct(refCoor, bondDir);
127
128 tempVec1 = invIFrame * refCrossBond;
129 tempVec2 = crossProduct(tempVec1, refCoor);
130
131 invMassVec += tempVec2;
132
133 }
134
135 void DCRollAFunctor::integrate(ConstraintRigidBody* consRB, const Vector3d& force){
136 StuntDouble* sd;
137 Vector3d vel;
138 Vector3d pos;
139 Vector3d Tb;
140 Vector3d ji;
141 double mass;
142 double dtOver2;
143 double dt;
144 const double eConvert = 4.184e-4;
145
146 dt = info->dt;
147 dtOver2 = dt /2;
148 sd = consRB->getStuntDouble();
149
150 sd->getVel(vel.vec);
151 sd->getPos(pos.vec);
152
153 mass = sd->getMass();
154
155 vel += eConvert * dtOver2/mass * force;
156 pos += dt * vel;
157
158 sd->setVel(vel.vec);
159 sd->setPos(pos.vec);
160
161 if (sd->isDirectional()){
162
163 // get and convert the torque to body frame
164
165 sd->getTrq(Tb.vec);
166 sd->lab2Body(Tb.vec);
167
168 // get the angular momentum, and propagate a half step
169
170 sd->getJ(ji.vec);
171
172 ji += eConvert * dtOver2 * Tb;
173
174 rotationPropagation( sd, ji.vec);
175
176 sd->setJ(ji.vec);
177 }
178
179 }
180
181 void DCRollAFunctor::rotationPropagation(StuntDouble* sd, double ji[3]){
182 double angle;
183 double A[3][3], I[3][3];
184 int i, j, k;
185 double dtOver2;
186
187 dtOver2 = info->dt /2;
188 // use the angular velocities to propagate the rotation matrix a
189 // full time step
190
191 sd->getA(A);
192 sd->getI(I);
193
194 if (sd->isLinear()) {
195 i = sd->linearAxis();
196 j = (i+1)%3;
197 k = (i+2)%3;
198
199 angle = dtOver2 * ji[j] / I[j][j];
200 this->rotate( k, i, angle, ji, A );
201
202 angle = dtOver2 * ji[k] / I[k][k];
203 this->rotate( i, j, angle, ji, A);
204
205 angle = dtOver2 * ji[j] / I[j][j];
206 this->rotate( k, i, angle, ji, A );
207
208 } else {
209 // rotate about the x-axis
210 angle = dtOver2 * ji[0] / I[0][0];
211 this->rotate( 1, 2, angle, ji, A );
212
213 // rotate about the y-axis
214 angle = dtOver2 * ji[1] / I[1][1];
215 this->rotate( 2, 0, angle, ji, A );
216
217 // rotate about the z-axis
218 angle = dtOver2 * ji[2] / I[2][2];
219 sd->addZangle(angle);
220 this->rotate( 0, 1, angle, ji, A);
221
222 // rotate about the y-axis
223 angle = dtOver2 * ji[1] / I[1][1];
224 this->rotate( 2, 0, angle, ji, A );
225
226 // rotate about the x-axis
227 angle = dtOver2 * ji[0] / I[0][0];
228 this->rotate( 1, 2, angle, ji, A );
229
230 }
231 sd->setA( A );
232 }
233
234 void DCRollAFunctor::rotate(int axes1, int axes2, double angle, double ji[3], double A[3][3]){
235 int i, j, k;
236 double sinAngle;
237 double cosAngle;
238 double angleSqr;
239 double angleSqrOver4;
240 double top, bottom;
241 double rot[3][3];
242 double tempA[3][3];
243 double tempJ[3];
244
245 // initialize the tempA
246
247 for (i = 0; i < 3; i++){
248 for (j = 0; j < 3; j++){
249 tempA[j][i] = A[i][j];
250 }
251 }
252
253 // initialize the tempJ
254
255 for (i = 0; i < 3; i++)
256 tempJ[i] = ji[i];
257
258 // initalize rot as a unit matrix
259
260 rot[0][0] = 1.0;
261 rot[0][1] = 0.0;
262 rot[0][2] = 0.0;
263
264 rot[1][0] = 0.0;
265 rot[1][1] = 1.0;
266 rot[1][2] = 0.0;
267
268 rot[2][0] = 0.0;
269 rot[2][1] = 0.0;
270 rot[2][2] = 1.0;
271
272 // use a small angle aproximation for sin and cosine
273
274 angleSqr = angle * angle;
275 angleSqrOver4 = angleSqr / 4.0;
276 top = 1.0 - angleSqrOver4;
277 bottom = 1.0 + angleSqrOver4;
278
279 cosAngle = top / bottom;
280 sinAngle = angle / bottom;
281
282 rot[axes1][axes1] = cosAngle;
283 rot[axes2][axes2] = cosAngle;
284
285 rot[axes1][axes2] = sinAngle;
286 rot[axes2][axes1] = -sinAngle;
287
288 // rotate the momentum acoording to: ji[] = rot[][] * ji[]
289
290 for (i = 0; i < 3; i++){
291 ji[i] = 0.0;
292 for (k = 0; k < 3; k++){
293 ji[i] += rot[i][k] * tempJ[k];
294 }
295 }
296
297 // rotate the Rotation matrix acording to:
298 // A[][] = A[][] * transpose(rot[][])
299
300
301 // NOte for as yet unknown reason, we are performing the
302 // calculation as:
303 // transpose(A[][]) = transpose(A[][]) * transpose(rot[][])
304
305 for (i = 0; i < 3; i++){
306 for (j = 0; j < 3; j++){
307 A[j][i] = 0.0;
308 for (k = 0; k < 3; k++){
309 A[j][i] += tempA[i][k] * rot[j][k];
310 }
311 }
312 }
313 }
314 ////////////////////////////////////////////////////////////////////////////////
315 //Implementation of DCRollBFunctor
316 ////////////////////////////////////////////////////////////////////////////////
317 int DCRollBFunctor::operator()(ConstraintRigidBody* consRB1, ConstraintRigidBody* consRB2){
318 return consElemHandlerFail;
319 }
320
321 void DCRollBFunctor::getEffInvMassVec(ConstraintRigidBody* consRB, const Vector3d& bondDir, Vector3d& invMassVec){
322
323 }
324
325 void DCRollBFunctor::integrate(ConstraintRigidBody* consRB, const Vector3d& force){
326
327 }

Properties

Name Value
svn:executable *