SpECTRE Documentation Coverage Report
Current view: top level - Domain/Creators - SphericalShells.hpp Hit Total Coverage
Commit: ecb8a275e1aebab77dcce48a5e098ed4e486ab4b Lines: 18 69 26.1 %
Date: 2026-08-22 01:05:40
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 <optional>
      10             : #include <string>
      11             : #include <unordered_map>
      12             : #include <variant>
      13             : #include <vector>
      14             : 
      15             : #include "Domain/BoundaryConditions/BoundaryCondition.hpp"
      16             : #include "Domain/BoundaryConditions/GetBoundaryConditionsBase.hpp"
      17             : #include "Domain/CoordinateMaps/Distribution.hpp"
      18             : #include "Domain/Creators/DomainCreator.hpp"
      19             : #include "Domain/Creators/TimeDependence/TimeDependence.hpp"
      20             : #include "Domain/Creators/TimeDependentOptions/Sphere.hpp"
      21             : #include "Options/Auto.hpp"
      22             : #include "Options/Context.hpp"
      23             : #include "Options/String.hpp"
      24             : #include "Utilities/TMPL.hpp"
      25             : 
      26             : /// \cond
      27             : template <size_t Dim, typename T>
      28             : class DirectionMap;
      29             : template <size_t Dim>
      30             : class Domain;
      31             : namespace domain {
      32             : namespace CoordinateMaps {
      33             : template <size_t Dim>
      34             : class Identity;
      35             : class Interval;
      36             : template <typename Map1, typename Map2>
      37             : class ProductOf2Maps;
      38             : class SphericalToCartesianPfaffian;
      39             : }  // namespace CoordinateMaps
      40             : 
      41             : template <typename SourceFrame, typename TargetFrame, typename... Maps>
      42             : class CoordinateMap;
      43             : }  // namespace domain
      44             : /// \endcond
      45             : 
      46             : namespace domain::creators {
      47             : /// \brief A set of concentric spherical shells
      48             : ///
      49             : /// \note This domain will use a spherical harmonic basis in the angular
      50             : /// directions.  It cannot be used with subcell.
      51             : ///
      52             : /// \see Sphere for a spherical domain compatible with subcell
      53             : ///
      54             : /// Setting the inner radius to $0$ will set the inner-most element to be a
      55             : /// filled sphere.
      56             : ///
      57             : /// This domain creator offers one grid anchor "Center" at the origin.
      58             : ///
      59             : /// #### Time dependent maps
      60             : /// There are two ways to add time dependent maps to the SphericalShells domain
      61             : /// creator. In the input file, these are specified under the
      62             : /// `TimeDependentMaps:` block.
      63             : ///
      64             : /// ##### TimeDependence
      65             : /// You can use a simple TimeDependence (e.g.
      66             : /// `domain::creators::time_dependence::UniformTranslation` or
      67             : /// `domain::creators::time_dependence::RotationAboutZAxis`) to add time
      68             : /// dependent maps. This method will add the same maps to all blocks in the
      69             : /// domain.
      70             : ///
      71             : /// ##### Hard-coded time dependent maps
      72             : /// The SphericalShells domain creator also has the option to use some hard
      73             : /// coded time dependent maps that may be useful in certain scenarios. This
      74             : /// method adds the maps in `domain::creators::sphere::TimeDependentMapOptions`
      75             : /// to the domain. Hard-coded time-dependent maps are currently supported only
      76             : /// for excised domains, i.e. when `InnerRadius` is positive. When a shape map
      77             : /// is specified, the innermost radial shell uses it by default, while
      78             : /// subsequent shells have maps only between `Frame::Grid` and
      79             : /// `Frame::Inertial`. The `NumberOfRadialShellsWithShapeMap` option can add
      80             : /// distorted-frame maps to more inner shells. For domains with multiple radial
      81             : /// shells, the final radial shell cannot use the shape map. With only one
      82             : /// radial shell, the shape map rolls off at the outer boundary.
      83             : ///
      84             : /// ##### None
      85             : /// To not have any time dependent maps, pass a `std::nullopt` as the
      86             : /// appropriate argument in the constructor. In the input file, simply have
      87             : /// `TimeDependentMaps: None`.
      88           1 : class SphericalShells : public DomainCreator<3> {
      89             :  public:
      90           0 :   using maps_list =
      91             :       tmpl::append<tmpl::list<domain::CoordinateMap<
      92             :                        Frame::BlockLogical, Frame::Inertial,
      93             :                        domain::CoordinateMaps::ProductOf2Maps<
      94             :                            domain::CoordinateMaps::Interval,
      95             :                            domain::CoordinateMaps::Identity<2>>,
      96             :                        domain::CoordinateMaps::SphericalToCartesianPfaffian>>,
      97             :                    typename sphere::TimeDependentMapOptions::maps_list>;
      98             : 
      99             :   /*!
     100             :    * \brief Radius of innermost spherical shell
     101             :    */
     102           1 :   struct InnerRadius {
     103           0 :     using type = double;
     104           0 :     static constexpr Options::String help = {
     105             :         "Inner radius of the spherical shells. If set to 0, the innermost "
     106             :         "element with be a B3 in which case the inner boundary condition is "
     107             :         "not used"};
     108             :   };
     109             : 
     110             :   /*!
     111             :    * \brief Radius of outer boundary
     112             :    */
     113           1 :   struct OuterRadius {
     114           0 :     using type = double;
     115           0 :     static constexpr Options::String help = {
     116             :         "Outer radius of the spherical shells."};
     117             :   };
     118             : 
     119             :   /*!
     120             :    * \brief Initial refinement in radial direction
     121             :    */
     122           1 :   struct InitialRadialRefinement {
     123           0 :     using type = size_t;
     124           0 :     static constexpr Options::String help = {
     125             :         "Initial radial refinement level."};
     126             :   };
     127             : 
     128             :   /*!
     129             :    * \brief Initial number of radial grid points
     130             :    */
     131           1 :   struct InitialNumberOfRadialGridPoints {
     132           0 :     using type = size_t;
     133           0 :     static constexpr Options::String help = {
     134             :         "Initial number of radial grid points."};
     135             :   };
     136             : 
     137             :   /*!
     138             :    * \brief Initial spherical harmonic resolution
     139             :    */
     140           1 :   struct InitialSphericalHarmonicL {
     141           0 :     using type = size_t;
     142           0 :     static size_t lower_bound() { return 6; }
     143           0 :     static constexpr Options::String help = {
     144             :         "Initial spherical harmonic resolution specified as the highest "
     145             :         "spherical harmonic represented on the grid.  Minimum value is 6."};
     146             :   };
     147             : 
     148             :   /*!
     149             :    * \brief Radial coordinates of the boundaries splitting elements
     150             :    */
     151           1 :   struct RadialPartitioning {
     152           0 :     using type = std::vector<double>;
     153           0 :     static constexpr Options::String help = {
     154             :         "Radial coordinates of the boundaries splitting the spherical shell "
     155             :         "between InnerRadius and OuterRadius. They must be given in ascending "
     156             :         "order. This should be used if boundaries need to be set at specific "
     157             :         "radii. If the number but not the specific locations of the boundaries "
     158             :         "are important, use InitialRefinement instead."};
     159             :   };
     160             : 
     161             :   /*!
     162             :    * \brief Distributions to apply to the radial coordinates
     163             :    */
     164           1 :   struct RadialDistribution {
     165           0 :     using type =
     166             :         std::variant<domain::CoordinateMaps::Distribution,
     167             :                      std::vector<domain::CoordinateMaps::Distribution>>;
     168           0 :     static constexpr Options::String help = {
     169             :         "Select the radial distribution of grid points in each spherical "
     170             :         "shell. There must be N+1 radial distributions specified for N radial "
     171             :         "partitions. You can also specify just a single radial distribution "
     172             :         "(not in a vector) which will use the same distribution for all "
     173             :         "partitions."};
     174             :   };
     175             : 
     176           0 :   using TimeDepOptionType = std::variant<
     177             :       sphere::TimeDependentMapOptions,
     178             :       std::unique_ptr<domain::creators::time_dependence::TimeDependence<3>>>;
     179             : 
     180             :   /*!
     181             :    * \brief Time dependence of the domain
     182             :    */
     183           1 :   struct TimeDependentMaps {
     184           0 :     using type = Options::Auto<TimeDepOptionType, Options::AutoLabel::None>;
     185           0 :     static constexpr Options::String help = {
     186             :         "The options for time dependent maps. This can either be a "
     187             :         "TimeDependence or hard coded time dependent options. Specify `None` "
     188             :         "for no time dependent maps."};
     189             :   };
     190             : 
     191             :   /*!
     192             :    * \brief Boundary condition to apply to inner boundary when not filled
     193             :    */
     194             :   template <typename BoundaryConditionsBase>
     195           1 :   struct InnerBoundaryCondition {
     196           0 :     static constexpr Options::String help =
     197             :         "Options for the boundary conditions at the inner radius.";
     198           0 :     using type = Options::Auto<std::unique_ptr<BoundaryConditionsBase>,
     199             :                                Options::AutoLabel::None>;
     200             :   };
     201             : 
     202             :   /*!
     203             :    * \brief Boundary condition to apply to outer boundary
     204             :    */
     205             :   template <typename BoundaryConditionsBase>
     206           1 :   struct OuterBoundaryCondition {
     207           0 :     static constexpr Options::String help =
     208             :         "Options for the boundary conditions at the outer radius.";
     209           0 :     using type = std::unique_ptr<BoundaryConditionsBase>;
     210             :   };
     211             : 
     212           0 :   using basic_options =
     213             :       tmpl::list<InnerRadius, OuterRadius, InitialRadialRefinement,
     214             :                  InitialNumberOfRadialGridPoints, InitialSphericalHarmonicL,
     215             :                  RadialPartitioning, RadialDistribution, TimeDependentMaps>;
     216             : 
     217             :   template <typename Metavariables>
     218           0 :   using options = tmpl::conditional_t<
     219             :       domain::BoundaryConditions::has_boundary_conditions_base_v<
     220             :           typename Metavariables::system>,
     221             :       tmpl::push_back<
     222             :           basic_options,
     223             :           InnerBoundaryCondition<
     224             :               domain::BoundaryConditions::get_boundary_conditions_base<
     225             :                   typename Metavariables::system>>,
     226             :           OuterBoundaryCondition<
     227             :               domain::BoundaryConditions::get_boundary_conditions_base<
     228             :                   typename Metavariables::system>>>,
     229             :       basic_options>;
     230             : 
     231           0 :   static constexpr Options::String help{
     232             :       "An optional B3 surrounded by a set of concentric spherical shells "
     233             :       "centered at the origin."};
     234             : 
     235           0 :   SphericalShells(
     236             :       double inner_radius, double outer_radius,
     237             :       size_t initial_radial_refinement,
     238             :       size_t initial_number_of_radial_grid_points,
     239             :       size_t initial_spherical_harmonic_l,
     240             :       std::vector<double> radial_partitioning = {},
     241             :       const typename RadialDistribution::type& radial_distribution =
     242             :           domain::CoordinateMaps::Distribution::Linear,
     243             :       std::optional<TimeDepOptionType> time_dependent_options = std::nullopt,
     244             :       std::optional<
     245             :           std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>>
     246             :           inner_boundary_condition = std::nullopt,
     247             :       std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
     248             :           outer_boundary_condition = nullptr,
     249             :       const Options::Context& context = {});
     250             : 
     251           0 :   SphericalShells() = default;
     252           0 :   SphericalShells(const SphericalShells&) = delete;
     253           0 :   SphericalShells(SphericalShells&&) = default;
     254           0 :   SphericalShells& operator=(const SphericalShells&) = delete;
     255           0 :   SphericalShells& operator=(SphericalShells&&) = default;
     256           0 :   ~SphericalShells() override = default;
     257             : 
     258           0 :   Domain<3> create_domain() const override;
     259             : 
     260             :   /// A single grid anchor "Center" at the origin.
     261             :   std::unordered_map<std::string, tnsr::I<double, 3, Frame::Grid>>
     262           1 :   grid_anchors() const override;
     263             : 
     264             :   std::vector<DirectionMap<
     265             :       3, std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>>>
     266           1 :   external_boundary_conditions() const override;
     267             : 
     268           1 :   std::vector<std::array<size_t, 3>> initial_extents() const override;
     269             : 
     270           1 :   std::vector<std::array<size_t, 3>> initial_refinement_levels() const override;
     271             : 
     272             :   /// The block names are Shell0, Shell1, ..., starting with the innermost
     273             :   /// Block.
     274           1 :   std::vector<std::string> block_names() const override;
     275             : 
     276             :   /// The block groups are Shell0, Shell1, ..., starting with the innermost
     277             :   /// Block.
     278             :   std::unordered_map<std::string, std::unordered_set<std::string>>
     279           1 :   block_groups() const override;
     280             : 
     281           1 :   auto functions_of_time(const std::unordered_map<std::string, double>&
     282             :                              initial_expiration_times = {}) const
     283             :       -> std::unordered_map<
     284             :           std::string,
     285             :           std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>> override;
     286             : 
     287             :  private:
     288           0 :   double inner_radius_{};
     289           0 :   double outer_radius_{};
     290           0 :   size_t initial_radial_refinement_{};
     291           0 :   size_t initial_number_of_radial_grid_points_{};
     292           0 :   bool excise_center_{};
     293           0 :   size_t initial_spherical_harmonic_l_{};
     294           0 :   std::vector<double> radial_partitioning_{};
     295           0 :   std::vector<domain::CoordinateMaps::Distribution> radial_distribution_{};
     296           0 :   std::optional<TimeDepOptionType> time_dependent_options_{};
     297           0 :   bool use_hard_coded_maps_{false};
     298             :   std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
     299           0 :       inner_boundary_condition_{};
     300             :   std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
     301           0 :       outer_boundary_condition_{};
     302           0 :   size_t num_blocks_{};
     303           0 :   std::vector<std::string> block_names_{};
     304             :   std::unordered_map<std::string, std::unordered_set<std::string>>
     305           0 :       block_groups_{};
     306             :   std::unordered_map<std::string, tnsr::I<double, 3, Frame::Grid>>
     307           0 :       grid_anchors_{};
     308             : };
     309             : }  // namespace domain::creators

Generated by: LCOV version 1.14