DDC 0.0.0

a discrete domain computation library

spline_evaluator_2d.hpp
1// Copyright (C) The DDC development team, see COPYRIGHT.md file
2//
3// SPDX-License-Identifier: MIT
4
5#pragma once
6
7#include <array>
8
9#include <ddc/ddc.hpp>
10
11#include "Kokkos_Macros.hpp"
12#include "view.hpp"
13
14namespace ddc {
15
19template <
20 class ExecSpace,
21 class MemorySpace,
22 class BSplinesType1,
23 class BSplinesType2,
24 class interpolation_mesh_type1,
25 class interpolation_mesh_type2,
30 class... IDimX>
32{
33private:
37 struct eval_type
38 {
39 };
40
44 struct eval_deriv_type
45 {
46 };
47
48 using tag_type1 = typename BSplinesType1::tag_type;
49 using tag_type2 = typename BSplinesType2::tag_type;
50
51public:
53
55
58
63
75 using batch_domain_type =
76 typename ddc::detail::convert_type_seq_to_discrete_domain<ddc::type_seq_remove_t<
77 ddc::detail::TypeSeq<IDimX...>,
78 ddc::detail::TypeSeq<interpolation_mesh_type1, interpolation_mesh_type2>>>;
81 typename ddc::detail::convert_type_seq_to_discrete_domain<ddc::type_seq_replace_t<
82 ddc::detail::TypeSeq<IDimX...>,
83 ddc::detail::TypeSeq<interpolation_mesh_type1, interpolation_mesh_type2>,
84 ddc::detail::TypeSeq<bsplines_type1, bsplines_type2>>>;
85
86
87private:
88 LeftExtrapolationRule1 m_left_extrap_rule_1;
89
90 RightExtrapolationRule1 m_right_extrap_rule_1;
91
92 LeftExtrapolationRule2 m_left_extrap_rule_2;
93
94 RightExtrapolationRule2 m_right_extrap_rule_2;
95
96public:
97 static_assert(
98 std::is_same_v<LeftExtrapolationRule1,
100 tag_type1>> == bsplines_type1::is_periodic()
101 && std::is_same_v<
104 tag_type1>> == bsplines_type1::is_periodic()
105 && std::is_same_v<
108 tag_type2>> == bsplines_type2::is_periodic()
109 && std::is_same_v<
112 tag_type2>> == bsplines_type2::is_periodic(),
113 "PeriodicExtrapolationRule has to be used if and only if dimension is periodic");
114 static_assert(
115 std::is_invocable_r_v<
116 double,
120 double const,
122 std::experimental::layout_right,
123 memory_space>>,
124 "LeftExtrapolationRule1::operator() has to be callable "
125 "with usual arguments.");
126 static_assert(
127 std::is_invocable_r_v<
128 double,
132 double const,
134 std::experimental::layout_right,
135 memory_space>>,
136 "RightExtrapolationRule1::operator() has to be callable "
137 "with usual arguments.");
138 static_assert(
139 std::is_invocable_r_v<
140 double,
144 double const,
146 std::experimental::layout_right,
147 memory_space>>,
148 "LeftExtrapolationRule2::operator() has to be callable "
149 "with usual arguments.");
150 static_assert(
151 std::is_invocable_r_v<
152 double,
156 double const,
158 std::experimental::layout_right,
159 memory_space>>,
160 "RightExtrapolationRule2::operator() has to be callable "
161 "with usual arguments.");
162
181 explicit SplineEvaluator2D(
186 : m_left_extrap_rule_1(left_extrap_rule1)
187 , m_right_extrap_rule_1(right_extrap_rule1)
188 , m_left_extrap_rule_2(left_extrap_rule2)
189 , m_right_extrap_rule_2(right_extrap_rule2)
190 {
191 }
192
200 SplineEvaluator2D(SplineEvaluator2D const& x) = default;
201
211 ~SplineEvaluator2D() = default;
212
222
232
233
236 {
237 return m_left_extrap_rule_1;
238 }
241 {
242 return m_right_extrap_rule_1;
243 }
246 {
247 return m_left_extrap_rule_2;
248 }
251 {
252 return m_right_extrap_rule_2;
253 }
254
272 }
273
274 template <class Layout1, class Layout2, class Layout3, class... CoordsDims>
275 void operator()(
281 Layout2,
284 spline_coef) const
285 {
286 batch_domain_type batch_domain(coords_eval.domain());
290 exec_space(),
291 batch_domain,
292 KOKKOS_CLASS_LAMBDA(typename batch_domain_type::discrete_element_type const j) {
293 const auto spline_eval_2D = spline_eval[j];
294 const auto coords_eval_2D = coords_eval[j];
295 const auto spline_coef_2D = spline_coef[j];
296 for (auto const i1 : interpolation_domain1) {
297 for (auto const i2 : interpolation_domain2) {
299 }
300 }
301 });
302 }
303
321 }
322
340 }
341
359 }
360
361 template <class InterestDim, class Layout, class... CoordsDims>
362 KOKKOS_FUNCTION double deriv(
365 spline_coef) const
366 {
367 static_assert(
368 std::is_same_v<
370 typename interpolation_mesh_type1::
371 continuous_dimension_type> || std::is_same_v<InterestDim, typename interpolation_mesh_type2::continuous_dimension_type>);
372 if constexpr (std::is_same_v<
374 typename interpolation_mesh_type1::continuous_dimension_type>) {
376 } else if constexpr (std::is_same_v<
378 typename interpolation_mesh_type2::
379 continuous_dimension_type>) {
381 }
382 }
383
384 template <class InterestDim1, class InterestDim2, class Layout, class... CoordsDims>
385 KOKKOS_FUNCTION double deriv2(
388 spline_coef) const
389 {
390 static_assert(
391 (std::is_same_v<
393 typename interpolation_mesh_type1::
394 continuous_dimension_type> && std::is_same_v<InterestDim2, typename interpolation_mesh_type2::continuous_dimension_type>)
395 || (std::is_same_v<
397 typename interpolation_mesh_type1::
398 continuous_dimension_type> && std::is_same_v<InterestDim1, typename interpolation_mesh_type2::continuous_dimension_type>));
400 }
401
412 template <class Layout1, class Layout2, class Layout3, class... CoordsDims>
413 void deriv_dim_1(
419 Layout2,
422 spline_coef) const
423 {
424 batch_domain_type batch_domain(coords_eval.domain());
428 exec_space(),
429 batch_domain,
430 KOKKOS_CLASS_LAMBDA(typename batch_domain_type::discrete_element_type const j) {
431 const auto spline_eval_2D = spline_eval[j];
432 const auto coords_eval_2D = coords_eval[j];
433 const auto spline_coef_2D = spline_coef[j];
434 for (auto const i1 : interpolation_domain1) {
435 for (auto const i2 : interpolation_domain2) {
436 spline_eval_2D(i1, i2) = eval_no_bc<
437 eval_deriv_type,
438 eval_type>(coords_eval_2D(i1, i2), spline_coef_2D);
439 }
440 }
441 });
442 }
443
454 template <class Layout1, class Layout2, class Layout3, class... CoordsDims>
455 void deriv_dim_2(
461 Layout2,
464 spline_coef) const
465 {
466 batch_domain_type batch_domain(coords_eval.domain());
470 exec_space(),
471 batch_domain,
472 KOKKOS_CLASS_LAMBDA(typename batch_domain_type::discrete_element_type const j) {
473 const auto spline_eval_2D = spline_eval[j];
474 const auto coords_eval_2D = coords_eval[j];
475 const auto spline_coef_2D = spline_coef[j];
476 for (auto const i1 : interpolation_domain1) {
477 for (auto const i2 : interpolation_domain2) {
478 spline_eval_2D(i1, i2) = eval_no_bc<
479 eval_type,
480 eval_deriv_type>(coords_eval_2D(i1, i2), spline_coef_2D);
481 }
482 }
483 });
484 }
485
496 template <class Layout1, class Layout2, class Layout3, class... CoordsDims>
497 void deriv_1_and_2(
503 Layout2,
506 spline_coef) const
507 {
508 batch_domain_type batch_domain(coords_eval.domain());
512 exec_space(),
513 batch_domain,
514 KOKKOS_CLASS_LAMBDA(typename batch_domain_type::discrete_element_type const j) {
515 const auto spline_eval_2D = spline_eval[j];
516 const auto coords_eval_2D = coords_eval[j];
517 const auto spline_coef_2D = spline_coef[j];
518 for (auto const i1 : interpolation_domain1) {
519 for (auto const i2 : interpolation_domain2) {
520 spline_eval_2D(i1, i2) = eval_no_bc<
521 eval_deriv_type,
522 eval_deriv_type>(coords_eval_2D(i1, i2), spline_coef_2D);
523 }
524 }
525 });
526 }
527
528 template <class InterestDim, class Layout1, class Layout2, class Layout3, class... CoordsDims>
529 void deriv(
535 Layout2,
538 spline_coef) const
539 {
540 static_assert(
541 std::is_same_v<
543 typename interpolation_mesh_type1::
544 continuous_dimension_type> || std::is_same_v<InterestDim, typename interpolation_mesh_type2::continuous_dimension_type>);
545 if constexpr (std::is_same_v<
547 typename interpolation_mesh_type1::continuous_dimension_type>) {
549 } else if constexpr (std::is_same_v<
551 typename interpolation_mesh_type2::
552 continuous_dimension_type>) {
554 }
555 }
556
557 template <
558 class InterestDim1,
559 class InterestDim2,
560 class Layout1,
561 class Layout2,
562 class Layout3,
563 class... CoordsDims>
564 void deriv2(
570 Layout2,
573 spline_coef) const
574 {
575 static_assert(
576 (std::is_same_v<
578 typename interpolation_mesh_type1::
579 continuous_dimension_type> && std::is_same_v<InterestDim2, typename interpolation_mesh_type2::continuous_dimension_type>)
580 || (std::is_same_v<
582 typename interpolation_mesh_type1::
583 continuous_dimension_type> && std::is_same_v<InterestDim1, typename interpolation_mesh_type2::continuous_dimension_type>));
585 }
586
594 template <class Layout1, class Layout2>
595 void integrate(
598 spline_coef) const
599 {
600 batch_domain_type batch_domain(integrals.domain());
609 Kokkos::parallel_for(
610 Kokkos::RangePolicy<exec_space>(0, 1),
611 KOKKOS_LAMBDA(int) {
614 });
615
617 exec_space(),
618 batch_domain,
619 KOKKOS_LAMBDA(typename batch_domain_type::discrete_element_type const j) {
620 integrals(j) = 0;
622 values1.domain()) {
624 values2.domain()) {
625 integrals(j) += spline_coef(i1, i2, j) * values1(i1) * values2(i2);
626 }
627 }
628 });
629 }
630
631private:
651 template <class Layout, class... CoordsDims>
652 KOKKOS_INLINE_FUNCTION double eval(
655 spline_coef) const
656 {
657 using Dim1 = typename interpolation_mesh_type1::continuous_dimension_type;
658 using Dim2 = typename interpolation_mesh_type2::continuous_dimension_type;
659 if constexpr (bsplines_type1::is_periodic()) {
663 -= Kokkos::floor(
668 }
669 }
670 if constexpr (bsplines_type2::is_periodic()) {
674 -= Kokkos::floor(
679 }
680 }
681 if constexpr (!bsplines_type1::is_periodic()) {
683 return m_left_extrap_rule_1(coord_eval, spline_coef);
684 }
686 return m_right_extrap_rule_1(coord_eval, spline_coef);
687 }
688 }
689 if constexpr (!bsplines_type2::is_periodic()) {
691 return m_left_extrap_rule_2(coord_eval, spline_coef);
692 }
694 return m_right_extrap_rule_2(coord_eval, spline_coef);
695 }
696 }
699 typename interpolation_mesh_type1::continuous_dimension_type,
700 typename interpolation_mesh_type2::continuous_dimension_type>(
704 }
705
720 template <class EvalType1, class EvalType2, class Layout, class... CoordsDims>
721 KOKKOS_INLINE_FUNCTION double eval_no_bc(
724 spline_coef) const
725 {
726 static_assert(
727 std::is_same_v<EvalType1, eval_type> || std::is_same_v<EvalType1, eval_deriv_type>);
728 static_assert(
729 std::is_same_v<EvalType2, eval_type> || std::is_same_v<EvalType2, eval_deriv_type>);
732
733 std::array<double, bsplines_type1::degree() + 1> vals1_ptr;
734 std::experimental::mdspan<
735 double,
736 std::experimental::extents<std::size_t, bsplines_type1::degree() + 1>> const
737 vals1(vals1_ptr.data());
738 std::array<double, bsplines_type2::degree() + 1> vals2_ptr;
739 std::experimental::mdspan<
740 double,
741 std::experimental::extents<std::size_t, bsplines_type2::degree() + 1>> const
742 vals2(vals2_ptr.data());
746 coord_eval);
750 coord_eval);
751
752 if constexpr (std::is_same_v<EvalType1, eval_type>) {
754 .eval_basis(vals1, coord_eval_interpolation1);
755 } else if constexpr (std::is_same_v<EvalType1, eval_deriv_type>) {
757 .eval_deriv(vals1, coord_eval_interpolation1);
758 }
759 if constexpr (std::is_same_v<EvalType2, eval_type>) {
761 .eval_basis(vals2, coord_eval_interpolation2);
762 } else if constexpr (std::is_same_v<EvalType2, eval_deriv_type>) {
764 .eval_deriv(vals2, coord_eval_interpolation2);
765 }
766
767 double y = 0.0;
768 for (std::size_t i = 0; i < bsplines_type1::degree() + 1; ++i) {
769 for (std::size_t j = 0; j < bsplines_type2::degree() + 1; ++j) {
773 * vals1[i] * vals2[j];
774 }
775 }
776 return y;
777 }
778};
779} // namespace ddc
Definition discrete_domain.hpp:51
Definition kokkos_allocator.hpp:17
Define an evaluator 2D on B-splines.
Definition spline_evaluator_2d.hpp:32
RightExtrapolationRule1 right_extrapolation_rule_1_type
Definition spline_evaluator_2d.hpp:60
BSplinesType2 bsplines_type2
Definition spline_evaluator_2d.hpp:57
right_extrapolation_rule_2_type right_extrapolation_rule_dim_2() const
Definition spline_evaluator_2d.hpp:249
void integrate(ddc::ChunkSpan< double, batch_domain_type, Layout1, memory_space > const integrals, ddc::ChunkSpan< double const, batched_spline_domain_type, Layout2, memory_space > const spline_coef) const
Get the the integral of the function on B-splines on the domain.
Definition spline_evaluator_2d.hpp:594
KOKKOS_FUNCTION double deriv_1_and_2(ddc::Coordinate< CoordsDims... > const &coord_eval, ddc::ChunkSpan< double const, spline_domain_type, Layout, memory_space > const spline_coef) const
Get the value of the cross derivative of the function on B-splines at the coordinate given.
Definition spline_evaluator_2d.hpp:352
left_extrapolation_rule_2_type left_extrapolation_rule_dim_2() const
Definition spline_evaluator_2d.hpp:244
KOKKOS_FUNCTION double deriv_dim_1(ddc::Coordinate< CoordsDims... > const &coord_eval, ddc::ChunkSpan< double const, spline_domain_type, Layout, memory_space > const spline_coef) const
Get the value of the derivative of the first dimension of the function on B-splines at the coordinate...
Definition spline_evaluator_2d.hpp:314
SplineEvaluator2D(LeftExtrapolationRule1 const &left_extrap_rule1, RightExtrapolationRule1 const &right_extrap_rule1, LeftExtrapolationRule2 const &left_extrap_rule2, RightExtrapolationRule2 const &right_extrap_rule2)
Instantiate an evaluator operator.
Definition spline_evaluator_2d.hpp:180
right_extrapolation_rule_1_type right_extrapolation_rule_dim_1() const
Definition spline_evaluator_2d.hpp:239
SplineEvaluator2D & operator=(SplineEvaluator2D const &x)=default
Assign a SplineEvaluator2D from another SplineEvaluator2D (lvalue).
ddc::DiscreteDomain< bsplines_type1, bsplines_type2 > spline_domain_type
Definition spline_evaluator_2d.hpp:72
LeftExtrapolationRule1 left_extrapolation_rule_1_type
Definition spline_evaluator_2d.hpp:59
~SplineEvaluator2D()=default
typename ddc::detail::convert_type_seq_to_discrete_domain< ddc::type_seq_remove_t< ddc::detail::TypeSeq< IDimX... >, ddc::detail::TypeSeq< interpolation_mesh_type1, interpolation_mesh_type2 > > > batch_domain_type
Definition spline_evaluator_2d.hpp:74
typename ddc::detail::convert_type_seq_to_discrete_domain< ddc::type_seq_replace_t< ddc::detail::TypeSeq< IDimX... >, ddc::detail::TypeSeq< interpolation_mesh_type1, interpolation_mesh_type2 >, ddc::detail::TypeSeq< bsplines_type1, bsplines_type2 > > > batched_spline_domain_type
Definition spline_evaluator_2d.hpp:79
RightExtrapolationRule2 right_extrapolation_rule_2_type
Definition spline_evaluator_2d.hpp:62
KOKKOS_FUNCTION double deriv(ddc::Coordinate< CoordsDims... > const &coord_eval, ddc::ChunkSpan< double const, spline_domain_type, Layout, memory_space > const spline_coef) const
Definition spline_evaluator_2d.hpp:361
KOKKOS_FUNCTION double operator()(ddc::Coordinate< CoordsDims... > const &coord_eval, ddc::ChunkSpan< double const, spline_domain_type, Layout, memory_space > const spline_coef) const
Get the value of the function on B-splines at the coordinate given.
Definition spline_evaluator_2d.hpp:265
ExecSpace exec_space
Definition spline_evaluator_2d.hpp:52
MemorySpace memory_space
Definition spline_evaluator_2d.hpp:54
BSplinesType1 bsplines_type1
Definition spline_evaluator_2d.hpp:56
KOKKOS_FUNCTION double deriv_dim_2(ddc::Coordinate< CoordsDims... > const &coord_eval, ddc::ChunkSpan< double const, spline_domain_type, Layout, memory_space > const spline_coef) const
Get the value of the derivative of the second dimension of the function on B-splines at the coordinat...
Definition spline_evaluator_2d.hpp:333
KOKKOS_FUNCTION double deriv2(ddc::Coordinate< CoordsDims... > const &coord_eval, ddc::ChunkSpan< double const, spline_domain_type, Layout, memory_space > const spline_coef) const
Definition spline_evaluator_2d.hpp:384
LeftExtrapolationRule2 left_extrapolation_rule_2_type
Definition spline_evaluator_2d.hpp:61
left_extrapolation_rule_1_type left_extrapolation_rule_dim_1() const
Definition spline_evaluator_2d.hpp:234
The top-level namespace of DDC.
Definition aligned_allocator.hpp:11
constexpr bool enable_chunk
Definition chunk_traits.hpp:16
KOKKOS_FUNCTION Coordinate< typename DDim::continuous_dimension_type > rmax(DiscreteDomain< DDim > const &d)
Definition non_uniform_point_sampling.hpp:182
void parallel_for_each(std::string const &label, ExecSpace const &execution_space, DiscreteDomain< DDims... > const &domain, Functor &&f) noexcept
iterates over a nD domain using a given Kokkos execution space
Definition parallel_for_each.hpp:155
KOKKOS_FUNCTION Coordinate< typename DDim::continuous_dimension_type > rmin(DiscreteDomain< DDim > const &d)
Definition non_uniform_point_sampling.hpp:175
detail::TaggedVector< CoordinateElement, CDims... > Coordinate
A Coordinate represents a coordinate in the continuous space.
Definition coordinate.hpp:26
Definition chunk.hpp:21
Definition chunk_span.hpp:30
Definition periodic_extrapolation_rule.hpp:13