8#include <similie/misc/are_all_same.hpp>
9#include <similie/misc/domain_contains.hpp>
10#include <similie/misc/filled_struct.hpp>
11#include <similie/misc/macros.hpp>
12#include <similie/misc/portable_stl.hpp>
13#include <similie/misc/specialization.hpp>
14#include <similie/misc/type_seq_conversion.hpp>
15#include <similie/tensor/antisymmetric_tensor.hpp>
16#include <similie/tensor/dummy_index.hpp>
17#include <similie/tensor/tensor_impl.hpp>
19#include <Kokkos_StdAlgorithms.hpp>
22#include "cosimplex.hpp"
38 class LayoutStridedPolicy1,
39 class LayoutStridedPolicy2,
44 LayoutStridedPolicy2>>
46 using type = Cosimplex<
Simplex<K + 1, Tag...>, ElementType>;
51template <misc::Specialization<Cochain> CochainType>
52using coboundary_t =
typename detail::CoboundaryType<CochainType>::type;
56template <
class TagToAddToCochain,
class CochainTag>
57struct CoboundaryIndex;
59template <tensor::TensorNatIndex TagToAddToCochain, tensor::TensorNatIndex CochainTag>
60 requires(CochainTag::rank() == 0)
61struct CoboundaryIndex<TagToAddToCochain, CochainTag>
63 using type = TagToAddToCochain;
66template <tensor::TensorNatIndex TagToAddToCochain, tensor::TensorNatIndex CochainTag>
67 requires(CochainTag::rank() == 1)
68struct CoboundaryIndex<TagToAddToCochain, CochainTag>
74struct CoboundaryIndex<TagToAddToCochain, tensor::TensorAntisymmetricIndex<Tag...>>
81template <
class TagToAddToCochain,
class CochainTag>
90struct CoboundaryTensorType;
99struct CoboundaryTensorType<
102 tensor::Tensor<ElementType, ddc::DiscreteDomain<DDim...>, SupportType, MemorySpace>>
104 static_assert(ddc::type_seq_contains_v<
105 ddc::detail::TypeSeq<CochainIndex>,
106 ddc::detail::TypeSeq<DDim...>>);
109 ddc::replace_dim_of_t<
110 ddc::DiscreteDomain<DDim...>,
124 typename detail::CoboundaryTensorType<TagToAddToCochain, CochainTag, TensorType>::type;
128template <misc::Specialization<Chain> ChainType>
129struct ComputeSimplex;
131template <std::size_t K,
class... Tag,
class LayoutStridedPolicy,
class ExecSpace>
132struct ComputeSimplex<
Chain<
Simplex<K, Tag...>, LayoutStridedPolicy, ExecSpace>>
134 KOKKOS_FUNCTION
static Simplex<K + 1, Tag...> run(
137 ddc::DiscreteVector<Tag...> vect {
138 0 * ddc::type_seq_rank_v<Tag, ddc::detail::TypeSeq<Tag...>>...};
139 for (
auto i = chain.begin(); i < chain.end(); ++i) {
140 vect = ddc::DiscreteVector<Tag...> {
141 (
static_cast<bool>(vect.template get<Tag>())
142 ||
static_cast<bool>((*i).discrete_vector().
template get<Tag>()))...};
145 std::integral_constant<std::size_t, K + 1> {},
146 chain[0].discrete_element(),
153template <misc::Specialization<Cochain> CochainType>
158 assert(cochain.size() == 2 * (cochain.dimension() + 1)
159 &&
"only cochain over the boundary of a single simplex is supported");
167 detail::ComputeSimplex<typename CochainType::chain_type>::run(cochain.chain()),
168 cochain.integrate());
173template <tensor::TensorNatIndex Index,
class Dom>
174struct NonSpectatorDimension;
177struct NonSpectatorDimension<Index, ddc::DiscreteDomain<DDim...>>
179 using type = ddc::cartesian_prod_t<std::conditional_t<
180 ddc::type_seq_contains_v<
181 ddc::detail::TypeSeq<typename DDim::continuous_dimension_type>,
182 typename Index::type_seq_dimensions>,
183 ddc::DiscreteDomain<DDim>,
184 ddc::DiscreteDomain<>>...>;
187struct CoboundaryDummyIndex
194 tensor::TensorNatIndex TagToAddToCochain,
195 tensor::TensorIndex CochainTag,
196 misc::Specialization<tensor::Tensor> TensorType,
199 ExecSpace
const& exec_space,
203 ddc::DiscreteDomain batch_dom
204 = ddc::remove_dims_of<coboundary_index_t<TagToAddToCochain, CochainTag>>(
205 coboundary_tensor.domain());
208 ddc::Chunk simplex_boundary_alloc(
209 ddc::cartesian_prod_t<
210 ddc::remove_dims_of_t<
214 TensorType>::discrete_domain_type,
216 ddc::DiscreteDomain<detail::CoboundaryDummyIndex>>(
218 ddc::DiscreteDomain<detail::CoboundaryDummyIndex>(
219 ddc::DiscreteElement<detail::CoboundaryDummyIndex>(0),
220 ddc::DiscreteVector<detail::CoboundaryDummyIndex>(
221 2 * (CochainTag::rank() + 1)))),
222 ddc::KokkosAllocator<
225 ddc::remove_dims_of_t<
229 TensorType>::discrete_domain_type,
231 typename ExecSpace::memory_space>());
232 ddc::ChunkSpan simplex_boundary(simplex_boundary_alloc);
235 ddc::Chunk boundary_values_alloc(
236 ddc::cartesian_prod_t<
237 ddc::remove_dims_of_t<
241 TensorType>::discrete_domain_type,
243 ddc::DiscreteDomain<detail::CoboundaryDummyIndex>>(
245 ddc::DiscreteDomain<detail::CoboundaryDummyIndex>(
246 ddc::DiscreteElement<detail::CoboundaryDummyIndex>(0),
247 ddc::DiscreteVector<detail::CoboundaryDummyIndex>(
248 2 * (CochainTag::rank() + 1)))),
249 ddc::KokkosAllocator<double, typename ExecSpace::memory_space>());
250 ddc::ChunkSpan boundary_values(boundary_values_alloc);
254 CochainTag::rank() + 1,
255 typename detail::NonSpectatorDimension<
257 typename TensorType::non_indices_domain_t>::type>(exec_space);
262 typename detail::NonSpectatorDimension<
264 typename TensorType::non_indices_domain_t>::type>(exec_space);
267 SIMILIE_DEBUG_LOG(
"similie_compute_coboundary");
268 ddc::parallel_for_each(
269 "similie_compute_coboundary",
272 KOKKOS_LAMBDA(
typename decltype(batch_dom)::discrete_element_type elem) {
274 auto cochain =
Cochain(chain, coboundary_tensor[elem]);
275 for (
auto i = cochain.begin(); i < cochain.end(); ++i) {
278 std::integral_constant<std::size_t, CochainTag::rank() + 1> {},
280 (*i).discrete_vector());
283 =
boundary(simplex_boundary[elem].allocation_kokkos_view(), simplex);
285 for (
auto j = boundary_chain.
begin(); j < boundary_chain.
end(); ++j) {
287 boundary_values[elem].allocation_kokkos_view()(
288 Kokkos::Experimental::distance(boundary_chain.
begin(), j))
292 (*j).discrete_element())
293 ? (*j).discrete_element()
295 ddc::DiscreteElement<CochainTag>(
296 Kokkos::Experimental::distance(
299 find(lower_chain.begin(),
301 (*j).discrete_vector()))));
306 boundary_values[elem].allocation_kokkos_view());
311 ddc::DiscreteElement<
313 Kokkos::Experimental::distance(cochain.begin(), i)))
318 return coboundary_tensor;
327 ExecSpace
const& exec_space,
334 TensorType>(exec_space, coboundary_tensor, tensor);
KOKKOS_FUNCTION auto end()
KOKKOS_FUNCTION auto begin()
KOKKOS_FUNCTION element_type integrate() noexcept
constexpr auto tangent_basis(ExecSpace const &exec_space)
Cochain(ChainType, TensorType) -> Cochain< ChainType, typename TensorType::value_type, ddc::detail::mdspan_to_kokkos_layout_t< typename TensorType::layout_type > >
Simplex(ddc::DiscreteElement< Tag... >, ddc::DiscreteVector< T... >) -> Simplex< sizeof...(T), Tag... >
KOKKOS_FUNCTION coboundary_t< CochainType > coboundary(CochainType cochain)
Chain(Head, Tail...) -> Chain< typename Head::value_type, typename Head::array_layout, typename Head::memory_space >
typename detail::CoboundaryTensorType< TagToAddToCochain, CochainTag, TensorType >::type coboundary_tensor_t
coboundary_tensor_t< TagToAddToCochain, CochainTag, TensorType > deriv(ExecSpace const &exec_space, coboundary_tensor_t< TagToAddToCochain, CochainTag, TensorType > coboundary_tensor, TensorType tensor)
KOKKOS_FUNCTION Chain< boundary_t< SimplexType >, typename AllocationType::array_layout, typename AllocationType::memory_space > boundary(AllocationType allocation, SimplexType simplex)
detail::SimplexForDomain< K, Dom >::type simplex_for_domain_t
typename detail::CoboundaryIndex< TagToAddToCochain, CochainTag >::type coboundary_index_t
typename detail::CoboundaryType< CochainType >::type coboundary_t
KOKKOS_FUNCTION bool domain_contains(ddc::DiscreteDomain< DDim... > dom, ddc::DiscreteElement< ODDim... > elem)
Tensor(ddc::Chunk< ElementType, SupportType, Allocator >) -> Tensor< ElementType, SupportType, Kokkos::layout_right, typename Allocator::memory_space >
The top-level namespace of SimiLie.