DDC 0.0.0

a discrete domain computation library

greville_interpolation_points.hpp
1// Copyright (C) The DDC development team, see COPYRIGHT.md file
2//
3// SPDX-License-Identifier: MIT
4
5#pragma once
6
7#include <cstddef>
8#include <type_traits>
9#include <vector>
10
11#include <ddc/ddc.hpp>
12
13#include "spline_boundary_conditions.hpp"
14
15namespace ddc {
16
24template <class BSplines, ddc::BoundCond BcXmin, ddc::BoundCond BcXmax>
26{
27 using tag_type = typename BSplines::tag_type;
28
29 template <class Sampling>
30 struct IntermediateUniformSampling
31 : UniformPointSampling<typename Sampling::continuous_dimension_type>
32 {
33 };
34
35 template <class Sampling>
36 struct IntermediateNonUniformSampling
37 : NonUniformPointSampling<typename Sampling::continuous_dimension_type>
38 {
39 };
40
41 template <class Sampling, typename U = BSplines, class = std::enable_if_t<U::is_uniform()>>
42 static auto uniform_greville_points()
43 {
44 using SamplingImpl = typename Sampling::template Impl<Sampling, Kokkos::HostSpace>;
45
46 double constexpr shift = (BSplines::degree() % 2 == 0) ? 0.5 : 0.0;
47 double dx
50 return SamplingImpl(
53 }
54
55 template <class Sampling, typename U = BSplines, class = std::enable_if_t<!U::is_uniform()>>
56 static auto non_uniform_greville_points()
57 {
58 using SamplingImpl = typename Sampling::template Impl<Sampling, Kokkos::HostSpace>;
59
61 if constexpr (U::is_periodic()) {
63 }
64
65 std::vector<double> greville_points(n_greville_points);
69
71 // Define the Greville points from the bspline knots
72 greville_points[ib.uid()] = 0.0;
73 for (std::size_t i(0); i < BSplines::degree(); ++i) {
74 greville_points[ib.uid()]
75 += ddc::discrete_space<BSplines>().get_support_knot_n(ib, i + 1);
76 }
77 greville_points[ib.uid()] /= BSplines::degree();
78 });
79
80 std::vector<double> temp_knots(BSplines::degree());
81 // Use periodicity to ensure all points are in the domain
82 if constexpr (U::is_periodic()) {
83 int npoints(0);
84 // Count the number of interpolation points that need shifting to preserve the ordering
86 temp_knots[npoints]
87 = greville_points[npoints] + ddc::discrete_space<BSplines>().length();
88 npoints++;
89 }
90 // Shift the points
91 for (std::size_t i = 0; i < ddc::discrete_space<BSplines>().nbasis() - npoints; ++i) {
92 greville_points[i] = greville_points[i + npoints];
93 }
94 for (int i = 0; i < npoints; ++i) {
95 greville_points[ddc::discrete_space<BSplines>().nbasis() - npoints + i]
96 = temp_knots[i];
97 }
98
99 // Save a periodic point to initialise the domain size
102 }
103
105 }
106
107 static constexpr int N_BE_MIN = n_boundary_equations(BcXmin, BSplines::degree());
108 static constexpr int N_BE_MAX = n_boundary_equations(BcXmax, BSplines::degree());
109 template <class U>
110 static constexpr bool is_uniform_mesh_v
111 = U::is_uniform() && ((N_BE_MIN != 0 && N_BE_MAX != 0) || U::is_periodic());
112
113public:
123 template <
124 class Sampling,
125 typename U = BSplines,
126 std::enable_if_t<
128 bool> = true> // U must be in condition for SFINAE
129 static auto get_sampling()
130 {
132 }
133
139 template <
140 class Sampling,
141 typename U = BSplines,
142 std::enable_if_t<
144 bool> = true> // U must be in condition for SFINAE
145 static auto get_sampling()
146 {
147 using SamplingImpl = typename Sampling::template Impl<Sampling, Kokkos::HostSpace>;
148 if constexpr (U::is_uniform()) {
149 using IntermediateSampling = IntermediateUniformSampling<Sampling>;
151 int const n_break_points = ddc::discrete_space<BSplines>().ncells() + 1;
152 int const npoints = ddc::discrete_space<BSplines>().nbasis() - N_BE_MIN - N_BE_MAX;
153 std::vector<double> points_with_bcs(npoints);
154
155 // Construct Greville-like points at the edge
156 if constexpr (BcXmin == ddc::BoundCond::GREVILLE) {
157 for (std::size_t i(0); i < BSplines::degree() / 2 + 1; ++i) {
159 = (BSplines::degree() - i) * ddc::discrete_space<BSplines>().rmin();
160 for (std::size_t j(0); j < i; ++j) {
161 points_with_bcs[i] += ddc::discrete_space<BSplines>().get_support_knot_n(
163 BSplines::degree() - j);
164 }
165 points_with_bcs[i] /= BSplines::degree();
166 }
167 } else {
170 }
171
172 int const n_start
173 = (BcXmin == ddc::BoundCond::GREVILLE) ? BSplines::degree() / 2 + 1 : 1;
174 int const domain_size = n_break_points - 2;
178
179 // Copy central points
180 ddc::for_each(domain, [&](auto ip) {
181 points_with_bcs[ip.uid() + n_start - 1] = points_wo_bcs.coordinate(ip);
182 });
183
184 // Construct Greville-like points at the edge
185 if constexpr (BcXmax == ddc::BoundCond::GREVILLE) {
186 for (std::size_t i(0); i < BSplines::degree() / 2 + 1; ++i) {
187 points_with_bcs[npoints - 1 - i]
188 = (BSplines::degree() - i) * ddc::discrete_space<BSplines>().rmax();
189 for (std::size_t j(0); j < i; ++j) {
190 points_with_bcs[npoints - 1 - i]
191 += ddc::discrete_space<BSplines>().get_support_knot_n(
193 ddc::discrete_space<BSplines>().nbasis() - 1 - i),
194 j + 1);
195 }
196 points_with_bcs[npoints - 1 - i] /= BSplines::degree();
197 }
198 } else {
199 points_with_bcs[npoints - 1]
201 ddc::discrete_space<BSplines>().ncells() - 1
202 + BSplines::degree() % 2));
203 }
205 } else {
206 using IntermediateSampling = IntermediateNonUniformSampling<Sampling>;
207 if constexpr (N_BE_MIN == 0 && N_BE_MAX == 0) {
209 } else {
211 // All points are Greville points. Extract unnecessary points near the boundary
212 std::vector<double> points_with_bcs(points_wo_bcs.size() - N_BE_MIN - N_BE_MAX);
213 int constexpr n_start = N_BE_MIN;
214
216
219 length(points_with_bcs.size()));
220
221 points_with_bcs[0] = points_wo_bcs.coordinate(domain.front());
222 ddc::for_each(domain.remove(length(1), length(1)), [&](auto ip) {
223 points_with_bcs[ip.uid() - n_start] = points_wo_bcs.coordinate(ip);
224 });
226 = points_wo_bcs.coordinate(domain.back());
227
229 }
230 }
231 }
232
238 using interpolation_mesh_type = std::conditional_t<
242
248 template <class Sampling>
250 {
251 int const npoints = ddc::discrete_space<BSplines>().nbasis() - N_BE_MIN - N_BE_MAX;
255 }
256};
257} // namespace ddc
Definition discrete_domain.hpp:51
KOKKOS_FUNCTION constexpr DiscreteDomain take_first(mlength_type n) const
Definition discrete_domain.hpp:164
KOKKOS_FUNCTION constexpr discrete_element_type front() const noexcept
Definition discrete_domain.hpp:154
KOKKOS_FUNCTION constexpr DiscreteDomain remove(mlength_type n1, mlength_type n2) const
Definition discrete_domain.hpp:184
KOKKOS_FUNCTION constexpr discrete_element_type back() const noexcept
Definition discrete_domain.hpp:159
A DiscreteElement identifies an element of the discrete dimension.
Definition discrete_element.hpp:146
A DiscreteVector is a vector in the discrete dimension.
Definition discrete_vector.hpp:254
A class which provides helper functions to initialise the Greville points from a B-Spline definition.
Definition greville_interpolation_points.hpp:26
static ddc::DiscreteDomain< Sampling > get_domain()
Get the domain which gives us access to all of the Greville points.
Definition greville_interpolation_points.hpp:249
std::conditional_t< is_uniform_mesh_v< BSplines >, ddc::UniformPointSampling< tag_type >, ddc::NonUniformPointSampling< tag_type > > interpolation_mesh_type
The type of the mesh.
Definition greville_interpolation_points.hpp:238
static auto get_sampling()
Get the UniformPointSampling defining the Greville points.
Definition greville_interpolation_points.hpp:129
NonUniformPointSampling models a non-uniform discretization of the CDim segment .
Definition non_uniform_point_sampling.hpp:34
UniformPointSampling models a uniform discretization of the provided continuous dimension.
Definition uniform_point_sampling.hpp:36
The top-level namespace of DDC.
Definition aligned_allocator.hpp:11
constexpr int n_boundary_equations(ddc::BoundCond const bc, std::size_t const degree)
Definition spline_boundary_conditions.hpp:35
constexpr bool enable_chunk
Definition chunk_traits.hpp:16
void for_each(DiscreteDomain< DDims... > const &domain, Functor &&f) noexcept
iterates over a nD domain in serial
Definition for_each.hpp:48
KOKKOS_FUNCTION Coordinate< typename DDim::continuous_dimension_type > rmin(DiscreteDomain< DDim > const &d)
Definition non_uniform_point_sampling.hpp:175
detail::TaggedVector< CoordinateElement, CDims... > Coordinate
A Coordinate represents a coordinate in the continuous space.
Definition coordinate.hpp:26