OpenMPCD
RemotelyStoredVector.hpp
Go to the documentation of this file.
1 /**
2  * @file
3  * Defines the OpenMPCD::RemotelyStoredVector class.
4  */
5 
6 #ifndef OPENMPCD_REMOTELYSTOREDVECTOR_HPP
7 #define OPENMPCD_REMOTELYSTOREDVECTOR_HPP
8 
10 #include <OpenMPCD/Exceptions.hpp>
11 #include <OpenMPCD/Types.hpp>
12 #include <OpenMPCD/Vector3D.hpp>
13 
14 #include <boost/static_assert.hpp>
15 #include <boost/type_traits/add_const.hpp>
16 #include <boost/type_traits/remove_const.hpp>
17 #include <cmath>
18 
19 namespace OpenMPCD
20 {
21  /**
22  * Represents a vector whose data is stored elsewhere.
23  * @tparam T The type stored.
24  * @tparam D The dimensionality of the vector.
25  */
26  template<typename T, unsigned int D=3> class RemotelyStoredVector
27  {
28  BOOST_STATIC_ASSERT(D != 0);
29 
30  public:
31  /**
32  * The constructor.
33  * @param[in] storageBase The base address of the storage.
34  * @param[in] vectorID The ID of the vector in the given storage.
35  */
37  RemotelyStoredVector(T* const storageBase, const std::size_t vectorID=0)
38  : storage(storageBase + D * vectorID)
39  {
40  }
41 
42  /**
43  * The copy constructor.
44  * @param[in] rhs The right-hand-side instance.
45  */
48  : storage(rhs.storage)
49  {
50  }
51 
52  public:
53  /**
54  * Returns the coodinate with the given index.
55  * @throw OutOfBoundsException If OPENMPCD_DEBUG is defined, in Host code, throws if i >= D.
56  * @param[in] i The coordinate index.
57  */
59  T get(const unsigned int i) const
60  {
61  #if defined(OPENMPCD_DEBUG) && !defined(__CUDA_ARCH__)
62  if(i >= D)
64  #endif
65  return storage[i];
66  }
67 
68  /**
69  * Returns the x coodinate.
70  */
72  T getX() const
73  {
74  return storage[0];
75  }
76 
77  /**
78  * Sets the x coordinate.
79  * @param[in] val The new value.
80  */
82  void setX(const T val)
83  {
84  storage[0] = val;
85  }
86 
87  /**
88  * Adds the given value to the x coordinate.
89  * @param[in] val The value to add
90  */
92  void addToX(const T val)
93  {
94  storage[0] += val;
95  }
96 
97  /**
98  * Returns the y coodinate.
99  */
101  T getY() const
102  {
103  BOOST_STATIC_ASSERT(D >= 2);
104 
105  return storage[1];
106  }
107 
108  /**
109  * Sets the y coordinate.
110  * @param[in] val The new value.
111  */
113  void setY(const FP val)
114  {
115  BOOST_STATIC_ASSERT(D >= 2);
116 
117  storage[1] = val;
118  }
119 
120  /**
121  * Returns the z coodinate.
122  */
124  FP getZ() const
125  {
126  BOOST_STATIC_ASSERT(D >= 3);
127 
128  return storage[2];
129  }
130 
131  /**
132  * Sets the z coordinate.
133  * @param[in] val The new value.
134  */
136  void setZ(const FP val)
137  {
138  BOOST_STATIC_ASSERT(D >= 3);
139 
140  storage[2] = val;
141  }
142 
143  /**
144  * Atomically adds the right-hand-side instance to this instance.
145  * @param[in] rhs The right-hand-side.
146  */
148  void atomicAdd(const RemotelyStoredVector<typename boost::add_const<T>::type, D>& rhs);
149 
150  /**
151  * Atomically adds the right-hand-side instance to this instance.
152  * @param[in] rhs The right-hand-side.
153  */
155  void atomicAdd(const RemotelyStoredVector<typename boost::remove_const<T>::type, D>& rhs);
156 
157  /**
158  * Atomically adds the right-hand-side instance to this instance.
159  * @param[in] rhs The right-hand-side.
160  */
162  void atomicAdd(const Vector3D<typename boost::remove_const<T>::type>& rhs);
163 
164  public:
165  /**
166  * Returns the scalar product of this vector with the given vector.
167  * @param[in] rhs The right-hand-side.
168  */
170  T dot(const RemotelyStoredVector& rhs) const
171  {
172  typename boost::remove_const<T>::type ret = 0;
173  for(std::size_t i=0; i<D; ++i)
174  ret += storage[i] * rhs.storage[i];
175  return ret;
176  }
177 
178  /**
179  * Returns the square of the magnitude of this vector.
180  */
183  {
184  return dot(*this);
185  }
186 
187  /**
188  * Returns the magnitude of this vector.
189  */
191  T getMagnitude() const
192  {
193  return sqrt(dot(*this));
194  }
195 
196  /**
197  * Returns whether all components are finite, i.e. neither infinite nor NaN.
198  */
200  bool isFinite() const
201  {
202  #ifndef __CUDA_ARCH__
203  using std::isfinite;
204  #endif
205 
206  for(std::size_t i=0; i<D; ++i)
207  {
208  if(!isfinite(storage[i]))
209  return false;
210  }
211 
212  return true;
213  }
214 
215  public:
216  /**
217  * The assignment operator.
218  * @param[in] rhs The right-hand-side instance.
219  * @return Returns this instance.
220  */
223  {
224  for(std::size_t i=0; i<D; ++i)
225  storage[i] = rhs.storage[i];
226 
227  return *this;
228  }
229 
230  /**
231  * The assignment operator.
232  * @param[in] rhs The right-hand-side instance.
233  * @return Returns this instance.
234  */
237  {
238  BOOST_STATIC_ASSERT(D == 3);
239 
240  storage[0] = rhs.getX();
241  storage[1] = rhs.getY();
242  storage[2] = rhs.getZ();
243 
244  return *this;
245  }
246 
247  /**
248  * The addition-and-assignment operator.
249  * @param[in] rhs The right-hand-side instance.
250  * @return Returns this instance.
251  */
254  {
255  BOOST_STATIC_ASSERT(D == 3);
256 
257  storage[0] += rhs.getX();
258  storage[1] += rhs.getY();
259  storage[2] += rhs.getZ();
260 
261  return *this;
262  }
263 
264  /**
265  * Addition operator.
266  * @param[in] rhs The right-hand-side vector.
267  */
270  operator+(const RemotelyStoredVector& rhs) const
271  {
272  BOOST_STATIC_ASSERT(D == 3);
273 
275  getX() + rhs.getX(),
276  getY() + rhs.getY(),
277  getZ() + rhs.getZ());
278  }
279 
280  /**
281  * Addition operator.
282  * @param[in] rhs The right-hand-side vector.
283  */
286  operator+(const Vector3D<typename boost::remove_const<T>::type>& rhs) const
287  {
288  BOOST_STATIC_ASSERT(D == 3);
289 
290  return Vector3D<T>(
291  getX() + rhs.getX(),
292  getY() + rhs.getY(),
293  getZ() + rhs.getZ());
294  }
295 
296  /**
297  * Substraction operator.
298  * @param[in] rhs The right-hand-side vector.
299  */
302  operator-(const RemotelyStoredVector& rhs) const
303  {
304  BOOST_STATIC_ASSERT(D == 3);
305 
307  getX() - rhs.getX(),
308  getY() - rhs.getY(),
309  getZ() - rhs.getZ());
310  }
311 
312  /**
313  * Substraction operator.
314  * @param[in] rhs The right-hand-side vector.
315  */
318  operator-(const Vector3D<typename boost::remove_const<T>::type>& rhs) const
319  {
320  BOOST_STATIC_ASSERT(D == 3);
321 
322  return Vector3D<T>(
323  getX() - rhs.getX(),
324  getY() - rhs.getY(),
325  getZ() - rhs.getZ());
326  }
327 
328  /**
329  * The scalar multiplication-and-assignment operator.
330  * @param[in] rhs The scalar factor.
331  * @return Returns this instance.
332  */
335  {
336  BOOST_STATIC_ASSERT(D == 3);
337 
338  storage[0] *= rhs;
339  storage[1] *= rhs;
340  storage[2] *= rhs;
341 
342  return *this;
343  }
344 
345  /**
346  * The scalar multiplication operator.
347  * @param[in] rhs The scalar factor.
348  */
351  {
352  BOOST_STATIC_ASSERT(D == 3);
353 
355  getX() * rhs,
356  getY() * rhs,
357  getZ() * rhs);
358  }
359 
360  /**
361  * Scalar division operator.
362  * @param[in] rhs The right-hand-side scalar.
363  */
366  {
367  BOOST_STATIC_ASSERT(D == 3);
368 
370  getX() / rhs,
371  getY() / rhs,
372  getZ() / rhs);
373  }
374 
375  /**
376  * Scalar division-and-assignment operator.
377  * @param[in] rhs The right-hand-side scalar.
378  */
381  {
382  BOOST_STATIC_ASSERT(D == 3);
383 
384  storage[0] /= rhs;
385  storage[1] /= rhs;
386  storage[2] /= rhs;
387 
388  return *this;
389  }
390 
391  /**
392  * Converts this instance into a Vector3D.
393  */
396  {
397  BOOST_STATIC_ASSERT(D == 3);
398 
400  }
401 
402  /**
403  * The comparison operator.
404  *
405  * @param[in] rhs The right-hand-side value.
406  */
409  const Vector3D<typename boost::remove_const<T>::type>& rhs)
410  const
411  {
412  BOOST_STATIC_ASSERT(D == 3);
413 
414  if(storage[0] != rhs.getX())
415  return false;
416  if(storage[1] != rhs.getY())
417  return false;
418  if(storage[2] != rhs.getZ())
419  return false;
420  return true;
421  }
422 
423  /**
424  * The inequality operator.
425  *
426  * @param[in] rhs The right-hand-side value.
427  */
430  const Vector3D<typename boost::remove_const<T>::type>& rhs)
431  const
432  {
433  BOOST_STATIC_ASSERT(D == 3);
434 
435  return !operator==(rhs);
436  }
437 
438  /**
439  * Output operator for streams.
440  *
441  * Appends `vector.getX()`, `vector.getY()`, and `vector.getZ()` to
442  * the stream in that order, separated by single spaces (`" "`).
443  *
444  * @param[in] stream The stream to print to.
445  * @param[in] vector The vector to print.
446  */
447  friend std::ostream&
448  operator<<(std::ostream& stream, const RemotelyStoredVector& vector)
449  {
450  stream
451  << vector.getX() << " "
452  << vector.getY() << " "
453  << vector.getZ();
454  return stream;
455  }
456 
457  private:
458  T* const storage; ///< The data storage.
459  };
460 
461 
462 
463  /**
464  * Addition-and-assignment operator.
465  * @tparam L The numeric type of the left-hand-side.
466  * @tparam R The numeric type of the left-hand-side.
467  * @param[in] lhs The left-hand-side.
468  * @param[in] rhs The right-hand-side.
469  */
470  template<typename L, typename R>
473  {
474  lhs.addToX(rhs.getX());
475  lhs.addToY(rhs.getY());
476  lhs.addToZ(rhs.getZ());
477 
478  return lhs;
479  }
480 }
481 
482 #endif
OpenMPCD::RemotelyStoredVector::RemotelyStoredVector
OPENMPCD_CUDA_HOST_AND_DEVICE RemotelyStoredVector(T *const storageBase, const std::size_t vectorID=0)
The constructor.
Definition: RemotelyStoredVector.hpp:37
OpenMPCD::RemotelyStoredVector::RemotelyStoredVector
OPENMPCD_CUDA_HOST_AND_DEVICE RemotelyStoredVector(const RemotelyStoredVector< T, D > &rhs)
The copy constructor.
Definition: RemotelyStoredVector.hpp:47
OpenMPCD::RemotelyStoredVector::operator<<
friend std::ostream & operator<<(std::ostream &stream, const RemotelyStoredVector &vector)
Output operator for streams.
Definition: RemotelyStoredVector.hpp:448
OpenMPCD::RemotelyStoredVector
Represents a vector whose data is stored elsewhere.
Definition: RemotelyStoredVector.hpp:26
OpenMPCD::RemotelyStoredVector::operator+
const OPENMPCD_CUDA_HOST_AND_DEVICE Vector3D< typename boost::remove_const< T >::type > operator+(const Vector3D< typename boost::remove_const< T >::type > &rhs) const
Addition operator.
Definition: RemotelyStoredVector.hpp:286
OpenMPCD::RemotelyStoredVector::operator*=
const OPENMPCD_CUDA_HOST_AND_DEVICE RemotelyStoredVector & operator*=(const FP rhs)
The scalar multiplication-and-assignment operator.
Definition: RemotelyStoredVector.hpp:334
OpenMPCD::RemotelyStoredVector::setX
OPENMPCD_CUDA_HOST_AND_DEVICE void setX(const T val)
Sets the x coordinate.
Definition: RemotelyStoredVector.hpp:82
Exceptions.hpp
OpenMPCD::Vector3D::getZ
OPENMPCD_CUDA_HOST_AND_DEVICE T getZ() const
Returns the z coordinate.
Definition: Vector3D.hpp:119
OPENMPCD_THROW
#define OPENMPCD_THROW(ExceptionType, message)
Throws the given ExceptionType, passing the given message along with file and line number information...
Definition: Exceptions.hpp:22
OpenMPCD::Vector3D
3-dimensional vector.
Definition: Vector3D.hpp:38
OpenMPCD::RemotelyStoredVector::operator==
OPENMPCD_CUDA_HOST_AND_DEVICE bool operator==(const Vector3D< typename boost::remove_const< T >::type > &rhs) const
The comparison operator.
Definition: RemotelyStoredVector.hpp:408
OpenMPCD::RemotelyStoredVector::operator*
const OPENMPCD_CUDA_HOST_AND_DEVICE Vector3D< typename boost::remove_const< T >::type > operator*(const FP rhs) const
The scalar multiplication operator.
Definition: RemotelyStoredVector.hpp:350
OpenMPCD::RemotelyStoredVector::getMagnitude
OPENMPCD_CUDA_HOST_AND_DEVICE T getMagnitude() const
Returns the magnitude of this vector.
Definition: RemotelyStoredVector.hpp:191
OpenMPCD::Vector3D::getX
OPENMPCD_CUDA_HOST_AND_DEVICE T getX() const
Returns the x coordinate.
Definition: Vector3D.hpp:61
OpenMPCD::RemotelyStoredVector::operator-
const OPENMPCD_CUDA_HOST_AND_DEVICE Vector3D< typename boost::remove_const< T >::type > operator-(const RemotelyStoredVector &rhs) const
Substraction operator.
Definition: RemotelyStoredVector.hpp:302
OpenMPCD::RemotelyStoredVector::operator/=
const OPENMPCD_CUDA_HOST_AND_DEVICE RemotelyStoredVector operator/=(const FP rhs)
Scalar division-and-assignment operator.
Definition: RemotelyStoredVector.hpp:380
OpenMPCD::RemotelyStoredVector::setY
OPENMPCD_CUDA_HOST_AND_DEVICE void setY(const FP val)
Sets the y coordinate.
Definition: RemotelyStoredVector.hpp:113
OpenMPCD::RemotelyStoredVector::setZ
OPENMPCD_CUDA_HOST_AND_DEVICE void setZ(const FP val)
Sets the z coordinate.
Definition: RemotelyStoredVector.hpp:136
OPENMPCD_CUDA_DEVICE
#define OPENMPCD_CUDA_DEVICE
Denotes a function to be callable from a CUDA Device.
Definition: Macros.hpp:25
OPENMPCD_CUDA_HOST_AND_DEVICE
#define OPENMPCD_CUDA_HOST_AND_DEVICE
Denotes a function to be callable both from the Host and from a CUDA Device.
Definition: Macros.hpp:15
OpenMPCD::Vector3D::getY
OPENMPCD_CUDA_HOST_AND_DEVICE T getY() const
Returns the y coordinate.
Definition: Vector3D.hpp:90
OpenMPCD::Vector3D::addToX
OPENMPCD_CUDA_HOST_AND_DEVICE void addToX(const T val)
Adds the given value to the x coordinate.
Definition: Vector3D.hpp:81
OpenMPCD::RemotelyStoredVector::getY
OPENMPCD_CUDA_HOST_AND_DEVICE T getY() const
Returns the y coodinate.
Definition: RemotelyStoredVector.hpp:101
OpenMPCD::operator+=
const OPENMPCD_CUDA_HOST_AND_DEVICE Vector3D< L > & operator+=(Vector3D< L > &lhs, const RemotelyStoredVector< R, 3 > &rhs)
Addition-and-assignment operator.
Definition: RemotelyStoredVector.hpp:472
OpenMPCD::RemotelyStoredVector::operator-
const OPENMPCD_CUDA_HOST_AND_DEVICE Vector3D< typename boost::remove_const< T >::type > operator-(const Vector3D< typename boost::remove_const< T >::type > &rhs) const
Substraction operator.
Definition: RemotelyStoredVector.hpp:318
OpenMPCD::RemotelyStoredVector::atomicAdd
OPENMPCD_CUDA_DEVICE void atomicAdd(const RemotelyStoredVector< typename boost::add_const< T >::type, D > &rhs)
Atomically adds the right-hand-side instance to this instance.
OpenMPCD::RemotelyStoredVector::operator+=
const OPENMPCD_CUDA_HOST_AND_DEVICE RemotelyStoredVector & operator+=(const Vector3D< T > &rhs)
The addition-and-assignment operator.
Definition: RemotelyStoredVector.hpp:253
OpenMPCD::RemotelyStoredVector::operator/
const OPENMPCD_CUDA_HOST_AND_DEVICE Vector3D< typename boost::remove_const< T >::type > operator/(const FP rhs) const
Scalar division operator.
Definition: RemotelyStoredVector.hpp:365
Vector3D.hpp
OpenMPCD::RemotelyStoredVector::operator=
const OPENMPCD_CUDA_HOST_AND_DEVICE RemotelyStoredVector & operator=(const RemotelyStoredVector &rhs)
The assignment operator.
Definition: RemotelyStoredVector.hpp:222
OpenMPCD::Vector3D::addToZ
OPENMPCD_CUDA_HOST_AND_DEVICE void addToZ(const T val)
Adds the given value to the z coordinate.
Definition: Vector3D.hpp:139
OpenMPCD::FP
double FP
Default floating point type.
Definition: Types.hpp:13
OpenMPCD::RemotelyStoredVector::get
OPENMPCD_CUDA_HOST_AND_DEVICE T get(const unsigned int i) const
Returns the coodinate with the given index.
Definition: RemotelyStoredVector.hpp:59
Types.hpp
OpenMPCD::RemotelyStoredVector::getMagnitudeSquared
OPENMPCD_CUDA_HOST_AND_DEVICE T getMagnitudeSquared() const
Returns the square of the magnitude of this vector.
Definition: RemotelyStoredVector.hpp:182
OpenMPCD::RemotelyStoredVector::getX
OPENMPCD_CUDA_HOST_AND_DEVICE T getX() const
Returns the x coodinate.
Definition: RemotelyStoredVector.hpp:72
OpenMPCD::RemotelyStoredVector::operator+
const OPENMPCD_CUDA_HOST_AND_DEVICE Vector3D< typename boost::remove_const< T >::type > operator+(const RemotelyStoredVector &rhs) const
Addition operator.
Definition: RemotelyStoredVector.hpp:270
Macros.hpp
OpenMPCD::Vector3D::addToY
OPENMPCD_CUDA_HOST_AND_DEVICE void addToY(const T val)
Adds the given value to the y coordinate.
Definition: Vector3D.hpp:110
OpenMPCD::RemotelyStoredVector::addToX
OPENMPCD_CUDA_HOST_AND_DEVICE void addToX(const T val)
Adds the given value to the x coordinate.
Definition: RemotelyStoredVector.hpp:92
OpenMPCD::Utility::MathematicalFunctions::sqrt
OPENMPCD_CUDA_HOST_AND_DEVICE T sqrt(const T x)
Returns the sqaure root of the argument.
OpenMPCD::RemotelyStoredVector::getZ
OPENMPCD_CUDA_HOST_AND_DEVICE FP getZ() const
Returns the z coodinate.
Definition: RemotelyStoredVector.hpp:124
OpenMPCD::OutOfBoundsException
Exception for out-of-bounds access.
Definition: Exceptions.hpp:112
OpenMPCD::RemotelyStoredVector::operator=
const OPENMPCD_CUDA_HOST_AND_DEVICE RemotelyStoredVector & operator=(const Vector3D< T > &rhs)
The assignment operator.
Definition: RemotelyStoredVector.hpp:236
OpenMPCD::RemotelyStoredVector::operator!=
OPENMPCD_CUDA_HOST_AND_DEVICE bool operator!=(const Vector3D< typename boost::remove_const< T >::type > &rhs) const
The inequality operator.
Definition: RemotelyStoredVector.hpp:429
OpenMPCD::RemotelyStoredVector::isFinite
OPENMPCD_CUDA_HOST_AND_DEVICE bool isFinite() const
Returns whether all components are finite, i.e.
Definition: RemotelyStoredVector.hpp:200
OpenMPCD::RemotelyStoredVector::dot
OPENMPCD_CUDA_HOST_AND_DEVICE T dot(const RemotelyStoredVector &rhs) const
Returns the scalar product of this vector with the given vector.
Definition: RemotelyStoredVector.hpp:170