19#include <Kokkos_Core.hpp>
32
33
34
35
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
61 class InterpolationDDim,
75 using exec_space = ExecSpace;
78 using memory_space = MemorySpace;
81 using continuous_dimension_type = InterpolationDDim::continuous_dimension_type;
84 using interpolation_discrete_dimension_type = InterpolationDDim;
87 using bsplines_type = BSplines;
90 using deriv_type =
ddc::
Deriv<continuous_dimension_type>;
93 using interpolation_domain_type =
ddc::
DiscreteDomain<interpolation_discrete_dimension_type>;
96
97
98
99
100 template <concepts::discrete_domain BatchedInterpolationDDom>
101 using batched_interpolation_domain_type = BatchedInterpolationDDom;
104
105
106
107
108
109
110
111
112 template <concepts::discrete_domain BatchedInterpolationDDom>
113 using batch_domain_type =
ddc::
114 remove_dims_of_t<BatchedInterpolationDDom, interpolation_discrete_dimension_type>;
117
118
119
120
121
122
123
124
125 template <concepts::discrete_domain BatchedInterpolationDDom>
126 using batched_spline_domain_type =
ddc::replace_dim_of_t<
127 BatchedInterpolationDDom,
128 interpolation_discrete_dimension_type,
133
134
135
136
137
138
139
140
141 template <concepts::discrete_domain BatchedInterpolationDDom>
142 using batched_spline_tr_domain_type
143 =
ddc::detail::convert_type_seq_to_discrete_domain_t<
ddc::type_seq_merge_t<
144 ddc::detail::TypeSeq<bsplines_type>,
145 ddc::type_seq_remove_t<
146 ddc::to_type_seq_t<BatchedInterpolationDDom>,
147 ddc::detail::TypeSeq<interpolation_discrete_dimension_type>>>>;
151
152
153
154
155
156
157
158
159 template <concepts::discrete_domain BatchedInterpolationDDom>
160 using batched_derivs_domain_type =
ddc::replace_dim_of_t<
161 BatchedInterpolationDDom,
162 interpolation_discrete_dimension_type,
166 static constexpr bool s_odd = BSplines::degree() % 2;
169 static constexpr int s_nbe_xmin = n_boundary_equations(SBCLower, BSplines::degree());
172 static constexpr int s_nbe_xmax = n_boundary_equations(SBCUpper, BSplines::degree());
177 : n_boundary_equations(SBCLower, BSplines::degree());
182 : n_boundary_equations(SBCUpper, BSplines::degree());
206 interpolation_domain_type m_interpolation_domain;
213 std::unique_ptr<
ddc::detail::SplinesLinearProblem<exec_space>> m_matrix;
218 void compute_offset(interpolation_domain_type
const& interpolation_domain,
int& offset);
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
241 interpolation_domain_type
const& interpolation_domain,
242 std::optional<std::size_t> cols_per_chunk = std::nullopt,
243 std::optional<
unsigned int> preconditioner_max_block_size = std::nullopt)
244 : m_interpolation_domain(interpolation_domain)
245 , m_dx((
ddc::discrete_space<BSplines>().rmax() -
ddc::discrete_space<BSplines>().rmin())
246 /
ddc::discrete_space<BSplines>().ncells())
247 , m_label(std::move(label))
252 "Incompatible closure relations");
255 compute_offset(
this->interpolation_domain(), m_offset);
258 int lower_block_size;
259 int upper_block_size;
260 if constexpr (bsplines_type::is_uniform()) {
261 upper_block_size = compute_block_sizes_uniform(SBCLower,
s_nbe_xmin);
262 lower_block_size = compute_block_sizes_uniform(SBCUpper,
s_nbe_xmax);
264 upper_block_size = compute_block_sizes_non_uniform(SBCLower,
s_nbe_xmin);
265 lower_block_size = compute_block_sizes_non_uniform(SBCUpper,
s_nbe_xmax);
271 preconditioner_max_block_size);
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
291 interpolation_domain_type
const& interpolation_domain,
292 std::optional<std::size_t> cols_per_chunk = std::nullopt,
293 std::optional<
unsigned int> preconditioner_max_block_size = std::nullopt)
296 interpolation_domain,
298 preconditioner_max_block_size)
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320 template <
concepts::discrete_domain BatchedInterpolationDDom>
323 BatchedInterpolationDDom
const& batched_interpolation_domain,
324 std::optional<std::size_t> cols_per_chunk = std::nullopt,
325 std::optional<
unsigned int> preconditioner_max_block_size = std::nullopt)
328 interpolation_domain_type(batched_interpolation_domain),
330 preconditioner_max_block_size)
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350 template <
concepts::discrete_domain BatchedInterpolationDDom>
352 BatchedInterpolationDDom
const& batched_interpolation_domain,
353 std::optional<std::size_t> cols_per_chunk = std::nullopt,
354 std::optional<
unsigned int> preconditioner_max_block_size = std::nullopt)
357 interpolation_domain_type(batched_interpolation_domain),
359 preconditioner_max_block_size)
368
369
370
380
381
382
383
387
388
389
390
391
392
395 return m_interpolation_domain;
399
400
401
402
403
404
405
406
407
408 template <
concepts::discrete_domain BatchedInterpolationDDom>
410 BatchedInterpolationDDom
const& batched_interpolation_domain)
const noexcept
413 return batched_interpolation_domain;
417
418
419
420
421
422
423
424
425 template <
class BatchedInterpolationDDom>
426 batch_domain_type<BatchedInterpolationDDom>
batch_domain(
427 BatchedInterpolationDDom
const& batched_interpolation_domain)
const noexcept
434
435
436
437
438
439
442 return ddc::discrete_space<bsplines_type>().full_domain();
446
447
448
449
450
451
452
453
454 template <
class BatchedInterpolationDDom>
456 BatchedInterpolationDDom
const& batched_interpolation_domain)
const noexcept
459 return ddc::replace_dim_of<
460 interpolation_discrete_dimension_type,
466
467
468
469
470
471
472
473
474 template <
class BatchedInterpolationDDom>
475 batched_spline_tr_domain_type<BatchedInterpolationDDom> batched_spline_tr_domain(
476 BatchedInterpolationDDom
const& batched_interpolation_domain)
const noexcept
479 return batched_spline_tr_domain_type<BatchedInterpolationDDom>(
480 ddc::replace_dim_of<bsplines_type, bsplines_type>(
481 batched_spline_domain(batched_interpolation_domain),
483 ddc::DiscreteElement<bsplines_type>(0),
485 m_matrix->required_number_of_rhs_rows()))));
490
491
492
493
494
495
496
497
498 template <
class BatchedInterpolationDDom>
500 BatchedInterpolationDDom
const& batched_interpolation_domain)
const noexcept
503 return ddc::replace_dim_of<interpolation_discrete_dimension_type, deriv_type>(
504 batched_interpolation_domain,
506 ddc::DiscreteElement<deriv_type>(1),
511
512
513
514
515
516
517
518
519 template <
class BatchedInterpolationDDom>
521 BatchedInterpolationDDom
const& batched_interpolation_domain)
const noexcept
524 return ddc::replace_dim_of<interpolation_discrete_dimension_type, deriv_type>(
525 batched_interpolation_domain,
527 ddc::DiscreteElement<deriv_type>(1),
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550 template <
class Layout,
class BatchedInterpolationDDom>
554 batched_spline_domain_type<BatchedInterpolationDDom>,
556 memory_space> spline,
557 ddc::
ChunkSpan<
double const, BatchedInterpolationDDom, Layout, memory_space> vals,
560 batched_derivs_domain_type<BatchedInterpolationDDom>,
562 memory_space>> derivs_xmin
566 batched_derivs_domain_type<BatchedInterpolationDDom>,
568 memory_space>> derivs_xmax
569 = std::nullopt)
const;
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594 template <
class OutMemorySpace = MemorySpace>
617 void allocate_matrix(
618 int lower_block_size,
619 int upper_block_size,
620 std::optional<std::size_t> cols_per_chunk = std::nullopt,
621 std::optional<
unsigned int> preconditioner_max_block_size = std::nullopt);
623 void build_matrix_system();
625 void check_valid_grid();
627 template <
class KnotElement>
628 static void check_n_points_in_cell(
int n_points_in_cell, KnotElement current_cell_end_idx);
635 class InterpolationDDim,
646 Solver>::compute_offset(interpolation_domain_type
const& interpolation_domain,
int& offset)
648 if constexpr (bsplines_type::is_periodic()) {
650 std::array<
double, bsplines_type::degree() + 1> values_ptr;
651 Kokkos::mdspan<
double, Kokkos::extents<std::size_t, bsplines_type::degree() + 1>>
const
652 values(values_ptr.data());
653 ddc::DiscreteElement<interpolation_discrete_dimension_type> start(
654 interpolation_domain.front());
655 auto jmin =
ddc::discrete_space<BSplines>()
656 .eval_basis(values,
ddc::coordinate(start + BSplines::degree()));
657 if constexpr (bsplines_type::degree() % 2 == 0) {
658 offset = jmin.uid() - start.uid() + bsplines_type::degree() / 2 - BSplines::degree();
660 int const mid = bsplines_type::degree() / 2;
661 offset = jmin.uid() - start.uid()
662 + (DDC_MDSPAN_ACCESS_OP(values, mid) > DDC_MDSPAN_ACCESS_OP(values, mid + 1)
665 - BSplines::degree();
676 class InterpolationDDim,
680int SplineBuilder<ExecSpace, MemorySpace, BSplines, InterpolationDDim, SBCLower, SBCUpper, Solver>::
684 return static_cast<
int>(bsplines_type::degree()) / 2;
693 return static_cast<
int>(bsplines_type::degree()) - 1;
696 throw std::runtime_error(
"ddc::SplineBuilderClosure not handled");
703 class InterpolationDDim,
707int SplineBuilder<ExecSpace, MemorySpace, BSplines, InterpolationDDim, SBCLower, SBCUpper, Solver>::
712 return static_cast<
int>(bsplines_type::degree()) - 1;
720 throw std::runtime_error(
"ddc::SplineBuilderClosure not handled");
727 class InterpolationDDim,
740 [[maybe_unused]]
int lower_block_size,
741 [[maybe_unused]]
int upper_block_size,
742 std::optional<std::size_t> cols_per_chunk,
743 std::optional<
unsigned int> preconditioner_max_block_size)
753 int upper_band_width;
754 if (bsplines_type::is_uniform()) {
755 upper_band_width = bsplines_type::degree() / 2;
757 upper_band_width = bsplines_type::degree() - 1;
759 if constexpr (bsplines_type::is_periodic()) {
760 m_matrix =
ddc::detail::SplinesLinearProblemMaker::make_new_periodic_band_matrix<
762 ddc::discrete_space<BSplines>().nbasis(),
765 bsplines_type::is_uniform());
767 m_matrix =
ddc::detail::SplinesLinearProblemMaker::
768 make_new_block_matrix_with_band_main_block<ExecSpace>(
769 ddc::discrete_space<BSplines>().nbasis(),
772 bsplines_type::is_uniform(),
777 m_matrix =
ddc::detail::SplinesLinearProblemMaker::make_new_sparse<ExecSpace>(
778 ddc::discrete_space<BSplines>().nbasis(),
780 preconditioner_max_block_size);
783 build_matrix_system();
785 m_matrix->setup_solver();
792 class InterpolationDDim,
803 Solver>::build_matrix_system()
809 std::array<
double, (bsplines_type::degree() / 2 + 1) * (bsplines_type::degree() + 1)>
812 derivs(derivs_ptr.data(),
813 bsplines_type::degree() + 1,
814 bsplines_type::degree() / 2 + 1);
815 ddc::discrete_space<BSplines>().eval_basis_and_n_derivs(
817 ddc::discrete_space<BSplines>().rmin(),
822 for (std::size_t i = 0; i < bsplines_type::degree() + 1; ++i) {
823 for (std::size_t j = 1; j < bsplines_type::degree() / 2 + 1; ++j) {
824 DDC_MDSPAN_ACCESS_OP(derivs, i, j) *=
ddc::detail::ipow(m_dx, j);
830 for (std::size_t i = 0; i <
s_nbe_xmin; ++i) {
831 for (std::size_t j = 0; j < bsplines_type::degree(); ++j) {
832 m_matrix->set_element(i, j, DDC_MDSPAN_ACCESS_OP(derivs, j, i + s_odd));
839 std::array<
double, bsplines_type::degree() + 1> values_ptr;
840 Kokkos::mdspan<
double, Kokkos::extents<std::size_t, bsplines_type::degree() + 1>>
const values(
845 auto jmin =
ddc::discrete_space<BSplines>().eval_basis(
847 ddc::coordinate(
ddc::DiscreteElement<interpolation_discrete_dimension_type>(ix)));
848 for (std::size_t s = 0; s < bsplines_type::degree() + 1; ++s) {
849 int const j =
ddc::detail::
850 modulo(
int(jmin.uid() - m_offset + s),
851 static_cast<
int>(
ddc::discrete_space<BSplines>().nbasis()));
852 m_matrix->set_element(
855 DDC_MDSPAN_ACCESS_OP(values, s));
863 std::array<
double, (bsplines_type::degree() / 2 + 1) * (bsplines_type::degree() + 1)>
869 bsplines_type::degree() + 1,
870 bsplines_type::degree() / 2 + 1>>
const derivs(derivs_ptr.data());
872 ddc::discrete_space<BSplines>().eval_basis_and_n_derivs(
874 ddc::discrete_space<BSplines>().rmax(),
879 for (std::size_t i = 0; i < bsplines_type::degree() + 1; ++i) {
880 for (std::size_t j = 1; j < bsplines_type::degree() / 2 + 1; ++j) {
881 DDC_MDSPAN_ACCESS_OP(derivs, i, j) *=
ddc::detail::ipow(m_dx, j);
886 int const i0 =
ddc::discrete_space<BSplines>().nbasis() -
s_nbe_xmax;
887 int const j0 =
ddc::discrete_space<BSplines>().nbasis() - bsplines_type::degree();
888 for (std::size_t j = 0; j < bsplines_type::degree(); ++j) {
889 for (std::size_t i = 0; i <
s_nbe_xmax; ++i) {
890 m_matrix->set_element(
893 DDC_MDSPAN_ACCESS_OP(derivs, j + 1, i +
s_odd));
908template <
class Layout,
class BatchedInterpolationDDom>
920 batched_spline_domain_type<BatchedInterpolationDDom>,
922 memory_space> spline,
923 ddc::
ChunkSpan<
double const, BatchedInterpolationDDom, Layout, memory_space> vals,
926 batched_derivs_domain_type<BatchedInterpolationDDom>,
928 memory_space>>
const derivs_xmin,
931 batched_derivs_domain_type<BatchedInterpolationDDom>,
933 memory_space>>
const derivs_xmax)
const
935 auto const batched_interpolation_domain = vals.domain();
938 assert(batch_domain_type<BatchedInterpolationDDom>(batched_interpolation_domain)
939 == batch_domain_type<BatchedInterpolationDDom>(spline.domain()));
941 if (batch_domain(batched_interpolation_domain).empty()) {
945 assert(vals.
template extent<interpolation_discrete_dimension_type>()
949 assert(
ddc::DiscreteElement<deriv_type>(derivs_xmin->domain().front()).uid() ==
s_odd);
950 assert(derivs_xmin.has_value() ||
s_nbe_xmin == 0);
952 assert(!derivs_xmin.has_value() || derivs_xmin->
template extent<deriv_type>() == 0);
955 assert(
ddc::DiscreteElement<deriv_type>(derivs_xmax->domain().front()).uid() ==
s_odd);
956 assert(derivs_xmax.has_value() ||
s_nbe_xmax == 0);
958 assert(!derivs_xmax.has_value() || derivs_xmax->
template extent<deriv_type>() == 0);
965 assert(derivs_xmin->
template extent<deriv_type>() ==
s_nbe_xmin);
966 auto derivs_xmin_values = *derivs_xmin;
967 auto const dx_proxy = m_dx;
968 auto const odd_proxy =
s_odd;
969 ddc::parallel_for_each(
970 "ddc_splines_hermite_compute_lower_coefficients",
972 batch_domain(batched_interpolation_domain),
974 batch_domain_type<BatchedInterpolationDDom>::discrete_element_type j) {
976 spline(
ddc::DiscreteElement<bsplines_type>(i), j)
977 = derivs_xmin_values(
978 ddc::DiscreteElement<deriv_type>(i + odd_proxy),
980 *
ddc::detail::ipow(dx_proxy, i + odd_proxy);
985 ddc::DiscreteElement<bsplines_type>(0),
987 batched_spline_domain_type<BatchedInterpolationDDom>
const
988 dx_spline_domain(dx_splines, batch_domain(batched_interpolation_domain));
989 ddc::parallel_fill(exec_space(), spline[dx_spline_domain], 0.0);
1008 interpolation_discrete_dimension_type>())))]
1009 .allocation_kokkos_view(),
1010 vals.allocation_kokkos_view());
1017 auto const& nbasis_proxy =
ddc::discrete_space<bsplines_type>().nbasis();
1019 assert(derivs_xmax->
template extent<deriv_type>() ==
s_nbe_xmax);
1020 auto derivs_xmax_values = *derivs_xmax;
1021 auto const dx_proxy = m_dx;
1022 auto const odd_proxy =
s_odd;
1023 ddc::parallel_for_each(
1024 "ddc_splines_hermite_compute_upper_coefficients",
1026 batch_domain(batched_interpolation_domain),
1028 batch_domain_type<BatchedInterpolationDDom>::discrete_element_type j) {
1030 spline(
ddc::DiscreteElement<bsplines_type>(nbasis_proxy -
s_nbe_xmax + i),
1032 = derivs_xmax_values(
1033 ddc::DiscreteElement<deriv_type>(i + odd_proxy),
1035 *
ddc::detail::ipow(dx_proxy, i + odd_proxy);
1040 ddc::DiscreteElement<bsplines_type>(nbasis_proxy -
s_nbe_xmax),
1042 batched_spline_domain_type<BatchedInterpolationDDom>
const
1043 dx_spline_domain(dx_splines, batch_domain(batched_interpolation_domain));
1044 ddc::parallel_fill(exec_space(), spline[dx_spline_domain], 0.0);
1048 auto const& offset_proxy = m_offset;
1050 m_label +
" > spline_tr (ddc::SplineBuilder::operator())",
1051 batched_spline_tr_domain(batched_interpolation_domain),
1053 ddc::
ChunkSpan const spline_tr = spline_tr_alloc.span_view();
1054 ddc::parallel_for_each(
1055 m_label +
" > ddc_splines_transpose_rhs",
1057 batch_domain(batched_interpolation_domain),
1059 batch_domain_type<BatchedInterpolationDDom>::discrete_element_type
const j) {
1060 for (std::size_t i = 0; i < nbasis_proxy; ++i) {
1061 spline_tr(
ddc::DiscreteElement<bsplines_type>(i), j)
1062 = spline(
ddc::DiscreteElement<bsplines_type>(i + offset_proxy), j);
1066 Kokkos::View<
double**, Kokkos::LayoutRight, exec_space>
const bcoef_section(
1067 spline_tr.data_handle(),
1068 static_cast<std::size_t>(spline_tr.
template extent<bsplines_type>()),
1069 batch_domain(batched_interpolation_domain).size());
1071 m_matrix->solve(bcoef_section,
false);
1073 ddc::parallel_for_each(
1074 m_label +
" > ddc_splines_transpose_back_rhs",
1076 batch_domain(batched_interpolation_domain),
1078 batch_domain_type<BatchedInterpolationDDom>::discrete_element_type
const j) {
1079 for (std::size_t i = 0; i < nbasis_proxy; ++i) {
1080 spline(
ddc::DiscreteElement<bsplines_type>(i + offset_proxy), j)
1081 = spline_tr(
ddc::DiscreteElement<bsplines_type>(i), j);
1086 if (bsplines_type::is_periodic()) {
1087 ddc::parallel_for_each(
1088 m_label +
" > ddc_splines_periodic_rows_duplicate_rhs",
1090 batch_domain(batched_interpolation_domain),
1092 batch_domain_type<BatchedInterpolationDDom>::discrete_element_type
const
1094 if (offset_proxy != 0) {
1095 for (
int i = 0; i < offset_proxy; ++i) {
1096 spline(
ddc::DiscreteElement<bsplines_type>(i), j) = spline(
1097 ddc::DiscreteElement<bsplines_type>(nbasis_proxy + i),
1100 for (std::size_t i = offset_proxy; i < bsplines_type::degree(); ++i) {
1101 spline(
ddc::DiscreteElement<bsplines_type>(nbasis_proxy + i), j)
1102 = spline(
ddc::DiscreteElement<bsplines_type>(i), j);
1105 for (std::size_t i(0); i < bsplines_type::degree(); ++i) {
1106 ddc::DiscreteElement<bsplines_type>
const i_start(i);
1107 ddc::DiscreteElement<bsplines_type>
const i_end(nbasis_proxy + i);
1109 spline(i_end, j) = spline(i_start, j);
1123template <
class OutMemorySpace>
1139SplineBuilder<ExecSpace, MemorySpace, BSplines, InterpolationDDim, SBCLower, SBCUpper, Solver>::
1144 ddc::integrals(ExecSpace(), integral_bsplines.span_view());
1147 ddc::
ChunkSpan const integral_bsplines_without_periodic_additional_bsplines
1152 Kokkos::View<
double**, Kokkos::LayoutRight, MemorySpace>
const
1153 integral_bsplines_mirror_with_additional_allocation(
1154 m_label +
" > integral_bsplines_mirror_with_additional_allocation",
1155 m_matrix->required_number_of_rhs_rows(),
1159 Kokkos::View<
double*, Kokkos::LayoutRight, MemorySpace>
const integral_bsplines_mirror
1161 subview(integral_bsplines_mirror_with_additional_allocation,
1163 pair {
static_cast<std::size_t>(0),
1164 integral_bsplines_without_periodic_additional_bsplines
1170 integral_bsplines_mirror,
1171 integral_bsplines_without_periodic_additional_bsplines.allocation_kokkos_view());
1172 m_matrix->solve(integral_bsplines_mirror_with_additional_allocation,
true);
1174 integral_bsplines_without_periodic_additional_bsplines.allocation_kokkos_view(),
1175 integral_bsplines_mirror);
1179 = integral_bsplines_without_periodic_additional_bsplines[
spline_domain().take_first(
1181 ddc::
ChunkSpan const coefficients = integral_bsplines_without_periodic_additional_bsplines
1189 = integral_bsplines_without_periodic_additional_bsplines
1197 auto const dx_proxy = m_dx;
1198 auto const odd_proxy =
s_odd;
1199 ddc::parallel_for_each(
1201 coefficients_derivs_xmin.domain(),
1202 KOKKOS_LAMBDA(
ddc::DiscreteElement<bsplines_type> i) {
1203 coefficients_derivs_xmin(i) *=
ddc::detail::
1205 static_cast<std::size_t>(get<bsplines_type>(
1206 (i - coefficients_derivs_xmin.domain().front()) + odd_proxy)));
1208 ddc::parallel_for_each(
1210 coefficients_derivs_xmax.domain(),
1211 KOKKOS_LAMBDA(
ddc::DiscreteElement<bsplines_type> i) {
1212 coefficients_derivs_xmax(i) *=
ddc::detail::
1214 static_cast<std::size_t>(get<bsplines_type>(
1215 (i - coefficients_derivs_xmax.domain().front()) + odd_proxy)));
1218 ddc::DiscreteElement<deriv_type>
const first_deriv(
s_odd);
1220 ddc::
Chunk coefficients_derivs_xmin_out(
1227 coefficients.size())),
1229 ddc::
Chunk coefficients_derivs_xmax_out(
1234 coefficients_derivs_xmin_out.allocation_kokkos_view(),
1235 coefficients_derivs_xmin.allocation_kokkos_view());
1237 coefficients_out.allocation_kokkos_view(),
1238 coefficients.allocation_kokkos_view());
1240 coefficients_derivs_xmax_out.allocation_kokkos_view(),
1241 coefficients_derivs_xmax.allocation_kokkos_view());
1242 return std::make_tuple(
1243 std::move(coefficients_derivs_xmin_out),
1244 std::move(coefficients_out),
1245 std::move(coefficients_derivs_xmax_out));
1256template <
class KnotElement>
1265 check_n_points_in_cell(
int const n_points_in_cell, KnotElement
const current_cell_end_idx)
1267 if (n_points_in_cell > BSplines::degree() + 1) {
1268 KnotElement
const rmin_idx =
ddc::discrete_space<BSplines>().break_point_domain().front();
1269 int const failed_cell = (current_cell_end_idx - rmin_idx).value();
1270 throw std::runtime_error(
1271 "The spline problem is overconstrained. There are "
1272 + std::to_string(n_points_in_cell) +
" points in the " + std::to_string(failed_cell)
1281 class InterpolationDDim,
1292 Solver>::check_valid_grid()
1295 std::size_t
const expected_npoints
1297 if (n_interp_points != expected_npoints) {
1298 throw std::runtime_error(
1299 "Incorrect number of points supplied to NonUniformInterpolationPoints. "
1301 + std::to_string(n_interp_points)
1302 +
", expected : " + std::to_string(expected_npoints));
1304 int n_points_in_cell = 0;
1305 auto current_cell_end_idx =
ddc::discrete_space<BSplines>().break_point_domain().front() + 1;
1307 ddc::Coordinate<continuous_dimension_type>
const point =
ddc::coordinate(idx);
1308 if (point >
ddc::coordinate(current_cell_end_idx)) {
1310 check_n_points_in_cell(n_points_in_cell, current_cell_end_idx);
1312 n_points_in_cell = 1;
1314 current_cell_end_idx += 1;
1315 }
else if (point ==
ddc::coordinate(current_cell_end_idx)) {
1317 check_n_points_in_cell(n_points_in_cell + 1, current_cell_end_idx);
1319 n_points_in_cell = 1;
1321 current_cell_end_idx += 1;
1324 n_points_in_cell += 1;
1328 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.
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.
std::tuple< ddc::Chunk< double, ddc::DiscreteDomain< ddc::Deriv< typename InterpolationDDim::continuous_dimension_type > >, ddc::KokkosAllocator< double, OutMemorySpace > >, ddc::Chunk< double, ddc::DiscreteDomain< InterpolationDDim >, ddc::KokkosAllocator< double, OutMemorySpace > >, ddc::Chunk< double, ddc::DiscreteDomain< ddc::Deriv< typename InterpolationDDim::continuous_dimension_type > >, ddc::KokkosAllocator< double, OutMemorySpace > > > quadrature_coefficients() const
Compute the quadrature coefficients associated to the b-splines used by this SplineBuilder.
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.
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.
void operator()(ddc::ChunkSpan< double, batched_spline_domain_type< BatchedInterpolationDDom >, Layout, memory_space > spline, ddc::ChunkSpan< double const, BatchedInterpolationDDom, Layout, memory_space > vals, std::optional< ddc::ChunkSpan< double const, batched_derivs_domain_type< BatchedInterpolationDDom >, Layout, memory_space > > derivs_xmin=std::nullopt, std::optional< ddc::ChunkSpan< double const, batched_derivs_domain_type< BatchedInterpolationDDom >, Layout, memory_space > > derivs_xmax=std::nullopt) const
Compute a spline approximation of a function.
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.
ddc::ChunkSpan< double, ddc::DiscreteDomain< DDim >, Layout, MemorySpace > integrals(ExecSpace const &execution_space, ddc::ChunkSpan< double, ddc::DiscreteDomain< DDim >, Layout, MemorySpace > int_vals)
Compute the integrals of the B-splines.
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.
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.