ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-1.0/utils/sysbuilder/MoLocator.cpp
(Generate patch)

Comparing trunk/OOPSE-1.0/utils/sysbuilder/MoLocator.cpp (file contents):
Revision 1334 by gezelter, Fri Jul 16 18:58:03 2004 UTC vs.
Revision 1435 by tim, Thu Jul 29 18:16:16 2004 UTC

# Line 4 | Line 4
4   #include <cmath>
5  
6   #include "simError.h"
7
7   #include "MoLocator.hpp"
8 + #include "MatVec3.h"
9  
10 + MoLocator::MoLocator( MoleculeStamp* theStamp, ForceFields* theFF){
11  
11 MoLocator::MoLocator( MoleculeStamp* theStamp ){
12
12    myStamp = theStamp;
13 <  nAtoms = myStamp->getNAtoms();
14 <
16 <  myCoords = NULL;
17 <  
13 >  myFF = theFF;
14 >  nIntegrableObjects = myStamp->getNIntegrable();
15    calcRefCoords();
16   }
17  
18 < MoLocator::~MoLocator(){
18 > void MoLocator::placeMol( const Vector3d& offset, const Vector3d& ort, Molecule* mol){
19 >  Vector3d newCoor;
20 >  Vector3d velocity(0.0, 0.0, 0.0);
21 >  Vector3d angMomentum(0.0, 0.0, 0.0);
22 >  double quaternion[4];
23 >  vector<StuntDouble*> myIntegrableObjects;
24 >  double rotMat[3][3];
25    
26 <  if( myCoords != NULL ) delete[] myCoords;
27 < }
26 >  quaternion[0] = 1.0;
27 >  quaternion[1] = 0.0;
28 >  quaternion[2] = 0.0;
29 >  quaternion[3] = 0.0;
30  
31 < 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;
31 >  latVec2RotMat(ort, rotMat);
32    
33 <  AtomStamp* currAtom;
37 <  DirectionalAtom* dAtom;
38 <  double vel[3];
39 <  for(i=0;i<3;i++)vel[i]=0.0;
33 >  myIntegrableObjects = mol->getIntegrableObjects();
34  
35 <  for(i=0; i<nAtoms; i++){
36 <    
37 <    currAtom = myStamp->getAtom( i );
38 <    j = atomIndex+i;
35 >  if(myIntegrableObjects.size() != nIntegrableObjects){
36 >      sprintf( painCave.errMsg,
37 >               "MoLocator error.\n"
38 >               "  The number of integrable objects of MoleculeStamp is not the same as  that of Molecule\n");
39 >          painCave.isFatal = 1;
40 >      simError();
41  
42 <    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 <    }
42 >  }
43      
44 <    atomArray[j]->setType( currAtom->getType() );
74 <    
75 <    for(k=0; k<3; k++) r[k] = myCoords[(i*3)+k];
44 >  for(int i=0; i<nIntegrableObjects; i++) {
45  
46 <    rotMe( r, A );
46 >    //calculate the reference coordinate for integrable objects after rotation
47 >    matVecMul3(rotMat, refCoords[i].vec, newCoor.vec);    
48 >    newCoor +=  offset;
49  
50 <    for(k=0; k<3; k++) r[k] += pos[k];
50 >    myIntegrableObjects[i]->setPos( newCoor.vec);
51 >    myIntegrableObjects[i]->setVel(velocity.vec);
52  
53 <    atomArray[j]->setPos( r );
54 <        
55 <    atomArray[j]->setVel( vel );;
53 >    if(myIntegrableObjects[i]->isDirectional()){
54 >      myIntegrableObjects[i]->setA(rotMat);
55 >      myIntegrableObjects[i]->setJ(angMomentum.vec);  
56 >    }
57    }
85 }
58  
59 + }
60 +
61   void MoLocator::calcRefCoords( void ){
62 +  AtomStamp* currAtomStamp;
63 +  int nAtoms;
64 +  int nRigidBodies;
65 +  vector<double> mass;
66 +  Vector3d coor;
67 +  Vector3d refMolCom;  
68 +  int nAtomsInRb;
69 +  double totMassInRb;
70 +  double currAtomMass;
71 +  double molMass;
72 +  
73 +  nAtoms= myStamp->getNAtoms();
74 +  nRigidBodies = myStamp->getNRigidBodies();
75  
76 <  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;
76 >  for(size_t i=0; i<nAtoms; i++){
77  
78 <  
98 <  centerX = 0.0;
99 <  centerY = 0.0;
100 <  centerZ = 0.0;
78 >    currAtomStamp = myStamp->getAtom(i);
79  
80 <  for(i=0; i<nAtoms; i++){
103 <    
104 <    currAtom = myStamp->getAtom(i);
105 <    if( !currAtom->havePosition() ){
80 >    if( !currAtomStamp->havePosition() ){
81        sprintf( painCave.errMsg,
82 <               "MoLocator error.\n"
83 <               "  Component %s, atom %s does not have a position specified.\n"
84 <               "  This means MoLocator cannot initalize it's position.\n",
85 <               myStamp->getID(),
86 <               currAtom->getType() );
82 >                  "MoLocator error.\n"
83 >                  "  Component %s, atom %s does not have a position specified.\n"
84 >                  "  This means MoLocator cannot initalize it's position.\n",
85 >                  myStamp->getID(),
86 >                  currAtomStamp->getType() );
87 >
88        painCave.isFatal = 1;
89        simError();
90      }
91  
92 <    
93 <    centerX += currAtom->getPosX();
94 <    centerY += currAtom->getPosY();
95 <    centerZ += currAtom->getPosZ();
96 <  }
92 >    //if atom belongs to rigidbody, just skip it
93 >    if(myStamp->isAtomInRigidBody(i))
94 >      continue;
95 >    //get mass and the reference coordinate
96 >    else{
97 >      currAtomMass = myFF->getAtomTypeMass(currAtomStamp->getType());
98 >      mass.push_back(currAtomMass);
99 >      coor.x = currAtomStamp->getPosX();
100 >      coor.y = currAtomStamp->getPosY();
101 >      coor.z = currAtomStamp->getPosZ();
102 >      refCoords.push_back(coor);
103  
104 <  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;
104 >    }
105    }
138  
139  smallX = myCoords[0];
140  smallY = myCoords[1];
141  smallZ = myCoords[2];
106  
107 <  bigX = myCoords[0];
108 <  bigY = myCoords[1];
109 <  bigZ = myCoords[2];
107 >  for(int i = 0; i < nRigidBodies; i++){
108 >    coor.x = 0;
109 >    coor.y = 0;
110 >    coor.z = 0;
111 >    totMassInRb = 0;
112  
113 <  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];
113 >    for(int j = 0; j < nAtomsInRb; j++){
114  
115 <    if( myCoords[j]   > bigX ) bigX = myCoords[j];
116 <    if( myCoords[j+1] > bigY ) bigY = myCoords[j+1];
117 <    if( myCoords[j+2] > bigZ ) bigZ = myCoords[j+2];
115 >      currAtomMass = myFF->getAtomTypeMass(currAtomStamp->getType());
116 >      totMassInRb +=  currAtomMass;
117 >      
118 >      coor.x += currAtomStamp->getPosX() * currAtomMass;
119 >      coor.y += currAtomStamp->getPosY() * currAtomMass;
120 >      coor.z += currAtomStamp->getPosZ() * currAtomMass;
121 >    }
122 >
123 >    mass.push_back(totMassInRb);
124 >    coor /= totMassInRb;
125 >    refCoords.push_back(coor);
126    }
127  
128  
129 <  dx = bigX - smallX;
130 <  dy = bigY - smallY;
131 <  dz = bigZ - smallZ;
132 <
133 <  dsqr = (dx * dx) + (dy * dy) + (dz * dz);
134 <  maxLength = sqrt( dsqr );
135 < }
136 <
137 < 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 <    }
129 >  //calculate the reference center of mass
130 >  molMass = 0;
131 >  refMolCom.x = 0;
132 >  refMolCom.y = 0;
133 >  refMolCom.z = 0;
134 >  
135 >  for(int i = 0; i < nIntegrableObjects; i++){
136 >    refMolCom += refCoords[i] * mass[i];
137 >   molMass += mass[i];
138    }
139 < }
139 >  
140 >  refMolCom /= molMass;
141  
142 < void getRandomRot( double rot[3][3] ){
143 <
144 <  double theta, phi, psi;
145 <  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 );
142 >  //move the reference center of mass to (0,0,0) and adjust the reference coordinate
143 >  //of the integrabel objects
144 >  for(int i = 0; i < nIntegrableObjects; i++)
145 >    refCoords[i] -= refMolCom;
146   }
147  
148  
149 < void getEulerRot( double theta, double phi, double psi, double rot[3][3] ){
149 > void latVec2RotMat(const Vector3d& lv, double rotMat[3][3]){
150  
151 <  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);
151 >  double theta, phi, psi;
152    
153 <  rot[1][0] = -(cos(phi) * sin(psi)) - (sin(phi) * cos(theta) * cos(psi));
154 <  rot[1][1] = -(sin(phi) * sin(psi)) + (cos(phi) * cos(theta) * cos(psi));
155 <  rot[1][2] = sin(theta) * cos(psi);
153 >  theta =acos(lv.z);
154 >  phi = atan2(lv.y, lv.x);
155 >  psi = 0;
156  
157 <  rot[2][0] = sin(phi) * sin(theta);
158 <  rot[2][1] = -cos(phi) * sin(theta);
159 <  rot[2][2] = cos(theta);  
157 >  rotMat[0][0] = (cos(phi) * cos(psi)) - (sin(phi) * cos(theta) * sin(psi));
158 >  rotMat[0][1] = (sin(phi) * cos(psi)) + (cos(phi) * cos(theta) * sin(psi));
159 >  rotMat[0][2] = sin(theta) * sin(psi);
160 >  
161 >  rotMat[1][0] = -(cos(phi) * sin(psi)) - (sin(phi) * cos(theta) * cos(psi));
162 >  rotMat[1][1] = -(sin(phi) * sin(psi)) + (cos(phi) * cos(theta) * cos(psi));
163 >  rotMat[1][2] = sin(theta) * cos(psi);
164 >  
165 >  rotMat[2][0] = sin(phi) * sin(theta);
166 >  rotMat[2][1] = -cos(phi) * sin(theta);
167 >  rotMat[2][2] = cos(theta);
168   }
169  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines