Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/molecule_geometry.cpp

    rd74077 r4bb63c  
    1010#endif
    1111
     12#include "Helpers/helpers.hpp"
     13#include "Helpers/Log.hpp"
    1214#include "Helpers/MemDebug.hpp"
     15#include "Helpers/Verbose.hpp"
     16#include "LinearAlgebra/Line.hpp"
     17#include "LinearAlgebra/Matrix.hpp"
     18#include "LinearAlgebra/Plane.hpp"
    1319
    1420#include "atom.hpp"
     
    1622#include "config.hpp"
    1723#include "element.hpp"
    18 #include "helpers.hpp"
    1924#include "leastsquaremin.hpp"
    20 #include "verbose.hpp"
    21 #include "log.hpp"
    2225#include "molecule.hpp"
    2326#include "World.hpp"
    24 #include "Plane.hpp"
    25 #include "Matrix.hpp"
     27
    2628#include "Box.hpp"
     29
    2730#include <boost/foreach.hpp>
    2831
     
    4548
    4649  // go through all atoms
    47   BOOST_FOREACH(atom* iter, atoms){
    48     *iter -= *Center;
    49     *iter -= *CenterBox;
    50     iter->setPosition(domain.WrapPeriodically(iter->getPosition()));
    51   }
     50  ActOnAllVectors( &Vector::SubtractVector, *Center);
     51  ActOnAllVectors( &Vector::SubtractVector, *CenterBox);
     52  atoms.transformNodes(boost::bind(&Box::WrapPeriodically,domain,_1));
    5253
    5354  delete(Center);
     
    6566  Box &domain = World::getInstance().getDomain();
    6667
    67   // go through all atoms
    68   BOOST_FOREACH(atom* iter, atoms){
    69     iter->setPosition(domain.WrapPeriodically(iter->getPosition()));
    70   }
     68  atoms.transformNodes(boost::bind(&Box::WrapPeriodically,domain,_1));
    7169
    7270  return status;
     
    8583  if (iter != end()) { //list not empty?
    8684    for (int i=NDIM;i--;) {
    87       max->at(i) = (*iter)->at(i);
    88       min->at(i) = (*iter)->at(i);
     85      max->at(i) = (*iter)->x[i];
     86      min->at(i) = (*iter)->x[i];
    8987    }
    9088    for (; iter != end(); ++iter) {// continue with second if present
    9189      //(*iter)->Output(1,1,out);
    9290      for (int i=NDIM;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);
     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);
    9593      }
    9694    }
     
    123121    for (; iter != end(); ++iter) {  // continue with second if present
    124122      Num++;
    125       Center += (*iter)->getPosition();
     123      Center += (*iter)->x;
    126124    }
    127125    Center.Scale(-1./(double)Num); // divide through total number (and sign for direction)
     
    145143    for (; iter != end(); ++iter) {  // continue with second if present
    146144      Num++;
    147       (*a) += (*iter)->getPosition();
     145      (*a) += (*iter)->x;
    148146    }
    149147    a->Scale(1./(double)Num); // divide through total mass (and sign for direction)
     
    167165 * \return pointer to center of gravity vector
    168166 */
    169 Vector * molecule::DetermineCenterOfGravity()
     167Vector * molecule::DetermineCenterOfGravity() const
    170168{
    171169  molecule::const_iterator iter = begin();  // start at first in list
     
    178176  if (iter != end()) {   //list not empty?
    179177    for (; iter != end(); ++iter) {  // continue with second if present
    180       Num += (*iter)->getType()->mass;
    181       tmp = (*iter)->getType()->mass * (*iter)->getPosition();
     178      Num += (*iter)->type->mass;
     179      tmp = (*iter)->type->mass * (*iter)->x;
    182180      (*a) += tmp;
    183181    }
     
    223221    for (int j=0;j<MDSteps;j++)
    224222      (*iter)->Trajectory.R.at(j).ScaleAll(*factor);
    225     (*iter)->ScaleAll(*factor);
     223    (*iter)->x.ScaleAll(*factor);
    226224  }
    227225};
     
    235233    for (int j=0;j<MDSteps;j++)
    236234      (*iter)->Trajectory.R.at(j) += (*trans);
    237     *(*iter) += (*trans);
     235    (*iter)->x += (*trans);
    238236  }
    239237};
     
    248246
    249247  // go through all atoms
    250   BOOST_FOREACH(atom* iter, atoms){
    251     *iter += *trans;
    252     iter->setPosition(domain.WrapPeriodically(iter->getPosition()));
    253   }
     248  ActOnAllVectors( &Vector::AddVector, *trans);
     249  atoms.transformNodes(boost::bind(&Box::WrapPeriodically,domain,_1));
    254250
    255251};
     
    263259  OBSERVE;
    264260  Plane p(*n,0);
    265   BOOST_FOREACH(atom* iter, atoms ){
    266     iter->setPosition(p.mirrorVector(iter->getPosition()));
    267   }
     261  atoms.transformNodes(boost::bind(&Plane::mirrorVector,p,_1));
    268262};
    269263
     
    284278    for (molecule::const_iterator iter = begin(); iter != end(); ++iter) {
    285279#ifdef ADDHYDROGEN
    286       if ((*iter)->getType()->Z != 1) {
     280      if ((*iter)->type->Z != 1) {
    287281#endif
    288         Testvector = inversematrix * (*iter)->getPosition();
     282        Testvector = inversematrix * (*iter)->x;
    289283        Translationvector.Zero();
    290284        for (BondList::const_iterator Runner = (*iter)->ListOfBonds.begin(); Runner != (*iter)->ListOfBonds.end(); (++Runner)) {
    291285         if ((*iter)->nr < (*Runner)->GetOtherAtom((*iter))->nr) // otherwise we shift one to, the other fro and gain nothing
    292286            for (int j=0;j<NDIM;j++) {
    293               tmp = (*iter)->at(j) - (*Runner)->GetOtherAtom(*iter)->at(j);
     287              tmp = (*iter)->x[j] - (*Runner)->GetOtherAtom(*iter)->x[j];
    294288              if ((fabs(tmp)) > BondDistance) {
    295289                flag = false;
     
    309303        // now also change all hydrogens
    310304        for (BondList::const_iterator Runner = (*iter)->ListOfBonds.begin(); Runner != (*iter)->ListOfBonds.end(); (++Runner)) {
    311           if ((*Runner)->GetOtherAtom((*iter))->getType()->Z == 1) {
    312             Testvector = inversematrix * (*Runner)->GetOtherAtom((*iter))->getPosition();
     305          if ((*Runner)->GetOtherAtom((*iter))->type->Z == 1) {
     306            Testvector = inversematrix * (*Runner)->GetOtherAtom((*iter))->x;
    313307            Testvector += Translationvector;
    314308            Testvector *= matrix;
     
    325319};
    326320
    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  */
    332 void 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 
    428321/** Align all atoms in such a manner that given vector \a *n is along z axis.
    429322 * \param n[] alignment vector.
     
    442335  DoLog(1) && (Log() << Verbose(1) << "Z-X-angle: " << alpha << " ... ");
    443336  for (molecule::const_iterator iter = begin(); iter != end(); ++iter) {
    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));
     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];
    447340    for (int j=0;j<MDSteps;j++) {
    448341      tmp = (*iter)->Trajectory.R.at(j)[0];
     
    461354  DoLog(1) && (Log() << Verbose(1) << "Z-Y-angle: " << alpha << " ... ");
    462355  for (molecule::const_iterator iter = begin(); iter != end(); ++iter) {
    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));
     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];
    466359    for (int j=0;j<MDSteps;j++) {
    467360      tmp = (*iter)->Trajectory.R.at(j)[1];
     
    501394  // go through all atoms
    502395  for (molecule::const_iterator iter = par->mol->begin(); iter != par->mol->end(); ++iter) {
    503     if ((*iter)->getType() == ((struct lsq_params *)params)->type) { // for specific type
    504       c = (*iter)->getPosition() - a;
     396    if ((*iter)->type == ((struct lsq_params *)params)->type) { // for specific type
     397      c = (*iter)->x - a;
    505398      t = c.ScalarProduct(b);           // get direction parameter
    506399      d = t*b;       // and create vector
Note: See TracChangeset for help on using the changeset viewer.