17#include <Kokkos_Core.hpp>
20#include "integrals.hpp"
21#include "math_tools.hpp"
22#include "spline_boundary_conditions.hpp"
23#include "splines_linear_problem_maker.hpp"
28
29
30
31
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
58 class InterpolationDDim,
73 using exec_space = ExecSpace;
76 using memory_space = MemorySpace;
79 using continuous_dimension_type =
typename InterpolationDDim::continuous_dimension_type;
82 using interpolation_discrete_dimension_type = InterpolationDDim;
85 using bsplines_type = BSplines;
88 using deriv_type =
ddc::
Deriv<continuous_dimension_type>;
91 using interpolation_domain_type =
ddc::
DiscreteDomain<interpolation_discrete_dimension_type>;
97
98
99
100
101
102
103 using batch_domain_type =
ddc::remove_dims_of_t<
104 batched_interpolation_domain_type,
105 interpolation_discrete_dimension_type>;
108
109
110
111
112
113
114 using batched_spline_domain_type =
ddc::replace_dim_of_t<
115 batched_interpolation_domain_type,
116 interpolation_discrete_dimension_type,
121
122
123
124
125
126
127 using batched_spline_tr_domain_type =
128 typename ddc::detail::convert_type_seq_to_discrete_domain_t<
ddc::type_seq_merge_t<
129 ddc::detail::TypeSeq<bsplines_type>,
130 ddc::type_seq_remove_t<
131 ddc::detail::TypeSeq<DDimX...>,
132 ddc::detail::TypeSeq<interpolation_discrete_dimension_type>>>>;
136
137
138
139
140
141
142 using batched_derivs_domain_type =
ddc::replace_dim_of_t<
143 batched_interpolation_domain_type,
144 interpolation_discrete_dimension_type,
148 static constexpr bool s_odd = BSplines::degree() % 2;
151 static constexpr int s_nbc_xmin = n_boundary_equations(BcLower, BSplines::degree());
154 static constexpr int s_nbc_xmax = n_boundary_equations(BcUpper, BSplines::degree());
166 batched_interpolation_domain_type m_batched_interpolation_domain;
173 std::unique_ptr<
ddc::detail::SplinesLinearProblem<exec_space>> matrix;
176 void compute_offset(interpolation_domain_type
const& interpolation_domain,
int& offset);
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
196 batched_interpolation_domain_type
const& batched_interpolation_domain,
197 std::optional<std::size_t> cols_per_chunk = std::nullopt,
198 std::optional<
unsigned int> preconditioner_max_block_size = std::nullopt)
199 : m_batched_interpolation_domain(batched_interpolation_domain)
200 , m_dx((
ddc::discrete_space<BSplines>().rmax() -
ddc::discrete_space<BSplines>().rmin())
201 /
ddc::discrete_space<BSplines>().ncells())
205 "Incompatible boundary conditions");
211 int lower_block_size;
212 int upper_block_size;
213 if constexpr (bsplines_type::is_uniform()) {
214 upper_block_size = compute_block_sizes_uniform(BcLower,
s_nbc_xmin);
215 lower_block_size = compute_block_sizes_uniform(BcUpper,
s_nbc_xmax);
217 upper_block_size = compute_block_sizes_non_uniform(BcLower,
s_nbc_xmin);
218 lower_block_size = compute_block_sizes_non_uniform(BcUpper,
s_nbc_xmax);
224 preconditioner_max_block_size);
231
232
233
243
244
245
246
250
251
252
253
254
255
258 return interpolation_domain_type(m_batched_interpolation_domain);
262
263
264
265
266
267
268
271 return m_batched_interpolation_domain;
275
276
277
278
279
280
287
288
289
290
291
292
295 return ddc::discrete_space<bsplines_type>().full_domain();
299
300
301
302
303
304
307 return ddc::replace_dim_of<
308 interpolation_discrete_dimension_type,
314
315
316
317
318
319
320 batched_spline_tr_domain_type batched_spline_tr_domain()
const noexcept
322 return batched_spline_tr_domain_type(
ddc::replace_dim_of<bsplines_type, bsplines_type>(
325 ddc::DiscreteElement<bsplines_type>(0),
327 matrix->required_number_of_rhs_rows()))));
332
333
334
335
336
337
340 return ddc::replace_dim_of<interpolation_discrete_dimension_type, deriv_type>(
343 ddc::DiscreteElement<deriv_type>(1),
348
349
350
351
352
353
356 return ddc::replace_dim_of<interpolation_discrete_dimension_type, deriv_type>(
359 ddc::DiscreteElement<deriv_type>(1),
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382 template <
class Layout>
384 ddc::
ChunkSpan<
double, batched_spline_domain_type, Layout, memory_space> spline,
385 ddc::
ChunkSpan<
double const, batched_interpolation_domain_type, Layout, memory_space>
388 ddc::
ChunkSpan<
double const, batched_derivs_domain_type, Layout, memory_space>>
392 ddc::
ChunkSpan<
double const, batched_derivs_domain_type, Layout, memory_space>>
394 = std::nullopt)
const;
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419 template <
class OutMemorySpace = MemorySpace>
438 static int compute_block_sizes_uniform(
ddc::
BoundCond bound_cond,
int nbc);
440 static int compute_block_sizes_non_uniform(
ddc::
BoundCond bound_cond,
int nbc);
442 void allocate_matrix(
443 int lower_block_size,
444 int upper_block_size,
445 std::optional<std::size_t> cols_per_chunk = std::nullopt,
446 std::optional<
unsigned int> preconditioner_max_block_size = std::nullopt);
448 void build_matrix_system();
450 void check_valid_grid();
452 template <
class KnotElement>
453 static void check_n_points_in_cell(
int n_points_in_cell, KnotElement current_cell_end_idx);
460 class InterpolationDDim,
474 compute_offset(interpolation_domain_type
const& interpolation_domain,
int& offset)
476 if constexpr (bsplines_type::is_periodic()) {
478 std::array<
double, bsplines_type::degree() + 1> values_ptr;
479 Kokkos::mdspan<
double, Kokkos::extents<std::size_t, bsplines_type::degree() + 1>>
const
480 values(values_ptr.data());
481 ddc::DiscreteElement<interpolation_discrete_dimension_type> start(
482 interpolation_domain.front());
483 auto jmin =
ddc::discrete_space<BSplines>()
484 .eval_basis(values,
ddc::coordinate(start + BSplines::degree()));
485 if constexpr (bsplines_type::degree() % 2 == 0) {
486 offset = jmin.uid() - start.uid() + bsplines_type::degree() / 2 - BSplines::degree();
488 int const mid = bsplines_type::degree() / 2;
489 offset = jmin.uid() - start.uid()
490 + (DDC_MDSPAN_ACCESS_OP(values, mid) > DDC_MDSPAN_ACCESS_OP(values, mid + 1)
493 - BSplines::degree();
504 class InterpolationDDim,
517 DDimX...>::compute_block_sizes_uniform(
ddc::
BoundCond const bound_cond,
int const nbc)
520 return static_cast<
int>(bsplines_type::degree()) / 2;
528 return static_cast<
int>(bsplines_type::degree()) - 1;
531 throw std::runtime_error(
"ddc::BoundCond not handled");
538 class InterpolationDDim,
551 DDimX...>::compute_block_sizes_non_uniform(
ddc::
BoundCond const bound_cond,
int const nbc)
554 return static_cast<
int>(bsplines_type::degree()) - 1;
561 throw std::runtime_error(
"ddc::BoundCond not handled");
568 class InterpolationDDim,
583 [[maybe_unused]]
int lower_block_size,
584 [[maybe_unused]]
int upper_block_size,
585 std::optional<std::size_t> cols_per_chunk,
586 std::optional<
unsigned int> preconditioner_max_block_size)
596 int upper_band_width;
597 if (bsplines_type::is_uniform()) {
598 upper_band_width = bsplines_type::degree() / 2;
600 upper_band_width = bsplines_type::degree() - 1;
602 if constexpr (bsplines_type::is_periodic()) {
603 matrix =
ddc::detail::SplinesLinearProblemMaker::make_new_periodic_band_matrix<
605 ddc::discrete_space<BSplines>().nbasis(),
608 bsplines_type::is_uniform());
610 matrix =
ddc::detail::SplinesLinearProblemMaker::
611 make_new_block_matrix_with_band_main_block<ExecSpace>(
612 ddc::discrete_space<BSplines>().nbasis(),
615 bsplines_type::is_uniform(),
620 matrix =
ddc::detail::SplinesLinearProblemMaker::make_new_sparse<ExecSpace>(
621 ddc::discrete_space<BSplines>().nbasis(),
623 preconditioner_max_block_size);
626 build_matrix_system();
628 matrix->setup_solver();
635 class InterpolationDDim,
648 DDimX...>::build_matrix_system()
652 std::array<
double, (bsplines_type::degree() / 2 + 1) * (bsplines_type::degree() + 1)>
655 derivs(derivs_ptr.data(),
656 bsplines_type::degree() + 1,
657 bsplines_type::degree() / 2 + 1);
658 ddc::discrete_space<BSplines>().eval_basis_and_n_derivs(
660 ddc::discrete_space<BSplines>().rmin(),
665 for (std::size_t i = 0; i < bsplines_type::degree() + 1; ++i) {
666 for (std::size_t j = 1; j < bsplines_type::degree() / 2 + 1; ++j) {
667 DDC_MDSPAN_ACCESS_OP(derivs, i, j) *=
ddc::detail::ipow(m_dx, j);
672 for (std::size_t i = 0; i <
s_nbc_xmin; ++i) {
673 for (std::size_t j = 0; j < bsplines_type::degree(); ++j) {
677 DDC_MDSPAN_ACCESS_OP(derivs, j, s_nbc_xmin - i - 1 + s_odd));
683 std::array<
double, bsplines_type::degree() + 1> values_ptr;
684 Kokkos::mdspan<
double, Kokkos::extents<std::size_t, bsplines_type::degree() + 1>>
const values(
689 auto jmin =
ddc::discrete_space<BSplines>().eval_basis(
691 ddc::coordinate(
ddc::DiscreteElement<interpolation_discrete_dimension_type>(ix)));
692 for (std::size_t s = 0; s < bsplines_type::degree() + 1; ++s) {
693 int const j =
ddc::detail::
694 modulo(
int(jmin.uid() - m_offset + s),
695 static_cast<
int>(
ddc::discrete_space<BSplines>().nbasis()));
696 matrix->set_element(ix.uid() - start +
s_nbc_xmin, j, DDC_MDSPAN_ACCESS_OP(values, s));
702 std::array<
double, (bsplines_type::degree() / 2 + 1) * (bsplines_type::degree() + 1)>
708 bsplines_type::degree() + 1,
709 bsplines_type::degree() / 2 + 1>>
const derivs(derivs_ptr.data());
711 ddc::discrete_space<BSplines>().eval_basis_and_n_derivs(
713 ddc::discrete_space<BSplines>().rmax(),
718 for (std::size_t i = 0; i < bsplines_type::degree() + 1; ++i) {
719 for (std::size_t j = 1; j < bsplines_type::degree() / 2 + 1; ++j) {
720 DDC_MDSPAN_ACCESS_OP(derivs, i, j) *=
ddc::detail::ipow(m_dx, j);
724 int const i0 =
ddc::discrete_space<BSplines>().nbasis() -
s_nbc_xmax;
725 int const j0 =
ddc::discrete_space<BSplines>().nbasis() - bsplines_type::degree();
726 for (std::size_t j = 0; j < bsplines_type::degree(); ++j) {
727 for (std::size_t i = 0; i <
s_nbc_xmax; ++i) {
728 matrix->set_element(i0 + i, j0 + j, DDC_MDSPAN_ACCESS_OP(derivs, j + 1, i + s_odd));
743template <
class Layout>
754 ddc::
ChunkSpan<
double, batched_spline_domain_type, Layout, memory_space> spline,
755 ddc::
ChunkSpan<
double const, batched_interpolation_domain_type, Layout, memory_space> vals,
758 batched_derivs_domain_type,
760 memory_space>>
const derivs_xmin,
763 batched_derivs_domain_type,
765 memory_space>>
const derivs_xmax)
const
767 assert(vals.
template extent<interpolation_discrete_dimension_type>()
768 == ddc::discrete_space<bsplines_type>().nbasis() - s_nbc_xmin - s_nbc_xmax);
770 assert((BcLower == ddc::BoundCond::HERMITE)
771 != (!derivs_xmin.has_value() || derivs_xmin->
template extent<deriv_type>() == 0));
772 assert((BcUpper == ddc::BoundCond::HERMITE)
773 != (!derivs_xmax.has_value() || derivs_xmax->
template extent<deriv_type>() == 0));
775 assert(ddc::DiscreteElement<deriv_type>(derivs_xmin->domain().front()).uid() == 1);
778 assert(ddc::DiscreteElement<deriv_type>(derivs_xmax->domain().front()).uid() == 1);
785 assert(derivs_xmin->
template extent<deriv_type>() == s_nbc_xmin);
786 auto derivs_xmin_values = *derivs_xmin;
787 auto const dx_proxy = m_dx;
788 ddc::parallel_for_each(
789 "ddc_splines_hermite_compute_lower_coefficients",
792 KOKKOS_LAMBDA(
typename batch_domain_type::discrete_element_type j) {
794 spline(
ddc::DiscreteElement<bsplines_type>(
s_nbc_xmin - i), j)
795 = derivs_xmin_values(
ddc::DiscreteElement<deriv_type>(i), j)
796 *
ddc::detail::ipow(dx_proxy, i +
s_odd - 1);
817 interpolation_discrete_dimension_type>())))]
818 .allocation_kokkos_view(),
819 vals.allocation_kokkos_view());
826 auto const& nbasis_proxy =
ddc::discrete_space<bsplines_type>().nbasis();
828 assert(derivs_xmax->
template extent<deriv_type>() == s_nbc_xmax);
829 auto derivs_xmax_values = *derivs_xmax;
830 auto const dx_proxy = m_dx;
831 ddc::parallel_for_each(
832 "ddc_splines_hermite_compute_upper_coefficients",
835 KOKKOS_LAMBDA(
typename batch_domain_type::discrete_element_type j) {
837 spline(
ddc::DiscreteElement<bsplines_type>(nbasis_proxy -
s_nbc_xmax - i),
839 = derivs_xmax_values(
ddc::DiscreteElement<deriv_type>(i + 1), j)
840 *
ddc::detail::ipow(dx_proxy, i +
s_odd);
846 auto const& offset_proxy = m_offset;
848 batched_spline_tr_domain(),
850 ddc::
ChunkSpan const spline_tr = spline_tr_alloc.span_view();
851 ddc::parallel_for_each(
852 "ddc_splines_transpose_rhs",
855 KOKKOS_LAMBDA(
typename batch_domain_type::discrete_element_type
const j) {
856 for (std::size_t i = 0; i < nbasis_proxy; ++i) {
857 spline_tr(
ddc::DiscreteElement<bsplines_type>(i), j)
858 = spline(
ddc::DiscreteElement<bsplines_type>(i + offset_proxy), j);
862 Kokkos::View<
double**, Kokkos::LayoutRight, exec_space>
const bcoef_section(
863 spline_tr.data_handle(),
864 static_cast<std::size_t>(spline_tr.
template extent<bsplines_type>()),
867 matrix->solve(bcoef_section,
false);
869 ddc::parallel_for_each(
870 "ddc_splines_transpose_back_rhs",
873 KOKKOS_LAMBDA(
typename batch_domain_type::discrete_element_type
const j) {
874 for (std::size_t i = 0; i < nbasis_proxy; ++i) {
875 spline(
ddc::DiscreteElement<bsplines_type>(i + offset_proxy), j)
876 = spline_tr(
ddc::DiscreteElement<bsplines_type>(i), j);
881 if (bsplines_type::is_periodic()) {
882 ddc::parallel_for_each(
883 "ddc_splines_periodic_rows_duplicate_rhs",
886 KOKKOS_LAMBDA(
typename batch_domain_type::discrete_element_type
const j) {
887 if (offset_proxy != 0) {
888 for (
int i = 0; i < offset_proxy; ++i) {
889 spline(
ddc::DiscreteElement<bsplines_type>(i), j) = spline(
890 ddc::DiscreteElement<bsplines_type>(nbasis_proxy + i),
893 for (std::size_t i = offset_proxy; i < bsplines_type::degree(); ++i) {
894 spline(
ddc::DiscreteElement<bsplines_type>(nbasis_proxy + i), j)
895 = spline(
ddc::DiscreteElement<bsplines_type>(i), j);
898 for (std::size_t i(0); i < bsplines_type::degree(); ++i) {
899 const ddc::DiscreteElement<bsplines_type> i_start(i);
900 const ddc::DiscreteElement<bsplines_type> i_end(nbasis_proxy + i);
902 spline(i_end, j) = spline(i_start, j);
917template <
class OutMemorySpace>
945 ddc::integrals(ExecSpace(), integral_bsplines.span_view());
948 ddc::
ChunkSpan const integral_bsplines_without_periodic_additional_bsplines
953 Kokkos::View<
double**, Kokkos::LayoutRight, MemorySpace>
const
954 integral_bsplines_mirror_with_additional_allocation(
955 "integral_bsplines_mirror_with_additional_allocation",
956 matrix->required_number_of_rhs_rows(),
960 Kokkos::View<
double*, Kokkos::LayoutRight, MemorySpace>
const integral_bsplines_mirror
962 subview(integral_bsplines_mirror_with_additional_allocation,
964 pair {
static_cast<std::size_t>(0),
965 integral_bsplines_without_periodic_additional_bsplines
971 integral_bsplines_mirror,
972 integral_bsplines_without_periodic_additional_bsplines.allocation_kokkos_view());
973 matrix->solve(integral_bsplines_mirror_with_additional_allocation,
true);
975 integral_bsplines_without_periodic_additional_bsplines.allocation_kokkos_view(),
976 integral_bsplines_mirror);
980 = integral_bsplines_without_periodic_additional_bsplines[
spline_domain().take_first(
982 ddc::
ChunkSpan const coefficients = integral_bsplines_without_periodic_additional_bsplines
989 = integral_bsplines_without_periodic_additional_bsplines
997 ddc::parallel_for_each(
999 coefficients_derivs_xmin.domain(),
1000 KOKKOS_LAMBDA(
ddc::DiscreteElement<bsplines_type> i) {
1001 ddc::Coordinate<continuous_dimension_type>
const dx
1002 =
ddc::distance_at_right(interpolation_domain_proxy.front() + 1);
1003 coefficients_derivs_xmin(i) *=
ddc::detail::
1005 static_cast<std::size_t>(get<bsplines_type>(
1006 i - coefficients_derivs_xmin.domain().front() + 1)));
1008 ddc::parallel_for_each(
1010 coefficients_derivs_xmax.domain(),
1011 KOKKOS_LAMBDA(
ddc::DiscreteElement<bsplines_type> i) {
1012 ddc::Coordinate<continuous_dimension_type>
const dx
1013 =
ddc::distance_at_left(interpolation_domain_proxy.back() - 1);
1014 coefficients_derivs_xmax(i) *=
ddc::detail::
1016 static_cast<std::size_t>(get<bsplines_type>(
1017 i - coefficients_derivs_xmax.domain().front() + 1)));
1021 ddc::
Chunk coefficients_derivs_xmin_out(
1023 ddc::DiscreteElement<deriv_type>(1),
1029 coefficients.size())),
1031 ddc::
Chunk coefficients_derivs_xmax_out(
1033 ddc::DiscreteElement<deriv_type>(1),
1037 coefficients_derivs_xmin_out.allocation_kokkos_view(),
1038 coefficients_derivs_xmin.allocation_kokkos_view());
1040 coefficients_out.allocation_kokkos_view(),
1041 coefficients.allocation_kokkos_view());
1043 coefficients_derivs_xmax_out.allocation_kokkos_view(),
1044 coefficients_derivs_xmax.allocation_kokkos_view());
1045 return std::make_tuple(
1046 std::move(coefficients_derivs_xmin_out),
1047 std::move(coefficients_out),
1048 std::move(coefficients_derivs_xmax_out));
1060template <
class KnotElement>
1070 check_n_points_in_cell(
int const n_points_in_cell, KnotElement
const current_cell_end_idx)
1072 if (n_points_in_cell > BSplines::degree() + 1) {
1073 KnotElement
const rmin_idx =
ddc::discrete_space<BSplines>().break_point_domain().front();
1074 int const failed_cell = (current_cell_end_idx - rmin_idx).value();
1075 throw std::runtime_error(
1076 "The spline problem is overconstrained. There are "
1077 + std::to_string(n_points_in_cell) +
" points in the " + std::to_string(failed_cell)
1086 class InterpolationDDim,
1099 DDimX...>::check_valid_grid()
1102 std::size_t
const expected_npoints
1104 if (n_interp_points != expected_npoints) {
1105 throw std::runtime_error(
1106 "Incorrect number of points supplied to NonUniformInterpolationPoints. "
1108 + std::to_string(n_interp_points)
1109 +
", expected : " + std::to_string(expected_npoints));
1111 int n_points_in_cell = 0;
1112 auto current_cell_end_idx =
ddc::discrete_space<BSplines>().break_point_domain().front() + 1;
1114 ddc::Coordinate<continuous_dimension_type>
const point =
ddc::coordinate(idx);
1115 if (point >
ddc::coordinate(current_cell_end_idx)) {
1117 check_n_points_in_cell(n_points_in_cell, current_cell_end_idx);
1119 n_points_in_cell = 1;
1121 current_cell_end_idx += 1;
1122 }
else if (point ==
ddc::coordinate(current_cell_end_idx)) {
1124 check_n_points_in_cell(n_points_in_cell + 1, current_cell_end_idx);
1126 n_points_in_cell = 1;
1128 current_cell_end_idx += 1;
1131 n_points_in_cell += 1;
1135 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.
static constexpr ddc::BoundCond s_bc_xmax
The boundary condition implemented at the upper bound.
static constexpr SplineSolver s_spline_solver
The SplineSolver giving the backend used to perform the spline approximation.
ddc::DiscreteDomain< bsplines_type > spline_domain() const noexcept
Get the 1D domain on which spline coefficients are defined.
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.
SplineBuilder(batched_interpolation_domain_type 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 batched_interpolation_domain.
static constexpr int s_nbc_xmin
The number of equations defining the boundary condition at the lower bound.
static constexpr int s_nbc_xmax
The number of equations defining the boundary condition at the upper bound.
SplineBuilder & operator=(SplineBuilder &&x)=default
Move-assigns.
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.
static constexpr bool s_odd
Indicates if the degree of the splines is odd or even.
~SplineBuilder()=default
Destructs.
batched_spline_domain_type batched_spline_domain() const noexcept
Get the whole domain on which spline coefficients are defined.
batched_interpolation_domain_type batched_interpolation_domain() const noexcept
Get the whole domain representing interpolation points.
SplineBuilder & operator=(SplineBuilder const &x)=delete
Copy-assignment is deleted.
static constexpr ddc::BoundCond s_bc_xmin
The boundary condition implemented at the lower bound.
batched_derivs_domain_type batched_derivs_xmax_domain() const noexcept
Get the whole domain on which derivatives on upper boundary are defined.
batch_domain_type batch_domain() const noexcept
Get the batch domain.
batched_derivs_domain_type batched_derivs_xmin_domain() const noexcept
Get the whole domain on which derivatives on lower boundary are defined.
SplineBuilder(SplineBuilder &&x)=default
Move-constructs.
void operator()(ddc::ChunkSpan< double, batched_spline_domain_type, Layout, memory_space > spline, ddc::ChunkSpan< double const, batched_interpolation_domain_type, Layout, memory_space > vals, std::optional< ddc::ChunkSpan< double const, batched_derivs_domain_type, Layout, memory_space > > derivs_xmin=std::nullopt, std::optional< ddc::ChunkSpan< double const, batched_derivs_domain_type, Layout, memory_space > > derivs_xmax=std::nullopt) const
Compute a spline approximation of a function.
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...