SpECTRE Documentation Coverage Report
Current view: top level - Domain/Creators - SphericalShells.hpp Coverage Total Hit
Commit: 0d1d717af84a81fb1284a20c4013708fe85cc2f0 Lines: 26.1 % 69 18
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 <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 2; }
     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 2."};
     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 2.0-1