Nektar++
NekPoint.hpp
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // File: NekPoint.hpp
4 //
5 // For more information, please see: http://www.nektar.info
6 //
7 // The MIT License
8 //
9 // Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
10 // Department of Aeronautics, Imperial College London (UK), and Scientific
11 // Computing and Imaging Institute, University of Utah (USA).
12 //
13 // Permission is hereby granted, free of charge, to any person obtaining a
14 // copy of this software and associated documentation files (the "Software"),
15 // to deal in the Software without restriction, including without limitation
16 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
17 // and/or sell copies of the Software, and to permit persons to whom the
18 // Software is furnished to do so, subject to the following conditions:
19 //
20 // The above copyright notice and this permission notice shall be included
21 // in all copies or substantial portions of the Software.
22 //
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29 // DEALINGS IN THE SOFTWARE.
30 //
31 // Description: Generic N-Dimensional Point.
32 //
33 ///////////////////////////////////////////////////////////////////////////////
34 
35 #ifndef NEKTAR_LIB_UTILITIES_NEK_POINT_HPP
36 #define NEKTAR_LIB_UTILITIES_NEK_POINT_HPP
37 
40 
41 #include <boost/lexical_cast.hpp>
42 #include <boost/tokenizer.hpp>
43 #include <boost/call_traits.hpp>
44 
45 #include <cmath>
46 #include <type_traits>
47 #include <functional>
48 #include <algorithm>
49 
50 namespace Nektar
51 {
52  template<typename data_type>
53  class NekPoint
54  {
55  public:
56  typedef data_type DataType;
57  typedef ThreeD dim;
58 
59  public:
61  {
62  // This may be suboptimal if DataType isn't numeric.
63  // If we use them then maybe we could look at an enable_if
64  // template to choose a better constructor.
65  for(unsigned int i = 0; i < dim::Value; ++i)
66  {
67  // If you get a compile error pointing you here then
68  // the DataType being stored in the point doesn't have an
69  // accessible operator= or default copy constructor.
70  m_data[i] = DataType();
71  }
72  }
73 
74  NekPoint(const std::string& pointValues)
75  {
76  bool result = fromString(pointValues, *this);
77  ASSERTL0(result, "Unable to create a point from a string.");
78  }
79 
80  NekPoint(typename boost::call_traits<DataType>::param_type x,
81  typename boost::call_traits<DataType>::param_type y,
82  typename boost::call_traits<DataType>::param_type z)
83  {
84  m_data[0] = x;
85  m_data[1] = y;
86  m_data[2] = z;
87  }
88 
89  explicit NekPoint(typename boost::call_traits<DataType>::const_reference a)
90  {
91  for(unsigned int i = 0; i < dim::Value; ++i)
92  {
93  m_data[i] = a;
94  }
95  }
96 
97 
99  {
100  for(unsigned int i = 0; i < dim::Value; ++i)
101  {
102  m_data[i] = rhs.m_data[i];
103  }
104  }
105 
107  {
108  }
109 
110 
112  {
113  for(unsigned int i = 0; i < dim::Value; ++i)
114  {
115  m_data[i] = rhs.m_data[i];
116  }
117  return *this;
118  }
119 
120  /// \brief Returns the number of dimensions for the point.
121  static unsigned int dimension() { return dim::Value; }
122 
123  /// \brief Returns i^{th} element.
124  /// \param i The element to return.
125  /// \pre i < dim
126  /// \return A reference to the i^{th} element.
127  ///
128  /// Retrieves the i^{th} element. Since it returns a reference you may
129  /// assign a new value (i.e., p(2) = 3.2;)
130  ///
131  /// This operator performs range checking.
132  typename boost::call_traits<DataType>::reference operator()(unsigned int i)
133  {
134  ASSERTL0(i < dim::Value,
135  "Invalid access to NekPoint data via parenthesis "
136  "operator: index out of range");
137  return m_data[i];
138  }
139 
140  typename boost::call_traits<DataType>::const_reference operator()(unsigned int i) const
141  {
142  ASSERTL0(i < dim::Value,
143  "Invalid access to NekPoint data via parenthesis "
144  "operator: index out of range");
145  return m_data[i];
146  }
147 
148  typename boost::call_traits<DataType>::reference operator[](unsigned int i)
149  {
150  return m_data[i];
151  }
152 
153  typename boost::call_traits<DataType>::const_reference operator[](unsigned int i) const
154  {
155  return m_data[i];
156  }
157 
158  typename boost::call_traits<DataType>::const_reference x() const
159  {
160  static_assert(dim::Value >= 1, "invalid dimension");
161  return m_data[0];
162  }
163 
164  typename boost::call_traits<DataType>::const_reference y() const
165  {
166  static_assert(dim::Value >= 2, "invalid dimension");
167  return (*this)[1];
168  }
169 
170  typename boost::call_traits<DataType>::const_reference z() const
171  {
172  static_assert(dim::Value >= 3, "invalid dimension");
173  return (*this)[2];
174  }
175 
176  typename boost::call_traits<DataType>::const_reference a() const
177  {
178  static_assert(dim::Value >= 1, "invalid dimension");
179  return m_data[0];
180  }
181 
182  typename boost::call_traits<DataType>::const_reference b() const
183  {
184  static_assert(dim::Value >= 2, "invalid dimension");
185  return (*this)[1];
186  }
187 
188  typename boost::call_traits<DataType>::const_reference c() const
189  {
190  static_assert(dim::Value >= 3, "invalid dimension");
191  return (*this)[2];
192  }
193 
194  typename boost::call_traits<DataType>::const_reference r() const
195  {
196  static_assert(dim::Value >= 1, "invalid dimension");
197  return m_data[0];
198  }
199 
200  typename boost::call_traits<DataType>::const_reference s() const
201  {
202  static_assert(dim::Value >= 2, "invalid dimension");
203  return (*this)[1];
204  }
205 
206  typename boost::call_traits<DataType>::const_reference t() const
207  {
208  static_assert(dim::Value >= 3, "invalid dimension");
209  return (*this)[2];
210  }
211 
212  void SetX(typename boost::call_traits<DataType>::const_reference val)
213  {
214  static_assert(dim::Value >= 1, "invalid dimension");
215  m_data[0] = val;
216  }
217 
218  void SetY(typename boost::call_traits<DataType>::const_reference val)
219  {
220  static_assert(dim::Value >= 2, "invalid dimension");
221  m_data[1] = val;
222  }
223 
224  void SetZ(typename boost::call_traits<DataType>::const_reference val)
225  {
226  static_assert(dim::Value >= 2, "invalid dimension");
227  m_data[2] = val;
228  }
229 
230  typename boost::call_traits<DataType>::reference x()
231  {
232  static_assert(dim::Value >= 1, "invalid dimension");
233  return (*this)(0);
234  }
235 
236  typename boost::call_traits<DataType>::reference y()
237  {
238  static_assert(dim::Value >= 2, "invalid dimension");
239  return (*this)(1);
240  }
241 
242  typename boost::call_traits<DataType>::reference z()
243  {
244  static_assert(dim::Value >= 3, "invalid dimension");
245  return (*this)(2);
246  }
247 
248  const DataType* GetPtr() const
249  {
250  return &m_data[0];
251  }
252 
253  bool operator==(const NekPoint<DataType>& rhs) const
254  {
255  for(unsigned int i = 0; i < dim::Value; ++i)
256  {
257  // If you get a compile error here then you have to
258  // add a != operator to the DataType class.
259  if( m_data[i] != rhs.m_data[i] )
260  {
261  return false;
262  }
263  }
264  return true;
265  }
266 
267  bool operator!=(const NekPoint<DataType>& rhs) const
268  {
269  return !(*this == rhs);
270  }
271 
272  /// Arithmetic Routines
273 
274  // Unitary operators
275  void negate()
276  {
277  for(int i=0; i < dim::Value; ++i)
278  {
279  (*this)[i] = -(*this)[i];
280  }
281  }
282 
284  {
285  NekPoint<DataType> result(*this);
286  result.negate();
287  return result;
288  }
289 
290 
292  {
293  for(unsigned int i=0; i < dim::Value; ++i)
294  {
295  m_data[i] += rhs.m_data[i];
296  }
297  return *this;
298  }
299 
300  NekPoint<DataType>& operator+=(typename boost::call_traits<DataType>::param_type rhs)
301  {
302  for(unsigned int i = 0; i < dim::Value; ++i)
303  {
304  m_data[i] += rhs;
305  }
306  return *this;
307  }
308 
310  {
311  for(unsigned int i=0; i < dim::Value; ++i)
312  {
313  m_data[i] -= rhs.m_data[i];
314  }
315  return *this;
316  }
317 
318 
319  NekPoint<DataType>& operator-=(typename boost::call_traits<DataType>::param_type rhs)
320  {
321  for(unsigned int i = 0; i < dim::Value; ++i)
322  {
323  m_data[i] -= rhs;
324  }
325  return *this;
326  }
327 
328  NekPoint<DataType>& operator*=(typename boost::call_traits<DataType>::param_type rhs)
329  {
330  for(unsigned int i = 0; i < dim::Value; ++i)
331  {
332  m_data[i] *= rhs;
333  }
334  return *this;
335  }
336 
337  NekPoint<DataType>& operator/=(typename boost::call_traits<DataType>::param_type rhs)
338  {
339  for(unsigned int i = 0; i < dim::Value; ++i)
340  {
341  m_data[i] /= rhs;
342  }
343  return *this;
344  }
345 
346  std::string AsString() const
347  {
348  std::string result = "(";
349  for(unsigned int i = 0; i < dim::Value; ++i)
350  {
351  result += boost::lexical_cast<std::string>(m_data[i]);
352  if( i < dim::Value-1 )
353  {
354  result += ", ";
355  }
356  }
357  result += ")";
358  return result;
359  }
360 
361  private:
363  };
364 
365  // Operators for expression templates
366  template<typename DataType>
368  {
369  rhs.negate();
370  }
371 
372  template<typename DataType>
373  NekPoint<DataType>
375  {
376  NekPoint<DataType> result(lhs);
377  result += rhs;
378  return result;
379  }
380 
381  template<typename DataType>
382  NekPoint<DataType>
383  operator+(typename boost::call_traits<DataType>::const_reference lhs, const NekPoint<DataType>& rhs)
384  {
385  NekPoint<DataType> result(rhs);
386  result += lhs;
387  return result;
388  }
389 
390  template<typename DataType>
391  NekPoint<DataType>
392  operator+(const NekPoint<DataType>& lhs, typename boost::call_traits<DataType>::const_reference rhs)
393  {
394  NekPoint<DataType> result(lhs);
395  result += rhs;
396  return result;
397  }
398 
399  template<typename DataType>
400  NekPoint<DataType>
402  {
403  NekPoint<DataType> result(lhs);
404  result -= rhs;
405  return result;
406  }
407 
408  template<typename DataType>
409  NekPoint<DataType>
410  operator-(typename boost::call_traits<DataType>::const_reference lhs, const NekPoint<DataType>& rhs)
411  {
412  NekPoint<DataType> result(-rhs);
413  result += lhs;
414  return result;
415  }
416 
417  template<typename DataType>
418  NekPoint<DataType>
419  operator-(const NekPoint<DataType>& lhs, typename boost::call_traits<DataType>::const_reference rhs)
420  {
421  NekPoint<DataType> result(lhs);
422  result -= rhs;
423  return result;
424  }
425 
426  template<typename DataType, typename dim, typename space, typename ScalarType>
427  NekPoint<DataType>
428  operator*(const ScalarType& lhs, const NekPoint<DataType>& rhs)
429  {
430  NekPoint<DataType> result(rhs);
431  result *= lhs;
432  return result;
433  }
434 
435  template<typename DataType, typename dim, typename space, typename ScalarType>
436  NekPoint<DataType>
437  operator*(const NekPoint<DataType>& lhs, const ScalarType& rhs)
438  {
439  NekPoint<DataType> result(lhs);
440  result *= rhs;
441  return result;
442  }
443 
444  template<typename DataType>
445  NekPoint<DataType>
446  operator/(const NekPoint<DataType>& lhs, typename boost::call_traits<DataType>::param_type rhs)
447  {
448  NekPoint<DataType> result(lhs);
449  result /= rhs;
450  return result;
451  }
452 
453  template<typename DataType>
454  typename boost::call_traits<DataType>::value_type distanceBetween(const NekPoint<DataType>& lhs,
455  const NekPoint<DataType>& rhs)
456  {
457  DataType result = 0.0;
458  for(unsigned int i = 0; i < 3; ++i)
459  {
460  DataType temp = lhs[i] - rhs[i];
461  result += temp*temp;
462  }
463  return sqrt(result);
464  }
465 
466  template<typename DataType>
467  bool fromString(const std::string& str, NekPoint<DataType>& result)
468  {
469  try
470  {
471  typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
472  boost::char_separator<char> sep("(<,>) ");
473  tokenizer tokens(str, sep);
474  unsigned int i = 0;
475  for(tokenizer::iterator iter = tokens.begin(); iter != tokens.end(); ++iter)
476  {
477  result[i] = boost::lexical_cast<DataType>(*iter);
478  ++i;
479  }
480 
481  return i == 3;
482  }
483  catch(boost::bad_lexical_cast&)
484  {
485  return false;
486  }
487  }
488 
489  template<typename DataType>
490  std::ostream& operator<<(std::ostream& os, const NekPoint<DataType>& p)
491  {
492  os << p.AsString();
493  return os;
494  }
495 
496 }
497 
498 #endif // NEKTAR_LIB_UTILITIES_NEK_POINT_HPP
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:216
const DataType * GetPtr() const
Definition: NekPoint.hpp:248
boost::call_traits< DataType >::reference z()
Definition: NekPoint.hpp:242
boost::call_traits< DataType >::reference operator[](unsigned int i)
Definition: NekPoint.hpp:148
boost::call_traits< DataType >::const_reference z() const
Definition: NekPoint.hpp:170
void SetX(typename boost::call_traits< DataType >::const_reference val)
Definition: NekPoint.hpp:212
boost::call_traits< DataType >::const_reference t() const
Definition: NekPoint.hpp:206
NekPoint(const std::string &pointValues)
Definition: NekPoint.hpp:74
NekPoint< DataType > & operator+=(typename boost::call_traits< DataType >::param_type rhs)
Definition: NekPoint.hpp:300
NekPoint< DataType > & operator=(const NekPoint< DataType > &rhs)
Definition: NekPoint.hpp:111
boost::call_traits< DataType >::const_reference operator[](unsigned int i) const
Definition: NekPoint.hpp:153
boost::call_traits< DataType >::const_reference s() const
Definition: NekPoint.hpp:200
bool operator!=(const NekPoint< DataType > &rhs) const
Definition: NekPoint.hpp:267
boost::call_traits< DataType >::reference y()
Definition: NekPoint.hpp:236
boost::call_traits< DataType >::const_reference a() const
Definition: NekPoint.hpp:176
boost::call_traits< DataType >::const_reference b() const
Definition: NekPoint.hpp:182
boost::call_traits< DataType >::const_reference c() const
Definition: NekPoint.hpp:188
bool operator==(const NekPoint< DataType > &rhs) const
Definition: NekPoint.hpp:253
boost::call_traits< DataType >::const_reference operator()(unsigned int i) const
Definition: NekPoint.hpp:140
NekPoint< DataType > & operator-=(const NekPoint< DataType > &rhs)
Definition: NekPoint.hpp:309
NekPoint(typename boost::call_traits< DataType >::const_reference a)
Definition: NekPoint.hpp:89
NekPoint< DataType > & operator+=(const NekPoint< DataType > &rhs)
Definition: NekPoint.hpp:291
NekPoint(typename boost::call_traits< DataType >::param_type x, typename boost::call_traits< DataType >::param_type y, typename boost::call_traits< DataType >::param_type z)
Definition: NekPoint.hpp:80
static unsigned int dimension()
Returns the number of dimensions for the point.
Definition: NekPoint.hpp:121
NekPoint< DataType > & operator-=(typename boost::call_traits< DataType >::param_type rhs)
Definition: NekPoint.hpp:319
void SetZ(typename boost::call_traits< DataType >::const_reference val)
Definition: NekPoint.hpp:224
data_type DataType
Definition: NekPoint.hpp:56
NekPoint< DataType > & operator*=(typename boost::call_traits< DataType >::param_type rhs)
Definition: NekPoint.hpp:328
boost::call_traits< DataType >::const_reference r() const
Definition: NekPoint.hpp:194
boost::call_traits< DataType >::reference x()
Definition: NekPoint.hpp:230
NekPoint< DataType > & operator/=(typename boost::call_traits< DataType >::param_type rhs)
Definition: NekPoint.hpp:337
std::string AsString() const
Definition: NekPoint.hpp:346
boost::call_traits< DataType >::reference operator()(unsigned int i)
Returns i^{th} element.
Definition: NekPoint.hpp:132
DataType m_data[dim::Value]
Definition: NekPoint.hpp:362
NekPoint(const NekPoint< DataType > &rhs)
Definition: NekPoint.hpp:98
boost::call_traits< DataType >::const_reference x() const
Definition: NekPoint.hpp:158
boost::call_traits< DataType >::const_reference y() const
Definition: NekPoint.hpp:164
void SetY(typename boost::call_traits< DataType >::const_reference val)
Definition: NekPoint.hpp:218
NekPoint< DataType > operator-() const
Definition: NekPoint.hpp:283
void negate()
Arithmetic Routines.
Definition: NekPoint.hpp:275
The above copyright notice and this permission notice shall be included.
Definition: CoupledSolver.h:1
void negate(NekPoint< DataType > &rhs)
Definition: NekPoint.hpp:367
NekVector< DataType > operator*(const NekMatrix< LhsDataType, MatrixType > &lhs, const NekVector< DataType > &rhs)
boost::call_traits< DataType >::value_type distanceBetween(const NekPoint< DataType > &lhs, const NekPoint< DataType > &rhs)
Definition: NekPoint.hpp:454
Array< OneD, DataType > operator+(const Array< OneD, DataType > &lhs, typename Array< OneD, DataType >::size_type offset)
bool fromString(const std::string &str, NekPoint< DataType > &result)
Definition: NekPoint.hpp:467
NekPoint< DataType > operator/(const NekPoint< DataType > &lhs, typename boost::call_traits< DataType >::param_type rhs)
Definition: NekPoint.hpp:446
std::ostream & operator<<(std::ostream &os, const NekMatrix< DataType, FormType > &rhs)
Definition: NekMatrix.hpp:49
NekMatrix< typename NekMatrix< LhsDataType, LhsMatrixType >::NumberType, StandardMatrixTag > operator-(const NekMatrix< LhsDataType, LhsMatrixType > &lhs, const NekMatrix< RhsDataType, RhsMatrixType > &rhs)
scalarT< T > sqrt(scalarT< T > in)
Definition: scalar.hpp:267
static const unsigned int Value