ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libmdtools/DirectionalAtom.cpp
Revision: 829
Committed: Tue Oct 28 16:03:37 2003 UTC (20 years, 8 months ago) by gezelter
File size: 8914 byte(s)
Log Message:
replace c++ header stuff with more portable c header stuff
Also, mod file fixes and portability changes
Some fortran changes will need to be reversed.

File Contents

# Content
1 #include <math.h>
2
3 #include "Atom.hpp"
4 #include "simError.h"
5
6 void DirectionalAtom::zeroForces() {
7 if( hasCoords ){
8 frc[offsetX] = 0.0;
9 frc[offsetY] = 0.0;
10 frc[offsetZ] = 0.0;
11
12 trq[offsetX] = 0.0;
13 trq[offsetY] = 0.0;
14 trq[offsetZ] = 0.0;
15 }
16 else{
17
18 sprintf( painCave.errMsg,
19 "Attempt to zero frc and trq for atom %d before coords set.\n",
20 index );
21 painCave.isFatal = 1;
22 simError();
23 }
24 }
25
26 void DirectionalAtom::setCoords(void){
27
28 if( myConfig->isAllocated() ){
29
30 myConfig->getAtomPointers( index,
31 &pos,
32 &vel,
33 &frc,
34 &trq,
35 &Amat,
36 &mu,
37 &ul );
38 }
39 else{
40 sprintf( painCave.errMsg,
41 "Attempted to set Atom %d coordinates with an unallocated "
42 "SimState object.\n", index );
43 painCave.isFatal = 1;
44 simError();
45 }
46
47 hasCoords = true;
48
49 *mu = myMu;
50
51 }
52
53 double DirectionalAtom::getMu( void ) {
54
55 if( hasCoords ){
56 return *mu;
57 }
58 else{
59 return myMu;
60 }
61 }
62
63 void DirectionalAtom::setMu( double the_mu ) {
64
65 if( hasCoords ){
66 *mu = the_mu;
67 myMu = the_mu;
68 }
69 else{
70 myMu = the_mu;
71 }
72 }
73
74 void DirectionalAtom::setA( double the_A[3][3] ){
75
76 if( hasCoords ){
77 Amat[Axx] = the_A[0][0]; Amat[Axy] = the_A[0][1]; Amat[Axz] = the_A[0][2];
78 Amat[Ayx] = the_A[1][0]; Amat[Ayy] = the_A[1][1]; Amat[Ayz] = the_A[1][2];
79 Amat[Azx] = the_A[2][0]; Amat[Azy] = the_A[2][1]; Amat[Azz] = the_A[2][2];
80
81 this->updateU();
82 }
83 else{
84
85 sprintf( painCave.errMsg,
86 "Attempt to set Amat for atom %d before coords set.\n",
87 index );
88 painCave.isFatal = 1;
89 simError();
90 }
91 }
92
93 void DirectionalAtom::setI( double the_I[3][3] ){
94
95 Ixx = the_I[0][0]; Ixy = the_I[0][1]; Ixz = the_I[0][2];
96 Iyx = the_I[1][0]; Iyy = the_I[1][1]; Iyz = the_I[1][2];
97 Izx = the_I[2][0]; Izy = the_I[2][1]; Izz = the_I[2][2];
98 }
99
100 void DirectionalAtom::setQ( double the_q[4] ){
101
102 double q0Sqr, q1Sqr, q2Sqr, q3Sqr;
103
104 if( hasCoords ){
105 q0Sqr = the_q[0] * the_q[0];
106 q1Sqr = the_q[1] * the_q[1];
107 q2Sqr = the_q[2] * the_q[2];
108 q3Sqr = the_q[3] * the_q[3];
109
110
111 Amat[Axx] = q0Sqr + q1Sqr - q2Sqr - q3Sqr;
112 Amat[Axy] = 2.0 * ( the_q[1] * the_q[2] + the_q[0] * the_q[3] );
113 Amat[Axz] = 2.0 * ( the_q[1] * the_q[3] - the_q[0] * the_q[2] );
114
115 Amat[Ayx] = 2.0 * ( the_q[1] * the_q[2] - the_q[0] * the_q[3] );
116 Amat[Ayy] = q0Sqr - q1Sqr + q2Sqr - q3Sqr;
117 Amat[Ayz] = 2.0 * ( the_q[2] * the_q[3] + the_q[0] * the_q[1] );
118
119 Amat[Azx] = 2.0 * ( the_q[1] * the_q[3] + the_q[0] * the_q[2] );
120 Amat[Azy] = 2.0 * ( the_q[2] * the_q[3] - the_q[0] * the_q[1] );
121 Amat[Azz] = q0Sqr - q1Sqr -q2Sqr +q3Sqr;
122
123 this->updateU();
124 }
125 else{
126
127 sprintf( painCave.errMsg,
128 "Attempt to set Q for atom %d before coords set.\n",
129 index );
130 painCave.isFatal = 1;
131 simError();
132 }
133
134 }
135
136 void DirectionalAtom::getA( double the_A[3][3] ){
137
138 if( hasCoords ){
139 the_A[0][0] = Amat[Axx];
140 the_A[0][1] = Amat[Axy];
141 the_A[0][2] = Amat[Axz];
142
143 the_A[1][0] = Amat[Ayx];
144 the_A[1][1] = Amat[Ayy];
145 the_A[1][2] = Amat[Ayz];
146
147 the_A[2][0] = Amat[Azx];
148 the_A[2][1] = Amat[Azy];
149 the_A[2][2] = Amat[Azz];
150 }
151 else{
152
153 sprintf( painCave.errMsg,
154 "Attempt to get Amat for atom %d before coords set.\n",
155 index );
156 painCave.isFatal = 1;
157 simError();
158 }
159
160 }
161
162 void DirectionalAtom::printAmatIndex( void ){
163
164 if( hasCoords ){
165 std::cerr << "Atom[" << index << "] index =>\n"
166 << "[ " << Axx << ", " << Axy << ", " << Axz << " ]\n"
167 << "[ " << Ayx << ", " << Ayy << ", " << Ayz << " ]\n"
168 << "[ " << Azx << ", " << Azy << ", " << Azz << " ]\n";
169 }
170 else{
171
172 sprintf( painCave.errMsg,
173 "Attempt to print Amat indices for atom %d before coords set.\n",
174 index );
175 painCave.isFatal = 1;
176 simError();
177 }
178 }
179
180
181 void DirectionalAtom::getU( double the_u[3] ){
182
183 the_u[0] = sux;
184 the_u[1] = suy;
185 the_u[2] = suz;
186
187 this->body2Lab( the_u );
188 }
189
190 void DirectionalAtom::getQ( double q[4] ){
191
192 double t, s;
193 double ad1, ad2, ad3;
194
195 if( hasCoords ){
196
197 t = Amat[Axx] + Amat[Ayy] + Amat[Azz] + 1.0;
198 if( t > 0.0 ){
199
200 s = 0.5 / sqrt( t );
201 q[0] = 0.25 / s;
202 q[1] = (Amat[Ayz] - Amat[Azy]) * s;
203 q[2] = (Amat[Azx] - Amat[Axz]) * s;
204 q[3] = (Amat[Axy] - Amat[Ayx]) * s;
205 }
206 else{
207
208 ad1 = fabs( Amat[Axx] );
209 ad2 = fabs( Amat[Ayy] );
210 ad3 = fabs( Amat[Azz] );
211
212 if( ad1 >= ad2 && ad1 >= ad3 ){
213
214 s = 2.0 * sqrt( 1.0 + Amat[Axx] - Amat[Ayy] - Amat[Azz] );
215 q[0] = (Amat[Ayz] + Amat[Azy]) / s;
216 q[1] = 0.5 / s;
217 q[2] = (Amat[Axy] + Amat[Ayx]) / s;
218 q[3] = (Amat[Axz] + Amat[Azx]) / s;
219 }
220 else if( ad2 >= ad1 && ad2 >= ad3 ){
221
222 s = sqrt( 1.0 + Amat[Ayy] - Amat[Axx] - Amat[Azz] ) * 2.0;
223 q[0] = (Amat[Axz] + Amat[Azx]) / s;
224 q[1] = (Amat[Axy] + Amat[Ayx]) / s;
225 q[2] = 0.5 / s;
226 q[3] = (Amat[Ayz] + Amat[Azy]) / s;
227 }
228 else{
229
230 s = sqrt( 1.0 + Amat[Azz] - Amat[Axx] - Amat[Ayy] ) * 2.0;
231 q[0] = (Amat[Axy] + Amat[Ayx]) / s;
232 q[1] = (Amat[Axz] + Amat[Azx]) / s;
233 q[2] = (Amat[Ayz] + Amat[Azy]) / s;
234 q[3] = 0.5 / s;
235 }
236 }
237 }
238 else{
239
240 sprintf( painCave.errMsg,
241 "Attempt to get Q for atom %d before coords set.\n",
242 index );
243 painCave.isFatal = 1;
244 simError();
245 }
246 }
247
248
249 void DirectionalAtom::setEuler( double phi, double theta, double psi ){
250
251 if( hasCoords ){
252 Amat[Axx] = (cos(phi) * cos(psi)) - (sin(phi) * cos(theta) * sin(psi));
253 Amat[Axy] = (sin(phi) * cos(psi)) + (cos(phi) * cos(theta) * sin(psi));
254 Amat[Axz] = sin(theta) * sin(psi);
255
256 Amat[Ayx] = -(cos(phi) * sin(psi)) - (sin(phi) * cos(theta) * cos(psi));
257 Amat[Ayy] = -(sin(phi) * sin(psi)) + (cos(phi) * cos(theta) * cos(psi));
258 Amat[Ayz] = sin(theta) * cos(psi);
259
260 Amat[Azx] = sin(phi) * sin(theta);
261 Amat[Azy] = -cos(phi) * sin(theta);
262 Amat[Azz] = cos(theta);
263
264 this->updateU();
265 }
266 else{
267
268 sprintf( painCave.errMsg,
269 "Attempt to set Euler angles for atom %d before coords set.\n",
270 index );
271 painCave.isFatal = 1;
272 simError();
273 }
274 }
275
276
277 void DirectionalAtom::lab2Body( double r[3] ){
278
279 double rl[3]; // the lab frame vector
280
281 if( hasCoords ){
282 rl[0] = r[0];
283 rl[1] = r[1];
284 rl[2] = r[2];
285
286 r[0] = (Amat[Axx] * rl[0]) + (Amat[Axy] * rl[1]) + (Amat[Axz] * rl[2]);
287 r[1] = (Amat[Ayx] * rl[0]) + (Amat[Ayy] * rl[1]) + (Amat[Ayz] * rl[2]);
288 r[2] = (Amat[Azx] * rl[0]) + (Amat[Azy] * rl[1]) + (Amat[Azz] * rl[2]);
289 }
290 else{
291
292 sprintf( painCave.errMsg,
293 "Attempt to convert lab2body for atom %d before coords set.\n",
294 index );
295 painCave.isFatal = 1;
296 simError();
297 }
298
299 }
300
301 void DirectionalAtom::body2Lab( double r[3] ){
302
303 double rb[3]; // the body frame vector
304
305 if( hasCoords ){
306 rb[0] = r[0];
307 rb[1] = r[1];
308 rb[2] = r[2];
309
310 r[0] = (Amat[Axx] * rb[0]) + (Amat[Ayx] * rb[1]) + (Amat[Azx] * rb[2]);
311 r[1] = (Amat[Axy] * rb[0]) + (Amat[Ayy] * rb[1]) + (Amat[Azy] * rb[2]);
312 r[2] = (Amat[Axz] * rb[0]) + (Amat[Ayz] * rb[1]) + (Amat[Azz] * rb[2]);
313 }
314 else{
315
316 sprintf( painCave.errMsg,
317 "Attempt to convert body2lab for atom %d before coords set.\n",
318 index );
319 painCave.isFatal = 1;
320 simError();
321 }
322 }
323
324 void DirectionalAtom::updateU( void ){
325
326 if( hasCoords ){
327 ul[offsetX] = (Amat[Axx] * sux) + (Amat[Ayx] * suy) + (Amat[Azx] * suz);
328 ul[offsetY] = (Amat[Axy] * sux) + (Amat[Ayy] * suy) + (Amat[Azy] * suz);
329 ul[offsetZ] = (Amat[Axz] * sux) + (Amat[Ayz] * suy) + (Amat[Azz] * suz);
330 }
331 else{
332
333 sprintf( painCave.errMsg,
334 "Attempt to updateU for atom %d before coords set.\n",
335 index );
336 painCave.isFatal = 1;
337 simError();
338 }
339 }
340
341 void DirectionalAtom::getJ( double theJ[3] ){
342
343 theJ[0] = jx;
344 theJ[1] = jy;
345 theJ[2] = jz;
346 }
347
348 void DirectionalAtom::setJ( double theJ[3] ){
349
350 jx = theJ[0];
351 jy = theJ[1];
352 jz = theJ[2];
353 }
354
355 void DirectionalAtom::getTrq( double theT[3] ){
356
357 if( hasCoords ){
358 theT[0] = trq[offsetX];
359 theT[1] = trq[offsetY];
360 theT[2] = trq[offsetZ];
361 }
362 else{
363
364 sprintf( painCave.errMsg,
365 "Attempt to get Trq for atom %d before coords set.\n",
366 index );
367 painCave.isFatal = 1;
368 simError();
369 }
370 }
371
372 void DirectionalAtom::addTrq( double theT[3] ){
373
374 if( hasCoords ){
375 trq[offsetX] += theT[0];
376 trq[offsetY] += theT[1];
377 trq[offsetZ] += theT[2];
378 }
379 else{
380
381 sprintf( painCave.errMsg,
382 "Attempt to add Trq for atom %d before coords set.\n",
383 index );
384 painCave.isFatal = 1;
385 simError();
386 }
387 }
388
389
390 void DirectionalAtom::getI( double the_I[3][3] ){
391
392 the_I[0][0] = Ixx;
393 the_I[0][1] = Ixy;
394 the_I[0][2] = Ixz;
395
396 the_I[1][0] = Iyx;
397 the_I[1][1] = Iyy;
398 the_I[1][2] = Iyz;
399
400 the_I[2][0] = Izx;
401 the_I[2][1] = Izy;
402 the_I[2][2] = Izz;
403 }