13#include <Kokkos_Macros.hpp>
14#include <Kokkos_MathematicalFunctions.hpp>
16#include "integrals.hpp"
17#include "periodic_extrapolation_rule.hpp"
22
23
24
25
26
27
28
29
30
31
32
38 class LowerExtrapolationRule,
39 class UpperExtrapolationRule>
44
45
51
52
53 struct eval_deriv_type
59 using exec_space = ExecSpace;
62 using memory_space = MemorySpace;
65 using continuous_dimension_type =
typename BSplines::continuous_dimension_type;
68 using evaluation_discrete_dimension_type = EvaluationDDim;
71 using bsplines_type = BSplines;
74 using evaluation_domain_type =
ddc::
DiscreteDomain<evaluation_discrete_dimension_type>;
77
78
79
80
82 class BatchedInterpolationDDom,
83 class = std::enable_if_t<
ddc::is_discrete_domain_v<BatchedInterpolationDDom>>>
84 using batched_evaluation_domain_type = BatchedInterpolationDDom;
90
91
92
93
94
96 class BatchedInterpolationDDom,
97 class = std::enable_if_t<
ddc::is_discrete_domain_v<BatchedInterpolationDDom>>>
98 using batch_domain_type
99 =
ddc::remove_dims_of_t<BatchedInterpolationDDom, evaluation_discrete_dimension_type>;
102
103
104
105
106
108 class BatchedInterpolationDDom,
109 class = std::enable_if_t<
ddc::is_discrete_domain_v<BatchedInterpolationDDom>>>
110 using batched_spline_domain_type =
ddc::replace_dim_of_t<
111 BatchedInterpolationDDom,
112 evaluation_discrete_dimension_type,
116 using lower_extrapolation_rule_type = LowerExtrapolationRule;
119 using upper_extrapolation_rule_type = UpperExtrapolationRule;
123 LowerExtrapolationRule m_lower_extrap_rule;
125 UpperExtrapolationRule m_upper_extrap_rule;
129 std::is_same_v<LowerExtrapolationRule,
131 == bsplines_type::is_periodic()
133 UpperExtrapolationRule,
135 == bsplines_type::is_periodic(),
136 "PeriodicExtrapolationRule has to be used if and only if dimension is periodic");
138 std::is_invocable_r_v<
140 LowerExtrapolationRule,
141 ddc::Coordinate<continuous_dimension_type>,
145 Kokkos::layout_right,
147 "LowerExtrapolationRule::operator() has to be callable with usual arguments.");
149 std::is_invocable_r_v<
151 UpperExtrapolationRule,
152 ddc::Coordinate<continuous_dimension_type>,
156 Kokkos::layout_right,
158 "UpperExtrapolationRule::operator() has to be callable with usual arguments.");
161
162
163
164
165
166
167
169 LowerExtrapolationRule
const& lower_extrap_rule,
170 UpperExtrapolationRule
const& upper_extrap_rule)
171 : m_lower_extrap_rule(lower_extrap_rule)
172 , m_upper_extrap_rule(upper_extrap_rule)
177
178
179
180
184
185
186
187
194
195
196
197
198
202
203
204
205
206
210
211
212
213
214
215
216
217
220 return m_lower_extrap_rule;
224
225
226
227
228
229
230
231
234 return m_upper_extrap_rule;
238
239
240
241
242
243
244
245
246
247
248
249 template <
class Layout,
class... CoordsDims>
251 ddc::Coordinate<CoordsDims...>
const& coord_eval,
252 ddc::
ChunkSpan<
double const, spline_domain_type, Layout, memory_space>
const
255 return eval(coord_eval, spline_coef);
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
282 class BatchedInterpolationDDom,
285 ddc::
ChunkSpan<
double, BatchedInterpolationDDom, Layout1, memory_space>
const
288 ddc::Coordinate<CoordsDims...>
const,
289 BatchedInterpolationDDom,
291 memory_space>
const coords_eval,
294 batched_spline_domain_type<BatchedInterpolationDDom>,
296 memory_space>
const spline_coef)
const
298 evaluation_domain_type
const evaluation_domain(spline_eval.domain());
299 batch_domain_type<BatchedInterpolationDDom>
const batch_domain(spline_eval.domain());
301 ddc::parallel_for_each(
302 "ddc_splines_evaluate",
306 typename batch_domain_type<
307 BatchedInterpolationDDom>::discrete_element_type
const j) {
308 const auto spline_eval_1D = spline_eval[j];
309 const auto coords_eval_1D = coords_eval[j];
310 const auto spline_coef_1D = spline_coef[j];
311 for (
auto const i : evaluation_domain) {
312 spline_eval_1D(i) = eval(coords_eval_1D(i), spline_coef_1D);
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335 template <
class Layout1,
class Layout2,
class BatchedInterpolationDDom>
337 ddc::
ChunkSpan<
double, BatchedInterpolationDDom, Layout1, memory_space>
const
341 batched_spline_domain_type<BatchedInterpolationDDom>,
343 memory_space>
const spline_coef)
const
345 evaluation_domain_type
const evaluation_domain(spline_eval.domain());
346 batch_domain_type<BatchedInterpolationDDom>
const batch_domain(spline_eval.domain());
348 ddc::parallel_for_each(
349 "ddc_splines_evaluate",
353 typename batch_domain_type<
354 BatchedInterpolationDDom>::discrete_element_type
const j) {
355 const auto spline_eval_1D = spline_eval[j];
356 const auto spline_coef_1D = spline_coef[j];
357 for (
auto const i : evaluation_domain) {
358 ddc::Coordinate<continuous_dimension_type> coord_eval_1D
359 =
ddc::coordinate(i);
360 spline_eval_1D(i) = eval(coord_eval_1D, spline_coef_1D);
366
367
368
369
370
371
372
373
374
375
376 template <
class Layout,
class... CoordsDims>
378 ddc::Coordinate<CoordsDims...>
const& coord_eval,
379 ddc::
ChunkSpan<
double const, spline_domain_type, Layout, memory_space>
const
382 return eval_no_bc<eval_deriv_type>(coord_eval, spline_coef);
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
407 class BatchedInterpolationDDom,
410 ddc::
ChunkSpan<
double, BatchedInterpolationDDom, Layout1, memory_space>
const
413 ddc::Coordinate<CoordsDims...>
const,
414 BatchedInterpolationDDom,
416 memory_space>
const coords_eval,
419 batched_spline_domain_type<BatchedInterpolationDDom>,
421 memory_space>
const spline_coef)
const
423 evaluation_domain_type
const evaluation_domain(spline_eval.domain());
424 batch_domain_type<BatchedInterpolationDDom>
const batch_domain(spline_eval.domain());
426 ddc::parallel_for_each(
427 "ddc_splines_differentiate",
431 typename batch_domain_type<
432 BatchedInterpolationDDom>::discrete_element_type
const j) {
433 const auto spline_eval_1D = spline_eval[j];
434 const auto coords_eval_1D = coords_eval[j];
435 const auto spline_coef_1D = spline_coef[j];
436 for (
auto const i : evaluation_domain) {
438 = eval_no_bc<eval_deriv_type>(coords_eval_1D(i), spline_coef_1D);
444
445
446
447
448
449
450
451
452
453
454
455
456
457 template <
class Layout1,
class Layout2,
class BatchedInterpolationDDom>
459 ddc::
ChunkSpan<
double, BatchedInterpolationDDom, Layout1, memory_space>
const
463 batched_spline_domain_type<BatchedInterpolationDDom>,
465 memory_space>
const spline_coef)
const
467 evaluation_domain_type
const evaluation_domain(spline_eval.domain());
468 batch_domain_type<BatchedInterpolationDDom>
const batch_domain(spline_eval.domain());
470 ddc::parallel_for_each(
471 "ddc_splines_differentiate",
475 typename batch_domain_type<
476 BatchedInterpolationDDom>::discrete_element_type
const j) {
477 const auto spline_eval_1D = spline_eval[j];
478 const auto spline_coef_1D = spline_coef[j];
479 for (
auto const i : evaluation_domain) {
480 ddc::Coordinate<continuous_dimension_type> coord_eval_1D
481 =
ddc::coordinate(i);
483 = eval_no_bc<eval_deriv_type>(coord_eval_1D, spline_coef_1D);
489
490
491
492
493
494
495
496
497
498
499
500
501 template <
class Layout1,
class Layout2,
class BatchedDDom,
class BatchedSplineDDom>
503 ddc::
ChunkSpan<
double, BatchedDDom, Layout1, memory_space>
const integrals,
504 ddc::
ChunkSpan<
double const, BatchedSplineDDom, Layout2, memory_space>
const
508 ddc::in_tags_v<bsplines_type, to_type_seq_t<BatchedSplineDDom>>,
509 "The spline coefficients domain must contain the bsplines dimension");
510 using batch_domain_type =
ddc::remove_dims_of_t<BatchedSplineDDom, bsplines_type>;
512 std::is_same_v<batch_domain_type, BatchedDDom>,
513 "The integrals domain must only contain the batch dimensions");
515 BatchedDDom
const batch_domain(integrals.domain());
520 ddc::integrals(exec_space(), values);
522 ddc::parallel_for_each(
523 "ddc_splines_integrate",
526 KOKKOS_LAMBDA(
typename BatchedDDom::discrete_element_type
const j) {
528 for (
typename spline_domain_type::discrete_element_type
const i :
530 integrals(j) += spline_coef(i, j) * values(i);
536 template <
class Layout,
class... CoordsDims>
537 KOKKOS_INLINE_FUNCTION
double eval(
538 ddc::Coordinate<CoordsDims...>
const& coord_eval,
539 ddc::
ChunkSpan<
double const, spline_domain_type, Layout, memory_space>
const
542 ddc::Coordinate<continuous_dimension_type> coord_eval_interest(coord_eval);
543 if constexpr (bsplines_type::is_periodic()) {
544 if (coord_eval_interest <
ddc::discrete_space<bsplines_type>().rmin()
545 || coord_eval_interest >
ddc::discrete_space<bsplines_type>().rmax()) {
546 coord_eval_interest -= Kokkos::floor(
548 -
ddc::discrete_space<bsplines_type>().rmin())
549 /
ddc::discrete_space<bsplines_type>().length())
550 *
ddc::discrete_space<bsplines_type>().length();
553 if (coord_eval_interest <
ddc::discrete_space<bsplines_type>().rmin()) {
554 return m_lower_extrap_rule(coord_eval_interest, spline_coef);
556 if (coord_eval_interest >
ddc::discrete_space<bsplines_type>().rmax()) {
557 return m_upper_extrap_rule(coord_eval_interest, spline_coef);
560 return eval_no_bc<eval_type>(coord_eval_interest, spline_coef);
563 template <
class EvalType,
class Layout,
class... CoordsDims>
564 KOKKOS_INLINE_FUNCTION
double eval_no_bc(
565 ddc::Coordinate<CoordsDims...>
const& coord_eval,
566 ddc::
ChunkSpan<
double const, spline_domain_type, Layout, memory_space>
const
570 std::is_same_v<EvalType, eval_type> || std::is_same_v<EvalType, eval_deriv_type>);
571 ddc::DiscreteElement<bsplines_type> jmin;
572 std::array<
double, bsplines_type::degree() + 1> vals_ptr;
573 Kokkos::mdspan<
double, Kokkos::extents<std::size_t, bsplines_type::degree() + 1>>
const
574 vals(vals_ptr.data());
575 ddc::Coordinate<continuous_dimension_type>
const coord_eval_interest(coord_eval);
576 if constexpr (std::is_same_v<EvalType, eval_type>) {
577 jmin =
ddc::discrete_space<bsplines_type>().eval_basis(vals, coord_eval_interest);
578 }
else if constexpr (std::is_same_v<EvalType, eval_deriv_type>) {
579 jmin =
ddc::discrete_space<bsplines_type>().eval_deriv(vals, coord_eval_interest);
582 for (std::size_t i = 0; i < bsplines_type::degree() + 1; ++i) {
583 y += spline_coef(
ddc::DiscreteElement<bsplines_type>(jmin + i)) * vals[i];
friend class DiscreteDomain
A class to evaluate, differentiate or integrate a spline function.
void operator()(ddc::ChunkSpan< double, BatchedInterpolationDDom, Layout1, memory_space > const spline_eval, ddc::ChunkSpan< ddc::Coordinate< CoordsDims... > const, BatchedInterpolationDDom, Layout2, memory_space > const coords_eval, ddc::ChunkSpan< double const, batched_spline_domain_type< BatchedInterpolationDDom >, Layout3, memory_space > const spline_coef) const
Evaluate spline function (described by its spline coefficients) on a mesh.
upper_extrapolation_rule_type upper_extrapolation_rule() const
Get the upper extrapolation rule.
SplineEvaluator & operator=(SplineEvaluator const &x)=default
Copy-assigns.
SplineEvaluator & operator=(SplineEvaluator &&x)=default
Move-assigns.
SplineEvaluator(LowerExtrapolationRule const &lower_extrap_rule, UpperExtrapolationRule const &upper_extrap_rule)
Build a SplineEvaluator acting on batched_spline_domain.
lower_extrapolation_rule_type lower_extrapolation_rule() const
Get the lower extrapolation rule.
KOKKOS_FUNCTION double deriv(ddc::Coordinate< CoordsDims... > const &coord_eval, ddc::ChunkSpan< double const, spline_domain_type, Layout, memory_space > const spline_coef) const
Differentiate 1D spline function (described by its spline coefficients) at a given coordinate.
void deriv(ddc::ChunkSpan< double, BatchedInterpolationDDom, Layout1, memory_space > const spline_eval, ddc::ChunkSpan< double const, batched_spline_domain_type< BatchedInterpolationDDom >, Layout2, memory_space > const spline_coef) const
Differentiate spline function (described by its spline coefficients) on a mesh.
KOKKOS_FUNCTION double operator()(ddc::Coordinate< CoordsDims... > const &coord_eval, ddc::ChunkSpan< double const, spline_domain_type, Layout, memory_space > const spline_coef) const
Evaluate 1D spline function (described by its spline coefficients) at a given coordinate.
SplineEvaluator(SplineEvaluator const &x)=default
Copy-constructs.
SplineEvaluator(SplineEvaluator &&x)=default
Move-constructs.
void integrate(ddc::ChunkSpan< double, BatchedDDom, Layout1, memory_space > const integrals, ddc::ChunkSpan< double const, BatchedSplineDDom, Layout2, memory_space > const spline_coef) const
Perform batched 1D integrations of a spline function (described by its spline coefficients) along the...
void operator()(ddc::ChunkSpan< double, BatchedInterpolationDDom, Layout1, memory_space > const spline_eval, ddc::ChunkSpan< double const, batched_spline_domain_type< BatchedInterpolationDDom >, Layout2, memory_space > const spline_coef) const
Evaluate a spline function (described by its spline coefficients) on a mesh.
void deriv(ddc::ChunkSpan< double, BatchedInterpolationDDom, Layout1, memory_space > const spline_eval, ddc::ChunkSpan< ddc::Coordinate< CoordsDims... > const, BatchedInterpolationDDom, Layout2, memory_space > const coords_eval, ddc::ChunkSpan< double const, batched_spline_domain_type< BatchedInterpolationDDom >, Layout3, memory_space > const spline_coef) const
Differentiate spline function (described by its spline coefficients) on a mesh.
~SplineEvaluator()=default
Destructs.
The top-level namespace of DDC.