SSAGES  0.1
A MetaDynamics Package
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Groups Pages
GridBase.h
1 
20 #pragma once
21 
22 #include <cmath>
23 #include <exception>
24 #include <vector>
25 
26 namespace SSAGES
27 {
28 
30 
37 template<typename T>
38 class GridBase
39 {
40 protected:
42  std::vector<T> data_;
43 
45  size_t dimension_;
46 
48  std::vector<int> numPoints_;
49 
51  std::pair< std::vector<double>,std::vector<double> > edges_;
52 
54  std::vector<bool> isPeriodic_;
55 
57  std::vector<int> wrapIndices(const std::vector<int> &indices) const
58  {
59  std::vector<int> newIndices(indices);
60  for (size_t i=0; i<dimension_; ++i) {
61  if (!GetPeriodic(i)) {
62  continue;
63  }
64 
65  int index = indices.at(i);
66  while (index < 0) { index += GetNumPoints(i); }
67  while (index >= GetNumPoints(i)) { index -= GetNumPoints(i); }
68  newIndices.at(i) = index;
69  }
70 
71  return newIndices;
72  }
73 
75 
83  virtual size_t mapTo1d(const std::vector<int> &indices) const = 0;
84 
85 protected:
87 
97  GridBase(std::vector<int> numPoints,
98  std::vector<double> lower,
99  std::vector<double> upper,
100  std::vector<bool> isPeriodic)
101  : dimension_(numPoints.size()),
102  numPoints_(numPoints),
103  edges_(std::pair< std::vector<double>, std::vector<double> >(lower, upper)),
104  isPeriodic_(isPeriodic)
105  {
106  // Check that vector sizes are correct
107  if (edges_.first.size() != dimension_ ||
108  edges_.second.size() != dimension_) {
109  throw std::invalid_argument("Size of vector containing upper or "
110  "lower edges, does not match size of vector containing "
111  "number of grid points.");
112  }
113  if (isPeriodic_.size() == 0) {
114  // Default: Non-periodic in all dimensions
115  isPeriodic.resize(dimension_, false);
116  } else if (isPeriodic_.size() != dimension_) {
117  throw std::invalid_argument("Size of vector isPeriodic does not "
118  "match size of vector containing number of grid points.");
119  }
120 
121  }
122 
123 public:
125 
128  size_t GetDimension() const
129  {
130  return dimension_;
131  }
132 
134 
138  const std::vector<int>& GetNumPoints() const
139  {
140  return numPoints_;
141  }
142 
144 
150  int GetNumPoints(size_t dim) const
151  {
152  if (dim >= GetDimension()) {
153  std::cerr << "Warning! Grid size requested for a dimension larger "
154  "than the grid dimensionality!\n";
155  return 0;
156  }
157 
158  return numPoints_.at(dim);
159  }
160 
162 
165  const std::vector<double>& GetLower() const
166  {
167  return edges_.first;
168  }
169 
171 
177  double GetLower(size_t dim) const
178  {
179  if (dim >= GetDimension()) {
180  std::cerr << "Warning! Lower edge requested for a dimension larger "
181  "than the grid dimensionality!\n";
182  return 0.0;
183  }
184  return GetLower().at(dim);
185  }
186 
188 
191  const std::vector<double>& GetUpper() const
192  {
193  return edges_.second;
194  }
195 
196 
198 
204  double GetUpper(size_t dim) const
205  {
206  if (dim >= GetDimension()) {
207  std::cerr << "Warning! Upper edge requested for a dimension larger "
208  "than the grid dimensionality!\n";
209  return 0.0;
210  }
211  return GetUpper().at(dim);
212  }
213 
215 
219  const std::vector<bool>& GetPeriodic() const
220  {
221  return isPeriodic_;
222  }
223 
225 
232  bool GetPeriodic(size_t dim) const
233  {
234  if (dim >= GetDimension()) {
235  std::cerr << "Warning! Periodicity requested for a dimension larger "
236  "than the grid dimensionality!\n";
237  return false;
238  }
239  return GetPeriodic().at(dim);
240  }
241 
243 
250  size_t size() const
251  {
252  return data_.size();
253  }
254 
256 
262  T *data()
263  {
264  return data_.data();
265  }
266 
268 
274  T const *data() const
275  {
276  return data_.data();
277  }
278 
280 
296  std::vector<int> GetIndices(const std::vector<double> &x) const
297  {
298  // Check that input vector has the correct dimensionality
299  if (x.size() != dimension_) {
300  throw std::invalid_argument("Specified point has a larger "
301  "dimensionality than the grid.");
302  }
303 
304  std::vector<int> indices(dimension_);
305  for (size_t i = 0; i < dimension_; ++i) {
306  double xpos = x.at(i);
307  if (!GetPeriodic(i)) {
308  if (xpos < GetLower(i)) {
309  indices.at(i) = -1;
310  continue;
311  } else if (xpos > GetUpper(i)) {
312  indices.at(i) = GetNumPoints(i);
313  continue;
314  }
315  }
316 
317  // To make sure, the value is rounded in the correct direction.
318  double spacing = (GetUpper(i) - GetLower(i)) / GetNumPoints(i);
319  indices.at(i) = std::floor( (xpos - GetLower(i)) / spacing);
320  }
321 
322  return wrapIndices(indices);
323  }
324 
326 
333  double GetInterpolated(const std::vector<double> &x)
334  {
335  double interpvalue = 0;
336  int tempindex;
337  for (size_t i = 0 ; i < pow(2,dimension_) ; ++i)
338  {
339 
340  std::vector<double> shiftedvector = x;
341  tempindex = i;
342 
343  double accumulatedweight = 1;
344  for(size_t j = 0; j < dimension_ ; ++j)
345  {
346  double spacing = (GetUpper(j) - GetLower(j)) / GetNumPoints(j);
347  shiftedvector[j] += ((tempindex%2)-0.5)*spacing;
348  tempindex = tempindex/2;
349  }
350 
351  std::vector<int> shiftedindices = GetIndices(shiftedvector);
352  std::vector<double> shiftedcenters = GetCoordinates(shiftedindices);
353 
354  for(size_t j = 0; j < dimension_ ; ++j)
355  {
356  double spacing = (GetUpper(j) - GetLower(j)) / GetNumPoints(j);
357  //Handle Edges
358  if(shiftedindices[j] == -1)
359  {
360  accumulatedweight *= ((std::abs(x[j]-GetCoordinates(GetIndices(x))[j])/spacing));
361  shiftedvector[j] += spacing/2;
362  }
363  else if (shiftedindices[j] == GetNumPoints(j))
364  {
365  accumulatedweight *= ((std::abs(x[j]-GetCoordinates(GetIndices(x))[j])/spacing));
366  shiftedvector[j] -= spacing/2;
367  }
368  else
369  {
370  // Handle Periodicity
371  if(std::abs(x[j]-shiftedcenters[j]) > spacing)
372  accumulatedweight *= (1-(std::abs(std::abs(x[j]-shiftedcenters[j]) - (GetUpper(j) - GetLower(j)))/spacing));
373  else
374  accumulatedweight *= (1-(std::abs(x[j]-shiftedcenters[j])/spacing));
375  }
376  }
377  interpvalue += accumulatedweight*at(shiftedvector);
378  }
379  return interpvalue;
380  }
381 
383 
391  int GetIndex(double x) const
392  {
393  if (dimension_ != 1) {
394  throw std::invalid_argument("1d Grid index can only be accessed for "
395  "1d-Grids can be accessed with a.");
396  }
397  return GetIndices({x}).at(0);
398  }
399 
401 
409  std::vector<double> GetCoordinates(const std::vector<int> &indices)
410  {
411  if (indices.size() != dimension_) {
412  throw std::invalid_argument(
413  "Grid indices specified for GetCoordinates() do not have "
414  "the same dimensionality as the grid.");
415  }
416 
417  std::vector<double> v(dimension_);
418 
419  for (size_t i = 0; i < dimension_; ++i) {
420  double spacing = (GetUpper(i) - GetLower(i)) / GetNumPoints(i);
421  v.at(i) = GetLower(i) + (indices[i] + 0.5)*spacing;
422  }
423 
424  return v;
425  }
426 
428 
434  double GetCoordinate(int index)
435  {
436  return GetCoordinates({index}).at(0);
437  }
438 
440 
452  const T& at(const std::vector<int> &indices) const
453  {
454  // Check that indices are in bound.
455  if (indices.size() != GetDimension()) {
456  throw std::invalid_argument("Dimension of indices does not match "
457  "dimension of the grid.");
458  }
459 
460  return data_.at(mapTo1d(indices));
461  }
462 
464 
468  T& at(const std::vector<int> &indices)
469  {
470  return const_cast<T&>(static_cast<const GridBase<T>* >(this)->at(indices));
471  }
472 
474 
484  template<typename R>
485  const T& at(std::initializer_list<R>&& x) const
486  {
487  return at(static_cast<std::vector<R> >(x));
488  }
489 
491 
501  template<typename R>
502  T& at(std::initializer_list<R>&& x)
503  {
504  return at(static_cast<std::vector<R> >(x));
505  }
506 
508 
514  const T& at(int index) const
515  {
516  if (dimension_ != 1) {
517  throw std::invalid_argument("Only 1d-Grids can be accessed with a "
518  "single integer as the index.");
519  }
520  return at({index});
521  }
522 
524 
530  T& at(int index)
531  {
532  return const_cast<T&>(static_cast<const GridBase<T>* >(this)->at(index));
533  }
534 
536 
543  const T& at(const std::vector<double> &x) const
544  {
545  return at(GetIndices(x));
546  }
547 
549 
556  T& at(const std::vector<double> &x)
557  {
558  return at(GetIndices(x));
559  }
560 
562 
569  const T& at(double x) const
570  {
571  if (dimension_ != 1) {
572  throw std::invalid_argument("Only 1d-Grids can be accessed with a "
573  "single float as the specified point.");
574  }
575  return at({x});
576  }
577 
579 
585  T& at(double x)
586  {
587  return const_cast<T&>(static_cast<const GridBase<T>* >(this)->at(x));
588  }
589 
591 
595  const T& operator[](const std::vector<int> &indices) const
596  {
597  return at(indices);
598  }
599 
601 
605  T& operator[](const std::vector<int> &indices)
606  {
607  return at(indices);
608  }
609 
611 
621  template<typename R>
622  const T& operator[](std::initializer_list<R>&& x) const
623  {
624  return at(static_cast<std::vector<R> >(x));
625  }
626 
628 
638  template<typename R>
639  T& operator[](std::initializer_list<R>&& x)
640  {
641  return at(static_cast<std::vector<R> >(x));
642  }
643 
645 
651  const T& operator[](int index) const
652  {
653  return at(index);
654  }
655 
657 
663  T& operator[](int index)
664  {
665  return at(index);
666  }
667 
669 
673  const T& operator[](const std::vector<double> &x) const
674  {
675  return at(x);
676  }
677 
679 
683  T& operator[](const std::vector<double> &x)
684  {
685  return at(x);
686  }
687 
689 
695  const T& operator[](double x) const
696  {
697  return at(x);
698  }
699 
701 
707  T& operator[](double x)
708  {
709  return at(x);
710  }
711 };
712 
713 } // End namespace SSAGES
const T & operator[](int index) const
Access 1d-Grid per [] operator, read-only.
Definition: GridBase.h:651
std::vector< double > GetCoordinates(const std::vector< int > &indices)
Return coordinates of the grid center points.
Definition: GridBase.h:409
T & operator[](const std::vector< double > &x)
Access Grid element pertaining to a specific point per [] read-write.
Definition: GridBase.h:683
const T & at(double x) const
Access 1d-Grid by point - read-only.
Definition: GridBase.h:569
T & at(int index)
Access 1d Grid by index, read-write.
Definition: GridBase.h:530
std::pair< std::vector< double >, std::vector< double > > edges_
Edges of the Grid in each dimension.
Definition: GridBase.h:51
T & operator[](const std::vector< int > &indices)
Access Grid element per [] read-write.
Definition: GridBase.h:605
T & at(std::initializer_list< R > &&x)
Access Grid element via initializer list.
Definition: GridBase.h:502
const T & operator[](std::initializer_list< R > &&x) const
Const access of Grid element via initializer list.
Definition: GridBase.h:622
T & at(const std::vector< int > &indices)
Access Grid element read/write.
Definition: GridBase.h:468
std::vector< int > GetIndices(const std::vector< double > &x) const
Return the Grid indices for a given point.
Definition: GridBase.h:296
size_t size() const
Get the size of the internal storage vector.
Definition: GridBase.h:250
double GetInterpolated(const std::vector< double > &x)
Return linear interpolation on a coordinate.
Definition: GridBase.h:333
bool GetPeriodic(size_t dim) const
Get the periodicity in a specific dimension.
Definition: GridBase.h:232
int GetNumPoints(size_t dim) const
Get the number of points for a specific dimension.
Definition: GridBase.h:150
std::vector< T > data_
Internal storage of the data.
Definition: GridBase.h:42
T const * data() const
Get pointer to const of the internal data storage vector.
Definition: GridBase.h:274
const std::vector< bool > & GetPeriodic() const
Return the periodicity of the Grid.
Definition: GridBase.h:219
std::vector< int > wrapIndices(const std::vector< int > &indices) const
Wrap the index around periodic boundaries.
Definition: GridBase.h:57
const T & operator[](const std::vector< int > &indices) const
Access Grid element per [] read-only.
Definition: GridBase.h:595
const std::vector< double > & GetLower() const
Return the lower edges of the Grid.
Definition: GridBase.h:165
std::vector< int > numPoints_
Number of points in each dimension.
Definition: GridBase.h:48
T & at(const std::vector< double > &x)
Access Grid element pertaining to a specific point – read/write.
Definition: GridBase.h:556
const std::vector< double > & GetUpper() const
Return the upper edges of the Grid.
Definition: GridBase.h:191
int GetIndex(double x) const
Return the Grid index for a one-dimensional grid.
Definition: GridBase.h:391
size_t dimension_
Dimension of the grid.
Definition: GridBase.h:45
const T & at(const std::vector< double > &x) const
Access Grid element pertaining to a specific point – read-only.
Definition: GridBase.h:543
virtual size_t mapTo1d(const std::vector< int > &indices) const =0
This function needs to be implemented by child classes.
double GetUpper(size_t dim) const
Get the upper edge for a specific dimension.
Definition: GridBase.h:204
double GetCoordinate(int index)
Return center point of 1d-grid.
Definition: GridBase.h:434
const std::vector< int > & GetNumPoints() const
Get the number of points for all dimensions.
Definition: GridBase.h:138
T & operator[](int index)
Access 1d-Grid per [] operator, read-write.
Definition: GridBase.h:663
T & operator[](double x)
Access 1d-Grid via specific point, read-write.
Definition: GridBase.h:707
const T & operator[](const std::vector< double > &x) const
Access Grid element pertaining to a specific point per [] read-only.
Definition: GridBase.h:673
size_t GetDimension() const
Get the dimension.
Definition: GridBase.h:128
T & at(double x)
Access 1d-Grid by point - read-write.
Definition: GridBase.h:585
const T & at(const std::vector< int > &indices) const
Access Grid element read-only.
Definition: GridBase.h:452
const T & at(std::initializer_list< R > &&x) const
Const access of Grid element via initializer list.
Definition: GridBase.h:485
T * data()
Get pointer to the internal data storage vector.
Definition: GridBase.h:262
double GetLower(size_t dim) const
Get the lower edge for a specific dimension.
Definition: GridBase.h:177
const T & at(int index) const
Access 1d Grid by index, read-only.
Definition: GridBase.h:514
GridBase(std::vector< int > numPoints, std::vector< double > lower, std::vector< double > upper, std::vector< bool > isPeriodic)
Constructor.
Definition: GridBase.h:97
T & operator[](std::initializer_list< R > &&x)
Access Grid element via initializer list.
Definition: GridBase.h:639
std::vector< bool > isPeriodic_
Periodicity of the Grid.
Definition: GridBase.h:54
const T & operator[](double x) const
Access 1d-Grid via specific point, read-only.
Definition: GridBase.h:695
Base class for Grids.
Definition: GridBase.h:38