13#include <Kokkos_Core.hpp>
16#include "integrals.hpp"
17#include "periodic_extrapolation_rule.hpp"
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
47 class EvaluationDDim1,
48 class EvaluationDDim2,
49 class EvaluationDDim3,
50 class LowerExtrapolationRule1,
51 class UpperExtrapolationRule1,
52 class LowerExtrapolationRule2,
53 class UpperExtrapolationRule2,
54 class LowerExtrapolationRule3,
55 class UpperExtrapolationRule3>
60 using continuous_dimension_type1 =
typename BSplines1::continuous_dimension_type;
63 using continuous_dimension_type2 =
typename BSplines2::continuous_dimension_type;
66 using continuous_dimension_type3 =
typename BSplines3::continuous_dimension_type;
69 using exec_space = ExecSpace;
72 using memory_space = MemorySpace;
75 using evaluation_discrete_dimension_type1 = EvaluationDDim1;
78 using evaluation_discrete_dimension_type2 = EvaluationDDim2;
81 using evaluation_discrete_dimension_type3 = EvaluationDDim3;
84 using bsplines_type1 = BSplines1;
87 using bsplines_type2 = BSplines2;
90 using bsplines_type3 = BSplines3;
93 using evaluation_domain_type1 =
ddc::
DiscreteDomain<evaluation_discrete_dimension_type1>;
96 using evaluation_domain_type2 =
ddc::
DiscreteDomain<evaluation_discrete_dimension_type2>;
99 using evaluation_domain_type3 =
ddc::
DiscreteDomain<evaluation_discrete_dimension_type3>;
103 evaluation_discrete_dimension_type1,
104 evaluation_discrete_dimension_type2,
105 evaluation_discrete_dimension_type3>;
108
109
110
111
113 class BatchedInterpolationDDom,
114 class = std::enable_if_t<
ddc::is_discrete_domain_v<BatchedInterpolationDDom>>>
115 using batched_evaluation_domain_type = BatchedInterpolationDDom;
127 using spline_domain_type =
ddc::
DiscreteDomain<bsplines_type1, bsplines_type2, bsplines_type3>;
130
131
132
133
134
136 class BatchedInterpolationDDom,
137 class = std::enable_if_t<
ddc::is_discrete_domain_v<BatchedInterpolationDDom>>>
138 using batch_domain_type =
typename ddc::remove_dims_of_t<
139 BatchedInterpolationDDom,
140 evaluation_discrete_dimension_type1,
141 evaluation_discrete_dimension_type2,
142 evaluation_discrete_dimension_type3>;
145
146
147
148
149
151 class BatchedInterpolationDDom,
152 class = std::enable_if_t<
ddc::is_discrete_domain_v<BatchedInterpolationDDom>>>
153 using batched_spline_domain_type =
154 typename ddc::detail::convert_type_seq_to_discrete_domain_t<
ddc::type_seq_replace_t<
155 ddc::to_type_seq_t<BatchedInterpolationDDom>,
156 ddc::detail::TypeSeq<
157 evaluation_discrete_dimension_type1,
158 evaluation_discrete_dimension_type2,
159 evaluation_discrete_dimension_type3>,
160 ddc::detail::TypeSeq<bsplines_type1, bsplines_type2, bsplines_type3>>>;
163 using lower_extrapolation_rule_1_type = LowerExtrapolationRule1;
166 using upper_extrapolation_rule_1_type = UpperExtrapolationRule1;
169 using lower_extrapolation_rule_2_type = LowerExtrapolationRule2;
172 using upper_extrapolation_rule_2_type = UpperExtrapolationRule2;
175 using lower_extrapolation_rule_3_type = LowerExtrapolationRule3;
178 using upper_extrapolation_rule_3_type = UpperExtrapolationRule3;
181 LowerExtrapolationRule1 m_lower_extrap_rule_1;
183 UpperExtrapolationRule1 m_upper_extrap_rule_1;
185 LowerExtrapolationRule2 m_lower_extrap_rule_2;
187 UpperExtrapolationRule2 m_upper_extrap_rule_2;
189 LowerExtrapolationRule3 m_lower_extrap_rule_3;
191 UpperExtrapolationRule3 m_upper_extrap_rule_3;
195 std::is_same_v<LowerExtrapolationRule1,
197 == bsplines_type1::is_periodic()
199 UpperExtrapolationRule1,
201 == bsplines_type1::is_periodic()
203 LowerExtrapolationRule2,
205 == bsplines_type2::is_periodic()
207 UpperExtrapolationRule2,
209 == bsplines_type2::is_periodic()
211 LowerExtrapolationRule3,
213 == bsplines_type3::is_periodic()
215 UpperExtrapolationRule3,
217 == bsplines_type3::is_periodic(),
218 "PeriodicExtrapolationRule has to be used if and only if dimension is periodic");
220 std::is_invocable_r_v<
222 LowerExtrapolationRule1,
223 ddc::Coordinate<continuous_dimension_type1>,
227 Kokkos::layout_right,
229 "LowerExtrapolationRule1::operator() has to be callable "
230 "with usual arguments.");
232 std::is_invocable_r_v<
234 UpperExtrapolationRule1,
235 ddc::Coordinate<continuous_dimension_type1>,
239 Kokkos::layout_right,
241 "UpperExtrapolationRule1::operator() has to be callable "
242 "with usual arguments.");
244 std::is_invocable_r_v<
246 LowerExtrapolationRule2,
247 ddc::Coordinate<continuous_dimension_type2>,
251 Kokkos::layout_right,
253 "LowerExtrapolationRule2::operator() has to be callable "
254 "with usual arguments.");
256 std::is_invocable_r_v<
258 UpperExtrapolationRule2,
259 ddc::Coordinate<continuous_dimension_type2>,
263 Kokkos::layout_right,
265 "UpperExtrapolationRule2::operator() has to be callable "
266 "with usual arguments.");
268 std::is_invocable_r_v<
270 LowerExtrapolationRule3,
271 ddc::Coordinate<continuous_dimension_type3>,
275 Kokkos::layout_right,
277 "LowerExtrapolationRule3::operator() has to be callable "
278 "with usual arguments.");
280 std::is_invocable_r_v<
282 UpperExtrapolationRule3,
283 ddc::Coordinate<continuous_dimension_type3>,
287 Kokkos::layout_right,
289 "UpperExtrapolationRule3::operator() has to be callable "
290 "with usual arguments.");
293
294
295
296
297
298
299
300
301
302
303
305 LowerExtrapolationRule1
const& lower_extrap_rule1,
306 UpperExtrapolationRule1
const& upper_extrap_rule1,
307 LowerExtrapolationRule2
const& lower_extrap_rule2,
308 UpperExtrapolationRule2
const& upper_extrap_rule2,
309 LowerExtrapolationRule3
const& lower_extrap_rule3,
310 UpperExtrapolationRule3
const& upper_extrap_rule3)
311 : m_lower_extrap_rule_1(lower_extrap_rule1)
312 , m_upper_extrap_rule_1(upper_extrap_rule1)
313 , m_lower_extrap_rule_2(lower_extrap_rule2)
314 , m_upper_extrap_rule_2(upper_extrap_rule2)
315 , m_lower_extrap_rule_3(lower_extrap_rule3)
316 , m_upper_extrap_rule_3(upper_extrap_rule3)
321
322
323
324
328
329
330
331
338
339
340
341
342
346
347
348
349
350
354
355
356
357
358
359
360
361
364 return m_lower_extrap_rule_1;
368
369
370
371
372
373
374
375
378 return m_upper_extrap_rule_1;
382
383
384
385
386
387
388
389
392 return m_lower_extrap_rule_2;
396
397
398
399
400
401
402
403
406 return m_upper_extrap_rule_2;
410
411
412
413
414
415
416
417
420 return m_lower_extrap_rule_3;
424
425
426
427
428
429
430
431
434 return m_upper_extrap_rule_3;
438
439
440
441
442
443
444
445
446
447
448
449 template <
class Layout,
class... CoordsDims>
451 ddc::Coordinate<CoordsDims...>
const& coord_eval,
452 ddc::
ChunkSpan<
double const, spline_domain_type, Layout, memory_space>
const
455 return eval(coord_eval, spline_coef);
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
482 class BatchedInterpolationDDom,
485 ddc::
ChunkSpan<
double, BatchedInterpolationDDom, Layout1, memory_space>
const
488 ddc::Coordinate<CoordsDims...>
const,
489 BatchedInterpolationDDom,
491 memory_space>
const coords_eval,
494 batched_spline_domain_type<BatchedInterpolationDDom>,
496 memory_space>
const spline_coef)
const
498 batch_domain_type<BatchedInterpolationDDom>
const batch_domain(coords_eval.domain());
499 evaluation_domain_type1
const evaluation_domain1(spline_eval.domain());
500 evaluation_domain_type2
const evaluation_domain2(spline_eval.domain());
501 evaluation_domain_type3
const evaluation_domain3(spline_eval.domain());
502 ddc::parallel_for_each(
503 "ddc_splines_evaluate_3d",
507 typename batch_domain_type<
508 BatchedInterpolationDDom>::discrete_element_type
const j) {
509 auto const spline_eval_3D = spline_eval[j];
510 auto const coords_eval_3D = coords_eval[j];
511 auto const spline_coef_3D = spline_coef[j];
512 for (
auto const i1 : evaluation_domain1) {
513 for (
auto const i2 : evaluation_domain2) {
514 for (
auto const i3 : evaluation_domain3) {
515 spline_eval_3D(i1, i2, i3)
516 = eval(coords_eval_3D(i1, i2, i3), spline_coef_3D);
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538 template <
class Layout1,
class Layout2,
class BatchedInterpolationDDom>
540 ddc::
ChunkSpan<
double, BatchedInterpolationDDom, Layout1, memory_space>
const
544 batched_spline_domain_type<BatchedInterpolationDDom>,
546 memory_space>
const spline_coef)
const
548 batch_domain_type<BatchedInterpolationDDom>
const batch_domain(spline_eval.domain());
549 evaluation_domain_type1
const evaluation_domain1(spline_eval.domain());
550 evaluation_domain_type2
const evaluation_domain2(spline_eval.domain());
551 evaluation_domain_type3
const evaluation_domain3(spline_eval.domain());
552 ddc::parallel_for_each(
553 "ddc_splines_evaluate_3d",
557 typename batch_domain_type<
558 BatchedInterpolationDDom>::discrete_element_type
const j) {
559 auto const spline_eval_3D = spline_eval[j];
560 auto const spline_coef_3D = spline_coef[j];
561 for (
auto const i1 : evaluation_domain1) {
562 for (
auto const i2 : evaluation_domain2) {
563 for (
auto const i3 : evaluation_domain3) {
565 continuous_dimension_type1,
566 continuous_dimension_type2,
567 continuous_dimension_type3>
571 ddc::coordinate(i3));
572 spline_eval_3D(i1, i2, i3)
573 = eval(coord_eval_3D(i1, i2, i3), spline_coef_3D);
581
582
583
584
585
586
587
588
589
590
591
592
593 template <
class DElem,
class Layout,
class... CoordsDims>
595 DElem
const& deriv_order,
596 ddc::Coordinate<CoordsDims...>
const& coord_eval,
597 ddc::
ChunkSpan<
double const, spline_domain_type, Layout, memory_space>
const
600 static_assert(is_discrete_element_v<DElem>);
601 return eval_no_bc(deriv_order, coord_eval, spline_coef);
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
629 class BatchedInterpolationDDom,
632 DElem
const& deriv_order,
633 ddc::
ChunkSpan<
double, BatchedInterpolationDDom, Layout1, memory_space>
const
636 ddc::Coordinate<CoordsDims...>
const,
637 BatchedInterpolationDDom,
639 memory_space>
const coords_eval,
642 batched_spline_domain_type<BatchedInterpolationDDom>,
644 memory_space>
const spline_coef)
const
646 static_assert(is_discrete_element_v<DElem>);
648 batch_domain_type<BatchedInterpolationDDom>
const batch_domain(coords_eval.domain());
649 evaluation_domain_type1
const evaluation_domain1(spline_eval.domain());
650 evaluation_domain_type2
const evaluation_domain2(spline_eval.domain());
651 evaluation_domain_type3
const evaluation_domain3(spline_eval.domain());
652 ddc::parallel_for_each(
653 "ddc_splines_cross_differentiate_3d",
657 typename batch_domain_type<
658 BatchedInterpolationDDom>::discrete_element_type
const j) {
659 auto const spline_eval_3D = spline_eval[j];
660 auto const coords_eval_3D = coords_eval[j];
661 auto const spline_coef_3D = spline_coef[j];
662 for (
auto const i1 : evaluation_domain1) {
663 for (
auto const i2 : evaluation_domain2) {
664 for (
auto const i3 : evaluation_domain3) {
665 spline_eval_3D(i1, i2, i3) = eval_no_bc(
667 coords_eval_3D(i1, i2, i3),
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690 template <
class DElem,
class Layout1,
class Layout2,
class BatchedInterpolationDDom>
692 DElem
const& deriv_order,
693 ddc::
ChunkSpan<
double, BatchedInterpolationDDom, Layout1, memory_space>
const
697 batched_spline_domain_type<BatchedInterpolationDDom>,
699 memory_space>
const spline_coef)
const
701 static_assert(is_discrete_element_v<DElem>);
703 batch_domain_type<BatchedInterpolationDDom>
const batch_domain(spline_eval.domain());
704 evaluation_domain_type1
const evaluation_domain1(spline_eval.domain());
705 evaluation_domain_type2
const evaluation_domain2(spline_eval.domain());
706 evaluation_domain_type3
const evaluation_domain3(spline_eval.domain());
707 ddc::parallel_for_each(
708 "ddc_splines_cross_differentiate_3d",
712 typename batch_domain_type<
713 BatchedInterpolationDDom>::discrete_element_type
const j) {
714 auto const spline_eval_3D = spline_eval[j];
715 auto const spline_coef_3D = spline_coef[j];
716 for (
auto const i1 : evaluation_domain1) {
717 for (
auto const i2 : evaluation_domain2) {
718 for (
auto const i3 : evaluation_domain3) {
720 continuous_dimension_type1,
721 continuous_dimension_type2,
722 continuous_dimension_type3>
726 ddc::coordinate(i3));
727 spline_eval_3D(i1, i2, i3)
728 = eval_no_bc(deriv_order, coord_eval_3D, spline_coef_3D);
736
737
738
739
740
741
742
743
744
745
746
747
748 template <
class Layout1,
class Layout2,
class BatchedDDom,
class BatchedSplineDDom>
750 ddc::
ChunkSpan<
double, BatchedDDom, Layout1, memory_space>
const integrals,
751 ddc::
ChunkSpan<
double const, BatchedSplineDDom, Layout2, memory_space>
const
755 ddc::type_seq_contains_v<
756 ddc::detail::TypeSeq<bsplines_type1, bsplines_type2, bsplines_type3>,
757 to_type_seq_t<BatchedSplineDDom>>,
758 "The spline coefficients domain must contain the bsplines dimensions");
759 using batch_domain_type =
ddc::
760 remove_dims_of_t<BatchedSplineDDom, bsplines_type1, bsplines_type2, bsplines_type3>;
762 std::is_same_v<batch_domain_type, BatchedDDom>,
763 "The integrals domain must only contain the batch dimensions");
765 batch_domain_type batch_domain(integrals.domain());
770 ddc::integrals(exec_space(), values1);
775 ddc::integrals(exec_space(), values2);
780 ddc::integrals(exec_space(), values3);
782 ddc::parallel_for_each(
783 "ddc_splines_integrate_bsplines",
786 KOKKOS_LAMBDA(
typename batch_domain_type::discrete_element_type
const j) {
788 for (
typename spline_domain_type1::discrete_element_type
const i1 :
790 for (
typename spline_domain_type2::discrete_element_type
const i2 :
792 for (
typename spline_domain_type3::discrete_element_type
const i3 :
794 integrals(j) += spline_coef(i1, i2, i3, j) * values1(i1)
795 * values2(i2) * values3(i3);
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818 template <
class Layout,
class... CoordsDims>
819 KOKKOS_INLINE_FUNCTION
double eval(
820 ddc::Coordinate<CoordsDims...> coord_eval,
821 ddc::
ChunkSpan<
double const, spline_domain_type, Layout, memory_space>
const
824 using Dim1 = continuous_dimension_type1;
825 using Dim2 = continuous_dimension_type2;
826 using Dim3 = continuous_dimension_type3;
827 if constexpr (bsplines_type1::is_periodic()) {
828 if (
ddc::get<Dim1>(coord_eval) <
ddc::discrete_space<bsplines_type1>().rmin()
829 ||
ddc::get<Dim1>(coord_eval) >
ddc::discrete_space<bsplines_type1>().rmax()) {
830 ddc::get<Dim1>(coord_eval)
832 (
ddc::get<Dim1>(coord_eval)
833 -
ddc::discrete_space<bsplines_type1>().rmin())
834 /
ddc::discrete_space<bsplines_type1>().length())
835 *
ddc::discrete_space<bsplines_type1>().length();
838 if constexpr (bsplines_type2::is_periodic()) {
839 if (
ddc::get<Dim2>(coord_eval) <
ddc::discrete_space<bsplines_type2>().rmin()
840 ||
ddc::get<Dim2>(coord_eval) >
ddc::discrete_space<bsplines_type2>().rmax()) {
841 ddc::get<Dim2>(coord_eval)
843 (
ddc::get<Dim2>(coord_eval)
844 -
ddc::discrete_space<bsplines_type2>().rmin())
845 /
ddc::discrete_space<bsplines_type2>().length())
846 *
ddc::discrete_space<bsplines_type2>().length();
849 if constexpr (bsplines_type3::is_periodic()) {
850 if (
ddc::get<Dim3>(coord_eval) <
ddc::discrete_space<bsplines_type3>().rmin()
851 ||
ddc::get<Dim3>(coord_eval) >
ddc::discrete_space<bsplines_type3>().rmax()) {
852 ddc::get<Dim3>(coord_eval)
854 (
ddc::get<Dim3>(coord_eval)
855 -
ddc::discrete_space<bsplines_type3>().rmin())
856 /
ddc::discrete_space<bsplines_type3>().length())
857 *
ddc::discrete_space<bsplines_type3>().length();
860 if constexpr (!bsplines_type1::is_periodic()) {
861 if (
ddc::get<Dim1>(coord_eval) <
ddc::discrete_space<bsplines_type1>().rmin()) {
862 return m_lower_extrap_rule_1(coord_eval, spline_coef);
864 if (
ddc::get<Dim1>(coord_eval) >
ddc::discrete_space<bsplines_type1>().rmax()) {
865 return m_upper_extrap_rule_1(coord_eval, spline_coef);
868 if constexpr (!bsplines_type2::is_periodic()) {
869 if (
ddc::get<Dim2>(coord_eval) <
ddc::discrete_space<bsplines_type2>().rmin()) {
870 return m_lower_extrap_rule_2(coord_eval, spline_coef);
872 if (
ddc::get<Dim2>(coord_eval) >
ddc::discrete_space<bsplines_type2>().rmax()) {
873 return m_upper_extrap_rule_2(coord_eval, spline_coef);
876 if constexpr (!bsplines_type3::is_periodic()) {
877 if (
ddc::get<Dim3>(coord_eval) <
ddc::discrete_space<bsplines_type3>().rmin()) {
878 return m_lower_extrap_rule_3(coord_eval, spline_coef);
880 if (
ddc::get<Dim3>(coord_eval) >
ddc::discrete_space<bsplines_type3>().rmax()) {
881 return m_upper_extrap_rule_3(coord_eval, spline_coef);
887 continuous_dimension_type1,
888 continuous_dimension_type2,
889 continuous_dimension_type3>(
890 ddc::get<Dim1>(coord_eval),
891 ddc::get<Dim2>(coord_eval),
892 ddc::get<Dim3>(coord_eval)),
897
898
899
900
901
902
903
904 template <
class... DerivDims,
class Layout,
class... CoordsDims>
905 KOKKOS_INLINE_FUNCTION
double eval_no_bc(
906 ddc::DiscreteElement<DerivDims...>
const& deriv_order,
907 ddc::Coordinate<CoordsDims...>
const& coord_eval,
908 ddc::
ChunkSpan<
double const, spline_domain_type, Layout, memory_space>
const
911 using deriv_dim1 =
Deriv<continuous_dimension_type1>;
912 using deriv_dim2 =
Deriv<continuous_dimension_type2>;
913 using deriv_dim3 =
Deriv<continuous_dimension_type3>;
914 using deriv_dims = detail::TypeSeq<DerivDims...>;
918 (in_tags_v<DerivDims,
ddc::detail::TypeSeq<deriv_dim1, deriv_dim2, deriv_dim3>>
920 "The only valid dimensions for deriv_order are Deriv<Dim1>, Deriv<Dim2> and "
923 ddc::DiscreteElement<bsplines_type1> jmin1;
924 ddc::DiscreteElement<bsplines_type2> jmin2;
925 ddc::DiscreteElement<bsplines_type3> jmin3;
927 std::array<
double, bsplines_type1::degree() + 1> vals1_ptr;
928 Kokkos::mdspan<
double, Kokkos::extents<std::size_t, bsplines_type1::degree() + 1>>
const
929 vals1(vals1_ptr.data());
930 std::array<
double, bsplines_type2::degree() + 1> vals2_ptr;
931 Kokkos::mdspan<
double, Kokkos::extents<std::size_t, bsplines_type2::degree() + 1>>
const
932 vals2(vals2_ptr.data());
933 std::array<
double, bsplines_type3::degree() + 1> vals3_ptr;
934 Kokkos::mdspan<
double, Kokkos::extents<std::size_t, bsplines_type3::degree() + 1>>
const
935 vals3(vals3_ptr.data());
936 ddc::Coordinate<continuous_dimension_type1>
const coord_eval_interest1(coord_eval);
937 ddc::Coordinate<continuous_dimension_type2>
const coord_eval_interest2(coord_eval);
938 ddc::Coordinate<continuous_dimension_type3>
const coord_eval_interest3(coord_eval);
940 if constexpr (!in_tags_v<deriv_dim1, deriv_dims>) {
941 jmin1 =
ddc::discrete_space<bsplines_type1>().eval_basis(vals1, coord_eval_interest1);
943 auto const order1 = deriv_order.
template uid<deriv_dim1>();
944 KOKKOS_ASSERT(order1 > 0 && order1 <= bsplines_type1::degree())
946 std::array<
double, (bsplines_type1::degree() + 1) * (bsplines_type1::degree() + 1)>
952 bsplines_type1::degree() + 1,
953 Kokkos::dynamic_extent>>
const derivs1(derivs1_ptr.data(), order1 + 1);
955 jmin1 =
ddc::discrete_space<bsplines_type1>()
956 .eval_basis_and_n_derivs(derivs1, coord_eval_interest1, order1);
958 for (std::size_t i = 0; i < bsplines_type1::degree() + 1; ++i) {
959 vals1[i] = DDC_MDSPAN_ACCESS_OP(derivs1, i, order1);
963 if constexpr (!in_tags_v<deriv_dim2, deriv_dims>) {
964 jmin2 =
ddc::discrete_space<bsplines_type2>().eval_basis(vals2, coord_eval_interest2);
966 auto const order2 = deriv_order.
template uid<deriv_dim2>();
967 KOKKOS_ASSERT(order2 > 0 && order2 <= bsplines_type2::degree())
969 std::array<
double, (bsplines_type2::degree() + 1) * (bsplines_type2::degree() + 1)>
975 bsplines_type2::degree() + 1,
976 Kokkos::dynamic_extent>>
const derivs2(derivs2_ptr.data(), order2 + 1);
978 jmin2 =
ddc::discrete_space<bsplines_type2>()
979 .eval_basis_and_n_derivs(derivs2, coord_eval_interest2, order2);
981 for (std::size_t i = 0; i < bsplines_type2::degree() + 1; ++i) {
982 vals2[i] = DDC_MDSPAN_ACCESS_OP(derivs2, i, order2);
986 if constexpr (!in_tags_v<deriv_dim3, deriv_dims>) {
987 jmin3 =
ddc::discrete_space<bsplines_type3>().eval_basis(vals3, coord_eval_interest3);
989 auto const order3 = deriv_order.
template uid<deriv_dim3>();
990 KOKKOS_ASSERT(order3 > 0 && order3 <= bsplines_type3::degree())
992 std::array<
double, (bsplines_type3::degree() + 1) * (bsplines_type3::degree() + 1)>
998 bsplines_type3::degree() + 1,
999 Kokkos::dynamic_extent>>
const derivs3(derivs3_ptr.data(), order3 + 1);
1001 jmin3 =
ddc::discrete_space<bsplines_type3>()
1002 .eval_basis_and_n_derivs(derivs3, coord_eval_interest3, order3);
1004 for (std::size_t i = 0; i < bsplines_type3::degree() + 1; ++i) {
1005 vals3[i] = DDC_MDSPAN_ACCESS_OP(derivs3, i, order3);
1010 for (std::size_t i = 0; i < bsplines_type1::degree() + 1; ++i) {
1011 for (std::size_t j = 0; j < bsplines_type2::degree() + 1; ++j) {
1012 for (std::size_t k = 0; k < bsplines_type3::degree() + 1; ++k) {
1014 ddc::DiscreteElement<
1017 bsplines_type3>(jmin1 + i, jmin2 + j, jmin3 + k))
1018 * vals1[i] * vals2[j] * vals3[k];
friend class DiscreteDomain
KOKKOS_DEFAULTED_FUNCTION constexpr DiscreteElement()=default
A class to evaluate, differentiate or integrate a 3D spline function.
upper_extrapolation_rule_1_type upper_extrapolation_rule_dim_1() const
Get the upper extrapolation rule along the first dimension.
void deriv(DElem const &deriv_order, ddc::ChunkSpan< double, BatchedInterpolationDDom, Layout1, memory_space > const spline_eval, ddc::ChunkSpan< double const, batched_spline_domain_type< BatchedInterpolationDDom >, Layout2, memory_space > const spline_coef) const
Differentiate 3D spline function (described by its spline coefficients) on a mesh along the dimension...
void operator()(ddc::ChunkSpan< double, BatchedInterpolationDDom, Layout1, memory_space > const spline_eval, ddc::ChunkSpan< ddc::Coordinate< CoordsDims... > const, BatchedInterpolationDDom, Layout2, memory_space > const coords_eval, ddc::ChunkSpan< double const, batched_spline_domain_type< BatchedInterpolationDDom >, Layout3, memory_space > const spline_coef) const
Evaluate 3D spline function (described by its spline coefficients) on a mesh.
SplineEvaluator3D & operator=(SplineEvaluator3D &&x)=default
Move-assigns.
upper_extrapolation_rule_3_type upper_extrapolation_rule_dim_3() const
Get the upper extrapolation rule along the third dimension.
SplineEvaluator3D(LowerExtrapolationRule1 const &lower_extrap_rule1, UpperExtrapolationRule1 const &upper_extrap_rule1, LowerExtrapolationRule2 const &lower_extrap_rule2, UpperExtrapolationRule2 const &upper_extrap_rule2, LowerExtrapolationRule3 const &lower_extrap_rule3, UpperExtrapolationRule3 const &upper_extrap_rule3)
Build a SplineEvaluator3D acting on batched_spline_domain.
~SplineEvaluator3D()=default
Destructs.
lower_extrapolation_rule_1_type lower_extrapolation_rule_dim_1() const
Get the lower extrapolation rule along the first dimension.
upper_extrapolation_rule_2_type upper_extrapolation_rule_dim_2() const
Get the upper extrapolation rule along the second dimension.
void deriv(DElem const &deriv_order, ddc::ChunkSpan< double, BatchedInterpolationDDom, Layout1, memory_space > const spline_eval, ddc::ChunkSpan< ddc::Coordinate< CoordsDims... > const, BatchedInterpolationDDom, Layout2, memory_space > const coords_eval, ddc::ChunkSpan< double const, batched_spline_domain_type< BatchedInterpolationDDom >, Layout3, memory_space > const spline_coef) const
Differentiate 3D spline function (described by its spline coefficients) on a mesh along the dimension...
KOKKOS_FUNCTION double deriv(DElem const &deriv_order, ddc::Coordinate< CoordsDims... > const &coord_eval, ddc::ChunkSpan< double const, spline_domain_type, Layout, memory_space > const spline_coef) const
Differentiate 3D spline function (described by its spline coefficients) at a given coordinate along t...
SplineEvaluator3D(SplineEvaluator3D const &x)=default
Copy-constructs.
KOKKOS_FUNCTION double operator()(ddc::Coordinate< CoordsDims... > const &coord_eval, ddc::ChunkSpan< double const, spline_domain_type, Layout, memory_space > const spline_coef) const
Evaluate 3D spline function (described by its spline coefficients) at a given coordinate.
lower_extrapolation_rule_3_type lower_extrapolation_rule_dim_3() const
Get the lower extrapolation rule along the third dimension.
SplineEvaluator3D(SplineEvaluator3D &&x)=default
Move-constructs.
void integrate(ddc::ChunkSpan< double, BatchedDDom, Layout1, memory_space > const integrals, ddc::ChunkSpan< double const, BatchedSplineDDom, Layout2, memory_space > const spline_coef) const
Perform batched 3D integrations of a spline function (described by its spline coefficients) along the...
lower_extrapolation_rule_2_type lower_extrapolation_rule_dim_2() const
Get the lower extrapolation rule along the second dimension.
SplineEvaluator3D & operator=(SplineEvaluator3D const &x)=default
Copy-assigns.
void operator()(ddc::ChunkSpan< double, BatchedInterpolationDDom, Layout1, memory_space > const spline_eval, ddc::ChunkSpan< double const, batched_spline_domain_type< BatchedInterpolationDDom >, Layout2, memory_space > const spline_coef) const
Evaluate 3D spline function (described by its spline coefficients) on a mesh.
The top-level namespace of DDC.
A templated struct representing a discrete dimension storing the derivatives of a function along a co...