SpECTRE Documentation Coverage Report
Current view: top level - Domain/Creators - CartoonSphere1D.hpp Hit Total Coverage
Commit: a18e59fda1a195609825c55450f7d61ad20a91a4 Lines: 7 68 10.3 %
Date: 2026-06-11 22:10:41
Legend: Lines: hit not hit

          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 <vector>
      12             : 
      13             : #include "Domain/BoundaryConditions/BoundaryCondition.hpp"
      14             : #include "Domain/BoundaryConditions/Cartoon.hpp"
      15             : #include "Domain/BoundaryConditions/GetBoundaryConditionsBase.hpp"
      16             : #include "Domain/CoordinateMaps/Distribution.hpp"
      17             : #include "Domain/Creators/DomainCreator.hpp"
      18             : #include "Domain/Creators/TimeDependence/TimeDependence.hpp"
      19             : #include "Domain/Domain.hpp"
      20             : #include "Domain/Structure/DirectionMap.hpp"
      21             : #include "Options/Context.hpp"
      22             : #include "Options/String.hpp"
      23             : #include "Utilities/TMPL.hpp"
      24             : 
      25             : /// \cond
      26             : namespace domain {
      27             : namespace CoordinateMaps {
      28             : class Interval;
      29             : template <typename Map1, typename Map2, typename Map3>
      30             : class ProductOf3Maps;
      31             : }  // namespace CoordinateMaps
      32             : 
      33             : template <typename SourceFrame, typename TargetFrame, typename... Maps>
      34             : class CoordinateMap;
      35             : }  // namespace domain
      36             : /// \endcond
      37             : 
      38             : namespace domain::creators {
      39             : /// Create a 3D Domain that is topologically a line. The 2nd and 3rd
      40             : /// dimensions use Cartoon bases with Killing vectors along the \f$\theta\f$ and
      41             : /// \f$\phi\f$ directions.
      42           1 : class CartoonSphere1D : public DomainCreator<3> {
      43             :  public:
      44           0 :   using maps_list = tmpl::list<domain::CoordinateMap<
      45             :       Frame::BlockLogical, Frame::Inertial,
      46             :       CoordinateMaps::ProductOf3Maps<CoordinateMaps::Interval,
      47             :                                      CoordinateMaps::Identity<1>,
      48             :                                      CoordinateMaps::Identity<1>>>>;
      49             : 
      50           0 :   static std::string name() { return "CartoonSphere1D"; }
      51             : 
      52           0 :   struct InnerRadius {
      53           0 :     using type = double;
      54           0 :     static constexpr Options::String help = {
      55             :         "Inner radius of domain, greater than or equal to 0. If the origin is "
      56             :         "included, the innermost element will use a 1D Zernike basis, "
      57             :         "otherwise the domain will be a spherical shell."};
      58             :   };
      59             : 
      60           0 :   struct OuterRadius {
      61           0 :     using type = double;
      62           0 :     static constexpr Options::String help = {"Outer radius of domain."};
      63             :   };
      64             : 
      65           0 :   struct InitialRadialRefinement {
      66           0 :     using type = std::variant<size_t, std::vector<size_t>>;
      67           0 :     static constexpr Options::String help = {
      68             :         "Initial refinement level for the radial direction. If one value is "
      69             :         "given, it will be applied to all blocks, or every block can be "
      70             :         "specified individually."};
      71             :   };
      72             : 
      73           0 :   struct InitialNumberOfRadialGridPoints {
      74           0 :     using type = std::variant<size_t, std::vector<size_t>>;
      75           0 :     static constexpr Options::String help = {
      76             :         "Initial number of radial grid points. If one input is given, it "
      77             :         "will be applied to all blocks, or every block can be specified "
      78             :         "individually."};
      79             :   };
      80             : 
      81           0 :   struct RadialPartitioning {
      82           0 :     using type = std::vector<double>;
      83           0 :     static constexpr Options::String help = {
      84             :         "Radial coordinates of the boundaries splitting the radial blocks, "
      85             :         "strictly between InnerRadius and OuterRadius. They must be given in "
      86             :         "ascending order."};
      87             :   };
      88             : 
      89           0 :   struct RadialDistributions {
      90           0 :     using type = std::variant<CoordinateMaps::Distribution,
      91             :                               std::vector<CoordinateMaps::Distribution>>;
      92           0 :     static constexpr Options::String help = {
      93             :         "Distribution of grid points along the radial blocks. A single input "
      94             :         "will be applied to all blocks, or every block can be specified "
      95             :         "individually, in which case for N partitions, there must be N+1 "
      96             :         "distributions."};
      97             :   };
      98             : 
      99             :   template <typename BoundaryConditionsBase>
     100           0 :   struct InnerBoundaryCondition {
     101           0 :     static constexpr Options::String help =
     102             :         "Options for the boundary conditions at the inner boundary.";
     103           0 :     using type = std::unique_ptr<BoundaryConditionsBase>;
     104             :   };
     105             : 
     106             :   template <typename BoundaryConditionsBase>
     107           0 :   struct OuterBoundaryCondition {
     108           0 :     static constexpr Options::String help =
     109             :         "Options for the boundary conditions at the outer boundary.";
     110           0 :     using type = std::unique_ptr<BoundaryConditionsBase>;
     111             :   };
     112             : 
     113             :   template <typename BoundaryConditionsBase>
     114           0 :   struct CartoonBoundaryCondition {
     115           0 :     static constexpr Options::String help =
     116             :         "Cartoon boundary condition will be automatically applied to "
     117             :         "internal cartoon boundaries. No user options needed.";
     118           0 :     using type = std::nullptr_t;
     119           0 :     static std::string name() { return "CartoonBC"; }
     120             :   };
     121             : 
     122           0 :   struct TimeDependence {
     123           0 :     using type =
     124             :         std::unique_ptr<domain::creators::time_dependence::TimeDependence<3>>;
     125           0 :     static constexpr Options::String help = {
     126             :         "The time dependence of the moving mesh domain. Specify `None` for no "
     127             :         "time dependant maps."};
     128             :   };
     129             : 
     130           0 :   using basic_options =
     131             :       tmpl::list<InnerRadius, OuterRadius, InitialRadialRefinement,
     132             :                  InitialNumberOfRadialGridPoints, RadialPartitioning,
     133             :                  RadialDistributions, TimeDependence>;
     134             : 
     135             :   template <typename Metavariables>
     136           0 :   using options = tmpl::conditional_t<
     137             :       domain::BoundaryConditions::has_boundary_conditions_base_v<
     138             :           typename Metavariables::system>,
     139             :       tmpl::push_back<
     140             :           basic_options,
     141             :           InnerBoundaryCondition<
     142             :               domain::BoundaryConditions::get_boundary_conditions_base<
     143             :                   typename Metavariables::system>>,
     144             :           OuterBoundaryCondition<
     145             :               domain::BoundaryConditions::get_boundary_conditions_base<
     146             :                   typename Metavariables::system>>>,
     147             :       basic_options>;
     148             : 
     149           0 :   static constexpr Options::String help{
     150             :       "A sphere domain that requires/enforces spherical symmetry, resulting in "
     151             :       "a 1D computational domain (the radial axis). It uses Cartoon partial "
     152             :       "derivatives for the angular directions not in the computational "
     153             :       "domain. If an element touches the x=0 axis, it uses ZernikeB1 bases and "
     154             :       "automatically applies a system's Cartoon-type boundary condition."};
     155             : 
     156           0 :   CartoonSphere1D(
     157             :       double inner_bound, double outer_bound,
     158             :       typename InitialRadialRefinement::type&& initial_refinement_levels,
     159             :       typename InitialNumberOfRadialGridPoints::type&& initial_num_points,
     160             :       std::vector<double> radial_partitioning = {},
     161             :       const typename RadialDistributions::type& radial_distributions =
     162             :           domain::CoordinateMaps::Distribution::Linear,
     163             :       std::unique_ptr<domain::creators::time_dependence::TimeDependence<3>>
     164             :           time_dependence = nullptr,
     165             :       std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
     166             :           inner_boundary_condition = nullptr,
     167             :       std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
     168             :           outer_boundary_condition = nullptr,
     169             :       std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
     170             :           cartoon_boundary_condition = nullptr,
     171             :       const Options::Context& context = {});
     172             : 
     173           0 :   CartoonSphere1D() = default;
     174           0 :   CartoonSphere1D(const CartoonSphere1D&) = delete;
     175           0 :   CartoonSphere1D(CartoonSphere1D&&) = default;
     176           0 :   CartoonSphere1D& operator=(const CartoonSphere1D&) = delete;
     177           0 :   CartoonSphere1D& operator=(CartoonSphere1D&&) = default;
     178           0 :   ~CartoonSphere1D() override = default;
     179             : 
     180           0 :   Domain<3> create_domain() const override;
     181             : 
     182             :   std::vector<DirectionMap<
     183             :       3, std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>>>
     184           1 :   external_boundary_conditions() const override;
     185             : 
     186           1 :   std::vector<std::array<size_t, 3>> initial_extents() const override;
     187             : 
     188           1 :   std::vector<std::array<size_t, 3>> initial_refinement_levels() const override;
     189             : 
     190             :   // The block names are Block0, Block1, ..., starting with the innermost
     191             :   // Block.
     192           1 :   std::vector<std::string> block_names() const override;
     193             : 
     194             :   // The only block group is PositiveBlocks
     195             :   std::unordered_map<std::string, std::unordered_set<std::string>>
     196           1 :   block_groups() const override;
     197             : 
     198           1 :   auto functions_of_time(const std::unordered_map<std::string, double>&
     199             :                              initial_expiration_times = {}) const
     200             :       -> std::unordered_map<
     201             :           std::string,
     202             :           std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>> override;
     203             : 
     204             :  private:
     205           0 :   double inner_bound_{};
     206           0 :   double outer_bound_{};
     207           0 :   std::vector<size_t> initial_refinement_levels_{};
     208           0 :   std::vector<size_t> initial_num_points_{};
     209           0 :   std::vector<double> radial_partitioning_{};
     210           0 :   std::vector<CoordinateMaps::Distribution> radial_distributions_{};
     211           0 :   bool use_zernike_{};
     212             :   std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
     213           0 :       inner_boundary_condition_{};
     214             :   std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
     215           0 :       outer_boundary_condition_{};
     216             :   std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
     217           0 :       cartoon_boundary_condition_{};
     218             :   std::unique_ptr<domain::creators::time_dependence::TimeDependence<3>>
     219           0 :       time_dependence_;
     220           0 :   size_t num_blocks_{};
     221           0 :   std::vector<std::string> block_names_{};
     222             :   std::unordered_map<std::string, std::unordered_set<std::string>>
     223           0 :       block_groups_{};
     224             : };
     225             : 
     226             : }  // namespace domain::creators
     227             : 
     228             : namespace domain::creators::detail {
     229             : /// \brief Helper struct for CartoonSphere1D options parsing so the internal
     230             : /// cartoon boundary condition at $x = 0$ is not a required argument.
     231             : ///
     232             : /// \details To get the cartoon-type boundary condition from a system we need
     233             : /// access to the system's metavariables, which is only present when parsing
     234             : /// options. The point of this design is so that the input file does not require
     235             : /// a dummy value for an InnerBoundaryCondition that is always the same for a
     236             : /// given system.
     237             : ///
     238             : /// This helper's constructor does not take an InnerBoundaryCondition, which
     239             : /// means if we parse a CartoonSphere1D as a CartonSphere1DOptionsHelper
     240             : /// by having an options parsing specialization (so the input file values are
     241             : /// the helper's construtor, not CartoonSphere1D's), we can detect the
     242             : /// cartoon-type boundary condition for the given system and only then call the
     243             : /// CartoonSphere1D constructor with the extra information.
     244             : struct CartoonSphere1DOptionsHelper {
     245             :   // Inherit the options template from CartoonSphere1D
     246             :   template <typename Metavariables>
     247             :   using options = typename domain::creators::CartoonSphere1D::template options<
     248             :       Metavariables>;
     249             : 
     250             :   using InitialRadialRefinement =
     251             :       domain::creators::CartoonSphere1D::InitialRadialRefinement;
     252             :   using InitialNumberOfRadialGridPoints =
     253             :       domain::creators::CartoonSphere1D::InitialNumberOfRadialGridPoints;
     254             :   using RadialDistributions =
     255             :       domain::creators::CartoonSphere1D::RadialDistributions;
     256             : 
     257             :   static constexpr Options::String help = {"CartoonSphere1DOptionsHelper"};
     258             : 
     259             :   // Default constructor required by Options system
     260             :   CartoonSphere1DOptionsHelper() = default;
     261             : 
     262             :   // Does not take cartoon BC
     263             :   CartoonSphere1DOptionsHelper(
     264             :       double inner_bound, double outer_bound,
     265             :       typename InitialRadialRefinement::type&& initial_refinement_levels,
     266             :       typename InitialNumberOfRadialGridPoints::type&& initial_num_points,
     267             :       std::vector<double> radial_partitioning = {},
     268             :       typename RadialDistributions::type&& radial_distributions =
     269             :           domain::CoordinateMaps::Distribution::Linear,
     270             :       std::unique_ptr<domain::creators::time_dependence::TimeDependence<3>>
     271             :           time_dependence = nullptr,
     272             :       std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
     273             :           inner_boundary_condition = nullptr,
     274             :       std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
     275             :           outer_boundary_condition = nullptr,
     276             :       Options::Context&& context = {});
     277             : 
     278             :   // Same members as in CartoonSphere1D; public, to be extracted
     279             :   double inner_bound_{std::numeric_limits<double>::signaling_NaN()};
     280             :   double outer_bound_{std::numeric_limits<double>::signaling_NaN()};
     281             :   typename domain::creators::CartoonSphere1D::InitialRadialRefinement::type
     282             :       initial_refinement_levels_{};
     283             :   typename domain::creators::CartoonSphere1D::InitialNumberOfRadialGridPoints::
     284             :       type initial_num_points_{};
     285             :   std::vector<double> radial_partitioning_{};
     286             :   domain::creators::CartoonSphere1D::RadialDistributions::type
     287             :       radial_distributions_{domain::CoordinateMaps::Distribution::Linear};
     288             :   std::unique_ptr<domain::creators::time_dependence::TimeDependence<3>>
     289             :       time_dependence_{nullptr};
     290             :   std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
     291             :       inner_boundary_condition_{nullptr};
     292             :   std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
     293             :       outer_boundary_condition_{nullptr};
     294             :   std::nullptr_t cartoon_boundary_condition_{
     295             :       nullptr};  // For CartoonBoundaryCondition option
     296             :   Options::Context context_{};
     297             : };
     298             : }  // namespace domain::creators::detail
     299             : 
     300             : // Options parsing specialization to automate CartoonSphere1D's cartoon
     301             : // boundary condition
     302             : template <>
     303           0 : struct Options::create_from_yaml<domain::creators::CartoonSphere1D> {
     304             :   template <typename Metavariables>
     305           0 :   static domain::creators::CartoonSphere1D create(
     306             :       const Options::Option& options) {
     307             :     auto helper =
     308             :         options.parse_as<domain::creators::detail::CartoonSphere1DOptionsHelper,
     309             :                          Metavariables>();
     310             : 
     311             :     // Create cartoon BC if system supports it, if not will throw parse error in
     312             :     // real constructor
     313             :     std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
     314             :         cartoon_boundary_condition = nullptr;
     315             :     if constexpr (domain::BoundaryConditions::has_boundary_conditions_base_v<
     316             :                       typename Metavariables::system>) {
     317             :       if constexpr (domain::BoundaryConditions::system_has_cartoon_bc_v<
     318             :                         Metavariables>) {
     319             :         cartoon_boundary_condition =
     320             :             domain::BoundaryConditions::make_cartoon_boundary_condition<
     321             :                 Metavariables>();
     322             :       }
     323             :     }
     324             : 
     325             :     // Construct CartoonSphere1D using the helper's parsed data + cartoon BC
     326             :     return domain::creators::CartoonSphere1D(
     327             :         helper.inner_bound_, helper.outer_bound_,
     328             :         std::move(helper.initial_refinement_levels_),
     329             :         std::move(helper.initial_num_points_),
     330             :         std::move(helper.radial_partitioning_), helper.radial_distributions_,
     331             :         std::move(helper.time_dependence_),
     332             :         std::move(helper.inner_boundary_condition_),
     333             :         std::move(helper.outer_boundary_condition_),
     334             :         std::move(cartoon_boundary_condition), helper.context_);
     335             :   }
     336             : };

Generated by: LCOV version 1.14