Skip to content
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Fixed

- Add missing `enable_tensor_type` for `CartesianLeviCivitaTensor` and LeviCivita `size()`.

### Changed

- Add Koliop in all toolchains.
Expand Down
40 changes: 31 additions & 9 deletions src/data_types/static_tensors.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ class IdentityTensor
* @tparam Dim The dimension of interest (0 <= dim < rank()).
*/
template <std::size_t dim>
using vector_index_set_t = std::conditional_t<dim == 0, ValidIndexSetRow, ValidIndexSetCol>;
using vector_index_set_t = ddc::type_seq_element_t<dim, index_set>;
};

/**
Expand All @@ -99,6 +99,16 @@ class CartesianLeviCivitaTensor
static_assert(is_vector_index_set_v<ValidIndexSet>);
static_assert(std::is_same_v<ValidIndexSet, vector_index_set_dual_t<ValidIndexSet>>);

private:
KOKKOS_FUNCTION static constexpr std::size_t compute_size()
{
std::size_t result = 1;
for (std::size_t i = 0; i < rank(); ++i) {
result *= ddc::type_seq_size_v<ValidIndexSet>;
}
return result;
}

public:
/// The type of the elements of the tensor.
using element_type = ElementType;
Expand All @@ -123,7 +133,7 @@ class CartesianLeviCivitaTensor
*/
KOKKOS_FUNCTION static constexpr std::size_t size()
{
return rank() * rank();
return compute_size();
}

/// The TensorIndexSet describing the possible indices.
Expand Down Expand Up @@ -171,7 +181,15 @@ class LeviCivitaTensor
|| (is_contravariant_vector_index_set_v<ValidIndexSet>));

private:
double m_coeff;
ElementType m_coeff;
KOKKOS_FUNCTION static constexpr std::size_t compute_size()
{
std::size_t result = 1;
for (std::size_t i = 0; i < rank(); ++i) {
result *= ddc::type_seq_size_v<ValidIndexSet>;
}
return result;
}

public:
/// The type of the elements of the tensor.
Expand All @@ -197,7 +215,7 @@ class LeviCivitaTensor
*/
KOKKOS_FUNCTION static constexpr std::size_t size()
{
return rank() * rank();
return compute_size();
}

/// The TensorIndexSet describing the possible indices.
Expand All @@ -206,7 +224,7 @@ class LeviCivitaTensor
/**
* @brief Construct an uninitialised tensor object.
*/
explicit KOKKOS_FUNCTION LeviCivitaTensor(double jacobian)
explicit KOKKOS_FUNCTION LeviCivitaTensor(ElementType jacobian)
{
if constexpr (is_covariant_vector_index_set_v<ValidIndexSet>) {
m_coeff = jacobian;
Expand All @@ -225,7 +243,7 @@ class LeviCivitaTensor
template <class QueryTensorIndexElement>
KOKKOS_INLINE_FUNCTION ElementType get() const
{
double constexpr eps = type_seq_permutation_parity_v<
int constexpr eps = type_seq_permutation_parity_v<
typename QueryTensorIndexElement::IdxTypeSeq,
ValidIndexSet>;
return eps * m_coeff;
Expand All @@ -243,7 +261,7 @@ class LeviCivitaTensor

namespace ddcHelper {
/**
* @brief A helper function to get a modifiable reference to an element of the tensor.
* @brief A helper function to get the value of an element of the tensor.
* @tparam QueryIndexTag A type describing the relevant index.
* @param tensor The tensor whose elements are examined.
* @return The relevant element of the tensor.
Expand All @@ -258,7 +276,7 @@ KOKKOS_INLINE_FUNCTION constexpr double get(
}

/**
* @brief A helper function to get a modifiable reference to an element of the tensor.
* @brief A helper function to get the value of an element of the tensor.
* @tparam QueryIndexTag A type describing the relevant index.
* @param tensor The tensor whose elements are examined.
* @return The relevant element of the tensor.
Expand All @@ -273,7 +291,7 @@ KOKKOS_INLINE_FUNCTION constexpr double get(
}

/**
* @brief A helper function to get a modifiable reference to an element of the tensor.
* @brief A helper function to get the value of an element of the tensor.
* @tparam QueryIndexTag A type describing the relevant index.
* @param tensor The tensor whose elements are examined.
* @return The relevant element of the tensor.
Expand All @@ -297,4 +315,8 @@ inline constexpr bool
template <class ElementType, class ValidIndexSet>
inline constexpr bool enable_tensor_type<LeviCivitaTensor<ElementType, ValidIndexSet>> = true;

template <class ElementType, class ValidIndexSet>
inline constexpr bool
enable_tensor_type<CartesianLeviCivitaTensor<ElementType, ValidIndexSet>> = true;

} // namespace detail
42 changes: 42 additions & 0 deletions tests/data_types/tensor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -506,3 +506,45 @@ TEST(TensorTest, ElementAssign)
EXPECT_EQ((ddcHelper::get<Y, X>(small)), (ddcHelper::get<Y, X>(big)));
EXPECT_EQ((ddcHelper::get<Y, Y>(small)), (ddcHelper::get<Y, Y>(big)));
}

TEST(TensorTest, CartesianLeviCivitaEnabledAsTensorType)
{
using CartLC = CartesianLeviCivitaTensor<int, VectorIndexSet<X, Y, Z>>;
static_assert(
is_tensor_type_v<CartLC>,
"CartesianLeviCivitaTensor should be recognised as a tensor type");
using LC = LeviCivitaTensor<int, VectorIndexSet<R, Theta>>;
using Id = IdentityTensor<int, VectorIndexSet<R, Z>, VectorIndexSet<R, Z>>;
static_assert(is_tensor_type_v<LC>);
static_assert(is_tensor_type_v<Id>);
}

TEST(TensorTest, LeviCivitaSize3D)
{
using CartLC3D = CartesianLeviCivitaTensor<int, VectorIndexSet<X, Y, Z>>;
using LC3D = LeviCivitaTensor<double, VectorIndexSet<R, Theta, Z>>;
static_assert(CartLC3D::size() == 27);
static_assert(LC3D::size() == 27);
static_assert(CartLC3D::rank() == 3);
static_assert(LC3D::rank() == 3);
using CartLC2D = CartesianLeviCivitaTensor<int, VectorIndexSet<X, Y>>;
using LC2D = LeviCivitaTensor<double, VectorIndexSet<R, Theta>>;
static_assert(CartLC2D::size() == 4);
static_assert(LC2D::size() == 4);
}

TEST(TensorTest, LeviCivitaFloatElementType)
{
LeviCivitaTensor<float, VectorIndexSet<R, Theta>> lc_float(2.0f);
static_assert(std::is_same_v<decltype(lc_float)::element_type, float>);
float val_rt = ddcHelper::get<R, Theta>(lc_float);
float val_tr = ddcHelper::get<Theta, R>(lc_float);
float val_rr = ddcHelper::get<R, R>(lc_float);

EXPECT_FLOAT_EQ(val_rt, 0.5f);
EXPECT_FLOAT_EQ(val_tr, -0.5f);
EXPECT_FLOAT_EQ(val_rr, 0.0f);

CartesianLeviCivitaTensor<float, VectorIndexSet<X, Y>> cart_lc_float;
static_assert(std::is_same_v<decltype(cart_lc_float)::element_type, float>);
}
Loading