ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-1.0/utils/sysbuilder/MoLocator.cpp
Revision: 1334
Committed: Fri Jul 16 18:58:03 2004 UTC (19 years, 11 months ago) by gezelter
File size: 4704 byte(s)
Log Message:
Initial import of OOPSE-1.0 source tree

File Contents

# User Rev Content
1 gezelter 1334 #include <iostream>
2    
3     #include <cstdlib>
4     #include <cmath>
5    
6     #include "simError.h"
7    
8     #include "MoLocator.hpp"
9    
10    
11     MoLocator::MoLocator( MoleculeStamp* theStamp ){
12    
13     myStamp = theStamp;
14     nAtoms = myStamp->getNAtoms();
15    
16     myCoords = NULL;
17    
18     calcRefCoords();
19     }
20    
21     MoLocator::~MoLocator(){
22    
23     if( myCoords != NULL ) delete[] myCoords;
24     }
25    
26     void MoLocator::placeMol( double pos[3], double A[3][3], Atom** atomArray,
27     int atomIndex, SimState* myConfig ){
28    
29     int i,j,k;
30     double r[3], ji[3];
31     double phi, theta, psi;
32     double sux, suy, suz;
33     double Axx, Axy, Axz, Ayx, Ayy, Ayz, Azx, Azy, Azz;
34     double ux, uy, uz, u, uSqr;
35    
36     AtomStamp* currAtom;
37     DirectionalAtom* dAtom;
38     double vel[3];
39     for(i=0;i<3;i++)vel[i]=0.0;
40    
41     for(i=0; i<nAtoms; i++){
42    
43     currAtom = myStamp->getAtom( i );
44     j = atomIndex+i;
45    
46     if( currAtom->haveOrientation()){
47    
48     dAtom = new DirectionalAtom( j, myConfig);
49     atomArray[j] = dAtom;
50     atomArray[j]->setCoords();
51    
52     // Directional Atoms have standard unit vectors which are oriented
53     // in space using the three Euler angles.
54    
55     phi = currAtom->getEulerPhi() * M_PI / 180.0;
56     theta = currAtom->getEulerTheta() * M_PI / 180.0;
57     psi = currAtom->getEulerPsi()* M_PI / 180.0;
58    
59     dAtom->setUnitFrameFromEuler(phi, theta, psi);
60     dAtom->setA( A );
61    
62     ji[0] = 0.0;
63     ji[1] = 0.0;
64     ji[2] = 0.0;
65     dAtom->setJ( ji );
66    
67     }
68     else{
69     atomArray[j] = new Atom( j, myConfig);
70     atomArray[j]->setCoords();
71     }
72    
73     atomArray[j]->setType( currAtom->getType() );
74    
75     for(k=0; k<3; k++) r[k] = myCoords[(i*3)+k];
76    
77     rotMe( r, A );
78    
79     for(k=0; k<3; k++) r[k] += pos[k];
80    
81     atomArray[j]->setPos( r );
82    
83     atomArray[j]->setVel( vel );;
84     }
85     }
86    
87     void MoLocator::calcRefCoords( void ){
88    
89     int i,j,k;
90     AtomStamp* currAtom;
91     double centerX, centerY, centerZ;
92     double smallX, smallY, smallZ;
93     double bigX, bigY, bigZ;
94     double dx, dy, dz;
95     double dsqr;
96    
97    
98     centerX = 0.0;
99     centerY = 0.0;
100     centerZ = 0.0;
101    
102     for(i=0; i<nAtoms; i++){
103    
104     currAtom = myStamp->getAtom(i);
105     if( !currAtom->havePosition() ){
106     sprintf( painCave.errMsg,
107     "MoLocator error.\n"
108     " Component %s, atom %s does not have a position specified.\n"
109     " This means MoLocator cannot initalize it's position.\n",
110     myStamp->getID(),
111     currAtom->getType() );
112     painCave.isFatal = 1;
113     simError();
114     }
115    
116    
117     centerX += currAtom->getPosX();
118     centerY += currAtom->getPosY();
119     centerZ += currAtom->getPosZ();
120     }
121    
122     centerX /= nAtoms;
123     centerY /= nAtoms;
124     centerZ /= nAtoms;
125    
126     myCoords = new double[nAtoms*3];
127    
128     j = 0;
129     for(i=0; i<nAtoms; i++){
130    
131     currAtom = myStamp->getAtom(i);
132     j = i*3;
133    
134     myCoords[j] = currAtom->getPosX() - centerX;
135     myCoords[j+1] = currAtom->getPosY() - centerY;
136     myCoords[j+2] = currAtom->getPosZ() - centerZ;
137     }
138    
139     smallX = myCoords[0];
140     smallY = myCoords[1];
141     smallZ = myCoords[2];
142    
143     bigX = myCoords[0];
144     bigY = myCoords[1];
145     bigZ = myCoords[2];
146    
147     j=0;
148     for(i=1; i<nAtoms; i++){
149     j= i*3;
150    
151     if( myCoords[j] < smallX ) smallX = myCoords[j];
152     if( myCoords[j+1] < smallY ) smallY = myCoords[j+1];
153     if( myCoords[j+2] < smallZ ) smallZ = myCoords[j+2];
154    
155     if( myCoords[j] > bigX ) bigX = myCoords[j];
156     if( myCoords[j+1] > bigY ) bigY = myCoords[j+1];
157     if( myCoords[j+2] > bigZ ) bigZ = myCoords[j+2];
158     }
159    
160    
161     dx = bigX - smallX;
162     dy = bigY - smallY;
163     dz = bigZ - smallZ;
164    
165     dsqr = (dx * dx) + (dy * dy) + (dz * dz);
166     maxLength = sqrt( dsqr );
167     }
168    
169     void MoLocator::rotMe( double r[3], double A[3][3] ){
170    
171     double rt[3];
172     int i,j;
173    
174     for(i=0; i<3; i++) rt[i] = r[i];
175    
176     for(i=0; i<3; i++){
177     r[i] = 0.0;
178     for(j=0; j<3; j++){
179     r[i] += A[i][j] * rt[j];
180     }
181     }
182     }
183    
184     void getRandomRot( double rot[3][3] ){
185    
186     double theta, phi, psi;
187     double cosTheta;
188    
189     // select random phi, psi, and cosTheta
190    
191     phi = 2.0 * M_PI * drand48();
192     psi = 2.0 * M_PI * drand48();
193     cosTheta = (2.0 * drand48()) - 1.0; // sample cos -1 to 1
194    
195     theta = acos( cosTheta );
196    
197     getEulerRot( theta, phi, psi, rot );
198     }
199    
200    
201     void getEulerRot( double theta, double phi, double psi, double rot[3][3] ){
202    
203     rot[0][0] = (cos(phi) * cos(psi)) - (sin(phi) * cos(theta) * sin(psi));
204     rot[0][1] = (sin(phi) * cos(psi)) + (cos(phi) * cos(theta) * sin(psi));
205     rot[0][2] = sin(theta) * sin(psi);
206    
207     rot[1][0] = -(cos(phi) * sin(psi)) - (sin(phi) * cos(theta) * cos(psi));
208     rot[1][1] = -(sin(phi) * sin(psi)) + (cos(phi) * cos(theta) * cos(psi));
209     rot[1][2] = sin(theta) * cos(psi);
210    
211     rot[2][0] = sin(phi) * sin(theta);
212     rot[2][1] = -cos(phi) * sin(theta);
213     rot[2][2] = cos(theta);
214     }
215