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 1427 by tim, Wed Jul 28 18:42:59 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  
65 <  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 <
65 >  double totMass;
66    
67 <  centerX = 0.0;
68 <  centerY = 0.0;
69 <  centerZ = 0.0;
67 >  mass.resize(nIntegrableObjects);
68 >  
69 >  nAtoms= myStamp->getNAtoms();
70 >  nRigidBodies = myStamp->getNRigidBodies();
71  
72 <  for(i=0; i<nAtoms; i++){
73 <    
74 <    currAtom = myStamp->getAtom(i);
75 <    if( !currAtom->havePosition() ){
72 >  //
73 >  for(size_t i=0; i<nAtoms; i++){
74 >
75 >    currAtomStamp = myStamp->getAtom(i);
76 >
77 >    if( !currAtomStamp->havePosition() ){
78        sprintf( painCave.errMsg,
79 <               "MoLocator error.\n"
80 <               "  Component %s, atom %s does not have a position specified.\n"
81 <               "  This means MoLocator cannot initalize it's position.\n",
82 <               myStamp->getID(),
83 <               currAtom->getType() );
79 >                  "MoLocator error.\n"
80 >                  "  Component %s, atom %s does not have a position specified.\n"
81 >                  "  This means MoLocator cannot initalize it's position.\n",
82 >                  myStamp->getID(),
83 >                  currAtomStamp->getType() );
84 >
85        painCave.isFatal = 1;
86        simError();
87      }
88  
89 <    
90 <    centerX += currAtom->getPosX();
91 <    centerY += currAtom->getPosY();
92 <    centerZ += currAtom->getPosZ();
93 <  }
89 >    //if atom belongs to rigidbody, just skip it
90 >    if(myStamp->isAtomInRigidBody(i))
91 >      continue;
92 >    //get mass and the reference coordinate
93 >    else{
94 >      currAtomMass = myFF->getAtomTypeMass(currAtomStamp->getType());
95 >      mass.push_back(currAtomMass);
96 >      coor.x = currAtomStamp->getPosX();
97 >      coor.y = currAtomStamp->getPosY();
98 >      coor.z = currAtomStamp->getPosZ();
99 >      refCoords.push_back(coor);
100  
101 <  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;
101 >    }
102    }
138  
139  smallX = myCoords[0];
140  smallY = myCoords[1];
141  smallZ = myCoords[2];
103  
104 <  bigX = myCoords[0];
105 <  bigY = myCoords[1];
106 <  bigZ = myCoords[2];
104 >  for(int i = 0; i < nRigidBodies; i++){
105 >    coor.x = 0;
106 >    coor.y = 0;
107 >    coor.z = 0;
108 >    totMassInRb = 0;
109  
110 <  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];
110 >    for(int j = 0; j < nAtomsInRb; j++){
111  
112 <    if( myCoords[j]   > bigX ) bigX = myCoords[j];
113 <    if( myCoords[j+1] > bigY ) bigY = myCoords[j+1];
114 <    if( myCoords[j+2] > bigZ ) bigZ = myCoords[j+2];
112 >      currAtomMass = myFF->getAtomTypeMass(currAtomStamp->getType());
113 >      totMassInRb +=  currAtomMass;
114 >      
115 >      coor.x += currAtomStamp->getPosX() * currAtomMass;
116 >      coor.y += currAtomStamp->getPosY() * currAtomMass;
117 >      coor.z += currAtomStamp->getPosZ() * currAtomMass;
118 >    }
119 >
120 >    mass.push_back(totMassInRb);
121 >    coor /= totMassInRb;
122 >    refCoords.push_back(coor);
123    }
124  
125 <
126 <  dx = bigX - smallX;
127 <  dy = bigY - smallY;
128 <  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 <    }
125 >  //calculate the reference center of mass
126 >  for(int i = 0; i < nIntegrableObjects; i++){
127 >    refMolCom += refCoords[i] * mass[i];
128 >    totMass += mass[i];
129    }
130 < }
130 >  refMolCom / = totMass;
131  
132 < void getRandomRot( double rot[3][3] ){
133 <
134 <  double theta, phi, psi;
135 <  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 );
132 >  //move the reference center of mass to (0,0,0) and adjust the reference coordinate
133 >  //of the integrabel objects
134 >  for(int i = 0; i < nIntegrableObjects; i++)
135 >    refCoords[i] -= refMolCom;
136   }
137  
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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines