Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/molecule_geometry.cpp

    r4bb63c rd74077  
    1010#endif
    1111
    12 #include "Helpers/helpers.hpp"
    13 #include "Helpers/Log.hpp"
    1412#include "Helpers/MemDebug.hpp"
    15 #include "Helpers/Verbose.hpp"
    16 #include "LinearAlgebra/Line.hpp"
    17 #include "LinearAlgebra/Matrix.hpp"
    18 #include "LinearAlgebra/Plane.hpp"
    1913
    2014#include "atom.hpp"
     
    2216#include "config.hpp"
    2317#include "element.hpp"
     18#include "helpers.hpp"
    2419#include "leastsquaremin.hpp"
     20#include "verbose.hpp"
     21#include "log.hpp"
    2522#include "molecule.hpp"
    2623#include "World.hpp"
    27 
     24#include "Plane.hpp"
     25#include "Matrix.hpp"
    2826#include "Box.hpp"
    29 
    3027#include <boost/foreach.hpp>
    3128
     
    4845
    4946  // go through all atoms
    50   ActOnAllVectors( &Vector::SubtractVector, *Center);
    51   ActOnAllVectors( &Vector::SubtractVector, *CenterBox);
    52   atoms.transformNodes(boost::bind(&Box::WrapPeriodically,domain,_1));
     47  BOOST_FOREACH(atom* iter, atoms){
     48    *iter -= *Center;
     49    *iter -= *CenterBox;
     50    iter->setPosition(domain.WrapPeriodically(iter->getPosition()));
     51  }
    5352
    5453  delete(Center);
     
    6665  Box &domain = World::getInstance().getDomain();
    6766
    68   atoms.transformNodes(boost::bind(&Box::WrapPeriodically,domain,_1));
     67  // go through all atoms
     68  BOOST_FOREACH(atom* iter, atoms){
     69    iter->setPosition(domain.WrapPeriodically(iter->getPosition()));
     70  }
    6971
    7072  return status;
     
    8385  if (iter != end()) { //list not empty?
    8486    for (int i=NDIM;i--;) {
    85       max->at(i) = (*iter)->x[i];
    86       min->at(i) = (*iter)->x[i];
     87      max->at(i) = (*iter)->at(i);
     88      min->at(i) = (*iter)->at(i);
    8789    }
    8890    for (; iter != end(); ++iter) {// continue with second if present
    8991      //(*iter)->Output(1,1,out);
    9092      for (int i=NDIM;i--;) {
    91         max->at(i) = (max->at(i) < (*iter)->x[i]) ? (*iter)->x[i] : max->at(i);
    92         min->at(i) = (min->at(i) > (*iter)->x[i]) ? (*iter)->x[i] : min->at(i);
     93        max->at(i) = (max->at(i) < (*iter)->at(i)) ? (*iter)->at(i) : max->at(i);
     94        min->at(i) = (min->at(i) > (*iter)->at(i)) ? (*iter)->at(i) : min->at(i);
    9395      }
    9496    }
     
    121123    for (; iter != end(); ++iter) {  // continue with second if present
    122124      Num++;
    123       Center += (*iter)->x;
     125      Center += (*iter)->getPosition();
    124126    }
    125127    Center.Scale(-1./(double)Num); // divide through total number (and sign for direction)
     
    143145    for (; iter != end(); ++iter) {  // continue with second if present
    144146      Num++;
    145       (*a) += (*iter)->x;
     147      (*a) += (*iter)->getPosition();
    146148    }
    147149    a->Scale(1./(double)Num); // divide through total mass (and sign for direction)
     
    165167 * \return pointer to center of gravity vector
    166168 */
    167 Vector * molecule::DetermineCenterOfGravity() const
     169Vector * molecule::DetermineCenterOfGravity()
    168170{
    169171  molecule::const_iterator iter = begin();  // start at first in list
     
    176178  if (iter != end()) {   //list not empty?
    177179    for (; iter != end(); ++iter) {  // continue with second if present
    178       Num += (*iter)->type->mass;
    179       tmp = (*iter)->type->mass * (*iter)->x;
     180      Num += (*iter)->getType()->mass;
     181      tmp = (*iter)->getType()->mass * (*iter)->getPosition();
    180182      (*a) += tmp;
    181183    }
     
    221223    for (int j=0;j<MDSteps;j++)
    222224      (*iter)->Trajectory.R.at(j).ScaleAll(*factor);
    223     (*iter)->x.ScaleAll(*factor);
     225    (*iter)->ScaleAll(*factor);
    224226  }
    225227};
     
    233235    for (int j=0;j<MDSteps;j++)
    234236      (*iter)->Trajectory.R.at(j) += (*trans);
    235     (*iter)->x += (*trans);
     237    *(*iter) += (*trans);
    236238  }
    237239};
     
    246248
    247249  // go through all atoms
    248   ActOnAllVectors( &Vector::AddVector, *trans);
    249   atoms.transformNodes(boost::bind(&Box::WrapPeriodically,domain,_1));
     250  BOOST_FOREACH(atom* iter, atoms){
     251    *iter += *trans;
     252    iter->setPosition(domain.WrapPeriodically(iter->getPosition()));
     253  }
    250254
    251255};
     
    259263  OBSERVE;
    260264  Plane p(*n,0);
    261   atoms.transformNodes(boost::bind(&Plane::mirrorVector,p,_1));
     265  BOOST_FOREACH(atom* iter, atoms ){
     266    iter->setPosition(p.mirrorVector(iter->getPosition()));
     267  }
    262268};
    263269
     
    278284    for (molecule::const_iterator iter = begin(); iter != end(); ++iter) {
    279285#ifdef ADDHYDROGEN
    280       if ((*iter)->type->Z != 1) {
     286      if ((*iter)->getType()->Z != 1) {
    281287#endif
    282         Testvector = inversematrix * (*iter)->x;
     288        Testvector = inversematrix * (*iter)->getPosition();
    283289        Translationvector.Zero();
    284290        for (BondList::const_iterator Runner = (*iter)->ListOfBonds.begin(); Runner != (*iter)->ListOfBonds.end(); (++Runner)) {
    285291         if ((*iter)->nr < (*Runner)->GetOtherAtom((*iter))->nr) // otherwise we shift one to, the other fro and gain nothing
    286292            for (int j=0;j<NDIM;j++) {
    287               tmp = (*iter)->x[j] - (*Runner)->GetOtherAtom(*iter)->x[j];
     293              tmp = (*iter)->at(j) - (*Runner)->GetOtherAtom(*iter)->at(j);
    288294              if ((fabs(tmp)) > BondDistance) {
    289295                flag = false;
     
    303309        // now also change all hydrogens
    304310        for (BondList::const_iterator Runner = (*iter)->ListOfBonds.begin(); Runner != (*iter)->ListOfBonds.end(); (++Runner)) {
    305           if ((*Runner)->GetOtherAtom((*iter))->type->Z == 1) {
    306             Testvector = inversematrix * (*Runner)->GetOtherAtom((*iter))->x;
     311          if ((*Runner)->GetOtherAtom((*iter))->getType()->Z == 1) {
     312            Testvector = inversematrix * (*Runner)->GetOtherAtom((*iter))->getPosition();
    307313            Testvector += Translationvector;
    308314            Testvector *= matrix;
     
    319325};
    320326
     327/** Transforms/Rotates the given molecule into its principal axis system.
     328 * \param *out output stream for debugging
     329 * \param DoRotate whether to rotate (true) or only to determine the PAS.
     330 * TODO treatment of trajetories missing
     331 */
     332void molecule::PrincipalAxisSystem(bool DoRotate)
     333{
     334  double InertiaTensor[NDIM*NDIM];
     335  Vector *CenterOfGravity = DetermineCenterOfGravity();
     336
     337  CenterPeriodic();
     338
     339  // reset inertia tensor
     340  for(int i=0;i<NDIM*NDIM;i++)
     341    InertiaTensor[i] = 0.;
     342
     343  // sum up inertia tensor
     344  for (molecule::const_iterator iter = begin(); iter != end(); ++iter) {
     345    Vector x = (*iter)->getPosition();
     346    //x.SubtractVector(CenterOfGravity);
     347    InertiaTensor[0] += (*iter)->getType()->mass*(x[1]*x[1] + x[2]*x[2]);
     348    InertiaTensor[1] += (*iter)->getType()->mass*(-x[0]*x[1]);
     349    InertiaTensor[2] += (*iter)->getType()->mass*(-x[0]*x[2]);
     350    InertiaTensor[3] += (*iter)->getType()->mass*(-x[1]*x[0]);
     351    InertiaTensor[4] += (*iter)->getType()->mass*(x[0]*x[0] + x[2]*x[2]);
     352    InertiaTensor[5] += (*iter)->getType()->mass*(-x[1]*x[2]);
     353    InertiaTensor[6] += (*iter)->getType()->mass*(-x[2]*x[0]);
     354    InertiaTensor[7] += (*iter)->getType()->mass*(-x[2]*x[1]);
     355    InertiaTensor[8] += (*iter)->getType()->mass*(x[0]*x[0] + x[1]*x[1]);
     356  }
     357  // print InertiaTensor for debugging
     358  DoLog(0) && (Log() << Verbose(0) << "The inertia tensor is:" << endl);
     359  for(int i=0;i<NDIM;i++) {
     360    for(int j=0;j<NDIM;j++)
     361      DoLog(0) && (Log() << Verbose(0) << InertiaTensor[i*NDIM+j] << " ");
     362    DoLog(0) && (Log() << Verbose(0) << endl);
     363  }
     364  DoLog(0) && (Log() << Verbose(0) << endl);
     365
     366  // diagonalize to determine principal axis system
     367  gsl_eigen_symmv_workspace *T = gsl_eigen_symmv_alloc(NDIM);
     368  gsl_matrix_view m = gsl_matrix_view_array(InertiaTensor, NDIM, NDIM);
     369  gsl_vector *eval = gsl_vector_alloc(NDIM);
     370  gsl_matrix *evec = gsl_matrix_alloc(NDIM, NDIM);
     371  gsl_eigen_symmv(&m.matrix, eval, evec, T);
     372  gsl_eigen_symmv_free(T);
     373  gsl_eigen_symmv_sort(eval, evec, GSL_EIGEN_SORT_ABS_DESC);
     374
     375  for(int i=0;i<NDIM;i++) {
     376    DoLog(1) && (Log() << Verbose(1) << "eigenvalue = " << gsl_vector_get(eval, i));
     377    DoLog(0) && (Log() << Verbose(0) << ", eigenvector = (" << evec->data[i * evec->tda + 0] << "," << evec->data[i * evec->tda + 1] << "," << evec->data[i * evec->tda + 2] << ")" << endl);
     378  }
     379
     380  // check whether we rotate or not
     381  if (DoRotate) {
     382    DoLog(1) && (Log() << Verbose(1) << "Transforming molecule into PAS ... ");
     383    // the eigenvectors specify the transformation matrix
     384    Matrix M = Matrix(evec->data);
     385    Vector tempVector;
     386    BOOST_FOREACH(atom* iter, atoms){
     387      tempVector = iter->getPosition();
     388      tempVector *= M;
     389      iter->setPosition(tempVector);
     390    }
     391    DoLog(0) && (Log() << Verbose(0) << "done." << endl);
     392
     393    // summing anew for debugging (resulting matrix has to be diagonal!)
     394    // reset inertia tensor
     395    for(int i=0;i<NDIM*NDIM;i++)
     396      InertiaTensor[i] = 0.;
     397
     398    // sum up inertia tensor
     399    for (molecule::const_iterator iter = begin(); iter != end(); ++iter) {
     400      Vector x = (*iter)->getPosition();
     401      InertiaTensor[0] += (*iter)->getType()->mass*(x[1]*x[1] + x[2]*x[2]);
     402      InertiaTensor[1] += (*iter)->getType()->mass*(-x[0]*x[1]);
     403      InertiaTensor[2] += (*iter)->getType()->mass*(-x[0]*x[2]);
     404      InertiaTensor[3] += (*iter)->getType()->mass*(-x[1]*x[0]);
     405      InertiaTensor[4] += (*iter)->getType()->mass*(x[0]*x[0] + x[2]*x[2]);
     406      InertiaTensor[5] += (*iter)->getType()->mass*(-x[1]*x[2]);
     407      InertiaTensor[6] += (*iter)->getType()->mass*(-x[2]*x[0]);
     408      InertiaTensor[7] += (*iter)->getType()->mass*(-x[2]*x[1]);
     409      InertiaTensor[8] += (*iter)->getType()->mass*(x[0]*x[0] + x[1]*x[1]);
     410    }
     411    // print InertiaTensor for debugging
     412    DoLog(0) && (Log() << Verbose(0) << "The inertia tensor is:" << endl);
     413    for(int i=0;i<NDIM;i++) {
     414      for(int j=0;j<NDIM;j++)
     415        DoLog(0) && (Log() << Verbose(0) << InertiaTensor[i*NDIM+j] << " ");
     416      DoLog(0) && (Log() << Verbose(0) << endl);
     417    }
     418    DoLog(0) && (Log() << Verbose(0) << endl);
     419  }
     420
     421  // free everything
     422  delete(CenterOfGravity);
     423  gsl_vector_free(eval);
     424  gsl_matrix_free(evec);
     425};
     426
     427
    321428/** Align all atoms in such a manner that given vector \a *n is along z axis.
    322429 * \param n[] alignment vector.
     
    335442  DoLog(1) && (Log() << Verbose(1) << "Z-X-angle: " << alpha << " ... ");
    336443  for (molecule::const_iterator iter = begin(); iter != end(); ++iter) {
    337     tmp = (*iter)->x[0];
    338     (*iter)->x[0] =  cos(alpha) * tmp + sin(alpha) * (*iter)->x[2];
    339     (*iter)->x[2] = -sin(alpha) * tmp + cos(alpha) * (*iter)->x[2];
     444    tmp = (*iter)->at(0);
     445    (*iter)->set(0,  cos(alpha) * tmp + sin(alpha) * (*iter)->at(2));
     446    (*iter)->set(2, -sin(alpha) * tmp + cos(alpha) * (*iter)->at(2));
    340447    for (int j=0;j<MDSteps;j++) {
    341448      tmp = (*iter)->Trajectory.R.at(j)[0];
     
    354461  DoLog(1) && (Log() << Verbose(1) << "Z-Y-angle: " << alpha << " ... ");
    355462  for (molecule::const_iterator iter = begin(); iter != end(); ++iter) {
    356     tmp = (*iter)->x[1];
    357     (*iter)->x[1] =  cos(alpha) * tmp + sin(alpha) * (*iter)->x[2];
    358     (*iter)->x[2] = -sin(alpha) * tmp + cos(alpha) * (*iter)->x[2];
     463    tmp = (*iter)->at(1);
     464    (*iter)->set(1,  cos(alpha) * tmp + sin(alpha) * (*iter)->at(2));
     465    (*iter)->set(2, -sin(alpha) * tmp + cos(alpha) * (*iter)->at(2));
    359466    for (int j=0;j<MDSteps;j++) {
    360467      tmp = (*iter)->Trajectory.R.at(j)[1];
     
    394501  // go through all atoms
    395502  for (molecule::const_iterator iter = par->mol->begin(); iter != par->mol->end(); ++iter) {
    396     if ((*iter)->type == ((struct lsq_params *)params)->type) { // for specific type
    397       c = (*iter)->x - a;
     503    if ((*iter)->getType() == ((struct lsq_params *)params)->type) { // for specific type
     504      c = (*iter)->getPosition() - a;
    398505      t = c.ScalarProduct(b);           // get direction parameter
    399506      d = t*b;       // and create vector
Note: See TracChangeset for help on using the changeset viewer.