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