8#include <similie/misc/macros.hpp>
9#include <similie/misc/small_matrix.hpp>
10#include <similie/misc/unsecure_parallel_deepcopy.hpp>
12#include "character.hpp"
13#include "diagonal_tensor.hpp"
14#include "identity_tensor.hpp"
15#include "lorentzian_sign_tensor.hpp"
17#include "relabelization.hpp"
18#include "symmetric_tensor.hpp"
19#include "tensor_prod.hpp"
27template <
class... CDim>
32template <
class MetricIndex>
34 = ddc::type_seq_element_t<0, ddc::to_type_seq_t<typename MetricIndex::subindices_domain_t>>;
36template <
class... CDim>
41template <
class MetricIndex>
43 = ddc::type_seq_element_t<1, ddc::to_type_seq_t<typename MetricIndex::subindices_domain_t>>;
47template <
class TypeSeqCDim>
48struct ConvertTypeSeqToMetricIndex1;
50template <
class... CDim>
51struct ConvertTypeSeqToMetricIndex1<ddc::detail::TypeSeq<CDim...>>
56template <
class TypeSeqCDim>
57struct ConvertTypeSeqToMetricIndex2;
59template <
class... CDim>
60struct ConvertTypeSeqToMetricIndex2<ddc::detail::TypeSeq<CDim...>>
75 typename detail::ConvertTypeSeqToMetricIndex1<
76 typename Index1::type_seq_dimensions>::type,
77 typename detail::ConvertTypeSeqToMetricIndex2<
78 typename Index2::type_seq_dimensions>::type>,
81template <TensorNatIndex Index1, TensorNatIndex Index2,
class Dom>
87 typename detail::ConvertTypeSeqToMetricIndex1<
88 typename Index1::type_seq_dimensions>::type,
89 typename detail::ConvertTypeSeqToMetricIndex2<
90 typename Index2::type_seq_dimensions>::type>,
94template <misc::Specialization<Tensor> TensorType, TensorNatIndex Index1, TensorNatIndex Index2>
98 typename detail::ConvertTypeSeqToMetricIndex1<
99 typename Index1::type_seq_dimensions>::type,
100 typename detail::ConvertTypeSeqToMetricIndex2<
101 typename Index2::type_seq_dimensions>::type>,
104template <TensorNatIndex Index1, TensorNatIndex Index2, misc::Specialization<Tensor> TensorType>
108 ddc::detail::TypeSeq<
109 typename detail::ConvertTypeSeqToMetricIndex1<
110 typename Index1::type_seq_dimensions>::type,
111 typename detail::ConvertTypeSeqToMetricIndex2<
112 typename Index2::type_seq_dimensions>::type>,
119template <
class MetricIndex,
class Indices1,
class Indices2>
120struct MetricProdDomainType;
122template <
class MetricIndex,
class... Index1,
class... Index2>
123struct MetricProdDomainType<
125 ddc::detail::TypeSeq<Index1...>,
126 ddc::detail::TypeSeq<Index2...>>
128 static_assert(
sizeof...(Index1) ==
sizeof...(Index2));
130 ddc::DiscreteDomain<MetricIndex>,
132 ddc::type_seq_element_t<
133 ddc::type_seq_rank_v<Index1, ddc::detail::TypeSeq<Index1...>>,
134 ddc::detail::TypeSeq<Index2...>>>...>;
140 TensorIndex MetricIndex,
144 typename detail::MetricProdDomainType<MetricIndex, Indices1, Indices2>::type;
154 class LayoutStridedPolicy,
156struct MetricProdType;
163 class LayoutStridedPolicy,
165struct MetricProdType<
168 ddc::detail::TypeSeq<Index1...>,
169 ddc::detail::TypeSeq<Index2...>,
175 ddc::cartesian_prod_t<
179 ddc::detail::TypeSeq<Index1...>,
180 ddc::detail::TypeSeq<Index2...>>>,
185template <
class MetricType,
class BatchElem,
class Indices1,
class Indices2>
186struct MetricProdValue;
188template <
class MetricType,
class BatchElem>
189struct MetricProdValue<MetricType, BatchElem, ddc::detail::TypeSeq<>, ddc::detail::TypeSeq<>>
191 KOKKOS_FUNCTION
static double run(
192 [[maybe_unused]] MetricType metric,
193 [[maybe_unused]] BatchElem elem,
194 [[maybe_unused]]
auto natural_elem)
207struct MetricProdValue<
210 ddc::detail::TypeSeq<HeadIndex1, TailIndex1...>,
211 ddc::detail::TypeSeq<HeadIndex2, TailIndex2...>>
213 KOKKOS_FUNCTION
static double run(MetricType metric, BatchElem elem,
auto natural_elem)
216 using metric_natural_elem_type =
typename decltype(relabeled_metric)::accessor_t::
217 natural_domain_t::discrete_element_type;
218 metric_natural_elem_type
const metric_natural_elem(natural_elem);
219 return relabeled_metric.get(relabeled_metric.access_element(elem, metric_natural_elem))
223 ddc::detail::TypeSeq<TailIndex1...>,
224 ddc::detail::TypeSeq<TailIndex2...>>::run(metric, elem, natural_elem);
232 TensorIndex MetricIndex,
235 class LayoutStridedPolicy,
253 template <misc::Specialization<Tensor> MetricProdType_>
254 KOKKOS_FUNCTION
static void run(MetricProdType_ metric_prod, MetricType metric, BatchElem elem)
256 ddc::device_for_each(metric_prod.domain(), [&](
auto mem_elem) {
257 metric_prod.mem(mem_elem)
258 = value(metric, elem, metric_prod.canonical_natural_element(mem_elem));
262 KOKKOS_FUNCTION
static double value(MetricType metric, BatchElem elem,
auto natural_elem)
264 return detail::MetricProdValue<MetricType, BatchElem, Indices1, Indices2>::
265 run(metric, elem, natural_elem);
270 TensorIndex MetricIndex,
271 misc::Specialization<ddc::detail::TypeSeq> Indices1,
272 misc::Specialization<ddc::detail::TypeSeq> Indices2,
273 misc::Specialization<Tensor> MetricType,
276 typename MetricType::non_indices_domain_t,
280 typename MetricType::layout_type,
281 typename MetricType::memory_space>
283 ExecSpace
const& exec_space,
285 typename MetricType::non_indices_domain_t,
289 typename MetricType::layout_type,
290 typename MetricType::memory_space> metric_prod,
293 SIMILIE_DEBUG_LOG(
"similie_compute_metric_prod");
294 ddc::parallel_for_each(
295 "similie_compute_metric_prod",
297 metric_prod.non_indices_domain(),
299 typename decltype(metric_prod)::non_indices_domain_t::discrete_element_type
301 MetricProd<MetricIndex, Indices1, Indices2, MetricType,
decltype(elem)>::
302 run(metric_prod[elem], metric, elem);
316 misc::Specialization<Tensor> MetricType,
317 misc::Specialization<Tensor> TensorType,
322 detail::non_primes<typename MetricType::accessor_t::natural_domain_t>>
325 ddc::Chunk result_alloc(
328 detail::non_primes<typename MetricType::accessor_t::natural_domain_t>>,
329 detail::non_primes<typename MetricType::accessor_t::natural_domain_t>>(
331 ddc::KokkosAllocator<double, typename ExecSpace::memory_space>());
335 detail::non_primes<typename MetricType::accessor_t::natural_domain_t>>
336 result(result_alloc);
337 SIMILIE_DEBUG_LOG(
"similie_inplace_apply_metric");
338 ddc::parallel_for_each(
339 "similie_inplace_apply_metric",
341 tensor.non_indices_domain(),
342 KOKKOS_LAMBDA(
typename TensorType::non_indices_domain_t::discrete_element_type elem) {
348 typename MetricType::accessor_t::natural_domain_t>>,
350 typename MetricType::accessor_t::natural_domain_t>>>>(
353 misc::detail::unsecure_parallel_deepcopy(exec_space, tensor, result);
357 detail::non_primes<typename MetricType::accessor_t::natural_domain_t>>(tensor);
361 TensorIndex MetricIndex,
362 TensorNatIndex... Index1,
369 ddc::detail::TypeSeq<Index1...>>
374 ddc::detail::TypeSeq<Index1...>,
375 primes<ddc::detail::TypeSeq<Index1...>>>>
376 metric_prod_accessor;
377 ddc::Chunk metric_prod_alloc(
378 ddc::cartesian_prod_t<
379 typename TensorType::non_indices_domain_t,
382 ddc::detail::TypeSeq<Index1...>,
383 primes<ddc::detail::TypeSeq<Index1...>>>>(
384 tensor.non_indices_domain(),
385 metric_prod_accessor.domain()),
386 ddc::KokkosAllocator<double, typename ExecSpace::memory_space>());
391 ddc::detail::TypeSeq<Index1...>,
392 primes<ddc::detail::TypeSeq<Index1...>>>(exec_space, metric_prod, metric);
397template <misc::Specialization<Tensor> MetricType>
400 ddc::to_type_seq_t<typename MetricType::accessor_t::natural_domain_t>,
403template <TensorIndex MetricIndex, misc::Specialization<Tensor> MetricType,
class BatchElem>
408 template <misc::Specialization<Tensor> OutputTensorType>
409 KOKKOS_FUNCTION
static void run(OutputTensorType inv_metric, MetricType metric, BatchElem elem)
414 ddc::device_for_each(inv_metric.domain(), [&](
auto mem_elem) {
415 inv_metric.mem(mem_elem)
416 = value(metric, elem, inv_metric.canonical_natural_element(mem_elem));
419 ddc::device_for_each(inv_metric.domain(), [&](
auto mem_elem) {
420 inv_metric.mem(mem_elem)
421 = value(metric, elem, inv_metric.canonical_natural_element(mem_elem));
425 using memory_space =
typename MetricType::memory_space;
429 std::array<double, N * N> matrix_alloc {};
430 std::array<double, N * N> inverse_alloc {};
431 std::array<double, N * N> workspace_alloc {};
439 for (std::size_t i = 0; i < N; ++i) {
440 for (std::size_t j = 0; j < N; ++j) {
441 matrix_view(i, j) = metric.get(metric.access_element(
443 ddc::DiscreteElement<metric_index_1_t, metric_index_2_t>(i, j)));
448 assert(success &&
"Kokkos-kernels failed at inverting metric tensor");
450 ddc::device_for_each(inv_metric.domain(), [&](
auto mem_elem) {
451 auto const natural_elem = inv_metric.canonical_natural_element(mem_elem);
452 auto const ids = ddc::detail::array(natural_elem);
453 inv_metric.mem(mem_elem) = inverse_view(ids[0], ids[1]);
458 KOKKOS_FUNCTION
static double value(MetricType metric, BatchElem elem,
auto natural_elem)
461 auto const ids = ddc::detail::array(natural_elem);
462 return ids[0] == ids[1] ? 1. : 0.;
464 return metric.get(metric.access_element(elem, natural_elem));
465 }
else if constexpr (misc::Specialization<MetricIndex, TensorDiagonalIndex>) {
470 typename MetricType::accessor_t::natural_domain_t>>,
472 typename MetricType::accessor_t::natural_domain_t>>(
474 .access_element(elem, natural_elem));
475 }
else if constexpr (misc::Specialization<MetricIndex, TensorSymmetricIndex>) {
476 [[maybe_unused]]
typename output_tensor_type::accessor_t accessor;
477 std::array<double, output_tensor_type::accessor_t::domain().size()> alloc {};
480 typename output_tensor_type::indices_domain_t,
481 Kokkos::layout_right,
482 typename MetricType::memory_space>
483 span(alloc.data(), accessor.domain());
485 run(local_inverse, metric, elem);
486 return local_inverse.get(local_inverse.access_element(natural_elem));
494template <TensorIndex MetricIndex, misc::Specialization<Tensor> MetricType,
class ExecSpace>
496 ExecSpace
const& exec_space,
500 SIMILIE_DEBUG_LOG(
"similie_invert_metric");
501 ddc::parallel_for_each(
502 "similie_invert_metric",
504 inv_metric.non_indices_domain(),
507 MetricType>::non_indices_domain_t::discrete_element_type elem) {
509 run(inv_metric[elem], metric, elem);
KOKKOS_FUNCTION bool invert(InverseView inverse, MatrixView matrix, WorkspaceView workspace)
KOKKOS_FUNCTION unmanaged_vector_view_t< Scalar, MemorySpace > vector_view(Scalar *data, std::size_t n)
KOKKOS_FUNCTION unmanaged_matrix_view_t< Scalar, MemorySpace > matrix_view(Scalar *data, std::size_t rows, std::size_t cols)
Tensor(ddc::Chunk< ElementType, SupportType, Allocator >) -> Tensor< ElementType, SupportType, Kokkos::layout_right, typename Allocator::memory_space >
relabelize_indices_of_t< MetricType, ddc::to_type_seq_t< typename MetricType::accessor_t::natural_domain_t >, swap_character_t< ddc::to_type_seq_t< typename MetricType::accessor_t::natural_domain_t > > > invert_metric_t
typename detail::MetricProdType< NonMetricDom, MetricIndex, Indices1, Indices2, LayoutStridedPolicy, MemorySpace >::type metric_prod_t
detail::RelabelizeIndicesOfType< TensorType, OldIndices, NewIndices >::type relabelize_indices_of_t
ddc::type_seq_element_t< 0, ddc::to_type_seq_t< typename MetricIndex::subindices_domain_t > > metric_index_1
detail::Primes< Indices, I >::type primes
constexpr relabelize_indices_in_t< T, OldIndices, NewIndices > relabelize_indices_in(T t)
invert_metric_t< MetricType > fill_inverse_metric(ExecSpace const &exec_space, invert_metric_t< MetricType > inv_metric, MetricType metric)
constexpr relabelize_metric_in_domain_t< Dom, Index1, Index2 > relabelize_metric_in_domain(Dom metric_dom)
relabelize_indices_of_t< TensorType, ddc::detail::TypeSeq< typename detail::ConvertTypeSeqToMetricIndex1< typename Index1::type_seq_dimensions >::type, typename detail::ConvertTypeSeqToMetricIndex2< typename Index2::type_seq_dimensions >::type >, ddc::detail::TypeSeq< uncharacterize_t< Index1 >, uncharacterize_t< Index2 > > > relabelize_metric_t
constexpr relabelize_metric_t< TensorType, Index1, Index2 > relabelize_metric(TensorType tensor)
ddc::type_seq_element_t< 1, ddc::to_type_seq_t< typename MetricIndex::subindices_domain_t > > metric_index_2
typename detail::MetricProdDomainType< MetricIndex, Indices1, Indices2 >::type metric_prod_domain_t
metric_prod_t< typename MetricType::non_indices_domain_t, MetricIndex, Indices1, Indices2, typename MetricType::layout_type, typename MetricType::memory_space > fill_metric_prod(ExecSpace const &exec_space, metric_prod_t< typename MetricType::non_indices_domain_t, MetricIndex, Indices1, Indices2, typename MetricType::layout_type, typename MetricType::memory_space > metric_prod, MetricType metric)
Tensor< ElementType, ddc::DiscreteDomain< ProdDDim... >, LayoutStridedPolicy, MemorySpace > tensor_prod(Tensor< ElementType, ddc::DiscreteDomain< ProdDDim... >, LayoutStridedPolicy, MemorySpace > prod_tensor, Tensor< ElementType, ddc::DiscreteDomain< DDim1... >, LayoutStridedPolicy, MemorySpace > tensor1, Tensor< ElementType, ddc::DiscreteDomain< DDim2... >, LayoutStridedPolicy, MemorySpace > tensor2)
detail::SwapCharacter< T >::type swap_character_t
relabelize_indices_of_t< TensorType, swap_character_t< detail::non_primes< typename MetricType::accessor_t::natural_domain_t > >, detail::non_primes< typename MetricType::accessor_t::natural_domain_t > > inplace_apply_metric(ExecSpace const &exec_space, TensorType tensor, MetricType metric_prod)
relabelize_indices_in_t< Dom, ddc::detail::TypeSeq< typename detail::ConvertTypeSeqToMetricIndex1< typename Index1::type_seq_dimensions >::type, typename detail::ConvertTypeSeqToMetricIndex2< typename Index2::type_seq_dimensions >::type >, ddc::detail::TypeSeq< uncharacterize_t< Index1 >, uncharacterize_t< Index2 > > > relabelize_metric_in_domain_t
detail::Uncharacterize< Index >::type uncharacterize_t
constexpr relabelize_indices_of_t< Tensor, OldIndices, NewIndices > relabelize_indices_of(Tensor tensor)
detail::TensorAccessorForDomain< Dom >::type tensor_accessor_for_domain_t
typename detail::RelabelizeIndicesInType< T, OldIndices, NewIndices >::type relabelize_indices_in_t
The top-level namespace of SimiLie.
invert_metric_t< MetricType > output_tensor_type
static KOKKOS_FUNCTION void run(OutputTensorType inv_metric, MetricType metric, BatchElem elem)
static KOKKOS_FUNCTION double value(MetricType metric, BatchElem elem, auto natural_elem)
static KOKKOS_FUNCTION double value(MetricType metric, BatchElem elem, auto natural_elem)
static KOKKOS_FUNCTION void run(MetricProdType_ metric_prod, MetricType metric, BatchElem elem)