DDC 0.0.0

a discrete domain computation library

spline_builder.hpp
1// Copyright (C) The DDC development team, see COPYRIGHT.md file
2//
3// SPDX-License-Identifier: MIT
4
5#pragma once
6#include "ddc/chunk_span.hpp"
7#include "ddc/discrete_domain.hpp"
8#include "ddc/kokkos_allocator.hpp"
9
10#include "deriv.hpp"
11
12namespace ddc {
13enum class SplineSolver {
14 GINKGO
15}; // Only GINKGO available atm, other solvers will be implemented in the futur
16
18 bool const is_uniform,
21 int degree)
22{
23 int N_BE_MIN = n_boundary_equations(BcXmin, degree);
24 int N_BE_MAX = n_boundary_equations(BcXmax, degree);
25 bool is_periodic = (BcXmin == ddc::BoundCond::PERIODIC) && (BcXmax == ddc::BoundCond::PERIODIC);
26 return is_uniform && ((N_BE_MIN != 0 && N_BE_MAX != 0) || is_periodic);
27}
28
38template <
39 class ExecSpace,
40 class MemorySpace,
41 class BSplines,
46 class... IDimX>
48{
49 static_assert(
50 (BSplines::is_periodic() && (BcXmin == ddc::BoundCond::PERIODIC)
52 || (!BSplines::is_periodic() && (BcXmin != ddc::BoundCond::PERIODIC)
54
55private:
56 using tag_type = typename InterpolationMesh::continuous_dimension_type;
57
58public:
60
62
67
72
74
79
81
83 typename ddc::detail::convert_type_seq_to_discrete_domain<ddc::type_seq_remove_t<
84 ddc::detail::TypeSeq<IDimX...>,
85 ddc::detail::TypeSeq<interpolation_mesh_type>>>;
86
88 typename ddc::detail::convert_type_seq_to_discrete_domain<ddc::type_seq_replace_t<
89 ddc::detail::TypeSeq<IDimX...>,
90 ddc::detail::TypeSeq<interpolation_mesh_type>,
91 ddc::detail::TypeSeq<bsplines_type>>>;
92
94 typename ddc::detail::convert_type_seq_to_discrete_domain<ddc::type_seq_merge_t<
95 ddc::detail::TypeSeq<bsplines_type>,
97 ddc::detail::TypeSeq<IDimX...>,
98 ddc::detail::TypeSeq<interpolation_mesh_type>>>>;
99
101 typename ddc::detail::convert_type_seq_to_discrete_domain<ddc::type_seq_replace_t<
102 ddc::detail::TypeSeq<IDimX...>,
103 ddc::detail::TypeSeq<interpolation_mesh_type>,
104 ddc::detail::TypeSeq<deriv_type>>>;
105
109 static constexpr bool s_odd = BSplines::degree() % 2;
110
114 static constexpr int s_nbc_xmin = n_boundary_equations(BcXmin, BSplines::degree());
115
119 static constexpr int s_nbc_xmax = n_boundary_equations(BcXmax, BSplines::degree());
120
124 static constexpr ddc::BoundCond s_bc_xmin = BcXmin;
125
129 static constexpr ddc::BoundCond s_bc_xmax = BcXmax;
130
131private:
132 batched_interpolation_domain_type m_batched_interpolation_domain;
133
134 int m_offset;
135
136 double m_dx; // average cell size for normalization of derivatives
137
138 // interpolator specific
139 std::unique_ptr<ddc::detail::Matrix> matrix;
140
142 int compute_offset(interpolation_domain_type const& interpolation_domain);
143
144public:
147 std::optional<int> cols_per_chunk = std::nullopt,
148 std::optional<unsigned int> preconditionner_max_block_size = std::nullopt)
149 : m_batched_interpolation_domain(batched_interpolation_domain)
150 , m_offset(compute_offset(interpolation_domain()))
152 / ddc::discrete_space<BSplines>().ncells())
153 {
154 static_assert(
156 "Incompatible boundary conditions");
157
158 // Calculate block sizes
160 if constexpr (bsplines_type::is_uniform()) {
161 compute_block_sizes_uniform(lower_block_size, upper_block_size);
162 } else {
163 compute_block_sizes_non_uniform(lower_block_size, upper_block_size);
164 }
165 allocate_matrix(
170 }
171
172 SplineBuilder(SplineBuilder const& x) = delete;
173
180
181 ~SplineBuilder() = default;
182
184
192
194 {
195 return m_batched_interpolation_domain;
196 }
197
210
215
220
235
240
249
258
267 const ddc::detail::Matrix& get_interpolation_matrix() const noexcept
268 {
269 return *matrix;
270 }
271
288 template <class Layout>
292 vals,
293 std::optional<ddc::ChunkSpan<
294 double const,
296 Layout,
298 = std::nullopt,
299 std::optional<ddc::ChunkSpan<
300 double const,
302 Layout,
304 = std::nullopt) const;
305
306private:
307 void compute_block_sizes_uniform(int& lower_block_size, int& upper_block_size) const;
308
309 void compute_block_sizes_non_uniform(int& lower_block_size, int& upper_block_size) const;
310
311 void allocate_matrix(
314 std::optional<int> cols_per_chunk = std::nullopt,
315 std::optional<unsigned int> preconditionner_max_block_size = std::nullopt);
316
317 void build_matrix_system();
318};
319
320template <
321 class ExecSpace,
322 class MemorySpace,
323 class BSplines,
324 class InterpolationMesh,
328 class... IDimX>
329int SplineBuilder<
330 ExecSpace,
332 BSplines,
334 BcXmin,
335 BcXmax,
336 Solver,
337 IDimX...>::compute_offset(interpolation_domain_type const& interpolation_domain)
338{
339 int offset;
340 if constexpr (bsplines_type::is_periodic()) {
341 // Calculate offset so that the matrix is diagonally dominant
342 std::array<double, bsplines_type::degree() + 1> values_ptr;
343 std::experimental::mdspan<
344 double,
345 std::experimental::extents<std::size_t, bsplines_type::degree() + 1>> const
346 values(values_ptr.data());
347 ddc::DiscreteElement<interpolation_mesh_type> start(interpolation_domain.front());
349 .eval_basis(values, ddc::coordinate(start + BSplines::degree()));
350 if constexpr (bsplines_type::degree() % 2 == 0) {
351 offset = jmin.uid() - start.uid() + bsplines_type::degree() / 2 - BSplines::degree();
352 } else {
353 int const mid = bsplines_type::degree() / 2;
354 offset = jmin.uid() - start.uid() + (values(mid) > values(mid + 1) ? mid : mid + 1)
355 - BSplines::degree();
356 }
357 } else {
358 offset = 0;
359 }
360 return offset;
361}
362
363template <
364 class ExecSpace,
365 class MemorySpace,
366 class BSplines,
367 class InterpolationMesh,
371 class... IDimX>
372void SplineBuilder<
373 ExecSpace,
375 BSplines,
377 BcXmin,
378 BcXmax,
379 Solver,
380 IDimX...>::compute_block_sizes_uniform(int& lower_block_size, int& upper_block_size) const
381{
382 switch (BcXmin) {
384 upper_block_size = (bsplines_type::degree()) / 2;
385 break;
387 upper_block_size = s_nbc_xmin;
388 break;
390 upper_block_size = bsplines_type::degree() - 1;
391 break;
392 default:
393 throw std::runtime_error("ddc::BoundCond not handled");
394 }
395 switch (BcXmax) {
397 lower_block_size = (bsplines_type::degree()) / 2;
398 break;
400 lower_block_size = s_nbc_xmax;
401 break;
403 lower_block_size = bsplines_type::degree() - 1;
404 break;
405 default:
406 throw std::runtime_error("ddc::BoundCond not handled");
407 }
408}
409
410template <
411 class ExecSpace,
412 class MemorySpace,
413 class BSplines,
414 class InterpolationMesh,
418 class... IDimX>
419void SplineBuilder<
420 ExecSpace,
422 BSplines,
424 BcXmin,
425 BcXmax,
426 Solver,
427 IDimX...>::compute_block_sizes_non_uniform(int& lower_block_size, int& upper_block_size)
428 const
429{
430 switch (BcXmin) {
432 upper_block_size = bsplines_type::degree() - 1;
433 break;
435 upper_block_size = s_nbc_xmin + 1;
436 break;
438 upper_block_size = bsplines_type::degree() - 1;
439 break;
440 default:
441 throw std::runtime_error("ddc::BoundCond not handled");
442 }
443 switch (BcXmax) {
445 lower_block_size = bsplines_type::degree() - 1;
446 break;
448 lower_block_size = s_nbc_xmax + 1;
449 break;
451 lower_block_size = bsplines_type::degree() - 1;
452 break;
453 default:
454 throw std::runtime_error("ddc::BoundCond not handled");
455 }
456}
457
458template <
459 class ExecSpace,
460 class MemorySpace,
461 class BSplines,
462 class InterpolationMesh,
466 class... IDimX>
467void SplineBuilder<
468 ExecSpace,
470 BSplines,
472 BcXmin,
473 BcXmax,
474 Solver,
475 IDimX...>::
479 std::optional<int> cols_per_chunk,
480 std::optional<unsigned int> preconditionner_max_block_size)
481{
482 // Special case: linear spline
483 // No need for matrix assembly
484 // (desactivated)
485 /*
486 if constexpr (bsplines_type::degree() == 1)
487 return;
488 */
489
490 matrix = ddc::detail::MatrixMaker::make_new_sparse<ExecSpace>(
494
495 build_matrix_system();
496
497 matrix->factorize();
498}
499
500template <
501 class ExecSpace,
502 class MemorySpace,
503 class BSplines,
504 class InterpolationMesh,
508 class... IDimX>
509void SplineBuilder<
510 ExecSpace,
512 BSplines,
514 BcXmin,
515 BcXmax,
516 Solver,
517 IDimX...>::build_matrix_system()
518{
519 // Hermite boundary conditions at xmin, if any
520 if constexpr (BcXmin == ddc::BoundCond::HERMITE) {
521 std::array<double, (bsplines_type::degree() / 2 + 1) * (bsplines_type::degree() + 1)>
524 derivs(derivs_ptr.data(),
525 bsplines_type::degree() + 1,
526 bsplines_type::degree() / 2 + 1);
527 ddc::discrete_space<BSplines>().eval_basis_and_n_derivs(
528 derivs,
530 s_nbc_xmin);
531
532 // In order to improve the condition number of the matrix, we normalize
533 // all derivatives by multiplying the i-th derivative by dx^i
534 for (std::size_t i = 0; i < bsplines_type::degree() + 1; ++i) {
535 for (std::size_t j = 1; j < bsplines_type::degree() / 2 + 1; ++j) {
536 derivs(i, j) *= ddc::detail::ipow(m_dx, j);
537 }
538 }
539
540 // iterate only to deg as last bspline is 0
541 for (std::size_t i = 0; i < s_nbc_xmin; ++i) {
542 for (std::size_t j = 0; j < bsplines_type::degree(); ++j) {
543 matrix->set_element(i, j, derivs(j, s_nbc_xmin - i - 1 + s_odd));
544 }
545 }
546 }
547
548 // Interpolation points
549 std::array<double, bsplines_type::degree() + 1> values_ptr;
550 std::experimental::mdspan<
551 double,
552 std::experimental::extents<std::size_t, bsplines_type::degree() + 1>> const
553 values(values_ptr.data());
554
555 int start = interpolation_domain().front().uid();
556 ddc::for_each(interpolation_domain(), [&](auto ix) {
557 auto jmin = ddc::discrete_space<BSplines>().eval_basis(
558 values,
560 for (std::size_t s = 0; s < bsplines_type::degree() + 1; ++s) {
561 int const j = ddc::detail::
562 modulo(int(jmin.uid() - m_offset + s),
563 (int)ddc::discrete_space<BSplines>().nbasis());
564 matrix->set_element(ix.uid() - start + s_nbc_xmin, j, values(s));
565 }
566 });
567
568 // Hermite boundary conditions at xmax, if any
569 if constexpr (BcXmax == ddc::BoundCond::HERMITE) {
570 std::array<double, (bsplines_type::degree() / 2 + 1) * (bsplines_type::degree() + 1)>
572 std::experimental::mdspan<
573 double,
574 std::experimental::extents<
575 std::size_t,
576 bsplines_type::degree() + 1,
577 bsplines_type::degree() / 2 + 1>> const derivs(derivs_ptr.data());
578
579 ddc::discrete_space<BSplines>().eval_basis_and_n_derivs(
580 derivs,
582 s_nbc_xmax);
583
584 // In order to improve the condition number of the matrix, we normalize
585 // all derivatives by multiplying the i-th derivative by dx^i
586 for (std::size_t i = 0; i < bsplines_type::degree() + 1; ++i) {
587 for (std::size_t j = 1; j < bsplines_type::degree() / 2 + 1; ++j) {
588 derivs(i, j) *= ddc::detail::ipow(m_dx, j);
589 }
590 }
591
592 int const i0 = ddc::discrete_space<BSplines>().nbasis() - s_nbc_xmax;
593 int const j0 = ddc::discrete_space<BSplines>().nbasis() - bsplines_type::degree();
594 for (std::size_t j = 0; j < bsplines_type::degree(); ++j) {
595 for (std::size_t i = 0; i < s_nbc_xmax; ++i) {
596 matrix->set_element(i0 + i, j0 + j, derivs(j + 1, i + s_odd));
597 }
598 }
599 }
600}
601
602template <
603 class ExecSpace,
604 class MemorySpace,
605 class BSplines,
606 class InterpolationMesh,
610 class... IDimX>
611template <class Layout>
612void SplineBuilder<
613 ExecSpace,
615 BSplines,
617 BcXmin,
618 BcXmax,
619 Solver,
621operator()(
624 std::optional<ddc::ChunkSpan<
625 double const,
627 Layout,
629 std::optional<ddc::ChunkSpan<
630 double const,
632 Layout,
633 memory_space>> const derivs_xmax) const
634{
636 == ddc::discrete_space<bsplines_type>().nbasis() - s_nbc_xmin - s_nbc_xmax);
637
639 != (!derivs_xmin.has_value() || derivs_xmin->template extent<deriv_type>() == 0));
641 != (!derivs_xmax.has_value() || derivs_xmax->template extent<deriv_type>() == 0));
642 if constexpr (BcXmin == BoundCond::HERMITE) {
643 assert(ddc::DiscreteElement<deriv_type>(derivs_xmin->domain().front()).uid() == 1);
644 }
645 if constexpr (BcXmax == BoundCond::HERMITE) {
646 assert(ddc::DiscreteElement<deriv_type>(derivs_xmax->domain().front()).uid() == 1);
647 }
648
649 // Hermite boundary conditions at xmin, if any
650 // NOTE: For consistency with the linear system, the i-th derivative
651 // provided by the user must be multiplied by dx^i
652 if constexpr (BcXmin == BoundCond::HERMITE) {
653 assert(derivs_xmin->template extent<deriv_type>() == s_nbc_xmin);
655 auto const dx_proxy = m_dx;
657 exec_space(),
658 batch_domain(),
659 KOKKOS_LAMBDA(typename batch_domain_type::discrete_element_type j) {
660 for (int i = s_nbc_xmin; i > 0; --i) {
663 * ddc::detail::ipow(dx_proxy, i + s_odd - 1);
664 }
665 });
666 }
667
668 // TODO : Consider optimizing
669 // Fill spline with vals (to work in spline afterward and preserve vals)
670 auto const& offset_proxy = m_offset;
671 auto const& interp_size_proxy = interpolation_domain().extents();
672 auto const& nbasis_proxy = ddc::discrete_space<bsplines_type>().nbasis();
674 exec_space(),
675 batch_domain(),
676 KOKKOS_LAMBDA(typename batch_domain_type::discrete_element_type j) {
677 for (int i = s_nbc_xmin; i < s_nbc_xmin + offset_proxy; ++i) {
679 }
680 for (int i = 0; i < interp_size_proxy; ++i) {
683 }
684 });
685
686 // Hermite boundary conditions at xmax, if any
687 // NOTE: For consistency with the linear system, the i-th derivative
688 // provided by the user must be multiplied by dx^i
689 if constexpr (BcXmax == BoundCond::HERMITE) {
690 assert(derivs_xmax->template extent<deriv_type>() == s_nbc_xmax);
692 auto const dx_proxy = m_dx;
694 exec_space(),
695 batch_domain(),
696 KOKKOS_LAMBDA(typename batch_domain_type::discrete_element_type j) {
697 for (int i = 0; i < s_nbc_xmax; ++i) {
699 j)
701 * ddc::detail::ipow(dx_proxy, i + s_odd);
702 }
703 });
704 }
705
706 // TODO : Consider optimizing
707 // Allocate and fill a transposed version of spline in order to get dimension of interest as last dimension (optimal for GPU, necessary for Ginkgo)
709 batched_spline_tr_domain(),
713 exec_space(),
714 batch_domain(),
715 KOKKOS_LAMBDA(typename batch_domain_type::discrete_element_type const j) {
716 for (std::size_t i = 0; i < nbasis_proxy; i++) {
719 }
720 });
721 // Create a 2D Kokkos::View to manage spline_tr as a matrix
722 Kokkos::View<double**, Kokkos::LayoutRight, exec_space> bcoef_section(
723 spline_tr.data_handle(),
725 batch_domain().size());
726 // Compute spline coef
727 matrix->solve_batch_inplace(bcoef_section);
728 // Transpose back spline_tr in spline
730 exec_space(),
731 batch_domain(),
732 KOKKOS_LAMBDA(typename batch_domain_type::discrete_element_type const j) {
733 for (std::size_t i = 0; i < nbasis_proxy; i++) {
736 }
737 });
738
739 // Not sure yet of what this part do
740 if (bsplines_type::is_periodic()) {
742 exec_space(),
743 batch_domain(),
744 KOKKOS_LAMBDA(typename batch_domain_type::discrete_element_type const j) {
745 if (offset_proxy != 0) {
746 for (int i = 0; i < offset_proxy; ++i) {
749 j);
750 }
751 for (std::size_t i = offset_proxy; i < bsplines_type::degree(); ++i) {
754 }
755 }
756 for (std::size_t i(0); i < bsplines_type::degree(); ++i) {
759
761 }
762 });
763 }
764}
765} // namespace ddc
Definition discrete_domain.hpp:51
A DiscreteElement identifies an element of the discrete dimension.
Definition discrete_element.hpp:146
KOKKOS_FUNCTION constexpr value_type & uid() noexcept
Definition discrete_element.hpp:223
A DiscreteVector is a vector in the discrete dimension.
Definition discrete_vector.hpp:254
Definition kokkos_allocator.hpp:17
A class for creating a spline approximation of a function.
Definition spline_builder.hpp:48
const ddc::detail::Matrix & get_interpolation_matrix() const noexcept
Get the interpolation matrix.
Definition spline_builder.hpp:267
static constexpr bool s_odd
Indicates if the degree of the splines is odd or even.
Definition spline_builder.hpp:109
ddc::DiscreteDomain< interpolation_mesh_type > interpolation_domain_type
The type of the domain for the interpolation mesh used by this class.
Definition spline_builder.hpp:78
batched_interpolation_domain_type batched_interpolation_domain() const noexcept
Definition spline_builder.hpp:193
batched_spline_tr_domain_type batched_spline_tr_domain() const noexcept
Definition spline_builder.hpp:236
SplineBuilder(batched_interpolation_domain_type const &batched_interpolation_domain, std::optional< int > cols_per_chunk=std::nullopt, std::optional< unsigned int > preconditionner_max_block_size=std::nullopt)
Definition spline_builder.hpp:145
batch_domain_type batch_domain() const noexcept
Definition spline_builder.hpp:211
typename ddc::detail::convert_type_seq_to_discrete_domain< ddc::type_seq_replace_t< ddc::detail::TypeSeq< IDimX... >, ddc::detail::TypeSeq< interpolation_mesh_type >, ddc::detail::TypeSeq< bsplines_type > > > batched_spline_domain_type
Definition spline_builder.hpp:87
void operator()(ddc::ChunkSpan< double, batched_spline_domain_type, Layout, memory_space > spline, ddc::ChunkSpan< double const, batched_interpolation_domain_type, Layout, memory_space > vals, std::optional< ddc::ChunkSpan< double const, batched_derivs_domain_type, Layout, memory_space > > const derivs_xmin=std::nullopt, std::optional< ddc::ChunkSpan< double const, batched_derivs_domain_type, Layout, memory_space > > const derivs_xmax=std::nullopt) const
Build a spline approximation of a function.
Definition spline_builder.hpp:621
SplineBuilder & operator=(SplineBuilder const &x)=delete
typename ddc::detail::convert_type_seq_to_discrete_domain< ddc::type_seq_remove_t< ddc::detail::TypeSeq< IDimX... >, ddc::detail::TypeSeq< interpolation_mesh_type > > > batch_domain_type
Definition spline_builder.hpp:82
ExecSpace exec_space
Definition spline_builder.hpp:59
static constexpr int s_nbc_xmax
The number of equations which define the boundary conditions at the upper bound.
Definition spline_builder.hpp:119
batched_derivs_domain_type batched_derivs_xmax_domain() const noexcept
Definition spline_builder.hpp:250
interpolation_domain_type interpolation_domain() const noexcept
Get the domain from which the approximation is defined.
Definition spline_builder.hpp:206
MemorySpace memory_space
Definition spline_builder.hpp:61
SplineBuilder(SplineBuilder const &x)=delete
batched_spline_domain_type batched_spline_domain() const noexcept
Get the domain on which the approximation is defined.
Definition spline_builder.hpp:229
InterpolationMesh interpolation_mesh_type
The type of the interpolation mesh used by this class.
Definition spline_builder.hpp:66
SplineBuilder(SplineBuilder &&x)=default
Create a new SplineBuilder by copy.
~SplineBuilder()=default
static constexpr int s_nbc_xmin
The number of equations which define the boundary conditions at the lower bound.
Definition spline_builder.hpp:114
typename ddc::detail::convert_type_seq_to_discrete_domain< ddc::type_seq_replace_t< ddc::detail::TypeSeq< IDimX... >, ddc::detail::TypeSeq< interpolation_mesh_type >, ddc::detail::TypeSeq< deriv_type > > > batched_derivs_domain_type
Definition spline_builder.hpp:100
BSplines bsplines_type
The type of the BSplines which are compatible with this class.
Definition spline_builder.hpp:71
batched_derivs_domain_type batched_derivs_xmin_domain() const noexcept
Definition spline_builder.hpp:241
typename ddc::detail::convert_type_seq_to_discrete_domain< ddc::type_seq_merge_t< ddc::detail::TypeSeq< bsplines_type >, ddc::type_seq_remove_t< ddc::detail::TypeSeq< IDimX... >, ddc::detail::TypeSeq< interpolation_mesh_type > > > > batched_spline_tr_domain_type
Definition spline_builder.hpp:93
ddc::DiscreteDomain< bsplines_type > spline_domain() const noexcept
Definition spline_builder.hpp:216
static constexpr ddc::BoundCond s_bc_xmax
The boundary condition implemented at the upper bound.
Definition spline_builder.hpp:129
SplineBuilder & operator=(SplineBuilder &&x)=default
Copy a SplineBuilder.
static constexpr ddc::BoundCond s_bc_xmin
The boundary condition implemented at the lower bound.
Definition spline_builder.hpp:124
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
KOKKOS_FUNCTION Coordinate< typename DDim::continuous_dimension_type > rmax(DiscreteDomain< DDim > const &d)
Definition non_uniform_point_sampling.hpp:182
ddc::Span2D< double > DSpan2D
Definition view.hpp:128
BoundCond
Definition spline_boundary_conditions.hpp:11
SplineSolver
Definition spline_builder.hpp:13
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... > coordinate(DiscreteElement< DDim... > const &c)
Definition coordinate.hpp:29
KOKKOS_FUNCTION constexpr auto remove_dims_of(DiscreteDomain< DDimsA... > const &DDom_a, DiscreteDomain< DDimsB... > const &DDom_b) noexcept
Definition discrete_domain.hpp:438
KOKKOS_FUNCTION constexpr auto replace_dim_of(DiscreteDomain< DDimsA... > const &DDom_a, DiscreteDomain< DDimsB... > const &DDom_b) noexcept
Definition discrete_domain.hpp:485
void parallel_for_each(std::string const &label, ExecSpace const &execution_space, DiscreteDomain< DDims... > const &domain, Functor &&f) noexcept
iterates over a nD domain using a given Kokkos execution space
Definition parallel_for_each.hpp:155
KOKKOS_FUNCTION Coordinate< typename DDim::continuous_dimension_type > rmin(DiscreteDomain< DDim > const &d)
Definition non_uniform_point_sampling.hpp:175
constexpr bool is_spline_interpolation_mesh_uniform(bool const is_uniform, ddc::BoundCond const BcXmin, ddc::BoundCond const BcXmax, int degree)
Definition spline_builder.hpp:17
KOKKOS_FUNCTION detail::ddim_impl_t< DDim, MemorySpace > const & discrete_space()
Definition discrete_space.hpp:207
Definition chunk.hpp:21
Definition chunk_span.hpp:30
Definition deriv.hpp:11