Line data Source code
1 1 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : /// \file
5 : /// Defines class ExcisionSphere.
6 :
7 : #pragma once
8 :
9 : #include <cstddef>
10 : #include <iosfwd>
11 : #include <limits>
12 : #include <memory>
13 : #include <optional>
14 : #include <unordered_map>
15 :
16 : #include "DataStructures/Tensor/Tensor.hpp"
17 : #include "Domain/CoordinateMaps/CoordinateMap.hpp"
18 : #include "Domain/Structure/Direction.hpp"
19 : #include "Domain/Structure/ElementId.hpp"
20 :
21 : /// \cond
22 : namespace Frame {
23 : struct Grid;
24 : struct Inertial;
25 : } // namespace Frame
26 : namespace PUP {
27 : class er;
28 : } // namespace PUP
29 : /// \endcond
30 :
31 : /// \ingroup ComputationalDomainGroup
32 : /// The excision sphere information of a computational domain.
33 : /// The excision sphere is assumed to be a coordinate sphere in the
34 : /// grid frame.
35 : ///
36 : /// \tparam VolumeDim the volume dimension.
37 : template <size_t VolumeDim>
38 1 : class ExcisionSphere {
39 : public:
40 : /// Constructor
41 : ///
42 : /// \param radius the radius of the excision sphere in the
43 : /// computational domain.
44 : /// \param center the coordinate center of the excision sphere
45 : /// in the computational domain.
46 : /// \param abutting_directions the set of blocks that touch the excision
47 : /// sphere, along with the direction in which they touch it.
48 1 : ExcisionSphere(
49 : double radius, tnsr::I<double, VolumeDim, Frame::Grid> center,
50 : std::unordered_map<size_t, Direction<VolumeDim>> abutting_directions);
51 :
52 : /// Default constructor needed for Charm++ serialization.
53 1 : ExcisionSphere() = default;
54 0 : ~ExcisionSphere() = default;
55 0 : ExcisionSphere(const ExcisionSphere<VolumeDim>& /*rhs*/);
56 0 : ExcisionSphere(ExcisionSphere<VolumeDim>&& /*rhs*/) = default;
57 0 : ExcisionSphere<VolumeDim>& operator=(
58 : const ExcisionSphere<VolumeDim>& /*rhs*/);
59 0 : ExcisionSphere<VolumeDim>& operator=(ExcisionSphere<VolumeDim>&& /*rhs*/) =
60 : default;
61 :
62 : /// \brief Add time dependent coordinate maps to the ExcisionSphere
63 : ///
64 : /// \note There is no actual mesh that is inside an excision sphere, but this
65 : /// region moves along with the domain just the same. Meaning that we
66 : /// should be able to take a point inside the excision sphere and map it to
67 : /// the Inertial frame.
68 1 : void inject_time_dependent_maps(
69 : std::unique_ptr<
70 : domain::CoordinateMapBase<Frame::Grid, Frame::Inertial, VolumeDim>>
71 : moving_mesh_grid_to_inertial_map);
72 :
73 : /// \brief The map going from the last time independent frame to the frame in
74 : /// which the equations are solved. Only used when `is_time_dependent()` is
75 : /// true.
76 : const domain::CoordinateMapBase<Frame::Grid, Frame::Inertial, VolumeDim>&
77 1 : moving_mesh_grid_to_inertial_map() const;
78 :
79 : /// \brief Return whether or not time dependent maps have been injected
80 1 : bool is_time_dependent() const { return grid_to_inertial_map_ != nullptr; }
81 :
82 : /// The radius of the ExcisionSphere.
83 1 : double radius() const { return radius_; }
84 :
85 : /// The coordinate center of the ExcisionSphere.
86 1 : const tnsr::I<double, VolumeDim, Frame::Grid>& center() const {
87 : return center_;
88 : }
89 :
90 : /// The set of blocks that touch the excision sphere, along with the direction
91 : /// in which they touch it
92 1 : const std::unordered_map<size_t, Direction<VolumeDim>>& abutting_directions()
93 : const {
94 : return abutting_directions_;
95 : }
96 : /// Checks whether an element abuts the excision sphere. If it does, returns
97 : /// the corresponding direction. Else, `nullopt` is returned.
98 1 : std::optional<Direction<VolumeDim>> abutting_direction(
99 : const ElementId<VolumeDim>& element_id) const;
100 :
101 : // NOLINTNEXTLINE(google-runtime-references)
102 0 : void pup(PUP::er& p);
103 :
104 : private:
105 : template <size_t LocalVolumeDim>
106 : // NOLINTNEXTLINE(readability-redundant-declaration)
107 0 : friend bool operator==(const ExcisionSphere<LocalVolumeDim>& lhs,
108 : const ExcisionSphere<LocalVolumeDim>& rhs);
109 :
110 0 : double radius_{std::numeric_limits<double>::signaling_NaN()};
111 0 : tnsr::I<double, VolumeDim, Frame::Grid> center_{
112 : std::numeric_limits<double>::signaling_NaN()};
113 0 : std::unordered_map<size_t, Direction<VolumeDim>> abutting_directions_{};
114 : std::unique_ptr<
115 : domain::CoordinateMapBase<Frame::Grid, Frame::Inertial, VolumeDim>>
116 0 : grid_to_inertial_map_{};
117 : };
118 :
119 : template <size_t VolumeDim>
120 0 : std::ostream& operator<<(std::ostream& os,
121 : const ExcisionSphere<VolumeDim>& excision_sphere);
122 :
123 : template <size_t VolumeDim>
124 0 : bool operator!=(const ExcisionSphere<VolumeDim>& lhs,
125 : const ExcisionSphere<VolumeDim>& rhs);
|