SpECTRE Documentation Coverage Report
Current view: top level - Domain/CoordinateMaps - CoordinateMapHelpers.hpp Hit Total Coverage
Commit: b7cf72820a3faaa6fb97f8d6135c1ee188e37de8 Lines: 0 1 0.0 %
Date: 2024-04-23 18:44:12
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 <memory>
       8             : #include <string>
       9             : #include <type_traits>
      10             : #include <unordered_map>
      11             : 
      12             : #include "DataStructures/Tensor/Identity.hpp"
      13             : #include "DataStructures/Tensor/Tensor.hpp"
      14             : #include "Domain/FunctionsOfTime/FunctionOfTime.hpp"
      15             : #include "Utilities/DereferenceWrapper.hpp"
      16             : #include "Utilities/ErrorHandling/FloatingPointExceptions.hpp"
      17             : #include "Utilities/Gsl.hpp"
      18             : #include "Utilities/TypeTraits/RemoveReferenceWrapper.hpp"
      19             : 
      20             : namespace domain {
      21             : namespace CoordinateMap_detail {
      22             : /// @{
      23             : /// Call the map passing in the time and FunctionsOfTime if the map is
      24             : /// time-dependent
      25             : template <typename T, size_t Dim, typename Map>
      26             : void apply_map(
      27             :     const gsl::not_null<std::array<T, Dim>*> t_map_point, const Map& the_map,
      28             :     const double /*t*/,
      29             :     const std::unordered_map<
      30             :         std::string, std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>>&
      31             :     /*functions_of_time*/,
      32             :     const std::false_type /*is_time_independent*/) {
      33             :   if (LIKELY(not the_map.is_identity())) {
      34             :     *t_map_point = the_map(*t_map_point);
      35             :   }
      36             : }
      37             : 
      38             : template <typename T, size_t Dim, typename Map>
      39             : void apply_map(
      40             :     const gsl::not_null<std::array<T, Dim>*> t_map_point, const Map& the_map,
      41             :     const double t,
      42             :     const std::unordered_map<
      43             :         std::string, std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>>&
      44             :         functions_of_time,
      45             :     const std::true_type
      46             :     /*is_time_dependent*/) {
      47             :   ASSERT(not functions_of_time.empty(),
      48             :          "A function of time must be present if the maps are time-dependent.");
      49             :   ASSERT(
      50             :       [t]() {
      51             :         const ScopedFpeState disable_fpes(false);
      52             :         return not std::isnan(t);
      53             :       }(),
      54             :       "The time must not be NaN for time-dependent maps.");
      55             :   *t_map_point = the_map(*t_map_point, t, functions_of_time);
      56             : }
      57             : 
      58             : template <typename T, size_t Dim, typename Map>
      59             : auto apply_map(
      60             :     const Map& the_map, const std::array<T, Dim>& source_points,
      61             :     const double /*t*/,
      62             :     const std::unordered_map<
      63             :         std::string, std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>>&
      64             :     /*functions_of_time*/,
      65             :     const std::false_type /*is_time_independent*/) {
      66             :   if (LIKELY(not the_map.is_identity())) {
      67             :     return the_map(source_points);
      68             :   }
      69             :   std::decay_t<decltype(the_map(source_points))> result{};
      70             :   for (size_t i = 0; i < result.size(); ++i) {
      71             :     gsl::at(result, i) = gsl::at(source_points, i);
      72             :   }
      73             :   return result;
      74             : }
      75             : 
      76             : template <typename T, size_t Dim, typename Map>
      77             : auto apply_map(
      78             :     const Map& the_map, const std::array<T, Dim>& source_points, const double t,
      79             :     const std::unordered_map<
      80             :         std::string, std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>>&
      81             :         functions_of_time,
      82             :     const std::true_type
      83             :     /*is_time_dependent*/) {
      84             :   // Note: We don't forward to the return-by-not-null version to avoid
      85             :   // additional allocations of the target points array. That is, we would
      86             :   // allocate the target points array once here, and then again inside the call
      87             :   // to the coordinate map.
      88             :   ASSERT(not functions_of_time.empty(),
      89             :          "A function of time must be present if the maps are time-dependent.");
      90             :   ASSERT(
      91             :       [t]() {
      92             :         const ScopedFpeState disable_fpes(false);
      93             :         return not std::isnan(t);
      94             :       }(),
      95             :       "The time must not be NaN for time-dependent maps.");
      96             :   return the_map(source_points, t, functions_of_time);
      97             : }
      98             : /// @}
      99             : 
     100             : /// @{
     101             : template <typename T, size_t Dim, typename Map>
     102             : auto apply_inverse_map(
     103             :     const Map& the_map, const std::array<T, Dim>& target_points,
     104             :     const double /*t*/,
     105             :     const std::unordered_map<
     106             :         std::string, std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>>&
     107             :     /*functions_of_time*/,
     108             :     const std::false_type /*is_time_independent*/) {
     109             :   if (LIKELY(not the_map.is_identity())) {
     110             :     return the_map.inverse(target_points);
     111             :   }
     112             :   using UnwrappedT = tt::remove_cvref_wrap_t<T>;
     113             :   std::decay_t<decltype(the_map.inverse(target_points))> result{
     114             :       std::array<UnwrappedT, Dim>{}};
     115             :   for (size_t i = 0; i < target_points.size(); ++i) {
     116             :     gsl::at(*result, i) = gsl::at(target_points, i);
     117             :   }
     118             :   return result;
     119             : }
     120             : 
     121             : template <typename T, size_t Dim, typename Map>
     122             : auto apply_inverse_map(
     123             :     const Map& the_map, const std::array<T, Dim>& target_points, const double t,
     124             :     const std::unordered_map<
     125             :         std::string, std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>>&
     126             :         functions_of_time,
     127             :     const std::true_type
     128             :     /*is_time_dependent*/) {
     129             :   ASSERT(not functions_of_time.empty(),
     130             :          "A function of time must be present if the maps are time-dependent.");
     131             :   ASSERT(
     132             :       [t]() {
     133             :         const ScopedFpeState disable_fpes(false);
     134             :         return not std::isnan(t);
     135             :       }(),
     136             :       "The time must not be NaN for time-dependent maps.");
     137             :   return the_map.inverse(target_points, t, functions_of_time);
     138             : }
     139             : /// @}
     140             : 
     141             : /// @{
     142             : /// Compute the frame velocity
     143             : template <typename T, size_t Dim, typename Map>
     144             : auto apply_frame_velocity(
     145             :     const Map& /*the_map*/, const std::array<T, Dim>& source_points,
     146             :     const double /*t*/,
     147             :     const std::unordered_map<
     148             :         std::string, std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>>&
     149             :     /*functions_of_time*/,
     150             :     const std::false_type /*is_time_independent*/) {
     151             :   return make_array<Map::dim, tt::remove_cvref_wrap_t<T>>(
     152             :       make_with_value<tt::remove_cvref_wrap_t<T>>(
     153             :           dereference_wrapper(source_points[0]), 0.0));
     154             : }
     155             : 
     156             : template <typename T, size_t Dim, typename Map>
     157             : auto apply_frame_velocity(
     158             :     const Map& the_map, const std::array<T, Dim>& source_points, const double t,
     159             :     const std::unordered_map<
     160             :         std::string, std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>>&
     161             :         functions_of_time,
     162             :     const std::true_type
     163             :     /*is_time_dependent*/) {
     164             :   ASSERT(not functions_of_time.empty(),
     165             :          "A function of time must be present if the maps are time-dependent.");
     166             :   ASSERT(
     167             :       [t]() {
     168             :         const ScopedFpeState disable_fpes(false);
     169             :         return not std::isnan(t);
     170             :       }(),
     171             :       "The time must not be NaN for time-dependent maps.");
     172             :   return the_map.frame_velocity(source_points, t, functions_of_time);
     173             : }
     174             : /// @}
     175             : 
     176             : /// @{
     177             : /// Compute the Jacobian
     178             : template <typename T, size_t Dim, typename Map>
     179             : auto apply_jacobian(
     180             :     const Map& the_map, const std::array<T, Dim>& source_points,
     181             :     const double /*t*/,
     182             :     const std::unordered_map<
     183             :         std::string, std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>>&
     184             :     /*functions_of_time*/,
     185             :     const std::false_type /*is_time_independent*/) {
     186             :   if (LIKELY(not the_map.is_identity())) {
     187             :     return the_map.jacobian(source_points);
     188             :   }
     189             :   return identity<Dim>(dereference_wrapper(source_points[0]));
     190             : }
     191             : 
     192             : template <typename T, size_t Dim, typename Map>
     193             : auto apply_jacobian(
     194             :     const Map& the_map, const std::array<T, Dim>& source_points, const double t,
     195             :     const std::unordered_map<
     196             :         std::string, std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>>&
     197             :         functions_of_time,
     198             :     const std::true_type
     199             :     /*is_time_dependent*/) {
     200             :   ASSERT(not functions_of_time.empty(),
     201             :          "A function of time must be present if the maps are time-dependent.");
     202             :   ASSERT(
     203             :       [t]() {
     204             :         const ScopedFpeState disable_fpes(false);
     205             :         return not std::isnan(t);
     206             :       }(),
     207             :       "The time must not be NaN for time-dependent maps.");
     208             :   if (LIKELY(not the_map.is_identity())) {
     209             :     return the_map.jacobian(source_points, t, functions_of_time);
     210             :   }
     211             :   return identity<Dim>(dereference_wrapper(source_points[0]));
     212             : }
     213             : /// @}
     214             : 
     215             : /// @{
     216             : /// Compute the Jacobian
     217             : template <typename T, size_t Dim, typename Map>
     218             : auto apply_inverse_jacobian(
     219             :     const Map& the_map, const std::array<T, Dim>& source_points,
     220             :     const double /*t*/,
     221             :     const std::unordered_map<
     222             :         std::string, std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>>&
     223             :     /*functions_of_time*/,
     224             :     const std::false_type /*is_time_independent*/) {
     225             :   if (LIKELY(not the_map.is_identity())) {
     226             :     return the_map.inv_jacobian(source_points);
     227             :   }
     228             :   return identity<Dim>(dereference_wrapper(source_points[0]));
     229             : }
     230             : 
     231             : template <typename T, size_t Dim, typename Map>
     232             : auto apply_inverse_jacobian(
     233             :     const Map& the_map, const std::array<T, Dim>& source_points, const double t,
     234             :     const std::unordered_map<
     235             :         std::string, std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>>&
     236             :         functions_of_time,
     237             :     const std::true_type
     238             :     /*is_time_dependent*/) {
     239             :   ASSERT(not functions_of_time.empty(),
     240             :          "A function of time must be present if the maps are time-dependent.");
     241             :   ASSERT(
     242             :       [t]() {
     243             :         const ScopedFpeState disable_fpes(false);
     244             :         return not std::isnan(t);
     245             :       }(),
     246             :       "The time must not be NaN for time-dependent maps.");
     247             :   if (LIKELY(not the_map.is_identity())) {
     248             :     return the_map.inv_jacobian(source_points, t, functions_of_time);
     249             :   }
     250             :   return identity<Dim>(dereference_wrapper(source_points[0]));
     251             : }
     252             : /// @}
     253             : }  // namespace CoordinateMap_detail
     254             : }  // namespace domain

Generated by: LCOV version 1.14