SpECTRE Documentation Coverage Report
Current view: top level - Domain/Creators - AngularCylinder.hpp Hit Total Coverage
Commit: 1e29a35ad8559408f21493dc5db8a49a237bb2f0 Lines: 22 92 23.9 %
Date: 2026-03-31 22:27:51
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 <unordered_set>
      12             : #include <variant>
      13             : #include <vector>
      14             : 
      15             : #include "DataStructures/Tensor/IndexType.hpp"
      16             : #include "Domain/BoundaryConditions/BoundaryCondition.hpp"
      17             : #include "Domain/BoundaryConditions/GetBoundaryConditionsBase.hpp"
      18             : #include "Domain/CoordinateMaps/Distribution.hpp"
      19             : #include "Domain/Creators/DomainCreator.hpp"
      20             : #include "Domain/Creators/TimeDependence/TimeDependence.hpp"
      21             : #include "Domain/Domain.hpp"
      22             : #include "Domain/Structure/DirectionMap.hpp"
      23             : #include "Options/Context.hpp"
      24             : #include "Options/String.hpp"
      25             : #include "Utilities/TMPL.hpp"
      26             : 
      27             : /// \cond
      28             : namespace domain {
      29             : namespace CoordinateMaps {
      30             : class Affine;
      31             : template <size_t Dim>
      32             : class Identity;
      33             : class Interval;
      34             : class PolarToCartesian;
      35             : template <typename Map1, typename Map2>
      36             : class ProductOf2Maps;
      37             : template <typename Map1, typename Map2, typename Map3>
      38             : class ProductOf3Maps;
      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             : /*!
      48             :  * \brief Create a 3D filled cylinder domain with radial partitioning using a
      49             :  * B2/I1 filled cylinder at the center and Fourier hollow cylinders surrounding
      50             :  * it.
      51             :  */
      52           1 : class AngularCylinder : public DomainCreator<3> {
      53             :  public:
      54           0 :   using maps_list = tmpl::list<domain::CoordinateMap<
      55             :       Frame::BlockLogical, Frame::Inertial,
      56             :       domain::CoordinateMaps::ProductOf3Maps<
      57             :           domain::CoordinateMaps::Affine, domain::CoordinateMaps::Identity<1>,
      58             :           domain::CoordinateMaps::Interval>,
      59             :       domain::CoordinateMaps::ProductOf2Maps<
      60             :           domain::CoordinateMaps::PolarToCartesian,
      61             :           domain::CoordinateMaps::Identity<1>>>>;
      62             : 
      63             :   /*!
      64             :    * \brief Radius of the cylinder's outer edge
      65             :    */
      66           1 :   struct OuterRadius {
      67           0 :     using type = double;
      68           0 :     static constexpr Options::String help = {"Radius of the cylinder."};
      69             :   };
      70             : 
      71             :   /*!
      72             :    * \brief Lower z-coordinate of the cylinder's base
      73             :    */
      74           1 :   struct LowerZBound {
      75           0 :     using type = double;
      76           0 :     static constexpr Options::String help = {
      77             :         "z-coordinate of the base of the cylinder."};
      78             :   };
      79             : 
      80             :   /*!
      81             :    * \brief Upper z-coordinate of the cylinder's top
      82             :    */
      83           1 :   struct UpperZBound {
      84           0 :     using type = double;
      85           0 :     static constexpr Options::String help = {
      86             :         "z-coordinate of the top of the cylinder."};
      87             :   };
      88             : 
      89             :   /*!
      90             :    * \brief Whether the cylinder is periodic in the z direction
      91             :    */
      92           1 :   struct IsPeriodicInZ {
      93           0 :     using type = bool;
      94           0 :     static constexpr Options::String help = {
      95             :         "True if periodic in the cylindrical z direction."};
      96             :   };
      97             : 
      98             :   /*!
      99             :    * \brief Radial coordinates of the boundaries splitting elements
     100             :    */
     101           1 :   struct RadialPartitioning {
     102           0 :     using type = std::vector<double>;
     103           0 :     static constexpr Options::String help = {
     104             :         "Radial coordinates of the boundaries splitting the inner cylinder and "
     105             :         "potential hollow cylinder shells"};
     106             :   };
     107             : 
     108             :   /*!
     109             :    * \brief Z-coordinates of the boundaries splitting the domain into layers
     110             :    */
     111           1 :   struct PartitioningInZ {
     112           0 :     using type = std::vector<double>;
     113           0 :     static constexpr Options::String help = {
     114             :         "z-coordinates of the boundaries splitting the domain into layers "
     115             :         "between LowerZBound and UpperZBound."};
     116             :   };
     117             : 
     118             :   /*!
     119             :    * \brief Initial number of \f$\theta\f$ gridpoints for filled cylinder. The
     120             :    * number for \f$r\f$ is accordingly set to match spectral space sizes. This
     121             :    * is enforced to be odd for numerical stability.
     122             :    */
     123           1 :   struct InitialCylinderThetaGridPoints {
     124           0 :     using type = size_t;
     125           0 :     static constexpr Options::String help = {
     126             :         "Initial number of grid points in theta (r is accordingly set). It "
     127             :         "must be an odd number for stability."};
     128             :   };
     129             : 
     130             :   /*!
     131             :    * \brief Initial number of z gridpoints for the cylinder
     132             :    */
     133           1 :   struct InitialCylinderZGridPoints {
     134           0 :     using type = size_t;
     135           0 :     static constexpr Options::String help = {
     136             :         "Initial number of grid points in z"};
     137             :   };
     138             : 
     139             :   /*!
     140             :    * \brief Initial number of \f$[r, \theta, z]\f$ gridpoints for hollow
     141             :    * cylinders. Can be one triplet which is applied to all shells, or each can
     142             :    * be specified. The theta component must be odd for numerical stability.
     143             :    */
     144           1 :   struct InitialHollowCylinderGridPoints {
     145           0 :     using type =
     146             :         std::variant<std::array<size_t, 3>, std::vector<std::array<size_t, 3>>>;
     147           0 :     static constexpr Options::String help = {
     148             :         "Initial number of grid points in [r, theta, z] for each hollow "
     149             :         "cylinder. If one triplet is given, it will be applied to all blocks, "
     150             :         "otherwise each hollow cylinder can be specified. The theta component "
     151             :         "must be odd for better numerical stability."};
     152             :   };
     153             : 
     154             :   /*!
     155             :    * \brief Grid point distribution along the z-axis for each layer
     156             :    */
     157           1 :   struct DistributionInZ {
     158           0 :     using type = std::vector<domain::CoordinateMaps::Distribution>;
     159           0 :     static constexpr Options::String help = {
     160             :         "Select the distribution of grid points along the z-axis in each "
     161             :         "layer. The lowermost layer must have a 'Linear' distribution, because "
     162             :         "both a 'Logarithmic' and 'Inverse' distribution places its "
     163             :         "singularity at 'LowerZBound'. The 'PartitioningInZ' determines the "
     164             :         "number of layers."};
     165           0 :     static size_t lower_bound_on_size() { return 1; }
     166             :   };
     167             : 
     168             :   /*!
     169             :    * \brief Initial refinement levels in the z direction
     170             :    */
     171           1 :   struct InitialRefinementInZ {
     172           0 :     using type = std::variant<size_t, std::vector<size_t>>;
     173           0 :     static constexpr Options::String help = {
     174             :         "Initial refinement level in the z-direction. Can be either a single "
     175             :         "value applied to all layers, or a vector with one value per layer. "
     176             :         "The number of layers is determined by 'PartitioningInZ'."};
     177             :   };
     178             : 
     179             :   /*!
     180             :    * \brief Time dependence of the domain
     181             :    */
     182           1 :   struct TimeDependence {
     183           0 :     using type =
     184             :         std::unique_ptr<domain::creators::time_dependence::TimeDependence<3>>;
     185           0 :     static constexpr Options::String help = {
     186             :         "The time dependence of the moving mesh domain. Specify `None` for no "
     187             :         "time dependent maps."};
     188             :   };
     189             : 
     190             :   /*!
     191             :    * \brief Boundary conditions group
     192             :    */
     193           1 :   struct BoundaryConditions {
     194           0 :     static constexpr Options::String help =
     195             :         "Options for the boundary conditions";
     196             :   };
     197             : 
     198             :   /*!
     199             :    * \brief Boundary condition on the lower base
     200             :    */
     201             :   template <typename BoundaryConditionsBase>
     202           1 :   struct LowerZBoundaryCondition {
     203           0 :     using group = BoundaryConditions;
     204           0 :     static std::string name() { return "LowerZ"; }
     205           0 :     static constexpr Options::String help =
     206             :         "The boundary condition to be imposed on the lower base of the "
     207             :         "cylinder, i.e. at the `LowerZBound` in the z-direction.";
     208           0 :     using type = std::unique_ptr<BoundaryConditionsBase>;
     209             :   };
     210             : 
     211             :   /*!
     212             :    * \brief Boundary condition on the upper base
     213             :    */
     214             :   template <typename BoundaryConditionsBase>
     215           1 :   struct UpperZBoundaryCondition {
     216           0 :     using group = BoundaryConditions;
     217           0 :     static std::string name() { return "UpperZ"; }
     218           0 :     static constexpr Options::String help =
     219             :         "The boundary condition to be imposed on the upper base of the "
     220             :         "cylinder, i.e. at the `UpperZBound` in the z-direction.";
     221           0 :     using type = std::unique_ptr<BoundaryConditionsBase>;
     222             :   };
     223             : 
     224             :   /*!
     225             :    * \brief Boundary condition on the radial boundary
     226             :    */
     227             :   template <typename BoundaryConditionsBase>
     228           1 :   struct MantleBoundaryCondition {
     229           0 :     using group = BoundaryConditions;
     230           0 :     static std::string name() { return "Mantle"; }
     231           0 :     static constexpr Options::String help =
     232             :         "The boundary condition to be imposed on the mantle of the "
     233             :         "cylinder, i.e. at the `OuterRadius` in the radial direction.";
     234           0 :     using type = std::unique_ptr<BoundaryConditionsBase>;
     235             :   };
     236             : 
     237           0 :   using basic_options =
     238             :       tmpl::list<OuterRadius, LowerZBound, UpperZBound, RadialPartitioning,
     239             :                  PartitioningInZ, InitialCylinderThetaGridPoints,
     240             :                  InitialCylinderZGridPoints, InitialHollowCylinderGridPoints,
     241             :                  DistributionInZ, InitialRefinementInZ, TimeDependence>;
     242             : 
     243             :   template <typename Metavariables>
     244           0 :   using options = tmpl::append<
     245             :       basic_options,
     246             :       tmpl::conditional_t<
     247             :           domain::BoundaryConditions::has_boundary_conditions_base_v<
     248             :               typename Metavariables::system>,
     249             :           tmpl::list<
     250             :               LowerZBoundaryCondition<
     251             :                   domain::BoundaryConditions::get_boundary_conditions_base<
     252             :                       typename Metavariables::system>>,
     253             :               UpperZBoundaryCondition<
     254             :                   domain::BoundaryConditions::get_boundary_conditions_base<
     255             :                       typename Metavariables::system>>,
     256             :               MantleBoundaryCondition<
     257             :                   domain::BoundaryConditions::get_boundary_conditions_base<
     258             :                       typename Metavariables::system>>>,
     259             :           tmpl::list<IsPeriodicInZ>>>;
     260             : 
     261           0 :   static constexpr Options::String help{
     262             :       "Creates a cylinder using a Zernike basis radially, Fourier in the "
     263             :       "angular direction, and I1 in the z direction"};
     264             : 
     265           0 :   AngularCylinder(
     266             :       typename OuterRadius::type outer_radius,
     267             :       typename LowerZBound::type lower_z_bound,
     268             :       typename UpperZBound::type upper_z_bound,
     269             :       typename RadialPartitioning::type radial_partitioning,
     270             :       typename PartitioningInZ::type partitioning_in_z,
     271             :       typename InitialCylinderThetaGridPoints::type
     272             :           initial_cylinder_theta_grid_points,
     273             :       typename InitialCylinderZGridPoints::type initial_cylinder_z_grid_points,
     274             :       typename InitialHollowCylinderGridPoints::type
     275             :           initial_hollow_cylinder_grid_points,
     276             :       typename DistributionInZ::type distribution_in_z,
     277             :       typename InitialRefinementInZ::type initial_refinement_in_z,
     278             :       std::unique_ptr<domain::creators::time_dependence::TimeDependence<3>>
     279             :           time_dependence = nullptr,
     280             :       bool is_periodic_in_z = false,
     281             :       const Options::Context& context = {});
     282             : 
     283           0 :   AngularCylinder(
     284             :       typename OuterRadius::type outer_radius,
     285             :       typename LowerZBound::type lower_z_bound,
     286             :       typename UpperZBound::type upper_z_bound,
     287             :       typename RadialPartitioning::type radial_partitioning,
     288             :       typename PartitioningInZ::type partitioning_in_z,
     289             :       typename InitialCylinderThetaGridPoints::type
     290             :           initial_cylinder_theta_grid_points,
     291             :       typename InitialCylinderZGridPoints::type initial_cylinder_z_grid_points,
     292             :       typename InitialHollowCylinderGridPoints::type
     293             :           initial_hollow_cylinder_grid_points,
     294             :       typename DistributionInZ::type distribution_in_z,
     295             :       typename InitialRefinementInZ::type initial_refinement_in_z,
     296             :       std::unique_ptr<domain::creators::time_dependence::TimeDependence<3>>
     297             :           time_dependence = nullptr,
     298             :       std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
     299             :           lower_z_boundary_condition = nullptr,
     300             :       std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
     301             :           upper_z_boundary_condition = nullptr,
     302             :       std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
     303             :           mantle_boundary_condition = nullptr,
     304             :       const Options::Context& context = {});
     305             : 
     306           0 :   AngularCylinder() = default;
     307           0 :   AngularCylinder(const AngularCylinder&) = delete;
     308           0 :   AngularCylinder(AngularCylinder&&) = default;
     309           0 :   AngularCylinder& operator=(const AngularCylinder&) = delete;
     310           0 :   AngularCylinder& operator=(AngularCylinder&&) = default;
     311           0 :   ~AngularCylinder() override = default;
     312             : 
     313           0 :   Domain<3> create_domain() const override;
     314             : 
     315             :   std::vector<DirectionMap<
     316             :       3, std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>>>
     317           1 :   external_boundary_conditions() const override;
     318             : 
     319           1 :   std::vector<std::array<size_t, 3>> initial_extents() const override;
     320             : 
     321           1 :   std::vector<std::array<size_t, 3>> initial_refinement_levels() const override;
     322             : 
     323           1 :   std::vector<std::string> block_names() const override { return block_names_; }
     324             : 
     325             :   std::unordered_map<std::string, std::unordered_set<std::string>>
     326           1 :   block_groups() const override {
     327             :     return block_groups_;
     328             :   }
     329             : 
     330             :  private:
     331           0 :   typename OuterRadius::type outer_radius_{};
     332           0 :   typename LowerZBound::type lower_z_bound_{};
     333           0 :   typename UpperZBound::type upper_z_bound_{};
     334           0 :   typename IsPeriodicInZ::type is_periodic_in_z_{};
     335           0 :   typename RadialPartitioning::type radial_partitioning_{};
     336           0 :   typename PartitioningInZ::type partitioning_in_z_{};
     337             :   typename InitialCylinderThetaGridPoints::type
     338           0 :       initial_cylinder_theta_grid_points_{};
     339           0 :   typename InitialCylinderZGridPoints::type initial_cylinder_z_grid_points_{};
     340           0 :   std::vector<std::array<size_t, 3>> initial_hollow_cylinder_grid_points_{};
     341           0 :   DistributionInZ::type distribution_in_z_{};
     342           0 :   std::vector<size_t> initial_refinement_in_z_{};
     343             :   std::unique_ptr<domain::creators::time_dependence::TimeDependence<3>>
     344           0 :       time_dependence_ = nullptr;
     345             :   std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
     346           0 :       lower_z_boundary_condition_{};
     347             :   std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
     348           0 :       upper_z_boundary_condition_{};
     349             :   std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
     350           0 :       mantle_boundary_condition_{};
     351           0 :   std::vector<std::string> block_names_;
     352             :   std::unordered_map<std::string, std::unordered_set<std::string>>
     353           0 :       block_groups_;
     354           0 :   size_t num_blocks_{};
     355             : };
     356             : }  // namespace domain::creators

Generated by: LCOV version 1.14