Line data Source code
1 0 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : #pragma once
5 :
6 : #include <array>
7 : #include <limits>
8 : #include <memory>
9 : #include <optional>
10 : #include <string>
11 : #include <type_traits>
12 : #include <variant>
13 :
14 : #include "Domain/CoordinateMaps/CoordinateMap.hpp"
15 : #include "Domain/CoordinateMaps/Identity.hpp"
16 : #include "Domain/CoordinateMaps/TimeDependent/RotScaleTrans.hpp"
17 : #include "Domain/CoordinateMaps/TimeDependent/Shape.hpp"
18 : #include "Domain/CoordinateMaps/TimeDependent/Translation.hpp"
19 : #include "Domain/Creators/TimeDependentOptions/ExpansionMap.hpp"
20 : #include "Domain/Creators/TimeDependentOptions/RotationMap.hpp"
21 : #include "Domain/Creators/TimeDependentOptions/ShapeMap.hpp"
22 : #include "Domain/Creators/TimeDependentOptions/TranslationMap.hpp"
23 : #include "Domain/FunctionsOfTime/FunctionOfTime.hpp"
24 : #include "Domain/Structure/ObjectLabel.hpp"
25 : #include "Options/Auto.hpp"
26 : #include "Options/String.hpp"
27 : #include "Utilities/TMPL.hpp"
28 :
29 : /// \cond
30 : namespace Frame {
31 : struct Grid;
32 : struct Distorted;
33 : struct Inertial;
34 : } // namespace Frame
35 : /// \endcond
36 :
37 0 : namespace domain::creators::sphere {
38 : /*!
39 : * \brief This holds all options related to the time dependent maps of the
40 : * domain::creators::Sphere domain creator.
41 : */
42 1 : struct TimeDependentMapOptions {
43 : private:
44 : template <typename SourceFrame, typename TargetFrame>
45 0 : using MapType =
46 : std::unique_ptr<domain::CoordinateMapBase<SourceFrame, TargetFrame, 3>>;
47 0 : using IdentityMap = domain::CoordinateMaps::Identity<3>;
48 : // Time-dependent maps
49 0 : using ShapeMap = domain::CoordinateMaps::TimeDependent::Shape;
50 0 : using RotScaleTransMap =
51 : domain::CoordinateMaps::TimeDependent::RotScaleTrans<3>;
52 :
53 : template <typename SourceFrame, typename TargetFrame>
54 0 : using IdentityForComposition =
55 : domain::CoordinateMap<SourceFrame, TargetFrame, IdentityMap>;
56 0 : using GridToDistortedComposition =
57 : domain::CoordinateMap<Frame::Grid, Frame::Distorted, ShapeMap>;
58 0 : using GridToInertialComposition =
59 : domain::CoordinateMap<Frame::Grid, Frame::Inertial, ShapeMap,
60 : RotScaleTransMap>;
61 0 : using GridToInertialSimple =
62 : domain::CoordinateMap<Frame::Grid, Frame::Inertial, RotScaleTransMap>;
63 0 : using DistortedToInertialComposition =
64 : domain::CoordinateMap<Frame::Distorted, Frame::Inertial,
65 : RotScaleTransMap>;
66 0 : using GridToInertialShapeMap =
67 : domain::CoordinateMap<Frame::Grid, Frame::Inertial, ShapeMap>;
68 :
69 : public:
70 0 : using maps_list =
71 : tmpl::list<IdentityForComposition<Frame::Grid, Frame::Inertial>,
72 : IdentityForComposition<Frame::Grid, Frame::Distorted>,
73 : IdentityForComposition<Frame::Distorted, Frame::Inertial>,
74 : GridToDistortedComposition, GridToInertialShapeMap,
75 : GridToInertialSimple, GridToInertialComposition,
76 : DistortedToInertialComposition>;
77 :
78 : /// \brief The initial time of the functions of time.
79 1 : struct InitialTime {
80 0 : using type = double;
81 0 : static constexpr Options::String help = {
82 : "The initial time of the functions of time"};
83 : };
84 :
85 0 : using ShapeMapOptions =
86 : time_dependent_options::ShapeMapOptions<false, domain::ObjectLabel::None>;
87 0 : using ShapeMapOptionType = typename ShapeMapOptions::type::value_type;
88 :
89 0 : using RotationMapOptions = time_dependent_options::RotationMapOptions<true>;
90 0 : using RotationMapOptionType = typename RotationMapOptions::type::value_type;
91 :
92 0 : using ExpansionMapOptions = time_dependent_options::ExpansionMapOptions<true>;
93 0 : using ExpansionMapOptionType = typename ExpansionMapOptions::type::value_type;
94 :
95 0 : using TranslationMapOptions =
96 : time_dependent_options::TranslationMapOptions<3>;
97 0 : using TranslationMapOptionType =
98 : typename TranslationMapOptions::type::value_type;
99 :
100 0 : struct TransitionRotScaleTrans {
101 0 : using type = bool;
102 0 : static constexpr Options::String help = {
103 : "Transition rotation, expansion, and translation to zero in the outer "
104 : "shell"};
105 : };
106 :
107 0 : using options = tmpl::list<InitialTime, ShapeMapOptions, RotationMapOptions,
108 : ExpansionMapOptions, TranslationMapOptions,
109 : TransitionRotScaleTrans>;
110 0 : static constexpr Options::String help{
111 : "The options for all the hard-coded time dependent maps in the "
112 : "Sphere domain."};
113 :
114 0 : TimeDependentMapOptions() = default;
115 :
116 0 : TimeDependentMapOptions(double initial_time,
117 : ShapeMapOptionType shape_map_options,
118 : RotationMapOptionType rotation_map_options,
119 : ExpansionMapOptionType expansion_map_options,
120 : TranslationMapOptionType translation_map_options,
121 : bool transition_rot_scale_trans);
122 :
123 : /*!
124 : * \brief Create the function of time map using the options that were
125 : * provided to this class.
126 : *
127 : * Currently, this will add:
128 : *
129 : * - Size: `PiecewisePolynomial<3>`
130 : * - Shape: `PiecewisePolynomial<2>`
131 : * - Rotation: `SettleToConstantQuaternion`
132 : * - Expansion: `SettleToConstant`
133 : * - ExpansionOuterBoundary: `PiecewisePolynomial<2>`
134 : * - Translation: `PiecewisePolynomial<2>`
135 : */
136 : std::unordered_map<std::string,
137 : std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>>
138 1 : create_functions_of_time(const std::unordered_map<std::string, double>&
139 : initial_expiration_times) const;
140 :
141 : /*!
142 : * \brief Construct the actual maps that will be used.
143 : *
144 : * Currently, this constructs a:
145 : *
146 : * - Shape: `Shape` (with a size function of time)
147 : * - Rotation: `Rotation`
148 : * - Expansion: `Expansion`
149 : * - Expansion outside the transition region: `ExpansionOuterBoundary`
150 : * - Translation: `Translation`
151 : */
152 1 : void build_maps(const std::array<double, 3>& center, bool is_filled,
153 : double inner_radius,
154 : const std::vector<double>& radial_partitions,
155 : double outer_radius);
156 :
157 : /*!
158 : * \brief This will construct the map from `Frame::Distorted` to
159 : * `Frame::Inertial`.
160 : *
161 : * For blocks with a shape map, this will be a RotScaleTrans map. For other
162 : * blocks, this returns `nullptr`.
163 : */
164 1 : MapType<Frame::Distorted, Frame::Inertial> distorted_to_inertial_map(
165 : size_t block_number, bool is_inner_cube,
166 : size_t num_blocks_per_shell) const;
167 :
168 : /*!
169 : * \brief This will construct the map from `Frame::Grid` to
170 : * `Frame::Distorted`.
171 : *
172 : * For blocks with a shape map, this will return the `Shape` map (with a size
173 : * function of time). For other blocks, this returns `nullptr`.
174 : */
175 1 : MapType<Frame::Grid, Frame::Distorted> grid_to_distorted_map(
176 : size_t block_number, bool is_inner_cube,
177 : size_t num_blocks_per_shell) const;
178 :
179 : /*!
180 : * \brief This will construct the map from `Frame::Grid` to `Frame::Inertial`.
181 : *
182 : * For blocks with a shape map, this will return the `Shape` and
183 : * `RotScaleTrans` composition. For other blocks, this returns just the
184 : * `RotScaleTrans` map. In the outer shell, the `RotScaleTrans` map will
185 : * transition to zero.
186 : */
187 1 : MapType<Frame::Grid, Frame::Inertial> grid_to_inertial_map(
188 : size_t block_number, bool is_outer_shell, bool is_central_region,
189 : size_t num_blocks_per_shell) const;
190 :
191 : /*!
192 : * \brief Whether or not the distorted frame is being used. I.e. whether or
193 : * not shape map options were specified.
194 : */
195 1 : bool using_distorted_frame() const;
196 :
197 0 : inline static const std::string size_name{"Size"};
198 0 : inline static const std::string shape_name{"Shape"};
199 0 : inline static const std::string rotation_name{"Rotation"};
200 0 : inline static const std::string expansion_name{"Expansion"};
201 0 : inline static const std::string expansion_outer_boundary_name{
202 : "ExpansionOuterBoundary"};
203 0 : inline static const std::string translation_name{"Translation"};
204 :
205 : private:
206 0 : double initial_time_{std::numeric_limits<double>::signaling_NaN()};
207 0 : bool filled_{false};
208 0 : double deformed_radius_{std::numeric_limits<double>::signaling_NaN()};
209 0 : std::array<ShapeMap, 12> shape_maps_{};
210 0 : RotScaleTransMap inner_rot_scale_trans_map_{};
211 0 : RotScaleTransMap transition_rot_scale_trans_map_{};
212 :
213 0 : ShapeMapOptionType shape_map_options_;
214 0 : RotationMapOptionType rotation_map_options_;
215 0 : ExpansionMapOptionType expansion_map_options_;
216 0 : TranslationMapOptionType translation_map_options_;
217 0 : bool transition_rot_scale_trans_{false};
218 : };
219 : } // namespace domain::creators::sphere
|