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 <optional>
7#include <utility>
8
9#include <ddc/ddc.hpp>
10
11#include <similie/misc/domain_contains.hpp>
12#include <similie/misc/macros.hpp>
13#include <similie/misc/specialization.hpp>
14#include <similie/tensor/character.hpp>
15#include <similie/tensor/tensor_impl.hpp>
16
17#include "coboundary.hpp"
18#include "codifferential.hpp"
19
20
21namespace sil {
22
23namespace exterior {
24
25namespace detail {
26
27template <
28 tensor::TensorIndex MetricIndex,
29 tensor::TensorNatIndex LaplacianDummyIndex,
30 tensor::TensorIndex CochainTag,
31 misc::Specialization<tensor::Tensor> DualTensorBufferType,
32 misc::Specialization<tensor::Tensor> TensorType,
33 misc::Specialization<tensor::Tensor> HodgeStarType,
34 misc::Specialization<tensor::Tensor> DualHodgeStarType,
35 class ExecSpace>
36TensorType codifferential_of_coboundary(
37 ExecSpace const& exec_space,
38 TensorType out_tensor,
39 TensorType tensor,
40 HodgeStarType hodge_star,
41 DualHodgeStarType dual_hodge_star,
42 DualTensorBufferType dual_tensor_buffer)
43{
44 using coboundary_output_index = coboundary_index_t<LaplacianDummyIndex, CochainTag>;
45 using codifferential_hodge_output_indices = codifferential_hodge_output_indices_t<
46 LaplacianDummyIndex::size() - coboundary_output_index::rank(),
47 LaplacianDummyIndex>;
48 using coboundary_dual_tensor_index = misc::convert_type_seq_to_t<
49 tensor::TensorAntisymmetricIndex,
50 codifferential_hodge_output_indices>;
51 using dual_codifferential_hodge_input_indices = ddc::type_seq_merge_t<
52 ddc::detail::TypeSeq<LaplacianDummyIndex>,
53 codifferential_hodge_output_indices>;
54 using dual_codifferential_index = misc::convert_type_seq_to_t<
55 tensor::TensorAntisymmetricIndex,
56 dual_codifferential_hodge_input_indices>;
57 auto chain = tangent_basis<
58 CochainTag::rank() + 1,
59 typename detail::NonSpectatorDimension<
60 LaplacianDummyIndex,
61 typename TensorType::non_indices_domain_t>::type>(exec_space);
62 auto lower_chain = tangent_basis<
63 CochainTag::rank(),
64 typename detail::NonSpectatorDimension<
65 LaplacianDummyIndex,
66 typename TensorType::non_indices_domain_t>::type>(exec_space);
67 auto dual_chain = tangent_basis<
68 coboundary_dual_tensor_index::rank() + 1,
69 typename detail::NonSpectatorDimension<
70 LaplacianDummyIndex,
71 typename TensorType::non_indices_domain_t>::type>(exec_space);
72 auto dual_lower_chain = tangent_basis<
73 coboundary_dual_tensor_index::rank(),
74 typename detail::NonSpectatorDimension<
75 LaplacianDummyIndex,
76 typename TensorType::non_indices_domain_t>::type>(exec_space);
77
78 SIMILIE_DEBUG_LOG("similie_deriv_and_apply_first_hodge_star_for_codifferential_of_coboundary");
79 ddc::parallel_for_each(
80 "similie_deriv_and_apply_first_hodge_star_for_codifferential_of_coboundary",
81 exec_space,
82 dual_tensor_buffer.non_indices_domain(),
83 KOKKOS_LAMBDA(typename TensorType::non_indices_domain_t::discrete_element_type elem) {
84 [[maybe_unused]] tensor::TensorAccessor<coboundary_output_index>
85 derivative_accessor;
86 std::array<double, coboundary_output_index::access_size()> derivative_alloc {};
87 ddc::ChunkSpan<
88 double,
89 ddc::DiscreteDomain<coboundary_output_index>,
90 Kokkos::layout_right,
91 typename TensorType::memory_space>
92 derivative_span(derivative_alloc.data(), derivative_accessor.domain());
93 sil::tensor::Tensor derivative_tensor(derivative_span);
94
95 Coboundary<LaplacianDummyIndex, CochainTag>::run(
96 derivative_tensor,
97 [&](auto sampled_elem, auto cochain_elem) {
98 auto const clamped_elem = misc::
99 clamp_to_domain(tensor.non_indices_domain(), sampled_elem);
100 return tensor.mem(clamped_elem, cochain_elem);
101 },
102 chain,
103 lower_chain,
104 elem);
105
107 tensor_prod(dual_tensor_buffer[elem], derivative_tensor, hodge_star[elem]);
108 });
109
110 SIMILIE_DEBUG_LOG("similie_deriv_and_apply_second_hodge_star_for_codifferential_of_coboundary");
111 ddc::parallel_for_each(
112 "similie_deriv_and_apply_second_hodge_star_for_codifferential_of_coboundary",
113 exec_space,
114 out_tensor.non_indices_domain(),
115 KOKKOS_LAMBDA(typename TensorType::non_indices_domain_t::discrete_element_type elem) {
116 [[maybe_unused]] tensor::TensorAccessor<dual_codifferential_index>
117 dual_codifferential_accessor;
118 std::array<double, dual_codifferential_index::access_size()>
119 dual_codifferential_alloc {};
120 ddc::ChunkSpan<
121 double,
122 ddc::DiscreteDomain<dual_codifferential_index>,
123 Kokkos::layout_right,
124 typename TensorType::memory_space>
125 dual_codifferential_span(
126 dual_codifferential_alloc.data(),
127 dual_codifferential_accessor.domain());
128 sil::tensor::Tensor dual_codifferential(dual_codifferential_span);
129
130 TransposedCoboundary<LaplacianDummyIndex, coboundary_dual_tensor_index>::run(
131 dual_codifferential,
132 [&](auto sampled_elem, auto dual_elem) {
134 dual_tensor_buffer.non_indices_domain(),
135 sampled_elem)) {
136 return 0.0;
137 }
138 return dual_tensor_buffer.mem(sampled_elem, dual_elem);
139 },
140 dual_chain,
141 dual_lower_chain,
142 elem);
143
145 tensor_prod(out_tensor[elem], dual_codifferential, dual_hodge_star[elem]);
146 if constexpr (
147 (LaplacianDummyIndex::size() * (coboundary_output_index::rank() + 1) + 1)
148 % 2
149 == 1) {
150 out_tensor[elem] *= -1;
151 }
152 });
153
154 return out_tensor;
155}
156
157template <class LaplacianDummyIndex, class CochainTag>
158concept ZeroRankLaplacianCochain = CochainTag::rank() == 0;
159
160template <class LaplacianDummyIndex, class CochainTag>
161concept IntermediateRankLaplacianCochain
162 = CochainTag::rank() > 0 && CochainTag::rank() < LaplacianDummyIndex::size();
163
164template <class LaplacianDummyIndex, class CochainTag>
165concept TopRankLaplacianCochain = CochainTag::rank() == LaplacianDummyIndex::size();
166
167} // namespace detail
168
169template <class T>
173
174template <class... Args>
176
177template <
178 tensor::TensorIndex MetricIndex,
179 tensor::TensorNatIndex LaplacianDummyIndex,
180 tensor::TensorIndex CochainTag,
184 class ExecSpace>
185 requires(detail::ZeroRankLaplacianCochain<LaplacianDummyIndex, CochainTag>)
186class StagedLaplacian<
187 MetricIndex,
188 LaplacianDummyIndex,
189 CochainTag,
190 TensorType,
191 MetricType,
192 PositionType,
193 ExecSpace>
194{
195 using MemorySpace = typename TensorType::memory_space;
196 using AllocatorType = ddc::KokkosAllocator<double, MemorySpace>;
197 using CodifferentialOfCoboundaryIndex
201 using CoboundaryHodgeInputIndices
203 using CoboundaryHodgeOutputIndices = codifferential_hodge_output_indices_t<
204 CodifferentialOfCoboundaryIndex::size() - CoboundaryOutputIndex::rank(),
205 CodifferentialOfCoboundaryIndex>;
206 using DualCoboundaryHodgeInputIndices = ddc::type_seq_merge_t<
207 ddc::detail::TypeSeq<CodifferentialOfCoboundaryIndex>,
208 CoboundaryHodgeOutputIndices>;
209 using DualCoboundaryHodgeOutputIndices = ddc::type_seq_remove_t<
211 ddc::detail::TypeSeq<CodifferentialOfCoboundaryIndex>>;
212 using CoboundaryDualTensorIndex = misc::
213 convert_type_seq_to_t<tensor::TensorAntisymmetricIndex, CoboundaryHodgeOutputIndices>;
214
215 using DerivativeHodgeStarDomainType = ddc::cartesian_prod_t<
216 typename MetricType::non_indices_domain_t,
218 using DualDerivativeHodgeStarDomainType = ddc::cartesian_prod_t<
219 typename MetricType::non_indices_domain_t,
222 DualCoboundaryHodgeOutputIndices>>;
223 using DerivativeDualTensorDomainType = ddc::cartesian_prod_t<
224 typename TensorType::non_indices_domain_t,
225 ddc::DiscreteDomain<CoboundaryDualTensorIndex>>;
226
227 using DerivativeHodgeStarAllocType
228 = ddc::Chunk<double, DerivativeHodgeStarDomainType, AllocatorType>;
229 using DualDerivativeHodgeStarAllocType
230 = ddc::Chunk<double, DualDerivativeHodgeStarDomainType, AllocatorType>;
231 using DerivativeDualTensorAllocType
232 = ddc::Chunk<double, DerivativeDualTensorDomainType, AllocatorType>;
233
234 using DerivativeHodgeStarTensorType = tensor::
235 Tensor<double, DerivativeHodgeStarDomainType, Kokkos::layout_right, MemorySpace>;
236 using DualDerivativeHodgeStarTensorType = tensor::
237 Tensor<double, DualDerivativeHodgeStarDomainType, Kokkos::layout_right, MemorySpace>;
238 using DerivativeDualTensorType = tensor::
239 Tensor<double, DerivativeDualTensorDomainType, Kokkos::layout_right, MemorySpace>;
240 ExecSpace m_exec_space;
241 std::optional<DerivativeHodgeStarAllocType> m_derivative_hodge_star_alloc;
242 std::optional<DualDerivativeHodgeStarAllocType> m_dual_derivative_hodge_star_alloc;
243 std::optional<DerivativeDualTensorAllocType> m_derivative_dual_tensor_alloc;
244 std::optional<DerivativeHodgeStarTensorType> m_derivative_hodge_star;
245 std::optional<DualDerivativeHodgeStarTensorType> m_dual_derivative_hodge_star;
246 std::optional<DerivativeDualTensorType> m_derivative_dual_tensor_buffer;
247
248public:
250 ExecSpace const& exec_space,
251 DerivativeHodgeStarTensorType&& derivative_hodge_star,
252 DualDerivativeHodgeStarTensorType&& dual_derivative_hodge_star,
253 DerivativeDualTensorType&& derivative_dual_tensor_buffer)
254 : m_exec_space(exec_space)
255 , m_derivative_hodge_star(std::move(derivative_hodge_star))
256 , m_dual_derivative_hodge_star(std::move(dual_derivative_hodge_star))
257 , m_derivative_dual_tensor_buffer(std::move(derivative_dual_tensor_buffer))
258 {
259 }
260
262 ExecSpace const& exec_space,
263 TensorType,
264 TensorType tensor,
265 MetricType metric,
266 PositionType position)
267 : m_exec_space(exec_space)
268 {
271 derivative_hodge_star_accessor;
274 DualCoboundaryHodgeOutputIndices>> dual_derivative_hodge_star_accessor;
276 derivative_dual_tensor_accessor;
277
278 m_derivative_hodge_star_alloc.emplace(
279 DerivativeHodgeStarDomainType(
280 metric.non_indices_domain(),
281 derivative_hodge_star_accessor.domain()),
282 AllocatorType());
283 m_dual_derivative_hodge_star_alloc.emplace(
284 DualDerivativeHodgeStarDomainType(
285 metric.non_indices_domain(),
286 dual_derivative_hodge_star_accessor.domain()),
287 AllocatorType());
288 m_derivative_dual_tensor_alloc.emplace(
289 DerivativeDualTensorDomainType(
290 tensor.non_indices_domain(),
291 derivative_dual_tensor_accessor.domain()),
292 AllocatorType());
293
294 m_derivative_hodge_star.emplace(*m_derivative_hodge_star_alloc);
295 m_dual_derivative_hodge_star.emplace(*m_dual_derivative_hodge_star_alloc);
296 m_derivative_dual_tensor_buffer.emplace(*m_derivative_dual_tensor_alloc);
297
299 exec_space,
300 *m_derivative_hodge_star,
301 metric,
302 position);
305 DualCoboundaryHodgeOutputIndices>(
306 exec_space,
307 *m_dual_derivative_hodge_star,
308 metric,
309 position);
310 }
311
312 TensorType run(TensorType laplacian_tensor, TensorType tensor)
313 {
314 return detail::codifferential_of_coboundary<
315 MetricIndex,
316 CodifferentialOfCoboundaryIndex,
317 CochainTag>(
318 m_exec_space,
319 laplacian_tensor,
320 tensor,
321 *m_derivative_hodge_star,
322 *m_dual_derivative_hodge_star,
323 *m_derivative_dual_tensor_buffer);
324 }
325};
326
327template <
328 tensor::TensorIndex MetricIndex,
329 tensor::TensorNatIndex LaplacianDummyIndex,
330 tensor::TensorIndex CochainTag,
331 class ExecSpace,
332 misc::Specialization<tensor::Tensor> TensorType,
333 misc::Specialization<tensor::Tensor> MetricType,
334 misc::Specialization<tensor::Tensor> PositionType>
335StagedLaplacian<
336 MetricIndex,
337 LaplacianDummyIndex,
338 CochainTag,
339 TensorType,
340 MetricType,
341 PositionType,
342 ExecSpace>
344 ExecSpace const& exec_space,
345 TensorType laplacian_tensor,
346 TensorType tensor,
347 MetricType metric,
348 PositionType position)
349{
350 return StagedLaplacian<
351 MetricIndex,
352 LaplacianDummyIndex,
353 CochainTag,
354 TensorType,
355 MetricType,
356 PositionType,
357 ExecSpace>(exec_space, laplacian_tensor, tensor, metric, position);
358}
359
360template <
361 tensor::TensorIndex MetricIndex,
362 tensor::TensorNatIndex LaplacianDummyIndex,
363 tensor::TensorIndex CochainTag,
367 class ExecSpace>
368 requires(detail::IntermediateRankLaplacianCochain<LaplacianDummyIndex, CochainTag>)
369class StagedLaplacian<
370 MetricIndex,
371 LaplacianDummyIndex,
372 CochainTag,
373 TensorType,
374 MetricType,
375 PositionType,
376 ExecSpace>
377{
378 using MemorySpace = typename TensorType::memory_space;
379 using AllocatorType = ddc::KokkosAllocator<double, MemorySpace>;
380 using CodifferentialOfCoboundaryIndex
381 = tensor::Covariant<IndexForCodifferentialOfCoboundaryInLaplacian<
384 using CoboundaryHodgeInputIndices
386 using CoboundaryHodgeOutputIndices = codifferential_hodge_output_indices_t<
387 CodifferentialOfCoboundaryIndex::size() - CoboundaryOutputIndex::rank(),
388 CodifferentialOfCoboundaryIndex>;
389 using DualCoboundaryHodgeInputIndices = ddc::type_seq_merge_t<
390 ddc::detail::TypeSeq<CodifferentialOfCoboundaryIndex>,
391 CoboundaryHodgeOutputIndices>;
392 using DualCoboundaryHodgeOutputIndices = ddc::type_seq_remove_t<
394 ddc::detail::TypeSeq<CodifferentialOfCoboundaryIndex>>;
395 using CoboundaryDualTensorIndex = misc::
396 convert_type_seq_to_t<tensor::TensorAntisymmetricIndex, CoboundaryHodgeOutputIndices>;
397
398 using CodifferentialHodgeInputIndices
400 using CodifferentialHodgeOutputIndices = codifferential_hodge_output_indices_t<
401 LaplacianDummyIndex::size() - CochainTag::rank(),
402 LaplacianDummyIndex>;
403 using DualCodifferentialHodgeInputIndices = ddc::type_seq_merge_t<
404 ddc::detail::TypeSeq<LaplacianDummyIndex>,
405 CodifferentialHodgeOutputIndices>;
406 using DualCodifferentialHodgeOutputIndices = ddc::type_seq_remove_t<
408 ddc::detail::TypeSeq<LaplacianDummyIndex>>;
409 using CodifferentialDualTensorIndex = misc::convert_type_seq_to_t<
411 CodifferentialHodgeOutputIndices>;
412 using CodifferentialOutputIndex = codifferential_index_t<LaplacianDummyIndex, CochainTag>;
413
414 using DerivativeHodgeStarDomainType = ddc::cartesian_prod_t<
415 typename MetricType::non_indices_domain_t,
417 using DualDerivativeHodgeStarDomainType = ddc::cartesian_prod_t<
418 typename MetricType::non_indices_domain_t,
421 DualCoboundaryHodgeOutputIndices>>;
422 using DerivativeDualTensorDomainType = ddc::cartesian_prod_t<
423 typename TensorType::non_indices_domain_t,
424 ddc::DiscreteDomain<CoboundaryDualTensorIndex>>;
425 using HodgeStarDomainType = ddc::cartesian_prod_t<
426 typename MetricType::non_indices_domain_t,
428 using DualHodgeStarDomainType = ddc::cartesian_prod_t<
429 typename MetricType::non_indices_domain_t,
432 DualCodifferentialHodgeOutputIndices>>;
433 using DualTensorDomainType = ddc::cartesian_prod_t<
434 typename TensorType::non_indices_domain_t,
435 ddc::DiscreteDomain<CodifferentialDualTensorIndex>>;
436 using CodifferentialDomainType = ddc::cartesian_prod_t<
437 typename TensorType::non_indices_domain_t,
438 ddc::DiscreteDomain<CodifferentialOutputIndex>>;
439
440 using DerivativeHodgeStarAllocType
441 = ddc::Chunk<double, DerivativeHodgeStarDomainType, AllocatorType>;
442 using DualDerivativeHodgeStarAllocType
443 = ddc::Chunk<double, DualDerivativeHodgeStarDomainType, AllocatorType>;
444 using DerivativeDualTensorAllocType
445 = ddc::Chunk<double, DerivativeDualTensorDomainType, AllocatorType>;
446 using HodgeStarAllocType = ddc::Chunk<double, HodgeStarDomainType, AllocatorType>;
447 using DualHodgeStarAllocType = ddc::Chunk<double, DualHodgeStarDomainType, AllocatorType>;
448 using DualTensorAllocType = ddc::Chunk<double, DualTensorDomainType, AllocatorType>;
449 using CodifferentialAllocType = ddc::Chunk<double, CodifferentialDomainType, AllocatorType>;
450 using CoboundaryOfCodifferentialAllocType
451 = ddc::Chunk<double, typename TensorType::discrete_domain_type, AllocatorType>;
452
453 using DerivativeHodgeStarTensorType = tensor::
454 Tensor<double, DerivativeHodgeStarDomainType, Kokkos::layout_right, MemorySpace>;
455 using DualDerivativeHodgeStarTensorType = tensor::
456 Tensor<double, DualDerivativeHodgeStarDomainType, Kokkos::layout_right, MemorySpace>;
457 using DerivativeDualTensorType = tensor::
458 Tensor<double, DerivativeDualTensorDomainType, Kokkos::layout_right, MemorySpace>;
459 using HodgeStarTensorType
461 using DualHodgeStarTensorType
463 using DualTensorType
465 using CodifferentialTensorType
467 ExecSpace m_exec_space;
468 std::optional<DerivativeHodgeStarAllocType> m_derivative_hodge_star_alloc;
469 std::optional<DualDerivativeHodgeStarAllocType> m_dual_derivative_hodge_star_alloc;
470 std::optional<DerivativeDualTensorAllocType> m_derivative_dual_tensor_alloc;
471 std::optional<HodgeStarAllocType> m_hodge_star_alloc;
472 std::optional<DualHodgeStarAllocType> m_dual_hodge_star_alloc;
473 std::optional<DualTensorAllocType> m_dual_tensor_alloc;
474 std::optional<CodifferentialAllocType> m_codifferential_alloc;
475 std::optional<CoboundaryOfCodifferentialAllocType> m_coboundary_of_codifferential_alloc;
476 std::optional<DerivativeHodgeStarTensorType> m_derivative_hodge_star;
477 std::optional<DualDerivativeHodgeStarTensorType> m_dual_derivative_hodge_star;
478 std::optional<DerivativeDualTensorType> m_derivative_dual_tensor_buffer;
479 std::optional<HodgeStarTensorType> m_hodge_star;
480 std::optional<DualHodgeStarTensorType> m_dual_hodge_star;
481 std::optional<DualTensorType> m_dual_tensor_buffer;
482 std::optional<CodifferentialTensorType> m_codifferential_tensor_buffer;
483 std::optional<TensorType> m_coboundary_of_codifferential_buffer;
484
485public:
487 ExecSpace const& exec_space,
488 DerivativeHodgeStarTensorType derivative_hodge_star,
489 DualDerivativeHodgeStarTensorType dual_derivative_hodge_star,
490 DerivativeDualTensorType derivative_dual_tensor_buffer,
491 HodgeStarTensorType hodge_star,
492 DualHodgeStarTensorType dual_hodge_star,
493 DualTensorType dual_tensor_buffer,
494 CodifferentialTensorType codifferential_tensor_buffer,
495 TensorType coboundary_of_codifferential_buffer)
496 : m_exec_space(exec_space)
497 , m_derivative_hodge_star(derivative_hodge_star)
498 , m_dual_derivative_hodge_star(dual_derivative_hodge_star)
499 , m_derivative_dual_tensor_buffer(derivative_dual_tensor_buffer)
500 , m_hodge_star(hodge_star)
501 , m_dual_hodge_star(dual_hodge_star)
502 , m_dual_tensor_buffer(dual_tensor_buffer)
503 , m_codifferential_tensor_buffer(codifferential_tensor_buffer)
504 , m_coboundary_of_codifferential_buffer(coboundary_of_codifferential_buffer)
505 {
506 }
507
509 ExecSpace const& exec_space,
510 TensorType laplacian_tensor,
511 TensorType tensor,
512 MetricType metric,
513 PositionType position)
514 : m_exec_space(exec_space)
515 {
518 derivative_hodge_star_accessor;
521 DualCoboundaryHodgeOutputIndices>> dual_derivative_hodge_star_accessor;
523 derivative_dual_tensor_accessor;
525 CodifferentialHodgeInputIndices,
526 CodifferentialHodgeOutputIndices>> hodge_star_accessor;
529 DualCodifferentialHodgeOutputIndices>> dual_hodge_star_accessor;
530 [[maybe_unused]] tensor::TensorAccessor<CodifferentialDualTensorIndex> dual_tensor_accessor;
531 [[maybe_unused]] tensor::TensorAccessor<CodifferentialOutputIndex> codifferential_accessor;
532
533 m_derivative_hodge_star_alloc.emplace(
534 DerivativeHodgeStarDomainType(
535 metric.non_indices_domain(),
536 derivative_hodge_star_accessor.domain()),
537 AllocatorType());
538 m_dual_derivative_hodge_star_alloc.emplace(
539 DualDerivativeHodgeStarDomainType(
540 metric.non_indices_domain(),
541 dual_derivative_hodge_star_accessor.domain()),
542 AllocatorType());
543 m_derivative_dual_tensor_alloc.emplace(
544 DerivativeDualTensorDomainType(
545 tensor.non_indices_domain(),
546 derivative_dual_tensor_accessor.domain()),
547 AllocatorType());
548 m_hodge_star_alloc.emplace(
549 HodgeStarDomainType(metric.non_indices_domain(), hodge_star_accessor.domain()),
550 AllocatorType());
551 m_dual_hodge_star_alloc.emplace(
552 DualHodgeStarDomainType(
553 metric.non_indices_domain(),
554 dual_hodge_star_accessor.domain()),
555 AllocatorType());
556 m_dual_tensor_alloc.emplace(
557 DualTensorDomainType(tensor.non_indices_domain(), dual_tensor_accessor.domain()),
558 AllocatorType());
559 m_codifferential_alloc.emplace(
560 CodifferentialDomainType(
561 tensor.non_indices_domain(),
562 codifferential_accessor.domain()),
563 AllocatorType());
564 m_coboundary_of_codifferential_alloc.emplace(laplacian_tensor.domain(), AllocatorType());
565
566 m_derivative_hodge_star.emplace(*m_derivative_hodge_star_alloc);
567 m_dual_derivative_hodge_star.emplace(*m_dual_derivative_hodge_star_alloc);
568 m_derivative_dual_tensor_buffer.emplace(*m_derivative_dual_tensor_alloc);
569 m_hodge_star.emplace(*m_hodge_star_alloc);
570 m_dual_hodge_star.emplace(*m_dual_hodge_star_alloc);
571 m_dual_tensor_buffer.emplace(*m_dual_tensor_alloc);
572 m_codifferential_tensor_buffer.emplace(*m_codifferential_alloc);
573 m_coboundary_of_codifferential_buffer.emplace(*m_coboundary_of_codifferential_alloc);
574
576 exec_space,
577 *m_derivative_hodge_star,
578 metric,
579 position);
582 DualCoboundaryHodgeOutputIndices>(
583 exec_space,
584 *m_dual_derivative_hodge_star,
585 metric,
586 position);
588 CodifferentialHodgeInputIndices,
589 CodifferentialHodgeOutputIndices>(exec_space, *m_hodge_star, metric, position);
592 DualCodifferentialHodgeOutputIndices>(
593 exec_space,
594 *m_dual_hodge_star,
595 metric,
596 position);
597 }
598
599 TensorType run(TensorType laplacian_tensor, TensorType tensor)
600 {
601 auto exec_spaces = Kokkos::Experimental::partition_space(m_exec_space, 1, 1);
602
603 detail::codifferential_of_coboundary<
604 MetricIndex,
605 CodifferentialOfCoboundaryIndex,
606 CochainTag>(
607 exec_spaces[0],
608 laplacian_tensor,
609 tensor,
610 *m_derivative_hodge_star,
611 *m_dual_derivative_hodge_star,
612 *m_derivative_dual_tensor_buffer);
613
615 MetricIndex,
616 LaplacianDummyIndex,
617 CochainTag,
618 TensorType,
619 MetricType,
620 PositionType,
621 ExecSpace>(
622 exec_spaces[1],
623 std::move(*m_hodge_star),
624 std::move(*m_dual_hodge_star),
625 std::move(*m_dual_tensor_buffer))
626 .run(*m_codifferential_tensor_buffer, tensor);
627 sil::exterior::
628 deriv<LaplacianDummyIndex, codifferential_index_t<LaplacianDummyIndex, CochainTag>>(
629 exec_spaces[1],
630 *m_coboundary_of_codifferential_buffer,
631 *m_codifferential_tensor_buffer);
632
633 exec_spaces[0].fence();
634 exec_spaces[1].fence();
635
636 auto coboundary_of_codifferential_buffer = *m_coboundary_of_codifferential_buffer;
637 SIMILIE_DEBUG_LOG("similie_add_coboundary_of_codifferential_contribution_to_laplacian");
638 ddc::parallel_for_each(
639 "similie_add_coboundary_of_codifferential_contribution_to_laplacian",
640 m_exec_space,
641 laplacian_tensor.domain(),
642 KOKKOS_LAMBDA(typename TensorType::discrete_element_type elem) {
643 laplacian_tensor.mem(elem) += coboundary_of_codifferential_buffer.mem(elem);
644 });
645
646 return laplacian_tensor;
647 }
648};
649
650template <
651 tensor::TensorIndex MetricIndex,
652 tensor::TensorNatIndex LaplacianDummyIndex,
653 tensor::TensorIndex CochainTag,
654 misc::Specialization<tensor::Tensor> TensorType,
655 misc::Specialization<tensor::Tensor> MetricType,
656 misc::Specialization<tensor::Tensor> PositionType,
657 class ExecSpace>
658 requires(detail::TopRankLaplacianCochain<LaplacianDummyIndex, CochainTag>)
660 MetricIndex,
661 LaplacianDummyIndex,
662 CochainTag,
663 TensorType,
664 MetricType,
665 PositionType,
666 ExecSpace>
667{
668private:
669 using MemorySpace = typename TensorType::memory_space;
670 using AllocatorType = ddc::KokkosAllocator<double, MemorySpace>;
671 using CodifferentialHodgeInputIndices
673 using CodifferentialHodgeOutputIndices = codifferential_hodge_output_indices_t<
674 LaplacianDummyIndex::size() - CochainTag::rank(),
675 LaplacianDummyIndex>;
676 using DualCodifferentialHodgeInputIndices = ddc::type_seq_merge_t<
677 ddc::detail::TypeSeq<LaplacianDummyIndex>,
678 CodifferentialHodgeOutputIndices>;
679 using DualCodifferentialHodgeOutputIndices = ddc::type_seq_remove_t<
681 ddc::detail::TypeSeq<LaplacianDummyIndex>>;
682 using CodifferentialDualTensorIndex = misc::convert_type_seq_to_t<
684 CodifferentialHodgeOutputIndices>;
685 using CodifferentialOutputIndex = codifferential_index_t<LaplacianDummyIndex, CochainTag>;
686
687 using HodgeStarDomainType = ddc::cartesian_prod_t<
688 typename MetricType::non_indices_domain_t,
690 using DualHodgeStarDomainType = ddc::cartesian_prod_t<
691 typename MetricType::non_indices_domain_t,
694 DualCodifferentialHodgeOutputIndices>>;
695 using DualTensorDomainType = ddc::cartesian_prod_t<
696 typename TensorType::non_indices_domain_t,
697 ddc::DiscreteDomain<CodifferentialDualTensorIndex>>;
698 using CodifferentialDomainType = ddc::cartesian_prod_t<
699 typename TensorType::non_indices_domain_t,
700 ddc::DiscreteDomain<CodifferentialOutputIndex>>;
701
702 using HodgeStarAllocType = ddc::Chunk<double, HodgeStarDomainType, AllocatorType>;
703 using DualHodgeStarAllocType = ddc::Chunk<double, DualHodgeStarDomainType, AllocatorType>;
704 using DualTensorAllocType = ddc::Chunk<double, DualTensorDomainType, AllocatorType>;
705 using CodifferentialAllocType = ddc::Chunk<double, CodifferentialDomainType, AllocatorType>;
706
707 using HodgeStarTensorType
709 using DualHodgeStarTensorType
711 using DualTensorType
713 using CodifferentialTensorType
715 ExecSpace m_exec_space;
716 std::optional<HodgeStarAllocType> m_hodge_star_alloc;
717 std::optional<DualHodgeStarAllocType> m_dual_hodge_star_alloc;
718 std::optional<DualTensorAllocType> m_dual_tensor_alloc;
719 std::optional<CodifferentialAllocType> m_codifferential_alloc;
720 std::optional<HodgeStarTensorType> m_hodge_star;
721 std::optional<DualHodgeStarTensorType> m_dual_hodge_star;
722 std::optional<DualTensorType> m_dual_tensor_buffer;
723 std::optional<CodifferentialTensorType> m_codifferential_tensor_buffer;
724
725public:
727 ExecSpace const& exec_space,
728 HodgeStarTensorType&& hodge_star,
729 DualHodgeStarTensorType&& dual_hodge_star,
730 DualTensorType&& dual_tensor_buffer,
731 CodifferentialTensorType&& codifferential_tensor_buffer)
732 : m_exec_space(exec_space)
733 , m_hodge_star(std::move(hodge_star))
734 , m_dual_hodge_star(std::move(dual_hodge_star))
735 , m_dual_tensor_buffer(std::move(dual_tensor_buffer))
736 , m_codifferential_tensor_buffer(std::move(codifferential_tensor_buffer))
737 {
738 }
739
741 ExecSpace const& exec_space,
742 TensorType,
743 TensorType tensor,
744 MetricType metric,
745 PositionType position)
746 : m_exec_space(exec_space)
747 {
749 CodifferentialHodgeInputIndices,
750 CodifferentialHodgeOutputIndices>> hodge_star_accessor;
753 DualCodifferentialHodgeOutputIndices>> dual_hodge_star_accessor;
754 [[maybe_unused]] tensor::TensorAccessor<CodifferentialDualTensorIndex> dual_tensor_accessor;
755 [[maybe_unused]] tensor::TensorAccessor<CodifferentialOutputIndex> codifferential_accessor;
756
757 m_hodge_star_alloc.emplace(
758 HodgeStarDomainType(metric.non_indices_domain(), hodge_star_accessor.domain()),
759 AllocatorType());
760 m_dual_hodge_star_alloc.emplace(
761 DualHodgeStarDomainType(
762 metric.non_indices_domain(),
763 dual_hodge_star_accessor.domain()),
764 AllocatorType());
765 m_dual_tensor_alloc.emplace(
766 DualTensorDomainType(tensor.non_indices_domain(), dual_tensor_accessor.domain()),
767 AllocatorType());
768 m_codifferential_alloc.emplace(
769 CodifferentialDomainType(
770 tensor.non_indices_domain(),
771 codifferential_accessor.domain()),
772 AllocatorType());
773
774 m_hodge_star.emplace(*m_hodge_star_alloc);
775 m_dual_hodge_star.emplace(*m_dual_hodge_star_alloc);
776 m_dual_tensor_buffer.emplace(*m_dual_tensor_alloc);
777 m_codifferential_tensor_buffer.emplace(*m_codifferential_alloc);
778
780 CodifferentialHodgeInputIndices,
781 CodifferentialHodgeOutputIndices>(exec_space, *m_hodge_star, metric, position);
784 DualCodifferentialHodgeOutputIndices>(
785 exec_space,
786 *m_dual_hodge_star,
787 metric,
788 position);
789 }
790
791 TensorType run(TensorType laplacian_tensor, TensorType tensor)
792 {
794 MetricIndex,
795 LaplacianDummyIndex,
796 CochainTag,
797 TensorType,
798 MetricType,
799 PositionType,
800 ExecSpace>(
801 m_exec_space,
802 std::move(*m_hodge_star),
803 std::move(*m_dual_hodge_star),
804 std::move(*m_dual_tensor_buffer))
805 .run(*m_codifferential_tensor_buffer, tensor);
806 return sil::exterior::
807 deriv<LaplacianDummyIndex, codifferential_index_t<LaplacianDummyIndex, CochainTag>>(
808 m_exec_space,
809 laplacian_tensor,
810 *m_codifferential_tensor_buffer);
811 }
812};
813
814template <
815 tensor::TensorIndex MetricIndex,
816 tensor::TensorNatIndex LaplacianDummyIndex,
817 tensor::TensorIndex CochainTag,
818 misc::Specialization<tensor::Tensor> TensorType,
819 misc::Specialization<tensor::Tensor> DerivativeHodgeStarType,
820 misc::Specialization<tensor::Tensor> DualDerivativeHodgeStarType,
821 misc::Specialization<tensor::Tensor> DerivativeDualTensorBufferType,
822 class ExecSpace>
823 requires(detail::ZeroRankLaplacianCochain<LaplacianDummyIndex, CochainTag>)
824TensorType laplacian(
825 ExecSpace const& exec_space,
826 TensorType laplacian_tensor,
827 TensorType tensor,
828 DerivativeHodgeStarType hodge_star,
829 DualDerivativeHodgeStarType dual_hodge_star,
830 DerivativeDualTensorBufferType dual_tensor_buffer)
831{
832 using codifferential_of_coboundary_index
835 return detail::codifferential_of_coboundary<
836 MetricIndex,
837 codifferential_of_coboundary_index,
838 CochainTag>(
839 exec_space,
840 laplacian_tensor,
841 tensor,
842 hodge_star,
843 dual_hodge_star,
844 dual_tensor_buffer);
845}
846
847template <
848 tensor::TensorIndex MetricIndex,
849 tensor::TensorNatIndex LaplacianDummyIndex,
850 tensor::TensorIndex CochainTag,
852 misc::Specialization<tensor::Tensor> DerivativeHodgeStarType,
853 misc::Specialization<tensor::Tensor> DualDerivativeHodgeStarType,
854 misc::Specialization<tensor::Tensor> DerivativeDualTensorBufferType,
856 misc::Specialization<tensor::Tensor> DualHodgeStarType,
857 misc::Specialization<tensor::Tensor> DualTensorBufferType,
858 misc::Specialization<tensor::Tensor> CodifferentialTensorBufferType,
859 misc::Specialization<tensor::Tensor> CoboundaryOfCodifferentialBufferType,
860 class ExecSpace>
861 requires(detail::IntermediateRankLaplacianCochain<LaplacianDummyIndex, CochainTag>)
862TensorType laplacian(
863 ExecSpace const& exec_space,
864 TensorType laplacian_tensor,
865 TensorType tensor,
866 DerivativeHodgeStarType derivative_hodge_star,
867 DualDerivativeHodgeStarType dual_derivative_hodge_star,
868 DerivativeDualTensorBufferType derivative_dual_tensor_buffer,
869 HodgeStarType hodge_star,
870 DualHodgeStarType dual_hodge_star,
871 DualTensorBufferType dual_tensor_buffer,
872 CodifferentialTensorBufferType codifferential_tensor_buffer,
873 CoboundaryOfCodifferentialBufferType coboundary_of_codifferential_buffer)
874{
875 using codifferential_of_coboundary_index
878 auto exec_spaces = Kokkos::Experimental::partition_space(exec_space, 1, 1);
879
880 detail::codifferential_of_coboundary<
881 MetricIndex,
882 codifferential_of_coboundary_index,
883 CochainTag>(
884 exec_spaces[0],
885 laplacian_tensor,
886 tensor,
887 derivative_hodge_star,
888 dual_derivative_hodge_star,
889 derivative_dual_tensor_buffer);
890
892 exec_spaces[1],
893 codifferential_tensor_buffer,
894 tensor,
895 hodge_star,
896 dual_hodge_star,
897 dual_tensor_buffer);
898 sil::exterior::
899 deriv<LaplacianDummyIndex, codifferential_index_t<LaplacianDummyIndex, CochainTag>>(
900 exec_spaces[1],
901 coboundary_of_codifferential_buffer,
902 codifferential_tensor_buffer);
903
904 exec_spaces[0].fence();
905 exec_spaces[1].fence();
906
907 SIMILIE_DEBUG_LOG("similie_add_coboundary_of_codifferential_contribution_to_laplacian");
908 ddc::parallel_for_each(
909 "similie_add_coboundary_of_codifferential_contribution_to_laplacian",
910 exec_space,
911 laplacian_tensor.domain(),
912 KOKKOS_LAMBDA(typename TensorType::discrete_element_type elem) {
913 laplacian_tensor.mem(elem) += coboundary_of_codifferential_buffer.mem(elem);
914 });
915
916 return laplacian_tensor;
917}
918
919template <
920 tensor::TensorIndex MetricIndex,
921 tensor::TensorNatIndex LaplacianDummyIndex,
922 tensor::TensorIndex CochainTag,
925 misc::Specialization<tensor::Tensor> DualHodgeStarType,
926 misc::Specialization<tensor::Tensor> DualTensorBufferType,
927 misc::Specialization<tensor::Tensor> CodifferentialTensorBufferType,
928 class ExecSpace>
929 requires(detail::TopRankLaplacianCochain<LaplacianDummyIndex, CochainTag>)
930TensorType laplacian(
931 ExecSpace const& exec_space,
932 TensorType laplacian_tensor,
933 TensorType tensor,
934 HodgeStarType hodge_star,
935 DualHodgeStarType dual_hodge_star,
936 DualTensorBufferType dual_tensor_buffer,
937 CodifferentialTensorBufferType codifferential_tensor_buffer)
938{
940 exec_space,
941 codifferential_tensor_buffer,
942 tensor,
943 hodge_star,
944 dual_hodge_star,
945 dual_tensor_buffer);
947 LaplacianDummyIndex,
949 LaplacianDummyIndex,
950 CochainTag>>(exec_space, laplacian_tensor, codifferential_tensor_buffer);
951}
952
953} // namespace exterior
954
955} // namespace sil
static constexpr discrete_domain_type domain()
constexpr auto tangent_basis(ExecSpace const &exec_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
TensorType laplacian(ExecSpace const &exec_space, TensorType laplacian_tensor, TensorType tensor, DerivativeHodgeStarType hodge_star, DualDerivativeHodgeStarType dual_hodge_star, DerivativeDualTensorBufferType dual_tensor_buffer)
StagedLaplacian< MetricIndex, LaplacianDummyIndex, CochainTag, TensorType, MetricType, PositionType, ExecSpace > make_staged_laplacian(ExecSpace const &exec_space, TensorType laplacian_tensor, TensorType tensor, MetricType metric, PositionType position)
coboundary_tensor_t< TagToAddToCochain, CochainTag, TensorType > deriv(ExecSpace const &exec_space, coboundary_tensor_t< TagToAddToCochain, CochainTag, TensorType > coboundary_tensor, TensorType tensor)
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::CoboundaryIndex< TagToAddToCochain, CochainTag >::type coboundary_index_t
KOKKOS_FUNCTION Elem clamp_to_domain(BatchDomain const &batch_domain, Elem const &elem)
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
Definition character.hpp:80
detail::TensorAccessorForDomain< Dom >::type tensor_accessor_for_domain_t
The top-level namespace of SimiLie.
Definition csr.hpp:15