SpECTRE Documentation Coverage Report
Current view: top level - Domain/Creators - Cylinder.hpp Coverage Total Hit
Commit: 0d1d717af84a81fb1284a20c4013708fe85cc2f0 Lines: 6.5 % 93 6
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 <unordered_map>
      10              : #include <unordered_set>
      11              : #include <variant>
      12              : #include <vector>
      13              : 
      14              : #include "Domain/BoundaryConditions/BoundaryCondition.hpp"
      15              : #include "Domain/BoundaryConditions/GetBoundaryConditionsBase.hpp"
      16              : #include "Domain/CoordinateMaps/Distribution.hpp"
      17              : #include "Domain/Creators/DomainCreator.hpp"
      18              : #include "Domain/Domain.hpp"
      19              : #include "Domain/Structure/DirectionMap.hpp"
      20              : #include "Options/Context.hpp"
      21              : #include "Options/String.hpp"
      22              : #include "Utilities/TMPL.hpp"
      23              : 
      24              : /// \cond
      25              : namespace domain {
      26              : namespace CoordinateMaps {
      27              : class Interval;
      28              : template <typename Map1, typename Map2>
      29              : class ProductOf2Maps;
      30              : template <typename Map1, typename Map2, typename Map3>
      31              : class ProductOf3Maps;
      32              : template <size_t Dim>
      33              : class Wedge;
      34              : }  // namespace CoordinateMaps
      35              : 
      36              : template <typename SourceFrame, typename TargetFrame, typename... Maps>
      37              : class CoordinateMap;
      38              : }  // namespace domain
      39              : /// \endcond
      40              : 
      41              : namespace domain::creators {
      42              : /// Create a 3D Domain in the shape of a cylinder where the cross-section
      43              : /// is a square surrounded by four two-dimensional wedges (see `Wedge`).
      44              : ///
      45              : /// The outer shell can be split into sub-shells and the cylinder can be split
      46              : /// into disks along its height.
      47              : /// The block numbering starts at the inner square and goes counter-clockwise,
      48              : /// starting with the eastern wedge (+x-direction), through consecutive shells,
      49              : /// then repeats this pattern for all layers bottom to top.
      50              : ///
      51              : /// \image html Cylinder.png "The Cylinder Domain."
      52            1 : class Cylinder : public DomainCreator<3> {
      53              :  public:
      54            0 :   using maps_list =
      55              :       tmpl::list<domain::CoordinateMap<
      56              :                      Frame::BlockLogical, Frame::Inertial,
      57              :                      CoordinateMaps::ProductOf3Maps<CoordinateMaps::Interval,
      58              :                                                     CoordinateMaps::Interval,
      59              :                                                     CoordinateMaps::Interval>>,
      60              :                  domain::CoordinateMap<
      61              :                      Frame::BlockLogical, Frame::Inertial,
      62              :                      CoordinateMaps::ProductOf2Maps<CoordinateMaps::Wedge<2>,
      63              :                                                     CoordinateMaps::Interval>>>;
      64              : 
      65            0 :   struct InnerRadius {
      66            0 :     using type = double;
      67            0 :     static constexpr Options::String help = {
      68              :         "Radius of the circle circumscribing the inner square."};
      69            0 :     static double lower_bound() { return 0.; }
      70              :   };
      71              : 
      72            0 :   struct OuterRadius {
      73            0 :     using type = double;
      74            0 :     static constexpr Options::String help = {"Radius of the cylinder."};
      75            0 :     static double lower_bound() { return 0.; }
      76              :   };
      77              : 
      78            0 :   struct LowerZBound {
      79            0 :     using type = double;
      80            0 :     static constexpr Options::String help = {
      81              :         "z-coordinate of the base of the cylinder."};
      82              :   };
      83              : 
      84            0 :   struct UpperZBound {
      85            0 :     using type = double;
      86            0 :     static constexpr Options::String help = {
      87              :         "z-coordinate of the top of the cylinder."};
      88              :   };
      89              : 
      90            0 :   struct IsPeriodicInZ {
      91            0 :     using type = bool;
      92            0 :     static constexpr Options::String help = {
      93              :         "True if periodic in the cylindrical z direction."};
      94              :   };
      95              : 
      96            0 :   struct InitialRefinement {
      97            0 :     using type =
      98              :         std::variant<size_t, std::array<size_t, 3>,
      99              :                      std::vector<std::array<size_t, 3>>,
     100              :                      std::unordered_map<std::string, std::array<size_t, 3>>>;
     101            0 :     static constexpr Options::String help = {
     102              :         "Initial refinement level. Specify one of: a single number, a list "
     103              :         "representing [r, theta, z], or such a list for every block in the "
     104              :         "domain. The central cube always uses the value for 'theta' in both "
     105              :         "x- and y-direction."};
     106              :   };
     107              : 
     108            0 :   struct InitialGridPoints {
     109            0 :     using type =
     110              :         std::variant<size_t, std::array<size_t, 3>,
     111              :                      std::vector<std::array<size_t, 3>>,
     112              :                      std::unordered_map<std::string, std::array<size_t, 3>>>;
     113            0 :     static constexpr Options::String help = {
     114              :         "Initial number of grid points. Specify one of: a single number, a "
     115              :         "list representing [r, theta, z], or such a list for every block in "
     116              :         "the domain. The central cube always uses the value for 'theta' in "
     117              :         "both x- and y-direction."};
     118              :   };
     119              : 
     120            0 :   struct UseEquiangularMap {
     121            0 :     using type = bool;
     122            0 :     static constexpr Options::String help = {
     123              :         "Use equiangular instead of equidistant coordinates."};
     124              :   };
     125              : 
     126            0 :   struct RadialPartitioning {
     127            0 :     using type = std::vector<double>;
     128            0 :     static constexpr Options::String help = {
     129              :         "Radial coordinates of the boundaries splitting the outer shell "
     130              :         "between InnerRadius and OuterRadius."};
     131              :   };
     132              : 
     133            0 :   struct PartitioningInZ {
     134            0 :     using type = std::vector<double>;
     135            0 :     static constexpr Options::String help = {
     136              :         "z-coordinates of the boundaries splitting the domain into layers "
     137              :         "between LowerZBound and UpperZBound."};
     138              :   };
     139              : 
     140            0 :   struct RadialDistribution {
     141            0 :     using type = std::vector<domain::CoordinateMaps::Distribution>;
     142            0 :     static constexpr Options::String help = {
     143              :         "Select the radial distribution of grid points in each cylindrical "
     144              :         "shell. The innermost shell must have a 'Linear' distribution because "
     145              :         "it changes in circularity. The 'RadialPartitioning' determines the "
     146              :         "number of shells."};
     147            0 :     static size_t lower_bound_on_size() { return 1; }
     148              :   };
     149              : 
     150            0 :   struct DistributionInZ {
     151            0 :     using type = std::vector<domain::CoordinateMaps::Distribution>;
     152            0 :     static constexpr Options::String help = {
     153              :         "Select the distribution of grid points along the z-axis in each "
     154              :         "layer. The lowermost layer must have a 'Linear' distribution, because "
     155              :         "both a 'Logarithmic' and 'Inverse' distribution places its "
     156              :         "singularity at 'LowerZBound'. The 'PartitioningInZ' determines the "
     157              :         "number of layers."};
     158            0 :     static size_t lower_bound_on_size() { return 1; }
     159              :   };
     160              : 
     161            0 :   struct BoundaryConditions {
     162            0 :     static constexpr Options::String help =
     163              :         "Options for the boundary conditions";
     164              :   };
     165              : 
     166              :   template <typename BoundaryConditionsBase>
     167            0 :   struct LowerZBoundaryCondition {
     168            0 :     using group = BoundaryConditions;
     169            0 :     static std::string name() { return "LowerZ"; }
     170            0 :     static constexpr Options::String help =
     171              :         "The boundary condition to be imposed on the lower base of the "
     172              :         "cylinder, i.e. at the `LowerZBound` in the z-direction.";
     173            0 :     using type = std::unique_ptr<BoundaryConditionsBase>;
     174              :   };
     175              : 
     176              :   template <typename BoundaryConditionsBase>
     177            0 :   struct UpperZBoundaryCondition {
     178            0 :     using group = BoundaryConditions;
     179            0 :     static std::string name() { return "UpperZ"; }
     180            0 :     static constexpr Options::String help =
     181              :         "The boundary condition to be imposed on the upper base of the "
     182              :         "cylinder, i.e. at the `UpperZBound` in the z-direction.";
     183            0 :     using type = std::unique_ptr<BoundaryConditionsBase>;
     184              :   };
     185              : 
     186              :   template <typename BoundaryConditionsBase>
     187            0 :   struct MantleBoundaryCondition {
     188            0 :     using group = BoundaryConditions;
     189            0 :     static std::string name() { return "Mantle"; }
     190            0 :     static constexpr Options::String help =
     191              :         "The boundary condition to be imposed on the mantle of the "
     192              :         "cylinder, i.e. at the `OuterRadius` in the radial direction.";
     193            0 :     using type = std::unique_ptr<BoundaryConditionsBase>;
     194              :   };
     195              : 
     196              :   template <typename Metavariables>
     197            0 :   using options = tmpl::append<
     198              :       tmpl::list<InnerRadius, OuterRadius, LowerZBound, UpperZBound>,
     199              :       tmpl::conditional_t<
     200              :           domain::BoundaryConditions::has_boundary_conditions_base_v<
     201              :               typename Metavariables::system>,
     202              :           tmpl::list<
     203              :               LowerZBoundaryCondition<
     204              :                   domain::BoundaryConditions::get_boundary_conditions_base<
     205              :                       typename Metavariables::system>>,
     206              :               UpperZBoundaryCondition<
     207              :                   domain::BoundaryConditions::get_boundary_conditions_base<
     208              :                       typename Metavariables::system>>,
     209              :               MantleBoundaryCondition<
     210              :                   domain::BoundaryConditions::get_boundary_conditions_base<
     211              :                       typename Metavariables::system>>>,
     212              :           tmpl::list<IsPeriodicInZ>>,
     213              :       tmpl::list<InitialRefinement, InitialGridPoints, UseEquiangularMap,
     214              :                  RadialPartitioning, PartitioningInZ, RadialDistribution,
     215              :                  DistributionInZ>>;
     216              : 
     217            0 :   static constexpr Options::String help{
     218              :       "Creates a right circular Cylinder with a square prism surrounded by \n"
     219              :       "wedges. \n"
     220              :       "The cylinder can be partitioned radially into multiple cylindrical \n"
     221              :       "shells as well as partitioned along the cylinder's height into \n"
     222              :       "multiple layers. Including this partitioning, the number of Blocks is \n"
     223              :       "given by (1 + 4*(1+n_s)) * (1+n_z), where n_s is the \n"
     224              :       "length of RadialPartitioning and n_z the length of \n"
     225              :       "HeightPartitioning. The block numbering starts at the inner square \n"
     226              :       "and goes counter-clockwise, starting with the eastern wedge \n"
     227              :       "(+x-direction) through consecutive shells, then repeats this pattern \n"
     228              :       "for all layers bottom to top. The wedges are named as follows: \n"
     229              :       "  +x-direction: East \n"
     230              :       "  +y-direction: North \n"
     231              :       "  -x-direction: West \n"
     232              :       "  -y-direction: South \n"
     233              :       "The circularity of the wedge changes from 0 to 1 within the first \n"
     234              :       "shell.\n"
     235              :       "Equiangular coordinates give better gridpoint spacings in the angular\n"
     236              :       "direction, while equidistant coordinates give better gridpoint\n"
     237              :       "spacings in the center block."};
     238              : 
     239            0 :   Cylinder(
     240              :       double inner_radius, double outer_radius, double lower_z_bound,
     241              :       double upper_z_bound, bool is_periodic_in_z,
     242              :       const typename InitialRefinement::type& initial_refinement,
     243              :       const typename InitialGridPoints::type& initial_number_of_grid_points,
     244              :       bool use_equiangular_map, std::vector<double> radial_partitioning = {},
     245              :       std::vector<double> partitioning_in_z = {},
     246              :       std::vector<domain::CoordinateMaps::Distribution> radial_distribution =
     247              :           {domain::CoordinateMaps::Distribution::Linear},
     248              :       std::vector<domain::CoordinateMaps::Distribution> distribution_in_z =
     249              :           {domain::CoordinateMaps::Distribution::Linear},
     250              :       const Options::Context& context = {});
     251              : 
     252            0 :   Cylinder(
     253              :       double inner_radius, double outer_radius, double lower_z_bound,
     254              :       double upper_z_bound,
     255              :       std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
     256              :           lower_z_boundary_condition,
     257              :       std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
     258              :           upper_z_boundary_condition,
     259              :       std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
     260              :           mantle_boundary_condition,
     261              :       const typename InitialRefinement::type& initial_refinement,
     262              :       const typename InitialGridPoints::type& initial_number_of_grid_points,
     263              :       bool use_equiangular_map, std::vector<double> radial_partitioning = {},
     264              :       std::vector<double> partitioning_in_z = {},
     265              :       std::vector<domain::CoordinateMaps::Distribution> radial_distribution =
     266              :           {domain::CoordinateMaps::Distribution::Linear},
     267              :       std::vector<domain::CoordinateMaps::Distribution> distribution_in_z =
     268              :           {domain::CoordinateMaps::Distribution::Linear},
     269              :       const Options::Context& context = {});
     270              : 
     271            0 :   Cylinder() = default;
     272            0 :   Cylinder(const Cylinder&) = delete;
     273            0 :   Cylinder(Cylinder&&) = default;
     274            0 :   Cylinder& operator=(const Cylinder&) = delete;
     275            0 :   Cylinder& operator=(Cylinder&&) = default;
     276            0 :   ~Cylinder() override = default;
     277              : 
     278            0 :   Domain<3> create_domain() const override;
     279              : 
     280              :   std::vector<DirectionMap<
     281              :       3, std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>>>
     282            1 :   external_boundary_conditions() const override;
     283              : 
     284            1 :   std::vector<std::array<size_t, 3>> initial_extents() const override;
     285              : 
     286            1 :   std::vector<std::array<size_t, 3>> initial_refinement_levels() const override;
     287              : 
     288            1 :   std::vector<std::string> block_names() const override { return block_names_; }
     289              : 
     290              :   std::unordered_map<std::string, std::unordered_set<std::string>>
     291            1 :   block_groups() const override {
     292              :     return block_groups_;
     293              :   }
     294              : 
     295              :  private:
     296            0 :   double inner_radius_{std::numeric_limits<double>::signaling_NaN()};
     297            0 :   double outer_radius_{std::numeric_limits<double>::signaling_NaN()};
     298            0 :   double lower_z_bound_{std::numeric_limits<double>::signaling_NaN()};
     299            0 :   double upper_z_bound_{std::numeric_limits<double>::signaling_NaN()};
     300            0 :   bool is_periodic_in_z_{true};
     301            0 :   std::vector<std::array<size_t, 3>> initial_refinement_{};
     302            0 :   std::vector<std::array<size_t, 3>> initial_number_of_grid_points_{};
     303            0 :   bool use_equiangular_map_{false};
     304            0 :   std::vector<double> radial_partitioning_{};
     305            0 :   std::vector<double> partitioning_in_z_{};
     306            0 :   std::vector<domain::CoordinateMaps::Distribution> radial_distribution_{};
     307            0 :   std::vector<domain::CoordinateMaps::Distribution> distribution_in_z_{};
     308              :   std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
     309            0 :       lower_z_boundary_condition_{};
     310              :   std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
     311            0 :       upper_z_boundary_condition_{};
     312              :   std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
     313            0 :       mantle_boundary_condition_{};
     314            0 :   std::vector<std::string> block_names_{};
     315              :   std::unordered_map<std::string, std::unordered_set<std::string>>
     316            0 :       block_groups_{};
     317              : };
     318              : }  // namespace domain::creators
        

Generated by: LCOV version 2.0-1