SpECTRE Documentation Coverage Report
Current view: top level - Domain/Creators - SphericalShells.hpp Hit Total Coverage
Commit: c3e43f8d41800b0ecefb9d1393f1de1d5a280c8f Lines: 18 69 26.1 %
Date: 2026-07-24 22:09:25
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. Currently, the first (inner-most) shell has maps between
      76             : /// `Frame::Grid`, `Frame::Distorted`, and `Frame::Inertial` while all
      77             : /// subsequent shells only have maps between `Frame::Grid` and
      78             : /// `Frame::Inertial`.
      79             : ///
      80             : /// ##### None
      81             : /// To not have any time dependent maps, pass a `std::nullopt` as the
      82             : /// appropriate argument in the constructor. In the input file, simply have
      83             : /// `TimeDependentMaps: None`.
      84           1 : class SphericalShells : public DomainCreator<3> {
      85             :  public:
      86           0 :   using maps_list =
      87             :       tmpl::append<tmpl::list<domain::CoordinateMap<
      88             :                        Frame::BlockLogical, Frame::Inertial,
      89             :                        domain::CoordinateMaps::ProductOf2Maps<
      90             :                            domain::CoordinateMaps::Interval,
      91             :                            domain::CoordinateMaps::Identity<2>>,
      92             :                        domain::CoordinateMaps::SphericalToCartesianPfaffian>>,
      93             :                    typename sphere::TimeDependentMapOptions::maps_list>;
      94             : 
      95             :   /*!
      96             :    * \brief Radius of innermost spherical shell
      97             :    */
      98           1 :   struct InnerRadius {
      99           0 :     using type = double;
     100           0 :     static constexpr Options::String help = {
     101             :         "Inner radius of the spherical shells. If set to 0, the innermost "
     102             :         "element with be a B3 in which case the inner boundary condition is "
     103             :         "not used"};
     104             :   };
     105             : 
     106             :   /*!
     107             :    * \brief Radius of outer boundary
     108             :    */
     109           1 :   struct OuterRadius {
     110           0 :     using type = double;
     111           0 :     static constexpr Options::String help = {
     112             :         "Outer radius of the spherical shells."};
     113             :   };
     114             : 
     115             :   /*!
     116             :    * \brief Initial refinement in radial direction
     117             :    */
     118           1 :   struct InitialRadialRefinement {
     119           0 :     using type = size_t;
     120           0 :     static constexpr Options::String help = {
     121             :         "Initial radial refinement level."};
     122             :   };
     123             : 
     124             :   /*!
     125             :    * \brief Initial number of radial grid points
     126             :    */
     127           1 :   struct InitialNumberOfRadialGridPoints {
     128           0 :     using type = size_t;
     129           0 :     static constexpr Options::String help = {
     130             :         "Initial number of radial grid points."};
     131             :   };
     132             : 
     133             :   /*!
     134             :    * \brief Initial spherical harmonic resolution
     135             :    */
     136           1 :   struct InitialSphericalHarmonicL {
     137           0 :     using type = size_t;
     138           0 :     static size_t lower_bound() { return 6; }
     139           0 :     static constexpr Options::String help = {
     140             :         "Initial spherical harmonic resolution specified as the highest "
     141             :         "spherical harmonic represented on the grid.  Minimum value is 6."};
     142             :   };
     143             : 
     144             :   /*!
     145             :    * \brief Radial coordinates of the boundaries splitting elements
     146             :    */
     147           1 :   struct RadialPartitioning {
     148           0 :     using type = std::vector<double>;
     149           0 :     static constexpr Options::String help = {
     150             :         "Radial coordinates of the boundaries splitting the spherical shell "
     151             :         "between InnerRadius and OuterRadius. They must be given in ascending "
     152             :         "order. This should be used if boundaries need to be set at specific "
     153             :         "radii. If the number but not the specific locations of the boundaries "
     154             :         "are important, use InitialRefinement instead."};
     155             :   };
     156             : 
     157             :   /*!
     158             :    * \brief Distributions to apply to the radial coordinates
     159             :    */
     160           1 :   struct RadialDistribution {
     161           0 :     using type =
     162             :         std::variant<domain::CoordinateMaps::Distribution,
     163             :                      std::vector<domain::CoordinateMaps::Distribution>>;
     164           0 :     static constexpr Options::String help = {
     165             :         "Select the radial distribution of grid points in each spherical "
     166             :         "shell. There must be N+1 radial distributions specified for N radial "
     167             :         "partitions. You can also specify just a single radial distribution "
     168             :         "(not in a vector) which will use the same distribution for all "
     169             :         "partitions."};
     170             :   };
     171             : 
     172           0 :   using TimeDepOptionType = std::variant<
     173             :       sphere::TimeDependentMapOptions,
     174             :       std::unique_ptr<domain::creators::time_dependence::TimeDependence<3>>>;
     175             : 
     176             :   /*!
     177             :    * \brief Time dependence of the domain
     178             :    */
     179           1 :   struct TimeDependentMaps {
     180           0 :     using type = Options::Auto<TimeDepOptionType, Options::AutoLabel::None>;
     181           0 :     static constexpr Options::String help = {
     182             :         "The options for time dependent maps. This can either be a "
     183             :         "TimeDependence or hard coded time dependent options. Specify `None` "
     184             :         "for no time dependent maps."};
     185             :   };
     186             : 
     187             :   /*!
     188             :    * \brief Boundary condition to apply to inner boundary when not filled
     189             :    */
     190             :   template <typename BoundaryConditionsBase>
     191           1 :   struct InnerBoundaryCondition {
     192           0 :     static constexpr Options::String help =
     193             :         "Options for the boundary conditions at the inner radius.";
     194           0 :     using type = Options::Auto<std::unique_ptr<BoundaryConditionsBase>,
     195             :                                Options::AutoLabel::None>;
     196             :   };
     197             : 
     198             :   /*!
     199             :    * \brief Boundary condition to apply to outer boundary
     200             :    */
     201             :   template <typename BoundaryConditionsBase>
     202           1 :   struct OuterBoundaryCondition {
     203           0 :     static constexpr Options::String help =
     204             :         "Options for the boundary conditions at the outer radius.";
     205           0 :     using type = std::unique_ptr<BoundaryConditionsBase>;
     206             :   };
     207             : 
     208           0 :   using basic_options =
     209             :       tmpl::list<InnerRadius, OuterRadius, InitialRadialRefinement,
     210             :                  InitialNumberOfRadialGridPoints, InitialSphericalHarmonicL,
     211             :                  RadialPartitioning, RadialDistribution, TimeDependentMaps>;
     212             : 
     213             :   template <typename Metavariables>
     214           0 :   using options = tmpl::conditional_t<
     215             :       domain::BoundaryConditions::has_boundary_conditions_base_v<
     216             :           typename Metavariables::system>,
     217             :       tmpl::push_back<
     218             :           basic_options,
     219             :           InnerBoundaryCondition<
     220             :               domain::BoundaryConditions::get_boundary_conditions_base<
     221             :                   typename Metavariables::system>>,
     222             :           OuterBoundaryCondition<
     223             :               domain::BoundaryConditions::get_boundary_conditions_base<
     224             :                   typename Metavariables::system>>>,
     225             :       basic_options>;
     226             : 
     227           0 :   static constexpr Options::String help{
     228             :       "An optional B3 surrounded by a set of concentric spherical shells "
     229             :       "centered at the origin."};
     230             : 
     231           0 :   SphericalShells(
     232             :       double inner_radius, double outer_radius,
     233             :       size_t initial_radial_refinement,
     234             :       size_t initial_number_of_radial_grid_points,
     235             :       size_t initial_spherical_harmonic_l,
     236             :       std::vector<double> radial_partitioning = {},
     237             :       const typename RadialDistribution::type& radial_distribution =
     238             :           domain::CoordinateMaps::Distribution::Linear,
     239             :       std::optional<TimeDepOptionType> time_dependent_options = std::nullopt,
     240             :       std::optional<
     241             :           std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>>
     242             :           inner_boundary_condition = std::nullopt,
     243             :       std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
     244             :           outer_boundary_condition = nullptr,
     245             :       const Options::Context& context = {});
     246             : 
     247           0 :   SphericalShells() = default;
     248           0 :   SphericalShells(const SphericalShells&) = delete;
     249           0 :   SphericalShells(SphericalShells&&) = default;
     250           0 :   SphericalShells& operator=(const SphericalShells&) = delete;
     251           0 :   SphericalShells& operator=(SphericalShells&&) = default;
     252           0 :   ~SphericalShells() override = default;
     253             : 
     254           0 :   Domain<3> create_domain() const override;
     255             : 
     256             :   /// A single grid anchor "Center" at the origin.
     257             :   std::unordered_map<std::string, tnsr::I<double, 3, Frame::Grid>>
     258           1 :   grid_anchors() const override;
     259             : 
     260             :   std::vector<DirectionMap<
     261             :       3, std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>>>
     262           1 :   external_boundary_conditions() const override;
     263             : 
     264           1 :   std::vector<std::array<size_t, 3>> initial_extents() const override;
     265             : 
     266           1 :   std::vector<std::array<size_t, 3>> initial_refinement_levels() const override;
     267             : 
     268             :   /// The block names are Shell0, Shell1, ..., starting with the innermost
     269             :   /// Block.
     270           1 :   std::vector<std::string> block_names() const override;
     271             : 
     272             :   /// The block groups are Shell0, Shell1, ..., starting with the innermost
     273             :   /// Block.
     274             :   std::unordered_map<std::string, std::unordered_set<std::string>>
     275           1 :   block_groups() const override;
     276             : 
     277           1 :   auto functions_of_time(const std::unordered_map<std::string, double>&
     278             :                              initial_expiration_times = {}) const
     279             :       -> std::unordered_map<
     280             :           std::string,
     281             :           std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>> override;
     282             : 
     283             :  private:
     284           0 :   double inner_radius_{};
     285           0 :   double outer_radius_{};
     286           0 :   size_t initial_radial_refinement_{};
     287           0 :   size_t initial_number_of_radial_grid_points_{};
     288           0 :   bool excise_center_{};
     289           0 :   size_t initial_spherical_harmonic_l_{};
     290           0 :   std::vector<double> radial_partitioning_{};
     291           0 :   std::vector<domain::CoordinateMaps::Distribution> radial_distribution_{};
     292           0 :   std::optional<TimeDepOptionType> time_dependent_options_{};
     293           0 :   bool use_hard_coded_maps_{false};
     294             :   std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
     295           0 :       inner_boundary_condition_{};
     296             :   std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
     297           0 :       outer_boundary_condition_{};
     298           0 :   size_t num_blocks_{};
     299           0 :   std::vector<std::string> block_names_{};
     300             :   std::unordered_map<std::string, std::unordered_set<std::string>>
     301           0 :       block_groups_{};
     302             :   std::unordered_map<std::string, tnsr::I<double, 3, Frame::Grid>>
     303           0 :       grid_anchors_{};
     304             : };
     305             : }  // namespace domain::creators

Generated by: LCOV version 1.14