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 1432 by tim, Thu Jul 29 03:31:50 2004 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines