9 #include <ddc/kernels/splines.hpp>
11 #include "ddc_aliases.hpp"
15 template <
class BSplines, ddc::BoundCond BcXmin, ddc::BoundCond BcXmax>
16 class NonUniformInterpolationPoints;
23 template <
class BSplines, ddc::BoundCond BcXmin, ddc::BoundCond BcXmax>
30 inline constexpr
bool is_non_uniform_interpolation_points_v
42 template <
class BSplines, ddc::BoundCond BcXmin, ddc::BoundCond BcXmax>
45 using Dim =
typename BSplines::continuous_dimension_type;
46 using BreakPointsType = std::conditional_t<
47 BSplines::is_uniform(),
48 ddc::UniformBsplinesKnots<BSplines>,
49 ddc::NonUniformBsplinesKnots<BSplines>>;
50 using IdxBreakPoints = Idx<BreakPointsType>;
54 static constexpr
int N_BE_MIN = n_boundary_equations(BcXmin, BSplines::degree());
56 static constexpr
int N_BE_MAX = n_boundary_equations(BcXmax, BSplines::degree());
59 static void check_n_points_in_cell(
int n_points_in_cell, IdxBreakPoints current_cell_end_idx)
61 if (n_points_in_cell > BSplines::degree() + 1) {
62 IdxBreakPoints rmin_idx = ddc::discrete_space<BSplines>().break_point_domain().front();
63 int failed_cell = (current_cell_end_idx - rmin_idx).value();
64 throw std::runtime_error(
65 "The spline problem is overconstrained. There are "
66 + std::to_string(n_points_in_cell) +
" points in the "
67 + std::to_string(failed_cell) +
"-th cell.");
80 template <
typename Sampling,
typename U = BSplines>
81 static auto get_sampling(std::vector<Coord<Dim>>& interp_points,
double TOL = 2e-14)
83 int const expected_npoints = ddc::discrete_space<BSplines>().nbasis() -
N_BE_MIN -
N_BE_MAX;
84 if (interp_points.size() != expected_npoints) {
85 throw std::runtime_error(
86 "Incorrect number of points supplied to NonUniformInterpolationPoints. "
88 + std::to_string(interp_points.size())
89 +
", expected : " + std::to_string(expected_npoints));
91 if constexpr (BSplines::is_periodic()) {
92 double domain_len = ddc::discrete_space<BSplines>().rmax()
93 - ddc::discrete_space<BSplines>().rmin();
95 interp_points.push_back(interp_points.back() + domain_len);
97 int n_points_in_cell = 0;
98 IdxBreakPoints current_cell_end_idx
99 = ddc::discrete_space<BSplines>().break_point_domain().front() + 1;
100 for (Coord<Dim> point : interp_points) {
101 if (point == ddc::coordinate(current_cell_end_idx)) {
102 check_n_points_in_cell(n_points_in_cell + 1, current_cell_end_idx);
103 n_points_in_cell = 1;
104 }
else if (point > ddc::coordinate(current_cell_end_idx)) {
105 check_n_points_in_cell(n_points_in_cell, current_cell_end_idx);
106 n_points_in_cell = 1;
108 n_points_in_cell += 1;
111 check_n_points_in_cell(n_points_in_cell, current_cell_end_idx);
113 if constexpr (ddc::is_non_uniform_point_sampling_v<Sampling>) {
114 using SamplingImpl =
typename Sampling::template Impl<Sampling, Kokkos::HostSpace>;
115 return SamplingImpl(interp_points);
117 using SamplingImpl =
typename Sampling::template Impl<Sampling, Kokkos::HostSpace>;
118 SamplingImpl result(interp_points[0], interp_points[1] - interp_points[0]);
119 IdxRange<Sampling> idx_range(get_domain<Sampling>());
120 bool same_points = ddc::transform_reduce(
123 ddc::reducer::land<bool>(),
124 [&](Idx<Sampling> idx) {
125 return fabs(result.coordinate(idx) - interp_points[idx - idx_range.front()])
129 throw std::runtime_error(
"Provided points are not uniform");
141 template <
typename Sampling>
144 int const npoints = ddc::discrete_space<BSplines>().nbasis() -
N_BE_MIN -
N_BE_MAX;
145 return IdxRange<Sampling>(Idx<Sampling>(0), IdxStep<Sampling>(npoints));