#ifndef SYMMETRY_UTILS_HPP
#define SYMMETRY_UTILS_HPP

#include <algebra/TinyMatrix.hpp>
#include <algebra/TinyVector.hpp>
#include <utils/PugsMacros.hpp>

template <size_t Dimension>
PUGS_INLINE auto
symmetrize_vector(const TinyVector<Dimension>& normal, const TinyVector<Dimension>& u)
{
  return u - 2 * dot(u, normal) * normal;
}

template <size_t Dimension>
PUGS_INLINE auto
symmetrize_matrix(const TinyVector<Dimension>& normal, const TinyMatrix<Dimension>& A)
{
  const TinyMatrix S = TinyMatrix<Dimension>{identity} - 2 * tensorProduct(normal, normal);
  return S * A * S;
}

template <size_t Dimension>
PUGS_INLINE auto
symmetrize_coordinates(const TinyVector<Dimension>& origin,
                       const TinyVector<Dimension>& normal,
                       const TinyVector<Dimension>& u)
{
  return u - 2 * dot(u - origin, normal) * normal;
}

#endif   // SYMMETRY_UTILS_HPP