Reference documentation for deal.II version 9.1.1
\(\newcommand{\dealcoloneq}{\mathrel{\vcenter{:}}=}\)
point.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 1998 - 2019 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 DEAL_II_DISABLE_EXTRA_DIAGNOSTICS
26 #include <boost/geometry.hpp>
27 DEAL_II_ENABLE_EXTRA_DIAGNOSTICS
28 
29 #include <cmath>
30 
31 DEAL_II_NAMESPACE_OPEN
32 
109 template <int dim, typename Number = double>
110 class Point : public Tensor<1, dim, Number>
111 {
112 public:
117  Point();
118 
122  explicit Point(const Tensor<1, dim, Number> &);
123 
130  explicit Point(const Number x);
131 
139  Point(const Number x, const Number y);
140 
148  Point(const Number x, const Number y, const Number z);
149 
153  template <std::size_t dummy_dim,
154  typename std::enable_if<(dim == dummy_dim) && (dummy_dim != 0),
155  int>::type = 0>
156  Point(const boost::geometry::model::
157  point<Number, dummy_dim, boost::geometry::cs::cartesian> &boost_pt);
158 
164  static Point<dim, Number>
165  unit_vector(const unsigned int i);
166 
170  Number
171  operator()(const unsigned int index) const;
172 
176  Number &
177  operator()(const unsigned int index);
178 
188  operator+(const Tensor<1, dim, Number> &) const;
189 
198  operator-(const Point<dim, Number> &) const;
199 
207  operator-(const Tensor<1, dim, Number> &) const;
208 
213  operator-() const;
214 
229  template <typename OtherNumber>
230  Point<dim,
231  typename ProductType<Number,
232  typename EnableIfScalar<OtherNumber>::type>::type>
233  operator*(const OtherNumber) const;
234 
238  template <typename OtherNumber>
239  Point<dim,
240  typename ProductType<Number,
241  typename EnableIfScalar<OtherNumber>::type>::type>
242  operator/(const OtherNumber) const;
243 
247  Number operator*(const Tensor<1, dim, Number> &p) const;
248 
260  square() const;
261 
268  distance(const Point<dim, Number> &p) const;
269 
275  distance_square(const Point<dim, Number> &p) const;
276 
285  template <class Archive>
286  void
287  serialize(Archive &ar, const unsigned int version);
288 };
289 
290 /*--------------------------- Inline functions: Point -----------------------*/
291 
292 #ifndef DOXYGEN
293 
294 // At least clang-3.7 requires us to have a user-defined constructor
295 // and we can't use 'Point<dim,Number>::Point () = default' here.
296 template <int dim, typename Number>
297 inline Point<dim, Number>::Point() // NOLINT
298 {}
299 
300 
301 
302 template <int dim, typename Number>
304  : Tensor<1, dim, Number>(t)
305 {}
306 
307 
308 
309 template <int dim, typename Number>
310 inline Point<dim, Number>::Point(const Number x)
311 {
312  Assert(dim == 1,
313  ExcMessage(
314  "You can only initialize Point<1> objects using the constructor "
315  "that takes only one argument. Point<dim> objects with dim!=1 "
316  "require initialization with the constructor that takes 'dim' "
317  "arguments."));
318 
319  // we can only get here if we pass the assertion. use the switch anyway so
320  // as to avoid compiler warnings about uninitialized elements or writing
321  // beyond the end of the 'values' array
322  switch (dim)
323  {
324  case 1:
325  this->values[0] = x;
326  break;
327 
328  default:;
329  }
330 }
331 
332 
333 
334 template <int dim, typename Number>
335 inline Point<dim, Number>::Point(const Number x, const Number y)
336 {
337  Assert(dim == 2,
338  ExcMessage(
339  "You can only initialize Point<2> objects using the constructor "
340  "that takes two arguments. Point<dim> objects with dim!=2 "
341  "require initialization with the constructor that takes 'dim' "
342  "arguments."));
343  // we can only get here if we pass the assertion. use the indirection anyway
344  // so as to avoid compiler warnings about uninitialized elements or writing
345  // beyond the end of the 'values' array
346  constexpr unsigned int y_index = (dim < 2) ? 0 : 1;
347  this->values[0] = x;
348  this->values[y_index] = y;
349 }
350 
351 
352 
353 template <int dim, typename Number>
354 inline Point<dim, Number>::Point(const Number x, const Number y, const Number z)
355 {
356  Assert(dim == 3,
357  ExcMessage(
358  "You can only initialize Point<3> objects using the constructor "
359  "that takes three arguments. Point<dim> objects with dim!=3 "
360  "require initialization with the constructor that takes 'dim' "
361  "arguments."));
362 
363  // we can only get here if we pass the assertion. use the indirection anyway
364  // so as to avoid compiler warnings about uninitialized elements or writing
365  // beyond the end of the 'values' array
366  constexpr unsigned int y_index = (dim < 2) ? 0 : 1;
367  constexpr unsigned int z_index = (dim < 3) ? 0 : 2;
368  this->values[0] = x;
369  this->values[y_index] = y;
370  this->values[z_index] = z;
371 }
372 
373 
374 
375 template <int dim, typename Number>
376 template <
377  std::size_t dummy_dim,
378  typename std::enable_if<(dim == dummy_dim) && (dummy_dim != 0), int>::type>
380  const boost::geometry::model::
381  point<Number, dummy_dim, boost::geometry::cs::cartesian> &boost_pt)
382 {
383  Assert(dim <= 3, ExcNotImplemented());
384  this->values[0] = boost::geometry::get<0>(boost_pt);
385  constexpr unsigned int y_index = (dim < 2) ? 0 : 1;
386  constexpr unsigned int z_index = (dim < 3) ? 0 : 2;
387 
388  if (dim >= 2)
389  this->values[y_index] = boost::geometry::get<y_index>(boost_pt);
390 
391  if (dim >= 3)
392  this->values[z_index] = boost::geometry::get<z_index>(boost_pt);
393 }
394 
395 
396 
397 template <int dim, typename Number>
398 inline Point<dim, Number>
399 Point<dim, Number>::unit_vector(unsigned int i)
400 {
402  p[i] = 1.;
403  return p;
404 }
405 
406 
407 template <int dim, typename Number>
408 inline Number
409 Point<dim, Number>::operator()(const unsigned int index) const
410 {
411  AssertIndexRange(index, dim);
412  return this->values[index];
413 }
414 
415 
416 
417 template <int dim, typename Number>
418 inline Number &
419 Point<dim, Number>::operator()(const unsigned int index)
420 {
421  AssertIndexRange(index, dim);
422  return this->values[index];
423 }
424 
425 
426 
427 template <int dim, typename Number>
428 inline Point<dim, Number>
430 {
431  Point<dim, Number> tmp = *this;
432  tmp += p;
433  return tmp;
434 }
435 
436 
437 
438 template <int dim, typename Number>
441 {
442  return (Tensor<1, dim, Number>(*this) -= p);
443 }
444 
445 
446 
447 template <int dim, typename Number>
448 inline Point<dim, Number>
450 {
451  Point<dim, Number> tmp = *this;
452  tmp -= p;
453  return tmp;
454 }
455 
456 
457 
458 template <int dim, typename Number>
459 inline Point<dim, Number>
461 {
462  Point<dim, Number> result;
463  for (unsigned int i = 0; i < dim; ++i)
464  result.values[i] = -this->values[i];
465  return result;
466 }
467 
468 
469 
470 template <int dim, typename Number>
471 template <typename OtherNumber>
472 inline Point<
473  dim,
474  typename ProductType<Number,
475  typename EnableIfScalar<OtherNumber>::type>::type>
476  Point<dim, Number>::operator*(const OtherNumber factor) const
477 {
479  for (unsigned int i = 0; i < dim; ++i)
480  tmp[i] = this->operator[](i) * factor;
481  return tmp;
482 }
483 
484 
485 
486 template <int dim, typename Number>
487 template <typename OtherNumber>
488 inline Point<
489  dim,
490  typename ProductType<Number,
491  typename EnableIfScalar<OtherNumber>::type>::type>
492 Point<dim, Number>::operator/(const OtherNumber factor) const
493 {
495  for (unsigned int i = 0; i < dim; ++i)
496  tmp[i] = this->operator[](i) / factor;
497  return tmp;
498 }
499 
500 
501 
502 template <int dim, typename Number>
503 inline Number Point<dim, Number>::
504  operator*(const Tensor<1, dim, Number> &p) const
505 {
506  Number res = Number();
507  for (unsigned int i = 0; i < dim; ++i)
508  res += this->operator[](i) * p[i];
509  return res;
510 }
511 
512 
513 template <int dim, typename Number>
516 {
517  return this->norm_square();
518 }
519 
520 
521 
522 template <int dim, typename Number>
525 {
526  return std::sqrt(distance_square(p));
527 }
528 
529 
530 
531 template <int dim, typename Number>
534 {
536  for (unsigned int i = 0; i < dim; ++i)
537  {
538  const Number diff = static_cast<Number>(this->values[i]) - p(i);
540  }
541 
542  return sum;
543 }
544 
545 
546 
547 template <int dim, typename Number>
548 template <class Archive>
549 inline void
550 Point<dim, Number>::serialize(Archive &ar, const unsigned int)
551 {
552  // forward to serialization
553  // function in the base class
554  ar &static_cast<Tensor<1, dim, Number> &>(*this);
555 }
556 
557 #endif // DOXYGEN
558 
559 
560 /*--------------------------- Global functions: Point -----------------------*/
561 
562 
569 template <int dim, typename Number, typename OtherNumber>
570 inline Point<
571  dim,
572  typename ProductType<Number,
573  typename EnableIfScalar<OtherNumber>::type>::type>
574 operator*(const OtherNumber factor, const Point<dim, Number> &p)
575 {
576  return p * factor;
577 }
578 
579 
580 
586 template <int dim, typename Number>
587 inline std::ostream &
588 operator<<(std::ostream &out, const Point<dim, Number> &p)
589 {
590  for (unsigned int i = 0; i < dim - 1; ++i)
591  out << p[i] << ' ';
592  out << p[dim - 1];
593 
594  return out;
595 }
596 
597 
598 
603 template <int dim, typename Number>
604 inline std::istream &
605 operator>>(std::istream &in, Point<dim, Number> &p)
606 {
607  for (unsigned int i = 0; i < dim; ++i)
608  in >> p[i];
609 
610  return in;
611 }
612 
613 
614 #ifndef DOXYGEN
615 
621 template <typename Number>
622 inline std::ostream &
623 operator<<(std::ostream &out, const Point<1, Number> &p)
624 {
625  out << p[0];
626 
627  return out;
628 }
629 
630 #endif // DOXYGEN
631 DEAL_II_NAMESPACE_CLOSE
632 
633 #endif
Point< dim, typename ProductType< Number, typename EnableIfScalar< OtherNumber >::type >::type > operator*(const OtherNumber factor, const Point< dim, Number > &p)
Definition: point.h:574
Point< dim, Number > operator+(const Tensor< 1, dim, Number > &) const
static constexpr std::enable_if< std::is_same< Dummy, number >::value &&is_cuda_compatible< Dummy >::value, real_type >::type abs_square(const number &x)
Definition: numbers.h:513
#define AssertIndexRange(index, range)
Definition: exceptions.h:1637
static Point< dim, Number > unit_vector(const unsigned int i)
Number operator()(const unsigned int index) const
Definition: point.h:110
static ::ExceptionBase & ExcMessage(std::string arg1)
Point< dim, Number > operator-() const
#define Assert(cond, exc)
Definition: exceptions.h:1407
void serialize(Archive &ar, const unsigned int version)
numbers::NumberTraits< Number >::real_type distance(const Point< dim, Number > &p) const
SymmetricTensor< rank, dim, Number > sum(const SymmetricTensor< rank, dim, Number > &local, const MPI_Comm &mpi_communicator)
Point< dim, typename ProductType< Number, typename EnableIfScalar< OtherNumber >::type >::type > operator/(const OtherNumber) const
Definition: mpi.h:90
numbers::NumberTraits< Number >::real_type square() const
static ::ExceptionBase & ExcNotImplemented()
numbers::NumberTraits< Number >::real_type distance_square(const Point< dim, Number > &p) const
std::istream & operator>>(std::istream &in, Point< dim, Number > &p)
Definition: point.h:605
Point< dim, typename ProductType< Number, typename EnableIfScalar< OtherNumber >::type >::type > operator*(const OtherNumber) const