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 <variant>
13 : #include <vector>
14 :
15 : #include "DataStructures/Tensor/IndexType.hpp"
16 : #include "Domain/BoundaryConditions/BoundaryCondition.hpp"
17 : #include "Domain/BoundaryConditions/GetBoundaryConditionsBase.hpp"
18 : #include "Domain/CoordinateMaps/DiscreteRotation.hpp"
19 : #include "Domain/CoordinateMaps/Distribution.hpp"
20 : #include "Domain/Creators/DomainCreator.hpp"
21 : #include "Domain/Creators/TimeDependence/TimeDependence.hpp"
22 : #include "Domain/Domain.hpp"
23 : #include "Domain/Structure/DirectionMap.hpp"
24 : #include "Options/Context.hpp"
25 : #include "Options/String.hpp"
26 : #include "Utilities/TMPL.hpp"
27 :
28 : /// \cond
29 : namespace domain {
30 : namespace CoordinateMaps {
31 : template <size_t Dim>
32 : class Identity;
33 : class Interval;
34 : class PolarToCartesian;
35 : template <typename Map1, typename Map2>
36 : class ProductOf2Maps;
37 : template <typename Map1, typename Map2, typename Map3>
38 : class ProductOf3Maps;
39 : } // namespace CoordinateMaps
40 :
41 : template <typename SourceFrame, typename TargetFrame, typename... Maps>
42 : class CoordinateMap;
43 : } // namespace domain
44 : /// \endcond
45 :
46 : namespace domain::creators {
47 : /*!
48 : * \brief An axisymmetric Cartoon domain covering the half-plane \f$x \ge 0\f$
49 : * with annular blocks that use a half-Fourier basis in the azimuthal
50 : * direction.
51 : *
52 : * \details This is the polar-coordinate counterpart of
53 : * `domain::creators::CartoonSphere2D`. Where `CartoonSphere2D` tiles the
54 : * half-plane with three Legendre wedges per shell, this creator uses a
55 : * single annular block per shell whose azimuthal direction is spanned by the
56 : * `Spectral::Basis::HalfFourier` basis.
57 : *
58 : * To match the symmetry to allowed solution, \f$\phi\f$ sweeps counterclockwise
59 : * from the \f$-y\f$ axis, through \f$+x\f$, to the \f$+y\f$ axis. The
60 : * symmetry axis \f$x = 0\f$ is not an external boundary: it is handled
61 : * internally by the parity of the half-Fourier basis. See
62 : * `Spectral::make_component_parity_array` and `Spectral::HalfFourier`.
63 : *
64 : * \note The origin must be excised as the radial topology is `I1`.
65 : */
66 1 : class AngularCartoonSphere2D : public DomainCreator<3> {
67 : public:
68 0 : using maps_list = tmpl::list<domain::CoordinateMap<
69 : Frame::BlockLogical, Frame::Inertial,
70 : domain::CoordinateMaps::ProductOf3Maps<
71 : domain::CoordinateMaps::Interval, domain::CoordinateMaps::Identity<1>,
72 : domain::CoordinateMaps::Identity<1>>,
73 : domain::CoordinateMaps::ProductOf2Maps<
74 : domain::CoordinateMaps::PolarToCartesian,
75 : domain::CoordinateMaps::Identity<1>>,
76 : domain::CoordinateMaps::ProductOf2Maps<
77 : domain::CoordinateMaps::DiscreteRotation<2>,
78 : domain::CoordinateMaps::Identity<1>>>>;
79 :
80 : /// \brief Radius of the excised region at the center of the domain
81 1 : struct InnerRadius {
82 0 : using type = double;
83 0 : static constexpr Options::String help = {
84 : "Radius of the excised region at the center of the domain. Must be "
85 : "positive."};
86 : };
87 :
88 : /// \brief Radius of the outer edge of the domain
89 1 : struct OuterRadius {
90 0 : using type = double;
91 0 : static constexpr Options::String help = {
92 : "Radius of the outer edge of the domain."};
93 : };
94 :
95 : /// \brief Radial coordinates of the boundaries splitting the shells
96 1 : struct RadialPartitioning {
97 0 : using type = std::vector<double>;
98 0 : static constexpr Options::String help = {
99 : "Radial coordinates of the boundaries splitting the domain into "
100 : "concentric shells. Must be strictly increasing and lie strictly "
101 : "between InnerRadius and OuterRadius."};
102 : };
103 :
104 : /// \brief Distribution of grid points in each radial block
105 1 : struct RadialDistribution {
106 0 : using type =
107 : std::variant<domain::CoordinateMaps::Distribution,
108 : std::vector<domain::CoordinateMaps::Distribution>>;
109 0 : static constexpr Options::String help = {
110 : "Distribution of grid points in the radial direction for each "
111 : "radial block. If one distribution is given it is applied to all "
112 : "shells, otherwise specify one per shell."};
113 : };
114 :
115 : /// \brief Initial number of \f$[r, \phi]\f$ grid points in each shell
116 1 : struct InitialGridPoints {
117 0 : using type =
118 : std::variant<std::array<size_t, 2>, std::vector<std::array<size_t, 2>>>;
119 0 : static constexpr Options::String help = {
120 : "Initial number of grid points in [r, phi] for each shell. If one "
121 : "pair is given it is applied to all shells, otherwise specify one "
122 : "pair per shell."};
123 : };
124 :
125 : /// \brief Initial refinement level in the radial direction of each shell
126 1 : struct InitialRefinementInR {
127 0 : using type = std::variant<size_t, std::vector<size_t>>;
128 0 : static constexpr Options::String help = {
129 : "Initial refinement level in the radial direction for each radial "
130 : "block. If one level is given it is applied to all shells, otherwise "
131 : "specify one per shell. The azimuthal and Cartoon directions cannot "
132 : "be h-refined."};
133 : };
134 :
135 : /// \brief Time dependence of the domain
136 1 : struct TimeDependence {
137 0 : using type =
138 : std::unique_ptr<domain::creators::time_dependence::TimeDependence<3>>;
139 0 : static constexpr Options::String help = {
140 : "The time dependence of the moving mesh domain. Specify `None` for no "
141 : "time dependent maps."};
142 : };
143 :
144 : /// \brief Boundary conditions group
145 1 : struct BoundaryConditions {
146 0 : static constexpr Options::String help =
147 : "Options for the boundary conditions";
148 : };
149 :
150 : /// \brief Boundary condition at the inner (excision) radius
151 : template <typename BoundaryConditionsBase>
152 1 : struct InnerBoundaryCondition {
153 0 : using group = BoundaryConditions;
154 0 : static std::string name() { return "InnerBoundary"; }
155 0 : static constexpr Options::String help =
156 : "The boundary condition imposed at the inner (excision) radius.";
157 0 : using type = std::unique_ptr<BoundaryConditionsBase>;
158 : };
159 :
160 : /// \brief Boundary condition at the outer radius
161 : template <typename BoundaryConditionsBase>
162 1 : struct OuterBoundaryCondition {
163 0 : using group = BoundaryConditions;
164 0 : static std::string name() { return "OuterBoundary"; }
165 0 : static constexpr Options::String help =
166 : "The boundary condition imposed at the outer radius.";
167 0 : using type = std::unique_ptr<BoundaryConditionsBase>;
168 : };
169 :
170 0 : using basic_options = tmpl::list<InnerRadius, OuterRadius, RadialPartitioning,
171 : RadialDistribution, InitialGridPoints,
172 : InitialRefinementInR, TimeDependence>;
173 :
174 : template <typename Metavariables>
175 0 : using options = tmpl::conditional_t<
176 : domain::BoundaryConditions::has_boundary_conditions_base_v<
177 : typename Metavariables::system>,
178 : tmpl::push_back<
179 : basic_options,
180 : InnerBoundaryCondition<
181 : domain::BoundaryConditions::get_boundary_conditions_base<
182 : typename Metavariables::system>>,
183 : OuterBoundaryCondition<
184 : domain::BoundaryConditions::get_boundary_conditions_base<
185 : typename Metavariables::system>>>,
186 : basic_options>;
187 :
188 0 : static constexpr Options::String help{
189 : "An axisymmetric Cartoon domain covering the half-plane x >= 0 with "
190 : "annular blocks that use a half-Fourier basis in the azimuthal "
191 : "direction."};
192 :
193 0 : AngularCartoonSphere2D(
194 : typename InnerRadius::type inner_radius,
195 : typename OuterRadius::type outer_radius,
196 : typename RadialPartitioning::type radial_partitioning,
197 : typename RadialDistribution::type radial_distribution,
198 : typename InitialGridPoints::type initial_grid_points,
199 : typename InitialRefinementInR::type initial_refinement_in_r,
200 : std::unique_ptr<domain::creators::time_dependence::TimeDependence<3>>
201 : time_dependence = nullptr,
202 : std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
203 : inner_boundary_condition = nullptr,
204 : std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
205 : outer_boundary_condition = nullptr,
206 : const Options::Context& context = {});
207 :
208 0 : AngularCartoonSphere2D() = default;
209 0 : AngularCartoonSphere2D(const AngularCartoonSphere2D&) = delete;
210 0 : AngularCartoonSphere2D(AngularCartoonSphere2D&&) = default;
211 0 : AngularCartoonSphere2D& operator=(const AngularCartoonSphere2D&) = delete;
212 0 : AngularCartoonSphere2D& operator=(AngularCartoonSphere2D&&) = default;
213 0 : ~AngularCartoonSphere2D() override = default;
214 :
215 0 : Domain<3> create_domain() const override;
216 :
217 : std::vector<DirectionMap<
218 : 3, std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>>>
219 1 : external_boundary_conditions() const override;
220 :
221 1 : std::vector<std::array<size_t, 3>> initial_extents() const override;
222 :
223 1 : std::vector<std::array<size_t, 3>> initial_refinement_levels() const override;
224 :
225 : /// Block names are `Shell0`, `Shell1`, ...
226 1 : std::vector<std::string> block_names() const override { return block_names_; }
227 :
228 : /// Block groups are `Shells`.
229 : std::unordered_map<std::string, std::unordered_set<std::string>>
230 1 : block_groups() const override {
231 : return block_groups_;
232 : }
233 :
234 1 : auto functions_of_time(const std::unordered_map<std::string, double>&
235 : initial_expiration_times = {}) const
236 : -> std::unordered_map<
237 : std::string,
238 : std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>> override;
239 :
240 : private:
241 0 : typename InnerRadius::type inner_radius_{};
242 0 : typename OuterRadius::type outer_radius_{};
243 0 : typename RadialPartitioning::type radial_partitioning_;
244 0 : std::vector<domain::CoordinateMaps::Distribution> radial_distribution_;
245 0 : std::vector<std::array<size_t, 2>> initial_grid_points_;
246 0 : std::vector<size_t> initial_refinement_in_r_;
247 : std::unique_ptr<domain::creators::time_dependence::TimeDependence<3>>
248 0 : time_dependence_ = nullptr;
249 : std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
250 0 : inner_boundary_condition_;
251 : std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
252 0 : outer_boundary_condition_;
253 0 : std::vector<std::string> block_names_;
254 : std::unordered_map<std::string, std::unordered_set<std::string>>
255 0 : block_groups_;
256 0 : size_t num_blocks_{};
257 : };
258 : } // namespace domain::creators
|