Line data Source code
1 1 : // Distributed under the MIT License. 2 : // See LICENSE.txt for details. 3 : 4 : /// \file 5 : /// Defines class Interval. 6 : 7 : #pragma once 8 : 9 : #include <array> 10 : #include <cstddef> 11 : #include <memory> 12 : #include <optional> 13 : #include <string> 14 : #include <unordered_map> 15 : #include <unordered_set> 16 : #include <vector> 17 : 18 : #include "Domain/BoundaryConditions/BoundaryCondition.hpp" 19 : #include "Domain/BoundaryConditions/GetBoundaryConditionsBase.hpp" 20 : #include "Domain/CoordinateMaps/Distribution.hpp" 21 : #include "Domain/Creators/DomainCreator.hpp" 22 : #include "Domain/Creators/TimeDependence/TimeDependence.hpp" 23 : #include "Domain/Domain.hpp" 24 : #include "Domain/Structure/DirectionMap.hpp" 25 : #include "Options/Auto.hpp" 26 : #include "Options/Context.hpp" 27 : #include "Options/String.hpp" 28 : #include "Utilities/MakeArray.hpp" 29 : #include "Utilities/TMPL.hpp" 30 : 31 : /// \cond 32 : namespace domain { 33 : namespace CoordinateMaps { 34 : class Interval; 35 : } // namespace CoordinateMaps 36 : 37 : template <typename SourceFrame, typename TargetFrame, typename... Maps> 38 : class CoordinateMap; 39 : } // namespace domain 40 : /// \endcond 41 : 42 : namespace domain { 43 : namespace creators { 44 : /// Create a 1D Domain consisting of a single Block. 45 1 : class Interval : public DomainCreator<1> { 46 : public: 47 0 : using maps_list = 48 : tmpl::list<domain::CoordinateMap<Frame::BlockLogical, Frame::Inertial, 49 : CoordinateMaps::Interval>>; 50 : 51 0 : struct LowerBound { 52 0 : using type = std::array<double, 1>; 53 0 : static constexpr Options::String help = { 54 : "Sequence of [x] for lower bounds."}; 55 : }; 56 0 : struct UpperBound { 57 0 : using type = std::array<double, 1>; 58 0 : static constexpr Options::String help = { 59 : "Sequence of [x] for upper bounds."}; 60 : }; 61 0 : struct Distribution { 62 0 : using type = CoordinateMaps::Distribution; 63 0 : static constexpr Options::String help = {"Distribution of grid points"}; 64 : }; 65 0 : struct Singularity { 66 0 : using type = Options::Auto<double, Options::AutoLabel::None>; 67 0 : static constexpr Options::String help = { 68 : "Position of coordinate singularity. Must be outside the domain. " 69 : "Required for 'Logarithmic' and 'Inverse' grid point distributions. " 70 : "Set to 'None' otherwise. " 71 : "A singularity position close to the lower or upper bound of the " 72 : "interval leads to very small grid spacing near that end, and " 73 : "placing the singularity further away from the domain increases the " 74 : "grid spacing. See the documentation of " 75 : "'domain::CoordinateMap::Distribution' for details."}; 76 : }; 77 0 : struct IsPeriodicIn { 78 0 : using type = std::array<bool, 1>; 79 0 : static constexpr Options::String help = { 80 : "Sequence for [x], true if periodic."}; 81 : }; 82 0 : struct InitialRefinement { 83 0 : using type = std::array<size_t, 1>; 84 0 : static constexpr Options::String help = { 85 : "Initial refinement level in [x]."}; 86 : }; 87 0 : struct InitialGridPoints { 88 0 : using type = std::array<size_t, 1>; 89 0 : static constexpr Options::String help = { 90 : "Initial number of grid points in [x]."}; 91 : }; 92 0 : struct TimeDependence { 93 0 : using type = 94 : std::unique_ptr<domain::creators::time_dependence::TimeDependence<1>>; 95 0 : static constexpr Options::String help = { 96 : "The time dependence of the moving mesh domain."}; 97 : }; 98 0 : struct BoundaryConditions { 99 0 : static constexpr Options::String help = "The boundary conditions to apply."; 100 : }; 101 : template <typename BoundaryConditionsBase> 102 0 : struct UpperBoundaryCondition { 103 0 : static std::string name() { return "UpperBoundary"; } 104 0 : static constexpr Options::String help = 105 : "Options for the boundary condition applied at the upper boundary."; 106 0 : using type = std::unique_ptr<BoundaryConditionsBase>; 107 0 : using group = BoundaryConditions; 108 : }; 109 : template <typename BoundaryConditionsBase> 110 0 : struct LowerBoundaryCondition { 111 0 : static std::string name() { return "LowerBoundary"; } 112 0 : static constexpr Options::String help = 113 : "Options for the boundary condition applied at the lower boundary."; 114 0 : using type = std::unique_ptr<BoundaryConditionsBase>; 115 0 : using group = BoundaryConditions; 116 : }; 117 : 118 0 : using common_options = 119 : tmpl::list<LowerBound, UpperBound, InitialRefinement, InitialGridPoints>; 120 : 121 0 : using options_periodic = tmpl::list<IsPeriodicIn>; 122 : template <typename System> 123 0 : using options_boundary_conditions = tmpl::list< 124 : LowerBoundaryCondition< 125 : domain::BoundaryConditions::get_boundary_conditions_base<System>>, 126 : UpperBoundaryCondition< 127 : domain::BoundaryConditions::get_boundary_conditions_base<System>>>; 128 : 129 : template <typename Metavariables> 130 0 : using options = tmpl::append< 131 : common_options, 132 : tmpl::conditional_t< 133 : domain::BoundaryConditions::has_boundary_conditions_base_v< 134 : typename Metavariables::system>, 135 : options_boundary_conditions<typename Metavariables::system>, 136 : options_periodic>, 137 : tmpl::list<Distribution, Singularity, TimeDependence>>; 138 : 139 0 : static constexpr Options::String help = {"Creates a 1D interval."}; 140 : 141 0 : Interval(std::array<double, 1> lower_x, std::array<double, 1> upper_x, 142 : std::array<size_t, 1> initial_refinement_level_x, 143 : std::array<size_t, 1> initial_number_of_grid_points_in_x, 144 : std::array<bool, 1> is_periodic_in_x = {{false}}, 145 : CoordinateMaps::Distribution distribution = 146 : CoordinateMaps::Distribution::Linear, 147 : std::optional<double> singularity = std::nullopt, 148 : std::unique_ptr<domain::creators::time_dependence::TimeDependence<1>> 149 : time_dependence = nullptr, 150 : const Options::Context& context = {}); 151 : 152 0 : Interval(std::array<double, 1> lower_x, std::array<double, 1> upper_x, 153 : std::array<size_t, 1> initial_refinement_level_x, 154 : std::array<size_t, 1> initial_number_of_grid_points_in_x, 155 : std::unique_ptr<domain::BoundaryConditions::BoundaryCondition> 156 : lower_boundary_condition, 157 : std::unique_ptr<domain::BoundaryConditions::BoundaryCondition> 158 : upper_boundary_condition, 159 : CoordinateMaps::Distribution distribution = 160 : CoordinateMaps::Distribution::Linear, 161 : std::optional<double> singularity = std::nullopt, 162 : std::unique_ptr<domain::creators::time_dependence::TimeDependence<1>> 163 : time_dependence = nullptr, 164 : const Options::Context& context = {}); 165 : 166 0 : Interval() = default; 167 0 : Interval(const Interval&) = delete; 168 0 : Interval(Interval&&) = default; 169 0 : Interval& operator=(const Interval&) = delete; 170 0 : Interval& operator=(Interval&&) = default; 171 0 : ~Interval() override = default; 172 : 173 0 : Domain<1> create_domain() const override; 174 : 175 : std::vector<DirectionMap< 176 : 1, std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>>> 177 1 : external_boundary_conditions() const override; 178 : 179 1 : std::vector<std::array<size_t, 1>> initial_extents() const override; 180 : 181 1 : std::vector<std::array<size_t, 1>> initial_refinement_levels() const override; 182 : 183 1 : auto functions_of_time(const std::unordered_map<std::string, double>& 184 : initial_expiration_times = {}) const 185 : -> std::unordered_map< 186 : std::string, 187 : std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>> override; 188 : 189 1 : std::vector<std::string> block_names() const override { return block_names_; } 190 : 191 : private: 192 0 : typename LowerBound::type lower_x_{}; 193 0 : typename UpperBound::type upper_x_{}; 194 0 : CoordinateMaps::Distribution distribution_{}; 195 0 : std::optional<double> singularity_{}; 196 0 : typename IsPeriodicIn::type is_periodic_in_x_{}; 197 0 : typename InitialRefinement::type initial_refinement_level_x_{}; 198 0 : typename InitialGridPoints::type initial_number_of_grid_points_in_x_{}; 199 : std::unique_ptr<domain::BoundaryConditions::BoundaryCondition> 200 0 : lower_boundary_condition_; 201 : std::unique_ptr<domain::BoundaryConditions::BoundaryCondition> 202 0 : upper_boundary_condition_; 203 : std::unique_ptr<domain::creators::time_dependence::TimeDependence<1>> 204 0 : time_dependence_; 205 0 : inline static std::vector<std::string> block_names_{"Interval"}; 206 : }; 207 : } // namespace creators 208 : } // namespace domain