20#include <Kokkos_Core.hpp>
33
34
35
36
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
62 class InterpolationDDim,
76 using exec_space = ExecSpace;
79 using memory_space = MemorySpace;
82 using continuous_dimension_type =
typename InterpolationDDim::continuous_dimension_type;
85 using interpolation_discrete_dimension_type = InterpolationDDim;
88 using bsplines_type = BSplines;
91 using deriv_type =
ddc::
Deriv<continuous_dimension_type>;
94 using interpolation_domain_type =
ddc::
DiscreteDomain<interpolation_discrete_dimension_type>;
97
98
99
100
102 class BatchedInterpolationDDom,
103 class = std::enable_if_t<
ddc::is_discrete_domain_v<BatchedInterpolationDDom>>>
104 using batched_interpolation_domain_type = BatchedInterpolationDDom;
107
108
109
110
111
112
113
114
116 class BatchedInterpolationDDom,
117 class = std::enable_if_t<
ddc::is_discrete_domain_v<BatchedInterpolationDDom>>>
118 using batch_domain_type =
ddc::
119 remove_dims_of_t<BatchedInterpolationDDom, interpolation_discrete_dimension_type>;
122
123
124
125
126
127
128
129
131 class BatchedInterpolationDDom,
132 class = std::enable_if_t<
ddc::is_discrete_domain_v<BatchedInterpolationDDom>>>
133 using batched_spline_domain_type =
ddc::replace_dim_of_t<
134 BatchedInterpolationDDom,
135 interpolation_discrete_dimension_type,
140
141
142
143
144
145
146
147
149 class BatchedInterpolationDDom,
150 class = std::enable_if_t<
ddc::is_discrete_domain_v<BatchedInterpolationDDom>>>
151 using batched_spline_tr_domain_type =
152 typename ddc::detail::convert_type_seq_to_discrete_domain_t<
ddc::type_seq_merge_t<
153 ddc::detail::TypeSeq<bsplines_type>,
154 ddc::type_seq_remove_t<
155 ddc::to_type_seq_t<BatchedInterpolationDDom>,
156 ddc::detail::TypeSeq<interpolation_discrete_dimension_type>>>>;
160
161
162
163
164
165
166
167
169 class BatchedInterpolationDDom,
170 class = std::enable_if_t<
ddc::is_discrete_domain_v<BatchedInterpolationDDom>>>
171 using batched_derivs_domain_type =
ddc::replace_dim_of_t<
172 BatchedInterpolationDDom,
173 interpolation_discrete_dimension_type,
177 static constexpr bool s_odd = BSplines::degree() % 2;
180 static constexpr int s_nbe_xmin = n_boundary_equations(BcLower, BSplines::degree());
183 static constexpr int s_nbe_xmax = n_boundary_equations(BcUpper, BSplines::degree());
188 : n_boundary_equations(BcLower, BSplines::degree());
193 : n_boundary_equations(BcUpper, BSplines::degree());
205 interpolation_domain_type m_interpolation_domain;
212 std::unique_ptr<
ddc::detail::SplinesLinearProblem<exec_space>> m_matrix;
215 void compute_offset(interpolation_domain_type
const& interpolation_domain,
int& offset);
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
235 interpolation_domain_type
const& interpolation_domain,
236 std::optional<std::size_t> cols_per_chunk = std::nullopt,
237 std::optional<
unsigned int> preconditioner_max_block_size = std::nullopt)
238 : m_interpolation_domain(interpolation_domain)
239 , m_dx((
ddc::discrete_space<BSplines>().rmax() -
ddc::discrete_space<BSplines>().rmin())
240 /
ddc::discrete_space<BSplines>().ncells())
244 "Incompatible boundary conditions");
247 compute_offset(
this->interpolation_domain(), m_offset);
250 int lower_block_size;
251 int upper_block_size;
252 if constexpr (bsplines_type::is_uniform()) {
253 upper_block_size = compute_block_sizes_uniform(BcLower,
s_nbe_xmin);
254 lower_block_size = compute_block_sizes_uniform(BcUpper,
s_nbe_xmax);
256 upper_block_size = compute_block_sizes_non_uniform(BcLower,
s_nbe_xmin);
257 lower_block_size = compute_block_sizes_non_uniform(BcUpper,
s_nbe_xmax);
263 preconditioner_max_block_size);
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
283 class BatchedInterpolationDDom,
284 class = std::enable_if_t<
ddc::is_discrete_domain_v<BatchedInterpolationDDom>>>
286 BatchedInterpolationDDom
const& batched_interpolation_domain,
287 std::optional<std::size_t> cols_per_chunk = std::nullopt,
288 std::optional<
unsigned int> preconditioner_max_block_size = std::nullopt)
290 interpolation_domain_type(batched_interpolation_domain),
292 preconditioner_max_block_size)
301
302
303
313
314
315
316
320
321
322
323
324
325
328 return m_interpolation_domain;
332
333
334
335
336
337
338
339
340
342 class BatchedInterpolationDDom,
343 class = std::enable_if_t<
ddc::is_discrete_domain_v<BatchedInterpolationDDom>>>
345 BatchedInterpolationDDom
const& batched_interpolation_domain)
const noexcept
348 return batched_interpolation_domain;
352
353
354
355
356
357
358
359
360 template <
class BatchedInterpolationDDom>
361 batch_domain_type<BatchedInterpolationDDom>
batch_domain(
362 BatchedInterpolationDDom
const& batched_interpolation_domain)
const noexcept
369
370
371
372
373
374
377 return ddc::discrete_space<bsplines_type>().full_domain();
381
382
383
384
385
386
387
388
389 template <
class BatchedInterpolationDDom>
391 BatchedInterpolationDDom
const& batched_interpolation_domain)
const noexcept
394 return ddc::replace_dim_of<
395 interpolation_discrete_dimension_type,
401
402
403
404
405
406
407
408
409 template <
class BatchedInterpolationDDom>
410 batched_spline_tr_domain_type<BatchedInterpolationDDom> batched_spline_tr_domain(
411 BatchedInterpolationDDom
const& batched_interpolation_domain)
const noexcept
414 return batched_spline_tr_domain_type<BatchedInterpolationDDom>(
415 ddc::replace_dim_of<bsplines_type, bsplines_type>(
416 batched_spline_domain(batched_interpolation_domain),
418 ddc::DiscreteElement<bsplines_type>(0),
420 m_matrix->required_number_of_rhs_rows()))));
425
426
427
428
429
430
431
432
433 template <
class BatchedInterpolationDDom>
435 BatchedInterpolationDDom
const& batched_interpolation_domain)
const noexcept
438 return ddc::replace_dim_of<interpolation_discrete_dimension_type, deriv_type>(
439 batched_interpolation_domain,
441 ddc::DiscreteElement<deriv_type>(1),
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<interpolation_discrete_dimension_type, deriv_type>(
460 batched_interpolation_domain,
462 ddc::DiscreteElement<deriv_type>(1),
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485 template <
class Layout,
class BatchedInterpolationDDom>
489 batched_spline_domain_type<BatchedInterpolationDDom>,
491 memory_space> spline,
492 ddc::
ChunkSpan<
double const, BatchedInterpolationDDom, Layout, memory_space> vals,
495 batched_derivs_domain_type<BatchedInterpolationDDom>,
497 memory_space>> derivs_xmin
501 batched_derivs_domain_type<BatchedInterpolationDDom>,
503 memory_space>> derivs_xmax
504 = std::nullopt)
const;
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529 template <
class OutMemorySpace = MemorySpace>
548 static int compute_block_sizes_uniform(
ddc::
BoundCond bound_cond,
int nbc);
550 static int compute_block_sizes_non_uniform(
ddc::
BoundCond bound_cond,
int nbc);
552 void allocate_matrix(
553 int lower_block_size,
554 int upper_block_size,
555 std::optional<std::size_t> cols_per_chunk = std::nullopt,
556 std::optional<
unsigned int> preconditioner_max_block_size = std::nullopt);
558 void build_matrix_system();
560 void check_valid_grid();
562 template <
class KnotElement>
563 static void check_n_points_in_cell(
int n_points_in_cell, KnotElement current_cell_end_idx);
570 class InterpolationDDim,
574void SplineBuilder<ExecSpace, MemorySpace, BSplines, InterpolationDDim, BcLower, BcUpper, Solver>::
575 compute_offset(interpolation_domain_type
const& interpolation_domain,
int& offset)
577 if constexpr (bsplines_type::is_periodic()) {
579 std::array<
double, bsplines_type::degree() + 1> values_ptr;
580 Kokkos::mdspan<
double, Kokkos::extents<std::size_t, bsplines_type::degree() + 1>>
const
581 values(values_ptr.data());
582 ddc::DiscreteElement<interpolation_discrete_dimension_type> start(
583 interpolation_domain.front());
584 auto jmin =
ddc::discrete_space<BSplines>()
585 .eval_basis(values,
ddc::coordinate(start + BSplines::degree()));
586 if constexpr (bsplines_type::degree() % 2 == 0) {
587 offset = jmin.uid() - start.uid() + bsplines_type::degree() / 2 - BSplines::degree();
589 int const mid = bsplines_type::degree() / 2;
590 offset = jmin.uid() - start.uid()
591 + (DDC_MDSPAN_ACCESS_OP(values, mid) > DDC_MDSPAN_ACCESS_OP(values, mid + 1)
594 - BSplines::degree();
605 class InterpolationDDim,
609int SplineBuilder<ExecSpace, MemorySpace, BSplines, InterpolationDDim, BcLower, BcUpper, Solver>::
610 compute_block_sizes_uniform(
ddc::
BoundCond const bound_cond,
int const nbc)
613 return static_cast<
int>(bsplines_type::degree()) / 2;
622 return static_cast<
int>(bsplines_type::degree()) - 1;
625 throw std::runtime_error(
"ddc::BoundCond not handled");
632 class InterpolationDDim,
636int SplineBuilder<ExecSpace, MemorySpace, BSplines, InterpolationDDim, BcLower, BcUpper, Solver>::
637 compute_block_sizes_non_uniform(
ddc::
BoundCond const bound_cond,
int const nbc)
640 return static_cast<
int>(bsplines_type::degree()) - 1;
648 throw std::runtime_error(
"ddc::BoundCond not handled");
655 class InterpolationDDim,
659void SplineBuilder<ExecSpace, MemorySpace, BSplines, InterpolationDDim, BcLower, BcUpper, Solver>::
661 [[maybe_unused]]
int lower_block_size,
662 [[maybe_unused]]
int upper_block_size,
663 std::optional<std::size_t> cols_per_chunk,
664 std::optional<
unsigned int> preconditioner_max_block_size)
674 int upper_band_width;
675 if (bsplines_type::is_uniform()) {
676 upper_band_width = bsplines_type::degree() / 2;
678 upper_band_width = bsplines_type::degree() - 1;
680 if constexpr (bsplines_type::is_periodic()) {
681 m_matrix =
ddc::detail::SplinesLinearProblemMaker::make_new_periodic_band_matrix<
683 ddc::discrete_space<BSplines>().nbasis(),
686 bsplines_type::is_uniform());
688 m_matrix =
ddc::detail::SplinesLinearProblemMaker::
689 make_new_block_matrix_with_band_main_block<ExecSpace>(
690 ddc::discrete_space<BSplines>().nbasis(),
693 bsplines_type::is_uniform(),
698 m_matrix =
ddc::detail::SplinesLinearProblemMaker::make_new_sparse<ExecSpace>(
699 ddc::discrete_space<BSplines>().nbasis(),
701 preconditioner_max_block_size);
704 build_matrix_system();
706 m_matrix->setup_solver();
713 class InterpolationDDim,
717void SplineBuilder<ExecSpace, MemorySpace, BSplines, InterpolationDDim, BcLower, BcUpper, Solver>::
718 build_matrix_system()
723 std::array<
double, (bsplines_type::degree() / 2 + 1) * (bsplines_type::degree() + 1)>
726 derivs(derivs_ptr.data(),
727 bsplines_type::degree() + 1,
728 bsplines_type::degree() / 2 + 1);
729 ddc::discrete_space<BSplines>().eval_basis_and_n_derivs(
731 ddc::discrete_space<BSplines>().rmin(),
736 for (std::size_t i = 0; i < bsplines_type::degree() + 1; ++i) {
737 for (std::size_t j = 1; j < bsplines_type::degree() / 2 + 1; ++j) {
738 DDC_MDSPAN_ACCESS_OP(derivs, i, j) *=
ddc::detail::ipow(m_dx, j);
744 for (std::size_t i = 0; i <
s_nbe_xmin; ++i) {
745 for (std::size_t j = 0; j < bsplines_type::degree(); ++j) {
746 m_matrix->set_element(i, j, DDC_MDSPAN_ACCESS_OP(derivs, j, i + s_odd));
753 std::array<
double, bsplines_type::degree() + 1> values_ptr;
754 Kokkos::mdspan<
double, Kokkos::extents<std::size_t, bsplines_type::degree() + 1>>
const values(
759 auto jmin =
ddc::discrete_space<BSplines>().eval_basis(
761 ddc::coordinate(
ddc::DiscreteElement<interpolation_discrete_dimension_type>(ix)));
762 for (std::size_t s = 0; s < bsplines_type::degree() + 1; ++s) {
763 int const j =
ddc::detail::
764 modulo(
int(jmin.uid() - m_offset + s),
765 static_cast<
int>(
ddc::discrete_space<BSplines>().nbasis()));
766 m_matrix->set_element(
769 DDC_MDSPAN_ACCESS_OP(values, s));
776 std::array<
double, (bsplines_type::degree() / 2 + 1) * (bsplines_type::degree() + 1)>
782 bsplines_type::degree() + 1,
783 bsplines_type::degree() / 2 + 1>>
const derivs(derivs_ptr.data());
785 ddc::discrete_space<BSplines>().eval_basis_and_n_derivs(
787 ddc::discrete_space<BSplines>().rmax(),
792 for (std::size_t i = 0; i < bsplines_type::degree() + 1; ++i) {
793 for (std::size_t j = 1; j < bsplines_type::degree() / 2 + 1; ++j) {
794 DDC_MDSPAN_ACCESS_OP(derivs, i, j) *=
ddc::detail::ipow(m_dx, j);
799 int const i0 =
ddc::discrete_space<BSplines>().nbasis() -
s_nbe_xmax;
800 int const j0 =
ddc::discrete_space<BSplines>().nbasis() - bsplines_type::degree();
801 for (std::size_t j = 0; j < bsplines_type::degree(); ++j) {
802 for (std::size_t i = 0; i <
s_nbe_xmax; ++i) {
803 m_matrix->set_element(
806 DDC_MDSPAN_ACCESS_OP(derivs, j + 1, i +
s_odd));
821template <
class Layout,
class BatchedInterpolationDDom>
822void SplineBuilder<ExecSpace, MemorySpace, BSplines, InterpolationDDim, BcLower, BcUpper, Solver>::
826 batched_spline_domain_type<BatchedInterpolationDDom>,
828 memory_space> spline,
829 ddc::
ChunkSpan<
double const, BatchedInterpolationDDom, Layout, memory_space> vals,
832 batched_derivs_domain_type<BatchedInterpolationDDom>,
834 memory_space>>
const derivs_xmin,
837 batched_derivs_domain_type<BatchedInterpolationDDom>,
839 memory_space>>
const derivs_xmax)
const
841 auto const batched_interpolation_domain = vals.domain();
844 assert(batch_domain_type<BatchedInterpolationDDom>(batched_interpolation_domain)
845 == batch_domain_type<BatchedInterpolationDDom>(spline.domain()));
847 if (batch_domain(batched_interpolation_domain).empty()) {
851 assert(vals.
template extent<interpolation_discrete_dimension_type>()
855 assert(
ddc::DiscreteElement<deriv_type>(derivs_xmin->domain().front()).uid() ==
s_odd);
856 assert(derivs_xmin.has_value() ||
s_nbe_xmin == 0);
858 assert(!derivs_xmin.has_value() || derivs_xmin->
template extent<deriv_type>() == 0);
861 assert(
ddc::DiscreteElement<deriv_type>(derivs_xmax->domain().front()).uid() ==
s_odd);
862 assert(derivs_xmax.has_value() ||
s_nbe_xmax == 0);
864 assert(!derivs_xmax.has_value() || derivs_xmax->
template extent<deriv_type>() == 0);
871 assert(derivs_xmin->
template extent<deriv_type>() ==
s_nbe_xmin);
872 auto derivs_xmin_values = *derivs_xmin;
873 auto const dx_proxy = m_dx;
874 auto const odd_proxy =
s_odd;
875 ddc::parallel_for_each(
876 "ddc_splines_hermite_compute_lower_coefficients",
878 batch_domain(batched_interpolation_domain),
880 typename batch_domain_type<BatchedInterpolationDDom>::discrete_element_type
883 spline(
ddc::DiscreteElement<bsplines_type>(i), j)
884 = derivs_xmin_values(
885 ddc::DiscreteElement<deriv_type>(i + odd_proxy),
887 *
ddc::detail::ipow(dx_proxy, i + odd_proxy);
892 ddc::DiscreteElement<bsplines_type>(0),
894 batched_spline_domain_type<BatchedInterpolationDDom>
const
895 dx_spline_domain(dx_splines, batch_domain(batched_interpolation_domain));
896 ddc::parallel_fill(exec_space(), spline[dx_spline_domain], 0.0);
915 interpolation_discrete_dimension_type>())))]
916 .allocation_kokkos_view(),
917 vals.allocation_kokkos_view());
924 auto const& nbasis_proxy =
ddc::discrete_space<bsplines_type>().nbasis();
926 assert(derivs_xmax->
template extent<deriv_type>() ==
s_nbe_xmax);
927 auto derivs_xmax_values = *derivs_xmax;
928 auto const dx_proxy = m_dx;
929 auto const odd_proxy =
s_odd;
930 ddc::parallel_for_each(
931 "ddc_splines_hermite_compute_upper_coefficients",
933 batch_domain(batched_interpolation_domain),
935 typename batch_domain_type<BatchedInterpolationDDom>::discrete_element_type
938 spline(
ddc::DiscreteElement<bsplines_type>(nbasis_proxy -
s_nbe_xmax + i),
940 = derivs_xmax_values(
941 ddc::DiscreteElement<deriv_type>(i + odd_proxy),
943 *
ddc::detail::ipow(dx_proxy, i + odd_proxy);
948 ddc::DiscreteElement<bsplines_type>(nbasis_proxy -
s_nbe_xmax),
950 batched_spline_domain_type<BatchedInterpolationDDom>
const
951 dx_spline_domain(dx_splines, batch_domain(batched_interpolation_domain));
952 ddc::parallel_fill(exec_space(), spline[dx_spline_domain], 0.0);
956 auto const& offset_proxy = m_offset;
958 batched_spline_tr_domain(batched_interpolation_domain),
960 ddc::
ChunkSpan const spline_tr = spline_tr_alloc.span_view();
961 ddc::parallel_for_each(
962 "ddc_splines_transpose_rhs",
964 batch_domain(batched_interpolation_domain),
966 typename batch_domain_type<
967 BatchedInterpolationDDom>::discrete_element_type
const j) {
968 for (std::size_t i = 0; i < nbasis_proxy; ++i) {
969 spline_tr(
ddc::DiscreteElement<bsplines_type>(i), j)
970 = spline(
ddc::DiscreteElement<bsplines_type>(i + offset_proxy), j);
974 Kokkos::View<
double**, Kokkos::LayoutRight, exec_space>
const bcoef_section(
975 spline_tr.data_handle(),
976 static_cast<std::size_t>(spline_tr.
template extent<bsplines_type>()),
977 batch_domain(batched_interpolation_domain).size());
979 m_matrix->solve(bcoef_section,
false);
981 ddc::parallel_for_each(
982 "ddc_splines_transpose_back_rhs",
984 batch_domain(batched_interpolation_domain),
986 typename batch_domain_type<
987 BatchedInterpolationDDom>::discrete_element_type
const j) {
988 for (std::size_t i = 0; i < nbasis_proxy; ++i) {
989 spline(
ddc::DiscreteElement<bsplines_type>(i + offset_proxy), j)
990 = spline_tr(
ddc::DiscreteElement<bsplines_type>(i), j);
995 if (bsplines_type::is_periodic()) {
996 ddc::parallel_for_each(
997 "ddc_splines_periodic_rows_duplicate_rhs",
999 batch_domain(batched_interpolation_domain),
1001 typename batch_domain_type<
1002 BatchedInterpolationDDom>::discrete_element_type
const j) {
1003 if (offset_proxy != 0) {
1004 for (
int i = 0; i < offset_proxy; ++i) {
1005 spline(
ddc::DiscreteElement<bsplines_type>(i), j) = spline(
1006 ddc::DiscreteElement<bsplines_type>(nbasis_proxy + i),
1009 for (std::size_t i = offset_proxy; i < bsplines_type::degree(); ++i) {
1010 spline(
ddc::DiscreteElement<bsplines_type>(nbasis_proxy + i), j)
1011 = spline(
ddc::DiscreteElement<bsplines_type>(i), j);
1014 for (std::size_t i(0); i < bsplines_type::degree(); ++i) {
1015 ddc::DiscreteElement<bsplines_type>
const i_start(i);
1016 ddc::DiscreteElement<bsplines_type>
const i_end(nbasis_proxy + i);
1018 spline(i_end, j) = spline(i_start, j);
1032template <
class OutMemorySpace>
1048SplineBuilder<ExecSpace, MemorySpace, BSplines, InterpolationDDim, BcLower, BcUpper, Solver>::
1053 ddc::integrals(ExecSpace(), integral_bsplines.span_view());
1056 ddc::
ChunkSpan const integral_bsplines_without_periodic_additional_bsplines
1061 Kokkos::View<
double**, Kokkos::LayoutRight, MemorySpace>
const
1062 integral_bsplines_mirror_with_additional_allocation(
1063 "integral_bsplines_mirror_with_additional_allocation",
1064 m_matrix->required_number_of_rhs_rows(),
1068 Kokkos::View<
double*, Kokkos::LayoutRight, MemorySpace>
const integral_bsplines_mirror
1070 subview(integral_bsplines_mirror_with_additional_allocation,
1072 pair {
static_cast<std::size_t>(0),
1073 integral_bsplines_without_periodic_additional_bsplines
1079 integral_bsplines_mirror,
1080 integral_bsplines_without_periodic_additional_bsplines.allocation_kokkos_view());
1081 m_matrix->solve(integral_bsplines_mirror_with_additional_allocation,
true);
1083 integral_bsplines_without_periodic_additional_bsplines.allocation_kokkos_view(),
1084 integral_bsplines_mirror);
1088 = integral_bsplines_without_periodic_additional_bsplines[
spline_domain().take_first(
1090 ddc::
ChunkSpan const coefficients = integral_bsplines_without_periodic_additional_bsplines
1098 = integral_bsplines_without_periodic_additional_bsplines
1106 auto const dx_proxy = m_dx;
1107 auto const odd_proxy =
s_odd;
1108 ddc::parallel_for_each(
1110 coefficients_derivs_xmin.domain(),
1111 KOKKOS_LAMBDA(
ddc::DiscreteElement<bsplines_type> i) {
1112 coefficients_derivs_xmin(i) *=
ddc::detail::
1114 static_cast<std::size_t>(get<bsplines_type>(
1115 (i - coefficients_derivs_xmin.domain().front()) + odd_proxy)));
1117 ddc::parallel_for_each(
1119 coefficients_derivs_xmax.domain(),
1120 KOKKOS_LAMBDA(
ddc::DiscreteElement<bsplines_type> i) {
1121 coefficients_derivs_xmax(i) *=
ddc::detail::
1123 static_cast<std::size_t>(get<bsplines_type>(
1124 (i - coefficients_derivs_xmax.domain().front()) + odd_proxy)));
1127 ddc::DiscreteElement<deriv_type>
const first_deriv(
s_odd);
1129 ddc::
Chunk coefficients_derivs_xmin_out(
1136 coefficients.size())),
1138 ddc::
Chunk coefficients_derivs_xmax_out(
1143 coefficients_derivs_xmin_out.allocation_kokkos_view(),
1144 coefficients_derivs_xmin.allocation_kokkos_view());
1146 coefficients_out.allocation_kokkos_view(),
1147 coefficients.allocation_kokkos_view());
1149 coefficients_derivs_xmax_out.allocation_kokkos_view(),
1150 coefficients_derivs_xmax.allocation_kokkos_view());
1151 return std::make_tuple(
1152 std::move(coefficients_derivs_xmin_out),
1153 std::move(coefficients_out),
1154 std::move(coefficients_derivs_xmax_out));
1165template <
class KnotElement>
1166void SplineBuilder<ExecSpace, MemorySpace, BSplines, InterpolationDDim, BcLower, BcUpper, Solver>::
1167 check_n_points_in_cell(
int const n_points_in_cell, KnotElement
const current_cell_end_idx)
1169 if (n_points_in_cell > BSplines::degree() + 1) {
1170 KnotElement
const rmin_idx =
ddc::discrete_space<BSplines>().break_point_domain().front();
1171 int const failed_cell = (current_cell_end_idx - rmin_idx).value();
1172 throw std::runtime_error(
1173 "The spline problem is overconstrained. There are "
1174 + std::to_string(n_points_in_cell) +
" points in the " + std::to_string(failed_cell)
1183 class InterpolationDDim,
1187void SplineBuilder<ExecSpace, MemorySpace, BSplines, InterpolationDDim, BcLower, BcUpper, Solver>::
1191 std::size_t
const expected_npoints
1193 if (n_interp_points != expected_npoints) {
1194 throw std::runtime_error(
1195 "Incorrect number of points supplied to NonUniformInterpolationPoints. "
1197 + std::to_string(n_interp_points)
1198 +
", expected : " + std::to_string(expected_npoints));
1200 int n_points_in_cell = 0;
1201 auto current_cell_end_idx =
ddc::discrete_space<BSplines>().break_point_domain().front() + 1;
1203 ddc::Coordinate<continuous_dimension_type>
const point =
ddc::coordinate(idx);
1204 if (point >
ddc::coordinate(current_cell_end_idx)) {
1206 check_n_points_in_cell(n_points_in_cell, current_cell_end_idx);
1208 n_points_in_cell = 1;
1210 current_cell_end_idx += 1;
1211 }
else if (point ==
ddc::coordinate(current_cell_end_idx)) {
1213 check_n_points_in_cell(n_points_in_cell + 1, current_cell_end_idx);
1215 n_points_in_cell = 1;
1217 current_cell_end_idx += 1;
1220 n_points_in_cell += 1;
1224 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.
static auto get_sampling()
Get the UniformPointSampling defining 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.
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.
static constexpr int s_nbe_xmax
The number of equations defining the boundary condition at the upper bound.
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.
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 int s_nbv_xmax
The number of input values defining the boundary condition at the upper bound.
static constexpr bool s_odd
Indicates if the degree of the splines is odd or even.
static constexpr int s_nbv_xmin
The number of input values defining the boundary condition at the lower bound.
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.
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.
static constexpr int s_nbe_xmin
The number of equations defining the boundary condition at the lower bound.
The top-level namespace of DDC.
constexpr int n_boundary_equations(ddc::BoundCond const bc, std::size_t const degree)
Return the number of equations needed to describe a given boundary condition.
constexpr bool is_uniform_bsplines_v
Indicates if a tag corresponds to uniform B-splines or not.
BoundCond
An enum representing a spline boundary condition.
@ HOMOGENEOUS_HERMITE
Homogeneous Hermite boundary condition (derivatives are 0)
@ 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)
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 bool is_non_uniform_bsplines_v
Indicates if a tag corresponds to non-uniform B-splines or not.
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.