19#include <Kokkos_Core.hpp>
31
32
33
34
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
60 class InterpolationDDim,
74 using exec_space = ExecSpace;
77 using memory_space = MemorySpace;
80 using continuous_dimension_type = InterpolationDDim::continuous_dimension_type;
83 using interpolation_discrete_dimension_type = InterpolationDDim;
86 using bsplines_type = BSplines;
89 using deriv_type =
ddc::
Deriv<continuous_dimension_type>;
92 using interpolation_domain_type =
ddc::
DiscreteDomain<interpolation_discrete_dimension_type>;
95
96
97
98
99 template <concepts::discrete_domain BatchedInterpolationDDom>
100 using batched_interpolation_domain_type = BatchedInterpolationDDom;
103
104
105
106
107
108
109
110
111 template <concepts::discrete_domain BatchedInterpolationDDom>
112 using batch_domain_type =
ddc::
113 remove_dims_of_t<BatchedInterpolationDDom, interpolation_discrete_dimension_type>;
116
117
118
119
120
121
122
123
124 template <concepts::discrete_domain BatchedInterpolationDDom>
125 using batched_spline_domain_type =
ddc::replace_dim_of_t<
126 BatchedInterpolationDDom,
127 interpolation_discrete_dimension_type,
132
133
134
135
136
137
138
139
140 template <concepts::discrete_domain BatchedInterpolationDDom>
141 using batched_spline_tr_domain_type
142 =
ddc::detail::convert_type_seq_to_discrete_domain_t<
ddc::type_seq_merge_t<
143 ddc::detail::TypeSeq<bsplines_type>,
144 ddc::type_seq_remove_t<
145 ddc::to_type_seq_t<BatchedInterpolationDDom>,
146 ddc::detail::TypeSeq<interpolation_discrete_dimension_type>>>>;
150
151
152
153
154
155
156
157
158 template <concepts::discrete_domain BatchedInterpolationDDom>
159 using batched_derivs_domain_type =
ddc::replace_dim_of_t<
160 BatchedInterpolationDDom,
161 interpolation_discrete_dimension_type,
165 static constexpr bool s_odd = BSplines::degree() % 2;
168 static constexpr int s_nbe_xmin = n_boundary_equations(SBCLower, BSplines::degree());
171 static constexpr int s_nbe_xmax = n_boundary_equations(SBCUpper, BSplines::degree());
176 : n_boundary_equations(SBCLower, BSplines::degree());
181 : n_boundary_equations(SBCUpper, BSplines::degree());
193 interpolation_domain_type m_interpolation_domain;
200 std::unique_ptr<
ddc::detail::SplinesLinearProblem<exec_space>> m_matrix;
205 void compute_offset(interpolation_domain_type
const& interpolation_domain,
int& offset);
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
228 interpolation_domain_type
const& interpolation_domain,
229 std::optional<std::size_t> cols_per_chunk = std::nullopt,
230 std::optional<
unsigned int> preconditioner_max_block_size = std::nullopt)
231 : m_interpolation_domain(interpolation_domain)
232 , m_dx((
ddc::discrete_space<BSplines>().rmax() -
ddc::discrete_space<BSplines>().rmin())
233 /
ddc::discrete_space<BSplines>().ncells())
234 , m_label(std::move(label))
239 "Incompatible closure relations");
242 compute_offset(
this->interpolation_domain(), m_offset);
245 int lower_block_size;
246 int upper_block_size;
247 if constexpr (bsplines_type::is_uniform()) {
248 upper_block_size = compute_block_sizes_uniform(SBCLower,
s_nbe_xmin);
249 lower_block_size = compute_block_sizes_uniform(SBCUpper,
s_nbe_xmax);
251 upper_block_size = compute_block_sizes_non_uniform(SBCLower,
s_nbe_xmin);
252 lower_block_size = compute_block_sizes_non_uniform(SBCUpper,
s_nbe_xmax);
258 preconditioner_max_block_size);
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
278 interpolation_domain_type
const& interpolation_domain,
279 std::optional<std::size_t> cols_per_chunk = std::nullopt,
280 std::optional<
unsigned int> preconditioner_max_block_size = std::nullopt)
283 interpolation_domain,
285 preconditioner_max_block_size)
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307 template <
concepts::discrete_domain BatchedInterpolationDDom>
310 BatchedInterpolationDDom
const& batched_interpolation_domain,
311 std::optional<std::size_t> cols_per_chunk = std::nullopt,
312 std::optional<
unsigned int> preconditioner_max_block_size = std::nullopt)
315 interpolation_domain_type(batched_interpolation_domain),
317 preconditioner_max_block_size)
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337 template <
concepts::discrete_domain BatchedInterpolationDDom>
339 BatchedInterpolationDDom
const& batched_interpolation_domain,
340 std::optional<std::size_t> cols_per_chunk = std::nullopt,
341 std::optional<
unsigned int> preconditioner_max_block_size = std::nullopt)
344 interpolation_domain_type(batched_interpolation_domain),
346 preconditioner_max_block_size)
355
356
357
367
368
369
370
374
375
376
377
378
379
382 return m_interpolation_domain;
386
387
388
389
390
391
392
393
394
395 template <
concepts::discrete_domain BatchedInterpolationDDom>
397 BatchedInterpolationDDom
const& batched_interpolation_domain)
const noexcept
400 return batched_interpolation_domain;
404
405
406
407
408
409
410
411
412 template <
class BatchedInterpolationDDom>
413 batch_domain_type<BatchedInterpolationDDom>
batch_domain(
414 BatchedInterpolationDDom
const& batched_interpolation_domain)
const noexcept
421
422
423
424
425
426
429 return ddc::discrete_space<bsplines_type>().full_domain();
433
434
435
436
437
438
439
440
441 template <
class BatchedInterpolationDDom>
443 BatchedInterpolationDDom
const& batched_interpolation_domain)
const noexcept
446 return ddc::replace_dim_of<
447 interpolation_discrete_dimension_type,
453
454
455
456
457
458
459
460
461 template <
class BatchedInterpolationDDom>
462 batched_spline_tr_domain_type<BatchedInterpolationDDom> batched_spline_tr_domain(
463 BatchedInterpolationDDom
const& batched_interpolation_domain)
const noexcept
466 return batched_spline_tr_domain_type<BatchedInterpolationDDom>(
467 ddc::replace_dim_of<bsplines_type, bsplines_type>(
468 batched_spline_domain(batched_interpolation_domain),
470 ddc::DiscreteElement<bsplines_type>(0),
472 m_matrix->required_number_of_rhs_rows()))));
477
478
479
480
481
482
483
484
485 template <
class BatchedInterpolationDDom>
487 BatchedInterpolationDDom
const& batched_interpolation_domain)
const noexcept
490 return ddc::replace_dim_of<interpolation_discrete_dimension_type, deriv_type>(
491 batched_interpolation_domain,
493 ddc::DiscreteElement<deriv_type>(1),
498
499
500
501
502
503
504
505
506 template <
class BatchedInterpolationDDom>
508 BatchedInterpolationDDom
const& batched_interpolation_domain)
const noexcept
511 return ddc::replace_dim_of<interpolation_discrete_dimension_type, deriv_type>(
512 batched_interpolation_domain,
514 ddc::DiscreteElement<deriv_type>(1),
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537 template <
class Layout,
class BatchedInterpolationDDom>
541 batched_spline_domain_type<BatchedInterpolationDDom>,
543 memory_space> spline,
544 ddc::
ChunkSpan<Real
const, BatchedInterpolationDDom, Layout, memory_space> vals,
547 batched_derivs_domain_type<BatchedInterpolationDDom>,
549 memory_space>> derivs_xmin
553 batched_derivs_domain_type<BatchedInterpolationDDom>,
555 memory_space>> derivs_xmax
556 = std::nullopt)
const;
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581 template <
class OutMemorySpace = MemorySpace>
604 void allocate_matrix(
605 int lower_block_size,
606 int upper_block_size,
607 std::optional<std::size_t> cols_per_chunk = std::nullopt,
608 std::optional<
unsigned int> preconditioner_max_block_size = std::nullopt);
610 void build_matrix_system();
612 void check_valid_grid();
614 template <
class KnotElement>
615 static void check_n_points_in_cell(
int n_points_in_cell, KnotElement current_cell_end_idx);
622 class InterpolationDDim,
633 Solver>::compute_offset(interpolation_domain_type
const& interpolation_domain,
int& offset)
635 if constexpr (bsplines_type::is_periodic()) {
637 std::array<Real, bsplines_type::degree() + 1> values_ptr;
638 Kokkos::mdspan<Real, Kokkos::extents<std::size_t, bsplines_type::degree() + 1>>
const
639 values(values_ptr.data());
640 ddc::DiscreteElement<interpolation_discrete_dimension_type> start(
641 interpolation_domain.front());
642 auto jmin =
ddc::discrete_space<BSplines>()
643 .eval_basis(values,
ddc::coordinate(start + BSplines::degree()));
644 if constexpr (bsplines_type::degree() % 2 == 0) {
645 offset = jmin.uid() - start.uid() + bsplines_type::degree() / 2 - BSplines::degree();
647 int const mid = bsplines_type::degree() / 2;
648 offset = jmin.uid() - start.uid()
649 + (DDC_MDSPAN_ACCESS_OP(values, mid) > DDC_MDSPAN_ACCESS_OP(values, mid + 1)
652 - BSplines::degree();
663 class InterpolationDDim,
667int SplineBuilder<ExecSpace, MemorySpace, BSplines, InterpolationDDim, SBCLower, SBCUpper, Solver>::
671 return static_cast<
int>(bsplines_type::degree()) / 2;
680 return static_cast<
int>(bsplines_type::degree()) - 1;
683 throw std::runtime_error(
"ddc::SplineBuilderClosure not handled");
690 class InterpolationDDim,
694int SplineBuilder<ExecSpace, MemorySpace, BSplines, InterpolationDDim, SBCLower, SBCUpper, Solver>::
699 return static_cast<
int>(bsplines_type::degree()) - 1;
707 throw std::runtime_error(
"ddc::SplineBuilderClosure not handled");
714 class InterpolationDDim,
727 [[maybe_unused]]
int lower_block_size,
728 [[maybe_unused]]
int upper_block_size,
729 std::optional<std::size_t> cols_per_chunk,
730 std::optional<
unsigned int> preconditioner_max_block_size)
740 int upper_band_width;
741 if (bsplines_type::is_uniform()) {
742 upper_band_width = bsplines_type::degree() / 2;
744 upper_band_width = bsplines_type::degree() - 1;
746 if constexpr (bsplines_type::is_periodic()) {
747 m_matrix =
ddc::detail::SplinesLinearProblemMaker::make_new_periodic_band_matrix<
749 ddc::discrete_space<BSplines>().nbasis(),
752 bsplines_type::is_uniform());
754 m_matrix =
ddc::detail::SplinesLinearProblemMaker::
755 make_new_block_matrix_with_band_main_block<ExecSpace>(
756 ddc::discrete_space<BSplines>().nbasis(),
759 bsplines_type::is_uniform(),
764 m_matrix =
ddc::detail::SplinesLinearProblemMaker::make_new_sparse<ExecSpace>(
765 ddc::discrete_space<BSplines>().nbasis(),
767 preconditioner_max_block_size);
770 build_matrix_system();
772 m_matrix->setup_solver();
779 class InterpolationDDim,
790 Solver>::build_matrix_system()
796 std::array<Real, (bsplines_type::degree() / 2 + 1) * (bsplines_type::degree() + 1)>
798 Kokkos::mdspan<
double, Kokkos::dextents<std::size_t, 2>>
const
799 derivs(derivs_ptr.data(),
800 bsplines_type::degree() + 1,
801 bsplines_type::degree() / 2 + 1);
802 ddc::discrete_space<BSplines>().eval_basis_and_n_derivs(
804 ddc::discrete_space<BSplines>().rmin(),
809 for (std::size_t i = 0; i < bsplines_type::degree() + 1; ++i) {
810 for (std::size_t j = 1; j < bsplines_type::degree() / 2 + 1; ++j) {
811 DDC_MDSPAN_ACCESS_OP(derivs, i, j) *=
ddc::detail::ipow(m_dx, j);
817 for (std::size_t i = 0; i <
s_nbe_xmin; ++i) {
818 for (std::size_t j = 0; j < bsplines_type::degree(); ++j) {
819 m_matrix->set_element(i, j, DDC_MDSPAN_ACCESS_OP(derivs, j, i + s_odd));
826 std::array<Real, bsplines_type::degree() + 1> values_ptr;
827 Kokkos::mdspan<Real, Kokkos::extents<std::size_t, bsplines_type::degree() + 1>>
const values(
832 auto jmin =
ddc::discrete_space<BSplines>().eval_basis(
834 ddc::coordinate(
ddc::DiscreteElement<interpolation_discrete_dimension_type>(ix)));
835 for (std::size_t s = 0; s < bsplines_type::degree() + 1; ++s) {
836 int const j =
ddc::detail::
837 modulo(
int(jmin.uid() - m_offset + s),
838 static_cast<
int>(
ddc::discrete_space<BSplines>().nbasis()));
839 m_matrix->set_element(
842 DDC_MDSPAN_ACCESS_OP(values, s));
850 std::array<Real, (bsplines_type::degree() / 2 + 1) * (bsplines_type::degree() + 1)>
856 bsplines_type::degree() + 1,
857 bsplines_type::degree() / 2 + 1>>
const derivs(derivs_ptr.data());
859 ddc::discrete_space<BSplines>().eval_basis_and_n_derivs(
861 ddc::discrete_space<BSplines>().rmax(),
866 for (std::size_t i = 0; i < bsplines_type::degree() + 1; ++i) {
867 for (std::size_t j = 1; j < bsplines_type::degree() / 2 + 1; ++j) {
868 DDC_MDSPAN_ACCESS_OP(derivs, i, j) *=
ddc::detail::ipow(m_dx, j);
873 int const i0 =
ddc::discrete_space<BSplines>().nbasis() -
s_nbe_xmax;
874 int const j0 =
ddc::discrete_space<BSplines>().nbasis() - bsplines_type::degree();
875 for (std::size_t j = 0; j < bsplines_type::degree(); ++j) {
876 for (std::size_t i = 0; i <
s_nbe_xmax; ++i) {
877 m_matrix->set_element(
880 DDC_MDSPAN_ACCESS_OP(derivs, j + 1, i +
s_odd));
895template <
class Layout,
class BatchedInterpolationDDom>
907 batched_spline_domain_type<BatchedInterpolationDDom>,
909 memory_space> spline,
910 ddc::
ChunkSpan<Real
const, BatchedInterpolationDDom, Layout, memory_space> vals,
913 batched_derivs_domain_type<BatchedInterpolationDDom>,
915 memory_space>>
const derivs_xmin,
918 batched_derivs_domain_type<BatchedInterpolationDDom>,
920 memory_space>>
const derivs_xmax)
const
922 auto const batched_interpolation_domain = vals.domain();
925 assert(batch_domain_type<BatchedInterpolationDDom>(batched_interpolation_domain)
926 == batch_domain_type<BatchedInterpolationDDom>(spline.domain()));
928 if (batch_domain(batched_interpolation_domain).empty()) {
932 assert(vals.
template extent<interpolation_discrete_dimension_type>()
936 assert(
ddc::DiscreteElement<deriv_type>(derivs_xmin->domain().front()).uid() ==
s_odd);
937 assert(derivs_xmin.has_value() ||
s_nbe_xmin == 0);
939 assert(!derivs_xmin.has_value() || derivs_xmin->
template extent<deriv_type>() == 0);
942 assert(
ddc::DiscreteElement<deriv_type>(derivs_xmax->domain().front()).uid() ==
s_odd);
943 assert(derivs_xmax.has_value() ||
s_nbe_xmax == 0);
945 assert(!derivs_xmax.has_value() || derivs_xmax->
template extent<deriv_type>() == 0);
952 assert(derivs_xmin->
template extent<deriv_type>() ==
s_nbe_xmin);
953 auto derivs_xmin_values = *derivs_xmin;
954 auto const dx_proxy = m_dx;
955 auto const odd_proxy =
s_odd;
956 ddc::parallel_for_each(
957 "ddc_splines_hermite_compute_lower_coefficients",
959 batch_domain(batched_interpolation_domain),
961 batch_domain_type<BatchedInterpolationDDom>::discrete_element_type j) {
963 spline(
ddc::DiscreteElement<bsplines_type>(i), j)
964 = derivs_xmin_values(
965 ddc::DiscreteElement<deriv_type>(i + odd_proxy),
967 *
ddc::detail::ipow(dx_proxy, i + odd_proxy);
972 ddc::DiscreteElement<bsplines_type>(0),
974 batched_spline_domain_type<BatchedInterpolationDDom>
const
975 dx_spline_domain(dx_splines, batch_domain(batched_interpolation_domain));
976 ddc::parallel_fill(exec_space(), spline[dx_spline_domain], 0.0);
995 interpolation_discrete_dimension_type>())))]
996 .allocation_kokkos_view(),
997 vals.allocation_kokkos_view());
1004 auto const& nbasis_proxy =
ddc::discrete_space<bsplines_type>().nbasis();
1006 assert(derivs_xmax->
template extent<deriv_type>() ==
s_nbe_xmax);
1007 auto derivs_xmax_values = *derivs_xmax;
1008 auto const dx_proxy = m_dx;
1009 auto const odd_proxy =
s_odd;
1010 ddc::parallel_for_each(
1011 "ddc_splines_hermite_compute_upper_coefficients",
1013 batch_domain(batched_interpolation_domain),
1015 batch_domain_type<BatchedInterpolationDDom>::discrete_element_type j) {
1017 spline(
ddc::DiscreteElement<bsplines_type>(nbasis_proxy -
s_nbe_xmax + i),
1019 = derivs_xmax_values(
1020 ddc::DiscreteElement<deriv_type>(i + odd_proxy),
1022 *
ddc::detail::ipow(dx_proxy, i + odd_proxy);
1027 ddc::DiscreteElement<bsplines_type>(nbasis_proxy -
s_nbe_xmax),
1029 batched_spline_domain_type<BatchedInterpolationDDom>
const
1030 dx_spline_domain(dx_splines, batch_domain(batched_interpolation_domain));
1031 ddc::parallel_fill(exec_space(), spline[dx_spline_domain], 0.0);
1035 auto const& offset_proxy = m_offset;
1037 m_label +
" > spline_tr (ddc::SplineBuilder::operator())",
1038 batched_spline_tr_domain(batched_interpolation_domain),
1040 ddc::
ChunkSpan const spline_tr = spline_tr_alloc.span_view();
1041 ddc::parallel_for_each(
1042 m_label +
" > ddc_splines_transpose_rhs",
1044 batch_domain(batched_interpolation_domain),
1046 batch_domain_type<BatchedInterpolationDDom>::discrete_element_type
const j) {
1047 for (std::size_t i = 0; i < nbasis_proxy; ++i) {
1048 spline_tr(
ddc::DiscreteElement<bsplines_type>(i), j)
1049 = spline(
ddc::DiscreteElement<bsplines_type>(i + offset_proxy), j);
1053 Kokkos::View<Real**, Kokkos::LayoutRight, exec_space>
const bcoef_section(
1054 spline_tr.data_handle(),
1055 static_cast<std::size_t>(spline_tr.
template extent<bsplines_type>()),
1056 batch_domain(batched_interpolation_domain).size());
1058 m_matrix->solve(bcoef_section,
false);
1060 ddc::parallel_for_each(
1061 m_label +
" > ddc_splines_transpose_back_rhs",
1063 batch_domain(batched_interpolation_domain),
1065 batch_domain_type<BatchedInterpolationDDom>::discrete_element_type
const j) {
1066 for (std::size_t i = 0; i < nbasis_proxy; ++i) {
1067 spline(
ddc::DiscreteElement<bsplines_type>(i + offset_proxy), j)
1068 = spline_tr(
ddc::DiscreteElement<bsplines_type>(i), j);
1073 if (bsplines_type::is_periodic()) {
1074 ddc::parallel_for_each(
1075 m_label +
" > ddc_splines_periodic_rows_duplicate_rhs",
1077 batch_domain(batched_interpolation_domain),
1079 batch_domain_type<BatchedInterpolationDDom>::discrete_element_type
const
1081 if (offset_proxy != 0) {
1082 for (
int i = 0; i < offset_proxy; ++i) {
1083 spline(
ddc::DiscreteElement<bsplines_type>(i), j) = spline(
1084 ddc::DiscreteElement<bsplines_type>(nbasis_proxy + i),
1087 for (std::size_t i = offset_proxy; i < bsplines_type::degree(); ++i) {
1088 spline(
ddc::DiscreteElement<bsplines_type>(nbasis_proxy + i), j)
1089 = spline(
ddc::DiscreteElement<bsplines_type>(i), j);
1092 for (std::size_t i(0); i < bsplines_type::degree(); ++i) {
1093 ddc::DiscreteElement<bsplines_type>
const i_start(i);
1094 ddc::DiscreteElement<bsplines_type>
const i_end(nbasis_proxy + i);
1096 spline(i_end, j) = spline(i_start, j);
1110template <
class OutMemorySpace>
1126SplineBuilder<ExecSpace, MemorySpace, BSplines, InterpolationDDim, SBCLower, SBCUpper, Solver>::
1131 ddc::integrals(ExecSpace(), integral_bsplines.span_view());
1134 ddc::
ChunkSpan const integral_bsplines_without_periodic_additional_bsplines
1139 Kokkos::View<Real**, Kokkos::LayoutRight, MemorySpace>
const
1140 integral_bsplines_mirror_with_additional_allocation(
1141 m_label +
" > integral_bsplines_mirror_with_additional_allocation",
1142 m_matrix->required_number_of_rhs_rows(),
1146 Kokkos::View<Real*, Kokkos::LayoutRight, MemorySpace>
const integral_bsplines_mirror = Kokkos::
1147 subview(integral_bsplines_mirror_with_additional_allocation,
1149 pair {
static_cast<std::size_t>(0),
1150 integral_bsplines_without_periodic_additional_bsplines.size()},
1155 integral_bsplines_mirror,
1156 integral_bsplines_without_periodic_additional_bsplines.allocation_kokkos_view());
1157 m_matrix->solve(integral_bsplines_mirror_with_additional_allocation,
true);
1159 integral_bsplines_without_periodic_additional_bsplines.allocation_kokkos_view(),
1160 integral_bsplines_mirror);
1164 = integral_bsplines_without_periodic_additional_bsplines[
spline_domain().take_first(
1166 ddc::
ChunkSpan const coefficients = integral_bsplines_without_periodic_additional_bsplines
1174 = integral_bsplines_without_periodic_additional_bsplines
1182 auto const dx_proxy = m_dx;
1183 auto const odd_proxy =
s_odd;
1184 ddc::parallel_for_each(
1186 coefficients_derivs_xmin.domain(),
1187 KOKKOS_LAMBDA(
ddc::DiscreteElement<bsplines_type> i) {
1188 coefficients_derivs_xmin(i) *=
ddc::detail::
1190 static_cast<std::size_t>(get<bsplines_type>(
1191 (i - coefficients_derivs_xmin.domain().front()) + odd_proxy)));
1193 ddc::parallel_for_each(
1195 coefficients_derivs_xmax.domain(),
1196 KOKKOS_LAMBDA(
ddc::DiscreteElement<bsplines_type> i) {
1197 coefficients_derivs_xmax(i) *=
ddc::detail::
1199 static_cast<std::size_t>(get<bsplines_type>(
1200 (i - coefficients_derivs_xmax.domain().front()) + odd_proxy)));
1203 ddc::DiscreteElement<deriv_type>
const first_deriv(
s_odd);
1205 ddc::
Chunk coefficients_derivs_xmin_out(
1212 coefficients.size())),
1214 ddc::
Chunk coefficients_derivs_xmax_out(
1219 coefficients_derivs_xmin_out.allocation_kokkos_view(),
1220 coefficients_derivs_xmin.allocation_kokkos_view());
1222 coefficients_out.allocation_kokkos_view(),
1223 coefficients.allocation_kokkos_view());
1225 coefficients_derivs_xmax_out.allocation_kokkos_view(),
1226 coefficients_derivs_xmax.allocation_kokkos_view());
1227 return std::make_tuple(
1228 std::move(coefficients_derivs_xmin_out),
1229 std::move(coefficients_out),
1230 std::move(coefficients_derivs_xmax_out));
1241template <
class KnotElement>
1250 check_n_points_in_cell(
int const n_points_in_cell, KnotElement
const current_cell_end_idx)
1252 if (n_points_in_cell > BSplines::degree() + 1) {
1253 KnotElement
const rmin_idx =
ddc::discrete_space<BSplines>().break_point_domain().front();
1254 int const failed_cell = (current_cell_end_idx - rmin_idx).value();
1255 throw std::runtime_error(
1256 "The spline problem is overconstrained. There are "
1257 + std::to_string(n_points_in_cell) +
" points in the " + std::to_string(failed_cell)
1266 class InterpolationDDim,
1277 Solver>::check_valid_grid()
1280 std::size_t
const expected_npoints
1282 if (n_interp_points != expected_npoints) {
1283 throw std::runtime_error(
1284 "Incorrect number of points supplied to NonUniformInterpolationPoints. "
1286 + std::to_string(n_interp_points)
1287 +
", expected : " + std::to_string(expected_npoints));
1289 int n_points_in_cell = 0;
1290 auto current_cell_end_idx =
ddc::discrete_space<BSplines>().break_point_domain().front() + 1;
1292 ddc::Coordinate<continuous_dimension_type>
const point =
ddc::coordinate(idx);
1293 if (point >
ddc::coordinate(current_cell_end_idx)) {
1295 check_n_points_in_cell(n_points_in_cell, current_cell_end_idx);
1297 n_points_in_cell = 1;
1299 current_cell_end_idx += 1;
1300 }
else if (point ==
ddc::coordinate(current_cell_end_idx)) {
1302 check_n_points_in_cell(n_points_in_cell + 1, current_cell_end_idx);
1304 n_points_in_cell = 1;
1306 current_cell_end_idx += 1;
1309 n_points_in_cell += 1;
1313 check_n_points_in_cell(n_points_in_cell, current_cell_end_idx);
friend class DiscreteDomain
KOKKOS_FUNCTION constexpr bool operator!=(DiscreteVector< OTags... > const &rhs) const noexcept
A class which provides helper functions to initialise the Greville points from a B-Spline definition.
static ddc::DiscreteDomain< Sampling > get_domain()
Get the domain which gives us access to all of the Greville points.
Helper class for the initialisation of the mesh of interpolation points.
static auto get_sampling()
Get the sampling of interpolation points.
static ddc::DiscreteDomain< Sampling > get_domain()
Get the domain which can be used to access the interpolation points in the sampling.
A class for creating a spline approximation of a function.
std::tuple< ddc::Chunk< Real, ddc::DiscreteDomain< ddc::Deriv< typename InterpolationDDim::continuous_dimension_type > >, ddc::KokkosAllocator< Real, OutMemorySpace > >, ddc::Chunk< Real, ddc::DiscreteDomain< InterpolationDDim >, ddc::KokkosAllocator< Real, OutMemorySpace > >, ddc::Chunk< Real, ddc::DiscreteDomain< ddc::Deriv< typename InterpolationDDim::continuous_dimension_type > >, ddc::KokkosAllocator< Real, OutMemorySpace > > > quadrature_coefficients() const
Compute the quadrature coefficients associated to the b-splines used by this SplineBuilder.
ddc::DiscreteDomain< bsplines_type > spline_domain() const noexcept
Get the 1D domain on which spline coefficients are defined.
SplineBuilder(BatchedInterpolationDDom const &batched_interpolation_domain, std::optional< std::size_t > cols_per_chunk=std::nullopt, std::optional< unsigned int > preconditioner_max_block_size=std::nullopt)
Build a SplineBuilder acting on the interpolation domain contained by batched_interpolation_domain.
SplineBuilder(SplineBuilder const &x)=delete
Copy-constructor is deleted.
interpolation_domain_type interpolation_domain() const noexcept
Get the domain for the 1D interpolation mesh used by this class.
batched_derivs_domain_type< BatchedInterpolationDDom > batched_derivs_xmax_domain(BatchedInterpolationDDom const &batched_interpolation_domain) const noexcept
Get the whole domain on which derivatives on upper boundary are defined.
static constexpr int s_nbe_xmin
The number of equations defining the closure relation at the lower bound.
static constexpr ddc::SplineBuilderClosure s_sbc_xmin
The closure relation implemented at the lower bound.
SplineBuilder(std::string label, BatchedInterpolationDDom const &batched_interpolation_domain, std::optional< std::size_t > cols_per_chunk=std::nullopt, std::optional< unsigned int > preconditioner_max_block_size=std::nullopt)
Build a SplineBuilder acting on the interpolation domain contained by batched_interpolation_domain.
batch_domain_type< BatchedInterpolationDDom > batch_domain(BatchedInterpolationDDom const &batched_interpolation_domain) const noexcept
Get the batch domain.
SplineBuilder & operator=(SplineBuilder &&x)=default
Move-assigns.
static constexpr int s_nbe_xmax
The number of equations defining the closure relation at the upper bound.
static constexpr SplineSolver s_spline_solver
The SplineSolver giving the backend used to perform the spline approximation.
static constexpr ddc::SplineBuilderClosure s_sbc_xmax
The closure relation implemented at the upper bound.
BatchedInterpolationDDom batched_interpolation_domain(BatchedInterpolationDDom const &batched_interpolation_domain) const noexcept
Get the whole domain representing interpolation points.
batched_spline_domain_type< BatchedInterpolationDDom > batched_spline_domain(BatchedInterpolationDDom const &batched_interpolation_domain) const noexcept
Get the whole domain on which spline coefficients are defined.
SplineBuilder(interpolation_domain_type const &interpolation_domain, std::optional< std::size_t > cols_per_chunk=std::nullopt, std::optional< unsigned int > preconditioner_max_block_size=std::nullopt)
Build a SplineBuilder acting on interpolation_domain.
static constexpr bool s_odd
Indicates if the degree of the splines is odd or even.
void operator()(ddc::ChunkSpan< Real, batched_spline_domain_type< BatchedInterpolationDDom >, Layout, memory_space > spline, ddc::ChunkSpan< Real const, BatchedInterpolationDDom, Layout, memory_space > vals, std::optional< ddc::ChunkSpan< Real const, batched_derivs_domain_type< BatchedInterpolationDDom >, Layout, memory_space > > derivs_xmin=std::nullopt, std::optional< ddc::ChunkSpan< Real const, batched_derivs_domain_type< BatchedInterpolationDDom >, Layout, memory_space > > derivs_xmax=std::nullopt) const
Compute a spline approximation of a function.
batched_derivs_domain_type< BatchedInterpolationDDom > batched_derivs_xmin_domain(BatchedInterpolationDDom const &batched_interpolation_domain) const noexcept
Get the whole domain on which derivatives on lower boundary are defined.
SplineBuilder(std::string label, interpolation_domain_type const &interpolation_domain, std::optional< std::size_t > cols_per_chunk=std::nullopt, std::optional< unsigned int > preconditioner_max_block_size=std::nullopt)
Build a SplineBuilder acting on interpolation_domain.
SplineBuilder(SplineBuilder &&x)=default
Move-constructs.
static constexpr int s_nbv_xmax
The number of input values defining the closure relation at the upper bound.
~SplineBuilder()=default
Destructs.
static constexpr int s_nbv_xmin
The number of input values defining the closure relation at the lower bound.
SplineBuilder & operator=(SplineBuilder const &x)=delete
Copy-assignment is deleted.
#define DDC_BUILD_DEPRECATED_CODE
The top-level namespace of DDC.
constexpr bool is_uniform_bsplines_v
Indicates if a tag corresponds to uniform B-splines or not.
SplineSolver
An enum determining the backend solver of a SplineBuilder or SplineBuilder2d.
@ LAPACK
Enum member to identify the LAPACK-based solver (direct method)
@ GINKGO
Enum member to identify the Ginkgo-based solver (iterative method)
constexpr int n_boundary_equations(ddc::SplineBuilderClosure const sbc, std::size_t const degree)
Return the number of equations needed to describe a given closure relation.
ddc::ChunkSpan< Real, ddc::DiscreteDomain< DDim >, Layout, MemorySpace > integrals(ExecSpace const &execution_space, ddc::ChunkSpan< Real, ddc::DiscreteDomain< DDim >, Layout, MemorySpace > int_vals)
Compute the integrals of the B-splines.
constexpr bool is_non_uniform_bsplines_v
Indicates if a tag corresponds to non-uniform B-splines or not.
SplineBuilderClosure
An enum representing a spline closure relation.
@ HOMOGENEOUS_HERMITE
Homogeneous Hermite closure relation (derivatives are 0)
@ GREVILLE
Use Greville points instead of conditions on derivative for B-Spline interpolation.
@ HERMITE
Hermite closure relation.
@ PERIODIC
Periodic closure relation u(1)=u(n)
A templated struct representing a discrete dimension storing the derivatives of a function along a co...
If the type DDim is a B-spline, defines type to the discrete dimension of the associated knots.