13#include <Kokkos_Core.hpp>
15#include "integrals.hpp"
16#include "periodic_extrapolation_rule.hpp"
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
42 class EvaluationDDim1,
43 class EvaluationDDim2,
44 class LowerExtrapolationRule1,
45 class UpperExtrapolationRule1,
46 class LowerExtrapolationRule2,
47 class UpperExtrapolationRule2,
53
54
60
61
62 struct eval_deriv_type
68 using continuous_dimension_type1 =
typename BSplines1::continuous_dimension_type;
71 using continuous_dimension_type2 =
typename BSplines2::continuous_dimension_type;
74 using exec_space = ExecSpace;
77 using memory_space = MemorySpace;
80 using evaluation_discrete_dimension_type1 = EvaluationDDim1;
83 using evaluation_discrete_dimension_type2 = EvaluationDDim2;
86 using bsplines_type1 = BSplines1;
89 using bsplines_type2 = BSplines2;
92 using evaluation_domain_type1 =
ddc::
DiscreteDomain<evaluation_discrete_dimension_type1>;
95 using evaluation_domain_type2 =
ddc::
DiscreteDomain<evaluation_discrete_dimension_type2>;
99 evaluation_discrete_dimension_type1,
100 evaluation_discrete_dimension_type2>;
115
116
117
118 using batch_domain_type =
typename ddc::remove_dims_of_t<
119 batched_evaluation_domain_type,
120 evaluation_discrete_dimension_type1,
121 evaluation_discrete_dimension_type2>;
124
125
126
127 using batched_spline_domain_type =
128 typename ddc::detail::convert_type_seq_to_discrete_domain_t<
ddc::type_seq_replace_t<
129 ddc::detail::TypeSeq<DDimX...>,
130 ddc::detail::TypeSeq<
131 evaluation_discrete_dimension_type1,
132 evaluation_discrete_dimension_type2>,
133 ddc::detail::TypeSeq<bsplines_type1, bsplines_type2>>>;
136 using lower_extrapolation_rule_1_type = LowerExtrapolationRule1;
139 using upper_extrapolation_rule_1_type = UpperExtrapolationRule1;
142 using lower_extrapolation_rule_2_type = LowerExtrapolationRule2;
145 using upper_extrapolation_rule_2_type = UpperExtrapolationRule2;
148 LowerExtrapolationRule1 m_lower_extrap_rule_1;
150 UpperExtrapolationRule1 m_upper_extrap_rule_1;
152 LowerExtrapolationRule2 m_lower_extrap_rule_2;
154 UpperExtrapolationRule2 m_upper_extrap_rule_2;
158 std::is_same_v<LowerExtrapolationRule1,
160 == bsplines_type1::is_periodic()
162 UpperExtrapolationRule1,
164 == bsplines_type1::is_periodic()
166 LowerExtrapolationRule2,
168 == bsplines_type2::is_periodic()
170 UpperExtrapolationRule2,
172 == bsplines_type2::is_periodic(),
173 "PeriodicExtrapolationRule has to be used if and only if dimension is periodic");
175 std::is_invocable_r_v<
177 LowerExtrapolationRule1,
178 ddc::Coordinate<continuous_dimension_type1>,
182 Kokkos::layout_right,
184 "LowerExtrapolationRule1::operator() has to be callable "
185 "with usual arguments.");
187 std::is_invocable_r_v<
189 UpperExtrapolationRule1,
190 ddc::Coordinate<continuous_dimension_type1>,
194 Kokkos::layout_right,
196 "UpperExtrapolationRule1::operator() has to be callable "
197 "with usual arguments.");
199 std::is_invocable_r_v<
201 LowerExtrapolationRule2,
202 ddc::Coordinate<continuous_dimension_type2>,
206 Kokkos::layout_right,
208 "LowerExtrapolationRule2::operator() has to be callable "
209 "with usual arguments.");
211 std::is_invocable_r_v<
213 UpperExtrapolationRule2,
214 ddc::Coordinate<continuous_dimension_type2>,
218 Kokkos::layout_right,
220 "UpperExtrapolationRule2::operator() has to be callable "
221 "with usual arguments.");
224
225
226
227
228
229
230
231
232
234 LowerExtrapolationRule1
const& lower_extrap_rule1,
235 UpperExtrapolationRule1
const& upper_extrap_rule1,
236 LowerExtrapolationRule2
const& lower_extrap_rule2,
237 UpperExtrapolationRule2
const& upper_extrap_rule2)
238 : m_lower_extrap_rule_1(lower_extrap_rule1)
239 , m_upper_extrap_rule_1(upper_extrap_rule1)
240 , m_lower_extrap_rule_2(lower_extrap_rule2)
241 , m_upper_extrap_rule_2(upper_extrap_rule2)
246
247
248
249
253
254
255
256
263
264
265
266
267
271
272
273
274
275
279
280
281
282
283
284
285
286
289 return m_lower_extrap_rule_1;
293
294
295
296
297
298
299
300
303 return m_upper_extrap_rule_1;
307
308
309
310
311
312
313
314
317 return m_lower_extrap_rule_2;
321
322
323
324
325
326
327
328
331 return m_upper_extrap_rule_2;
335
336
337
338
339
340
341
342
343
344
345
346 template <
class Layout,
class... CoordsDims>
348 ddc::Coordinate<CoordsDims...>
const& coord_eval,
349 ddc::
ChunkSpan<
double const, spline_domain_type, Layout, memory_space>
const
352 return eval(coord_eval, spline_coef);
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375 template <
class Layout1,
class Layout2,
class Layout3,
class... CoordsDims>
377 ddc::
ChunkSpan<
double, batched_evaluation_domain_type, Layout1, memory_space>
const
380 ddc::Coordinate<CoordsDims...>
const,
381 batched_evaluation_domain_type,
383 memory_space>
const coords_eval,
384 ddc::
ChunkSpan<
double const, batched_spline_domain_type, Layout3, memory_space>
const
387 batch_domain_type
const batch_domain(coords_eval.domain());
388 evaluation_domain_type1
const evaluation_domain1(spline_eval.domain());
389 evaluation_domain_type2
const evaluation_domain2(spline_eval.domain());
390 ddc::parallel_for_each(
391 "ddc_splines_evaluate_2d",
394 KOKKOS_CLASS_LAMBDA(
typename batch_domain_type::discrete_element_type
const j) {
395 const auto spline_eval_2D = spline_eval[j];
396 const auto coords_eval_2D = coords_eval[j];
397 const auto spline_coef_2D = spline_coef[j];
398 for (
auto const i1 : evaluation_domain1) {
399 for (
auto const i2 : evaluation_domain2) {
400 spline_eval_2D(i1, i2) = eval(coords_eval_2D(i1, i2), spline_coef_2D);
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421 template <
class Layout1,
class Layout2>
423 ddc::
ChunkSpan<
double, batched_evaluation_domain_type, Layout1, memory_space>
const
425 ddc::
ChunkSpan<
double const, batched_spline_domain_type, Layout2, memory_space>
const
428 batch_domain_type
const batch_domain(spline_eval.domain());
429 evaluation_domain_type1
const evaluation_domain1(spline_eval.domain());
430 evaluation_domain_type2
const evaluation_domain2(spline_eval.domain());
431 ddc::parallel_for_each(
432 "ddc_splines_evaluate_2d",
435 KOKKOS_CLASS_LAMBDA(
typename batch_domain_type::discrete_element_type
const j) {
436 const auto spline_eval_2D = spline_eval[j];
437 const auto spline_coef_2D = spline_coef[j];
438 for (
auto const i1 : evaluation_domain1) {
439 for (
auto const i2 : evaluation_domain2) {
440 ddc::Coordinate<continuous_dimension_type1, continuous_dimension_type2>
441 coord_eval_2D(
ddc::coordinate(i1),
ddc::coordinate(i2));
442 spline_eval_2D(i1, i2) = eval(coord_eval_2D(i1, i2), spline_coef_2D);
449
450
451
452
453
454
455
456
457
458
459 template <
class Layout,
class... CoordsDims>
461 ddc::Coordinate<CoordsDims...>
const& coord_eval,
462 ddc::
ChunkSpan<
double const, spline_domain_type, Layout, memory_space>
const
465 return eval_no_bc<eval_deriv_type, eval_type>(coord_eval, spline_coef);
469
470
471
472
473
474
475
476
477
478
479 template <
class Layout,
class... CoordsDims>
481 ddc::Coordinate<CoordsDims...>
const& coord_eval,
482 ddc::
ChunkSpan<
double const, spline_domain_type, Layout, memory_space>
const
485 return eval_no_bc<eval_type, eval_deriv_type>(coord_eval, spline_coef);
489
490
491
492
493
494
495
496
497
498
499 template <
class Layout,
class... CoordsDims>
501 ddc::Coordinate<CoordsDims...>
const& coord_eval,
502 ddc::
ChunkSpan<
double const, spline_domain_type, Layout, memory_space>
const
505 return eval_no_bc<eval_deriv_type, eval_deriv_type>(coord_eval, spline_coef);
509
510
511
512
513
514
515
516
517
518
519
520
521 template <
class InterestDim,
class Layout,
class... CoordsDims>
523 ddc::Coordinate<CoordsDims...>
const& coord_eval,
524 ddc::
ChunkSpan<
double const, spline_domain_type, Layout, memory_space>
const
528 std::is_same_v<InterestDim, continuous_dimension_type1>
529 || std::is_same_v<InterestDim, continuous_dimension_type2>);
530 if constexpr (std::is_same_v<
532 typename evaluation_discrete_dimension_type1::
533 continuous_dimension_type>) {
534 return deriv_dim_1(coord_eval, spline_coef);
535 }
else if constexpr (std::is_same_v<
537 typename evaluation_discrete_dimension_type2::
538 continuous_dimension_type>) {
539 return deriv_dim_2(coord_eval, spline_coef);
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559 template <
class InterestDim1,
class InterestDim2,
class Layout,
class... CoordsDims>
561 ddc::Coordinate<CoordsDims...>
const& coord_eval,
562 ddc::
ChunkSpan<
double const, spline_domain_type, Layout, memory_space>
const
568 typename evaluation_discrete_dimension_type1::continuous_dimension_type>
569 && std::is_same_v<InterestDim2, continuous_dimension_type2>)
572 typename evaluation_discrete_dimension_type1::continuous_dimension_type>
573 && std::is_same_v<InterestDim1, continuous_dimension_type2>));
574 return deriv_1_and_2(coord_eval, spline_coef);
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597 template <
class Layout1,
class Layout2,
class Layout3,
class... CoordsDims>
599 ddc::
ChunkSpan<
double, batched_evaluation_domain_type, Layout1, memory_space>
const
602 ddc::Coordinate<CoordsDims...>
const,
603 batched_evaluation_domain_type,
605 memory_space>
const coords_eval,
606 ddc::
ChunkSpan<
double const, batched_spline_domain_type, Layout3, memory_space>
const
609 batch_domain_type
const batch_domain(coords_eval.domain());
610 evaluation_domain_type1
const evaluation_domain1(spline_eval.domain());
611 evaluation_domain_type2
const evaluation_domain2(spline_eval.domain());
612 ddc::parallel_for_each(
613 "ddc_splines_differentiate_2d_dim_1",
616 KOKKOS_CLASS_LAMBDA(
typename batch_domain_type::discrete_element_type
const j) {
617 const auto spline_eval_2D = spline_eval[j];
618 const auto coords_eval_2D = coords_eval[j];
619 const auto spline_coef_2D = spline_coef[j];
620 for (
auto const i1 : evaluation_domain1) {
621 for (
auto const i2 : evaluation_domain2) {
622 spline_eval_2D(i1, i2) = eval_no_bc<
624 eval_type>(coords_eval_2D(i1, i2), spline_coef_2D);
631
632
633
634
635
636
637
638
639
640
641
642
643 template <
class Layout1,
class Layout2>
645 ddc::
ChunkSpan<
double, batched_evaluation_domain_type, Layout1, memory_space>
const
647 ddc::
ChunkSpan<
double const, batched_spline_domain_type, Layout2, memory_space>
const
650 batch_domain_type
const batch_domain(spline_eval.domain());
651 evaluation_domain_type1
const evaluation_domain1(spline_eval.domain());
652 evaluation_domain_type2
const evaluation_domain2(spline_eval.domain());
653 ddc::parallel_for_each(
654 "ddc_splines_differentiate_2d_dim_1",
657 KOKKOS_CLASS_LAMBDA(
typename batch_domain_type::discrete_element_type
const j) {
658 const auto spline_eval_2D = spline_eval[j];
659 const auto spline_coef_2D = spline_coef[j];
660 for (
auto const i1 : evaluation_domain1) {
661 for (
auto const i2 : evaluation_domain2) {
662 ddc::Coordinate<continuous_dimension_type1, continuous_dimension_type2>
663 coord_eval_2D(
ddc::coordinate(i1),
ddc::coordinate(i2));
664 spline_eval_2D(i1, i2) = eval_no_bc<
666 eval_type>(coord_eval_2D, spline_coef_2D);
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690 template <
class Layout1,
class Layout2,
class Layout3,
class... CoordsDims>
692 ddc::
ChunkSpan<
double, batched_evaluation_domain_type, Layout1, memory_space>
const
695 ddc::Coordinate<CoordsDims...>
const,
696 batched_evaluation_domain_type,
698 memory_space>
const coords_eval,
699 ddc::
ChunkSpan<
double const, batched_spline_domain_type, Layout3, memory_space>
const
702 batch_domain_type
const batch_domain(coords_eval.domain());
703 evaluation_domain_type1
const evaluation_domain1(spline_eval.domain());
704 evaluation_domain_type2
const evaluation_domain2(spline_eval.domain());
705 ddc::parallel_for_each(
706 "ddc_splines_differentiate_2d_dim_2",
709 KOKKOS_CLASS_LAMBDA(
typename batch_domain_type::discrete_element_type
const j) {
710 const auto spline_eval_2D = spline_eval[j];
711 const auto coords_eval_2D = coords_eval[j];
712 const auto spline_coef_2D = spline_coef[j];
713 for (
auto const i1 : evaluation_domain1) {
714 for (
auto const i2 : evaluation_domain2) {
715 spline_eval_2D(i1, i2) = eval_no_bc<
717 eval_deriv_type>(coords_eval_2D(i1, i2), spline_coef_2D);
724
725
726
727
728
729
730
731
732
733
734
735
736 template <
class Layout1,
class Layout2>
738 ddc::
ChunkSpan<
double, batched_evaluation_domain_type, Layout1, memory_space>
const
740 ddc::
ChunkSpan<
double const, batched_spline_domain_type, Layout2, memory_space>
const
743 batch_domain_type
const batch_domain(spline_eval.domain());
744 evaluation_domain_type1
const evaluation_domain1(spline_eval.domain());
745 evaluation_domain_type2
const evaluation_domain2(spline_eval.domain());
746 ddc::parallel_for_each(
747 "ddc_splines_differentiate_2d_dim_2",
750 KOKKOS_CLASS_LAMBDA(
typename batch_domain_type::discrete_element_type
const j) {
751 const auto spline_eval_2D = spline_eval[j];
752 const auto spline_coef_2D = spline_coef[j];
753 for (
auto const i1 : evaluation_domain1) {
754 for (
auto const i2 : evaluation_domain2) {
755 ddc::Coordinate<continuous_dimension_type1, continuous_dimension_type2>
756 coord_eval_2D(
ddc::coordinate(i1),
ddc::coordinate(i2));
757 spline_eval_2D(i1, i2) = eval_no_bc<
759 eval_deriv_type>(coord_eval_2D, spline_coef_2D);
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783 template <
class Layout1,
class Layout2,
class Layout3,
class... CoordsDims>
785 ddc::
ChunkSpan<
double, batched_evaluation_domain_type, Layout1, memory_space>
const
788 ddc::Coordinate<CoordsDims...>
const,
789 batched_evaluation_domain_type,
791 memory_space>
const coords_eval,
792 ddc::
ChunkSpan<
double const, batched_spline_domain_type, Layout3, memory_space>
const
795 batch_domain_type
const batch_domain(coords_eval.domain());
796 evaluation_domain_type1
const evaluation_domain1(spline_eval.domain());
797 evaluation_domain_type2
const evaluation_domain2(spline_eval.domain());
798 ddc::parallel_for_each(
799 "ddc_splines_cross_differentiate",
802 KOKKOS_CLASS_LAMBDA(
typename batch_domain_type::discrete_element_type
const j) {
803 const auto spline_eval_2D = spline_eval[j];
804 const auto coords_eval_2D = coords_eval[j];
805 const auto spline_coef_2D = spline_coef[j];
806 for (
auto const i1 : evaluation_domain1) {
807 for (
auto const i2 : evaluation_domain2) {
808 spline_eval_2D(i1, i2) = eval_no_bc<
810 eval_deriv_type>(coords_eval_2D(i1, i2), spline_coef_2D);
817
818
819
820
821
822
823
824
825
826
827
828
829 template <
class Layout1,
class Layout2>
831 ddc::
ChunkSpan<
double, batched_evaluation_domain_type, Layout1, memory_space>
const
833 ddc::
ChunkSpan<
double const, batched_spline_domain_type, Layout2, memory_space>
const
836 batch_domain_type
const batch_domain(spline_eval.domain());
837 evaluation_domain_type1
const evaluation_domain1(spline_eval.domain());
838 evaluation_domain_type2
const evaluation_domain2(spline_eval.domain());
839 ddc::parallel_for_each(
840 "ddc_splines_cross_differentiate",
843 KOKKOS_CLASS_LAMBDA(
typename batch_domain_type::discrete_element_type
const j) {
844 const auto spline_eval_2D = spline_eval[j];
845 const auto spline_coef_2D = spline_coef[j];
846 for (
auto const i1 : evaluation_domain1) {
847 for (
auto const i2 : evaluation_domain2) {
848 ddc::Coordinate<continuous_dimension_type1, continuous_dimension_type2>
849 coord_eval_2D(
ddc::coordinate(i1),
ddc::coordinate(i2));
850 spline_eval_2D(i1, i2) = eval_no_bc<
852 eval_deriv_type>(coord_eval_2D, spline_coef_2D);
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877 template <
class InterestDim,
class Layout1,
class Layout2,
class Layout3,
class... CoordsDims>
879 ddc::
ChunkSpan<
double, batched_evaluation_domain_type, Layout1, memory_space>
const
882 ddc::Coordinate<CoordsDims...>
const,
883 batched_evaluation_domain_type,
885 memory_space>
const coords_eval,
886 ddc::
ChunkSpan<
double const, batched_spline_domain_type, Layout3, memory_space>
const
892 typename evaluation_discrete_dimension_type1::continuous_dimension_type>
893 || std::is_same_v<InterestDim, continuous_dimension_type2>);
894 if constexpr (std::is_same_v<
896 typename evaluation_discrete_dimension_type1::
897 continuous_dimension_type>) {
898 return deriv_dim_1(spline_eval, coords_eval, spline_coef);
899 }
else if constexpr (std::is_same_v<
901 typename evaluation_discrete_dimension_type2::
902 continuous_dimension_type>) {
903 return deriv_dim_2(spline_eval, coords_eval, spline_coef);
908
909
910
911
912
913
914
915
916
917
918
919
920
921 template <
class InterestDim,
class Layout1,
class Layout2>
923 ddc::
ChunkSpan<
double, batched_evaluation_domain_type, Layout1, memory_space>
const
925 ddc::
ChunkSpan<
double const, batched_spline_domain_type, Layout2, memory_space>
const
931 typename evaluation_discrete_dimension_type1::continuous_dimension_type>
932 || std::is_same_v<InterestDim, continuous_dimension_type2>);
933 if constexpr (std::is_same_v<
935 typename evaluation_discrete_dimension_type1::
936 continuous_dimension_type>) {
937 return deriv_dim_1(spline_eval, spline_coef);
938 }
else if constexpr (std::is_same_v<
940 typename evaluation_discrete_dimension_type2::
941 continuous_dimension_type>) {
942 return deriv_dim_2(spline_eval, spline_coef);
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
977 ddc::
ChunkSpan<
double, batched_evaluation_domain_type, Layout1, memory_space>
const
980 ddc::Coordinate<CoordsDims...>
const,
981 batched_evaluation_domain_type,
983 memory_space>
const coords_eval,
984 ddc::
ChunkSpan<
double const, batched_spline_domain_type, Layout3, memory_space>
const
990 typename evaluation_discrete_dimension_type1::continuous_dimension_type>
991 && std::is_same_v<InterestDim2, continuous_dimension_type2>)
994 typename evaluation_discrete_dimension_type1::continuous_dimension_type>
995 && std::is_same_v<InterestDim1, continuous_dimension_type2>));
996 return deriv_1_and_2(spline_eval, coords_eval, spline_coef);
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017 template <
class InterestDim1,
class InterestDim2,
class Layout1,
class Layout2>
1019 ddc::
ChunkSpan<
double, batched_evaluation_domain_type, Layout1, memory_space>
const
1021 ddc::
ChunkSpan<
double const, batched_spline_domain_type, Layout2, memory_space>
const
1027 typename evaluation_discrete_dimension_type1::continuous_dimension_type>
1028 && std::is_same_v<InterestDim2, continuous_dimension_type2>)
1031 typename evaluation_discrete_dimension_type1::continuous_dimension_type>
1032 && std::is_same_v<InterestDim1, continuous_dimension_type2>));
1033 return deriv_1_and_2(spline_eval, spline_coef);
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049 template <
class Layout1,
class Layout2>
1051 ddc::
ChunkSpan<
double, batch_domain_type, Layout1, memory_space>
const integrals,
1052 ddc::
ChunkSpan<
double const, batched_spline_domain_type, Layout2, memory_space>
const
1055 batch_domain_type batch_domain(integrals.domain());
1060 ddc::integrals(exec_space(), values1);
1065 ddc::integrals(exec_space(), values2);
1067 ddc::parallel_for_each(
1068 "ddc_splines_integrate_bsplines",
1071 KOKKOS_LAMBDA(
typename batch_domain_type::discrete_element_type
const j) {
1073 for (
typename spline_domain_type1::discrete_element_type
const i1 :
1075 for (
typename spline_domain_type2::discrete_element_type
const i2 :
1077 integrals(j) += spline_coef(i1, i2, j) * values1(i1) * values2(i2);
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099 template <
class Layout,
class... CoordsDims>
1100 KOKKOS_INLINE_FUNCTION
double eval(
1101 ddc::Coordinate<CoordsDims...> coord_eval,
1102 ddc::
ChunkSpan<
double const, spline_domain_type, Layout, memory_space>
const
1105 using Dim1 = continuous_dimension_type1;
1106 using Dim2 = continuous_dimension_type2;
1107 if constexpr (bsplines_type1::is_periodic()) {
1108 if (
ddc::get<Dim1>(coord_eval) <
ddc::discrete_space<bsplines_type1>().rmin()
1109 ||
ddc::get<Dim1>(coord_eval) >
ddc::discrete_space<bsplines_type1>().rmax()) {
1110 ddc::get<Dim1>(coord_eval)
1112 (
ddc::get<Dim1>(coord_eval)
1113 -
ddc::discrete_space<bsplines_type1>().rmin())
1114 /
ddc::discrete_space<bsplines_type1>().length())
1115 *
ddc::discrete_space<bsplines_type1>().length();
1118 if constexpr (bsplines_type2::is_periodic()) {
1119 if (
ddc::get<Dim2>(coord_eval) <
ddc::discrete_space<bsplines_type2>().rmin()
1120 ||
ddc::get<Dim2>(coord_eval) >
ddc::discrete_space<bsplines_type2>().rmax()) {
1121 ddc::get<Dim2>(coord_eval)
1123 (
ddc::get<Dim2>(coord_eval)
1124 -
ddc::discrete_space<bsplines_type2>().rmin())
1125 /
ddc::discrete_space<bsplines_type2>().length())
1126 *
ddc::discrete_space<bsplines_type2>().length();
1129 if constexpr (!bsplines_type1::is_periodic()) {
1130 if (
ddc::get<Dim1>(coord_eval) <
ddc::discrete_space<bsplines_type1>().rmin()) {
1131 return m_lower_extrap_rule_1(coord_eval, spline_coef);
1133 if (
ddc::get<Dim1>(coord_eval) >
ddc::discrete_space<bsplines_type1>().rmax()) {
1134 return m_upper_extrap_rule_1(coord_eval, spline_coef);
1137 if constexpr (!bsplines_type2::is_periodic()) {
1138 if (
ddc::get<Dim2>(coord_eval) <
ddc::discrete_space<bsplines_type2>().rmin()) {
1139 return m_lower_extrap_rule_2(coord_eval, spline_coef);
1141 if (
ddc::get<Dim2>(coord_eval) >
ddc::discrete_space<bsplines_type2>().rmax()) {
1142 return m_upper_extrap_rule_2(coord_eval, spline_coef);
1145 return eval_no_bc<eval_type, eval_type>(
1146 ddc::Coordinate<continuous_dimension_type1, continuous_dimension_type2>(
1147 ddc::get<Dim1>(coord_eval),
1148 ddc::get<Dim2>(coord_eval)),
1153
1154
1155
1156
1157
1158
1159
1160 template <
class EvalType1,
class EvalType2,
class Layout,
class... CoordsDims>
1161 KOKKOS_INLINE_FUNCTION
double eval_no_bc(
1162 ddc::Coordinate<CoordsDims...>
const& coord_eval,
1163 ddc::
ChunkSpan<
double const, spline_domain_type, Layout, memory_space>
const
1167 std::is_same_v<EvalType1, eval_type> || std::is_same_v<EvalType1, eval_deriv_type>);
1169 std::is_same_v<EvalType2, eval_type> || std::is_same_v<EvalType2, eval_deriv_type>);
1170 ddc::DiscreteElement<bsplines_type1> jmin1;
1171 ddc::DiscreteElement<bsplines_type2> jmin2;
1173 std::array<
double, bsplines_type1::degree() + 1> vals1_ptr;
1174 Kokkos::mdspan<
double, Kokkos::extents<std::size_t, bsplines_type1::degree() + 1>>
const
1175 vals1(vals1_ptr.data());
1176 std::array<
double, bsplines_type2::degree() + 1> vals2_ptr;
1177 Kokkos::mdspan<
double, Kokkos::extents<std::size_t, bsplines_type2::degree() + 1>>
const
1178 vals2(vals2_ptr.data());
1179 ddc::Coordinate<continuous_dimension_type1>
const coord_eval_interest1(coord_eval);
1180 ddc::Coordinate<continuous_dimension_type2>
const coord_eval_interest2(coord_eval);
1182 if constexpr (std::is_same_v<EvalType1, eval_type>) {
1183 jmin1 =
ddc::discrete_space<bsplines_type1>().eval_basis(vals1, coord_eval_interest1);
1184 }
else if constexpr (std::is_same_v<EvalType1, eval_deriv_type>) {
1185 jmin1 =
ddc::discrete_space<bsplines_type1>().eval_deriv(vals1, coord_eval_interest1);
1187 if constexpr (std::is_same_v<EvalType2, eval_type>) {
1188 jmin2 =
ddc::discrete_space<bsplines_type2>().eval_basis(vals2, coord_eval_interest2);
1189 }
else if constexpr (std::is_same_v<EvalType2, eval_deriv_type>) {
1190 jmin2 =
ddc::discrete_space<bsplines_type2>().eval_deriv(vals2, coord_eval_interest2);
1194 for (std::size_t i = 0; i < bsplines_type1::degree() + 1; ++i) {
1195 for (std::size_t j = 0; j < bsplines_type2::degree() + 1; ++j) {
1196 y += spline_coef(
ddc::DiscreteElement<
1198 bsplines_type2>(jmin1 + i, jmin2 + j))
1199 * vals1[i] * vals2[j];
friend class DiscreteDomain
A class to evaluate, differentiate or integrate a 2D spline function.
void deriv_dim_2(ddc::ChunkSpan< double, batched_evaluation_domain_type, Layout1, memory_space > const spline_eval, ddc::ChunkSpan< ddc::Coordinate< CoordsDims... > const, batched_evaluation_domain_type, Layout2, memory_space > const coords_eval, ddc::ChunkSpan< double const, batched_spline_domain_type, Layout3, memory_space > const spline_coef) const
Differentiate 2D spline function (described by its spline coefficients) on a mesh along second dimens...
void deriv2(ddc::ChunkSpan< double, batched_evaluation_domain_type, Layout1, memory_space > const spline_eval, ddc::ChunkSpan< double const, batched_spline_domain_type, Layout2, memory_space > const spline_coef) const
Double-differentiate 2D spline function (described by its spline coefficients) on a mesh along specif...
void deriv(ddc::ChunkSpan< double, batched_evaluation_domain_type, Layout1, memory_space > const spline_eval, ddc::ChunkSpan< double const, batched_spline_domain_type, Layout2, memory_space > const spline_coef) const
Differentiate spline function (described by its spline coefficients) on a mesh along a specified dime...
void deriv(ddc::ChunkSpan< double, batched_evaluation_domain_type, Layout1, memory_space > const spline_eval, ddc::ChunkSpan< ddc::Coordinate< CoordsDims... > const, batched_evaluation_domain_type, Layout2, memory_space > const coords_eval, ddc::ChunkSpan< double const, batched_spline_domain_type, Layout3, memory_space > const spline_coef) const
Differentiate spline function (described by its spline coefficients) on a mesh along a specified dime...
void deriv2(ddc::ChunkSpan< double, batched_evaluation_domain_type, Layout1, memory_space > const spline_eval, ddc::ChunkSpan< ddc::Coordinate< CoordsDims... > const, batched_evaluation_domain_type, Layout2, memory_space > const coords_eval, ddc::ChunkSpan< double const, batched_spline_domain_type, Layout3, memory_space > const spline_coef) const
Double-differentiate 2D spline function (described by its spline coefficients) on a mesh along specif...
lower_extrapolation_rule_2_type lower_extrapolation_rule_dim_2() const
Get the lower extrapolation rule along the second dimension.
void operator()(ddc::ChunkSpan< double, batched_evaluation_domain_type, Layout1, memory_space > const spline_eval, ddc::ChunkSpan< ddc::Coordinate< CoordsDims... > const, batched_evaluation_domain_type, Layout2, memory_space > const coords_eval, ddc::ChunkSpan< double const, batched_spline_domain_type, Layout3, memory_space > const spline_coef) const
Evaluate 2D spline function (described by its spline coefficients) on a mesh.
KOKKOS_FUNCTION double deriv2(ddc::Coordinate< CoordsDims... > const &coord_eval, ddc::ChunkSpan< double const, spline_domain_type, Layout, memory_space > const spline_coef) const
Double-differentiate 2D spline function (described by its spline coefficients) at a given coordinate ...
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
Cross-differentiate 2D spline function (described by its spline coefficients) at a given coordinate.
upper_extrapolation_rule_2_type upper_extrapolation_rule_dim_2() const
Get the upper extrapolation rule along the second dimension.
KOKKOS_FUNCTION double deriv(ddc::Coordinate< CoordsDims... > const &coord_eval, ddc::ChunkSpan< double const, spline_domain_type, Layout, memory_space > const spline_coef) const
Differentiate 2D spline function (described by its spline coefficients) at a given coordinate along a...
void deriv_dim_1(ddc::ChunkSpan< double, batched_evaluation_domain_type, Layout1, memory_space > const spline_eval, ddc::ChunkSpan< double const, batched_spline_domain_type, Layout2, memory_space > const spline_coef) const
Differentiate 2D spline function (described by its spline coefficients) on a mesh along first dimensi...
void deriv_1_and_2(ddc::ChunkSpan< double, batched_evaluation_domain_type, Layout1, memory_space > const spline_eval, ddc::ChunkSpan< ddc::Coordinate< CoordsDims... > const, batched_evaluation_domain_type, Layout2, memory_space > const coords_eval, ddc::ChunkSpan< double const, batched_spline_domain_type, Layout3, memory_space > const spline_coef) const
Cross-differentiate 2D spline function (described by its spline coefficients) on a mesh along dimensi...
SplineEvaluator2D(LowerExtrapolationRule1 const &lower_extrap_rule1, UpperExtrapolationRule1 const &upper_extrap_rule1, LowerExtrapolationRule2 const &lower_extrap_rule2, UpperExtrapolationRule2 const &upper_extrap_rule2)
Build a SplineEvaluator2D acting on batched_spline_domain.
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 2D spline function (described by its spline coefficients) at a given coordinate.
SplineEvaluator2D & operator=(SplineEvaluator2D &&x)=default
Move-assigns.
void deriv_dim_1(ddc::ChunkSpan< double, batched_evaluation_domain_type, Layout1, memory_space > const spline_eval, ddc::ChunkSpan< ddc::Coordinate< CoordsDims... > const, batched_evaluation_domain_type, Layout2, memory_space > const coords_eval, ddc::ChunkSpan< double const, batched_spline_domain_type, Layout3, memory_space > const spline_coef) const
Differentiate 2D spline function (described by its spline coefficients) on a mesh along first dimensi...
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
Differentiate 2D spline function (described by its spline coefficients) at a given coordinate along s...
SplineEvaluator2D(SplineEvaluator2D &&x)=default
Move-constructs.
lower_extrapolation_rule_1_type lower_extrapolation_rule_dim_1() const
Get the lower extrapolation rule along the first dimension.
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
Perform batched 2D integrations of a spline function (described by its spline coefficients) along the...
void deriv_dim_2(ddc::ChunkSpan< double, batched_evaluation_domain_type, Layout1, memory_space > const spline_eval, ddc::ChunkSpan< double const, batched_spline_domain_type, Layout2, memory_space > const spline_coef) const
Differentiate 2D spline function (described by its spline coefficients) on a mesh along second dimens...
SplineEvaluator2D(SplineEvaluator2D const &x)=default
Copy-constructs.
void deriv_1_and_2(ddc::ChunkSpan< double, batched_evaluation_domain_type, Layout1, memory_space > const spline_eval, ddc::ChunkSpan< double const, batched_spline_domain_type, Layout2, memory_space > const spline_coef) const
Cross-differentiate 2D spline function (described by its spline coefficients) on a mesh along dimensi...
void operator()(ddc::ChunkSpan< double, batched_evaluation_domain_type, Layout1, memory_space > const spline_eval, ddc::ChunkSpan< double const, batched_spline_domain_type, Layout2, memory_space > const spline_coef) const
Evaluate 2D spline function (described by its spline coefficients) on a mesh.
~SplineEvaluator2D()=default
Destructs.
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
Differentiate 2D spline function (described by its spline coefficients) at a given coordinate along f...
SplineEvaluator2D & operator=(SplineEvaluator2D const &x)=default
Copy-assigns.
upper_extrapolation_rule_1_type upper_extrapolation_rule_dim_1() const
Get the upper extrapolation rule along the first dimension.
The top-level namespace of DDC.