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/Creators/DomainCreator.hpp"
19 : #include "Domain/Creators/TimeDependence/TimeDependence.hpp"
20 : #include "Domain/Domain.hpp"
21 : #include "Domain/Structure/DirectionMap.hpp"
22 : #include "Options/Context.hpp"
23 : #include "Options/String.hpp"
24 : #include "Utilities/TMPL.hpp"
25 :
26 : /// \cond
27 : namespace domain {
28 : namespace CoordinateMaps {
29 : class Affine;
30 : template <size_t Dim>
31 : class Identity;
32 : class PolarToCartesian;
33 : template <typename Map1, typename Map2>
34 : class ProductOf2Maps;
35 : } // namespace CoordinateMaps
36 :
37 : template <typename SourceFrame, typename TargetFrame, typename... Maps>
38 : class CoordinateMap;
39 : } // namespace domain
40 : /// \endcond
41 :
42 : namespace domain::creators {
43 : /*!
44 : * \brief Create a 2D filled disk domain with radial partitioning using a B2
45 : * filled disk at the center and Fourier hollow disks surrounding it.
46 : */
47 1 : class AngularDisk : public DomainCreator<2> {
48 : public:
49 0 : using maps_list = tmpl::list<domain::CoordinateMap<
50 : Frame::BlockLogical, Frame::Inertial,
51 : domain::CoordinateMaps::ProductOf2Maps<
52 : domain::CoordinateMaps::Affine, domain::CoordinateMaps::Identity<1>>,
53 : domain::CoordinateMaps::PolarToCartesian>>;
54 :
55 : /*!
56 : * \brief Radius of the disk's outer edge
57 : */
58 1 : struct OuterRadius {
59 0 : using type = double;
60 0 : static constexpr Options::String help = {"Radius of the Disk."};
61 : };
62 :
63 : /*!
64 : * \brief Radial coordinates of the boundaries splitting elements
65 : */
66 1 : struct RadialPartitioning {
67 0 : using type = std::vector<double>;
68 0 : static constexpr Options::String help = {
69 : "Radial coordinates of the boundaries splitting the inner disk and "
70 : "potential annulus shells"};
71 : };
72 :
73 : /*!
74 : * \brief Initial number of \f$\theta\f$ gridpoints for filled disk. The
75 : * number for \f$r\f$ is accordingly set to match spectral space sizes. This
76 : * is enforced to be odd for numerical stability.
77 : */
78 1 : struct InitialDiskThetaGridPoints {
79 0 : using type = size_t;
80 0 : static constexpr Options::String help = {
81 : "Initial number of grid points in theta (r is accordingly set). This "
82 : "value must be odd for better numerical stability."};
83 : };
84 :
85 : /*!
86 : * \brief Initial number of \f$[r, \theta]\f$ gridpoints. Can be one pair
87 : * which is applied to all shells, or each can be specified.
88 : */
89 1 : struct InitialAnnulusGridPoints {
90 0 : using type =
91 : std::variant<std::array<size_t, 2>, std::vector<std::array<size_t, 2>>>;
92 0 : static constexpr Options::String help = {
93 : "Initial number of grid points in [r, theta] for each annulus. If one "
94 : "pair is given, it will be applied to all blocks, otherwise each "
95 : "annulus can be specified."};
96 : };
97 :
98 : /*!
99 : * \brief Boundary condition to impose on outer side
100 : */
101 : template <typename BoundaryConditionsBase>
102 1 : struct BoundaryCondition {
103 0 : static std::string name() { return "BoundaryCondition"; }
104 0 : static constexpr Options::String help =
105 : "The boundary condition to impose on outer side.";
106 0 : using type = std::unique_ptr<BoundaryConditionsBase>;
107 : };
108 :
109 : /*!
110 : * \brief Time dependence of the domain
111 : */
112 1 : struct TimeDependence {
113 0 : using type =
114 : std::unique_ptr<domain::creators::time_dependence::TimeDependence<2>>;
115 0 : static constexpr Options::String help = {
116 : "The time dependence of the moving mesh domain. Specify `None` for no "
117 : "time dependent maps."};
118 : };
119 :
120 0 : using basic_options =
121 : tmpl::list<OuterRadius, RadialPartitioning, InitialDiskThetaGridPoints,
122 : InitialAnnulusGridPoints, TimeDependence>;
123 :
124 : template <typename Metavariables>
125 0 : using options = tmpl::conditional_t<
126 : domain::BoundaryConditions::has_boundary_conditions_base_v<
127 : typename Metavariables::system>,
128 : tmpl::push_back<
129 : basic_options,
130 : BoundaryCondition<
131 : domain::BoundaryConditions::get_boundary_conditions_base<
132 : typename Metavariables::system>>>,
133 : basic_options>;
134 :
135 0 : static constexpr Options::String help{
136 : "Creates a disk using a Zernike basis radially and Fourier in the "
137 : "angular direction"};
138 :
139 0 : AngularDisk(
140 : typename OuterRadius::type outer_radius,
141 : typename RadialPartitioning::type radial_partitioning,
142 : typename InitialDiskThetaGridPoints::type initial_disk_grid_points,
143 : typename InitialAnnulusGridPoints::type initial_annulus_grid_points,
144 : std::unique_ptr<domain::creators::time_dependence::TimeDependence<2>>
145 : time_dependence = nullptr,
146 : std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
147 : boundary_condition = nullptr,
148 : const Options::Context& context = {});
149 :
150 0 : AngularDisk() = default;
151 0 : AngularDisk(const AngularDisk&) = delete;
152 0 : AngularDisk(AngularDisk&&) = default;
153 0 : AngularDisk& operator=(const AngularDisk&) = delete;
154 0 : AngularDisk& operator=(AngularDisk&&) = default;
155 0 : ~AngularDisk() override = default;
156 :
157 0 : Domain<2> create_domain() const override;
158 :
159 : std::vector<DirectionMap<
160 : 2, std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>>>
161 1 : external_boundary_conditions() const override;
162 :
163 1 : std::vector<std::array<size_t, 2>> initial_extents() const override;
164 :
165 1 : std::vector<std::array<size_t, 2>> initial_refinement_levels() const override;
166 :
167 1 : std::vector<std::string> block_names() const override { return block_names_; }
168 :
169 : std::unordered_map<std::string, std::unordered_set<std::string>>
170 1 : block_groups() const override {
171 : return block_groups_;
172 : }
173 :
174 : private:
175 0 : typename OuterRadius::type outer_radius_{};
176 0 : typename RadialPartitioning::type radial_partitioning_{};
177 0 : typename InitialDiskThetaGridPoints::type initial_disk_grid_points_{};
178 0 : std::vector<std::array<size_t, 2>> initial_annulus_grid_points_{};
179 : std::unique_ptr<domain::creators::time_dependence::TimeDependence<2>>
180 0 : time_dependence_ = nullptr;
181 : std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
182 0 : boundary_condition_;
183 0 : std::vector<std::string> block_names_;
184 : std::unordered_map<std::string, std::unordered_set<std::string>>
185 0 : block_groups_;
186 0 : size_t num_blocks_{};
187 : };
188 : } // namespace domain::creators
|