10#include <similie/misc/binomial_coefficient.hpp>
11#include <similie/misc/clamp_to_domain.hpp>
12#include <similie/misc/domain_contains.hpp>
13#include <similie/misc/factorial.hpp>
14#include <similie/misc/small_matrix.hpp>
15#include <similie/tensor/metric.hpp>
28template <std::
size_t N, std::
size_t K>
29KOKKOS_FUNCTION std::array<std::size_t, N - K> complement(std::array<std::size_t, K>
const& ids)
31 std::array<std::size_t, N - K> complement_ids {};
32 std::size_t complement_id = 0;
33 for (std::size_t i = 0; i < N; ++i) {
35 for (std::size_t
id : ids) {
36 found = found ||
id == i;
39 complement_ids[complement_id++] = i;
42 return complement_ids;
45template <CellComplex Complex, std::
size_t N>
46KOKKOS_FUNCTION
double complex_volume_factor(std::size_t
const simplex_dim)
55template <
class PositionIndex,
class PositionType,
class BatchElem>
56KOKKOS_FUNCTION std::array<double, PositionIndex::size()> edge_vector(
57 PositionType position,
59 std::size_t
const dim_id)
61 std::array<double, PositionIndex::size()> vector {};
62 BatchElem forward = elem;
63 BatchElem backward = elem;
64 ddc::detail::array(forward)[dim_id] += 1;
65 ddc::detail::array(backward)[dim_id] -= 1;
70 for (std::size_t comp = 0; comp < PositionIndex::size(); ++comp) {
71 ddc::DiscreteElement<PositionIndex>
const component(comp);
72 double const center = position.get(position.access_element(elem, component));
74 vector[comp] = position.get(position.access_element(forward, component)) - center;
75 }
else if (has_backward) {
76 vector[comp] = center - position.get(position.access_element(backward, component));
84template <std::
size_t N>
85KOKKOS_FUNCTION
double dot(
86 std::array<double, N>
const& lhs,
87 std::array<double, N>
const& rhs,
88 std::array<double, N * N>
const& local_metric)
91 for (std::size_t i = 0; i < N; ++i) {
92 for (std::size_t j = 0; j < N; ++j) {
93 result += lhs[i] * local_metric[i * N + j] * rhs[j];
101template <CellComplex Complex, std::
size_t N,
class MetricType,
class PositionType,
class BatchElem>
104 template <std::
size_t K>
105 KOKKOS_FUNCTION
static double run(
107 PositionType position,
109 std::array<std::size_t, K>
const& ids)
111 if constexpr (K == 0) {
114 using PositionIndex = ddc::type_seq_element_t<
116 ddc::to_type_seq_t<typename PositionType::indices_domain_t>>;
117 using MetricIndex = ddc::type_seq_element_t<
119 ddc::to_type_seq_t<typename MetricType::indices_domain_t>>;
123 std::array<double, N * N> local_metric {};
124 for (std::size_t i = 0; i < N; ++i) {
125 for (std::size_t j = 0; j < N; ++j) {
126 local_metric[i * N + j] = metric.get(metric.access_element(
128 ddc::DiscreteElement<MetricIndex1, MetricIndex2>(i, j)));
132 std::array<std::array<double, N>, K> edges {};
133 for (std::size_t i = 0; i < K; ++i) {
134 edges[i] = detail::edge_vector<PositionIndex>(position, elem, ids[i]);
137 std::array<double, K * K> gram_matrix {};
138 for (std::size_t i = 0; i < K; ++i) {
139 for (std::size_t j = i; j < K; ++j) {
140 double const value = detail::dot(edges[i], edges[j], local_metric);
141 gram_matrix[i * K + j] = value;
142 gram_matrix[j * K + i] = value;
146 return Kokkos::sqrt(Kokkos::abs([&]() {
147 std::array<double, K * K> determinant_alloc = gram_matrix;
150 typename MetricType::memory_space>(determinant_alloc.data(), K, K);
157template <CellComplex Complex, std::
size_t N,
class MetricType,
class PositionType,
class BatchElem>
160 template <std::
size_t K>
161 KOKKOS_FUNCTION
static double run(
163 PositionType position,
165 std::array<std::size_t, K>
const& ids)
169 "DualSimplexVolume must use a dual cell complex.");
171 N - K>(metric, position, elem, detail::complement<N>(ids));
KOKKOS_FUNCTION unmanaged_matrix_view_t< Scalar, MemorySpace > matrix_view(Scalar *data, std::size_t rows, std::size_t cols)
KOKKOS_FUNCTION MatrixView::non_const_value_type determinant(MatrixView matrix)
KOKKOS_FUNCTION bool domain_contains(ddc::DiscreteDomain< DDim... > dom, ddc::DiscreteElement< ODDim... > elem)
constexpr std::size_t binomial_coefficient(std::size_t n, std::size_t k) noexcept
ddc::type_seq_element_t< 0, ddc::to_type_seq_t< typename MetricIndex::subindices_domain_t > > metric_index_1
ddc::type_seq_element_t< 1, ddc::to_type_seq_t< typename MetricIndex::subindices_domain_t > > metric_index_2
The top-level namespace of SimiLie.
static KOKKOS_FUNCTION double run(MetricType metric, PositionType position, BatchElem elem, std::array< std::size_t, K > const &ids)
static KOKKOS_FUNCTION double run(MetricType metric, PositionType position, BatchElem elem, std::array< std::size_t, K > const &ids)