12#include <similie/exterior/hodge_star.hpp>
13#include <similie/misc/domain_contains.hpp>
14#include <similie/misc/macros.hpp>
15#include <similie/misc/specialization.hpp>
16#include <similie/tensor/character.hpp>
17#include <similie/tensor/tensor_impl.hpp>
19#include <Kokkos_StdAlgorithms.hpp>
21#include "coboundary.hpp"
23#include "cosimplex.hpp"
33struct CodifferentialType;
39 class LayoutStridedPolicy1,
40 class LayoutStridedPolicy2,
42struct CodifferentialType<
45 LayoutStridedPolicy2>>
47 using type = Cosimplex<
Simplex<K - 1, Tag...>, ElementType>;
52template <misc::Specialization<Cochain> CochainType>
57template <
class TagToRemoveFromCochain,
class CochainTag>
58struct CodifferentialIndex;
60template <tensor::TensorNatIndex TagToRemoveFromCochain, tensor::TensorNatIndex CochainTag>
61 requires(CochainTag::rank() == 1 && std::is_same_v<TagToRemoveFromCochain, CochainTag>)
62struct CodifferentialIndex<TagToRemoveFromCochain, CochainTag>
67template <tensor::TensorNatIndex TagToRemoveFromCochain, tensor::TensorNatIndex Tag>
68struct CodifferentialIndex<
69 TagToRemoveFromCochain,
70 tensor::TensorAntisymmetricIndex<TagToRemoveFromCochain, Tag>>
76 requires(
sizeof...(Tag) > 1)
77struct CodifferentialIndex<
78 TagToRemoveFromCochain,
86template <
class TagToRemoveFromCochain,
class CochainTag>
88 typename detail::CodifferentialIndex<TagToRemoveFromCochain, CochainTag>::type;
96struct CodifferentialTensorType;
105 requires(ddc::type_seq_contains_v<
106 ddc::detail::TypeSeq<CochainIndex>,
107 ddc::detail::TypeSeq<DDim...>>)
108struct CodifferentialTensorType<
109 TagToRemoveFromCochain,
111 tensor::Tensor<ElementType, ddc::DiscreteDomain<DDim...>, SupportType, MemorySpace>>
115 ddc::replace_dim_of_t<
116 ddc::DiscreteDomain<DDim...>,
130 CodifferentialTensorType<TagToRemoveFromCochain, CochainTag, TensorType>::type;
134template <std::
size_t I,
class T>
139template <
class Ids,
class T>
140struct CodifferentialHodgeOutputIndexSeq_;
142template <std::size_t... Id,
class T>
143struct CodifferentialHodgeOutputIndexSeq_<std::index_sequence<Id...>, T>
145 using type = ddc::detail::TypeSeq<tensor::Covariant<CodifferentialHodgeOutputIndex<Id, T>>...>;
148template <std::
size_t EndId,
class T>
149struct CodifferentialHodgeOutputIndexSeq;
151template <std::
size_t EndId,
class T>
153struct CodifferentialHodgeOutputIndexSeq<EndId, T>
155 using type = ddc::detail::TypeSeq<>;
158template <std::
size_t EndId,
class T>
160struct CodifferentialHodgeOutputIndexSeq<EndId, T>
163 typename CodifferentialHodgeOutputIndexSeq_<std::make_index_sequence<EndId>, T>::type;
168template <std::
size_t EndId,
class T>
170 typename detail::CodifferentialHodgeOutputIndexSeq<EndId, T>::type;
172template <
class... Args>
184 TagToRemoveFromCochain,
190 KOKKOS_FUNCTION
static void run(
191 auto codifferential_tensor,
194 PositionType position,
197 typename TensorType::non_indices_domain_t::discrete_element_type elem)
199 using source_hodge_input_indices
202 TagToRemoveFromCochain::size() - CochainTag::rank(),
203 TagToRemoveFromCochain>;
204 using target_hodge_input_indices = ddc::type_seq_merge_t<
205 ddc::detail::TypeSeq<TagToRemoveFromCochain>,
206 source_hodge_output_indices>;
209 source_hodge_output_indices>;
210 using dual_codifferential_index = misc::
211 convert_type_seq_to_t<tensor::TensorAntisymmetricIndex, target_hodge_input_indices>;
213 dual_codifferential_accessor;
215 std::array<double, dual_codifferential_index::access_size()> dual_codifferential_alloc {};
218 ddc::DiscreteDomain<dual_codifferential_index>,
219 Kokkos::layout_right,
220 typename TensorType::memory_space>
221 dual_codifferential_span(
222 dual_codifferential_alloc.data(),
223 dual_codifferential_accessor.
domain());
227 auto dual_evaluator = [&](
auto sampled_elem,
auto dual_elem) {
232 std::array<double, dual_tensor_index::access_size()> dual_tensor_alloc {};
235 ddc::DiscreteDomain<dual_tensor_index>,
236 Kokkos::layout_right,
237 typename TensorType::memory_space>
238 dual_tensor_span(dual_tensor_alloc.data(), dual_tensor_accessor.
domain());
243 source_hodge_input_indices,
244 source_hodge_output_indices,
247 typename TensorType::non_indices_domain_t::discrete_element_type>::
248 run(dual_tensor, tensor[sampled_elem], metric, position, sampled_elem);
249 return dual_tensor.mem(dual_elem);
253 run(dual_codifferential, dual_evaluator, chain, lower_chain, elem);
258 ddc::type_seq_remove_t<
260 ddc::detail::TypeSeq<TagToRemoveFromCochain>>,
263 typename TensorType::non_indices_domain_t::discrete_element_type>::
264 run(codifferential_tensor, dual_codifferential, metric, position, elem);
265 if constexpr ((TagToRemoveFromCochain::size() * (CochainTag::rank() + 1) + 1) % 2 == 1) {
266 codifferential_tensor *= -1;
281 using CodifferentialTensorType
283 using MemorySpace =
typename TensorType::memory_space;
284 using AllocatorType = ddc::KokkosAllocator<double, MemorySpace>;
285 using SourceHodgeInputIndices
288 TagToRemoveFromCochain::size() - CochainTag::rank(),
289 TagToRemoveFromCochain>;
290 using TargetHodgeInputIndices = ddc::type_seq_merge_t<
291 ddc::detail::TypeSeq<TagToRemoveFromCochain>,
292 SourceHodgeOutputIndices>;
293 using TargetHodgeOutputIndices = ddc::type_seq_remove_t<
295 ddc::detail::TypeSeq<TagToRemoveFromCochain>>;
296 using DualTensorIndex = misc::
297 convert_type_seq_to_t<tensor::TensorAntisymmetricIndex, SourceHodgeOutputIndices>;
298 using DualCodifferentialIndex = misc::
299 convert_type_seq_to_t<tensor::TensorAntisymmetricIndex, TargetHodgeInputIndices>;
300 using NonSpectatorDimensions =
typename detail::NonSpectatorDimension<
301 TagToRemoveFromCochain,
302 typename TensorType::non_indices_domain_t>::type;
304 std::declval<ExecSpace const&>()));
306 std::declval<ExecSpace const&>()));
308 using HodgeStarDomainType = ddc::cartesian_prod_t<
309 typename MetricType::non_indices_domain_t,
311 using DualHodgeStarDomainType = ddc::cartesian_prod_t<
312 typename MetricType::non_indices_domain_t,
315 TargetHodgeOutputIndices>>;
316 using DualTensorDomainType = ddc::cartesian_prod_t<
317 typename TensorType::non_indices_domain_t,
318 ddc::DiscreteDomain<DualTensorIndex>>;
320 using HodgeStarAllocType = ddc::Chunk<double, HodgeStarDomainType, AllocatorType>;
321 using DualHodgeStarAllocType = ddc::Chunk<double, DualHodgeStarDomainType, AllocatorType>;
322 using DualTensorAllocType = ddc::Chunk<double, DualTensorDomainType, AllocatorType>;
324 using HodgeStarTensorType
326 using DualHodgeStarTensorType
331 ExecSpace m_exec_space;
332 std::optional<HodgeStarAllocType> m_hodge_star_alloc;
333 std::optional<DualHodgeStarAllocType> m_dual_hodge_star_alloc;
334 std::optional<DualTensorAllocType> m_dual_tensor_alloc;
335 std::optional<HodgeStarTensorType> m_hodge_star;
336 std::optional<DualHodgeStarTensorType> m_dual_hodge_star;
337 std::optional<DualTensorType> m_dual_tensor_buffer;
339 LowerChainType m_lower_chain;
343 ExecSpace
const& exec_space,
344 HodgeStarTensorType&& hodge_star,
345 DualHodgeStarTensorType&& dual_hodge_star,
346 DualTensorType&& dual_tensor_buffer)
347 : m_exec_space(exec_space)
348 , m_hodge_star(std::move(hodge_star))
349 , m_dual_hodge_star(std::move(dual_hodge_star))
350 , m_dual_tensor_buffer(std::move(dual_tensor_buffer))
351 , m_chain(
tangent_basis<DualTensorIndex::rank() + 1, NonSpectatorDimensions>(exec_space))
352 , m_lower_chain(
tangent_basis<DualTensorIndex::rank(), NonSpectatorDimensions>(exec_space))
357 ExecSpace
const& exec_space,
360 PositionType position)
361 : m_exec_space(exec_space)
362 , m_chain(
tangent_basis<DualTensorIndex::rank() + 1, NonSpectatorDimensions>(exec_space))
363 , m_lower_chain(
tangent_basis<DualTensorIndex::rank(), NonSpectatorDimensions>(exec_space))
370 TargetHodgeOutputIndices>> dual_hodge_star_accessor;
373 m_hodge_star_alloc.emplace(
374 HodgeStarDomainType(metric.non_indices_domain(), hodge_star_accessor.domain()),
376 m_dual_hodge_star_alloc.emplace(
377 DualHodgeStarDomainType(
378 metric.non_indices_domain(),
379 dual_hodge_star_accessor.domain()),
381 m_dual_tensor_alloc.emplace(
382 DualTensorDomainType(tensor.non_indices_domain(), dual_tensor_accessor.
domain()),
385 m_hodge_star.emplace(*m_hodge_star_alloc);
386 m_dual_hodge_star.emplace(*m_dual_hodge_star_alloc);
387 m_dual_tensor_buffer.emplace(*m_dual_tensor_alloc);
390 SourceHodgeInputIndices,
391 SourceHodgeOutputIndices>(exec_space, *m_hodge_star, metric, position);
394 TargetHodgeOutputIndices>(exec_space, *m_dual_hodge_star, metric, position);
397 CodifferentialTensorType
run(CodifferentialTensorType codifferential_tensor, TensorType tensor)
400 auto exec_space = m_exec_space;
401 auto hodge_star = *m_hodge_star;
402 auto dual_hodge_star = *m_dual_hodge_star;
403 auto dual_tensor_buffer = *m_dual_tensor_buffer;
404 auto chain = m_chain;
405 auto lower_chain = m_lower_chain;
407 SIMILIE_DEBUG_LOG(
"similie_apply_first_hodge_star_for_codifferential");
408 ddc::parallel_for_each(
409 "similie_apply_first_hodge_star_for_codifferential",
411 dual_tensor_buffer.non_indices_domain(),
413 typename TensorType::non_indices_domain_t::discrete_element_type elem) {
415 tensor_prod(dual_tensor_buffer[elem], tensor[elem], hodge_star[elem]);
418 SIMILIE_DEBUG_LOG(
"similie_apply_second_hodge_star_for_codifferential");
419 ddc::parallel_for_each(
420 "similie_apply_second_hodge_star_for_codifferential",
422 codifferential_tensor.non_indices_domain(),
424 typename TensorType::non_indices_domain_t::discrete_element_type elem) {
426 dual_codifferential_accessor;
427 std::array<double, DualCodifferentialIndex::access_size()>
428 dual_codifferential_alloc {};
431 ddc::DiscreteDomain<DualCodifferentialIndex>,
432 Kokkos::layout_right,
433 typename TensorType::memory_space>
434 dual_codifferential_span(
435 dual_codifferential_alloc.data(),
436 dual_codifferential_accessor.
domain());
439 TransposedCoboundary<TagToRemoveFromCochain, DualTensorIndex>::run(
441 [&](
auto sampled_elem,
auto dual_elem) {
443 dual_tensor_buffer.non_indices_domain(),
447 return dual_tensor_buffer.mem(sampled_elem, dual_elem);
454 codifferential_tensor[elem],
456 dual_hodge_star[elem]);
458 (TagToRemoveFromCochain::size() * (CochainTag::rank() + 1) + 1) % 2
460 codifferential_tensor[elem] *= -1;
464 return codifferential_tensor;
469 tensor::TensorIndex MetricIndex,
470 tensor::TensorNatIndex TagToRemoveFromCochain,
471 tensor::TensorIndex CochainTag,
473 misc::Specialization<tensor::Tensor> TensorType,
474 misc::Specialization<tensor::Tensor> MetricType,
475 misc::Specialization<tensor::Tensor> PositionType>
478 TagToRemoveFromCochain,
485 ExecSpace
const& exec_space,
488 PositionType position)
492 TagToRemoveFromCochain,
497 ExecSpace>(exec_space, tensor, metric, position);
510 ExecSpace
const& exec_space,
512 codifferential_tensor,
514 HodgeStarType hodge_star,
515 DualHodgeStarType dual_hodge_star,
516 DualTensorType dual_tensor_buffer)
520 TagToRemoveFromCochain::size() - CochainTag::rank(),
521 TagToRemoveFromCochain>;
522 using dual_tensor_index = misc::
523 convert_type_seq_to_t<tensor::TensorAntisymmetricIndex, source_hodge_output_indices>;
524 using target_hodge_input_indices = ddc::type_seq_merge_t<
525 ddc::detail::TypeSeq<TagToRemoveFromCochain>,
526 source_hodge_output_indices>;
527 using dual_codifferential_index = misc::
528 convert_type_seq_to_t<tensor::TensorAntisymmetricIndex, target_hodge_input_indices>;
529 using non_spectator_dimensions =
typename detail::NonSpectatorDimension<
530 TagToRemoveFromCochain,
531 typename TensorType::non_indices_domain_t>::type;
536 SIMILIE_DEBUG_LOG(
"similie_apply_first_hodge_star_for_codifferential");
537 ddc::parallel_for_each(
538 "similie_apply_first_hodge_star_for_codifferential",
540 dual_tensor_buffer.non_indices_domain(),
541 KOKKOS_LAMBDA(
typename TensorType::non_indices_domain_t::discrete_element_type elem) {
545 SIMILIE_DEBUG_LOG(
"similie_apply_second_hodge_star_for_codifferential");
546 ddc::parallel_for_each(
547 "similie_apply_second_hodge_star_for_codifferential",
549 codifferential_tensor.non_indices_domain(),
550 KOKKOS_LAMBDA(
typename TensorType::non_indices_domain_t::discrete_element_type elem) {
552 dual_codifferential_accessor;
553 std::array<double, dual_codifferential_index::access_size()>
554 dual_codifferential_alloc {};
557 ddc::DiscreteDomain<dual_codifferential_index>,
558 Kokkos::layout_right,
559 typename TensorType::memory_space>
560 dual_codifferential_span(
561 dual_codifferential_alloc.data(),
562 dual_codifferential_accessor.
domain());
567 [&](
auto sampled_elem,
auto dual_elem) {
569 dual_tensor_buffer.non_indices_domain(),
573 return dual_tensor_buffer.mem(sampled_elem, dual_elem);
580 codifferential_tensor[elem],
582 dual_hodge_star[elem]);
584 (TagToRemoveFromCochain::size() * (CochainTag::rank() + 1) + 1) % 2 == 1) {
585 codifferential_tensor[elem] *= -1;
589 return codifferential_tensor;
601 ExecSpace
const& exec_space,
603 codifferential_tensor,
606 PositionType position)
611 TagToRemoveFromCochain,
612 CochainTag>(exec_space, tensor, metric, position)
613 .run(codifferential_tensor, tensor);
CodifferentialTensorType run(CodifferentialTensorType codifferential_tensor, TensorType tensor) const
StagedCodifferential(ExecSpace const &exec_space, HodgeStarTensorType &&hodge_star, DualHodgeStarTensorType &&dual_hodge_star, DualTensorType &&dual_tensor_buffer)
static constexpr discrete_domain_type domain()
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... >
ddc::detail::convert_type_seq_to_discrete_domain_t< ddc::type_seq_merge_t< ddc::detail::TypeSeq< misc::convert_type_seq_to_t< tensor::TensorFullIndex, Indices1 > >, std::conditional_t<(ddc::type_seq_size_v< Indices2 >==0), ddc::detail::TypeSeq<>, ddc::detail::TypeSeq< misc::convert_type_seq_to_t< tensor::TensorAntisymmetricIndex, Indices2 > > > > > hodge_star_domain_t
typename detail:: CodifferentialTensorType< TagToRemoveFromCochain, CochainTag, TensorType >::type codifferential_tensor_t
Chain(Head, Tail...) -> Chain< typename Head::value_type, typename Head::array_layout, typename Head::memory_space >
StagedCodifferential< MetricIndex, TagToRemoveFromCochain, CochainTag, TensorType, MetricType, PositionType, ExecSpace > make_staged_codifferential(ExecSpace const &exec_space, TensorType tensor, MetricType metric, PositionType position)
HodgeStarType fill_discrete_hodge_star(ExecSpace const &exec_space, HodgeStarType hodge_star, MetricType metric, PositionType position)
codifferential_tensor_t< TagToRemoveFromCochain, CochainTag, TensorType > codifferential(ExecSpace const &exec_space, codifferential_tensor_t< TagToRemoveFromCochain, CochainTag, TensorType > codifferential_tensor, TensorType tensor, HodgeStarType hodge_star, DualHodgeStarType dual_hodge_star, DualTensorType dual_tensor_buffer)
typename detail::CodifferentialIndex< TagToRemoveFromCochain, CochainTag >::type codifferential_index_t
typename detail::CodifferentialHodgeOutputIndexSeq< EndId, T >::type codifferential_hodge_output_indices_t
typename detail::CodifferentialType< CochainType >::type codifferential_t
KOKKOS_FUNCTION bool domain_contains(ddc::DiscreteDomain< DDim... > dom, ddc::DiscreteElement< ODDim... > elem)
typename detail::ConvertTypeSeqTo< T, Seq >::type convert_type_seq_to_t
Tensor(ddc::Chunk< ElementType, SupportType, Allocator >) -> Tensor< ElementType, SupportType, Kokkos::layout_right, typename Allocator::memory_space >
detail::Upper< T >::type upper_t
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::Uncharacterize< Index >::type uncharacterize_t
detail::Lower< T >::type lower_t
bool constexpr is_covariant_v
detail::TensorAccessorForDomain< Dom >::type tensor_accessor_for_domain_t
The top-level namespace of SimiLie.
static KOKKOS_FUNCTION void run(auto codifferential_tensor, TensorType tensor, MetricType metric, PositionType position, auto chain, auto lower_chain, typename TensorType::non_indices_domain_t::discrete_element_type elem)