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
33
39 class LowerExtrapolationRule,
40 class UpperExtrapolationRule,
46
47
53
54
55 struct eval_deriv_type
61 using exec_space = ExecSpace;
64 using memory_space = MemorySpace;
67 using continuous_dimension_type =
typename BSplines::continuous_dimension_type;
70 using evaluation_discrete_dimension_type = EvaluationDDim;
73 using bsplines_type = BSplines;
76 using evaluation_domain_type =
ddc::
DiscreteDomain<evaluation_discrete_dimension_type>;
85
86
87
88 using batch_domain_type =
ddc::
89 remove_dims_of_t<batched_evaluation_domain_type, evaluation_discrete_dimension_type>;
92
93
94
95 using batched_spline_domain_type =
ddc::replace_dim_of_t<
96 batched_evaluation_domain_type,
97 evaluation_discrete_dimension_type,
101 using lower_extrapolation_rule_type = LowerExtrapolationRule;
104 using upper_extrapolation_rule_type = UpperExtrapolationRule;
108 LowerExtrapolationRule m_lower_extrap_rule;
110 UpperExtrapolationRule m_upper_extrap_rule;
114 std::is_same_v<LowerExtrapolationRule,
116 == bsplines_type::is_periodic()
118 UpperExtrapolationRule,
120 == bsplines_type::is_periodic(),
121 "PeriodicExtrapolationRule has to be used if and only if dimension is periodic");
123 std::is_invocable_r_v<
125 LowerExtrapolationRule,
126 ddc::Coordinate<continuous_dimension_type>,
130 Kokkos::layout_right,
132 "LowerExtrapolationRule::operator() has to be callable with usual arguments.");
134 std::is_invocable_r_v<
136 UpperExtrapolationRule,
137 ddc::Coordinate<continuous_dimension_type>,
141 Kokkos::layout_right,
143 "UpperExtrapolationRule::operator() has to be callable with usual arguments.");
146
147
148
149
150
151
152
154 LowerExtrapolationRule
const& lower_extrap_rule,
155 UpperExtrapolationRule
const& upper_extrap_rule)
156 : m_lower_extrap_rule(lower_extrap_rule)
157 , m_upper_extrap_rule(upper_extrap_rule)
162
163
164
165
169
170
171
172
179
180
181
182
183
187
188
189
190
191
195
196
197
198
199
200
201
202
205 return m_lower_extrap_rule;
209
210
211
212
213
214
215
216
219 return m_upper_extrap_rule;
223
224
225
226
227
228
229
230
231
232
233
234 template <
class Layout,
class... CoordsDims>
236 ddc::Coordinate<CoordsDims...>
const& coord_eval,
237 ddc::
ChunkSpan<
double const, spline_domain_type, Layout, memory_space>
const
240 return eval(coord_eval, spline_coef);
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263 template <
class Layout1,
class Layout2,
class Layout3,
class... CoordsDims>
265 ddc::
ChunkSpan<
double, batched_evaluation_domain_type, Layout1, memory_space>
const
268 ddc::Coordinate<CoordsDims...>
const,
269 batched_evaluation_domain_type,
271 memory_space>
const coords_eval,
272 ddc::
ChunkSpan<
double const, batched_spline_domain_type, Layout3, memory_space>
const
275 evaluation_domain_type
const evaluation_domain(spline_eval.domain());
276 batch_domain_type
const batch_domain(spline_eval.domain());
278 ddc::parallel_for_each(
279 "ddc_splines_evaluate",
282 KOKKOS_CLASS_LAMBDA(
typename batch_domain_type::discrete_element_type
const j) {
283 const auto spline_eval_1D = spline_eval[j];
284 const auto coords_eval_1D = coords_eval[j];
285 const auto spline_coef_1D = spline_coef[j];
286 for (
auto const i : evaluation_domain) {
287 spline_eval_1D(i) = eval(coords_eval_1D(i), spline_coef_1D);
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310 template <
class Layout1,
class Layout2>
312 ddc::
ChunkSpan<
double, batched_evaluation_domain_type, Layout1, memory_space>
const
314 ddc::
ChunkSpan<
double const, batched_spline_domain_type, Layout2, memory_space>
const
317 evaluation_domain_type
const evaluation_domain(spline_eval.domain());
318 batch_domain_type
const batch_domain(spline_eval.domain());
320 ddc::parallel_for_each(
321 "ddc_splines_evaluate",
324 KOKKOS_CLASS_LAMBDA(
typename batch_domain_type::discrete_element_type
const j) {
325 const auto spline_eval_1D = spline_eval[j];
326 const auto spline_coef_1D = spline_coef[j];
327 for (
auto const i : evaluation_domain) {
328 ddc::Coordinate<continuous_dimension_type> coord_eval_1D
329 =
ddc::coordinate(i);
330 spline_eval_1D(i) = eval(coord_eval_1D, spline_coef_1D);
336
337
338
339
340
341
342
343
344
345
346 template <
class Layout,
class... CoordsDims>
348 ddc::Coordinate<CoordsDims...>
const& coord_eval,
349 ddc::
ChunkSpan<
double const, spline_domain_type, Layout, memory_space>
const
352 return eval_no_bc<eval_deriv_type>(coord_eval, spline_coef);
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373 template <
class Layout1,
class Layout2,
class Layout3,
class... CoordsDims>
375 ddc::
ChunkSpan<
double, batched_evaluation_domain_type, Layout1, memory_space>
const
378 ddc::Coordinate<CoordsDims...>
const,
379 batched_evaluation_domain_type,
381 memory_space>
const coords_eval,
382 ddc::
ChunkSpan<
double const, batched_spline_domain_type, Layout3, memory_space>
const
385 evaluation_domain_type
const evaluation_domain(spline_eval.domain());
386 batch_domain_type
const batch_domain(spline_eval.domain());
388 ddc::parallel_for_each(
389 "ddc_splines_differentiate",
392 KOKKOS_CLASS_LAMBDA(
typename batch_domain_type::discrete_element_type
const j) {
393 const auto spline_eval_1D = spline_eval[j];
394 const auto coords_eval_1D = coords_eval[j];
395 const auto spline_coef_1D = spline_coef[j];
396 for (
auto const i : evaluation_domain) {
398 = eval_no_bc<eval_deriv_type>(coords_eval_1D(i), spline_coef_1D);
404
405
406
407
408
409
410
411
412
413
414
415
416
417 template <
class Layout1,
class Layout2>
419 ddc::
ChunkSpan<
double, batched_evaluation_domain_type, Layout1, memory_space>
const
421 ddc::
ChunkSpan<
double const, batched_spline_domain_type, Layout2, memory_space>
const
424 evaluation_domain_type
const evaluation_domain(spline_eval.domain());
425 batch_domain_type
const batch_domain(spline_eval.domain());
427 ddc::parallel_for_each(
428 "ddc_splines_differentiate",
431 KOKKOS_CLASS_LAMBDA(
typename batch_domain_type::discrete_element_type
const j) {
432 const auto spline_eval_1D = spline_eval[j];
433 const auto spline_coef_1D = spline_coef[j];
434 for (
auto const i : evaluation_domain) {
435 ddc::Coordinate<continuous_dimension_type> coord_eval_1D
436 =
ddc::coordinate(i);
438 = eval_no_bc<eval_deriv_type>(coord_eval_1D, spline_coef_1D);
444
445
446
447
448
449
450
451
452
453
454
455
456 template <
class Layout1,
class Layout2>
458 ddc::
ChunkSpan<
double, batch_domain_type, Layout1, memory_space>
const integrals,
459 ddc::
ChunkSpan<
double const, batched_spline_domain_type, Layout2, memory_space>
const
462 batch_domain_type
const batch_domain(integrals.domain());
467 ddc::integrals(exec_space(), values);
469 ddc::parallel_for_each(
470 "ddc_splines_integrate",
473 KOKKOS_LAMBDA(
typename batch_domain_type::discrete_element_type
const j) {
475 for (
typename spline_domain_type::discrete_element_type
const i :
477 integrals(j) += spline_coef(i, j) * values(i);
483 template <
class Layout,
class... CoordsDims>
484 KOKKOS_INLINE_FUNCTION
double eval(
485 ddc::Coordinate<CoordsDims...>
const& coord_eval,
486 ddc::
ChunkSpan<
double const, spline_domain_type, Layout, memory_space>
const
489 ddc::Coordinate<continuous_dimension_type> coord_eval_interest(coord_eval);
490 if constexpr (bsplines_type::is_periodic()) {
491 if (coord_eval_interest <
ddc::discrete_space<bsplines_type>().rmin()
492 || coord_eval_interest >
ddc::discrete_space<bsplines_type>().rmax()) {
493 coord_eval_interest -= Kokkos::floor(
495 -
ddc::discrete_space<bsplines_type>().rmin())
496 /
ddc::discrete_space<bsplines_type>().length())
497 *
ddc::discrete_space<bsplines_type>().length();
500 if (coord_eval_interest <
ddc::discrete_space<bsplines_type>().rmin()) {
501 return m_lower_extrap_rule(coord_eval_interest, spline_coef);
503 if (coord_eval_interest >
ddc::discrete_space<bsplines_type>().rmax()) {
504 return m_upper_extrap_rule(coord_eval_interest, spline_coef);
507 return eval_no_bc<eval_type>(coord_eval_interest, spline_coef);
510 template <
class EvalType,
class Layout,
class... CoordsDims>
511 KOKKOS_INLINE_FUNCTION
double eval_no_bc(
512 ddc::Coordinate<CoordsDims...>
const& coord_eval,
513 ddc::
ChunkSpan<
double const, spline_domain_type, Layout, memory_space>
const
517 std::is_same_v<EvalType, eval_type> || std::is_same_v<EvalType, eval_deriv_type>);
518 ddc::DiscreteElement<bsplines_type> jmin;
519 std::array<
double, bsplines_type::degree() + 1> vals_ptr;
520 Kokkos::mdspan<
double, Kokkos::extents<std::size_t, bsplines_type::degree() + 1>>
const
521 vals(vals_ptr.data());
522 ddc::Coordinate<continuous_dimension_type>
const coord_eval_interest(coord_eval);
523 if constexpr (std::is_same_v<EvalType, eval_type>) {
524 jmin =
ddc::discrete_space<bsplines_type>().eval_basis(vals, coord_eval_interest);
525 }
else if constexpr (std::is_same_v<EvalType, eval_deriv_type>) {
526 jmin =
ddc::discrete_space<bsplines_type>().eval_deriv(vals, coord_eval_interest);
529 for (std::size_t i = 0; i < bsplines_type::degree() + 1; ++i) {
530 y += spline_coef(
ddc::DiscreteElement<bsplines_type>(jmin + i)) * vals[i];
friend class DiscreteDomain
A class to evaluate, differentiate or integrate a spline function.
SplineEvaluator & operator=(SplineEvaluator &&x)=default
Move-assigns.
void integrate(ddc::ChunkSpan< double, batch_domain_type, Layout1, memory_space > const integrals, ddc::ChunkSpan< double const, batched_spline_domain_type, 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, batched_evaluation_domain_type, Layout1, memory_space > const spline_eval, ddc::ChunkSpan< ddc::Coordinate< CoordsDims... > const, batched_evaluation_domain_type, Layout2, memory_space > const coords_eval, ddc::ChunkSpan< double const, batched_spline_domain_type, 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.
lower_extrapolation_rule_type lower_extrapolation_rule() const
Get the lower extrapolation rule.
~SplineEvaluator()=default
Destructs.
SplineEvaluator(SplineEvaluator const &x)=default
Copy-constructs.
SplineEvaluator(LowerExtrapolationRule const &lower_extrap_rule, UpperExtrapolationRule const &upper_extrap_rule)
Build a SplineEvaluator acting on batched_spline_domain.
void deriv(ddc::ChunkSpan< double, batched_evaluation_domain_type, Layout1, memory_space > const spline_eval, ddc::ChunkSpan< double const, batched_spline_domain_type, Layout2, memory_space > const spline_coef) const
Differentiate spline function (described by its spline coefficients) on a mesh.
SplineEvaluator & operator=(SplineEvaluator const &x)=default
Copy-assigns.
void deriv(ddc::ChunkSpan< double, batched_evaluation_domain_type, Layout1, memory_space > const spline_eval, ddc::ChunkSpan< ddc::Coordinate< CoordsDims... > const, batched_evaluation_domain_type, Layout2, memory_space > const coords_eval, ddc::ChunkSpan< double const, batched_spline_domain_type, Layout3, memory_space > const spline_coef) const
Differentiate spline function (described by its spline coefficients) on a mesh.
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 operator()(ddc::ChunkSpan< double, batched_evaluation_domain_type, Layout1, memory_space > const spline_eval, ddc::ChunkSpan< double const, batched_spline_domain_type, Layout2, memory_space > const spline_coef) const
Evaluate a spline function (described by its spline coefficients) on a mesh.
SplineEvaluator(SplineEvaluator &&x)=default
Move-constructs.
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.
The top-level namespace of DDC.