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/ShapeMap.hpp"
20 : #include "Domain/FunctionsOfTime/FunctionOfTime.hpp"
21 : #include "Domain/Structure/ObjectLabel.hpp"
22 : #include "Options/Auto.hpp"
23 : #include "Options/String.hpp"
24 : #include "Utilities/TMPL.hpp"
25 :
26 : /// \cond
27 : namespace Frame {
28 : struct Grid;
29 : struct Distorted;
30 : struct Inertial;
31 : } // namespace Frame
32 : /// \endcond
33 :
34 0 : namespace domain::creators::sphere {
35 : /*!
36 : * \brief This holds all options related to the time dependent maps of the
37 : * domain::creators::Sphere domain creator.
38 : *
39 : * \details Currently this class will only add a Shape map (and size
40 : * FunctionOfTime) to the domain. Other maps can be added as needed.
41 : *
42 : * \note This struct contains no information about what blocks the time
43 : * dependent maps will go in.
44 : */
45 1 : struct TimeDependentMapOptions {
46 : private:
47 : template <typename SourceFrame, typename TargetFrame>
48 0 : using MapType =
49 : std::unique_ptr<domain::CoordinateMapBase<SourceFrame, TargetFrame, 3>>;
50 0 : using IdentityMap = domain::CoordinateMaps::Identity<3>;
51 : // Time-dependent maps
52 0 : using ShapeMap = domain::CoordinateMaps::TimeDependent::Shape;
53 0 : using RotScaleTransMap =
54 : domain::CoordinateMaps::TimeDependent::RotScaleTrans<3>;
55 :
56 : template <typename SourceFrame, typename TargetFrame>
57 0 : using IdentityForComposition =
58 : domain::CoordinateMap<SourceFrame, TargetFrame, IdentityMap>;
59 0 : using GridToDistortedComposition =
60 : domain::CoordinateMap<Frame::Grid, Frame::Distorted, ShapeMap>;
61 0 : using GridToInertialComposition =
62 : domain::CoordinateMap<Frame::Grid, Frame::Inertial, ShapeMap,
63 : RotScaleTransMap>;
64 0 : using GridToInertialSimple =
65 : domain::CoordinateMap<Frame::Grid, Frame::Inertial, RotScaleTransMap>;
66 0 : using DistortedToInertialComposition =
67 : domain::CoordinateMap<Frame::Distorted, Frame::Inertial,
68 : RotScaleTransMap>;
69 0 : using GridToInertialShapeMap =
70 : domain::CoordinateMap<Frame::Grid, Frame::Inertial, ShapeMap>;
71 :
72 : public:
73 0 : using maps_list =
74 : tmpl::list<IdentityForComposition<Frame::Grid, Frame::Inertial>,
75 : IdentityForComposition<Frame::Grid, Frame::Distorted>,
76 : IdentityForComposition<Frame::Distorted, Frame::Inertial>,
77 : GridToDistortedComposition, GridToInertialShapeMap,
78 : GridToInertialSimple, GridToInertialComposition,
79 : DistortedToInertialComposition>;
80 :
81 : /// \brief The initial time of the functions of time.
82 1 : struct InitialTime {
83 0 : using type = double;
84 0 : static constexpr Options::String help = {
85 : "The initial time of the functions of time"};
86 : };
87 :
88 0 : using ShapeMapOptions =
89 : time_dependent_options::ShapeMapOptions<false, domain::ObjectLabel::None>;
90 :
91 0 : struct RotationMapOptions {
92 0 : using type = Options::Auto<RotationMapOptions, Options::AutoLabel::None>;
93 0 : static std::string name() { return "RotationMap"; }
94 0 : static constexpr Options::String help = {
95 : "Options for a time-dependent rotation map about an arbitrary axis. "
96 : "Specify 'None' to not use this map."};
97 :
98 0 : struct InitialValues {
99 0 : using type = std::array<std::array<double, 4>, 3>;
100 0 : static constexpr Options::String help = {
101 : "The initial values for the quaternion function and its first two "
102 : "derivatives."};
103 : };
104 :
105 0 : struct DecayTimescaleRotation {
106 0 : using type = double;
107 0 : static constexpr Options::String help = {
108 : "The timescale for how fast the rotation approaches its asymptotic "
109 : "value."};
110 : };
111 :
112 0 : using options = tmpl::list<InitialValues, DecayTimescaleRotation>;
113 0 : RotationMapOptions();
114 0 : RotationMapOptions(std::array<std::array<double, 4>, 3> initial_values_in,
115 : double decay_timescale_in);
116 :
117 0 : std::array<std::array<double, 4>, 3> initial_values{};
118 0 : double decay_timescale{std::numeric_limits<double>::signaling_NaN()};
119 : };
120 :
121 0 : struct ExpansionMapOptions {
122 0 : using type = Options::Auto<ExpansionMapOptions, Options::AutoLabel::None>;
123 0 : static std::string name() { return "ExpansionMap"; }
124 0 : static constexpr Options::String help = {
125 : "Options for the expansion map. Specify 'None' to not use this map."};
126 :
127 0 : struct InitialValues {
128 0 : using type = std::array<double, 3>;
129 0 : static constexpr Options::String help = {
130 : "Initial value and first two derivatives of expansion."};
131 : };
132 :
133 0 : struct DecayTimescaleExpansion {
134 0 : using type = double;
135 0 : static constexpr Options::String help = {
136 : "The timescale for how fast the expansion approaches "
137 : "its asymptotic value."};
138 : };
139 :
140 0 : struct InitialValuesOuterBoundary {
141 0 : using type = std::array<double, 3>;
142 0 : static constexpr Options::String help = {
143 : "Initial value and first two derivatives of expansion outside the "
144 : "transition region."};
145 : };
146 :
147 0 : struct DecayTimescaleExpansionOuterBoundary {
148 0 : using type = double;
149 0 : static constexpr Options::String help = {
150 : "The timescale for how fast the expansion approaches "
151 : "its asymptotic value outside the transition region."};
152 : };
153 :
154 0 : using options = tmpl::list<InitialValues, DecayTimescaleExpansion,
155 : InitialValuesOuterBoundary,
156 : DecayTimescaleExpansionOuterBoundary>;
157 0 : ExpansionMapOptions();
158 0 : ExpansionMapOptions(std::array<double, 3> initial_values_in,
159 : double decay_timescale_in,
160 : std::array<double, 3> initial_values_outer_boundary_in,
161 : double decay_timescale_outer_boundary_in);
162 :
163 0 : std::array<double, 3> initial_values{
164 : std::numeric_limits<double>::signaling_NaN(),
165 : std::numeric_limits<double>::signaling_NaN(),
166 : std::numeric_limits<double>::signaling_NaN()};
167 0 : double decay_timescale{std::numeric_limits<double>::signaling_NaN()};
168 0 : std::array<double, 3> initial_values_outer_boundary{
169 : std::numeric_limits<double>::signaling_NaN(),
170 : std::numeric_limits<double>::signaling_NaN(),
171 : std::numeric_limits<double>::signaling_NaN()};
172 0 : double decay_timescale_outer_boundary{
173 : std::numeric_limits<double>::signaling_NaN()};
174 : };
175 :
176 0 : struct TranslationMapOptions {
177 0 : using type = Options::Auto<TranslationMapOptions, Options::AutoLabel::None>;
178 0 : static std::string name() { return "TranslationMap"; }
179 0 : static constexpr Options::String help = {
180 : "Options for a time-dependent translation map in that keeps the "
181 : "outer boundary fixed. Specify 'None' to not use this map."};
182 :
183 0 : struct InitialValues {
184 0 : using type = std::array<std::array<double, 3>, 3>;
185 0 : static constexpr Options::String help = {
186 : "Initial values for the translation map, its velocity and "
187 : "acceleration."};
188 : };
189 :
190 0 : using options = tmpl::list<InitialValues>;
191 0 : TranslationMapOptions();
192 0 : explicit TranslationMapOptions(
193 : std::array<std::array<double, 3>, 3> initial_values_in);
194 :
195 0 : std::array<std::array<double, 3>, 3> initial_values{};
196 : };
197 :
198 0 : using options = tmpl::list<InitialTime, ShapeMapOptions, RotationMapOptions,
199 : ExpansionMapOptions, TranslationMapOptions>;
200 0 : static constexpr Options::String help{
201 : "The options for all the hard-coded time dependent maps in the "
202 : "Sphere domain."};
203 :
204 0 : TimeDependentMapOptions() = default;
205 :
206 0 : TimeDependentMapOptions(
207 : double initial_time, std::optional<ShapeMapOptions> shape_map_options,
208 : std::optional<RotationMapOptions> rotation_map_options,
209 : std::optional<ExpansionMapOptions> expansion_map_options,
210 : std::optional<TranslationMapOptions> translation_map_options);
211 :
212 : /*!
213 : * \brief Create the function of time map using the options that were
214 : * provided to this class.
215 : *
216 : * Currently, this will add:
217 : *
218 : * - Size: `PiecewisePolynomial<3>`
219 : * - Shape: `PiecewisePolynomial<2>`
220 : * - Rotation: `SettleToConstantQuaternion`
221 : * - Expansion: `SettleToConstant`
222 : * - ExpansionOuterBoundary: `PiecewisePolynomial<2>`
223 : * - Translation: `PiecewisePolynomial<2>`
224 : */
225 : std::unordered_map<std::string,
226 : std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>>
227 1 : create_functions_of_time(double inner_radius,
228 : const std::unordered_map<std::string, double>&
229 : initial_expiration_times) const;
230 :
231 : /*!
232 : * \brief Construct the actual maps that will be used.
233 : *
234 : * Currently, this constructs a:
235 : *
236 : * - Shape: `Shape` (with a size function of time)
237 : * - Rotation: `Rotation`
238 : * - Expansion: `Expansion`
239 : * - Expansion outside the transition region: `ExpansionOuterBoundary`
240 : * - Translation: `Translation`
241 : */
242 1 : void build_maps(const std::array<double, 3>& center,
243 : std::pair<double, double> inner_shell_radii,
244 : std::pair<double, double> outer_shell_radii);
245 :
246 : /*!
247 : * \brief This will construct the map from `Frame::Distorted` to
248 : * `Frame::Inertial`.
249 : *
250 : * If the argument `include_distorted_map` is true, then this will be a
251 : * RotScaleTrans map. If it is false, then this returns `nullptr`.
252 : */
253 1 : MapType<Frame::Distorted, Frame::Inertial> distorted_to_inertial_map(
254 : bool include_distorted_map) const;
255 :
256 : /*!
257 : * \brief This will construct the map from `Frame::Grid` to
258 : * `Frame::Distorted`.
259 : *
260 : * If the argument `include_distorted_map` is true, then this will add a
261 : * `Shape` map (with a size function of time). If it is false, then this
262 : * returns `nullptr`.
263 : */
264 1 : MapType<Frame::Grid, Frame::Distorted> grid_to_distorted_map(
265 : bool include_distorted_map) const;
266 :
267 : /*!
268 : * \brief This will construct the map from `Frame::Grid` to
269 : * `Frame::Inertial`.
270 : *
271 : * If the argument `include_distorted_map` is true, then this map will
272 : * have a `Shape` map (with a size function of time). If it is false, then
273 : * there will be a RotScaleTrans map in either the inner region or in the
274 : * transition region.
275 : */
276 1 : MapType<Frame::Grid, Frame::Inertial> grid_to_inertial_map(
277 : bool include_distorted_map, bool use_rigid) const;
278 :
279 : /*!
280 : * \brief Whether or not the distorted frame is being used. I.e. whether or
281 : * not shape map options were specified.
282 : */
283 1 : bool using_distorted_frame() const;
284 :
285 0 : inline static const std::string size_name{"Size"};
286 0 : inline static const std::string shape_name{"Shape"};
287 0 : inline static const std::string rotation_name{"Rotation"};
288 0 : inline static const std::string expansion_name{"Expansion"};
289 0 : inline static const std::string expansion_outer_boundary_name{
290 : "ExpansionOuterBoundary"};
291 0 : inline static const std::string translation_name{"Translation"};
292 :
293 : private:
294 0 : double initial_time_{std::numeric_limits<double>::signaling_NaN()};
295 0 : std::optional<ShapeMap> shape_map_{};
296 0 : RotScaleTransMap inner_rot_scale_trans_map_{};
297 0 : RotScaleTransMap transition_rot_scale_trans_map_{};
298 :
299 0 : std::optional<ShapeMapOptions> shape_map_options_{};
300 0 : std::optional<RotationMapOptions> rotation_map_options_{};
301 0 : std::optional<ExpansionMapOptions> expansion_map_options_{};
302 0 : std::optional<TranslationMapOptions> translation_map_options_{};
303 : };
304 : } // namespace domain::creators::sphere
|