Reference documentation for deal.II version 9.1.0-pre
point.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 1998 - 2018 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE.md at
12 // the top level directory of deal.II.
13 //
14 // ---------------------------------------------------------------------
15 
16 #ifndef dealii_point_h
17 #define dealii_point_h
18 
19 
20 #include <deal.II/base/config.h>
21 
22 #include <deal.II/base/exceptions.h>
23 #include <deal.II/base/tensor.h>
24 
25 #include <cmath>
26 
27 DEAL_II_NAMESPACE_OPEN
28 
105 template <int dim, typename Number = double>
106 class Point : public Tensor<1, dim, Number>
107 {
108 public:
113  Point();
114 
118  explicit Point(const Tensor<1, dim, Number> &);
119 
126  explicit Point(const Number x);
127 
135  Point(const Number x, const Number y);
136 
144  Point(const Number x, const Number y, const Number z);
145 
151  static Point<dim, Number>
152  unit_vector(const unsigned int i);
153 
157  Number
158  operator()(const unsigned int index) const;
159 
163  Number &
164  operator()(const unsigned int index);
165 
166  /*
167  * @name Addition and subtraction of points.
168  * @{
169  */
170 
175  operator+(const Tensor<1, dim, Number> &) const;
176 
185  operator-(const Point<dim, Number> &) const;
186 
194  operator-(const Tensor<1, dim, Number> &) const;
195 
200  operator-() const;
201 
206  /*
207  * @name Multiplication and scaling of points. Dot products. Norms.
208  * @{
209  */
210 
216  template <typename OtherNumber>
217  Point<dim,
218  typename ProductType<Number,
219  typename EnableIfScalar<OtherNumber>::type>::type>
220  operator*(const OtherNumber) const;
221 
225  template <typename OtherNumber>
226  Point<dim,
227  typename ProductType<Number,
228  typename EnableIfScalar<OtherNumber>::type>::type>
229  operator/(const OtherNumber) const;
230 
234  Number operator*(const Tensor<1, dim, Number> &p) const;
235 
247  square() const;
248 
255  distance(const Point<dim, Number> &p) const;
256 
262  distance_square(const Point<dim, Number> &p) const;
263 
272  template <class Archive>
273  void
274  serialize(Archive &ar, const unsigned int version);
275 };
276 
277 /*--------------------------- Inline functions: Point -----------------------*/
278 
279 #ifndef DOXYGEN
280 
281 // At least clang-3.7 requires us to have a user-defined constructor
282 // and we can't use 'Point<dim,Number>::Point () = default' here.
283 template <int dim, typename Number>
285 {}
286 
287 
288 
289 template <int dim, typename Number>
292 {}
293 
294 
295 
296 template <int dim, typename Number>
297 inline Point<dim, Number>::Point(const Number x)
298 {
299  Assert(dim == 1,
300  ExcMessage(
301  "You can only initialize Point<1> objects using the constructor "
302  "that takes only one argument. Point<dim> objects with dim!=1 "
303  "require initialization with the constructor that takes 'dim' "
304  "arguments."));
305 
306  // we can only get here if we pass the assertion. use the switch anyway so
307  // as to avoid compiler warnings about uninitialized elements or writing
308  // beyond the end of the 'values' array
309  switch (dim)
310  {
311  case 1:
312  this->values[0] = x;
313  break;
314 
315  default:;
316  }
317 }
318 
319 
320 
321 template <int dim, typename Number>
322 inline Point<dim, Number>::Point(const Number x, const Number y)
323 {
324  Assert(dim == 2,
325  ExcMessage(
326  "You can only initialize Point<2> objects using the constructor "
327  "that takes two arguments. Point<dim> objects with dim!=2 "
328  "require initialization with the constructor that takes 'dim' "
329  "arguments."));
330  // we can only get here if we pass the assertion. use the indirection anyway
331  // so as to avoid compiler warnings about uninitialized elements or writing
332  // beyond the end of the 'values' array
333  constexpr unsigned int y_index = (dim < 2) ? 0 : 1;
334  this->values[0] = x;
335  this->values[y_index] = y;
336 }
337 
338 
339 
340 template <int dim, typename Number>
341 inline Point<dim, Number>::Point(const Number x, const Number y, const Number z)
342 {
343  Assert(dim == 3,
344  ExcMessage(
345  "You can only initialize Point<3> objects using the constructor "
346  "that takes three arguments. Point<dim> objects with dim!=3 "
347  "require initialization with the constructor that takes 'dim' "
348  "arguments."));
349 
350  // we can only get here if we pass the assertion. use the indirection anyway
351  // so as to avoid compiler warnings about uninitialized elements or writing
352  // beyond the end of the 'values' array
353  constexpr unsigned int y_index = (dim < 2) ? 0 : 1;
354  constexpr unsigned int z_index = (dim < 3) ? 0 : 2;
355  this->values[0] = x;
356  this->values[y_index] = y;
357  this->values[z_index] = z;
358 }
359 
360 
361 template <int dim, typename Number>
362 inline Point<dim, Number>
363 Point<dim, Number>::unit_vector(unsigned int i)
364 {
366  p[i] = 1.;
367  return p;
368 }
369 
370 
371 template <int dim, typename Number>
372 inline Number
373 Point<dim, Number>::operator()(const unsigned int index) const
374 {
375  AssertIndexRange((int)index, dim);
376  return this->values[index];
377 }
378 
379 
380 
381 template <int dim, typename Number>
382 inline Number &
383 Point<dim, Number>::operator()(const unsigned int index)
384 {
385  AssertIndexRange((int)index, dim);
386  return this->values[index];
387 }
388 
389 
390 
391 template <int dim, typename Number>
392 inline Point<dim, Number>
394 {
395  Point<dim, Number> tmp = *this;
396  tmp += p;
397  return tmp;
398 }
399 
400 
401 
402 template <int dim, typename Number>
405 {
406  return (Tensor<1, dim, Number>(*this) -= p);
407 }
408 
409 
410 
411 template <int dim, typename Number>
412 inline Point<dim, Number>
414 {
415  Point<dim, Number> tmp = *this;
416  tmp -= p;
417  return tmp;
418 }
419 
420 
421 
422 template <int dim, typename Number>
423 inline Point<dim, Number>
425 {
426  Point<dim, Number> result;
427  for (unsigned int i = 0; i < dim; ++i)
428  result.values[i] = -this->values[i];
429  return result;
430 }
431 
432 
433 
434 template <int dim, typename Number>
435 template <typename OtherNumber>
436 inline Point<
437  dim,
438  typename ProductType<Number,
439  typename EnableIfScalar<OtherNumber>::type>::type>
440  Point<dim, Number>::operator*(const OtherNumber factor) const
441 {
443  for (unsigned int i = 0; i < dim; ++i)
444  tmp[i] = this->operator[](i) * factor;
445  return tmp;
446 }
447 
448 
449 
450 template <int dim, typename Number>
451 template <typename OtherNumber>
452 inline Point<
453  dim,
454  typename ProductType<Number,
455  typename EnableIfScalar<OtherNumber>::type>::type>
456 Point<dim, Number>::operator/(const OtherNumber factor) const
457 {
459  for (unsigned int i = 0; i < dim; ++i)
460  tmp[i] = this->operator[](i) / factor;
461  return tmp;
462 }
463 
464 
465 
466 template <int dim, typename Number>
467 inline Number Point<dim, Number>::
468  operator*(const Tensor<1, dim, Number> &p) const
469 {
470  Number res = Number();
471  for (unsigned int i = 0; i < dim; ++i)
472  res += this->operator[](i) * p[i];
473  return res;
474 }
475 
476 
477 template <int dim, typename Number>
480 {
481  return this->norm_square();
482 }
483 
484 
485 
486 template <int dim, typename Number>
489 {
490  return std::sqrt(distance_square(p));
491 }
492 
493 
494 
495 template <int dim, typename Number>
498 {
499  Number sum = internal::NumberType<Number>::value(0.0);
500  for (unsigned int i = 0; i < dim; ++i)
501  {
502  const Number diff = static_cast<Number>(this->values[i]) - p(i);
504  }
505 
506  return sum;
507 }
508 
509 
510 
511 template <int dim, typename Number>
512 template <class Archive>
513 inline void
514 Point<dim, Number>::serialize(Archive &ar, const unsigned int)
515 {
516  // forward to serialization
517  // function in the base class
518  ar &static_cast<Tensor<1, dim, Number> &>(*this);
519 }
520 
521 #endif // DOXYGEN
522 
523 
524 /*--------------------------- Global functions: Point -----------------------*/
525 
526 
533 template <int dim, typename Number, typename OtherNumber>
534 inline Point<
535  dim,
536  typename ProductType<Number,
537  typename EnableIfScalar<OtherNumber>::type>::type>
538 operator*(const OtherNumber factor, const Point<dim, Number> &p)
539 {
540  return p * factor;
541 }
542 
543 
544 
550 template <int dim, typename Number>
551 inline std::ostream &
552 operator<<(std::ostream &out, const Point<dim, Number> &p)
553 {
554  for (unsigned int i = 0; i < dim - 1; ++i)
555  out << p[i] << ' ';
556  out << p[dim - 1];
557 
558  return out;
559 }
560 
561 
562 
567 template <int dim, typename Number>
568 inline std::istream &
569 operator>>(std::istream &in, Point<dim, Number> &p)
570 {
571  for (unsigned int i = 0; i < dim; ++i)
572  in >> p[i];
573 
574  return in;
575 }
576 
577 
578 #ifndef DOXYGEN
579 
585 template <typename Number>
586 inline std::ostream &
587 operator<<(std::ostream &out, const Point<1, Number> &p)
588 {
589  out << p[0];
590 
591  return out;
592 }
593 
594 #endif // DOXYGEN
595 DEAL_II_NAMESPACE_CLOSE
596 
597 #endif
Number operator()(const unsigned int index) const
Point< dim, typename ProductType< Number, typename EnableIfScalar< OtherNumber >::type >::type > operator*(const OtherNumber factor, const Point< dim, Number > &p)
Definition: point.h:538
Point< dim, typename ProductType< Number, typename EnableIfScalar< OtherNumber >::type >::type > operator/(const OtherNumber) const
#define AssertIndexRange(index, range)
Definition: exceptions.h:1407
Tensor< rank_-1, dim, Number > values[(dim!=0)?dim:1]
Definition: tensor.h:671
static Point< dim, Number > unit_vector(const unsigned int i)
numbers::NumberTraits< Number >::real_type distance(const Point< dim, Number > &p) const
Definition: point.h:106
static::ExceptionBase & ExcMessage(std::string arg1)
static real_type abs_square(const number &x)
Definition: numbers.h:474
#define Assert(cond, exc)
Definition: exceptions.h:1227
numbers::NumberTraits< Number >::real_type distance_square(const Point< dim, Number > &p) const
void serialize(Archive &ar, const unsigned int version)
numbers::NumberTraits< Number >::real_type square() const
Point< dim, Number > operator+(const Tensor< 1, dim, Number > &) const
Definition: mpi.h:55
Point< dim, Number > operator-() const
Point< dim, typename ProductType< Number, typename EnableIfScalar< OtherNumber >::type >::type > operator*(const OtherNumber) const
numbers::NumberTraits< Number >::real_type norm_square() const
std::istream & operator>>(std::istream &in, Point< dim, Number > &p)
Definition: point.h:569