1#ifndef LINEAR_INTERPOLATION_H
2#define LINEAR_INTERPOLATION_H
6#include "AMReX_Extension.H"
8using namespace amrex::literals;
24template <
typename It,
typename T>
25AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
Index
28 const int sz =
static_cast<int>(end - begin);
30 if ((sz < 2) || (x < *begin)) {
33 if (x > *(begin + (sz - 1))) {
40template <
typename It,
typename T>
41AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE Index
53 while ((ir - il) > 1) {
54 int mid = (il + ir) >> 1;
55 const T xmid = *(begin + mid);
57 if ((x - xmid) * (x - xl) <= 0.0_rt) {
67template <
typename It,
typename T>
68AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE Index
77 if ((x - begin[idx.idx]) > (begin[idx.idx + 1] - x)) {
84template <
typename It,
typename T>
85AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE Index
86find_index(
const It begin,
const It end,
const T& x,
const int hint = 1)
93 for (It it = (begin + hint); it < end; ++it) {
95 idx.idx = it - begin - 1;
102template <
typename C1,
typename C2>
103AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
104 typename std::iterator_traits<C2>::value_type
108 const typename std::iterator_traits<C1>::value_type& xout,
113 using DType1 =
typename std::iterator_traits<C1>::value_type;
116 return yinp[ncomp * idx.
idx + comp];
118 static constexpr DType1 eps = std::numeric_limits<float>::epsilon();
119 const int j = idx.
idx;
120 const auto denom = (xbegin[j + 1] - xbegin[j]);
121 const auto facR = (denom > eps) ? ((xout - xbegin[j]) / denom) : 1.0_rt;
122 const auto facL =
static_cast<DType1
>(1.0_rt) - facR;
123 return facL * yinp[ncomp * j + comp] + facR * yinp[ncomp * (j + 1) + comp];
126template <
typename C1,
typename C2>
127AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
128 typename std::iterator_traits<C2>::value_type
133 const typename std::iterator_traits<C1>::value_type& xout,
138 return linear_impl(xbegin, yinp, xout, idx, ncomp, comp);
141template <
typename C1,
typename C2>
145 const typename C1::value_type& xout,
150 xinp.data(), (xinp.data() + xinp.size()), yinp.data(), xout, ncomp,
154template <
typename C1,
typename C2>
163 static constexpr typename C1::value_type eps =
164 std::numeric_limits<float>::epsilon();
165 AMREX_ASSERT(xinp.size() == yinp.size());
166 AMREX_ASSERT(xout.size() == yout.size());
169 int npts = xout.size();
170 for (
int i = 0; i < npts; ++i) {
171 const auto& x = xout[i];
173 find_index(xinp.data(), (xinp.data() + xinp.size()), x, hint);
176 yout[i] = yinp[ncomp * idx.idx + comp];
179 const auto denom = (xinp[j + 1] - xinp[j]);
180 const auto facR = (denom > eps) ? ((x - xinp[j]) / denom) : 1.0_rt;
182 static_cast<typename C1::value_type
>(1.0_rt) - facR;
183 yout[i] = facL * yinp[ncomp * j + comp] +
184 facR * yinp[ncomp * (j + 1) + comp];
191template <
typename C1,
typename C2>
201 static_cast<amrex::Long
>(xinp.size()) ==
202 static_cast<amrex::Long
>(yinp.size()));
204 static_cast<amrex::Long
>(xout.size()) ==
205 static_cast<amrex::Long
>(yout.size()));
207 int npts = xout.size();
208 for (
int i = 0; i < npts; ++i) {
209 yout[i] =
linear(xinp, yinp, xout[i], ncomp, comp);
215template <
typename C1,
typename C2>
216AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
217 typename std::iterator_traits<C2>::value_type
222 const typename std::iterator_traits<C1>::value_type& xout,
223 const typename std::iterator_traits<C1>::value_type& upper_bound)
225 using DType1 =
typename std::iterator_traits<C1>::value_type;
229 return yinp[idx.idx];
231 static constexpr DType1 eps = std::numeric_limits<float>::epsilon();
232 const int j = idx.idx;
233 const auto denom = (xbegin[j + 1] - xbegin[j]);
236 const auto R = (denom > eps) ? ((xout - xbegin[j]) / denom) : 0.0_rt;
237 const auto ub = upper_bound;
238 const auto hb = 0.5_rt * upper_bound;
239 const auto ohb = 1.5_rt * upper_bound;
241 (std::fmod((std::fmod(yinp[j + 1] - yinp[j], ub) + ohb), ub) - hb) *
245template <
typename C1,
typename C2>
249 const typename C1::value_type& xout,
250 const typename C1::value_type& upper_bound)
253 xinp.data(), (xinp.data() + xinp.size()), yinp.data(), xout,
257template <
typename C1,
typename C2>
263 const typename C1::value_type& upper_bound)
266 static_cast<amrex::Long
>(xinp.size()) ==
267 static_cast<amrex::Long
>(yinp.size()));
269 static_cast<amrex::Long
>(xout.size()) ==
270 static_cast<amrex::Long
>(yout.size()));
272 int npts = xout.size();
273 for (
int i = 0; i < npts; ++i) {
274 yout[i] =
linear_angle(xinp, yinp, xout[i], upper_bound);
278template <
typename C1,
typename C2>
279AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
280 typename std::iterator_traits<C2>::value_type
286 const typename std::iterator_traits<C1>::value_type& xout,
287 const typename std::iterator_traits<C1>::value_type& yout,
291 using DType1 =
typename std::iterator_traits<C1>::value_type;
295 return zinp[xidx.
idx * ny + yidx.
idx];
298 const int i = xidx.
idx;
299 const int j = yidx.
idx;
301 static constexpr DType1 eps = std::numeric_limits<float>::epsilon();
302 const auto xdenom = (xbegin[i + 1] - xbegin[i]);
303 const auto xfacR = (xdenom > eps) ? ((xout - xbegin[i]) / xdenom) : 1.0_rt;
304 const auto xfacL =
static_cast<DType1
>(1.0_rt) - xfacR;
305 const auto ydenom = (ybegin[j + 1] - ybegin[j]);
306 const auto yfacR = (ydenom > eps) ? ((yout - ybegin[j]) / ydenom) : 1.0_rt;
307 const auto yfacL =
static_cast<DType1
>(1.0_rt) - yfacR;
309 const auto z00 = zinp[i * ny + j];
310 const auto z10 = zinp[(i + 1) * ny + j];
311 const auto z01 = zinp[i * ny + (j + 1)];
312 const auto z11 = zinp[(i + 1) * ny + (j + 1)];
314 return z00 * xfacL * yfacL + z10 * xfacR * yfacL + z01 * xfacL * yfacR +
318template <
typename C1,
typename C2>
319AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
320 typename std::iterator_traits<C2>::value_type
327 const typename std::iterator_traits<C1>::value_type& xout,
328 const typename std::iterator_traits<C1>::value_type& yout)
333 xbegin, ybegin,
static_cast<int>(yend - ybegin), zinp, xout, yout, xidx,
337template <
typename C1,
typename C2>
342 const typename C1::value_type& xout,
343 const typename C1::value_type& yout)
345 AMREX_ALWAYS_ASSERT((xinp.size() * yinp.size()) == zinp.size());
347 xinp.data(), (xinp.data() + xinp.size()), yinp.data(),
348 (yinp.data() + yinp.size()), zinp.data(), xout, yout);
Definition linear_interpolation.H:10
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE Index find_index(const It begin, const It end, const T &x, const int hint=1)
Definition linear_interpolation.H:86
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE Index check_bounds(const It begin, const It end, const T &x)
Definition linear_interpolation.H:26
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE Index bisection_search(const It begin, const It end, const T &x)
Definition linear_interpolation.H:42
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE std::iterator_traits< C2 >::value_type linear_angle(const C1 xbegin, const C1 xend, const C2 yinp, const typename std::iterator_traits< C1 >::value_type &xout, const typename std::iterator_traits< C1 >::value_type &upper_bound)
Definition linear_interpolation.H:218
Limits
Definition linear_interpolation.H:12
@ UPLIM
Definition linear_interpolation.H:14
@ VALID
Definition linear_interpolation.H:15
@ LOWLIM
Definition linear_interpolation.H:13
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE std::iterator_traits< C2 >::value_type bilinear(const C1 xbegin, const C1 xend, const C1 ybegin, const C1 yend, const C2 zinp, const typename std::iterator_traits< C1 >::value_type &xout, const typename std::iterator_traits< C1 >::value_type &yout)
Definition linear_interpolation.H:321
void linear_monotonic(const C1 &xinp, const C2 &yinp, const C1 &xout, C2 &yout, const int ncomp=1, const int comp=0)
Definition linear_interpolation.H:155
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE Index nearest_search(const It begin, const It end, const T &x)
Definition linear_interpolation.H:69
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE std::iterator_traits< C2 >::value_type linear(const C1 xbegin, const C1 xend, const C2 yinp, const typename std::iterator_traits< C1 >::value_type &xout, const int ncomp=1, const int comp=0)
Definition linear_interpolation.H:129
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE std::iterator_traits< C2 >::value_type linear_impl(const C1 xbegin, const C2 yinp, const typename std::iterator_traits< C1 >::value_type &xout, const Index &idx, const int ncomp=1, const int comp=0)
Definition linear_interpolation.H:105
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE std::iterator_traits< C2 >::value_type bilinear_impl(const C1 xbegin, const C1 ybegin, const int ny, const C2 zinp, const typename std::iterator_traits< C1 >::value_type &xout, const typename std::iterator_traits< C1 >::value_type &yout, const Index &xidx, const Index &yidx)
Definition linear_interpolation.H:281
Definition linear_interpolation.H:19
Limits lim
Definition linear_interpolation.H:21
int idx
Definition linear_interpolation.H:20