SpECTRE Documentation Coverage Report
Current view: top level - Domain/Creators - NonconformingSphericalShells.hpp Hit Total Coverage
Commit: 107e15b340886ae54549b1baa4bfc92e676f667e Lines: 8 89 9.0 %
Date: 2026-09-17 16:38:56
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 <unordered_set>
      13             : #include <variant>
      14             : #include <vector>
      15             : 
      16             : #include "Domain/BoundaryConditions/BoundaryCondition.hpp"
      17             : #include "Domain/BoundaryConditions/GetBoundaryConditionsBase.hpp"
      18             : #include "Domain/CoordinateMaps/BulgedCube.hpp"
      19             : #include "Domain/CoordinateMaps/Equiangular.hpp"
      20             : #include "Domain/CoordinateMaps/ProductMaps.hpp"
      21             : #include "Domain/Creators/DomainCreator.hpp"
      22             : #include "Domain/Creators/Sphere.hpp"
      23             : #include "Domain/Creators/TimeDependence/TimeDependence.hpp"
      24             : #include "Domain/Creators/TimeDependentOptions/Sphere.hpp"
      25             : #include "Options/Auto.hpp"
      26             : #include "Options/Context.hpp"
      27             : #include "Options/String.hpp"
      28             : #include "Utilities/TMPL.hpp"
      29             : 
      30             : /// \cond
      31             : template <size_t Dim, typename T>
      32             : class DirectionMap;
      33             : template <size_t Dim>
      34             : class Domain;
      35             : namespace domain {
      36             : namespace CoordinateMaps {
      37             : class Affine;
      38             : template <size_t Dim>
      39             : class Identity;
      40             : class Interval;
      41             : template <typename Map1, typename Map2>
      42             : class ProductOf2Maps;
      43             : class SphericalToCartesianPfaffian;
      44             : template <size_t Dim>
      45             : class Wedge;
      46             : }  // namespace CoordinateMaps
      47             : 
      48             : template <typename SourceFrame, typename TargetFrame, typename... Maps>
      49             : class CoordinateMap;
      50             : }  // namespace domain
      51             : /// \endcond
      52             : 
      53             : namespace domain::creators {
      54             : /*!
      55             :  * \brief A set of non-conforming concentric spherical shells
      56             :  *
      57             :  * \details The inner spherical shells are decomposed into six wedges
      58             :  * surrounding an optionally excised interior region.  The outer spherical
      59             :  * shells will use a spherical harmonic basis which cannot be used with subcell.
      60             :  *
      61             :  * This domain creator offers one grid anchor "Center" at the origin.
      62             :  *
      63             :  */
      64           1 : class NonconformingSphericalShells : public DomainCreator<3> {
      65             :  private:
      66           0 :   using Affine = CoordinateMaps::Affine;
      67           0 :   using Affine3D = CoordinateMaps::ProductOf3Maps<Affine, Affine, Affine>;
      68           0 :   using Equiangular = CoordinateMaps::Equiangular;
      69           0 :   using Equiangular3D =
      70             :       CoordinateMaps::ProductOf3Maps<Equiangular, Equiangular, Equiangular>;
      71           0 :   using BulgedCube = CoordinateMaps::BulgedCube;
      72             : 
      73             :  public:
      74           0 :   using maps_list = tmpl::list<
      75             :       // Inner cube
      76             :       domain::CoordinateMap<Frame::BlockLogical, Frame::Inertial, BulgedCube>,
      77             :       domain::CoordinateMap<Frame::BlockLogical, Frame::Inertial, Affine3D>,
      78             :       domain::CoordinateMap<Frame::BlockLogical, Frame::Inertial,
      79             :                             Equiangular3D>,
      80             :       // Wedges
      81             :       domain::CoordinateMap<Frame::BlockLogical, Frame::Inertial,
      82             :                             CoordinateMaps::Wedge<3>>,
      83             :       // Spherical shells
      84             :       domain::CoordinateMap<
      85             :           Frame::BlockLogical, Frame::Inertial,
      86             :           domain::CoordinateMaps::ProductOf2Maps<
      87             :               domain::CoordinateMaps::Interval,
      88             :               domain::CoordinateMaps::Identity<2>>,
      89             :           domain::CoordinateMaps::SphericalToCartesianPfaffian>,
      90             :       typename sphere::TimeDependentMapOptions::maps_list>;
      91             : 
      92           0 :   struct InnerRadius {
      93           0 :     using type = double;
      94           0 :     static constexpr Options::String help = {
      95             :         "Inner radius of the inner wedges."};
      96             :   };
      97             : 
      98           0 :   struct InterfaceRadius {
      99           0 :     using type = double;
     100           0 :     static constexpr Options::String help = {
     101             :         "Radius of interface between the inner wedges and the outer spherical "
     102             :         "shells."};
     103             :   };
     104             : 
     105           0 :   struct OuterRadius {
     106           0 :     using type = double;
     107           0 :     static constexpr Options::String help = {
     108             :         "Outer radius of the outer spherical shell."};
     109             :   };
     110             : 
     111           0 :   using Excision = detail::Excision;
     112           0 :   using InnerCube = detail::InnerCube;
     113             : 
     114           0 :   struct Interior {
     115           0 :     using type = std::variant<Excision, InnerCube>;
     116           0 :     static constexpr Options::String help = {
     117             :         "Specify 'ExciseWithBoundaryCondition' and a boundary condition to "
     118             :         "excise the interior of the sphere, leaving a spherical shell "
     119             :         "(or just 'Excise' if boundary conditions are disabled). "
     120             :         "Or specify 'FillWithSphericity' to fill the interior."};
     121             :   };
     122             : 
     123           0 :   struct InitialCubeRefinement {
     124           0 :     using type =
     125             :         std::variant<std::array<size_t, 2>, std::vector<std::array<size_t, 2>>,
     126             :                      std::unordered_map<std::string, std::array<size_t, 2>>>;
     127           0 :     static constexpr Options::String help = {
     128             :         "Initial cube refinement level. Specify one of: a "
     129             :         "list representing [angular, r], or such a list for every block "
     130             :         "in the domain. The central cube always uses the angular value for all "
     131             :         "directions."};
     132             :   };
     133             : 
     134           0 :   struct InitialSHRefinement {
     135           0 :     using type = std::variant<size_t, std::vector<size_t>,
     136             :                               std::unordered_map<std::string, size_t>>;
     137           0 :     static constexpr Options::String help = {
     138             :         "Initial spherical harmonic shell radial refinement level. Specify one "
     139             :         "of: a single number, or such a number for every block in the domain."};
     140             :   };
     141             : 
     142           0 :   struct InitialCubeGridPoints {
     143           0 :     using type =
     144             :         std::variant<std::array<size_t, 2>, std::vector<std::array<size_t, 2>>,
     145             :                      std::unordered_map<std::string, std::array<size_t, 2>>>;
     146           0 :     static constexpr Options::String help = {
     147             :         "Initial number of grid points for the cube region. Specify one of: a "
     148             :         "list representing [angular, r], or such a list for every block "
     149             :         "in the domain. The central cube always uses the angular value for all "
     150             :         "directions."};
     151             :   };
     152             : 
     153           0 :   struct InitialSHGridPoints {
     154           0 :     using type =
     155             :         std::variant<std::array<size_t, 2>, std::vector<std::array<size_t, 2>>,
     156             :                      std::unordered_map<std::string, std::array<size_t, 2>>>;
     157           0 :     static constexpr Options::String help = {
     158             :         "Initial number of grid points for the spherical harmonic shells. "
     159             :         "Specify one of: a list representing [l_max, r], or such a list for "
     160             :         "every block in the domain."};
     161             :   };
     162             : 
     163           0 :   struct RadialPartitioning {
     164           0 :     using type = std::array<std::vector<double>, 2>;
     165           0 :     static constexpr Options::String help = {
     166             :         "Radial coordinates of the boundaries splitting the spherical shell "
     167             :         "between InnerRadius and InterfaceRadius and then the InterfaceRadius "
     168             :         "and OuterRadius. They must be given in ascending order."};
     169             :   };
     170             : 
     171           0 :   struct RadialDistribution {
     172           0 :     using type =
     173             :         std::array<std::vector<domain::CoordinateMaps::Distribution>, 2>;
     174           0 :     static constexpr Options::String help = {
     175             :         "Select the radial distribution of grid points in each spherical "
     176             :         "shell. There must be N+1 radial distributions specified for N radial "
     177             :         "partitions for both the wedges and spherical shells. If the interior "
     178             :         "of the sphere is filled with a cube, the innermost shell must have a "
     179             :         "'Linear' distribution because it changes in sphericity."};
     180             :   };
     181             : 
     182           0 :   struct UseEquiangularMap {
     183           0 :     using type = bool;
     184           0 :     static constexpr Options::String help = {
     185             :         "Use equiangular instead of equidistant coordinates. Equiangular "
     186             :         "coordinates give better gridpoint spacings in the angular "
     187             :         "directions, while equidistant coordinates give better gridpoint "
     188             :         "spacings in the inner cube."};
     189             :   };
     190             : 
     191           0 :   using TimeDepOptionType = std::variant<
     192             :       sphere::TimeDependentMapOptions,
     193             :       std::unique_ptr<domain::creators::time_dependence::TimeDependence<3>>>;
     194             : 
     195           0 :   struct TimeDependentMaps {
     196           0 :     using type = Options::Auto<TimeDepOptionType, Options::AutoLabel::None>;
     197           0 :     static constexpr Options::String help = {
     198             :         "The options for time dependent maps. This can either be a "
     199             :         "TimeDependence or hard coded time dependent options. Specify `None` "
     200             :         "for no time dependent maps."};
     201             :   };
     202             : 
     203             :   template <typename BoundaryConditionsBase>
     204           0 :   struct OuterBoundaryCondition {
     205           0 :     static constexpr Options::String help =
     206             :         "Options for the boundary conditions at the outer radius.";
     207           0 :     using type = std::unique_ptr<BoundaryConditionsBase>;
     208             :   };
     209             : 
     210           0 :   using basic_options =
     211             :       tmpl::list<InnerRadius, InterfaceRadius, OuterRadius, Interior,
     212             :                  InitialCubeRefinement, InitialSHRefinement,
     213             :                  InitialCubeGridPoints, InitialSHGridPoints, RadialPartitioning,
     214             :                  RadialDistribution, UseEquiangularMap, TimeDependentMaps>;
     215             : 
     216             :   template <typename Metavariables>
     217           0 :   using options = tmpl::conditional_t<
     218             :       domain::BoundaryConditions::has_boundary_conditions_base_v<
     219             :           typename Metavariables::system>,
     220             :       tmpl::push_back<
     221             :           basic_options,
     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             :       "A set of concentric spherical shells centered at the origin."};
     229             : 
     230           0 :   NonconformingSphericalShells(
     231             :       double inner_radius, double interface_radius, double outer_radius,
     232             :       std::variant<Excision, InnerCube> interior,
     233             :       const typename InitialCubeRefinement::type& initial_cube_refinement,
     234             :       const typename InitialSHRefinement::type& initial_sh_refinement,
     235             :       const typename InitialCubeGridPoints::type& initial_cube_grid_points,
     236             :       const typename InitialSHGridPoints::type& initial_sh_grid_points,
     237             :       std::array<std::vector<double>, 2> radial_partitioning = {},
     238             :       std::array<std::vector<domain::CoordinateMaps::Distribution>, 2>
     239             :           radial_distribution =
     240             :               {std::vector<domain::CoordinateMaps::Distribution>{
     241             :                    domain::CoordinateMaps::Distribution::Linear},
     242             :                std::vector<domain::CoordinateMaps::Distribution>{
     243             :                    domain::CoordinateMaps::Distribution::Linear}},
     244             :       bool use_equiangular_map = true,
     245             :       std::optional<TimeDepOptionType> time_dependent_options = std::nullopt,
     246             :       std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
     247             :           outer_boundary_condition = nullptr,
     248             :       const Options::Context& context = {});
     249             : 
     250           0 :   NonconformingSphericalShells() = default;
     251           0 :   NonconformingSphericalShells(const NonconformingSphericalShells&) = delete;
     252           0 :   NonconformingSphericalShells(NonconformingSphericalShells&&) = default;
     253           0 :   NonconformingSphericalShells& operator=(const NonconformingSphericalShells&) =
     254             :       delete;
     255           0 :   NonconformingSphericalShells& operator=(NonconformingSphericalShells&&) =
     256             :       default;
     257           0 :   ~NonconformingSphericalShells() override = default;
     258             : 
     259           0 :   Domain<3> create_domain() const override;
     260             : 
     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::string> block_names() const override { return block_names_; }
     269             : 
     270             :   std::unordered_map<std::string, std::unordered_set<std::string>>
     271           1 :   block_groups() const override {
     272             :     return block_groups_;
     273             :   }
     274             : 
     275           1 :   std::vector<std::array<size_t, 3>> initial_extents() const override;
     276             : 
     277           1 :   std::vector<std::array<size_t, 3>> initial_refinement_levels() const override;
     278             : 
     279           1 :   auto functions_of_time(const std::unordered_map<std::string, double>&
     280             :                              initial_expiration_times = {}) const
     281             :       -> std::unordered_map<
     282             :           std::string,
     283             :           std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>> override;
     284             : 
     285             :  private:
     286           0 :   double inner_radius_{};
     287           0 :   double interface_radius_{};
     288           0 :   double outer_radius_{};
     289           0 :   std::variant<Excision, InnerCube> interior_{};
     290           0 :   bool fill_interior_ = false;
     291           0 :   std::vector<std::array<size_t, 2>> initial_cube_refinement_{};
     292           0 :   std::vector<size_t> initial_sh_refinement_{};
     293           0 :   std::vector<std::array<size_t, 2>> initial_cube_grid_points_{};
     294           0 :   std::vector<std::array<size_t, 2>> initial_sh_grid_points_{};
     295           0 :   std::array<std::vector<double>, 2> radial_partitioning_;
     296             :   std::array<std::vector<domain::CoordinateMaps::Distribution>, 2>
     297           0 :       radial_distribution_;
     298           0 :   bool use_equiangular_map_ = false;
     299           0 :   std::optional<TimeDepOptionType> time_dependent_options_{};
     300           0 :   bool use_hard_coded_maps_{false};
     301             :   std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
     302           0 :       outer_boundary_condition_{};
     303           0 :   std::vector<std::string> block_names_;
     304             :   std::unordered_map<std::string, std::unordered_set<std::string>>
     305           0 :       block_groups_;
     306           0 :   size_t num_blocks_{};
     307           0 :   size_t num_cube_shells_{};
     308           0 :   size_t num_sh_shells_{};
     309             :   std::unordered_map<std::string, tnsr::I<double, 3, Frame::Grid>>
     310           0 :       grid_anchors_{};
     311             : };
     312             : }  // namespace domain::creators

Generated by: LCOV version 1.14