DDC 0.16.0
Loading...
Searching...
No Matches
integrals.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 <array>
8#include <cassert>
9#include <cstddef>
10
11#include <ddc/ddc.hpp>
12
13#include <Kokkos_Core.hpp>
14
15#include "bsplines.hpp"
18#include "math_tools.hpp"
19
20namespace ddc {
21
22namespace detail {
23
24/** @brief Compute the integrals of the uniform B-splines.
25 *
26 * The integral of each of the B-splines over their support within the domain on which this basis was defined.
27 *
28 * @param[in] execution_space a Kokkos execution space where the loop will be executed on
29 * @param[out] int_vals The values of the integrals. It has to be a 1D Chunkspan of size (nbasis).
30 */
31template <class ExecSpace, class DDim, class Layout, class MemorySpace>
32void uniform_bsplines_integrals(
33 ExecSpace const& execution_space,
34 ddc::ChunkSpan<Real, ddc::DiscreteDomain<DDim>, Layout, MemorySpace> int_vals)
35{
36 static_assert(ddc::concepts::uniform_bsplines<DDim>);
37 static_assert(
38 Kokkos::SpaceAccessibility<ExecSpace, MemorySpace>::accessible,
39 "MemorySpace has to be accessible for ExecutionSpace.");
40
41 assert([&]() -> bool {
42 if constexpr (DDim::is_periodic()) {
43 return int_vals.size() == ddc::discrete_space<DDim>().nbasis()
44 || int_vals.size() == ddc::discrete_space<DDim>().size();
45 } else {
46 return int_vals.size() == ddc::discrete_space<DDim>().nbasis();
47 }
48 }());
49
50 ddc::DiscreteDomain<DDim> const full_dom_splines(ddc::discrete_space<DDim>().full_domain());
51
52 if constexpr (DDim::is_periodic()) {
53 ddc::DiscreteDomain<DDim> const dom_bsplines(full_dom_splines.take_first(
54 ddc::DiscreteVector<DDim> {ddc::discrete_space<DDim>().nbasis()}));
55 ddc::parallel_fill(
56 execution_space,
57 int_vals[dom_bsplines],
58 ddc::step<UniformBsplinesKnots<DDim>>());
59 if (int_vals.size() == ddc::discrete_space<DDim>().size()) {
60 ddc::DiscreteDomain<DDim> const dom_bsplines_repeated(
61 full_dom_splines.take_last(ddc::DiscreteVector<DDim> {DDim::degree()}));
62 ddc::parallel_fill(execution_space, int_vals[dom_bsplines_repeated], 0);
63 }
64 } else {
65 ddc::DiscreteDomain<DDim> const dom_bspline_entirely_in_domain
66 = full_dom_splines
67 .remove(ddc::DiscreteVector<DDim>(DDim::degree()),
68 ddc::DiscreteVector<DDim>(DDim::degree()));
69 ddc::parallel_fill(
70 execution_space,
71 int_vals[dom_bspline_entirely_in_domain],
72 ddc::step<UniformBsplinesKnots<DDim>>());
73
74 ddc::DiscreteElement<DDim> const first_bspline = full_dom_splines.front();
75 ddc::DiscreteElement<DDim> const last_bspline = full_dom_splines.back();
76
77 Kokkos::parallel_for(
78 Kokkos::RangePolicy<
79 ExecSpace,
80 Kokkos::IndexType<std::size_t>>(execution_space, 0, DDim::degree()),
81 KOKKOS_LAMBDA(std::size_t i) {
82 std::array<Real, DDim::degree() + 2> edge_vals_ptr;
83 Kokkos::mdspan<Real, Kokkos::extents<std::size_t, DDim::degree() + 2>> const
84 edge_vals(edge_vals_ptr.data());
85
86 ddc::discrete_space<DDim>().eval_basis(
87 edge_vals,
88 ddc::discrete_space<DDim>().rmin(),
89 DDim::degree() + 1);
90
91 Real const d_eval = ddc::detail::sum(edge_vals);
92
93 Real const c_eval = ddc::detail::sum(edge_vals, 0, DDim::degree() - i);
94
95 Real const edge_value
96 = ddc::step<UniformBsplinesKnots<DDim>>() * (d_eval - c_eval);
97
98 int_vals(first_bspline + i) = edge_value;
99 int_vals(last_bspline - i) = edge_value;
100 });
101 }
102}
103
104/** @brief Compute the integrals of the non uniform B-splines.
105 *
106 * The integral of each of the B-splines over their support within the domain on which this basis was defined.
107 *
108 * @param[in] execution_space a Kokkos execution space where the loop will be executed on
109 * @param[out] int_vals The values of the integrals. It has to be a 1D Chunkspan of size (nbasis).
110 */
111template <class ExecSpace, class DDim, class Layout, class MemorySpace>
112void non_uniform_bsplines_integrals(
113 ExecSpace const& execution_space,
114 ddc::ChunkSpan<Real, ddc::DiscreteDomain<DDim>, Layout, MemorySpace> int_vals)
115{
116 static_assert(ddc::concepts::non_uniform_bsplines<DDim>);
117 static_assert(
118 Kokkos::SpaceAccessibility<ExecSpace, MemorySpace>::accessible,
119 "MemorySpace has to be accessible for ExecutionSpace.");
120
121 assert([&]() -> bool {
122 if constexpr (DDim::is_periodic()) {
123 return int_vals.size() == ddc::discrete_space<DDim>().nbasis()
124 || int_vals.size() == ddc::discrete_space<DDim>().size();
125 } else {
126 return int_vals.size() == ddc::discrete_space<DDim>().nbasis();
127 }
128 }());
129
130 ddc::DiscreteDomain<DDim> const full_dom_splines(ddc::discrete_space<DDim>().full_domain());
131
132 Real const inv_deg = 1.0 / (DDim::degree() + 1);
133
134 ddc::DiscreteDomain<DDim> const dom_bsplines(full_dom_splines.take_first(
135 ddc::DiscreteVector<DDim> {ddc::discrete_space<DDim>().nbasis()}));
136 ddc::parallel_for_each(
137 execution_space,
138 dom_bsplines,
139 KOKKOS_LAMBDA(ddc::DiscreteElement<DDim> ix) {
140 int_vals(ix)
141 = (ddc::coordinate(ddc::discrete_space<DDim>().get_last_support_knot(ix))
142 - ddc::coordinate(
143 ddc::discrete_space<DDim>().get_first_support_knot(ix)))
144 * inv_deg;
145 });
146
147 if constexpr (DDim::is_periodic()) {
148 if (int_vals.size() == ddc::discrete_space<DDim>().size()) {
149 ddc::DiscreteDomain<DDim> const dom_bsplines_wrap(
150 full_dom_splines.take_last(ddc::DiscreteVector<DDim> {DDim::degree()}));
151 ddc::parallel_fill(execution_space, int_vals[dom_bsplines_wrap], 0);
152 }
153 }
154}
155
156} // namespace detail
157
158/** @brief Compute the integrals of the B-splines.
159 *
160 * The integral of each of the B-splines over their support within the domain on which this basis was defined.
161 *
162 * @param[in] execution_space a Kokkos execution space where the loop will be executed on
163 * @param[out] int_vals The values of the integrals. It has to be a 1D Chunkspan of size (nbasis).
164 * @return The values of the integrals.
165 */
166template <class ExecSpace, concepts::bsplines DDim, class Layout, class MemorySpace>
167ddc::ChunkSpan<Real, ddc::DiscreteDomain<DDim>, Layout, MemorySpace> integrals(
168 ExecSpace const& execution_space,
169 ddc::ChunkSpan<Real, ddc::DiscreteDomain<DDim>, Layout, MemorySpace> int_vals)
170{
171 if constexpr (is_uniform_bsplines_v<DDim>) {
172 uniform_bsplines_integrals(execution_space, int_vals);
173 } else if constexpr (is_non_uniform_bsplines_v<DDim>) {
174 non_uniform_bsplines_integrals(execution_space, int_vals);
175 }
176 return int_vals;
177}
178
179} // namespace ddc
friend class ChunkSpan
friend class DiscreteDomain
KOKKOS_FUNCTION constexpr bool operator!=(DiscreteVector< OTags... > const &rhs) const noexcept
A class which provides helper functions to initialise the Greville points from a B-Spline definition.
static ddc::DiscreteDomain< Sampling > get_domain()
Get the domain which gives us access to all of the Greville points.
Storage class of the static attributes of the discrete dimension.
KOKKOS_INLINE_FUNCTION std::size_t ncells() const noexcept
Returns the number of cells over which the B-splines are defined.
Impl(Impl &&x)=default
Move-constructs.
KOKKOS_INLINE_FUNCTION std::size_t nbasis() const noexcept
Returns the number of basis functions.
KOKKOS_INLINE_FUNCTION ddc::DiscreteElement< knot_discrete_dimension_type > get_last_support_knot(discrete_element_type const &ix) const
Returns the coordinate of the last support knot associated to a DiscreteElement identifying a B-splin...
KOKKOS_INLINE_FUNCTION discrete_element_type eval_basis_and_n_derivs(Kokkos::mdspan< double, Kokkos::dextents< std::size_t, 2 > > derivs, ddc::Coordinate< CDim > const &x, std::size_t n) const
Evaluates non-zero B-spline values and derivatives at a given coordinate.
Impl(Impl< DDim, OriginMemorySpace > const &impl)
Copy-constructs from another Impl with a different Kokkos memory space.
Impl(Impl const &x)=default
Copy-constructs.
KOKKOS_INLINE_FUNCTION discrete_element_type eval_deriv(Kokkos::mdspan< double, Kokkos::dextents< std::size_t, 1 > > derivs, ddc::Coordinate< CDim > const &x) const
Evaluates non-zero B-spline derivatives at a given coordinate.
KOKKOS_INLINE_FUNCTION ddc::DiscreteDomain< knot_discrete_dimension_type > break_point_domain() const
Returns the discrete domain which describes the break points.
Impl & operator=(Impl const &x)=default
Copy-assigns.
KOKKOS_INLINE_FUNCTION Real length() const noexcept
Returns the length of the domain.
KOKKOS_INLINE_FUNCTION std::size_t npoints() const noexcept
The number of break points.
KOKKOS_INLINE_FUNCTION ddc::DiscreteElement< knot_discrete_dimension_type > get_first_support_knot(discrete_element_type const &ix) const
Returns the coordinate of the first support knot associated to a DiscreteElement identifying a B-spli...
Impl(RandomIt breaks_begin, RandomIt breaks_end)
Constructs an Impl by iterating over a range of break points from begin to end.
KOKKOS_INLINE_FUNCTION discrete_domain_type full_domain() const
Returns the discrete domain including eventual additional B-splines in the periodic case.
KOKKOS_INLINE_FUNCTION std::size_t size() const noexcept
Returns the number of elements necessary to construct a spline representation of a function.
Impl(std::initializer_list< ddc::Coordinate< CDim > > breaks)
Constructs an Impl using a brace-list, i.e.
Impl & operator=(Impl &&x)=default
Move-assigns.
KOKKOS_INLINE_FUNCTION ddc::Coordinate< CDim > rmin() const noexcept
Returns the coordinate of the first break point of the domain on which the B-splines are defined.
KOKKOS_INLINE_FUNCTION discrete_element_type eval_basis(Kokkos::mdspan< double, Kokkos::dextents< std::size_t, 1 > > values, ddc::Coordinate< CDim > const &x) const
Evaluates non-zero B-splines at a given coordinate.
~Impl()=default
Destructs.
KOKKOS_INLINE_FUNCTION ddc::Coordinate< CDim > rmax() const noexcept
Returns the coordinate of the last break point of the domain on which the B-splines are defined.
Impl(std::vector< ddc::Coordinate< CDim > > const &breaks)
Constructs an Impl using a std::vector.
The type of a non-uniform 1D spline basis (B-spline).
static constexpr std::size_t degree() noexcept
The degree of B-splines.
static constexpr bool is_periodic() noexcept
Indicates if the B-splines are periodic or not.
static constexpr bool is_uniform() noexcept
Indicates if the B-splines are uniform or not (this is not the case here).
NonUniformPointSampling models a non-uniform discretization of the CDim segment .
Storage class of the static attributes of the discrete dimension.
KOKKOS_INLINE_FUNCTION std::size_t ncells() const noexcept
Returns the number of cells over which the B-splines are defined.
KOKKOS_INLINE_FUNCTION Real length() const noexcept
Returns the length of the domain.
KOKKOS_INLINE_FUNCTION ddc::Coordinate< CDim > rmin() const noexcept
Returns the coordinate of the lower bound of the domain on which the B-splines are defined.
Impl(Impl const &x)=default
Copy-constructs.
KOKKOS_INLINE_FUNCTION discrete_domain_type full_domain() const
Returns the discrete domain including eventual additional B-splines in the periodic case.
KOKKOS_INLINE_FUNCTION discrete_element_type eval_deriv(Kokkos::mdspan< double, Kokkos::dextents< std::size_t, 1 > > derivs, ddc::Coordinate< CDim > const &x) const
Evaluates non-zero B-spline derivatives at a given coordinate.
~Impl()=default
Destructs.
Impl(Impl< DDim, OriginMemorySpace > const &impl)
Copy-constructs from another Impl with a different Kokkos memory space.
KOKKOS_INLINE_FUNCTION discrete_element_type eval_basis_and_n_derivs(Kokkos::mdspan< double, Kokkos::dextents< std::size_t, 2 > > derivs, ddc::Coordinate< CDim > const &x, std::size_t n) const
Evaluates non-zero B-spline values and derivatives at a given coordinate.
Impl & operator=(Impl &&x)=default
Move-assigns.
KOKKOS_INLINE_FUNCTION ddc::Coordinate< CDim > rmax() const noexcept
Returns the coordinate of the upper bound of the domain on which the B-splines are defined.
KOKKOS_INLINE_FUNCTION ddc::DiscreteElement< knot_discrete_dimension_type > get_last_support_knot(discrete_element_type const &ix) const
Returns the coordinate of the last support knot associated to a DiscreteElement identifying a B-splin...
KOKKOS_INLINE_FUNCTION ddc::DiscreteDomain< knot_discrete_dimension_type > break_point_domain() const
Returns the discrete domain which describes the break points.
KOKKOS_INLINE_FUNCTION discrete_element_type eval_basis(Kokkos::mdspan< double, Kokkos::dextents< std::size_t, 1 > > values, ddc::Coordinate< CDim > const &x) const
Evaluates non-zero B-splines at a given coordinate.
KOKKOS_INLINE_FUNCTION ddc::DiscreteElement< knot_discrete_dimension_type > get_first_support_knot(discrete_element_type const &ix) const
Returns the coordinate of the first support knot associated to a DiscreteElement identifying a B-spli...
KOKKOS_INLINE_FUNCTION std::size_t nbasis() const noexcept
Returns the number of basis functions.
Impl & operator=(Impl const &x)=default
Copy-assigns.
KOKKOS_INLINE_FUNCTION std::size_t size() const noexcept
Returns the number of elements necessary to construct a spline representation of a function.
Impl(Impl &&x)=default
Move-constructs.
Impl(ddc::Coordinate< CDim > rmin, ddc::Coordinate< CDim > rmax, std::size_t ncells)
Constructs a spline basis (B-splines) with n equidistant knots over .
The type of a uniform 1D spline basis (B-spline).
static constexpr bool is_uniform() noexcept
Indicates if the B-splines are uniform or not (this is the case here).
static constexpr std::size_t degree() noexcept
The degree of B-splines.
static constexpr bool is_periodic() noexcept
Indicates if the B-splines are periodic or not.
UniformPointSampling models a uniform discretization of the provided continuous dimension.
The top-level namespace of DDC.
constexpr bool is_uniform_bsplines_v
Indicates if a tag corresponds to uniform B-splines or not.
constexpr int n_boundary_equations(ddc::SplineBuilderClosure const sbc, std::size_t const degree)
Return the number of equations needed to describe a given closure relation.
ddc::ChunkSpan< Real, ddc::DiscreteDomain< DDim >, Layout, MemorySpace > integrals(ExecSpace const &execution_space, ddc::ChunkSpan< Real, ddc::DiscreteDomain< DDim >, Layout, MemorySpace > int_vals)
Compute the integrals of the B-splines.
constexpr bool is_non_uniform_bsplines_v
Indicates if a tag corresponds to non-uniform B-splines or not.
SplineBuilderClosure
An enum representing a spline closure relation.
@ HOMOGENEOUS_HERMITE
Homogeneous Hermite closure relation (derivatives are 0)
@ GREVILLE
Use Greville points instead of conditions on derivative for B-Spline interpolation.
@ HERMITE
Hermite closure relation.
@ PERIODIC
Periodic closure relation u(1)=u(n)
A compile-time sequence of types.
Definition type_seq.hpp:30
A functor for describing a spline boundary value by a constant extrapolation for 2D evaluator.
KOKKOS_FUNCTION Real operator()(CoordType coord_extrap, ddc::ChunkSpan< Real const, ddc::DiscreteDomain< BSplines... >, Layout, MemorySpace > const spline_coef) const
Get the value of the function on B-splines at a coordinate outside the domain.
ConstantExtrapolationRule(ddc::Coordinate< DimI > eval_pos)
Instantiate a ConstantExtrapolationRule.
A templated struct representing a discrete dimension storing the derivatives of a function along a co...
Definition deriv.hpp:17