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/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
50namespace Nektar
51{
52template <typename data_type> class NekPoint
53{
54public:
55 typedef data_type DataType;
56 typedef ThreeD dim;
57
58public:
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 {
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 {
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
365private:
367};
368
369// Operators for expression templates
370template <typename DataType> void negate(NekPoint<DataType> &rhs)
371{
372 rhs.negate();
373}
374
375template <typename DataType>
377 const NekPoint<DataType> &rhs)
378{
379 NekPoint<DataType> result(lhs);
380 result += rhs;
381 return result;
382}
383
384template <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
394template <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
404template <typename DataType>
406 const NekPoint<DataType> &rhs)
407{
408 NekPoint<DataType> result(lhs);
409 result -= rhs;
410 return result;
411}
412
413template <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
423template <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
433template <typename DataType, typename dim, typename space, typename ScalarType>
434NekPoint<DataType> operator*(const ScalarType &lhs,
435 const NekPoint<DataType> &rhs)
436{
437 NekPoint<DataType> result(rhs);
438 result *= lhs;
439 return result;
440}
441
442template <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
451template <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
461template <typename DataType>
462typename 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
474template <typename DataType>
475bool 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
498template <typename DataType>
499std::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:208
boost::call_traits< DataType >::reference operator()(unsigned int i)
Returns i^{th} element.
Definition: NekPoint.hpp:132
boost::call_traits< DataType >::reference y()
Definition: NekPoint.hpp:238
NekPoint< DataType > & operator+=(typename boost::call_traits< DataType >::param_type rhs)
Definition: NekPoint.hpp:301
boost::call_traits< DataType >::const_reference t() const
Definition: NekPoint.hpp:208
NekPoint< DataType > & operator*=(typename boost::call_traits< DataType >::param_type rhs)
Definition: NekPoint.hpp:330
void SetX(typename boost::call_traits< DataType >::const_reference val)
Definition: NekPoint.hpp:214
NekPoint< DataType > & operator/=(typename boost::call_traits< DataType >::param_type rhs)
Definition: NekPoint.hpp:340
NekPoint(const std::string &pointValues)
Definition: NekPoint.hpp:73
NekPoint< DataType > & operator=(const NekPoint< DataType > &rhs)
Definition: NekPoint.hpp:108
boost::call_traits< DataType >::const_reference c() const
Definition: NekPoint.hpp:190
boost::call_traits< DataType >::const_reference x() const
Definition: NekPoint.hpp:160
bool operator!=(const NekPoint< DataType > &rhs) const
Definition: NekPoint.hpp:269
boost::call_traits< DataType >::const_reference operator[](unsigned int i) const
Definition: NekPoint.hpp:154
boost::call_traits< DataType >::const_reference a() const
Definition: NekPoint.hpp:178
NekPoint< DataType > & operator-=(typename boost::call_traits< DataType >::param_type rhs)
Definition: NekPoint.hpp:320
bool operator==(const NekPoint< DataType > &rhs) const
Definition: NekPoint.hpp:255
boost::call_traits< DataType >::reference z()
Definition: NekPoint.hpp:244
NekPoint(typename boost::call_traits< DataType >::const_reference a)
Definition: NekPoint.hpp:88
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
NekPoint< DataType > & operator-=(const NekPoint< DataType > &rhs)
Definition: NekPoint.hpp:311
boost::call_traits< DataType >::const_reference r() const
Definition: NekPoint.hpp:196
static unsigned int dimension()
Returns the number of dimensions for the point.
Definition: NekPoint.hpp:118
boost::call_traits< DataType >::const_reference z() const
Definition: NekPoint.hpp:172
NekPoint< DataType > & operator+=(const NekPoint< DataType > &rhs)
Definition: NekPoint.hpp:292
void SetZ(typename boost::call_traits< DataType >::const_reference val)
Definition: NekPoint.hpp:226
data_type DataType
Definition: NekPoint.hpp:55
boost::call_traits< DataType >::reference operator[](unsigned int i)
Definition: NekPoint.hpp:149
const DataType * GetPtr() const
Definition: NekPoint.hpp:250
boost::call_traits< DataType >::const_reference b() const
Definition: NekPoint.hpp:184
std::string AsString() const
Definition: NekPoint.hpp:350
boost::call_traits< DataType >::const_reference operator()(unsigned int i) const
Definition: NekPoint.hpp:140
boost::call_traits< DataType >::const_reference y() const
Definition: NekPoint.hpp:166
DataType m_data[dim::Value]
Definition: NekPoint.hpp:366
boost::call_traits< DataType >::const_reference s() const
Definition: NekPoint.hpp:202
NekPoint(const NekPoint< DataType > &rhs)
Definition: NekPoint.hpp:96
boost::call_traits< DataType >::reference x()
Definition: NekPoint.hpp:232
NekPoint< DataType > operator-() const
Definition: NekPoint.hpp:285
void SetY(typename boost::call_traits< DataType >::const_reference val)
Definition: NekPoint.hpp:220
void negate()
Arithmetic Routines.
Definition: NekPoint.hpp:277
NekMatrix< typename NekMatrix< LhsDataType, LhsMatrixType >::NumberType, StandardMatrixTag > operator-(const NekMatrix< LhsDataType, LhsMatrixType > &lhs, const NekMatrix< RhsDataType, RhsMatrixType > &rhs)
void negate(NekPoint< DataType > &rhs)
Definition: NekPoint.hpp:370
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)
NekVector< DataType > operator*(const NekMatrix< LhsDataType, MatrixType > &lhs, const NekVector< DataType > &rhs)
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
scalarT< T > sqrt(scalarT< T > in)
Definition: scalar.hpp:294
static const unsigned int Value