SpECTRE Documentation Coverage Report
Current view: top level - Domain/Creators - CartoonSphere1D.hpp Coverage Total Hit
Commit: 0d1d717af84a81fb1284a20c4013708fe85cc2f0 Lines: 10.3 % 68 7
Test Date: 2026-10-22 17:29:42
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 2.0-1