18#include <Kokkos_Core.hpp>
21#include "integrals.hpp"
22#include "math_tools.hpp"
23#include "spline_boundary_conditions.hpp"
24#include "splines_linear_problem_maker.hpp"
29
30
31
32
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
58 class InterpolationDDim,
72 using exec_space = ExecSpace;
75 using memory_space = MemorySpace;
78 using continuous_dimension_type =
typename InterpolationDDim::continuous_dimension_type;
81 using interpolation_discrete_dimension_type = InterpolationDDim;
84 using bsplines_type = BSplines;
87 using deriv_type =
ddc::
Deriv<continuous_dimension_type>;
90 using interpolation_domain_type =
ddc::
DiscreteDomain<interpolation_discrete_dimension_type>;
93
94
95
96
98 class BatchedInterpolationDDom,
99 class = std::enable_if_t<
ddc::is_discrete_domain_v<BatchedInterpolationDDom>>>
100 using batched_interpolation_domain_type = BatchedInterpolationDDom;
103
104
105
106
107
108
109
110
112 class BatchedInterpolationDDom,
113 class = std::enable_if_t<
ddc::is_discrete_domain_v<BatchedInterpolationDDom>>>
114 using batch_domain_type =
ddc::
115 remove_dims_of_t<BatchedInterpolationDDom, interpolation_discrete_dimension_type>;
118
119
120
121
122
123
124
125
127 class BatchedInterpolationDDom,
128 class = std::enable_if_t<
ddc::is_discrete_domain_v<BatchedInterpolationDDom>>>
129 using batched_spline_domain_type =
ddc::replace_dim_of_t<
130 BatchedInterpolationDDom,
131 interpolation_discrete_dimension_type,
136
137
138
139
140
141
142
143
145 class BatchedInterpolationDDom,
146 class = std::enable_if_t<
ddc::is_discrete_domain_v<BatchedInterpolationDDom>>>
147 using batched_spline_tr_domain_type =
148 typename ddc::detail::convert_type_seq_to_discrete_domain_t<
ddc::type_seq_merge_t<
149 ddc::detail::TypeSeq<bsplines_type>,
150 ddc::type_seq_remove_t<
151 ddc::to_type_seq_t<BatchedInterpolationDDom>,
152 ddc::detail::TypeSeq<interpolation_discrete_dimension_type>>>>;
156
157
158
159
160
161
162
163
165 class BatchedInterpolationDDom,
166 class = std::enable_if_t<
ddc::is_discrete_domain_v<BatchedInterpolationDDom>>>
167 using batched_derivs_domain_type =
ddc::replace_dim_of_t<
168 BatchedInterpolationDDom,
169 interpolation_discrete_dimension_type,
173 static constexpr bool s_odd = BSplines::degree() % 2;
176 static constexpr int s_nbc_xmin = n_boundary_equations(BcLower, BSplines::degree());
179 static constexpr int s_nbc_xmax = n_boundary_equations(BcUpper, BSplines::degree());
191 interpolation_domain_type m_interpolation_domain;
198 std::unique_ptr<
ddc::detail::SplinesLinearProblem<exec_space>> matrix;
201 void compute_offset(interpolation_domain_type
const& interpolation_domain,
int& offset);
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
221 interpolation_domain_type
const& interpolation_domain,
222 std::optional<std::size_t> cols_per_chunk = std::nullopt,
223 std::optional<
unsigned int> preconditioner_max_block_size = std::nullopt)
224 : m_interpolation_domain(interpolation_domain)
225 , m_dx((
ddc::discrete_space<BSplines>().rmax() -
ddc::discrete_space<BSplines>().rmin())
226 /
ddc::discrete_space<BSplines>().ncells())
230 "Incompatible boundary conditions");
233 compute_offset(
this->interpolation_domain(), m_offset);
236 int lower_block_size;
237 int upper_block_size;
238 if constexpr (bsplines_type::is_uniform()) {
239 upper_block_size = compute_block_sizes_uniform(BcLower,
s_nbc_xmin);
240 lower_block_size = compute_block_sizes_uniform(BcUpper,
s_nbc_xmax);
242 upper_block_size = compute_block_sizes_non_uniform(BcLower,
s_nbc_xmin);
243 lower_block_size = compute_block_sizes_non_uniform(BcUpper,
s_nbc_xmax);
249 preconditioner_max_block_size);
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
269 class BatchedInterpolationDDom,
270 class = std::enable_if_t<
ddc::is_discrete_domain_v<BatchedInterpolationDDom>>>
272 BatchedInterpolationDDom
const& batched_interpolation_domain,
273 std::optional<std::size_t> cols_per_chunk = std::nullopt,
274 std::optional<
unsigned int> preconditioner_max_block_size = std::nullopt)
276 interpolation_domain_type(batched_interpolation_domain),
278 preconditioner_max_block_size)
287
288
289
299
300
301
302
306
307
308
309
310
311
314 return m_interpolation_domain;
318
319
320
321
322
323
324
325
326
328 class BatchedInterpolationDDom,
329 class = std::enable_if_t<
ddc::is_discrete_domain_v<BatchedInterpolationDDom>>>
331 BatchedInterpolationDDom
const& batched_interpolation_domain)
const noexcept
333 assert(interpolation_domain() == interpolation_domain_type(batched_interpolation_domain));
334 return batched_interpolation_domain;
338
339
340
341
342
343
344
345
346 template <
class BatchedInterpolationDDom>
347 batch_domain_type<BatchedInterpolationDDom>
batch_domain(
348 BatchedInterpolationDDom
const& batched_interpolation_domain)
const noexcept
350 assert(interpolation_domain() == interpolation_domain_type(batched_interpolation_domain));
355
356
357
358
359
360
363 return ddc::discrete_space<bsplines_type>().full_domain();
367
368
369
370
371
372
373
374
375 template <
class BatchedInterpolationDDom>
377 BatchedInterpolationDDom
const& batched_interpolation_domain)
const noexcept
379 assert(interpolation_domain() == interpolation_domain_type(batched_interpolation_domain));
380 return ddc::replace_dim_of<
381 interpolation_discrete_dimension_type,
387
388
389
390
391
392
393
394
395 template <
class BatchedInterpolationDDom>
396 batched_spline_tr_domain_type<BatchedInterpolationDDom> batched_spline_tr_domain(
397 BatchedInterpolationDDom
const& batched_interpolation_domain)
const noexcept
399 assert(interpolation_domain() == interpolation_domain_type(batched_interpolation_domain));
400 return batched_spline_tr_domain_type<BatchedInterpolationDDom>(
401 ddc::replace_dim_of<bsplines_type, bsplines_type>(
402 batched_spline_domain(batched_interpolation_domain),
404 ddc::DiscreteElement<bsplines_type>(0),
406 matrix->required_number_of_rhs_rows()))));
411
412
413
414
415
416
417
418
419 template <
class BatchedInterpolationDDom>
421 BatchedInterpolationDDom
const& batched_interpolation_domain)
const noexcept
423 assert(interpolation_domain() == interpolation_domain_type(batched_interpolation_domain));
424 return ddc::replace_dim_of<interpolation_discrete_dimension_type, deriv_type>(
425 batched_interpolation_domain,
427 ddc::DiscreteElement<deriv_type>(1),
432
433
434
435
436
437
438
439
440 template <
class BatchedInterpolationDDom>
442 BatchedInterpolationDDom
const& batched_interpolation_domain)
const noexcept
444 assert(interpolation_domain() == interpolation_domain_type(batched_interpolation_domain));
445 return ddc::replace_dim_of<interpolation_discrete_dimension_type, deriv_type>(
446 batched_interpolation_domain,
448 ddc::DiscreteElement<deriv_type>(1),
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471 template <
class Layout,
class BatchedInterpolationDDom>
475 batched_spline_domain_type<BatchedInterpolationDDom>,
477 memory_space> spline,
478 ddc::
ChunkSpan<
double const, BatchedInterpolationDDom, Layout, memory_space> vals,
481 batched_derivs_domain_type<BatchedInterpolationDDom>,
483 memory_space>> derivs_xmin
487 batched_derivs_domain_type<BatchedInterpolationDDom>,
489 memory_space>> derivs_xmax
490 = std::nullopt)
const;
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515 template <
class OutMemorySpace = MemorySpace>
534 static int compute_block_sizes_uniform(
ddc::
BoundCond bound_cond,
int nbc);
536 static int compute_block_sizes_non_uniform(
ddc::
BoundCond bound_cond,
int nbc);
538 void allocate_matrix(
539 int lower_block_size,
540 int upper_block_size,
541 std::optional<std::size_t> cols_per_chunk = std::nullopt,
542 std::optional<
unsigned int> preconditioner_max_block_size = std::nullopt);
544 void build_matrix_system();
546 void check_valid_grid();
548 template <
class KnotElement>
549 static void check_n_points_in_cell(
int n_points_in_cell, KnotElement current_cell_end_idx);
556 class InterpolationDDim,
560void SplineBuilder<ExecSpace, MemorySpace, BSplines, InterpolationDDim, BcLower, BcUpper, Solver>::
561 compute_offset(interpolation_domain_type
const& interpolation_domain,
int& offset)
563 if constexpr (bsplines_type::is_periodic()) {
565 std::array<
double, bsplines_type::degree() + 1> values_ptr;
566 Kokkos::mdspan<
double, Kokkos::extents<std::size_t, bsplines_type::degree() + 1>>
const
567 values(values_ptr.data());
568 ddc::DiscreteElement<interpolation_discrete_dimension_type> start(
569 interpolation_domain.front());
570 auto jmin =
ddc::discrete_space<BSplines>()
571 .eval_basis(values,
ddc::coordinate(start + BSplines::degree()));
572 if constexpr (bsplines_type::degree() % 2 == 0) {
573 offset = jmin.uid() - start.uid() + bsplines_type::degree() / 2 - BSplines::degree();
575 int const mid = bsplines_type::degree() / 2;
576 offset = jmin.uid() - start.uid()
577 + (DDC_MDSPAN_ACCESS_OP(values, mid) > DDC_MDSPAN_ACCESS_OP(values, mid + 1)
580 - BSplines::degree();
591 class InterpolationDDim,
595int SplineBuilder<ExecSpace, MemorySpace, BSplines, InterpolationDDim, BcLower, BcUpper, Solver>::
596 compute_block_sizes_uniform(
ddc::
BoundCond const bound_cond,
int const nbc)
599 return static_cast<
int>(bsplines_type::degree()) / 2;
607 return static_cast<
int>(bsplines_type::degree()) - 1;
610 throw std::runtime_error(
"ddc::BoundCond not handled");
617 class InterpolationDDim,
621int SplineBuilder<ExecSpace, MemorySpace, BSplines, InterpolationDDim, BcLower, BcUpper, Solver>::
622 compute_block_sizes_non_uniform(
ddc::
BoundCond const bound_cond,
int const nbc)
625 return static_cast<
int>(bsplines_type::degree()) - 1;
632 throw std::runtime_error(
"ddc::BoundCond not handled");
639 class InterpolationDDim,
643void SplineBuilder<ExecSpace, MemorySpace, BSplines, InterpolationDDim, BcLower, BcUpper, Solver>::
645 [[maybe_unused]]
int lower_block_size,
646 [[maybe_unused]]
int upper_block_size,
647 std::optional<std::size_t> cols_per_chunk,
648 std::optional<
unsigned int> preconditioner_max_block_size)
658 int upper_band_width;
659 if (bsplines_type::is_uniform()) {
660 upper_band_width = bsplines_type::degree() / 2;
662 upper_band_width = bsplines_type::degree() - 1;
664 if constexpr (bsplines_type::is_periodic()) {
665 matrix =
ddc::detail::SplinesLinearProblemMaker::make_new_periodic_band_matrix<
667 ddc::discrete_space<BSplines>().nbasis(),
670 bsplines_type::is_uniform());
672 matrix =
ddc::detail::SplinesLinearProblemMaker::
673 make_new_block_matrix_with_band_main_block<ExecSpace>(
674 ddc::discrete_space<BSplines>().nbasis(),
677 bsplines_type::is_uniform(),
682 matrix =
ddc::detail::SplinesLinearProblemMaker::make_new_sparse<ExecSpace>(
683 ddc::discrete_space<BSplines>().nbasis(),
685 preconditioner_max_block_size);
688 build_matrix_system();
690 matrix->setup_solver();
697 class InterpolationDDim,
701void SplineBuilder<ExecSpace, MemorySpace, BSplines, InterpolationDDim, BcLower, BcUpper, Solver>::
702 build_matrix_system()
706 std::array<
double, (bsplines_type::degree() / 2 + 1) * (bsplines_type::degree() + 1)>
709 derivs(derivs_ptr.data(),
710 bsplines_type::degree() + 1,
711 bsplines_type::degree() / 2 + 1);
712 ddc::discrete_space<BSplines>().eval_basis_and_n_derivs(
714 ddc::discrete_space<BSplines>().rmin(),
719 for (std::size_t i = 0; i < bsplines_type::degree() + 1; ++i) {
720 for (std::size_t j = 1; j < bsplines_type::degree() / 2 + 1; ++j) {
721 DDC_MDSPAN_ACCESS_OP(derivs, i, j) *=
ddc::detail::ipow(m_dx, j);
726 for (std::size_t i = 0; i <
s_nbc_xmin; ++i) {
727 for (std::size_t j = 0; j < bsplines_type::degree(); ++j) {
731 DDC_MDSPAN_ACCESS_OP(derivs, j, s_nbc_xmin - i - 1 + s_odd));
737 std::array<
double, bsplines_type::degree() + 1> values_ptr;
738 Kokkos::mdspan<
double, Kokkos::extents<std::size_t, bsplines_type::degree() + 1>>
const values(
743 auto jmin =
ddc::discrete_space<BSplines>().eval_basis(
745 ddc::coordinate(
ddc::DiscreteElement<interpolation_discrete_dimension_type>(ix)));
746 for (std::size_t s = 0; s < bsplines_type::degree() + 1; ++s) {
747 int const j =
ddc::detail::
748 modulo(
int(jmin.uid() - m_offset + s),
749 static_cast<
int>(
ddc::discrete_space<BSplines>().nbasis()));
750 matrix->set_element(ix.uid() - start +
s_nbc_xmin, j, DDC_MDSPAN_ACCESS_OP(values, s));
756 std::array<
double, (bsplines_type::degree() / 2 + 1) * (bsplines_type::degree() + 1)>
762 bsplines_type::degree() + 1,
763 bsplines_type::degree() / 2 + 1>>
const derivs(derivs_ptr.data());
765 ddc::discrete_space<BSplines>().eval_basis_and_n_derivs(
767 ddc::discrete_space<BSplines>().rmax(),
772 for (std::size_t i = 0; i < bsplines_type::degree() + 1; ++i) {
773 for (std::size_t j = 1; j < bsplines_type::degree() / 2 + 1; ++j) {
774 DDC_MDSPAN_ACCESS_OP(derivs, i, j) *=
ddc::detail::ipow(m_dx, j);
778 int const i0 =
ddc::discrete_space<BSplines>().nbasis() -
s_nbc_xmax;
779 int const j0 =
ddc::discrete_space<BSplines>().nbasis() - bsplines_type::degree();
780 for (std::size_t j = 0; j < bsplines_type::degree(); ++j) {
781 for (std::size_t i = 0; i <
s_nbc_xmax; ++i) {
782 matrix->set_element(i0 + i, j0 + j, DDC_MDSPAN_ACCESS_OP(derivs, j + 1, i + s_odd));
796template <
class Layout,
class BatchedInterpolationDDom>
797void SplineBuilder<ExecSpace, MemorySpace, BSplines, InterpolationDDim, BcLower, BcUpper, Solver>::
801 batched_spline_domain_type<BatchedInterpolationDDom>,
803 memory_space> spline,
804 ddc::
ChunkSpan<
double const, BatchedInterpolationDDom, Layout, memory_space> vals,
807 batched_derivs_domain_type<BatchedInterpolationDDom>,
809 memory_space>>
const derivs_xmin,
812 batched_derivs_domain_type<BatchedInterpolationDDom>,
814 memory_space>>
const derivs_xmax)
const
816 auto const batched_interpolation_domain = vals.domain();
818 assert(interpolation_domain() == interpolation_domain_type(batched_interpolation_domain));
820 assert(vals.
template extent<interpolation_discrete_dimension_type>()
821 == ddc::discrete_space<bsplines_type>().nbasis() - s_nbc_xmin - s_nbc_xmax);
823 assert((BcLower == ddc::BoundCond::HERMITE)
824 != (!derivs_xmin.has_value() || derivs_xmin->
template extent<deriv_type>() == 0));
825 assert((BcUpper == ddc::BoundCond::HERMITE)
826 != (!derivs_xmax.has_value() || derivs_xmax->
template extent<deriv_type>() == 0));
828 assert(ddc::DiscreteElement<deriv_type>(derivs_xmin->domain().front()).uid() == 1);
831 assert(ddc::DiscreteElement<deriv_type>(derivs_xmax->domain().front()).uid() == 1);
838 assert(derivs_xmin->
template extent<deriv_type>() == s_nbc_xmin);
839 auto derivs_xmin_values = *derivs_xmin;
840 auto const dx_proxy = m_dx;
841 ddc::parallel_for_each(
842 "ddc_splines_hermite_compute_lower_coefficients",
844 batch_domain(batched_interpolation_domain),
846 typename batch_domain_type<BatchedInterpolationDDom>::discrete_element_type
849 spline(
ddc::DiscreteElement<bsplines_type>(
s_nbc_xmin - i), j)
850 = derivs_xmin_values(
ddc::DiscreteElement<deriv_type>(i), j)
851 *
ddc::detail::ipow(dx_proxy, i +
s_odd - 1);
872 interpolation_discrete_dimension_type>())))]
873 .allocation_kokkos_view(),
874 vals.allocation_kokkos_view());
881 auto const& nbasis_proxy =
ddc::discrete_space<bsplines_type>().nbasis();
883 assert(derivs_xmax->
template extent<deriv_type>() == s_nbc_xmax);
884 auto derivs_xmax_values = *derivs_xmax;
885 auto const dx_proxy = m_dx;
886 ddc::parallel_for_each(
887 "ddc_splines_hermite_compute_upper_coefficients",
889 batch_domain(batched_interpolation_domain),
891 typename batch_domain_type<BatchedInterpolationDDom>::discrete_element_type
894 spline(
ddc::DiscreteElement<bsplines_type>(nbasis_proxy -
s_nbc_xmax - i),
896 = derivs_xmax_values(
ddc::DiscreteElement<deriv_type>(i + 1), j)
897 *
ddc::detail::ipow(dx_proxy, i +
s_odd);
903 auto const& offset_proxy = m_offset;
905 batched_spline_tr_domain(batched_interpolation_domain),
907 ddc::
ChunkSpan const spline_tr = spline_tr_alloc.span_view();
908 ddc::parallel_for_each(
909 "ddc_splines_transpose_rhs",
911 batch_domain(batched_interpolation_domain),
913 typename batch_domain_type<
914 BatchedInterpolationDDom>::discrete_element_type
const j) {
915 for (std::size_t i = 0; i < nbasis_proxy; ++i) {
916 spline_tr(
ddc::DiscreteElement<bsplines_type>(i), j)
917 = spline(
ddc::DiscreteElement<bsplines_type>(i + offset_proxy), j);
921 Kokkos::View<
double**, Kokkos::LayoutRight, exec_space>
const bcoef_section(
922 spline_tr.data_handle(),
923 static_cast<std::size_t>(spline_tr.
template extent<bsplines_type>()),
924 batch_domain(batched_interpolation_domain).size());
926 matrix->solve(bcoef_section,
false);
928 ddc::parallel_for_each(
929 "ddc_splines_transpose_back_rhs",
931 batch_domain(batched_interpolation_domain),
933 typename batch_domain_type<
934 BatchedInterpolationDDom>::discrete_element_type
const j) {
935 for (std::size_t i = 0; i < nbasis_proxy; ++i) {
936 spline(
ddc::DiscreteElement<bsplines_type>(i + offset_proxy), j)
937 = spline_tr(
ddc::DiscreteElement<bsplines_type>(i), j);
942 if (bsplines_type::is_periodic()) {
943 ddc::parallel_for_each(
944 "ddc_splines_periodic_rows_duplicate_rhs",
946 batch_domain(batched_interpolation_domain),
948 typename batch_domain_type<
949 BatchedInterpolationDDom>::discrete_element_type
const j) {
950 if (offset_proxy != 0) {
951 for (
int i = 0; i < offset_proxy; ++i) {
952 spline(
ddc::DiscreteElement<bsplines_type>(i), j) = spline(
953 ddc::DiscreteElement<bsplines_type>(nbasis_proxy + i),
956 for (std::size_t i = offset_proxy; i < bsplines_type::degree(); ++i) {
957 spline(
ddc::DiscreteElement<bsplines_type>(nbasis_proxy + i), j)
958 = spline(
ddc::DiscreteElement<bsplines_type>(i), j);
961 for (std::size_t i(0); i < bsplines_type::degree(); ++i) {
962 const ddc::DiscreteElement<bsplines_type> i_start(i);
963 const ddc::DiscreteElement<bsplines_type> i_end(nbasis_proxy + i);
965 spline(i_end, j) = spline(i_start, j);
979template <
class OutMemorySpace>
995SplineBuilder<ExecSpace, MemorySpace, BSplines, InterpolationDDim, BcLower, BcUpper, Solver>::
1000 ddc::integrals(ExecSpace(), integral_bsplines.span_view());
1003 ddc::
ChunkSpan const integral_bsplines_without_periodic_additional_bsplines
1008 Kokkos::View<
double**, Kokkos::LayoutRight, MemorySpace>
const
1009 integral_bsplines_mirror_with_additional_allocation(
1010 "integral_bsplines_mirror_with_additional_allocation",
1011 matrix->required_number_of_rhs_rows(),
1015 Kokkos::View<
double*, Kokkos::LayoutRight, MemorySpace>
const integral_bsplines_mirror
1017 subview(integral_bsplines_mirror_with_additional_allocation,
1019 pair {
static_cast<std::size_t>(0),
1020 integral_bsplines_without_periodic_additional_bsplines
1026 integral_bsplines_mirror,
1027 integral_bsplines_without_periodic_additional_bsplines.allocation_kokkos_view());
1028 matrix->solve(integral_bsplines_mirror_with_additional_allocation,
true);
1030 integral_bsplines_without_periodic_additional_bsplines.allocation_kokkos_view(),
1031 integral_bsplines_mirror);
1035 = integral_bsplines_without_periodic_additional_bsplines[
spline_domain().take_first(
1037 ddc::
ChunkSpan const coefficients = integral_bsplines_without_periodic_additional_bsplines
1045 = integral_bsplines_without_periodic_additional_bsplines
1054 ddc::parallel_for_each(
1056 coefficients_derivs_xmin.domain(),
1057 KOKKOS_LAMBDA(
ddc::DiscreteElement<bsplines_type> i) {
1058 ddc::Coordinate<continuous_dimension_type>
const dx
1059 =
ddc::distance_at_right(interpolation_domain_proxy.front() + 1);
1060 coefficients_derivs_xmin(i) *=
ddc::detail::
1062 static_cast<std::size_t>(get<bsplines_type>(
1063 i - coefficients_derivs_xmin.domain().front() + 1)));
1065 ddc::parallel_for_each(
1067 coefficients_derivs_xmax.domain(),
1068 KOKKOS_LAMBDA(
ddc::DiscreteElement<bsplines_type> i) {
1069 ddc::Coordinate<continuous_dimension_type>
const dx
1070 =
ddc::distance_at_left(interpolation_domain_proxy.back() - 1);
1071 coefficients_derivs_xmax(i) *=
ddc::detail::
1073 static_cast<std::size_t>(get<bsplines_type>(
1074 i - coefficients_derivs_xmax.domain().front() + 1)));
1078 ddc::
Chunk coefficients_derivs_xmin_out(
1080 ddc::DiscreteElement<deriv_type>(1),
1086 coefficients.size())),
1088 ddc::
Chunk coefficients_derivs_xmax_out(
1090 ddc::DiscreteElement<deriv_type>(1),
1094 coefficients_derivs_xmin_out.allocation_kokkos_view(),
1095 coefficients_derivs_xmin.allocation_kokkos_view());
1097 coefficients_out.allocation_kokkos_view(),
1098 coefficients.allocation_kokkos_view());
1100 coefficients_derivs_xmax_out.allocation_kokkos_view(),
1101 coefficients_derivs_xmax.allocation_kokkos_view());
1102 return std::make_tuple(
1103 std::move(coefficients_derivs_xmin_out),
1104 std::move(coefficients_out),
1105 std::move(coefficients_derivs_xmax_out));
1116template <
class KnotElement>
1117void SplineBuilder<ExecSpace, MemorySpace, BSplines, InterpolationDDim, BcLower, BcUpper, Solver>::
1118 check_n_points_in_cell(
int const n_points_in_cell, KnotElement
const current_cell_end_idx)
1120 if (n_points_in_cell > BSplines::degree() + 1) {
1121 KnotElement
const rmin_idx =
ddc::discrete_space<BSplines>().break_point_domain().front();
1122 int const failed_cell = (current_cell_end_idx - rmin_idx).value();
1123 throw std::runtime_error(
1124 "The spline problem is overconstrained. There are "
1125 + std::to_string(n_points_in_cell) +
" points in the " + std::to_string(failed_cell)
1134 class InterpolationDDim,
1138void SplineBuilder<ExecSpace, MemorySpace, BSplines, InterpolationDDim, BcLower, BcUpper, Solver>::
1142 std::size_t
const expected_npoints
1144 if (n_interp_points != expected_npoints) {
1145 throw std::runtime_error(
1146 "Incorrect number of points supplied to NonUniformInterpolationPoints. "
1148 + std::to_string(n_interp_points)
1149 +
", expected : " + std::to_string(expected_npoints));
1151 int n_points_in_cell = 0;
1152 auto current_cell_end_idx =
ddc::discrete_space<BSplines>().break_point_domain().front() + 1;
1154 ddc::Coordinate<continuous_dimension_type>
const point =
ddc::coordinate(idx);
1155 if (point >
ddc::coordinate(current_cell_end_idx)) {
1157 check_n_points_in_cell(n_points_in_cell, current_cell_end_idx);
1159 n_points_in_cell = 1;
1161 current_cell_end_idx += 1;
1162 }
else if (point ==
ddc::coordinate(current_cell_end_idx)) {
1164 check_n_points_in_cell(n_points_in_cell + 1, current_cell_end_idx);
1166 n_points_in_cell = 1;
1168 current_cell_end_idx += 1;
1171 n_points_in_cell += 1;
1175 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 for creating a spline approximation of a function.
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 SplineSolver s_spline_solver
The SplineSolver giving the backend used to perform the spline approximation.
batch_domain_type< BatchedInterpolationDDom > batch_domain(BatchedInterpolationDDom const &batched_interpolation_domain) const noexcept
Get the batch domain.
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.
SplineBuilder & operator=(SplineBuilder const &x)=delete
Copy-assignment is deleted.
SplineBuilder(SplineBuilder &&x)=default
Move-constructs.
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 ddc::BoundCond s_bc_xmin
The boundary condition implemented at the lower bound.
static constexpr int s_nbc_xmin
The number of equations defining the boundary condition at the lower bound.
SplineBuilder & operator=(SplineBuilder &&x)=default
Move-assigns.
BatchedInterpolationDDom batched_interpolation_domain(BatchedInterpolationDDom const &batched_interpolation_domain) const noexcept
Get the whole domain representing interpolation points.
SplineBuilder(SplineBuilder const &x)=delete
Copy-constructor is deleted.
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.
static constexpr bool s_odd
Indicates if the degree of the splines is odd or even.
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_xmin_domain(BatchedInterpolationDDom const &batched_interpolation_domain) const noexcept
Get the whole domain on which derivatives on lower boundary are defined.
static constexpr ddc::BoundCond s_bc_xmax
The boundary condition implemented at the upper bound.
static constexpr int s_nbc_xmax
The number of equations defining the boundary condition at the upper bound.
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.
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.
ddc::DiscreteDomain< bsplines_type > spline_domain() const noexcept
Get the 1D domain on which spline coefficients are defined.
~SplineBuilder()=default
Destructs.
The top-level namespace of DDC.
BoundCond
An enum representing a spline boundary condition.
@ GREVILLE
Use Greville points instead of conditions on derivative for B-Spline interpolation.
@ HERMITE
Hermite boundary condition.
@ PERIODIC
Periodic boundary condition u(1)=u(n)
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)
A templated struct representing a discrete dimension storing the derivatives of a function along a co...