SimiLie
Loading...
Searching...
No Matches
codifferential.hpp
1// SPDX-FileCopyrightText: 2024 Baptiste Legouix
2// SPDX-License-Identifier: MIT
3
4#pragma once
5
6#include <ddc/ddc.hpp>
7
8#include <similie/exterior/hodge_star.hpp>
9#include <similie/misc/specialization.hpp>
10#include <similie/tensor/character.hpp>
11#include <similie/tensor/tensor_impl.hpp>
12
13#include <Kokkos_StdAlgorithms.hpp>
14
15#include "cochain.hpp"
16#include "cosimplex.hpp"
17
18
19namespace sil {
20
21namespace exterior {
22
23namespace detail {
24
25template <class T>
26struct CodifferentialType;
27
28template <
29 std::size_t K,
30 class... Tag,
31 class ElementType,
32 class LayoutStridedPolicy1,
33 class LayoutStridedPolicy2,
34 class ExecSpace>
35struct CodifferentialType<
36 Cochain<Chain<Simplex<K, Tag...>, LayoutStridedPolicy1, ExecSpace>,
37 ElementType,
38 LayoutStridedPolicy2>>
39{
40 using type = Cosimplex<Simplex<K - 1, Tag...>, ElementType>;
41};
42
43} // namespace detail
44
45template <misc::Specialization<Cochain> CochainType>
46using codifferential_t = typename detail::CodifferentialType<CochainType>::type;
47
48namespace detail {
49
50template <class TagToRemoveFromCochain, class CochainTag>
51struct CodifferentialIndex;
52
53template <tensor::TensorNatIndex TagToRemoveFromCochain, tensor::TensorNatIndex CochainTag>
54 requires(CochainTag::rank() == 1 && std::is_same_v<TagToRemoveFromCochain, CochainTag>)
55struct CodifferentialIndex<TagToRemoveFromCochain, CochainTag>
56{
58};
59
60template <tensor::TensorNatIndex TagToRemoveFromCochain, tensor::TensorNatIndex Tag>
61struct CodifferentialIndex<
62 TagToRemoveFromCochain,
63 tensor::TensorAntisymmetricIndex<TagToRemoveFromCochain, Tag>>
64{
65 using type = Tag;
66};
67
68template <tensor::TensorNatIndex TagToRemoveFromCochain, tensor::TensorNatIndex... Tag>
69 requires(sizeof...(Tag) > 1)
70struct CodifferentialIndex<
71 TagToRemoveFromCochain,
73{
74 using type = tensor::TensorAntisymmetricIndex<Tag...>;
75};
76
77} // namespace detail
78
79template <class TagToRemoveFromCochain, class CochainTag>
81 typename detail::CodifferentialIndex<TagToRemoveFromCochain, CochainTag>::type;
82
83namespace detail {
84
85template <
86 tensor::TensorNatIndex TagToRemoveFromCochain,
87 tensor::TensorIndex CochainTag,
89struct CodifferentialTensorType;
90
91template <
92 tensor::TensorNatIndex TagToRemoveFromCochain,
93 tensor::TensorIndex CochainIndex,
94 class ElementType,
95 class... DDim,
96 class SupportType,
97 class MemorySpace>
98struct CodifferentialTensorType<
99 TagToRemoveFromCochain,
100 CochainIndex,
101 tensor::Tensor<ElementType, ddc::DiscreteDomain<DDim...>, SupportType, MemorySpace>>
102{
103 static_assert(ddc::type_seq_contains_v<
104 ddc::detail::TypeSeq<CochainIndex>,
105 ddc::detail::TypeSeq<DDim...>>);
106 using type = tensor::Tensor<
107 ElementType,
108 ddc::replace_dim_of_t<
109 ddc::DiscreteDomain<DDim...>,
110 CochainIndex,
112 SupportType,
113 MemorySpace>;
114};
115
116} // namespace detail
117
118template <
119 tensor::TensorNatIndex TagToRemoveFromCochain,
120 tensor::TensorIndex CochainTag,
122using codifferential_tensor_t = typename detail::
123 CodifferentialTensorType<TagToRemoveFromCochain, CochainTag, TensorType>::type;
124
125namespace detail {
126
127template <std::size_t I, class T>
128struct CodifferentialDummyIndex : tensor::uncharacterize_t<T>
129{
130};
131
132template <class Ids, class T>
133struct CodifferentialDummyIndexSeq_;
134
135template <std::size_t... Id, class T>
136struct CodifferentialDummyIndexSeq_<std::index_sequence<Id...>, T>
137{
138 using type = ddc::detail::TypeSeq<tensor::Covariant<CodifferentialDummyIndex<Id, T>>...>;
139};
140
141template <std::size_t EndId, class T>
142struct CodifferentialDummyIndexSeq;
143
144template <std::size_t EndId, class T>
145 requires(EndId == 0)
146struct CodifferentialDummyIndexSeq<EndId, T>
147{
148 using type = ddc::detail::TypeSeq<>;
149};
150
151template <std::size_t EndId, class T>
152 requires(EndId > 0)
153struct CodifferentialDummyIndexSeq<EndId, T>
154{
155 using type = typename CodifferentialDummyIndexSeq_<std::make_index_sequence<EndId>, T>::type;
156};
157
158} // namespace detail
159
160template <
161 tensor::TensorIndex MetricIndex,
162 tensor::TensorNatIndex TagToRemoveFromCochain,
163 tensor::TensorIndex CochainTag,
166 class ExecSpace>
168 ExecSpace const& exec_space,
170 codifferential_tensor,
171 TensorType tensor,
172 MetricType inv_metric)
173{
176 using NuLowSeq = typename detail::CodifferentialDummyIndexSeq<
177 TagToRemoveFromCochain::size() - CochainTag::rank(),
178 TagToRemoveFromCochain>::type;
179 using RhoLowSeq = ddc::type_seq_merge_t<ddc::detail::TypeSeq<TagToRemoveFromCochain>, NuLowSeq>;
180 using RhoUpSeq = tensor::upper_t<RhoLowSeq>;
181 using SigmaLowSeq = ddc::type_seq_remove_t<
183 ddc::detail::TypeSeq<TagToRemoveFromCochain>>;
184
187
188 // Hodge star
189 [[maybe_unused]] sil::tensor::tensor_accessor_for_domain_t<HodgeStarDomain> hodge_star_accessor;
190 ddc::cartesian_prod_t<typename MetricType::non_indices_domain_t, HodgeStarDomain>
191 hodge_star_dom(inv_metric.non_indices_domain(), hodge_star_accessor.domain());
192 ddc::Chunk hodge_star_alloc(
193 hodge_star_dom,
194 ddc::KokkosAllocator<double, typename ExecSpace::memory_space>());
195 sil::tensor::Tensor hodge_star(hodge_star_alloc);
196
199 MuUpSeq,
200 NuLowSeq>(exec_space, hodge_star, inv_metric);
201
202 // Dual tensor
203 [[maybe_unused]] tensor::TensorAccessor<
205 dual_tensor_accessor;
206 ddc::cartesian_prod_t<
207 typename TensorType::non_indices_domain_t,
208 ddc::DiscreteDomain<
210 dual_tensor_dom(tensor.non_indices_domain(), dual_tensor_accessor.domain());
211 ddc::Chunk dual_tensor_alloc(
212 dual_tensor_dom,
213 ddc::KokkosAllocator<double, typename ExecSpace::memory_space>());
214 sil::tensor::Tensor dual_tensor(dual_tensor_alloc);
215
216 ddc::parallel_for_each(
217 exec_space,
218 dual_tensor.non_indices_domain(),
219 KOKKOS_LAMBDA(typename TensorType::non_indices_domain_t::discrete_element_type elem) {
220 sil::tensor::tensor_prod(dual_tensor[elem], tensor[elem], hodge_star[elem]);
221 });
222
223 // Dual codifferential
224 [[maybe_unused]] tensor::TensorAccessor<
226 dual_codifferential_accessor;
227 ddc::cartesian_prod_t<
228 typename TensorType::non_indices_domain_t,
229 ddc::DiscreteDomain<
231 dual_codifferential_dom(
232 tensor.non_indices_domain(),
233 dual_codifferential_accessor.domain());
234 ddc::Chunk dual_codifferential_alloc(
235 dual_codifferential_dom,
236 ddc::KokkosAllocator<double, typename ExecSpace::memory_space>());
237 sil::tensor::Tensor dual_codifferential(dual_codifferential_alloc);
239 TagToRemoveFromCochain,
242 NuLowSeq>>(exec_space, dual_codifferential, dual_tensor);
243
244 // Hodge star 2
246 hodge_star_accessor2;
247 ddc::cartesian_prod_t<typename MetricType::non_indices_domain_t, HodgeStarDomain2>
248 hodge_star_dom2(inv_metric.non_indices_domain(), hodge_star_accessor2.domain());
249 ddc::Chunk hodge_star_alloc2(
250 hodge_star_dom2,
251 ddc::KokkosAllocator<double, typename ExecSpace::memory_space>());
252 sil::tensor::Tensor hodge_star2(hodge_star_alloc2);
253
256 RhoUpSeq,
257 SigmaLowSeq>(exec_space, hodge_star2, inv_metric);
258
259 // Codifferential
260 ddc::parallel_for_each(
261 exec_space,
262 codifferential_tensor.non_indices_domain(),
263 KOKKOS_LAMBDA(typename TensorType::non_indices_domain_t::discrete_element_type elem) {
265 codifferential_tensor[elem],
266 dual_codifferential[elem],
267 hodge_star2[elem]);
268 if constexpr (
269 (TagToRemoveFromCochain::size() * (CochainTag::rank() + 1) + 1) % 2 == 1) {
270 codifferential_tensor[elem] *= -1;
271 }
272 });
273
274 return codifferential_tensor;
275}
276
277} // namespace exterior
278
279} // namespace sil
HodgeStarType fill_hodge_star(ExecSpace const &exec_space, HodgeStarType hodge_star, MetricDeterminantType metric_determinant, MetricProdType metric_prod)
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... >
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 >
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
coboundary_tensor_t< TagToAddToCochain, CochainTag, TensorType > deriv(ExecSpace const &exec_space, coboundary_tensor_t< TagToAddToCochain, CochainTag, TensorType > coboundary_tensor, TensorType tensor)
typename detail::CodifferentialIndex< TagToRemoveFromCochain, CochainTag >::type codifferential_index_t
codifferential_tensor_t< TagToRemoveFromCochain, CochainTag, TensorType > codifferential(ExecSpace const &exec_space, codifferential_tensor_t< TagToRemoveFromCochain, CochainTag, TensorType > codifferential_tensor, TensorType tensor, MetricType inv_metric)
typename detail::CodifferentialType< CochainType >::type codifferential_t
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
Definition character.hpp:80
bool constexpr is_covariant_v
detail::TensorAccessorForDomain< Dom >::type tensor_accessor_for_domain_t
The top-level namespace of SimiLie.
Definition csr.hpp:14