Nektar++
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
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/call_traits.hpp>
42 #include <boost/lexical_cast.hpp>
43 #include <boost/tokenizer.hpp>
44 
45 #include <algorithm>
46 #include <cmath>
47 #include <functional>
48 #include <type_traits>
49 
50 namespace Nektar
51 {
52 template <typename data_type> class NekPoint
53 {
54 public:
55  typedef data_type DataType;
56  typedef ThreeD dim;
57 
58 public:
60  {
61  // This may be suboptimal if DataType isn't numeric.
62  // If we use them then maybe we could look at an enable_if
63  // template to choose a better constructor.
64  for (unsigned int i = 0; i < dim::Value; ++i)
65  {
66  // If you get a compile error pointing you here then
67  // the DataType being stored in the point doesn't have an
68  // accessible operator= or default copy constructor.
69  m_data[i] = DataType();
70  }
71  }
72 
73  NekPoint(const std::string &pointValues)
74  {
75  bool result = fromString(pointValues, *this);
76  ASSERTL0(result, "Unable to create a point from a string.");
77  }
78 
79  NekPoint(typename boost::call_traits<DataType>::param_type x,
80  typename boost::call_traits<DataType>::param_type y,
81  typename boost::call_traits<DataType>::param_type z)
82  {
83  m_data[0] = x;
84  m_data[1] = y;
85  m_data[2] = z;
86  }
87 
88  explicit NekPoint(typename boost::call_traits<DataType>::const_reference a)
89  {
90  for (unsigned int i = 0; i < dim::Value; ++i)
91  {
92  m_data[i] = a;
93  }
94  }
95 
97  {
98  for (unsigned int i = 0; i < dim::Value; ++i)
99  {
100  m_data[i] = rhs.m_data[i];
101  }
102  }
103 
105  {
106  }
107 
109  {
110  for (unsigned int i = 0; i < dim::Value; ++i)
111  {
112  m_data[i] = rhs.m_data[i];
113  }
114  return *this;
115  }
116 
117  /// \brief Returns the number of dimensions for the point.
118  static unsigned int dimension()
119  {
120  return dim::Value;
121  }
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()(
141  unsigned int i) const
142  {
143  ASSERTL0(i < dim::Value,
144  "Invalid access to NekPoint data via parenthesis "
145  "operator: index out of range");
146  return m_data[i];
147  }
148 
149  typename boost::call_traits<DataType>::reference operator[](unsigned int i)
150  {
151  return m_data[i];
152  }
153 
154  typename boost::call_traits<DataType>::const_reference operator[](
155  unsigned int i) const
156  {
157  return m_data[i];
158  }
159 
160  typename boost::call_traits<DataType>::const_reference x() const
161  {
162  static_assert(dim::Value >= 1, "invalid dimension");
163  return m_data[0];
164  }
165 
166  typename boost::call_traits<DataType>::const_reference y() const
167  {
168  static_assert(dim::Value >= 2, "invalid dimension");
169  return (*this)[1];
170  }
171 
172  typename boost::call_traits<DataType>::const_reference z() const
173  {
174  static_assert(dim::Value >= 3, "invalid dimension");
175  return (*this)[2];
176  }
177 
178  typename boost::call_traits<DataType>::const_reference a() const
179  {
180  static_assert(dim::Value >= 1, "invalid dimension");
181  return m_data[0];
182  }
183 
184  typename boost::call_traits<DataType>::const_reference b() const
185  {
186  static_assert(dim::Value >= 2, "invalid dimension");
187  return (*this)[1];
188  }
189 
190  typename boost::call_traits<DataType>::const_reference c() const
191  {
192  static_assert(dim::Value >= 3, "invalid dimension");
193  return (*this)[2];
194  }
195 
196  typename boost::call_traits<DataType>::const_reference r() const
197  {
198  static_assert(dim::Value >= 1, "invalid dimension");
199  return m_data[0];
200  }
201 
202  typename boost::call_traits<DataType>::const_reference s() const
203  {
204  static_assert(dim::Value >= 2, "invalid dimension");
205  return (*this)[1];
206  }
207 
208  typename boost::call_traits<DataType>::const_reference t() const
209  {
210  static_assert(dim::Value >= 3, "invalid dimension");
211  return (*this)[2];
212  }
213 
214  void SetX(typename boost::call_traits<DataType>::const_reference val)
215  {
216  static_assert(dim::Value >= 1, "invalid dimension");
217  m_data[0] = val;
218  }
219 
220  void SetY(typename boost::call_traits<DataType>::const_reference val)
221  {
222  static_assert(dim::Value >= 2, "invalid dimension");
223  m_data[1] = val;
224  }
225 
226  void SetZ(typename boost::call_traits<DataType>::const_reference val)
227  {
228  static_assert(dim::Value >= 2, "invalid dimension");
229  m_data[2] = val;
230  }
231 
232  typename boost::call_traits<DataType>::reference x()
233  {
234  static_assert(dim::Value >= 1, "invalid dimension");
235  return (*this)(0);
236  }
237 
238  typename boost::call_traits<DataType>::reference y()
239  {
240  static_assert(dim::Value >= 2, "invalid dimension");
241  return (*this)(1);
242  }
243 
244  typename boost::call_traits<DataType>::reference z()
245  {
246  static_assert(dim::Value >= 3, "invalid dimension");
247  return (*this)(2);
248  }
249 
250  const DataType *GetPtr() const
251  {
252  return &m_data[0];
253  }
254 
255  bool operator==(const NekPoint<DataType> &rhs) const
256  {
257  for (unsigned int i = 0; i < dim::Value; ++i)
258  {
259  // If you get a compile error here then you have to
260  // add a != operator to the DataType class.
261  if (m_data[i] != rhs.m_data[i])
262  {
263  return false;
264  }
265  }
266  return true;
267  }
268 
269  bool operator!=(const NekPoint<DataType> &rhs) const
270  {
271  return !(*this == rhs);
272  }
273 
274  /// Arithmetic Routines
275 
276  // Unitary operators
277  void negate()
278  {
279  for (int i = 0; i < dim::Value; ++i)
280  {
281  (*this)[i] = -(*this)[i];
282  }
283  }
284 
286  {
287  NekPoint<DataType> result(*this);
288  result.negate();
289  return result;
290  }
291 
293  {
294  for (unsigned int i = 0; i < dim::Value; ++i)
295  {
296  m_data[i] += rhs.m_data[i];
297  }
298  return *this;
299  }
300 
302  typename boost::call_traits<DataType>::param_type rhs)
303  {
304  for (unsigned int i = 0; i < dim::Value; ++i)
305  {
306  m_data[i] += rhs;
307  }
308  return *this;
309  }
310 
312  {
313  for (unsigned int i = 0; i < dim::Value; ++i)
314  {
315  m_data[i] -= rhs.m_data[i];
316  }
317  return *this;
318  }
319 
321  typename boost::call_traits<DataType>::param_type rhs)
322  {
323  for (unsigned int i = 0; i < dim::Value; ++i)
324  {
325  m_data[i] -= rhs;
326  }
327  return *this;
328  }
329 
331  typename boost::call_traits<DataType>::param_type rhs)
332  {
333  for (unsigned int i = 0; i < dim::Value; ++i)
334  {
335  m_data[i] *= rhs;
336  }
337  return *this;
338  }
339 
341  typename boost::call_traits<DataType>::param_type rhs)
342  {
343  for (unsigned int i = 0; i < dim::Value; ++i)
344  {
345  m_data[i] /= rhs;
346  }
347  return *this;
348  }
349 
350  std::string AsString() const
351  {
352  std::string result = "(";
353  for (unsigned int i = 0; i < dim::Value; ++i)
354  {
355  result += boost::lexical_cast<std::string>(m_data[i]);
356  if (i < dim::Value - 1)
357  {
358  result += ", ";
359  }
360  }
361  result += ")";
362  return result;
363  }
364 
365 private:
367 };
368 
369 // Operators for expression templates
370 template <typename DataType> void negate(NekPoint<DataType> &rhs)
371 {
372  rhs.negate();
373 }
374 
375 template <typename DataType>
377  const NekPoint<DataType> &rhs)
378 {
379  NekPoint<DataType> result(lhs);
380  result += rhs;
381  return result;
382 }
383 
384 template <typename DataType>
386  typename boost::call_traits<DataType>::const_reference lhs,
387  const NekPoint<DataType> &rhs)
388 {
389  NekPoint<DataType> result(rhs);
390  result += lhs;
391  return result;
392 }
393 
394 template <typename DataType>
396  const NekPoint<DataType> &lhs,
397  typename boost::call_traits<DataType>::const_reference rhs)
398 {
399  NekPoint<DataType> result(lhs);
400  result += rhs;
401  return result;
402 }
403 
404 template <typename DataType>
406  const NekPoint<DataType> &rhs)
407 {
408  NekPoint<DataType> result(lhs);
409  result -= rhs;
410  return result;
411 }
412 
413 template <typename DataType>
415  typename boost::call_traits<DataType>::const_reference lhs,
416  const NekPoint<DataType> &rhs)
417 {
418  NekPoint<DataType> result(-rhs);
419  result += lhs;
420  return result;
421 }
422 
423 template <typename DataType>
425  const NekPoint<DataType> &lhs,
426  typename boost::call_traits<DataType>::const_reference rhs)
427 {
428  NekPoint<DataType> result(lhs);
429  result -= rhs;
430  return result;
431 }
432 
433 template <typename DataType, typename dim, typename space, typename ScalarType>
434 NekPoint<DataType> operator*(const ScalarType &lhs,
435  const NekPoint<DataType> &rhs)
436 {
437  NekPoint<DataType> result(rhs);
438  result *= lhs;
439  return result;
440 }
441 
442 template <typename DataType, typename dim, typename space, typename ScalarType>
444  const ScalarType &rhs)
445 {
446  NekPoint<DataType> result(lhs);
447  result *= rhs;
448  return result;
449 }
450 
451 template <typename DataType>
453  const NekPoint<DataType> &lhs,
454  typename boost::call_traits<DataType>::param_type rhs)
455 {
456  NekPoint<DataType> result(lhs);
457  result /= rhs;
458  return result;
459 }
460 
461 template <typename DataType>
462 typename boost::call_traits<DataType>::value_type distanceBetween(
463  const NekPoint<DataType> &lhs, const NekPoint<DataType> &rhs)
464 {
465  DataType result = 0.0;
466  for (unsigned int i = 0; i < 3; ++i)
467  {
468  DataType temp = lhs[i] - rhs[i];
469  result += temp * temp;
470  }
471  return sqrt(result);
472 }
473 
474 template <typename DataType>
475 bool fromString(const std::string &str, NekPoint<DataType> &result)
476 {
477  try
478  {
479  typedef boost::tokenizer<boost::char_separator<char>> tokenizer;
480  boost::char_separator<char> sep("(<,>) ");
481  tokenizer tokens(str, sep);
482  unsigned int i = 0;
483  for (tokenizer::iterator iter = tokens.begin(); iter != tokens.end();
484  ++iter)
485  {
486  result[i] = boost::lexical_cast<DataType>(*iter);
487  ++i;
488  }
489 
490  return i == 3;
491  }
492  catch (boost::bad_lexical_cast &)
493  {
494  return false;
495  }
496 }
497 
498 template <typename DataType>
499 std::ostream &operator<<(std::ostream &os, const NekPoint<DataType> &p)
500 {
501  os << p.AsString();
502  return os;
503 }
504 
505 } // namespace Nektar
506 
507 #endif // NEKTAR_LIB_UTILITIES_NEK_POINT_HPP
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:215
const DataType * GetPtr() const
Definition: NekPoint.hpp:250
boost::call_traits< DataType >::reference z()
Definition: NekPoint.hpp:244
boost::call_traits< DataType >::reference operator[](unsigned int i)
Definition: NekPoint.hpp:149
boost::call_traits< DataType >::const_reference z() const
Definition: NekPoint.hpp:172
void SetX(typename boost::call_traits< DataType >::const_reference val)
Definition: NekPoint.hpp:214
boost::call_traits< DataType >::const_reference t() const
Definition: NekPoint.hpp:208
NekPoint(const std::string &pointValues)
Definition: NekPoint.hpp:73
NekPoint< DataType > & operator+=(typename boost::call_traits< DataType >::param_type rhs)
Definition: NekPoint.hpp:301
NekPoint< DataType > & operator=(const NekPoint< DataType > &rhs)
Definition: NekPoint.hpp:108
boost::call_traits< DataType >::const_reference operator[](unsigned int i) const
Definition: NekPoint.hpp:154
boost::call_traits< DataType >::const_reference s() const
Definition: NekPoint.hpp:202
bool operator!=(const NekPoint< DataType > &rhs) const
Definition: NekPoint.hpp:269
boost::call_traits< DataType >::reference y()
Definition: NekPoint.hpp:238
boost::call_traits< DataType >::const_reference a() const
Definition: NekPoint.hpp:178
boost::call_traits< DataType >::const_reference b() const
Definition: NekPoint.hpp:184
boost::call_traits< DataType >::const_reference c() const
Definition: NekPoint.hpp:190
bool operator==(const NekPoint< DataType > &rhs) const
Definition: NekPoint.hpp:255
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:311
NekPoint(typename boost::call_traits< DataType >::const_reference a)
Definition: NekPoint.hpp:88
NekPoint< DataType > & operator+=(const NekPoint< DataType > &rhs)
Definition: NekPoint.hpp:292
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:79
static unsigned int dimension()
Returns the number of dimensions for the point.
Definition: NekPoint.hpp:118
NekPoint< DataType > & operator-=(typename boost::call_traits< DataType >::param_type rhs)
Definition: NekPoint.hpp:320
void SetZ(typename boost::call_traits< DataType >::const_reference val)
Definition: NekPoint.hpp:226
data_type DataType
Definition: NekPoint.hpp:55
NekPoint< DataType > & operator*=(typename boost::call_traits< DataType >::param_type rhs)
Definition: NekPoint.hpp:330
boost::call_traits< DataType >::const_reference r() const
Definition: NekPoint.hpp:196
boost::call_traits< DataType >::reference x()
Definition: NekPoint.hpp:232
NekPoint< DataType > & operator/=(typename boost::call_traits< DataType >::param_type rhs)
Definition: NekPoint.hpp:340
std::string AsString() const
Definition: NekPoint.hpp:350
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:366
NekPoint(const NekPoint< DataType > &rhs)
Definition: NekPoint.hpp:96
boost::call_traits< DataType >::const_reference x() const
Definition: NekPoint.hpp:160
boost::call_traits< DataType >::const_reference y() const
Definition: NekPoint.hpp:166
void SetY(typename boost::call_traits< DataType >::const_reference val)
Definition: NekPoint.hpp:220
NekPoint< DataType > operator-() const
Definition: NekPoint.hpp:285
void negate()
Arithmetic Routines.
Definition: NekPoint.hpp:277
The above copyright notice and this permission notice shall be included.
Definition: CoupledSolver.h:2
void negate(NekPoint< DataType > &rhs)
Definition: NekPoint.hpp:370
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:462
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:475
NekPoint< DataType > operator/(const NekPoint< DataType > &lhs, typename boost::call_traits< DataType >::param_type rhs)
Definition: NekPoint.hpp:452
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:294
static const unsigned int Value