SpECTRE Documentation Coverage Report
Current view: top level - Domain/CoordinateMaps - CoordinateMap.hpp Hit Total Coverage
Commit: 923cd4a8ea30f5a5589baa60b0a93e358ca9f8e8 Lines: 39 82 47.6 %
Date: 2025-11-07 19:37:56
Legend: Lines: hit not hit

          Line data    Source code
       1           1 : // Distributed under the MIT License.
       2             : // See LICENSE.txt for details.
       3             : 
       4             : /// \file
       5             : /// Defines class CoordinateMap
       6             : 
       7             : #pragma once
       8             : 
       9             : #include <cstddef>
      10             : #include <limits>
      11             : #include <memory>
      12             : #include <optional>
      13             : #include <pup.h>
      14             : #include <string>
      15             : #include <tuple>
      16             : #include <type_traits>
      17             : #include <typeinfo>
      18             : #include <unordered_map>
      19             : #include <unordered_set>
      20             : #include <utility>
      21             : #include <vector>
      22             : 
      23             : #include "DataStructures/Tensor/Tensor.hpp"
      24             : #include "Domain/FunctionsOfTime/FunctionOfTime.hpp"
      25             : #include "Utilities/Serialization/CharmPupable.hpp"
      26             : #include "Utilities/TMPL.hpp"
      27             : #include "Utilities/TypeTraits/CreateIsCallable.hpp"
      28             : 
      29             : /// \cond
      30             : class DataVector;
      31             : /// \endcond
      32             : 
      33             : namespace domain {
      34             : /// Contains all coordinate maps.
      35             : namespace CoordinateMaps {
      36             : /// Contains the time-dependent coordinate maps
      37           1 : namespace TimeDependent {}
      38             : template <typename FirstMap, typename... Maps>
      39           0 : constexpr size_t map_dim = FirstMap::dim;
      40             : }  // namespace CoordinateMaps
      41             : 
      42             : namespace CoordinateMap_detail {
      43             : CREATE_IS_CALLABLE(function_of_time_names)
      44             : CREATE_IS_CALLABLE_V(function_of_time_names)
      45             : 
      46             : template <typename T>
      47             : struct map_type {
      48             :   using type = T;
      49             : };
      50             : 
      51             : template <typename T>
      52             : struct map_type<std::unique_ptr<T>> {
      53             :   using type = T;
      54             : };
      55             : 
      56             : template <typename T>
      57             : using map_type_t = typename map_type<T>::type;
      58             : 
      59             : template <typename... Maps, size_t... Is>
      60             : std::unordered_set<std::string> initialize_names(
      61             :     const std::tuple<Maps...>& maps, std::index_sequence<Is...> /*meta*/) {
      62             :   std::unordered_set<std::string> function_of_time_names{};
      63             :   const auto add_names = [&function_of_time_names, &maps](auto index) {
      64             :     const auto& map = std::get<decltype(index)::value>(maps);
      65             :     using TupleMap = std::decay_t<decltype(map)>;
      66             :     constexpr bool map_is_unique_ptr = tt::is_a_v<std::unique_ptr, TupleMap>;
      67             :     using Map = map_type_t<TupleMap>;
      68             :     if constexpr (is_function_of_time_names_callable_v<Map>) {
      69             :       if constexpr (map_is_unique_ptr) {
      70             :         const auto& names = map->function_of_time_names();
      71             :         function_of_time_names.insert(names.begin(), names.end());
      72             :       } else {
      73             :         const auto& names = map.function_of_time_names();
      74             :         function_of_time_names.insert(names.begin(), names.end());
      75             :       }
      76             :     } else {
      77             :       (void)function_of_time_names;
      78             :     }
      79             :   };
      80             :   EXPAND_PACK_LEFT_TO_RIGHT(add_names(std::integral_constant<size_t, Is>{}));
      81             : 
      82             :   return function_of_time_names;
      83             : }
      84             : }  // namespace CoordinateMap_detail
      85             : 
      86             : /*!
      87             :  * \ingroup CoordinateMapsGroup
      88             :  * \brief Abstract base class for CoordinateMap
      89             :  */
      90             : template <typename SourceFrame, typename TargetFrame, size_t Dim>
      91           1 : class CoordinateMapBase : public PUP::able {
      92             :  public:
      93           0 :   static constexpr size_t dim = Dim;
      94           0 :   using source_frame = SourceFrame;
      95           0 :   using target_frame = TargetFrame;
      96             : 
      97           0 :   WRAPPED_PUPable_abstract(CoordinateMapBase);  // NOLINT
      98             : 
      99           0 :   CoordinateMapBase() = default;
     100           0 :   CoordinateMapBase(const CoordinateMapBase& /*rhs*/) = default;
     101           0 :   CoordinateMapBase& operator=(const CoordinateMapBase& /*rhs*/) = default;
     102           0 :   CoordinateMapBase(CoordinateMapBase&& /*rhs*/) = default;
     103           0 :   CoordinateMapBase& operator=(CoordinateMapBase&& /*rhs*/) = default;
     104           0 :   ~CoordinateMapBase() override = default;
     105             : 
     106             :   virtual std::unique_ptr<CoordinateMapBase<SourceFrame, TargetFrame, Dim>>
     107           0 :   get_clone() const = 0;
     108             : 
     109             :   /// \brief Retrieve the same map but going from `SourceFrame` to
     110             :   /// `Frame::Grid`.
     111             :   ///
     112             :   /// This functionality is needed when composing time-dependent maps with
     113             :   /// time-independent maps, where the target frame of the time-independent map
     114             :   /// is `Frame::Grid`.
     115             :   virtual std::unique_ptr<CoordinateMapBase<SourceFrame, Frame::Grid, Dim>>
     116           1 :   get_to_grid_frame() const = 0;
     117             : 
     118             :   /// Returns `true` if the map is the identity
     119           1 :   virtual bool is_identity() const = 0;
     120             : 
     121             :   /// Returns `true` if the inverse Jacobian depends on time.
     122           1 :   virtual bool inv_jacobian_is_time_dependent() const = 0;
     123             : 
     124             :   /// Returns `true` if the Jacobian depends on time.
     125           1 :   virtual bool jacobian_is_time_dependent() const = 0;
     126             : 
     127             :   /// Get a set of all FunctionOfTime names used in this mapping
     128           1 :   virtual const std::unordered_set<std::string>& function_of_time_names()
     129             :       const = 0;
     130             : 
     131             :   /// @{
     132             :   /// Apply the `Maps` to the point(s) `source_point`
     133           1 :   virtual tnsr::I<double, Dim, TargetFrame> operator()(
     134             :       tnsr::I<double, Dim, SourceFrame> source_point,
     135             :       double time = std::numeric_limits<double>::signaling_NaN(),
     136             :       const FunctionsOfTimeMap& functions_of_time = {}) const = 0;
     137           1 :   virtual tnsr::I<DataVector, Dim, TargetFrame> operator()(
     138             :       tnsr::I<DataVector, Dim, SourceFrame> source_point,
     139             :       double time = std::numeric_limits<double>::signaling_NaN(),
     140             :       const FunctionsOfTimeMap& functions_of_time = {}) const = 0;
     141             :   /// @}
     142             : 
     143             :   /// @{
     144             :   /// Apply the inverse `Maps` to the point(s) `target_point`.
     145             :   /// The returned std::optional is invalid if the map is not invertible
     146             :   /// at `target_point`, or if `target_point` can be easily determined to not
     147             :   /// make sense for the map.  An example of the latter is passing a
     148             :   /// point with a negative value of z into a positive-z Wedge<3> inverse map.
     149             :   /// The inverse function is only callable with doubles because the inverse
     150             :   /// might fail if called for a point out of range, and it is unclear
     151             :   /// what should happen if the inverse were to succeed for some points in a
     152             :   /// DataVector but fail for other points.
     153           1 :   virtual std::optional<tnsr::I<double, Dim, SourceFrame>> inverse(
     154             :       tnsr::I<double, Dim, TargetFrame> target_point,
     155             :       double time = std::numeric_limits<double>::signaling_NaN(),
     156             :       const FunctionsOfTimeMap& functions_of_time = {}) const = 0;
     157             :   /// @}
     158             : 
     159             :   /// @{
     160             :   /// Compute the inverse Jacobian of the `Maps` at the point(s)
     161             :   /// `source_point`
     162           1 :   virtual InverseJacobian<double, Dim, SourceFrame, TargetFrame> inv_jacobian(
     163             :       tnsr::I<double, Dim, SourceFrame> source_point,
     164             :       double time = std::numeric_limits<double>::signaling_NaN(),
     165             :       const FunctionsOfTimeMap& functions_of_time = {}) const = 0;
     166             :   virtual InverseJacobian<DataVector, Dim, SourceFrame, TargetFrame>
     167           1 :   inv_jacobian(tnsr::I<DataVector, Dim, SourceFrame> source_point,
     168             :                double time = std::numeric_limits<double>::signaling_NaN(),
     169             :                const FunctionsOfTimeMap& functions_of_time = {}) const = 0;
     170             :   /// @}
     171             : 
     172             :   /// @{
     173             :   /// Compute the Jacobian of the `Maps` at the point(s) `source_point`
     174           1 :   virtual Jacobian<double, Dim, SourceFrame, TargetFrame> jacobian(
     175             :       tnsr::I<double, Dim, SourceFrame> source_point,
     176             :       double time = std::numeric_limits<double>::signaling_NaN(),
     177             :       const FunctionsOfTimeMap& functions_of_time = {}) const = 0;
     178           1 :   virtual Jacobian<DataVector, Dim, SourceFrame, TargetFrame> jacobian(
     179             :       tnsr::I<DataVector, Dim, SourceFrame> source_point,
     180             :       double time = std::numeric_limits<double>::signaling_NaN(),
     181             :       const FunctionsOfTimeMap& functions_of_time = {}) const = 0;
     182             :   /// @}
     183             : 
     184             :   /// @{
     185             :   /// Compute the mapped coordinates, frame velocity, Jacobian, and inverse
     186             :   /// Jacobian
     187             :   virtual std::tuple<tnsr::I<double, Dim, TargetFrame>,
     188             :                      InverseJacobian<double, Dim, SourceFrame, TargetFrame>,
     189             :                      Jacobian<double, Dim, SourceFrame, TargetFrame>,
     190             :                      tnsr::I<double, Dim, TargetFrame>>
     191           1 :   coords_frame_velocity_jacobians(
     192             :       tnsr::I<double, Dim, SourceFrame> source_point,
     193             :       double time = std::numeric_limits<double>::signaling_NaN(),
     194             :       const FunctionsOfTimeMap& functions_of_time = {}) const = 0;
     195             :   virtual std::tuple<tnsr::I<DataVector, Dim, TargetFrame>,
     196             :                      InverseJacobian<DataVector, Dim, SourceFrame, TargetFrame>,
     197             :                      Jacobian<DataVector, Dim, SourceFrame, TargetFrame>,
     198             :                      tnsr::I<DataVector, Dim, TargetFrame>>
     199           1 :   coords_frame_velocity_jacobians(
     200             :       tnsr::I<DataVector, Dim, SourceFrame> source_point,
     201             :       double time = std::numeric_limits<double>::signaling_NaN(),
     202             :       const FunctionsOfTimeMap& functions_of_time = {}) const = 0;
     203             :   /// @}
     204             : 
     205             :  private:
     206           0 :   virtual bool is_equal_to(const CoordinateMapBase& other) const = 0;
     207           0 :   friend bool operator==(const CoordinateMapBase& lhs,
     208             :                          const CoordinateMapBase& rhs) {
     209             :     return typeid(lhs) == typeid(rhs) and lhs.is_equal_to(rhs);
     210             :   }
     211           0 :   friend bool operator!=(const CoordinateMapBase& lhs,
     212             :                          const CoordinateMapBase& rhs) {
     213             :     return not(lhs == rhs);
     214             :   }
     215             : };
     216             : 
     217             : /*!
     218             :  * \ingroup CoordinateMapsGroup
     219             :  * \brief A coordinate map or composition of coordinate maps
     220             :  *
     221             :  * Maps coordinates from the `SourceFrame` to the `TargetFrame` using the
     222             :  * coordinate maps `Maps...`. The individual maps are applied left to right
     223             :  * from the source to the target Frame. The inverse map, as well as Jacobian
     224             :  * and inverse Jacobian are also provided. The `CoordinateMap` class must
     225             :  * be used even if just wrapping a single coordinate map. It is designed to
     226             :  * be an extremely minimal interface to the underlying coordinate maps. For
     227             :  * a list of all coordinate maps see the CoordinateMaps group or namespace.
     228             :  *
     229             :  * Each coordinate map must contain a `static constexpr size_t dim` variable
     230             :  * that is equal to the dimensionality of the map. The Coordinatemap class
     231             :  * contains a member `static constexpr size_t dim`, a type alias `source_frame`,
     232             :  * a type alias `target_frame` and `typelist of the `Maps...`.
     233             :  */
     234             : template <typename SourceFrame, typename TargetFrame, typename... Maps>
     235           1 : class CoordinateMap
     236             :     : public CoordinateMapBase<SourceFrame, TargetFrame,
     237             :                                CoordinateMaps::map_dim<Maps...>> {
     238             :   static_assert(sizeof...(Maps) > 0, "Must have at least one map");
     239             :   static_assert(
     240             :       tmpl::all<tmpl::integral_list<size_t, Maps::dim...>,
     241             :                 std::is_same<tmpl::integral_constant<
     242             :                                  size_t, CoordinateMaps::map_dim<Maps...>>,
     243             :                              tmpl::_1>>::value,
     244             :       "All Maps passed to CoordinateMap must be of the same dimensionality.");
     245             : 
     246             :  public:
     247           0 :   static constexpr size_t dim = CoordinateMaps::map_dim<Maps...>;
     248           0 :   using source_frame = SourceFrame;
     249           0 :   using target_frame = TargetFrame;
     250           0 :   using maps_list = tmpl::list<Maps...>;
     251             : 
     252             :   /// Used for Charm++ serialization
     253           1 :   CoordinateMap() = default;
     254             : 
     255           0 :   CoordinateMap(const CoordinateMap& /*rhs*/) = default;
     256           0 :   CoordinateMap& operator=(const CoordinateMap& /*rhs*/) = default;
     257           0 :   CoordinateMap(CoordinateMap&& /*rhs*/) = default;
     258           0 :   CoordinateMap& operator=(CoordinateMap&& /*rhs*/) = default;
     259           0 :   ~CoordinateMap() override = default;
     260             : 
     261           0 :   explicit CoordinateMap(Maps... maps);
     262             : 
     263           0 :   std::unique_ptr<CoordinateMapBase<SourceFrame, TargetFrame, dim>> get_clone()
     264             :       const override {
     265             :     return std::make_unique<CoordinateMap>(*this);
     266             :   }
     267             : 
     268             :   std::unique_ptr<CoordinateMapBase<SourceFrame, Frame::Grid, dim>>
     269           1 :   get_to_grid_frame() const override {
     270             :     return get_to_grid_frame_impl(std::make_index_sequence<sizeof...(Maps)>{});
     271             :   }
     272             : 
     273             :   /// Returns `true` if the map is the identity
     274           1 :   bool is_identity() const override;
     275             : 
     276             :   /// Returns `true` if the inverse Jacobian depends on time.
     277           1 :   bool inv_jacobian_is_time_dependent() const override;
     278             : 
     279             :   /// Returns `true` if the Jacobian depends on time.
     280           1 :   bool jacobian_is_time_dependent() const override;
     281             : 
     282             :   /// Get a set of all FunctionOfTime names from `Maps`
     283           1 :   const std::unordered_set<std::string>& function_of_time_names()
     284             :       const override {
     285             :     return function_of_time_names_;
     286             :   }
     287             : 
     288             :   /// @{
     289             :   /// Apply the `Maps...` to the point(s) `source_point`
     290           1 :   tnsr::I<double, dim, TargetFrame> operator()(
     291             :       tnsr::I<double, dim, SourceFrame> source_point,
     292             :       const double time = std::numeric_limits<double>::signaling_NaN(),
     293             :       const FunctionsOfTimeMap& functions_of_time = {}) const override {
     294             :     return call_impl(std::move(source_point), time, functions_of_time,
     295             :                      std::make_index_sequence<sizeof...(Maps)>{});
     296             :   }
     297           1 :   tnsr::I<DataVector, dim, TargetFrame> operator()(
     298             :       tnsr::I<DataVector, dim, SourceFrame> source_point,
     299             :       const double time = std::numeric_limits<double>::signaling_NaN(),
     300             :       const FunctionsOfTimeMap& functions_of_time = {}) const override {
     301             :     return call_impl(std::move(source_point), time, functions_of_time,
     302             :                      std::make_index_sequence<sizeof...(Maps)>{});
     303             :   }
     304             :   /// @}
     305             : 
     306             :   /// @{
     307             :   /// Apply the inverse `Maps...` to the point(s) `target_point`
     308           1 :   std::optional<tnsr::I<double, dim, SourceFrame>> inverse(
     309             :       tnsr::I<double, dim, TargetFrame> target_point,
     310             :       const double time = std::numeric_limits<double>::signaling_NaN(),
     311             :       const FunctionsOfTimeMap& functions_of_time = {}) const override {
     312             :     return inverse_impl(std::move(target_point), time, functions_of_time,
     313             :                         std::make_index_sequence<sizeof...(Maps)>{});
     314             :   }
     315             :   /// @}
     316             : 
     317             :   /// @{
     318             :   /// Compute the inverse Jacobian of the `Maps...` at the point(s)
     319             :   /// `source_point`
     320           1 :   InverseJacobian<double, dim, SourceFrame, TargetFrame> inv_jacobian(
     321             :       tnsr::I<double, dim, SourceFrame> source_point,
     322             :       const double time = std::numeric_limits<double>::signaling_NaN(),
     323             :       const FunctionsOfTimeMap& functions_of_time = {}) const override {
     324             :     return inv_jacobian_impl(std::move(source_point), time, functions_of_time);
     325             :   }
     326           1 :   InverseJacobian<DataVector, dim, SourceFrame, TargetFrame> inv_jacobian(
     327             :       tnsr::I<DataVector, dim, SourceFrame> source_point,
     328             :       const double time = std::numeric_limits<double>::signaling_NaN(),
     329             :       const FunctionsOfTimeMap& functions_of_time = {}) const override {
     330             :     return inv_jacobian_impl(std::move(source_point), time, functions_of_time);
     331             :   }
     332             :   /// @}
     333             : 
     334             :   /// @{
     335             :   /// Compute the Jacobian of the `Maps...` at the point(s) `source_point`
     336           1 :   Jacobian<double, dim, SourceFrame, TargetFrame> jacobian(
     337             :       tnsr::I<double, dim, SourceFrame> source_point,
     338             :       const double time = std::numeric_limits<double>::signaling_NaN(),
     339             :       const FunctionsOfTimeMap& functions_of_time = {}) const override {
     340             :     return jacobian_impl(std::move(source_point), time, functions_of_time);
     341             :   }
     342           1 :   Jacobian<DataVector, dim, SourceFrame, TargetFrame> jacobian(
     343             :       tnsr::I<DataVector, dim, SourceFrame> source_point,
     344             :       const double time = std::numeric_limits<double>::signaling_NaN(),
     345             :       const FunctionsOfTimeMap& functions_of_time = {}) const override {
     346             :     return jacobian_impl(std::move(source_point), time, functions_of_time);
     347             :   }
     348             :   /// @}
     349             : 
     350             :   /// @{
     351             :   /// Compute the mapped coordinates, frame velocity, Jacobian, and inverse
     352             :   /// Jacobian. The inverse Jacobian is computed by numerically inverting the
     353             :   /// Jacobian as this was measured to be quicker than computing it directly for
     354             :   /// more complex map concatenations.
     355             :   std::tuple<tnsr::I<double, dim, TargetFrame>,
     356             :              InverseJacobian<double, dim, SourceFrame, TargetFrame>,
     357             :              Jacobian<double, dim, SourceFrame, TargetFrame>,
     358             :              tnsr::I<double, dim, TargetFrame>>
     359           1 :   coords_frame_velocity_jacobians(
     360             :       tnsr::I<double, dim, SourceFrame> source_point,
     361             :       const double time = std::numeric_limits<double>::signaling_NaN(),
     362             :       const FunctionsOfTimeMap& functions_of_time = {}) const override {
     363             :     return coords_frame_velocity_jacobians_impl(std::move(source_point), time,
     364             :                                                 functions_of_time);
     365             :   }
     366             :   std::tuple<tnsr::I<DataVector, dim, TargetFrame>,
     367             :              InverseJacobian<DataVector, dim, SourceFrame, TargetFrame>,
     368             :              Jacobian<DataVector, dim, SourceFrame, TargetFrame>,
     369             :              tnsr::I<DataVector, dim, TargetFrame>>
     370           1 :   coords_frame_velocity_jacobians(
     371             :       tnsr::I<DataVector, dim, SourceFrame> source_point,
     372             :       const double time = std::numeric_limits<double>::signaling_NaN(),
     373             :       const FunctionsOfTimeMap& functions_of_time = {}) const override {
     374             :     return coords_frame_velocity_jacobians_impl(std::move(source_point), time,
     375             :                                                 functions_of_time);
     376             :   }
     377             :   /// @}
     378             : 
     379           0 :   WRAPPED_PUPable_decl_base_template(  // NOLINT
     380             :       SINGLE_ARG(CoordinateMapBase<SourceFrame, TargetFrame, dim>),
     381             :       CoordinateMap);
     382             : 
     383           0 :   explicit CoordinateMap(CkMigrateMessage* /*unused*/) {}
     384             : 
     385             :   // NOLINTNEXTLINE(google-runtime-references)
     386           0 :   void pup(PUP::er& p) override {
     387             :     size_t version = 0;
     388             :     p | version;
     389             :     // Remember to increment the version number when making changes to this
     390             :     // function. Retain support for unpacking data written by previous versions
     391             :     // whenever possible. See `Domain` docs for details.
     392             :     if (version >= 0) {
     393             :       CoordinateMapBase<SourceFrame, TargetFrame, dim>::pup(p);
     394             :       p | maps_;
     395             :     }
     396             : 
     397             :     // No need to pup this because it is uniquely determined by the maps
     398             :     if (p.isUnpacking()) {
     399             :       function_of_time_names_ = CoordinateMap_detail::initialize_names(
     400             :           maps_, std::make_index_sequence<sizeof...(Maps)>{});
     401             :     }
     402             :   }
     403             : 
     404             :  private:
     405           0 :   friend bool operator==(const CoordinateMap& lhs, const CoordinateMap& rhs) {
     406             :     return lhs.maps_ == rhs.maps_;
     407             :   }
     408             : 
     409             :   template <typename NewMap, typename LocalSourceFrame,
     410             :             typename LocalTargetFrame, typename... LocalMaps, size_t... Is>
     411             :   friend CoordinateMap<LocalSourceFrame, LocalTargetFrame, LocalMaps..., NewMap>
     412             :   // NOLINTNEXTLINE(readability-redundant-declaration,-warnings-as-errors)
     413           0 :   push_back_impl(
     414             :       CoordinateMap<LocalSourceFrame, LocalTargetFrame, LocalMaps...>&& old_map,
     415             :       NewMap new_map, std::index_sequence<Is...> /*meta*/);
     416             : 
     417             :   template <typename... NewMaps, typename LocalSourceFrame,
     418             :             typename LocalTargetFrame, typename... LocalMaps, size_t... Is,
     419             :             size_t... Js>
     420             :   friend CoordinateMap<LocalSourceFrame, LocalTargetFrame, LocalMaps...,
     421             :                        NewMaps...>
     422             :   // NOLINTNEXTLINE(readability-redundant-declaration,-warnings-as-errors)
     423           0 :   push_back_impl(
     424             :       CoordinateMap<LocalSourceFrame, LocalTargetFrame, LocalMaps...>&& old_map,
     425             :       CoordinateMap<LocalSourceFrame, LocalTargetFrame, NewMaps...> new_map,
     426             :       std::index_sequence<Is...> /*meta*/, std::index_sequence<Js...> /*meta*/);
     427             : 
     428             :   template <typename NewMap, typename LocalSourceFrame,
     429             :             typename LocalTargetFrame, typename... LocalMaps, size_t... Is>
     430             :   friend CoordinateMap<LocalSourceFrame, LocalTargetFrame, NewMap, LocalMaps...>
     431             :   // NOLINTNEXTLINE(readability-redundant-declaration,-warnings-as-errors)
     432           0 :   push_front_impl(
     433             :       CoordinateMap<LocalSourceFrame, LocalTargetFrame, LocalMaps...>&& old_map,
     434             :       NewMap new_map, std::index_sequence<Is...> /*meta*/);
     435             : 
     436             :   template <size_t... Is>
     437             :   std::unique_ptr<CoordinateMapBase<SourceFrame, Frame::Grid, dim>>
     438           0 :       get_to_grid_frame_impl(std::index_sequence<Is...> /*meta*/) const;
     439             : 
     440           0 :   bool is_equal_to(const CoordinateMapBase<SourceFrame, TargetFrame, dim>&
     441             :                        other) const override {
     442             :     const auto& cast_of_other = dynamic_cast<const CoordinateMap&>(other);
     443             :     return *this == cast_of_other;
     444             :   }
     445             : 
     446           0 :   void check_functions_of_time(
     447             :       const FunctionsOfTimeMap& functions_of_time) const;
     448             : 
     449             :   template <typename T, size_t... Is>
     450           0 :   tnsr::I<T, dim, TargetFrame> call_impl(
     451             :       tnsr::I<T, dim, SourceFrame>&& source_point, double time,
     452             :       const FunctionsOfTimeMap& functions_of_time,
     453             :       std::index_sequence<Is...> /*meta*/) const;
     454             : 
     455             :   template <typename T, size_t... Is>
     456           0 :   std::optional<tnsr::I<T, dim, SourceFrame>> inverse_impl(
     457             :       tnsr::I<T, dim, TargetFrame>&& target_point, double time,
     458             :       const FunctionsOfTimeMap& functions_of_time,
     459             :       std::index_sequence<Is...> /*meta*/) const;
     460             : 
     461             :   template <typename T>
     462           0 :   InverseJacobian<T, dim, SourceFrame, TargetFrame> inv_jacobian_impl(
     463             :       tnsr::I<T, dim, SourceFrame>&& source_point, double time,
     464             :       const FunctionsOfTimeMap& functions_of_time) const;
     465             : 
     466             :   template <typename T>
     467           0 :   Jacobian<T, dim, SourceFrame, TargetFrame> jacobian_impl(
     468             :       tnsr::I<T, dim, SourceFrame>&& source_point, double time,
     469             :       const FunctionsOfTimeMap& functions_of_time) const;
     470             : 
     471             :   template <typename T>
     472             :   std::tuple<tnsr::I<T, dim, TargetFrame>,
     473             :              InverseJacobian<T, dim, SourceFrame, TargetFrame>,
     474             :              Jacobian<T, dim, SourceFrame, TargetFrame>,
     475             :              tnsr::I<T, dim, TargetFrame>>
     476           0 :   coords_frame_velocity_jacobians_impl(
     477             :       tnsr::I<T, dim, SourceFrame> source_point, double time,
     478             :       const FunctionsOfTimeMap& functions_of_time) const;
     479             : 
     480           0 :   std::tuple<Maps...> maps_;
     481           0 :   std::unordered_set<std::string> function_of_time_names_;
     482             : };
     483             : 
     484             : /// \ingroup ComputationalDomainGroup
     485             : /// \brief Creates a `CoordinateMap` of `maps...`
     486             : template <typename SourceFrame, typename TargetFrame, typename... Maps>
     487           1 : auto make_coordinate_map(Maps&&... maps)
     488             :     -> CoordinateMap<SourceFrame, TargetFrame, std::decay_t<Maps>...>;
     489             : 
     490             : /// \ingroup ComputationalDomainGroup
     491             : /// \brief Creates a `std::unique_ptr<CoordinateMapBase>` of `maps...`
     492             : template <typename SourceFrame, typename TargetFrame, typename... Maps>
     493           1 : auto make_coordinate_map_base(Maps&&... maps)
     494             :     -> std::unique_ptr<CoordinateMapBase<
     495             :         SourceFrame, TargetFrame,
     496             :         CoordinateMap<SourceFrame, TargetFrame, std::decay_t<Maps>...>::dim>>;
     497             : 
     498             : /// \ingroup ComputationalDomainGroup
     499             : /// \brief Creates a `std::vector<std::unique_ptr<CoordinateMapBase>>`
     500             : /// containing the result of `make_coordinate_map_base` applied to each
     501             : /// argument passed in.
     502             : template <typename SourceFrame, typename TargetFrame, typename Arg0,
     503             :           typename... Args>
     504           1 : auto make_vector_coordinate_map_base(Arg0&& arg_0, Args&&... remaining_args)
     505             :     -> std::vector<std::unique_ptr<
     506             :         CoordinateMapBase<SourceFrame, TargetFrame, std::decay_t<Arg0>::dim>>>;
     507             : 
     508             : /// \ingroup ComputationalDomainGroup
     509             : /// \brief Creates a `std::vector<std::unique_ptr<CoordinateMapBase>>`
     510             : /// containing the result of `make_coordinate_map_base` applied to each
     511             : /// element of the vector of maps composed with the rest of the arguments
     512             : /// passed in.
     513             : template <typename SourceFrame, typename TargetFrame, size_t Dim, typename Map,
     514             :           typename... Maps>
     515           1 : auto make_vector_coordinate_map_base(std::vector<Map> maps,
     516             :                                      const Maps&... remaining_maps)
     517             :     -> std::vector<
     518             :         std::unique_ptr<CoordinateMapBase<SourceFrame, TargetFrame, Dim>>>;
     519             : 
     520             : /// \ingroup ComputationalDomainGroup
     521             : /// \brief Creates a `CoordinateMap` by appending the new map to the end of the
     522             : /// old maps
     523             : template <typename SourceFrame, typename TargetFrame, typename... Maps,
     524             :           typename NewMap>
     525           1 : CoordinateMap<SourceFrame, TargetFrame, Maps..., NewMap> push_back(
     526             :     CoordinateMap<SourceFrame, TargetFrame, Maps...> old_map, NewMap new_map);
     527             : 
     528             : /// \ingroup ComputationalDomainGroup
     529             : /// \brief Creates a `CoordinateMap` by prepending the new map to the beginning
     530             : /// of the old maps
     531             : template <typename SourceFrame, typename TargetFrame, typename... Maps,
     532             :           typename NewMap>
     533           1 : CoordinateMap<SourceFrame, TargetFrame, NewMap, Maps...> push_front(
     534             :     CoordinateMap<SourceFrame, TargetFrame, Maps...> old_map, NewMap new_map);
     535             : 
     536             : /// \cond
     537             : template <typename SourceFrame, typename TargetFrame, typename... Maps>
     538             : PUP::able::PUP_ID
     539             :     CoordinateMap<SourceFrame, TargetFrame, Maps...>::my_PUP_ID =  // NOLINT
     540             :     0;
     541             : /// \endcond
     542             : }  // namespace domain

Generated by: LCOV version 1.14