Gyselalib++
 
Loading...
Searching...
No Matches
polar_spline_evaluator.hpp
1#pragma once
2
3#include <sll/polar_spline.hpp>
4#include <sll/view.hpp>
5
11template <class PolarBSplinesType, class OuterExtrapolationRule, class MemSpace>
13{
14private:
15 // Tags to determine what to evaluate
19 struct eval_type
20 {
21 };
22
27 struct eval_deriv_r_type
28 {
29 };
30
35 struct eval_deriv_theta_type
36 {
37 };
38
42 struct eval_deriv_r_theta_type
43 {
44 };
45
46public:
50 using bsplines_type = PolarBSplinesType;
54 using BSplinesR = typename PolarBSplinesType::BSplinesR_tag;
58 using BSplinesTheta = typename PolarBSplinesType::BSplinesTheta_tag;
62 using DimR = typename BSplinesR::continuous_dimension_type;
66 using DimTheta = typename BSplinesTheta::continuous_dimension_type;
67
68public:
73 static int constexpr continuity = PolarBSplinesType::continuity;
74
75private:
76 OuterExtrapolationRule m_outer_bc;
77
78public:
79 PolarSplineEvaluator() = delete;
80
92 explicit PolarSplineEvaluator(OuterExtrapolationRule const& outer_bc) : m_outer_bc(outer_bc) {}
93
101
109
110 ~PolarSplineEvaluator() = default;
111
121
131
143 ddc::Coordinate<DimR, DimTheta> coord_eval,
144 PolarSplineView<PolarBSplinesType, MemSpace> const spline_coef) const
145 {
146 return eval(coord_eval, spline_coef);
147 }
148
159 template <class Domain>
161 ddc::ChunkSpan<double, Domain, Kokkos::layout_right, MemSpace> const spline_eval,
162 ddc::ChunkSpan<
163 ddc::Coordinate<DimR, DimTheta> const,
164 Domain,
165 Kokkos::layout_right,
166 MemSpace> const coords_eval,
167 PolarSplineView<PolarBSplinesType, MemSpace> const spline_coef) const
168 {
169 ddc::for_each(coords_eval.domain(), [=](auto i) {
170 spline_eval(i) = eval(coords_eval(i), spline_coef);
171 });
172 }
173
187 ddc::Coordinate<DimR, DimTheta> coord_eval,
188 PolarSplineView<PolarBSplinesType, MemSpace> const spline_coef) const
189 {
190 return eval_no_bc(coord_eval, spline_coef, eval_deriv_r_type());
191 }
192
206 ddc::Coordinate<DimR, DimTheta> coord_eval,
207 PolarSplineView<PolarBSplinesType, MemSpace> const spline_coef) const
208 {
209 return eval_no_bc(coord_eval, spline_coef, eval_deriv_theta_type());
210 }
211
212
225 ddc::Coordinate<DimR, DimTheta> coord_eval,
226 PolarSplineView<PolarBSplinesType, MemSpace> const spline_coef) const
227 {
228 return eval_no_bc(coord_eval, spline_coef, eval_deriv_r_theta_type());
229 }
230
242 template <class Domain>
244 ddc::ChunkSpan<double, Domain> const spline_eval,
245 ddc::ChunkSpan<ddc::Coordinate<DimR, DimTheta> const, Domain> const coords_eval,
246 PolarSplineView<PolarBSplinesType, MemSpace> const spline_coef) const
247 {
248 ddc::for_each(coords_eval.domain(), [=](auto i) {
249 spline_eval(i) = eval_no_bc(coords_eval(i), spline_coef, eval_deriv_r_type());
250 });
251 }
252
264 template <class Domain>
266 ddc::ChunkSpan<double, Domain> const spline_eval,
267 ddc::ChunkSpan<ddc::Coordinate<DimR, DimTheta> const, Domain> const coords_eval,
268 PolarSplineView<PolarBSplinesType, MemSpace> const spline_coef) const
269 {
270 ddc::for_each(coords_eval.domain(), [=](auto i) {
271 spline_eval(i) = eval_no_bc(coords_eval(i), spline_coef, eval_deriv_theta_type());
272 });
273 }
274
285 template <class Domain>
287 ddc::ChunkSpan<double, Domain> const spline_eval,
288 ddc::ChunkSpan<ddc::Coordinate<DimR, DimTheta> const, Domain> const coords_eval,
289 PolarSplineView<PolarBSplinesType, MemSpace> const spline_coef) const
290 {
291 ddc::for_each(coords_eval.domain(), [=](auto i) {
292 spline_eval(i) = eval_no_bc(coords_eval(i), spline_coef, eval_deriv_r_theta_type());
293 });
294 }
295
306 template <class Mapping>
307 double integrate(
309 Mapping const mapping) const
310 {
311 int constexpr nr = ddc::discrete_space<BSplinesR>().ncells() + BSplinesR::degree() - 2;
312 int constexpr ntheta
313 = ddc::discrete_space<BSplinesTheta>().ncells() + BSplinesTheta::degree();
314 std::array<double, PolarBSplinesType::eval_size()> singular_values;
315 DSpan1D singular_vals(singular_values.data(), PolarBSplinesType::n_singular_basis());
316 std::array<double, nr * ntheta> values;
317 DSpan2D vals(values.data(), nr, ntheta);
318
319 ddc::discrete_space<PolarBSplinesType>().integrals(singular_vals, vals);
320
321 double y = 0.;
322 ddc::for_each(
323 spline_coef.singular_spline_coef.domain(),
324 [=](ddc::DiscreteElement<PolarBSplinesType> const i) {
325 y += spline_coef.singular_spline_coef(i) * singular_vals(i)
326 * mapping.determinant(i);
327 });
328 ddc::for_each(
329 spline_coef.spline_coef.domain(),
330 [=](ddc::DiscreteElement<BSplinesR, BSplinesTheta> const i) {
331 y += spline_coef.spline_coef(i)
332 * vals(ddc::select<BSplinesR>(i), ddc::select<BSplinesTheta>(i))
333 * mapping.determinant(i);
334 });
335 return y;
336 }
337
338private:
339 double eval(
340 ddc::Coordinate<DimR, DimTheta> coord_eval,
341 PolarSplineView<PolarBSplinesType, MemSpace> const spline_coef) const
342 {
343 const double coord_eval1 = ddc::get<DimR>(coord_eval);
344 double coord_eval2 = ddc::get<DimTheta>(coord_eval);
345 if (coord_eval1 > ddc::discrete_space<BSplinesR>().rmax()) {
346 return m_outer_bc(coord_eval, spline_coef);
347 }
348 if (coord_eval2 < ddc::discrete_space<BSplinesTheta>().rmin()
349 || coord_eval2 > ddc::discrete_space<BSplinesTheta>().rmax()) {
350 coord_eval2 -= std::floor(
351 (coord_eval2 - ddc::discrete_space<BSplinesTheta>().rmin())
352 / ddc::discrete_space<BSplinesTheta>().length())
353 * ddc::discrete_space<BSplinesTheta>().length();
354 }
355 return eval_no_bc(coord_eval, spline_coef, eval_type());
356 }
357
358 template <class EvalType>
359 double eval_no_bc(
360 ddc::Coordinate<DimR, DimTheta> coord_eval,
362 EvalType const) const
363 {
364 static_assert(
365 std::is_same_v<
366 EvalType,
367 eval_type> || std::is_same_v<EvalType, eval_deriv_r_type> || std::is_same_v<EvalType, eval_deriv_theta_type> || std::is_same_v<EvalType, eval_deriv_r_theta_type>);
368
369 std::array<double, PolarBSplinesType::n_singular_basis()> singular_data;
370 DSpan1D singular_vals(singular_data.data(), PolarBSplinesType::n_singular_basis());
371 std::array<double, (BSplinesR::degree() + 1) * (BSplinesTheta::degree() + 1)> data;
372 DSpan2D vals(data.data(), BSplinesR::degree() + 1, BSplinesTheta::degree() + 1);
373
374 ddc::DiscreteElement<BSplinesR, BSplinesTheta> jmin;
375
376 if constexpr (std::is_same_v<EvalType, eval_type>) {
377 jmin = ddc::discrete_space<PolarBSplinesType>()
378 .eval_basis(singular_vals, vals, coord_eval);
379 } else if constexpr (std::is_same_v<EvalType, eval_deriv_r_type>) {
380 jmin = ddc::discrete_space<PolarBSplinesType>()
381 .eval_deriv_r(singular_vals, vals, coord_eval);
382 } else if constexpr (std::is_same_v<EvalType, eval_deriv_theta_type>) {
383 jmin = ddc::discrete_space<PolarBSplinesType>()
384 .eval_deriv_theta(singular_vals, vals, coord_eval);
385 } else if constexpr (std::is_same_v<EvalType, eval_deriv_r_theta_type>) {
386 jmin = ddc::discrete_space<PolarBSplinesType>()
387 .eval_deriv_r_and_theta(singular_vals, vals, coord_eval);
388 }
389
390 double y = 0.0;
391 for (std::size_t i = 0; i < PolarBSplinesType::n_singular_basis(); ++i) {
392 y += spline_coef.singular_spline_coef(ddc::DiscreteElement<PolarBSplinesType>(i))
393 * singular_vals(i);
394 }
395 ddc::DiscreteElement<BSplinesR> jmin_r = ddc::select<BSplinesR>(jmin);
396 ddc::DiscreteElement<BSplinesTheta> jmin_theta = ddc::select<BSplinesTheta>(jmin);
397 int nr = BSplinesR::degree() + 1;
398 if (jmin_r.uid() < continuity + 1) {
399 nr = nr - (continuity + 1 - jmin_r.uid());
400 jmin_r = ddc::DiscreteElement<BSplinesR>(continuity + 1);
401 }
402 for (int i = 0; i < nr; ++i) {
403 for (std::size_t j = 0; j < BSplinesTheta::degree() + 1; ++j) {
404 y += spline_coef.spline_coef(jmin_r + i, jmin_theta + j) * vals(i, j);
405 }
406 }
407 return y;
408 }
409};
Define an evaluator on polar B-splines.
Definition polar_spline_evaluator.hpp:13
void deriv_dim_1(ddc::ChunkSpan< double, Domain > const spline_eval, ddc::ChunkSpan< ddc::Coordinate< DimR, DimTheta > const, Domain > const coords_eval, PolarSplineView< PolarBSplinesType, MemSpace > const spline_coef) const
Get the values of the derivative of the spline function on the first dimension.
Definition polar_spline_evaluator.hpp:243
PolarBSplinesType bsplines_type
Tag the type of B-splines.
Definition polar_spline_evaluator.hpp:50
double integrate(PolarSplineView< PolarBSplinesType, MemSpace > const spline_coef, Mapping const mapping) const
Get the in integral of a spline function over the domain.
Definition polar_spline_evaluator.hpp:307
double deriv_dim_1(ddc::Coordinate< DimR, DimTheta > coord_eval, PolarSplineView< PolarBSplinesType, MemSpace > const spline_coef) const
Get the value of the derivative of the spline function on the first dimension.
Definition polar_spline_evaluator.hpp:186
void deriv_dim_1_and_2(ddc::ChunkSpan< double, Domain > const spline_eval, ddc::ChunkSpan< ddc::Coordinate< DimR, DimTheta > const, Domain > const coords_eval, PolarSplineView< PolarBSplinesType, MemSpace > const spline_coef) const
Get the values of the cross derivative of the spline function.
Definition polar_spline_evaluator.hpp:286
PolarSplineEvaluator & operator=(PolarSplineEvaluator &&x)=default
Assign a PolarSplineEvaluator from another temporary.
typename BSplinesR::continuous_dimension_type DimR
Tag the first dimension of the space.
Definition polar_spline_evaluator.hpp:62
void operator()(ddc::ChunkSpan< double, Domain, Kokkos::layout_right, MemSpace > const spline_eval, ddc::ChunkSpan< ddc::Coordinate< DimR, DimTheta > const, Domain, Kokkos::layout_right, MemSpace > const coords_eval, PolarSplineView< PolarBSplinesType, MemSpace > const spline_coef) const
Get the values of the spline function on a domain.
Definition polar_spline_evaluator.hpp:160
double deriv_dim_2(ddc::Coordinate< DimR, DimTheta > coord_eval, PolarSplineView< PolarBSplinesType, MemSpace > const spline_coef) const
Get the value of the derivative of the spline function on the second dimension.
Definition polar_spline_evaluator.hpp:205
PolarSplineEvaluator & operator=(PolarSplineEvaluator const &x)=default
Assign a PolarSplineEvaluator from another.
void deriv_dim_2(ddc::ChunkSpan< double, Domain > const spline_eval, ddc::ChunkSpan< ddc::Coordinate< DimR, DimTheta > const, Domain > const coords_eval, PolarSplineView< PolarBSplinesType, MemSpace > const spline_coef) const
Get the values of the derivative of the spline function on the second dimension.
Definition polar_spline_evaluator.hpp:265
PolarSplineEvaluator(OuterExtrapolationRule const &outer_bc)
Instantiate a PolarSplineEvaluator with boundary evaluation conditions.
Definition polar_spline_evaluator.hpp:92
double operator()(ddc::Coordinate< DimR, DimTheta > coord_eval, PolarSplineView< PolarBSplinesType, MemSpace > const spline_coef) const
Get the value of the spline function at a given coordinate.
Definition polar_spline_evaluator.hpp:142
typename BSplinesTheta::continuous_dimension_type DimTheta
Tag the second dimension of the space.
Definition polar_spline_evaluator.hpp:66
PolarSplineEvaluator(PolarSplineEvaluator &&x)=default
Instantiate a PolarSplineEvaluator from another temporary.
double deriv_1_and_2(ddc::Coordinate< DimR, DimTheta > coord_eval, PolarSplineView< PolarBSplinesType, MemSpace > const spline_coef) const
Get the value of the cross derivative of the spline function.
Definition polar_spline_evaluator.hpp:224
PolarSplineEvaluator(PolarSplineEvaluator const &x)=default
Instantiate a PolarSplineEvaluator from another.
static int constexpr continuity
Tag the order of continuity of the B-splines basis at the O-point.
Definition polar_spline_evaluator.hpp:73
Definition geometry.hpp:93
Definition geometry.hpp:100
A structure containing the two ChunkViews necessary to define a constant reference to a spline on a s...
Definition polar_spline.hpp:183
ddc::ChunkSpan< double const, ddc::DiscreteDomain< PolarBSplinesType >, Kokkos::layout_right, MemSpace > const singular_spline_coef
A ChunkView containing the coefficients in front of the b-spline elements near the singular point whi...
Definition polar_spline.hpp:209
ddc::ChunkSpan< double const, ddc::DiscreteDomain< BSplinesR, BSplinesTheta >, Kokkos::layout_right, MemSpace > const spline_coef
A ChunkView containing the coefficients in front of the b-spline elements which can be expressed as a...
Definition polar_spline.hpp:199