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 <vector> 11 : 12 : #include "Domain/BoundaryConditions/BoundaryCondition.hpp" 13 : #include "Domain/BoundaryConditions/GetBoundaryConditionsBase.hpp" 14 : #include "Domain/Creators/DomainCreator.hpp" // IWYU pragma: keep 15 : #include "Domain/Domain.hpp" 16 : #include "Domain/Structure/DirectionMap.hpp" 17 : #include "Options/Context.hpp" 18 : #include "Options/String.hpp" 19 : #include "Utilities/TMPL.hpp" 20 : 21 : /// \cond 22 : namespace domain { 23 : namespace CoordinateMaps { 24 : class Affine; 25 : template <size_t VolumeDim> 26 : class DiscreteRotation; 27 : template <typename Map1, typename Map2> 28 : class ProductOf2Maps; 29 : } // namespace CoordinateMaps 30 : 31 : template <typename SourceFrame, typename TargetFrame, typename... Maps> 32 : class CoordinateMap; 33 : } // namespace domain 34 : /// \endcond 35 : 36 : namespace domain { 37 : namespace creators { 38 : /// Create a 2D Domain consisting of four rotated Blocks. 39 : /// - The lower left block has its logical \f$\xi\f$-axis aligned with 40 : /// the grid x-axis. 41 : /// 42 : /// - The lower right block is rotated a half-turn (180 degrees) relative to the 43 : /// lower left block. 44 : /// 45 : /// - The upper left block is rotated a quarter-turn counterclockwise 46 : /// (+90 degrees) relative to the lower left block. 47 : // 48 : /// - The upper right block is rotated a quarter-turn clockwise 49 : /// (-90 degrees) relative to the lower left block. 50 : /// 51 : /// This DomainCreator is useful for testing code that deals with 52 : /// unaligned blocks. 53 1 : class RotatedRectangles : public DomainCreator<2> { 54 : public: 55 0 : using maps_list = 56 : tmpl::list<domain::CoordinateMap< 57 : Frame::BlockLogical, Frame::Inertial, 58 : CoordinateMaps::ProductOf2Maps<CoordinateMaps::Affine, 59 : CoordinateMaps::Affine>>, 60 : domain::CoordinateMap< 61 : Frame::BlockLogical, Frame::Inertial, 62 : CoordinateMaps::DiscreteRotation<2>, 63 : CoordinateMaps::ProductOf2Maps<CoordinateMaps::Affine, 64 : CoordinateMaps::Affine>>>; 65 : 66 0 : struct LowerBound { 67 0 : using type = std::array<double, 2>; 68 0 : static constexpr Options::String help = { 69 : "Sequence of [x,y] for lower bounds in the target frame."}; 70 : }; 71 : 72 0 : struct Midpoint { 73 0 : using type = std::array<double, 2>; 74 0 : static constexpr Options::String help = { 75 : "Sequence of [x,y] for midpoints in the target frame."}; 76 : }; 77 : 78 0 : struct UpperBound { 79 0 : using type = std::array<double, 2>; 80 0 : static constexpr Options::String help = { 81 : "Sequence of [x,y] for upper bounds in the target frame."}; 82 : }; 83 : 84 0 : struct IsPeriodicIn { 85 0 : using type = std::array<bool, 2>; 86 0 : static constexpr Options::String help = { 87 : "Sequence for [x], true if periodic."}; 88 : }; 89 : 90 0 : struct InitialRefinement { 91 0 : using type = std::array<size_t, 2>; 92 0 : static constexpr Options::String help = { 93 : "Initial refinement level in [x, y]."}; 94 : }; 95 : 96 0 : struct InitialGridPoints { 97 0 : using type = std::array<std::array<size_t, 2>, 2>; 98 0 : static constexpr Options::String help = { 99 : "Initial number of grid points in [[x], [y]]."}; 100 : }; 101 : 102 : template <typename BoundaryConditionsBase> 103 0 : struct BoundaryCondition { 104 0 : static std::string name() { return "BoundaryCondition"; } 105 0 : static constexpr Options::String help = 106 : "The boundary condition to impose on all sides."; 107 0 : using type = std::unique_ptr<BoundaryConditionsBase>; 108 : }; 109 : 110 0 : using common_options = tmpl::list<LowerBound, Midpoint, UpperBound, 111 : InitialRefinement, InitialGridPoints>; 112 0 : using options_periodic = tmpl::list<IsPeriodicIn>; 113 : 114 : template <typename Metavariables> 115 0 : using options = tmpl::append< 116 : common_options, 117 : tmpl::conditional_t< 118 : domain::BoundaryConditions::has_boundary_conditions_base_v< 119 : typename Metavariables::system>, 120 : tmpl::list<BoundaryCondition< 121 : domain::BoundaryConditions::get_boundary_conditions_base< 122 : typename Metavariables::system>>>, 123 : options_periodic>>; 124 : 125 0 : static constexpr Options::String help = { 126 : "A DomainCreator useful for testing purposes.\n" 127 : "RotatedRectangles uses four rotated Blocks to create the rectangle\n" 128 : "[LowerX,UpperX] x [LowerY,UpperY]. The outermost index to\n" 129 : "InitialGridPoints is the dimension index, and the innermost index is\n" 130 : "the block index along that dimension."}; 131 : 132 0 : RotatedRectangles( 133 : typename LowerBound::type lower_xy, typename Midpoint::type midpoint_xy, 134 : typename UpperBound::type upper_xy, 135 : typename InitialRefinement::type initial_refinement_level_xy, 136 : typename InitialGridPoints::type initial_number_of_grid_points_in_xy, 137 : typename IsPeriodicIn::type is_periodic_in); 138 : 139 0 : RotatedRectangles( 140 : typename LowerBound::type lower_xy, typename Midpoint::type midpoint_xy, 141 : typename UpperBound::type upper_xy, 142 : typename InitialRefinement::type initial_refinement_level_xy, 143 : typename InitialGridPoints::type initial_number_of_grid_points_in_xy, 144 : std::unique_ptr<domain::BoundaryConditions::BoundaryCondition> 145 : boundary_condition, 146 : const Options::Context& context = {}); 147 : 148 0 : RotatedRectangles() = default; 149 0 : RotatedRectangles(const RotatedRectangles&) = delete; 150 0 : RotatedRectangles(RotatedRectangles&&) = default; 151 0 : RotatedRectangles& operator=(const RotatedRectangles&) = delete; 152 0 : RotatedRectangles& operator=(RotatedRectangles&&) = default; 153 0 : ~RotatedRectangles() override = default; 154 : 155 0 : Domain<2> create_domain() const override; 156 : 157 : std::vector<DirectionMap< 158 : 2, std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>>> 159 1 : external_boundary_conditions() const override; 160 : 161 1 : std::vector<std::array<size_t, 2>> initial_extents() const override; 162 : 163 1 : std::vector<std::array<size_t, 2>> initial_refinement_levels() const override; 164 : 165 : private: 166 0 : typename LowerBound::type lower_xy_{ 167 : {std::numeric_limits<double>::signaling_NaN()}}; 168 0 : typename Midpoint::type midpoint_xy_{ 169 : {std::numeric_limits<double>::signaling_NaN()}}; 170 0 : typename UpperBound::type upper_xy_{ 171 : {std::numeric_limits<double>::signaling_NaN()}}; 172 0 : typename IsPeriodicIn::type is_periodic_in_{{false, false}}; 173 0 : typename InitialRefinement::type initial_refinement_level_xy_{ 174 : {std::numeric_limits<size_t>::max()}}; 175 0 : typename InitialGridPoints::type initial_number_of_grid_points_in_xy_{ 176 : {{{std::numeric_limits<size_t>::max()}}}}; 177 : std::unique_ptr<domain::BoundaryConditions::BoundaryCondition> 178 0 : boundary_condition_; 179 : }; 180 : } // namespace creators 181 : } // namespace domain