Frustum.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <array>
7 #include <boost/optional.hpp>
8 #include <cstddef>
9 #include <limits>
10 
12 #include "Domain/OrientationMap.hpp"
13 #include "Utilities/TypeTraits.hpp"
14 
15 /// \cond
16 namespace PUP {
17 class er;
18 } // namespace PUP
19 /// \endcond
20 
21 namespace domain {
22 namespace CoordinateMaps {
23 
24 /// \ingroup CoordinateMapsGroup
25 ///
26 /// Frustum map from the cube to a rectangular frustum where the bases of the
27 /// frustum are perpendicular to the z-axis. The `lower_bound` and
28 /// `upper_bound` values correspond to the locations of the bases along this
29 /// axis. The `face_vertices` values determine the size of the two rectangular
30 /// bases along the other two axes. For example, for a frustum along the z-axis,
31 /// with the lower base starting at (x,y) = (-2.0,3.0) and extending to
32 /// (2.0,5.0), and with the upper base extending from (0.0,1.0) to (1.0,3.0),
33 /// the corresponding value for `face_vertices` is `{{{{-2.0,3.0}}, {{2.0,5.0}},
34 /// {{0.0,1.0}}, {{1.0,3.0}}}}`. The user may reorient the frustum by passing
35 /// an `OrientationMap` to the constructor. If `with_equiangular_map` is true,
36 /// then this coordinate map applies a tangent function mapping to the logical
37 /// xi and eta coordinates.
38 class Frustum {
39  public:
40  static constexpr size_t dim = 3;
41  Frustum(const std::array<std::array<double, 2>, 4>& face_vertices,
42  double lower_bound, double upper_bound,
43  OrientationMap<3> orientation_of_frustum,
44  bool with_equiangular_map = false) noexcept;
45  Frustum() = default;
46  ~Frustum() = default;
47  Frustum(Frustum&&) = default;
48  Frustum(const Frustum&) = default;
49  Frustum& operator=(const Frustum&) = default;
50  Frustum& operator=(Frustum&&) = default;
51 
52  template <typename T>
54  const std::array<T, 3>& source_coords) const noexcept;
55 
56  /// Returns boost::none if \f$z\f$ is at or beyond the \f$z\f$-coordinate of
57  /// the apex of the pyramid, tetrahedron, or triangular prism that is
58  /// formed by extending the `Frustum` (for a
59  /// \f$z\f$-oriented `Frustum`).
60  boost::optional<std::array<double, 3>> inverse(
61  const std::array<double, 3>& target_coords) const noexcept;
62 
63  template <typename T>
64  tnsr::Ij<tt::remove_cvref_wrap_t<T>, 3, Frame::NoFrame> jacobian(
65  const std::array<T, 3>& source_coords) const noexcept;
66 
67  template <typename T>
68  tnsr::Ij<tt::remove_cvref_wrap_t<T>, 3, Frame::NoFrame> inv_jacobian(
69  const std::array<T, 3>& source_coords) const noexcept;
70 
71  // clang-tidy: google runtime references
72  void pup(PUP::er& p) noexcept; // NOLINT
73 
74  bool is_identity() const noexcept { return is_identity_; }
75 
76  private:
77  friend bool operator==(const Frustum& lhs, const Frustum& rhs) noexcept;
78 
79  OrientationMap<3> orientation_of_frustum_{};
80  double sum_midpoint_x_{std::numeric_limits<double>::signaling_NaN()};
81  double dif_midpoint_x_{std::numeric_limits<double>::signaling_NaN()};
82  double sum_half_length_x_{std::numeric_limits<double>::signaling_NaN()};
83  double dif_half_length_x_{std::numeric_limits<double>::signaling_NaN()};
84  double sum_midpoint_y_{std::numeric_limits<double>::signaling_NaN()};
85  double dif_midpoint_y_{std::numeric_limits<double>::signaling_NaN()};
86  double sum_half_length_y_{std::numeric_limits<double>::signaling_NaN()};
87  double dif_half_length_y_{std::numeric_limits<double>::signaling_NaN()};
88  double midpoint_z_{std::numeric_limits<double>::signaling_NaN()};
89  double half_length_z_{std::numeric_limits<double>::signaling_NaN()};
90  bool with_equiangular_map_{false};
91  bool is_identity_{false};
92 };
93 
94 bool operator!=(const Frustum& lhs, const Frustum& rhs) noexcept;
95 } // namespace CoordinateMaps
96 } // namespace domain
Definition: Strahlkorper.hpp:14
Definition: BlockId.hpp:16
T signaling_NaN(T... args)
Defines a list of useful type aliases for tensors.
Represents an index that is not in a known frame, e.g. some internal intermediate frame that is irrel...
Definition: IndexType.hpp:48
Frustum map from the cube to a rectangular frustum where the bases of the frustum are perpendicular t...
Definition: Frustum.hpp:38
Defines type traits, some of which are future STL type_traits header.