#ifndef LINE_TRANSFORMATION_HPP #define LINE_TRANSFORMATION_HPP #include <algebra/TinyVector.hpp> template <size_t GivenDimension> class LineTransformation; template <> class LineTransformation<1> { public: constexpr static size_t Dimension = 1; private: double m_jacobian; TinyVector<Dimension> m_shift; public: PUGS_INLINE TinyVector<Dimension> operator()(const TinyVector<1>& x) const { return m_jacobian * x + m_shift; } double jacobianDeterminant() const { return m_jacobian; } PUGS_INLINE LineTransformation(const TinyVector<Dimension>& a, const TinyVector<Dimension>& b) { m_jacobian = 0.5 * (b[0] - a[0]); m_shift = 0.5 * (a + b); } ~LineTransformation() = default; }; template <size_t GivenDimension> class LineTransformation { public: constexpr static size_t Dimension = GivenDimension; private: TinyVector<Dimension> m_velocity; const double m_velocity_norm; TinyVector<Dimension> m_shift; public: PUGS_INLINE TinyVector<Dimension> operator()(const TinyVector<1>& x) const { return x[0] * m_velocity + m_shift; } PUGS_INLINE const TinyVector<Dimension>& velocity() const { return m_velocity; } PUGS_INLINE const TinyVector<Dimension>& velocity(const TinyVector<1>&) const { return m_velocity; } PUGS_INLINE double velocityNorm() const { return m_velocity_norm; } PUGS_INLINE double velocityNorm(const TinyVector<1>&) const { return m_velocity_norm; } PUGS_INLINE LineTransformation(const TinyVector<Dimension>& a, const TinyVector<Dimension>& b) : m_velocity{0.5 * (b - a)}, m_velocity_norm{l2Norm(m_velocity)}, m_shift{0.5 * (a + b)} { static_assert(Dimension > 1); } ~LineTransformation() = default; }; #endif // LINE_TRANSFORMATION_HPP