DDC 0.10.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
17#include "math_tools.hpp"
18
19namespace ddc {
20
21namespace detail {
22
23/** @brief Compute the integrals of the uniform B-splines.
24 *
25 * The integral of each of the B-splines over their support within the domain on which this basis was defined.
26 *
27 * @param[in] execution_space a Kokkos execution space where the loop will be executed on
28 * @param[out] int_vals The values of the integrals. It has to be a 1D Chunkspan of size (nbasis).
29 */
30template <class ExecSpace, class DDim, class Layout, class MemorySpace>
31void uniform_bsplines_integrals(
32 ExecSpace const& execution_space,
33 ddc::ChunkSpan<double, ddc::DiscreteDomain<DDim>, Layout, MemorySpace> int_vals)
34{
35 static_assert(is_uniform_bsplines_v<DDim>);
36 static_assert(
37 Kokkos::SpaceAccessibility<ExecSpace, MemorySpace>::accessible,
38 "MemorySpace has to be accessible for ExecutionSpace.");
39
40 assert([&]() -> bool {
41 if constexpr (DDim::is_periodic()) {
42 return int_vals.size() == ddc::discrete_space<DDim>().nbasis()
43 || int_vals.size() == ddc::discrete_space<DDim>().size();
44 } else {
45 return int_vals.size() == ddc::discrete_space<DDim>().nbasis();
46 }
47 }());
48
49 ddc::DiscreteDomain<DDim> const full_dom_splines(ddc::discrete_space<DDim>().full_domain());
50
51 if constexpr (DDim::is_periodic()) {
52 ddc::DiscreteDomain<DDim> const dom_bsplines(full_dom_splines.take_first(
53 ddc::DiscreteVector<DDim> {ddc::discrete_space<DDim>().nbasis()}));
54 ddc::parallel_fill(
55 execution_space,
56 int_vals[dom_bsplines],
57 ddc::step<UniformBsplinesKnots<DDim>>());
58 if (int_vals.size() == ddc::discrete_space<DDim>().size()) {
59 ddc::DiscreteDomain<DDim> const dom_bsplines_repeated(
60 full_dom_splines.take_last(ddc::DiscreteVector<DDim> {DDim::degree()}));
61 ddc::parallel_fill(execution_space, int_vals[dom_bsplines_repeated], 0);
62 }
63 } else {
64 ddc::DiscreteDomain<DDim> const dom_bspline_entirely_in_domain
65 = full_dom_splines
66 .remove(ddc::DiscreteVector<DDim>(DDim::degree()),
67 ddc::DiscreteVector<DDim>(DDim::degree()));
68 ddc::parallel_fill(
69 execution_space,
70 int_vals[dom_bspline_entirely_in_domain],
71 ddc::step<UniformBsplinesKnots<DDim>>());
72
73 ddc::DiscreteElement<DDim> const first_bspline = full_dom_splines.front();
74 ddc::DiscreteElement<DDim> const last_bspline = full_dom_splines.back();
75
76 Kokkos::parallel_for(
77 Kokkos::RangePolicy<
78 ExecSpace,
79 Kokkos::IndexType<std::size_t>>(execution_space, 0, DDim::degree()),
80 KOKKOS_LAMBDA(std::size_t i) {
81 std::array<double, DDim::degree() + 2> edge_vals_ptr;
82 Kokkos::mdspan<double, Kokkos::extents<std::size_t, DDim::degree() + 2>> const
83 edge_vals(edge_vals_ptr.data());
84
85 ddc::discrete_space<DDim>().eval_basis(
86 edge_vals,
87 ddc::discrete_space<DDim>().rmin(),
88 DDim::degree() + 1);
89
90 double const d_eval = ddc::detail::sum(edge_vals);
91
92 double const c_eval = ddc::detail::sum(edge_vals, 0, DDim::degree() - i);
93
94 double const edge_value
95 = ddc::step<UniformBsplinesKnots<DDim>>() * (d_eval - c_eval);
96
97 int_vals(first_bspline + i) = edge_value;
98 int_vals(last_bspline - i) = edge_value;
99 });
100 }
101}
102
103/** @brief Compute the integrals of the non uniform B-splines.
104 *
105 * The integral of each of the B-splines over their support within the domain on which this basis was defined.
106 *
107 * @param[in] execution_space a Kokkos execution space where the loop will be executed on
108 * @param[out] int_vals The values of the integrals. It has to be a 1D Chunkspan of size (nbasis).
109 */
110template <class ExecSpace, class DDim, class Layout, class MemorySpace>
111void non_uniform_bsplines_integrals(
112 ExecSpace const& execution_space,
113 ddc::ChunkSpan<double, ddc::DiscreteDomain<DDim>, Layout, MemorySpace> int_vals)
114{
115 static_assert(is_non_uniform_bsplines_v<DDim>);
116 static_assert(
117 Kokkos::SpaceAccessibility<ExecSpace, MemorySpace>::accessible,
118 "MemorySpace has to be accessible for ExecutionSpace.");
119
120 assert([&]() -> bool {
121 if constexpr (DDim::is_periodic()) {
122 return int_vals.size() == ddc::discrete_space<DDim>().nbasis()
123 || int_vals.size() == ddc::discrete_space<DDim>().size();
124 } else {
125 return int_vals.size() == ddc::discrete_space<DDim>().nbasis();
126 }
127 }());
128
129 ddc::DiscreteDomain<DDim> const full_dom_splines(ddc::discrete_space<DDim>().full_domain());
130
131 double const inv_deg = 1.0 / (DDim::degree() + 1);
132
133 ddc::DiscreteDomain<DDim> const dom_bsplines(full_dom_splines.take_first(
134 ddc::DiscreteVector<DDim> {ddc::discrete_space<DDim>().nbasis()}));
135 ddc::parallel_for_each(
136 execution_space,
137 dom_bsplines,
138 KOKKOS_LAMBDA(ddc::DiscreteElement<DDim> ix) {
139 int_vals(ix)
140 = (ddc::coordinate(ddc::discrete_space<DDim>().get_last_support_knot(ix))
141 - ddc::coordinate(
142 ddc::discrete_space<DDim>().get_first_support_knot(ix)))
143 * inv_deg;
144 });
145
146 if constexpr (DDim::is_periodic()) {
147 if (int_vals.size() == ddc::discrete_space<DDim>().size()) {
148 ddc::DiscreteDomain<DDim> const dom_bsplines_wrap(
149 full_dom_splines.take_last(ddc::DiscreteVector<DDim> {DDim::degree()}));
150 ddc::parallel_fill(execution_space, int_vals[dom_bsplines_wrap], 0);
151 }
152 }
153}
154
155} // namespace detail
156
157/** @brief Compute the integrals of the B-splines.
158 *
159 * The integral of each of the B-splines over their support within the domain on which this basis was defined.
160 *
161 * @param[in] execution_space a Kokkos execution space where the loop will be executed on
162 * @param[out] int_vals The values of the integrals. It has to be a 1D Chunkspan of size (nbasis).
163 * @return The values of the integrals.
164 */
165template <class ExecSpace, class DDim, class Layout, class MemorySpace>
166ddc::ChunkSpan<double, ddc::DiscreteDomain<DDim>, Layout, MemorySpace> integrals(
167 ExecSpace const& execution_space,
168 ddc::ChunkSpan<double, ddc::DiscreteDomain<DDim>, Layout, MemorySpace> int_vals)
169{
170 static_assert(is_uniform_bsplines_v<DDim> || is_non_uniform_bsplines_v<DDim>);
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.
static auto get_sampling()
Get the UniformPointSampling defining the Greville points.
Storage class of the static attributes of the discrete dimension.
Impl & operator=(Impl &&x)=default
Move-assigns.
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 ddc::Coordinate< CDim > rmin() const noexcept
Returns the coordinate of the first 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.
KOKKOS_INLINE_FUNCTION discrete_element_type eval_basis(DSpan1D values, ddc::Coordinate< CDim > const &x) const
Evaluates non-zero B-splines at a given coordinate.
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< DDim, OriginMemorySpace > const &impl)
Copy-constructs from another Impl with a different Kokkos memory space.
~Impl()=default
Destructs.
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 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...
Impl(Impl &&x)=default
Move-constructs.
Impl(std::initializer_list< ddc::Coordinate< CDim > > breaks)
Constructs an Impl using a brace-list, i.e.
KOKKOS_INLINE_FUNCTION discrete_element_type eval_basis_and_n_derivs(ddc::DSpan2D derivs, ddc::Coordinate< CDim > const &x, std::size_t n) const
Evaluates non-zero B-spline values and derivatives at a given coordinate.
KOKKOS_INLINE_FUNCTION std::size_t ncells() const noexcept
Returns the number of cells over which the B-splines are defined.
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 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 npoints() const noexcept
The number of break points.
KOKKOS_INLINE_FUNCTION std::size_t nbasis() const noexcept
Returns the number of basis functions.
Impl(Impl const &x)=default
Copy-constructs.
KOKKOS_INLINE_FUNCTION discrete_element_type eval_deriv(DSpan1D derivs, ddc::Coordinate< CDim > const &x) const
Evaluates non-zero B-spline derivatives at a given coordinate.
KOKKOS_INLINE_FUNCTION double length() const noexcept
Returns the length of the domain.
Impl & operator=(Impl const &x)=default
Copy-assigns.
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.
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 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...
Impl(ddc::Coordinate< CDim > rmin, ddc::Coordinate< CDim > rmax, std::size_t ncells)
Constructs a spline basis (B-splines) with n equidistant knots over .
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 discrete_element_type eval_basis(DSpan1D values, ddc::Coordinate< CDim > const &x) const
Evaluates non-zero B-splines 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.
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()=default
Destructs.
KOKKOS_INLINE_FUNCTION std::size_t nbasis() const noexcept
Returns the number of basis functions.
Impl(Impl const &x)=default
Copy-constructs.
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.
KOKKOS_INLINE_FUNCTION discrete_element_type eval_basis_and_n_derivs(ddc::DSpan2D derivs, ddc::Coordinate< CDim > const &x, std::size_t n) const
Evaluates non-zero B-spline values and derivatives 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 double length() const noexcept
Returns the length of the domain.
Impl(Impl< DDim, OriginMemorySpace > const &impl)
Copy-constructs from another Impl with a different Kokkos memory space.
KOKKOS_INLINE_FUNCTION std::size_t ncells() const noexcept
Returns the number of cells over which the B-splines are defined.
KOKKOS_INLINE_FUNCTION discrete_element_type eval_deriv(DSpan1D derivs, ddc::Coordinate< CDim > const &x) const
Evaluates non-zero B-spline derivatives at a given coordinate.
Impl & operator=(Impl &&x)=default
Move-assigns.
KOKKOS_INLINE_FUNCTION discrete_domain_type full_domain() const
Returns the discrete domain including eventual additional B-splines in the periodic case.
Impl & operator=(Impl const &x)=default
Copy-assigns.
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 bool is_periodic() noexcept
Indicates if the B-splines are periodic or not.
static constexpr std::size_t degree() noexcept
The degree of B-splines.
UniformPointSampling models a uniform discretization of the provided continuous dimension.
The top-level namespace of DDC.
constexpr int n_boundary_equations(ddc::BoundCond const bc, std::size_t const degree)
Return the number of equations needed to describe a given boundary condition.
constexpr bool is_uniform_bsplines_v
Indicates if a tag corresponds to uniform B-splines or not.
BoundCond
An enum representing a spline boundary condition.
@ GREVILLE
Use Greville points instead of conditions on derivative for B-Spline interpolation.
@ HERMITE
Hermite boundary condition.
@ PERIODIC
Periodic boundary condition u(1)=u(n)
ddc::ChunkSpan< double, ddc::DiscreteDomain< DDim >, Layout, MemorySpace > integrals(ExecSpace const &execution_space, ddc::ChunkSpan< double, 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.
A templated struct representing a discrete dimension storing the derivatives of a function along a co...
Definition deriv.hpp:15
ConstantExtrapolationRule(ddc::Coordinate< DimI > eval_pos, ddc::Coordinate< DimNI > eval_pos_not_interest_min, ddc::Coordinate< DimNI > eval_pos_not_interest_max)
Instantiate a ConstantExtrapolationRule.
KOKKOS_FUNCTION double operator()(CoordType coord_extrap, ddc::ChunkSpan< double const, ddc::DiscreteDomain< BSplines1, BSplines2 >, 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.
KOKKOS_FUNCTION double operator()(CoordType pos, ddc::ChunkSpan< double 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.