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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines