Line data Source code
1 1 : // Distributed under the MIT License. 2 : // See LICENSE.txt for details. 3 : 4 : /// \file 5 : /// Defines the class Affine. 6 : 7 : #pragma once 8 : 9 : #include <array> 10 : #include <cstddef> 11 : #include <optional> 12 : 13 : #include "DataStructures/Tensor/TypeAliases.hpp" 14 : 15 : /// \cond 16 : namespace PUP { 17 : class er; 18 : } // namespace PUP 19 : /// \endcond 20 : 21 : namespace domain { 22 1 : namespace CoordinateMaps { 23 : 24 : /*! 25 : * \ingroup CoordinateMapsGroup 26 : * \brief Affine map from \f$\xi \in [A, B]\rightarrow x \in [a, b]\f$. 27 : * 28 : * The formula for the mapping is... 29 : * \f[ 30 : * x = \frac{b}{B-A} (\xi-A) +\frac{a}{B-A}(B-\xi) 31 : * \f] 32 : * \f[ 33 : * \xi =\frac{B}{b-a} (x-a) +\frac{A}{b-a}(b-x) 34 : * \f] 35 : */ 36 1 : class Affine { 37 : public: 38 0 : static constexpr size_t dim = 1; 39 : 40 0 : Affine(double A, double B, double a, double b); 41 : 42 0 : Affine() = default; 43 0 : ~Affine() = default; 44 0 : Affine(const Affine&) = default; 45 0 : Affine(Affine&&) = default; // NOLINT 46 0 : Affine& operator=(const Affine&) = default; 47 0 : Affine& operator=(Affine&&) = default; 48 : 49 : template <typename T> 50 0 : std::array<T, 1> operator()(const std::array<T, 1>& source_coords) const; 51 : 52 : /// The inverse function is only callable with doubles because the inverse 53 : /// might fail if called for a point out of range, and it is unclear 54 : /// what should happen if the inverse were to succeed for some points in a 55 : /// DataVector but fail for other points. 56 1 : std::optional<std::array<double, 1>> inverse( 57 : const std::array<double, 1>& target_coords) const; 58 : 59 : template <typename T> 60 0 : tnsr::Ij<T, 1, Frame::NoFrame> jacobian( 61 : const std::array<T, 1>& source_coords) const; 62 : 63 : template <typename T> 64 0 : tnsr::Ij<T, 1, Frame::NoFrame> inv_jacobian( 65 : const std::array<T, 1>& source_coords) const; 66 : 67 : // NOLINTNEXTLINE(google-runtime-references) 68 0 : void pup(PUP::er& p); 69 : 70 0 : bool is_identity() const { return is_identity_; } 71 : 72 0 : static constexpr bool supports_hessian{true}; 73 : 74 : private: 75 0 : friend bool operator==(const Affine& lhs, const Affine& rhs); 76 : 77 0 : double A_{-1.0}; 78 0 : double B_{1.0}; 79 0 : double a_{-1.0}; 80 0 : double b_{1.0}; 81 0 : double length_of_domain_{2.0}; // B-A 82 0 : double length_of_range_{2.0}; // b-a 83 0 : double jacobian_{length_of_range_ / length_of_domain_}; 84 0 : double inverse_jacobian_{length_of_domain_ / length_of_range_}; 85 0 : bool is_identity_{false}; 86 : }; 87 : 88 0 : inline bool operator!=(const CoordinateMaps::Affine& lhs, 89 : const CoordinateMaps::Affine& rhs) { 90 : return not(lhs == rhs); 91 : } 92 : 93 : } // namespace CoordinateMaps 94 : } // namespace domain