DDC 0.1.0
Loading...
Searching...
No Matches
constant_extrapolation_rule.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 <cstddef>
9#include <type_traits>
10
11#include <ddc/ddc.hpp>
12
13#include <Kokkos_Core.hpp>
14
15namespace ddc {
16
17template <class DimI, class... Dim>
19{
20};
21
22/**
23 * @brief A functor for describing a spline boundary value by a constant extrapolation for 1D evaluator.
24 *
25 * To define the value of a function on B-splines out of the domain, we here use a constant
26 * extrapolation on the edge.
27 */
28template <class DimI>
30{
31private:
32 ddc::Coordinate<DimI> m_eval_pos;
33
34public:
35 /**
36 * @brief Instantiate a ConstantExtrapolationRule.
37 *
38 * The boundary value will be the same as at the coordinate eval_pos given.
39 *
40 * @param[in] eval_pos
41 * Coordinate inside the domain where we will evaluate each points outside the domain.
42 */
43 explicit ConstantExtrapolationRule(ddc::Coordinate<DimI> eval_pos) : m_eval_pos(eval_pos) {}
44
45 /**
46 * @brief Get the value of the function on B-splines at a coordinate outside the domain.
47 *
48 * @param[in] pos
49 * The coordinate where we want to evaluate the function on B-splines.
50 * @param[in] spline_coef
51 * The coefficients of the function on B-splines.
52 *
53 * @return A double with the value of the function on B-splines evaluated at the coordinate.
54 */
55 template <class CoordType, class BSplines, class Layout, class MemorySpace>
57 [[maybe_unused]] CoordType pos,
58 ddc::ChunkSpan<double const, ddc::DiscreteDomain<BSplines>, Layout, MemorySpace> const
59 spline_coef) const
60 {
61 static_assert(in_tags_v<DimI, to_type_seq_t<CoordType>>);
62
63 std::array<double, BSplines::degree() + 1> vals_ptr;
64 Kokkos::mdspan<double, Kokkos::extents<std::size_t, BSplines::degree() + 1>> const vals(
65 vals_ptr.data());
66
67 ddc::DiscreteElement<BSplines> const idx
68 = ddc::discrete_space<BSplines>().eval_basis(vals, m_eval_pos);
69
70 double y = 0.0;
71 for (std::size_t i = 0; i < BSplines::degree() + 1; ++i) {
72 y += spline_coef(idx + i) * vals[i];
73 }
74 return y;
75 }
76};
77
78/**
79 * @brief A functor for describing a spline boundary value by a constant extrapolation for 2D evaluator.
80 *
81 * To define the value of a function on B-splines out of the domain, we here use a constant
82 * extrapolation on the edge.
83 */
84template <class DimI, class DimNI>
85struct ConstantExtrapolationRule<DimI, DimNI>
86{
87private:
88 ddc::Coordinate<DimI> m_eval_pos;
89 ddc::Coordinate<DimNI> m_eval_pos_not_interest_min;
90 ddc::Coordinate<DimNI> m_eval_pos_not_interest_max;
91
92public:
93 /**
94 * @brief Instantiate a ConstantExtrapolationRule.
95 *
96 * The boundary value will be the same as at the coordinate given in a dimension given.
97 * The dimension of the input defines the dimension of the boundary condition.
98 * The second and the third parameters are needed in case of non-periodic splines on the
99 * dimension off-interest (the complementary dimension of the boundary condition),
100 * because the evaluator can receive coordinates outside the domain in both dimension.
101 *
102 * @param[in] eval_pos
103 * Coordinate in the dimension given inside the domain where we will evaluate
104 * each points outside the domain.
105 * @param[in] eval_pos_not_interest_min
106 * The minimum coordinate inside the domain on the complementary dimension of the boundary condition.
107 * @param[in] eval_pos_not_interest_max
108 * The maximum coordinate inside the domain on the complementary dimension of the boundary condition.
109 */
111 ddc::Coordinate<DimI> eval_pos,
112 ddc::Coordinate<DimNI> eval_pos_not_interest_min,
113 ddc::Coordinate<DimNI> eval_pos_not_interest_max)
114 : m_eval_pos(eval_pos)
115 , m_eval_pos_not_interest_min(eval_pos_not_interest_min)
116 , m_eval_pos_not_interest_max(eval_pos_not_interest_max)
117 {
118 }
119
120 /**
121 * @brief Instantiate a ConstantExtrapolationRule.
122 *
123 * The boundary value will be the same as at the coordinate given in a dimension given.
124 * The dimension of the input defines the dimension of the boundary condition.
125 * No second and third parameters are needed in case of periodic splines on the
126 * dimension off-interest (the complementary dimension of the boundary condition).
127 *
128 * @param[in] eval_pos
129 * Coordinate in the dimension given inside the domain where we will evaluate
130 * each points outside the domain.
131 */
132 template <class DimNI_sfinae = DimNI, std::enable_if_t<DimNI_sfinae::PERIODIC, int> = 0>
133 explicit ConstantExtrapolationRule(ddc::Coordinate<DimI> eval_pos)
134 : m_eval_pos(eval_pos)
135 , m_eval_pos_not_interest_min(0.)
136 , m_eval_pos_not_interest_max(0.)
137 {
138 }
139
140 /**
141 * @brief Get the value of the function on B-splines at a coordinate outside the domain.
142 *
143 * In the dimension defined in the constructor Dim1 (or Dim2), it sets the coordinate pos_1 (or pos_2)
144 * given at the m_eval_pos coordinate if it is outside the domain.
145 * If the coordinate on the complementary dimension of the boundary condition dimension ddc::select<DimNI>(coord_extrap) is
146 * outside the domain, then it also sets the coordinate at eval_pos_not_interest_min
147 * (if ddc::select<DimNI>(coord_extrap) @f$ < @f$ eval_pos_not_interest_min) or
148 * at eval_pos_not_interest_max (if ddc::select<DimNI>(coord_extrap) @f$ > @f$ eval_pos_not_interest_max).
149 *
150 * @param[in] coord_extrap
151 * The coordinates where we want to evaluate the function on B-splines
152 * @param[in] spline_coef
153 * The coefficients of the function on B-splines.
154 *
155 *@return A double with the value of the function on B-splines evaluated at the coordinate.
156 */
157 template <class CoordType, class BSplines1, class BSplines2, class Layout, class MemorySpace>
158 KOKKOS_FUNCTION double operator()(
159 CoordType coord_extrap,
160 ddc::ChunkSpan<
161 double const,
162 ddc::DiscreteDomain<BSplines1, BSplines2>,
163 Layout,
164 MemorySpace> const spline_coef) const
165 {
166 static_assert(
167 in_tags_v<DimI, to_type_seq_t<CoordType>>
168 && in_tags_v<DimNI, to_type_seq_t<CoordType>>);
169
170 ddc::Coordinate<DimI, DimNI> eval_pos;
171 if constexpr (DimNI::PERIODIC) {
172 eval_pos = ddc::Coordinate<DimI, DimNI>(m_eval_pos, ddc::select<DimNI>(coord_extrap));
173 } else {
174 eval_pos = ddc::Coordinate<DimI, DimNI>(
175 m_eval_pos,
176 Kokkos::
177 clamp(ddc::select<DimNI>(coord_extrap),
178 m_eval_pos_not_interest_min,
179 m_eval_pos_not_interest_max));
180 }
181
182 std::array<double, BSplines1::degree() + 1> vals1_ptr;
183 Kokkos::mdspan<double, Kokkos::extents<std::size_t, BSplines1::degree() + 1>> const vals1(
184 vals1_ptr.data());
185 std::array<double, BSplines2::degree() + 1> vals2_ptr;
186 Kokkos::mdspan<double, Kokkos::extents<std::size_t, BSplines2::degree() + 1>> const vals2(
187 vals2_ptr.data());
188
189 ddc::DiscreteElement<BSplines1> const idx1 = ddc::discrete_space<BSplines1>().eval_basis(
190 vals1,
191 ddc::select<typename BSplines1::continuous_dimension_type>(eval_pos));
192 ddc::DiscreteElement<BSplines2> const idx2 = ddc::discrete_space<BSplines2>().eval_basis(
193 vals2,
194 ddc::select<typename BSplines2::continuous_dimension_type>(eval_pos));
195
196 double y = 0.0;
197 for (std::size_t i = 0; i < BSplines1::degree() + 1; ++i) {
198 for (std::size_t j = 0; j < BSplines2::degree() + 1; ++j) {
199 y += spline_coef(idx1 + i, idx2 + j) * vals1[i] * vals2[j];
200 }
201 }
202
203 return y;
204 }
205};
206
207} // namespace ddc
friend class DiscreteDomain
The top-level namespace of DDC.
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.