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 <memory>
9 : #include <string>
10 : #include <unordered_map>
11 : #include <unordered_set>
12 : #include <vector>
13 :
14 : #include "Domain/BoundaryConditions/BoundaryCondition.hpp"
15 : #include "Domain/BoundaryConditions/GetBoundaryConditionsBase.hpp"
16 : #include "Domain/Creators/DomainCreator.hpp"
17 : #include "Domain/Domain.hpp"
18 : #include "Domain/Structure/DirectionMap.hpp"
19 : #include "Options/Context.hpp"
20 : #include "Options/String.hpp"
21 : #include "Utilities/TMPL.hpp"
22 :
23 : /// \cond
24 : namespace domain {
25 : namespace CoordinateMaps {
26 : class Affine;
27 : class Equiangular;
28 : template <typename Map1, typename Map2>
29 : class ProductOf2Maps;
30 : template <size_t Dim>
31 : class Wedge;
32 : } // namespace CoordinateMaps
33 :
34 : template <typename SourceFrame, typename TargetFrame, typename... Maps>
35 : class CoordinateMap;
36 : } // namespace domain
37 : /// \endcond
38 :
39 : namespace domain {
40 : namespace creators {
41 : /// Create a 2D Domain in the shape of a disk from a square surrounded by four
42 : /// wedges.
43 1 : class Disk : public DomainCreator<2> {
44 : public:
45 0 : using maps_list =
46 : tmpl::list<domain::CoordinateMap<
47 : Frame::BlockLogical, Frame::Inertial,
48 : CoordinateMaps::ProductOf2Maps<CoordinateMaps::Affine,
49 : CoordinateMaps::Affine>>,
50 : domain::CoordinateMap<Frame::BlockLogical, Frame::Inertial,
51 : CoordinateMaps::ProductOf2Maps<
52 : CoordinateMaps::Equiangular,
53 : CoordinateMaps::Equiangular>>,
54 : domain::CoordinateMap<Frame::BlockLogical, Frame::Inertial,
55 : CoordinateMaps::Wedge<2>>>;
56 :
57 0 : struct InnerRadius {
58 0 : using type = double;
59 0 : static constexpr Options::String help = {
60 : "Radius of the circle circumscribing the inner square."};
61 : };
62 :
63 0 : struct OuterRadius {
64 0 : using type = double;
65 0 : static constexpr Options::String help = {"Radius of the Disk."};
66 : };
67 :
68 0 : struct InitialRefinement {
69 0 : using type = size_t;
70 0 : static constexpr Options::String help = {
71 : "Initial refinement level in each dimension."};
72 : };
73 :
74 0 : struct InitialGridPoints {
75 0 : using type = std::array<size_t, 2>;
76 0 : static constexpr Options::String help = {
77 : "Initial number of grid points in [r,theta]."};
78 : };
79 :
80 0 : struct UseEquiangularMap {
81 0 : using type = bool;
82 0 : static constexpr Options::String help = {
83 : "Use equiangular instead of equidistant coordinates."};
84 : };
85 :
86 : template <typename BoundaryConditionsBase>
87 0 : struct BoundaryCondition {
88 0 : static std::string name() { return "BoundaryCondition"; }
89 0 : static constexpr Options::String help =
90 : "The boundary condition to impose on all sides.";
91 0 : using type = std::unique_ptr<BoundaryConditionsBase>;
92 : };
93 :
94 0 : using basic_options = tmpl::list<InnerRadius, OuterRadius, InitialRefinement,
95 : InitialGridPoints, UseEquiangularMap>;
96 :
97 : template <typename Metavariables>
98 0 : using options = tmpl::conditional_t<
99 : domain::BoundaryConditions::has_boundary_conditions_base_v<
100 : typename Metavariables::system>,
101 : tmpl::push_back<
102 : basic_options,
103 : BoundaryCondition<
104 : domain::BoundaryConditions::get_boundary_conditions_base<
105 : typename Metavariables::system>>>,
106 : basic_options>;
107 :
108 0 : static constexpr Options::String help{
109 : "Creates a 2D Disk with five Blocks.\n"
110 : "Only one refinement level for both dimensions is currently supported.\n"
111 : "The number of gridpoints in each dimension can be set independently.\n"
112 : "The number of gridpoints along the dimensions of the square is equal\n"
113 : "to the number of gridpoints along the angular dimension of the wedges.\n"
114 : "Equiangular coordinates give better gridpoint spacings in the angular\n"
115 : "direction, while equidistant coordinates give better gridpoint\n"
116 : "spacings in the center block."};
117 :
118 0 : Disk(typename InnerRadius::type inner_radius,
119 : typename OuterRadius::type outer_radius,
120 : typename InitialRefinement::type initial_refinement,
121 : typename InitialGridPoints::type initial_number_of_grid_points,
122 : typename UseEquiangularMap::type use_equiangular_map,
123 : std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
124 : boundary_condition = nullptr,
125 : const Options::Context& context = {});
126 :
127 0 : Disk() = default;
128 0 : Disk(const Disk&) = delete;
129 0 : Disk(Disk&&) = default;
130 0 : Disk& operator=(const Disk&) = delete;
131 0 : Disk& operator=(Disk&&) = default;
132 0 : ~Disk() override = default;
133 :
134 0 : Domain<2> create_domain() const override;
135 :
136 : std::vector<DirectionMap<
137 : 2, std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>>>
138 1 : external_boundary_conditions() const override;
139 :
140 1 : std::vector<std::array<size_t, 2>> initial_extents() const override;
141 :
142 1 : std::vector<std::array<size_t, 2>> initial_refinement_levels() const override;
143 :
144 1 : std::vector<std::string> block_names() const override { return block_names_; }
145 :
146 : std::unordered_map<std::string, std::unordered_set<std::string>>
147 1 : block_groups() const override {
148 : return block_groups_;
149 : }
150 :
151 : private:
152 0 : typename InnerRadius::type inner_radius_{};
153 0 : typename OuterRadius::type outer_radius_{};
154 0 : typename InitialRefinement::type initial_refinement_{};
155 0 : typename InitialGridPoints::type initial_number_of_grid_points_{};
156 0 : typename UseEquiangularMap::type use_equiangular_map_{false};
157 : std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
158 0 : boundary_condition_;
159 0 : std::vector<std::string> block_names_;
160 : std::unordered_map<std::string, std::unordered_set<std::string>>
161 0 : block_groups_;
162 : };
163 : } // namespace creators
164 : } // namespace domain
|