SpECTRE Documentation Coverage Report
Current view: top level - Domain/Creators - AngularCylinder.hpp Coverage Total Hit
Commit: 0d1d717af84a81fb1284a20c4013708fe85cc2f0 Lines: 23.9 % 92 22
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 <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 2.0-1