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