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 <cstddef>
8 : #include <limits>
9 : #include <memory>
10 : #include <optional>
11 : #include <string>
12 : #include <unordered_map>
13 : #include <vector>
14 :
15 : #include "Domain/CoordinateMaps/CoordinateMap.hpp"
16 : #include "Domain/CoordinateMaps/Identity.hpp"
17 : #include "Domain/CoordinateMaps/TimeDependent/Rotation.hpp"
18 : #include "Domain/Creators/TimeDependence/GenerateCoordinateMap.hpp"
19 : #include "Domain/Creators/TimeDependence/TimeDependence.hpp"
20 : #include "Options/String.hpp"
21 : #include "Utilities/ErrorHandling/Assert.hpp"
22 : #include "Utilities/PrettyType.hpp"
23 : #include "Utilities/TMPL.hpp"
24 :
25 : /// \cond
26 : namespace domain::FunctionsOfTime {
27 : class FunctionOfTime;
28 : } // namespace domain::FunctionsOfTime
29 : namespace domain::CoordinateMaps::TimeDependent {
30 : template <typename Map1, typename Map2>
31 : class ProductOf2Maps;
32 : } // namespace domain::CoordinateMaps::TimeDependent
33 : namespace domain {
34 : template <typename SourceFrame, typename TargetFrame, typename... Maps>
35 : class CoordinateMap;
36 : } // namespace domain
37 :
38 : namespace Frame {
39 : struct Distorted;
40 : struct Grid;
41 : struct Inertial;
42 : } // namespace Frame
43 : /// \endcond
44 :
45 : namespace domain::creators::time_dependence {
46 : /*!
47 : * \brief A spatially uniform rotation about the \f$z\f$ axis:
48 : * \f{eqnarray*}
49 : * x &\to& x \cos \alpha(t) - y \sin \alpha(t)\text{,} \\
50 : * y &\to& x \sin \alpha(t) + y \cos \alpha(t)\text{,}
51 : * \f}
52 : * where \f$\alpha(t)\f$ is a `domain::FunctionsOfTime::FunctionOfTime`. For 3
53 : * spatial dimensions, \f$z \to z\f$, and the rotation is implemented as a
54 : * product of the 2D rotation and an identity map. The rotation is undefined
55 : * (and therefore unimplemented here) for 1 spatial dimension.
56 : */
57 : template <size_t MeshDim>
58 1 : class RotationAboutZAxis final : public TimeDependence<MeshDim> {
59 : static_assert(MeshDim > 1,
60 : "RotationAboutZAxis<MeshDim> undefined for MeshDim == 1");
61 :
62 : private:
63 0 : using Identity = domain::CoordinateMaps::Identity<1>;
64 0 : using Rotation = domain::CoordinateMaps::TimeDependent::Rotation<2>;
65 :
66 : public:
67 0 : using maps_list = tmpl::list<
68 : domain::CoordinateMap<Frame::Grid, Frame::Inertial, Rotation>,
69 : domain::CoordinateMap<
70 : Frame::Grid, Frame::Inertial,
71 : CoordinateMaps::TimeDependent::ProductOf2Maps<Rotation, Identity>>>;
72 :
73 0 : static constexpr size_t mesh_dim = MeshDim;
74 :
75 : /// \brief The initial time of the function of time.
76 1 : struct InitialTime {
77 0 : using type = double;
78 0 : static constexpr Options::String help = {
79 : "The initial time of the function of time"};
80 : };
81 0 : struct InitialAngle {
82 0 : using type = double;
83 0 : static constexpr Options::String help = {"The initial angle."};
84 : };
85 : /// \brief The \f$x\f$-, \f$y\f$-, and \f$z\f$-velocity.
86 1 : struct InitialAngularVelocity {
87 0 : using type = double;
88 0 : static constexpr Options::String help = {
89 : "The initial angular velocity of the map."};
90 : };
91 0 : struct InitialAngularAcceleration {
92 0 : using type = double;
93 0 : static constexpr Options::String help = {
94 : "The initial angular acceleration of the map."};
95 : };
96 :
97 0 : using GridToInertialMap = detail::generate_coordinate_map_t<
98 : Frame::Grid, Frame::Inertial,
99 : tmpl::list<tmpl::conditional_t<MeshDim == 2, Rotation,
100 : domain::CoordinateMaps::TimeDependent::
101 : ProductOf2Maps<Rotation, Identity>>>>;
102 :
103 0 : using options = tmpl::list<InitialTime, InitialAngle, InitialAngularVelocity,
104 : InitialAngularAcceleration>;
105 :
106 0 : static constexpr Options::String help = {
107 : "A spatially uniform rotation about the z axis initialized with a "
108 : "constant angular velocity."};
109 :
110 0 : RotationAboutZAxis() = default;
111 0 : ~RotationAboutZAxis() override = default;
112 0 : RotationAboutZAxis(const RotationAboutZAxis&) = delete;
113 0 : RotationAboutZAxis(RotationAboutZAxis&&) = default;
114 0 : RotationAboutZAxis& operator=(const RotationAboutZAxis&) = delete;
115 0 : RotationAboutZAxis& operator=(RotationAboutZAxis&&) = default;
116 :
117 0 : RotationAboutZAxis(double initial_time, double initial_angle,
118 : double initial_angular_velocity,
119 : double initial_angular_acceleration);
120 :
121 1 : auto get_clone() const -> std::unique_ptr<TimeDependence<MeshDim>> override;
122 :
123 1 : auto block_maps_grid_to_inertial(size_t number_of_blocks) const
124 : -> std::vector<std::unique_ptr<domain::CoordinateMapBase<
125 : Frame::Grid, Frame::Inertial, MeshDim>>> override;
126 :
127 1 : auto block_maps_grid_to_distorted(size_t number_of_blocks) const
128 : -> std::vector<std::unique_ptr<domain::CoordinateMapBase<
129 : Frame::Grid, Frame::Distorted, MeshDim>>> override {
130 : using ptr_type =
131 : domain::CoordinateMapBase<Frame::Grid, Frame::Distorted, MeshDim>;
132 : return std::vector<std::unique_ptr<ptr_type>>(number_of_blocks);
133 : }
134 :
135 1 : auto block_maps_distorted_to_inertial(size_t number_of_blocks) const
136 : -> std::vector<std::unique_ptr<domain::CoordinateMapBase<
137 : Frame::Distorted, Frame::Inertial, MeshDim>>> override {
138 : using ptr_type =
139 : domain::CoordinateMapBase<Frame::Distorted, Frame::Inertial, MeshDim>;
140 : return std::vector<std::unique_ptr<ptr_type>>(number_of_blocks);
141 : }
142 :
143 1 : auto functions_of_time(const std::unordered_map<std::string, double>&
144 : initial_expiration_times = {}) const
145 : -> std::unordered_map<
146 : std::string,
147 : std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>> override;
148 :
149 : private:
150 : template <size_t LocalDim>
151 : // NOLINTNEXTLINE(readability-redundant-declaration)
152 0 : friend bool operator==(const RotationAboutZAxis<LocalDim>& lhs,
153 : const RotationAboutZAxis<LocalDim>& rhs);
154 :
155 0 : GridToInertialMap grid_to_inertial_map() const;
156 :
157 0 : double initial_time_{std::numeric_limits<double>::signaling_NaN()};
158 0 : double initial_angle_{std::numeric_limits<double>::signaling_NaN()};
159 0 : double initial_angular_velocity_{
160 : std::numeric_limits<double>::signaling_NaN()};
161 0 : double initial_angular_acceleration_{
162 : std::numeric_limits<double>::signaling_NaN()};
163 0 : inline static const std::string function_of_time_name_{"Rotation"};
164 : };
165 :
166 : template <size_t Dim>
167 0 : bool operator==(const RotationAboutZAxis<Dim>& lhs,
168 : const RotationAboutZAxis<Dim>& rhs);
169 :
170 : template <size_t Dim>
171 0 : bool operator!=(const RotationAboutZAxis<Dim>& lhs,
172 : const RotationAboutZAxis<Dim>& rhs);
173 : } // namespace domain::creators::time_dependence
|