| 1 | 
  | 
#include <math.h> | 
| 2 | 
+ | 
#include <iostream> | 
| 3 | 
  | 
#include "RigidBody.hpp" | 
| 4 | 
  | 
#include "VDWAtom.hpp" | 
| 5 | 
  | 
#include "MatVec3.h" | 
| 174 | 
  | 
 | 
| 175 | 
  | 
void RigidBody::calcRefCoords( ) { | 
| 176 | 
  | 
 | 
| 177 | 
< | 
  int i, j, it, n_linear_coords; | 
| 177 | 
> | 
  int i, j, it, n_linear_coords, pAxis, maxAxis, midAxis; | 
| 178 | 
  | 
  double mtmp; | 
| 179 | 
  | 
  vec3 apos; | 
| 180 | 
  | 
  double refCOM[3]; | 
| 181 | 
  | 
  vec3 ptmp; | 
| 182 | 
  | 
  double Itmp[3][3]; | 
| 183 | 
+ | 
  double pAxisMat[3][3], pAxisRotMat[3][3]; | 
| 184 | 
  | 
  double evals[3]; | 
| 185 | 
  | 
  double r, r2, len; | 
| 186 | 
< | 
 | 
| 186 | 
> | 
  double iMat[3][3]; | 
| 187 | 
> | 
  double test[3]; | 
| 188 | 
> | 
   | 
| 189 | 
  | 
  // First, find the center of mass: | 
| 190 | 
  | 
   | 
| 191 | 
  | 
  mass = 0.0; | 
| 197 | 
  | 
    mass += mtmp; | 
| 198 | 
  | 
 | 
| 199 | 
  | 
    apos = refCoords[i]; | 
| 196 | 
– | 
     | 
| 200 | 
  | 
    for(j = 0; j < 3; j++) { | 
| 201 | 
  | 
      refCOM[j] += apos[j]*mtmp;      | 
| 202 | 
  | 
    }     | 
| 260 | 
  | 
  if (n_linear_coords > 1) { | 
| 261 | 
  | 
          printf( | 
| 262 | 
  | 
               "RigidBody error.\n" | 
| 263 | 
< | 
               "\tOOPSE found more than one axis in this rigid body with a vanishing \n" | 
| 263 | 
> | 
               "\tSHAPES found more than one axis in this rigid body with a vanishing \n" | 
| 264 | 
  | 
               "\tmoment of inertia.  This can happen in one of three ways:\n" | 
| 265 | 
  | 
               "\t 1) Only one atom was specified, or \n" | 
| 266 | 
  | 
               "\t 2) All atoms were specified at the same location, or\n" | 
| 269 | 
  | 
               ); | 
| 270 | 
  | 
               exit(-1);      | 
| 271 | 
  | 
  } | 
| 272 | 
< | 
   | 
| 272 | 
> | 
 | 
| 273 | 
  | 
  // renormalize column vectors: | 
| 274 | 
  | 
   | 
| 275 | 
  | 
  for (i=0; i < 3; i++) { | 
| 282 | 
  | 
      sU[i][j] /= len; | 
| 283 | 
  | 
    } | 
| 284 | 
  | 
  } | 
| 285 | 
+ | 
   | 
| 286 | 
+ | 
  //sort and reorder the moment axes | 
| 287 | 
+ | 
 | 
| 288 | 
+ | 
  // The only problem below is for molecules like C60 with 3 nearly identical  | 
| 289 | 
+ | 
  // non-zero moments of inertia.  In this case it doesn't really matter which is  | 
| 290 | 
+ | 
  // the principal axis, so they get assigned nearly randomly depending on the  | 
| 291 | 
+ | 
  // floating point comparison between eigenvalues | 
| 292 | 
+ | 
  if (! is_linear) { | 
| 293 | 
+ | 
    pAxis = 0; | 
| 294 | 
+ | 
    maxAxis = 0; | 
| 295 | 
+ | 
   | 
| 296 | 
+ | 
    for (i = 0; i < 3; i++) { | 
| 297 | 
+ | 
      if (evals[i] < evals[pAxis]) pAxis = i; | 
| 298 | 
+ | 
      if (evals[i] > evals[maxAxis]) maxAxis = i; | 
| 299 | 
+ | 
    } | 
| 300 | 
+ | 
   | 
| 301 | 
+ | 
    midAxis = 0; | 
| 302 | 
+ | 
    for (i=0; i < 3; i++) { | 
| 303 | 
+ | 
      if (pAxis != i && maxAxis != i) midAxis = i; | 
| 304 | 
+ | 
    } | 
| 305 | 
+ | 
  } else { | 
| 306 | 
+ | 
    pAxis = linear_axis; | 
| 307 | 
+ | 
    // linear molecules have one zero moment of inertia and two identical | 
| 308 | 
+ | 
    // moments of inertia.  In this case, it doesn't matter which is chosen | 
| 309 | 
+ | 
    // as mid and which is max, so just permute from the pAxis: | 
| 310 | 
+ | 
    midAxis = (pAxis + 1)%3; | 
| 311 | 
+ | 
    maxAxis = (pAxis + 2)%3; | 
| 312 | 
+ | 
  } | 
| 313 | 
+ | 
       | 
| 314 | 
+ | 
  //let z be the smallest and x be the largest eigenvalue axes | 
| 315 | 
+ | 
  for (i=0; i<3; i++){ | 
| 316 | 
+ | 
    pAxisMat[i][2] = sU[i][pAxis]; | 
| 317 | 
+ | 
    pAxisMat[i][1] = sU[i][midAxis]; | 
| 318 | 
+ | 
    pAxisMat[i][0] = sU[i][maxAxis]; | 
| 319 | 
+ | 
  } | 
| 320 | 
+ | 
     | 
| 321 | 
+ | 
  //calculate the proper rotation matrix | 
| 322 | 
+ | 
  transposeMat3(pAxisMat, pAxisRotMat); | 
| 323 | 
+ | 
   | 
| 324 | 
+ | 
   | 
| 325 | 
+ | 
  //rotate the rigid body to the principle axis frame | 
| 326 | 
+ | 
  for (i = 0; i < myAtoms.size(); i++) { | 
| 327 | 
+ | 
    matVecMul3(pAxisRotMat, refCoords[i].vec, refCoords[i].vec); | 
| 328 | 
+ | 
    myAtoms[i]->setPos(refCoords[i].vec); | 
| 329 | 
+ | 
  } | 
| 330 | 
+ | 
   | 
| 331 | 
+ | 
  identityMat3(iMat); | 
| 332 | 
+ | 
  setA(iMat); | 
| 333 | 
  | 
} | 
| 334 | 
  | 
 | 
| 335 | 
  | 
void RigidBody::doEulerToRotMat(double euler[3], double myA[3][3] ){ | 
| 524 | 
  | 
  pos[2] = ref[2]; | 
| 525 | 
  | 
   | 
| 526 | 
  | 
} | 
| 527 | 
+ | 
 | 
| 528 | 
+ | 
double RigidBody::getAtomRpar(int index){ | 
| 529 | 
+ | 
   | 
| 530 | 
+ | 
  return myAtoms[index]->getRpar(); | 
| 531 | 
+ | 
   | 
| 532 | 
+ | 
} | 
| 533 | 
+ | 
 | 
| 534 | 
+ | 
double RigidBody::getAtomEps(int index){ | 
| 535 | 
+ | 
   | 
| 536 | 
+ | 
  return myAtoms[index]->getEps(); | 
| 537 | 
+ | 
   | 
| 538 | 
+ | 
} |