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