Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/vector.cpp

    r4b94bb r112b09  
    1212#include "Helpers/Assert.hpp"
    1313#include "Helpers/fast_functions.hpp"
    14 #include "Exceptions/MathException.hpp"
    1514
    1615#include <iostream>
    17 #include <gsl/gsl_blas.h>
    18 
    1916
    2017using namespace std;
     
    2724Vector::Vector()
    2825{
    29   content = gsl_vector_calloc (NDIM);
     26  x[0] = x[1] = x[2] = 0.;
    3027};
    3128
     
    3633Vector::Vector(const Vector& src)
    3734{
    38   content = gsl_vector_alloc(NDIM);
    39   gsl_vector_memcpy(content, src.content);
     35  x[0] = src[0];
     36  x[1] = src[1];
     37  x[2] = src[2];
    4038}
    4139
     
    4442Vector::Vector(const double x1, const double x2, const double x3)
    4543{
    46   content = gsl_vector_alloc(NDIM);
    47   gsl_vector_set(content,0,x1);
    48   gsl_vector_set(content,1,x2);
    49   gsl_vector_set(content,2,x3);
    50 };
    51 
    52 Vector::Vector(gsl_vector *_content) :
    53   content(_content)
    54 {}
     44  x[0] = x1;
     45  x[1] = x2;
     46  x[2] = x3;
     47};
    5548
    5649/**
     
    6053  // check for self assignment
    6154  if(&src!=this){
    62     gsl_vector_memcpy(content, src.content);
     55    x[0] = src[0];
     56    x[1] = src[1];
     57    x[2] = src[2];
    6358  }
    6459  return *this;
     
    6762/** Desctructor of class vector.
    6863 */
    69 Vector::~Vector() {
    70   gsl_vector_free(content);
    71 };
     64Vector::~Vector() {};
    7265
    7366/** Calculates square of distance between this and another vector.
     
    7972  double res = 0.;
    8073  for (int i=NDIM;i--;)
    81     res += (at(i)-y[i])*(at(i)-y[i]);
     74    res += (x[i]-y[i])*(x[i]-y[i]);
    8275  return (res);
    8376};
     
    9790}
    9891
     92/** Calculates distance between this and another vector in a periodic cell.
     93 * \param *y array to second vector
     94 * \param *cell_size 6-dimensional array with (xx, xy, yy, xz, yz, zz) entries specifying the periodic cell
     95 * \return \f$| x - y |\f$
     96 */
     97double Vector::PeriodicDistance(const Vector &y, const double * const cell_size) const
     98{
     99  double res = distance(y), tmp, matrix[NDIM*NDIM];
     100    Vector Shiftedy, TranslationVector;
     101    int N[NDIM];
     102    matrix[0] = cell_size[0];
     103    matrix[1] = cell_size[1];
     104    matrix[2] = cell_size[3];
     105    matrix[3] = cell_size[1];
     106    matrix[4] = cell_size[2];
     107    matrix[5] = cell_size[4];
     108    matrix[6] = cell_size[3];
     109    matrix[7] = cell_size[4];
     110    matrix[8] = cell_size[5];
     111    // in order to check the periodic distance, translate one of the vectors into each of the 27 neighbouring cells
     112    for (N[0]=-1;N[0]<=1;N[0]++)
     113      for (N[1]=-1;N[1]<=1;N[1]++)
     114        for (N[2]=-1;N[2]<=1;N[2]++) {
     115          // create the translation vector
     116          TranslationVector.Zero();
     117          for (int i=NDIM;i--;)
     118            TranslationVector[i] = (double)N[i];
     119          TranslationVector.MatrixMultiplication(matrix);
     120          // add onto the original vector to compare with
     121          Shiftedy = y + TranslationVector;
     122          // get distance and compare with minimum so far
     123          tmp = distance(Shiftedy);
     124          if (tmp < res) res = tmp;
     125        }
     126    return (res);
     127};
     128
     129/** Calculates distance between this and another vector in a periodic cell.
     130 * \param *y array to second vector
     131 * \param *cell_size 6-dimensional array with (xx, xy, yy, xz, yz, zz) entries specifying the periodic cell
     132 * \return \f$| x - y |^2\f$
     133 */
     134double Vector::PeriodicDistanceSquared(const Vector &y, const double * const cell_size) const
     135{
     136  double res = DistanceSquared(y), tmp, matrix[NDIM*NDIM];
     137    Vector Shiftedy, TranslationVector;
     138    int N[NDIM];
     139    matrix[0] = cell_size[0];
     140    matrix[1] = cell_size[1];
     141    matrix[2] = cell_size[3];
     142    matrix[3] = cell_size[1];
     143    matrix[4] = cell_size[2];
     144    matrix[5] = cell_size[4];
     145    matrix[6] = cell_size[3];
     146    matrix[7] = cell_size[4];
     147    matrix[8] = cell_size[5];
     148    // in order to check the periodic distance, translate one of the vectors into each of the 27 neighbouring cells
     149    for (N[0]=-1;N[0]<=1;N[0]++)
     150      for (N[1]=-1;N[1]<=1;N[1]++)
     151        for (N[2]=-1;N[2]<=1;N[2]++) {
     152          // create the translation vector
     153          TranslationVector.Zero();
     154          for (int i=NDIM;i--;)
     155            TranslationVector[i] = (double)N[i];
     156          TranslationVector.MatrixMultiplication(matrix);
     157          // add onto the original vector to compare with
     158          Shiftedy = y + TranslationVector;
     159          // get distance and compare with minimum so far
     160          tmp = DistanceSquared(Shiftedy);
     161          if (tmp < res) res = tmp;
     162        }
     163    return (res);
     164};
     165
     166/** Keeps the vector in a periodic cell, defined by the symmetric \a *matrix.
     167 * \param *out ofstream for debugging messages
     168 * Tries to translate a vector into each adjacent neighbouring cell.
     169 */
     170void Vector::KeepPeriodic(const double * const matrix)
     171{
     172  //  int N[NDIM];
     173  //  bool flag = false;
     174    //vector Shifted, TranslationVector;
     175  //  Log() << Verbose(1) << "Begin of KeepPeriodic." << endl;
     176  //  Log() << Verbose(2) << "Vector is: ";
     177  //  Output(out);
     178  //  Log() << Verbose(0) << endl;
     179    InverseMatrixMultiplication(matrix);
     180    for(int i=NDIM;i--;) { // correct periodically
     181      if (at(i) < 0) {  // get every coefficient into the interval [0,1)
     182        at(i) += ceil(at(i));
     183      } else {
     184        at(i) -= floor(at(i));
     185      }
     186    }
     187    MatrixMultiplication(matrix);
     188  //  Log() << Verbose(2) << "New corrected vector is: ";
     189  //  Output(out);
     190  //  Log() << Verbose(0) << endl;
     191  //  Log() << Verbose(1) << "End of KeepPeriodic." << endl;
     192};
     193
    99194/** Calculates scalar product between this and another vector.
    100195 * \param *y array to second vector
     
    104199{
    105200  double res = 0.;
    106   gsl_blas_ddot(content, y.content, &res);
     201  for (int i=NDIM;i--;)
     202    res += x[i]*y[i];
    107203  return (res);
    108204};
     
    118214{
    119215  Vector tmp;
    120   for(int i=NDIM;i--;)
    121     tmp[i] = at((i+1)%NDIM)*y[(i+2)%NDIM] - at((i+2)%NDIM)*y[(i+1)%NDIM];
     216  tmp[0] = x[1]* y[2] - x[2]* y[1];
     217  tmp[1] = x[2]* y[0] - x[0]* y[2];
     218  tmp[2] = x[0]* y[1] - x[1]* y[0];
    122219  (*this) = tmp;
    123220};
     
    212309bool Vector::IsZero() const
    213310{
    214   return (fabs(at(0))+fabs(at(1))+fabs(at(2)) < MYEPSILON);
     311  return (fabs(x[0])+fabs(x[1])+fabs(x[2]) < MYEPSILON);
    215312};
    216313
     
    241338  bool status = true;
    242339  for (int i=0;i<NDIM;i++) {
    243     if (fabs(at(i) - a[i]) > MYEPSILON)
     340    if (fabs(x[i] - a[i]) > MYEPSILON)
    244341      status = false;
    245342  }
     
    269366double& Vector::operator[](size_t i){
    270367  ASSERT(i<=NDIM && i>=0,"Vector Index out of Range");
    271   return *gsl_vector_ptr (content, i);
     368  return x[i];
    272369}
    273370
    274371const double& Vector::operator[](size_t i) const{
    275372  ASSERT(i<=NDIM && i>=0,"Vector Index out of Range");
    276   return *gsl_vector_ptr (content, i);
     373  return x[i];
    277374}
    278375
     
    285382}
    286383
    287 gsl_vector* Vector::get(){
    288   return content;
     384double* Vector::get(){
     385  return x;
    289386}
    290387
     
    401498{
    402499  for (int i=NDIM;i--;)
    403     at(i) *= factor[i];
    404 };
    405 
    406 void Vector::ScaleAll(const Vector &factor){
    407   gsl_vector_mul(content, factor.content);
    408 }
     500    x[i] *= factor[i];
     501};
     502
    409503
    410504
    411505void Vector::Scale(const double factor)
    412506{
    413   gsl_vector_scale(content,factor);
     507  for (int i=NDIM;i--;)
     508    x[i] *= factor;
     509};
     510
     511/** Given a box by its matrix \a *M and its inverse *Minv the vector is made to point within that box.
     512 * \param *M matrix of box
     513 * \param *Minv inverse matrix
     514 */
     515void Vector::WrapPeriodically(const double * const M, const double * const Minv)
     516{
     517  MatrixMultiplication(Minv);
     518  // truncate to [0,1] for each axis
     519  for (int i=0;i<NDIM;i++) {
     520    //x[i] += 0.5;  // set to center of box
     521    while (x[i] >= 1.)
     522      x[i] -= 1.;
     523    while (x[i] < 0.)
     524      x[i] += 1.;
     525  }
     526  MatrixMultiplication(M);
    414527};
    415528
     
    431544}
    432545
     546/** Do a matrix multiplication.
     547 * \param *matrix NDIM_NDIM array
     548 */
     549void Vector::MatrixMultiplication(const double * const M)
     550{
     551  // do the matrix multiplication
     552  at(0) = M[0]*x[0]+M[3]*x[1]+M[6]*x[2];
     553  at(1) = M[1]*x[0]+M[4]*x[1]+M[7]*x[2];
     554  at(2) = M[2]*x[0]+M[5]*x[1]+M[8]*x[2];
     555};
     556
     557/** Do a matrix multiplication with the \a *A' inverse.
     558 * \param *matrix NDIM_NDIM array
     559 */
     560bool Vector::InverseMatrixMultiplication(const double * const A)
     561{
     562  double B[NDIM*NDIM];
     563  double detA = RDET3(A);
     564  double detAReci;
     565
     566  // calculate the inverse B
     567  if (fabs(detA) > MYEPSILON) {;  // RDET3(A) yields precisely zero if A irregular
     568    detAReci = 1./detA;
     569    B[0] =  detAReci*RDET2(A[4],A[5],A[7],A[8]);    // A_11
     570    B[1] = -detAReci*RDET2(A[1],A[2],A[7],A[8]);    // A_12
     571    B[2] =  detAReci*RDET2(A[1],A[2],A[4],A[5]);    // A_13
     572    B[3] = -detAReci*RDET2(A[3],A[5],A[6],A[8]);    // A_21
     573    B[4] =  detAReci*RDET2(A[0],A[2],A[6],A[8]);    // A_22
     574    B[5] = -detAReci*RDET2(A[0],A[2],A[3],A[5]);    // A_23
     575    B[6] =  detAReci*RDET2(A[3],A[4],A[6],A[7]);    // A_31
     576    B[7] = -detAReci*RDET2(A[0],A[1],A[6],A[7]);    // A_32
     577    B[8] =  detAReci*RDET2(A[0],A[1],A[3],A[4]);    // A_33
     578
     579    // do the matrix multiplication
     580    at(0) = B[0]*x[0]+B[3]*x[1]+B[6]*x[2];
     581    at(1) = B[1]*x[0]+B[4]*x[1]+B[7]*x[2];
     582    at(2) = B[2]*x[0]+B[5]*x[1]+B[8]*x[2];
     583
     584    return true;
     585  } else {
     586    return false;
     587  }
     588};
     589
     590
    433591/** Creates this vector as the b y *factors' components scaled linear combination of the given three.
    434592 * this vector = x1*factors[0] + x2* factors[1] + x3*factors[2]
     
    458616  SubtractVector(x1);
    459617  for (int i=NDIM;i--;)
    460     result = result || (fabs(at(i)) > MYEPSILON);
     618    result = result || (fabs(x[i]) > MYEPSILON);
    461619
    462620  return result;
     
    519677void Vector::AddVector(const Vector &y)
    520678{
    521   gsl_vector_add(content, y.content);
     679  for(int i=NDIM;i--;)
     680    x[i] += y[i];
    522681}
    523682
     
    527686void Vector::SubtractVector(const Vector &y)
    528687{
    529   gsl_vector_sub(content, y.content);
     688  for(int i=NDIM;i--;)
     689    x[i] -= y[i];
     690}
     691
     692/**
     693 * Checks whether this vector is within the parallelepiped defined by the given three vectors and
     694 * their offset.
     695 *
     696 * @param offest for the origin of the parallelepiped
     697 * @param three vectors forming the matrix that defines the shape of the parallelpiped
     698 */
     699bool Vector::IsInParallelepiped(const Vector &offset, const double * const parallelepiped) const
     700{
     701  Vector a = (*this)-offset;
     702  a.InverseMatrixMultiplication(parallelepiped);
     703  bool isInside = true;
     704
     705  for (int i=NDIM;i--;)
     706    isInside = isInside && ((a[i] <= 1) && (a[i] >= 0));
     707
     708  return isInside;
    530709}
    531710
Note: See TracChangeset for help on using the changeset viewer.