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/ShapeMapOptions.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 :
114 0 : std::array<std::array<double, 4>, 3> initial_values{};
115 0 : double decay_timescale{std::numeric_limits<double>::signaling_NaN()};
116 : };
117 :
118 0 : struct ExpansionMapOptions {
119 0 : using type = Options::Auto<ExpansionMapOptions, Options::AutoLabel::None>;
120 0 : static std::string name() { return "ExpansionMap"; }
121 0 : static constexpr Options::String help = {
122 : "Options for the expansion map. Specify 'None' to not use this map."};
123 :
124 0 : struct InitialValues {
125 0 : using type = std::array<double, 3>;
126 0 : static constexpr Options::String help = {
127 : "Initial value and first two derivatives of expansion."};
128 : };
129 :
130 0 : struct DecayTimescaleExpansion {
131 0 : using type = double;
132 0 : static constexpr Options::String help = {
133 : "The timescale for how fast the expansion approaches "
134 : "its asymptotic value."};
135 : };
136 :
137 0 : struct InitialValuesOuterBoundary {
138 0 : using type = std::array<double, 3>;
139 0 : static constexpr Options::String help = {
140 : "Initial value and first two derivatives of expansion outside the "
141 : "transition region."};
142 : };
143 :
144 0 : struct DecayTimescaleExpansionOuterBoundary {
145 0 : using type = double;
146 0 : static constexpr Options::String help = {
147 : "The timescale for how fast the expansion approaches "
148 : "its asymptotic value outside the transition region."};
149 : };
150 :
151 0 : using options = tmpl::list<InitialValues, DecayTimescaleExpansion,
152 : InitialValuesOuterBoundary,
153 : DecayTimescaleExpansionOuterBoundary>;
154 :
155 0 : std::array<double, 3> initial_values{
156 : std::numeric_limits<double>::signaling_NaN(),
157 : std::numeric_limits<double>::signaling_NaN(),
158 : std::numeric_limits<double>::signaling_NaN()};
159 0 : double decay_timescale{std::numeric_limits<double>::signaling_NaN()};
160 0 : std::array<double, 3> initial_values_outer_boundary{
161 : std::numeric_limits<double>::signaling_NaN(),
162 : std::numeric_limits<double>::signaling_NaN(),
163 : std::numeric_limits<double>::signaling_NaN()};
164 0 : double decay_timescale_outer_boundary{
165 : std::numeric_limits<double>::signaling_NaN()};
166 : };
167 :
168 0 : struct TranslationMapOptions {
169 0 : using type = Options::Auto<TranslationMapOptions, Options::AutoLabel::None>;
170 0 : static std::string name() { return "TranslationMap"; }
171 0 : static constexpr Options::String help = {
172 : "Options for a time-dependent translation map in that keeps the "
173 : "outer boundary fixed. Specify 'None' to not use this map."};
174 :
175 0 : struct InitialValues {
176 0 : using type = std::array<std::array<double, 3>, 3>;
177 0 : static constexpr Options::String help = {
178 : "Initial values for the translation map, its velocity and "
179 : "acceleration."};
180 : };
181 :
182 0 : using options = tmpl::list<InitialValues>;
183 :
184 0 : std::array<std::array<double, 3>, 3> initial_values{};
185 : };
186 :
187 0 : using options = tmpl::list<InitialTime, ShapeMapOptions, RotationMapOptions,
188 : ExpansionMapOptions, TranslationMapOptions>;
189 0 : static constexpr Options::String help{
190 : "The options for all the hard-coded time dependent maps in the "
191 : "Sphere domain."};
192 :
193 0 : TimeDependentMapOptions() = default;
194 :
195 0 : TimeDependentMapOptions(
196 : double initial_time, std::optional<ShapeMapOptions> shape_map_options,
197 : std::optional<RotationMapOptions> rotation_map_options,
198 : std::optional<ExpansionMapOptions> expansion_map_options,
199 : std::optional<TranslationMapOptions> translation_map_options);
200 :
201 : /*!
202 : * \brief Create the function of time map using the options that were
203 : * provided to this class.
204 : *
205 : * Currently, this will add:
206 : *
207 : * - Size: `PiecewisePolynomial<3>`
208 : * - Shape: `PiecewisePolynomial<2>`
209 : * - Rotation: `SettleToConstantQuaternion`
210 : * - Expansion: `SettleToConstant`
211 : * - ExpansionOuterBoundary: `PiecewisePolynomial<2>`
212 : * - Translation: `PiecewisePolynomial<2>`
213 : */
214 : std::unordered_map<std::string,
215 : std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>>
216 1 : create_functions_of_time(double inner_radius,
217 : const std::unordered_map<std::string, double>&
218 : initial_expiration_times) const;
219 :
220 : /*!
221 : * \brief Construct the actual maps that will be used.
222 : *
223 : * Currently, this constructs a:
224 : *
225 : * - Shape: `Shape` (with a size function of time)
226 : * - Rotation: `Rotation`
227 : * - Expansion: `Expansion`
228 : * - Expansion outside the transition region: `ExpansionOuterBoundary`
229 : * - Translation: `Translation`
230 : */
231 1 : void build_maps(const std::array<double, 3>& center,
232 : std::pair<double, double> inner_shell_radii,
233 : std::pair<double, double> outer_shell_radii);
234 :
235 : /*!
236 : * \brief This will construct the map from `Frame::Distorted` to
237 : * `Frame::Inertial`.
238 : *
239 : * If the argument `include_distorted_map` is true, then this will be a
240 : * RotScaleTrans map. If it is false, then this returns `nullptr`.
241 : */
242 1 : MapType<Frame::Distorted, Frame::Inertial> distorted_to_inertial_map(
243 : bool include_distorted_map) const;
244 :
245 : /*!
246 : * \brief This will construct the map from `Frame::Grid` to
247 : * `Frame::Distorted`.
248 : *
249 : * If the argument `include_distorted_map` is true, then this will add a
250 : * `Shape` map (with a size function of time). If it is false, then this
251 : * returns `nullptr`.
252 : */
253 1 : MapType<Frame::Grid, Frame::Distorted> grid_to_distorted_map(
254 : bool include_distorted_map) const;
255 :
256 : /*!
257 : * \brief This will construct the map from `Frame::Grid` to
258 : * `Frame::Inertial`.
259 : *
260 : * If the argument `include_distorted_map` is true, then this map will
261 : * have a `Shape` map (with a size function of time). If it is false, then
262 : * there will be a RotScaleTrans map in either the inner region or in the
263 : * transition region.
264 : */
265 1 : MapType<Frame::Grid, Frame::Inertial> grid_to_inertial_map(
266 : bool include_distorted_map, bool use_rigid) const;
267 :
268 : /*!
269 : * \brief Whether or not the distorted frame is being used. I.e. whether or
270 : * not shape map options were specified.
271 : */
272 1 : bool using_distorted_frame() const;
273 :
274 0 : inline static const std::string size_name{"Size"};
275 0 : inline static const std::string shape_name{"Shape"};
276 0 : inline static const std::string rotation_name{"Rotation"};
277 0 : inline static const std::string expansion_name{"Expansion"};
278 0 : inline static const std::string expansion_outer_boundary_name{
279 : "ExpansionOuterBoundary"};
280 0 : inline static const std::string translation_name{"Translation"};
281 :
282 : private:
283 0 : double initial_time_{std::numeric_limits<double>::signaling_NaN()};
284 0 : std::optional<ShapeMap> shape_map_{};
285 0 : RotScaleTransMap inner_rot_scale_trans_map_{};
286 0 : RotScaleTransMap transition_rot_scale_trans_map_{};
287 :
288 0 : std::optional<ShapeMapOptions> shape_map_options_{};
289 0 : std::optional<RotationMapOptions> rotation_map_options_{};
290 0 : std::optional<ExpansionMapOptions> expansion_map_options_{};
291 0 : std::optional<TranslationMapOptions> translation_map_options_{};
292 : };
293 : } // namespace domain::creators::sphere
|