SimiLie
Loading...
Searching...
No Matches
laplacian.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/misc/specialization.hpp>
9#include <similie/tensor/character.hpp>
10#include <similie/tensor/tensor_impl.hpp>
11
12#include "coboundary.hpp"
13#include "codifferential.hpp"
14
15
16namespace sil {
17
18namespace exterior {
19
20namespace detail {
21
22template <
23 tensor::TensorIndex MetricIndex,
24 tensor::TensorNatIndex LaplacianDummyIndex,
25 tensor::TensorIndex CochainTag,
26 misc::Specialization<tensor::Tensor> TensorType,
27 misc::Specialization<tensor::Tensor> MetricType,
28 class ExecSpace>
29TensorType codifferential_of_coboundary(
30 ExecSpace const& exec_space,
31 TensorType out_tensor,
32 TensorType tensor,
33 MetricType inv_metric)
34{
35 // Coboundary
36 [[maybe_unused]] tensor::TensorAccessor<coboundary_index_t<LaplacianDummyIndex, CochainTag>>
37 derivative_accessor;
38 ddc::cartesian_prod_t<
39 typename TensorType::non_indices_domain_t,
40 ddc::DiscreteDomain<coboundary_index_t<LaplacianDummyIndex, CochainTag>>>
41 derivative_tensor_dom(tensor.non_indices_domain(), derivative_accessor.domain());
42 ddc::Chunk derivative_tensor_alloc(
43 derivative_tensor_dom,
44 ddc::KokkosAllocator<double, typename ExecSpace::memory_space>());
45 sil::tensor::Tensor derivative_tensor(derivative_tensor_alloc);
46
47 sil::exterior::deriv<LaplacianDummyIndex, CochainTag>(exec_space, derivative_tensor, tensor);
48
49 // Codifferential
51 MetricIndex,
52 LaplacianDummyIndex,
54 LaplacianDummyIndex,
55 CochainTag>>(exec_space, out_tensor, derivative_tensor, inv_metric);
56
57 return out_tensor;
58}
59
60template <
61 tensor::TensorIndex MetricIndex,
62 tensor::TensorNatIndex LaplacianDummyIndex,
63 tensor::TensorIndex CochainTag,
64 misc::Specialization<tensor::Tensor> TensorType,
65 misc::Specialization<tensor::Tensor> MetricType,
66 class ExecSpace>
67TensorType coboundary_of_codifferential(
68 ExecSpace const& exec_space,
69 TensorType out_tensor,
70 TensorType tensor,
71 MetricType inv_metric)
72{
73 // Codifferential
74 [[maybe_unused]] tensor::TensorAccessor<codifferential_index_t<LaplacianDummyIndex, CochainTag>>
75 codifferential_accessor;
76 ddc::cartesian_prod_t<
77 typename TensorType::non_indices_domain_t,
78 ddc::DiscreteDomain<codifferential_index_t<LaplacianDummyIndex, CochainTag>>>
79 codifferential_tensor_dom(
80 tensor.non_indices_domain(),
81 codifferential_accessor.domain());
82 ddc::Chunk codifferential_tensor_alloc(
83 codifferential_tensor_dom,
84 ddc::KokkosAllocator<double, typename ExecSpace::memory_space>());
85 sil::tensor::Tensor codifferential_tensor(codifferential_tensor_alloc);
86
88 MetricIndex,
89 LaplacianDummyIndex,
90 CochainTag>(exec_space, codifferential_tensor, tensor, inv_metric);
91
92 // Coboundary
94 LaplacianDummyIndex,
96 LaplacianDummyIndex,
97 CochainTag>>(exec_space, out_tensor, codifferential_tensor);
98
99 return out_tensor;
100}
101
102template <class T>
103struct LaplacianDummy2 : T
104{
105};
106
107} // namespace detail
108
109template <
110 tensor::TensorIndex MetricIndex,
111 tensor::TensorNatIndex LaplacianDummyIndex,
112 tensor::TensorIndex CochainTag,
113 misc::Specialization<tensor::Tensor> TensorType,
114 misc::Specialization<tensor::Tensor> MetricType,
115 class ExecSpace>
116TensorType laplacian(
117 ExecSpace const& exec_space,
118 TensorType laplacian_tensor,
119 TensorType tensor,
120 MetricType inv_metric)
121{
123 using LaplacianDummyIndex2 = tensor::Covariant<
124 detail::LaplacianDummy2<tensor::uncharacterize_t<LaplacianDummyIndex>>>;
125
126 if constexpr (CochainTag::rank() == 0) {
127 detail::codifferential_of_coboundary<
128 MetricIndex,
129 LaplacianDummyIndex2,
130 CochainTag>(exec_space, laplacian_tensor, tensor, inv_metric);
131 } else if constexpr (CochainTag::rank() < LaplacianDummyIndex::size()) {
132 auto tmp_alloc = ddc::create_mirror(exec_space, laplacian_tensor);
133 tensor::Tensor tmp(tmp_alloc);
134
135 auto exec_spaces = Kokkos::Experimental::partition_space(exec_space, 1, 1);
136
137 detail::codifferential_of_coboundary<
138 MetricIndex,
139 LaplacianDummyIndex2,
140 CochainTag>(exec_spaces[0], laplacian_tensor, tensor, inv_metric);
141 detail::coboundary_of_codifferential<
142 MetricIndex,
143 LaplacianDummyIndex,
144 CochainTag>(exec_spaces[1], tmp, tensor, inv_metric);
145 exec_spaces[0].fence();
146 exec_spaces[1].fence();
147
148 ddc::parallel_for_each(
149 exec_space,
150 laplacian_tensor.domain(),
151 KOKKOS_LAMBDA(typename TensorType::discrete_element_type elem) {
152 laplacian_tensor(elem) += tmp(elem);
153 });
154 } else if constexpr (CochainTag::rank() == LaplacianDummyIndex::size()) {
155 detail::coboundary_of_codifferential<
156 MetricIndex,
157 LaplacianDummyIndex,
158 CochainTag>(exec_space, laplacian_tensor, tensor, inv_metric);
159 } else {
160 assert(false && "Unsupported differential form in Laplacian operator");
161 }
162
163 return laplacian_tensor;
164}
165
166} // namespace exterior
167
168} // namespace sil
TensorType laplacian(ExecSpace const &exec_space, TensorType laplacian_tensor, TensorType tensor, MetricType inv_metric)
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
typename detail::CoboundaryIndex< TagToAddToCochain, CochainTag >::type coboundary_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)
Tensor(ddc::Chunk< ElementType, SupportType, Allocator >) -> Tensor< ElementType, SupportType, Kokkos::layout_right, typename Allocator::memory_space >
bool constexpr is_covariant_v
The top-level namespace of SimiLie.
Definition csr.hpp:14