SpECTRE Documentation Coverage Report
Current view: top level - Domain/Creators - CartoonCylinder.hpp Coverage Total Hit
Commit: 0d1d717af84a81fb1284a20c4013708fe85cc2f0 Lines: 9.6 % 73 7
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 <vector>
      12              : 
      13              : #include "Domain/BoundaryConditions/BoundaryCondition.hpp"
      14              : #include "Domain/BoundaryConditions/Cartoon.hpp"
      15              : #include "Domain/BoundaryConditions/GetBoundaryConditionsBase.hpp"
      16              : #include "Domain/CoordinateMaps/Distribution.hpp"
      17              : #include "Domain/Creators/DomainCreator.hpp"
      18              : #include "Domain/Creators/TimeDependence/TimeDependence.hpp"
      19              : #include "Domain/Domain.hpp"
      20              : #include "Domain/Structure/DirectionMap.hpp"
      21              : #include "Options/Context.hpp"
      22              : #include "Options/String.hpp"
      23              : #include "Utilities/TMPL.hpp"
      24              : 
      25              : /// \cond
      26              : namespace domain {
      27              : namespace CoordinateMaps {
      28              : class Interval;
      29              : template <typename Map1, typename Map2, typename Map3>
      30              : class ProductOf3Maps;
      31              : }  // namespace CoordinateMaps
      32              : 
      33              : template <typename SourceFrame, typename TargetFrame, typename... Maps>
      34              : class CoordinateMap;
      35              : }  // namespace domain
      36              : /// \endcond
      37              : 
      38              : namespace domain::creators {
      39              : /// Create a 3D Domain with its computational domain being the\f$x-y\f$
      40              : /// plane. The third dimension uses a Cartoon basis with Killing vector along
      41              : /// the \f$\phi\f$ direction.
      42            1 : class CartoonCylinder : public DomainCreator<3> {
      43              :  public:
      44            0 :   using maps_list = tmpl::list<domain::CoordinateMap<
      45              :       Frame::BlockLogical, Frame::Inertial,
      46              :       CoordinateMaps::ProductOf3Maps<CoordinateMaps::Interval,
      47              :                                      CoordinateMaps::Interval,
      48              :                                      CoordinateMaps::Identity<1>>>>;
      49              : 
      50            0 :   static std::string name() { return "CartoonCylinder"; }
      51              : 
      52            0 :   struct LowerBounds {
      53            0 :     using type = std::array<double, 2>;
      54            0 :     static constexpr Options::String help = {
      55              :         "Lower bound in the [x,y] dimensions. The lower x must be greater than "
      56              :         "or equal to 0. If x=0 is included, the innermost elements use a 1D "
      57              :         "Zernike basis, otherwise the domain will be a cylindrical shell."};
      58              :   };
      59              : 
      60            0 :   struct UpperBounds {
      61            0 :     using type = std::array<double, 2>;
      62            0 :     static constexpr Options::String help = {
      63              :         "Upper bound in the [x,y] dimensions."};
      64              :   };
      65              : 
      66            0 :   struct InitialRefinement {
      67            0 :     using type = std::array<size_t, 2>;
      68            0 :     static constexpr Options::String help = {
      69              :         "Initial refinement level for the [x,y] dimensions."};
      70              :   };
      71              : 
      72            0 :   struct InitialGridPoints {
      73            0 :     using type = std::array<size_t, 2>;
      74            0 :     static constexpr Options::String help = {
      75              :         "Initial number of grid points in the [x,y] dimensions."};
      76              :   };
      77              : 
      78            0 :   struct Distributions {
      79            0 :     using type = std::array<CoordinateMaps::Distribution, 2>;
      80            0 :     static constexpr Options::String help = {
      81              :         "Distribution of grid points in the [x,y] dimensions."};
      82              :   };
      83              : 
      84              :   template <typename BoundaryConditionsBase>
      85            0 :   struct LowerUpperBoundaryCondition {
      86            0 :     static constexpr Options::String help =
      87              :         "Lower and upper Boundary Conditions";
      88            0 :     struct LowerBC {
      89            0 :       using type = std::unique_ptr<BoundaryConditionsBase>;
      90            0 :       static constexpr Options::String help = "Lower Boundary Condition";
      91            0 :       static std::string name() { return "Lower"; };
      92              :     };
      93            0 :     struct UpperBC {
      94            0 :       using type = std::unique_ptr<BoundaryConditionsBase>;
      95            0 :       static constexpr Options::String help = "Upper Boundary Condition";
      96            0 :       static std::string name() { return "Upper"; };
      97              :     };
      98            0 :     LowerUpperBoundaryCondition(typename LowerBC::type lower_bc,
      99              :                                 typename UpperBC::type upper_bc)
     100              :         : lower(std::move(lower_bc)), upper(std::move(upper_bc)){};
     101            0 :     LowerUpperBoundaryCondition() = default;
     102            0 :     std::unique_ptr<BoundaryConditionsBase> lower;
     103            0 :     std::unique_ptr<BoundaryConditionsBase> upper;
     104            0 :     using options = tmpl::list<LowerBC, UpperBC>;
     105              :   };
     106              : 
     107              :   template <typename BoundaryConditionsBase>
     108            0 :   struct BoundaryConditions {
     109            0 :     static constexpr Options::String help = {
     110              :         "The boundary conditions to be imposed in the x & y dimensions. "
     111              :         "Either specify one B.C. to be imposed for both "
     112              :         "lower and upper boundary or a pair 'Lower:' and 'Upper:'."};
     113            0 :     using type = std::array<
     114              :         std::variant<std::unique_ptr<BoundaryConditionsBase>,
     115              :                      LowerUpperBoundaryCondition<BoundaryConditionsBase>>,
     116              :         2>;
     117              :   };
     118              : 
     119            0 :   struct TimeDependence {
     120            0 :     using type =
     121              :         std::unique_ptr<domain::creators::time_dependence::TimeDependence<3>>;
     122            0 :     static constexpr Options::String help = {
     123              :         "The time dependence of the moving mesh domain. Specify `None` for no "
     124              :         "time dependant maps."};
     125              :   };
     126              : 
     127            0 :   using basic_options =
     128              :       tmpl::list<LowerBounds, UpperBounds, InitialRefinement, InitialGridPoints,
     129              :                  Distributions, TimeDependence>;
     130              : 
     131              :   template <typename Metavariables>
     132            0 :   using options = tmpl::conditional_t<
     133              :       domain::BoundaryConditions::has_boundary_conditions_base_v<
     134              :           typename Metavariables::system>,
     135              :       tmpl::push_back<
     136              :           basic_options,
     137              :           BoundaryConditions<
     138              :               domain::BoundaryConditions::get_boundary_conditions_base<
     139              :                   typename Metavariables::system>>>,
     140              :       basic_options>;
     141              : 
     142            0 :   static constexpr Options::String help{
     143              :       "A cylinder domain that requires/enforces axial symmetry. The "
     144              :       "computational domain is the x-y plane, with Cartoon partial derivatives "
     145              :       "being used for the z direction. Elements touching the x=0 axis use "
     146              :       "ZernikeB1 bases in the x direction and automatically apply a system's "
     147              :       "Cartoon-type boundary condition."};
     148              : 
     149            0 :   CartoonCylinder(
     150              :       std::array<double, 2> lower_bounds, std::array<double, 2> upper_bounds,
     151              :       std::array<size_t, 2> initial_refinement_levels,
     152              :       std::array<size_t, 2> initial_num_points,
     153              :       std::array<CoordinateMaps::Distribution, 2> distributions = {},
     154              :       std::unique_ptr<domain::creators::time_dependence::TimeDependence<3>>
     155              :           time_dependence = nullptr,
     156              :       std::array<std::array<std::unique_ptr<
     157              :                                 domain::BoundaryConditions::BoundaryCondition>,
     158              :                             2>,
     159              :                  2>
     160              :           boundary_conditions = {},
     161              :       std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
     162              :           cartoon_boundary_condition = nullptr,
     163              :       const Options::Context& context = {});
     164              : 
     165            0 :   CartoonCylinder() = default;
     166            0 :   CartoonCylinder(const CartoonCylinder&) = delete;
     167            0 :   CartoonCylinder(CartoonCylinder&&) = default;
     168            0 :   CartoonCylinder& operator=(const CartoonCylinder&) = delete;
     169            0 :   CartoonCylinder& operator=(CartoonCylinder&&) = default;
     170            0 :   ~CartoonCylinder() override = default;
     171              : 
     172            0 :   Domain<3> create_domain() const override;
     173              : 
     174              :   std::vector<DirectionMap<
     175              :       3, std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>>>
     176            1 :   external_boundary_conditions() const override;
     177              : 
     178            1 :   std::vector<std::array<size_t, 3>> initial_extents() const override;
     179              : 
     180            1 :   std::vector<std::array<size_t, 3>> initial_refinement_levels() const override;
     181              : 
     182              :   /// The only block is Block0
     183            1 :   std::vector<std::string> block_names() const override;
     184              : 
     185              :   /// The only group is CartoonCylinder
     186              :   std::unordered_map<std::string, std::unordered_set<std::string>>
     187            1 :   block_groups() const override;
     188              : 
     189            1 :   auto functions_of_time(const std::unordered_map<std::string, double>&
     190              :                              initial_expiration_times = {}) const
     191              :       -> std::unordered_map<
     192              :           std::string,
     193              :           std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>> override;
     194              : 
     195              :   // Transforms from option-created boundary conditions to the type used in the
     196              :   // constructor
     197              :   template <typename BoundaryConditionsBase>
     198            0 :   static auto transform_boundary_conditions(
     199              :       std::array<
     200              :           std::variant<std::unique_ptr<BoundaryConditionsBase>,
     201              :                        LowerUpperBoundaryCondition<BoundaryConditionsBase>>,
     202              :           2>
     203              :           boundary_conditions)
     204              :       -> std::array<
     205              :           std::array<
     206              :               std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>,
     207              :               2>,
     208              :           2>;
     209              : 
     210              :  private:
     211            0 :   std::array<double, 2> lower_bounds_{};
     212            0 :   std::array<double, 2> upper_bounds_{};
     213            0 :   std::array<size_t, 2> initial_refinement_levels_{};
     214            0 :   std::array<size_t, 2> initial_num_points_{};
     215            0 :   bool is_periodic_in_y_{};
     216            0 :   std::array<CoordinateMaps::Distribution, 2> distributions_{};
     217            0 :   bool using_zernike_{};
     218              :   std::array<
     219              :       std::array<std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>,
     220              :                  2>,
     221              :       2>
     222            0 :       boundary_conditions_{};
     223              :   std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
     224            0 :       cartoon_boundary_condition_{};
     225              :   std::unique_ptr<domain::creators::time_dependence::TimeDependence<3>>
     226            0 :       time_dependence_;
     227            0 :   size_t num_blocks_{};
     228            0 :   std::vector<std::string> block_names_{};
     229              :   std::unordered_map<std::string, std::unordered_set<std::string>>
     230            0 :       block_groups_{};
     231              : };
     232              : 
     233              : template <typename BoundaryConditionsBase>
     234              : auto CartoonCylinder::transform_boundary_conditions(
     235              :     std::array<
     236              :         std::variant<std::unique_ptr<BoundaryConditionsBase>,
     237              :                      LowerUpperBoundaryCondition<BoundaryConditionsBase>>,
     238              :         2>
     239              :         boundary_conditions)
     240              :     -> std::array<
     241              :         std::array<
     242              :             std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>, 2>,
     243              :         2> {
     244              :   std::array<
     245              :       std::array<std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>,
     246              :                  2>,
     247              :       2>
     248              :       result{};
     249              :   for (size_t d = 0; d < 2; ++d) {
     250              :     if (std::holds_alternative<std::unique_ptr<BoundaryConditionsBase>>(
     251              :             boundary_conditions[d])) {
     252              :       auto bc = std::move(std::get<std::unique_ptr<BoundaryConditionsBase>>(
     253              :           boundary_conditions[d]));
     254              :       gsl::at(gsl::at(result, d), 0) = bc->get_clone();
     255              :       gsl::at(gsl::at(result, d), 1) = std::move(bc);
     256              :     } else {
     257              :       auto& bc = std::get<LowerUpperBoundaryCondition<BoundaryConditionsBase>>(
     258              :           boundary_conditions[d]);
     259              :       gsl::at(gsl::at(result, d), 0) = std::move(bc.lower);
     260              :       gsl::at(gsl::at(result, d), 1) = std::move(bc.upper);
     261              :     }
     262              :   }
     263              :   return result;
     264              : }
     265              : 
     266              : }  // namespace domain::creators
     267              : 
     268              : namespace domain::creators::detail {
     269              : /// \brief Helper struct for CartoonCylinder options parsing so the internal
     270              : /// cartoon boundary condition at $x = 0$ is not a required argument.
     271              : ///
     272              : /// \details To get the cartoon-type boundary condition from a system we need
     273              : /// access to the system's metavariables, which is only present when parsing
     274              : /// options. The point of this design is so that the input file does not
     275              : /// require a dummy value for an InnerBoundaryCondition that is always the
     276              : /// same for a given system.
     277              : ///
     278              : /// This helper's constructor does not take an InnerBoundaryCondition, which
     279              : /// means if we parse a CartoonCylinder as a CartonSphere2DOptionsHelper
     280              : /// by having an options parsing specialization (so the input file values are
     281              : /// the helper's construtor, not CartoonCylinder's), we can detect the
     282              : /// cartoon-type boundary condition for the given system and only then call
     283              : /// the CartoonCylinder constructor with the extra information.
     284              : struct CartoonCylinderOptionsHelper {
     285              :   template <typename Metavariables>
     286              :   using options = typename domain::creators::CartoonCylinder::template options<
     287              :       Metavariables>;
     288              : 
     289              :   template <typename BoundaryConditionsBase>
     290              :   using LowerUpperBoundaryCondition =
     291              :       domain::creators::CartoonCylinder::LowerUpperBoundaryCondition<
     292              :           BoundaryConditionsBase>;
     293              : 
     294              :   static constexpr Options::String help = {"CartoonCylinderOptionsHelper"};
     295              : 
     296              :   // Default constructor required by Options system
     297              :   CartoonCylinderOptionsHelper() = default;
     298              : 
     299              :   // Does not take cartoon BC
     300              :   CartoonCylinderOptionsHelper(
     301              :       std::array<double, 2> lower_bounds, std::array<double, 2> upper_bounds,
     302              :       std::array<size_t, 2> initial_refinement_levels,
     303              :       std::array<size_t, 2> initial_num_points,
     304              :       std::array<CoordinateMaps::Distribution, 2> distributions,
     305              :       std::unique_ptr<domain::creators::time_dependence::TimeDependence<3>>
     306              :           time_dependence = nullptr,
     307              :       std::array<std::array<std::unique_ptr<
     308              :                                 domain::BoundaryConditions::BoundaryCondition>,
     309              :                             2>,
     310              :                  2>
     311              :           boundary_conditions = {},
     312              :       Options::Context context = {});
     313              : 
     314              :   template <typename BoundaryConditionsBase>
     315              :   CartoonCylinderOptionsHelper(
     316              :       std::array<double, 2> lower_bounds, std::array<double, 2> upper_bounds,
     317              :       std::array<size_t, 2> initial_refinement_levels,
     318              :       std::array<size_t, 2> initial_num_points,
     319              :       std::array<CoordinateMaps::Distribution, 2> distributions,
     320              :       std::unique_ptr<domain::creators::time_dependence::TimeDependence<3>>
     321              :           time_dependence = nullptr,
     322              :       std::array<
     323              :           std::variant<std::unique_ptr<BoundaryConditionsBase>,
     324              :                        LowerUpperBoundaryCondition<BoundaryConditionsBase>>,
     325              :           2>
     326              :           boundary_conditions = {},
     327              :       Options::Context context = {})
     328              :       : CartoonCylinderOptionsHelper(
     329              :             std::move(lower_bounds), std::move(upper_bounds),
     330              :             std::move(initial_refinement_levels), std::move(initial_num_points),
     331              :             std::move(distributions), std::move(time_dependence),
     332              :             domain::creators::CartoonCylinder::transform_boundary_conditions(
     333              :                 std::move(boundary_conditions)),
     334              :             std::move(context)) {}
     335              :   // Same members as in CartoonCylinder; public, to be extracted
     336              :   std::array<double, 2> lower_bounds_{};
     337              :   std::array<double, 2> upper_bounds_{};
     338              :   std::array<size_t, 2> initial_refinement_levels_{};
     339              :   std::array<size_t, 2> initial_num_points_{};
     340              :   std::array<CoordinateMaps::Distribution, 2> distributions_{};
     341              :   std::unique_ptr<domain::creators::time_dependence::TimeDependence<3>>
     342              :       time_dependence_{nullptr};
     343              :   std::array<
     344              :       std::array<std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>,
     345              :                  2>,
     346              :       2>
     347              :       boundary_conditions_{};
     348              :   Options::Context context_{};
     349              : };
     350              : }  // namespace domain::creators::detail
     351              : 
     352              : // Options parsing specialization to automate CartoonCylinder's cartoon
     353              : // boundary condition
     354              : template <>
     355            0 : struct Options::create_from_yaml<domain::creators::CartoonCylinder> {
     356              :   template <typename Metavariables>
     357            0 :   static domain::creators::CartoonCylinder create(
     358              :       const Options::Option& options) {
     359              :     auto helper =
     360              :         options.parse_as<domain::creators::detail::CartoonCylinderOptionsHelper,
     361              :                          Metavariables>();
     362              : 
     363              :     // Create cartoon BC if system supports it, if not will throw parse error in
     364              :     // real constructor
     365              :     std::unique_ptr<domain::BoundaryConditions::BoundaryCondition>
     366              :         cartoon_boundary_condition = nullptr;
     367              :     if constexpr (domain::BoundaryConditions::has_boundary_conditions_base_v<
     368              :                       typename Metavariables::system>) {
     369              :       if constexpr (domain::BoundaryConditions::system_has_cartoon_bc_v<
     370              :                         Metavariables>) {
     371              :         cartoon_boundary_condition =
     372              :             domain::BoundaryConditions::make_cartoon_boundary_condition<
     373              :                 Metavariables>();
     374              :       }
     375              :     }
     376              : 
     377              :     // Construct CartoonCylinder using the helper's parsed data + cartoon BC
     378              :     return domain::creators::CartoonCylinder(
     379              :         helper.lower_bounds_, helper.upper_bounds_,
     380              :         helper.initial_refinement_levels_, helper.initial_num_points_,
     381              :         helper.distributions_, std::move(helper.time_dependence_),
     382              :         std::move(helper.boundary_conditions_),
     383              :         std::move(cartoon_boundary_condition), helper.context_);
     384              :   }
     385              : };
        

Generated by: LCOV version 2.0-1