Block-Structured AMR Software Framework
Loading...
Searching...
No Matches
AMReX_Algorithm.H
Go to the documentation of this file.
1#ifndef AMREX_ALGORITHM_H_
2#define AMREX_ALGORITHM_H_
3#include <AMReX_Config.H>
4
9
10#include <AMReX_GpuQualifiers.H>
11#include <AMReX_Extension.H>
12#include <AMReX_Dim3.H>
13#include <AMReX_BLassert.H>
14#include <AMReX_Math.H>
15
16#include <algorithm>
17#include <concepts>
18#include <limits>
19#include <type_traits>
20#include <cstdint>
21#include <climits>
22
23namespace amrex
24{
29 template <class T>
31 AMREX_FORCE_INLINE constexpr const T& min (const T& a, const T& b) noexcept
32 {
33 return std::min(a,b);
34 }
35
41 template <class T, class ... Ts>
43 AMREX_FORCE_INLINE constexpr T min (const T& a, const T& b, const Ts& ... c) noexcept
44 {
45 return min(min(a,b),c...);
46 }
47
52 template <class T>
54 AMREX_FORCE_INLINE constexpr const T& max (const T& a, const T& b) noexcept
55 {
56 return std::max(a,b);
57 }
58
64 template <class T, class ... Ts>
66 AMREX_FORCE_INLINE constexpr T max (const T& a, const T& b, const Ts& ... c) noexcept
67 {
68 return max(max(a,b),c...);
69 }
70
73 template <class T>
75 T elemwiseMin (T const& a, T const& b) noexcept {
76 return T{amrex::min(a.x,b.x),amrex::min(a.y,b.y),amrex::min(a.z,b.z)};
77 }
78
81 template <class T, class ... Ts>
83 T elemwiseMin (const T& a, const T& b, const Ts& ... c) noexcept
84 {
85 return elemwiseMin(elemwiseMin(a,b),c...);
86 }
87
90 template <class T>
92 T elemwiseMax (T const& a, T const& b) noexcept {
93 return T{amrex::max(a.x,b.x),amrex::max(a.y,b.y),amrex::max(a.z,b.z)};
94 }
95
98 template <class T, class ... Ts>
100 T elemwiseMax (const T& a, const T& b, const Ts& ... c) noexcept
101 {
102 return elemwiseMax(elemwiseMax(a,b),c...);
103 }
104
108 template<typename T>
110 void Swap (T& t1, T& t2) noexcept
111 {
112 T temp = std::move(t1);
113 t1 = std::move(t2);
114 t2 = std::move(temp);
115 }
116
121 template <typename T>
123 constexpr T Clamp (const T& v, const T& lo, const T& hi)
124 {
125 if (v < lo) {
126 return lo;
127 } else if (hi < v) {
128 return hi;
129 } else {
130 return v;
131 }
132 }
133
137 template <std::floating_point T>
139 bool
140 almostEqual (T x, T y, int ulp = 2)
141 {
142 // Reference: https://en.cppreference.com/w/cpp/types/numeric_limits/epsilon
143 // The machine epsilon has to be scaled to the magnitude of the values used
144 // and multiplied by the desired precision in ULPs (units in the last place)
145 return std::abs(x-y) <= std::numeric_limits<T>::epsilon() * std::abs(x+y) * T(ulp)
146 // unless the result is subnormal
147 || std::abs(x-y) < std::numeric_limits<T>::min();
148 }
149
168 template <std::floating_point T, class F>
170 T bisect (T lo, T hi, F f, T tol=1e-12, int max_iter=100)
171 {
173 "Error - calling bisect but lo and hi don't describe a reasonable interval.");
174
175 T flo = f(lo);
176 T fhi = f(hi);
177
178 if (flo == T(0)) { return lo; }
179 if (fhi == T(0)) { return hi; }
180
181 AMREX_ASSERT_WITH_MESSAGE((flo < T(0)) != (fhi < T(0)),
182 "Error - calling bisect but lo and hi don't bracket a root.");
183
184 T mi = (lo + hi) / T(2);
185 T fmi = T(0);
186 int n = 1;
187 while (n <= max_iter)
188 {
189 if (hi - lo < tol || almostEqual(lo,hi)) { break; }
190 mi = (lo + hi) / T(2);
191 fmi = f(mi);
192 if (fmi == T(0)) { break; }
193 ((fmi < T(0)) != (flo < T(0))) ? hi = mi : lo = mi;
194 flo = f(lo);
195 fhi = f(hi);
196 ++n;
197 }
198
199 AMREX_ASSERT_WITH_MESSAGE(n <= max_iter,
200 "Error - maximum number of iterations reached in bisect.");
201
202 return mi;
203 }
204
227 template <typename T, std::integral Index>
229 Index bisect (T const* d, Index lo, Index hi, T const& v)
230 {
231 while (hi - lo > 1) {
232 Index mid = lo + (hi - lo) / 2;
233 if (v < d[mid]) {
234 hi = mid;
235 } else {
236 lo = mid;
237 }
238 };
239 return lo;
240 }
241
257 template<typename ItType, typename ValType>
259 ItType upper_bound (ItType first, ItType last, const ValType& val)
260 {
262 std::ptrdiff_t count = last-first;
263 while(count>0){
264 auto it = first;
265 const auto step = count/2;
266 it += step;
267 if (!(val < *it)){
268 first = ++it;
269 count -= step + 1;
270 }
271 else{
272 count = step;
273 }
274 }
275 return first;
276 ))
278 return std::upper_bound(first, last, val);
279 ))
280 }
281
297 template<typename ItType, typename ValType>
299 ItType lower_bound (ItType first, ItType last, const ValType& val)
300 {
302 std::ptrdiff_t count = last-first;
303 while(count>0)
304 {
305 auto it = first;
306 const auto step = count/2;
307 it += step;
308 if (*it < val){
309 first = ++it;
310 count -= step + 1;
311 }
312 else{
313 count = step;
314 }
315 }
316
317 return first;
318 ))
320 return std::lower_bound(first, last, val);
321 ))
322 }
323
342 template<typename ItType, std::floating_point ValType>
343 requires (std::floating_point<typename std::iterator_traits<ItType>::value_type>)
345 void linspace (ItType first, const ItType& last, const ValType& start, const ValType& stop)
346 {
347 const std::ptrdiff_t count = last-first;
348 if (count >= 2){
349 const auto delta = (stop - start)/(count - 1);
350 for (std::ptrdiff_t i = 0; i < count-1; ++i){
351 *(first++) = start + i*delta;
352 }
353 *first = stop;
354 }
355 }
356
376 template<typename ItType, std::floating_point ValType>
377 requires (std::floating_point<typename std::iterator_traits<ItType>::value_type>)
379 void logspace (ItType first, const ItType& last,
380 const ValType& start, const ValType& stop, const ValType& base)
381 {
382 const std::ptrdiff_t count = last-first;
383 if (count >= 2){
384 const auto delta = (stop - start)/(count - 1);
385 for (std::ptrdiff_t i = 0; i < count-1; ++i){
386 *(first++) = std::pow(base, start + i*delta);
387 }
388 *first = std::pow(base, stop);
389 }
390 }
391}
392
393#endif
Assertion macros used across AMReX for runtime consistency checks.
#define AMREX_ASSERT_WITH_MESSAGE(EX, MSG)
Definition AMReX_BLassert.H:37
Simple structs for 3-component integer and real-valued tuples.
Compiler- and backend-specific extension macros (e.g., restrict, SIMD, inline).
#define AMREX_FORCE_INLINE
Definition AMReX_Extension.H:124
#define AMREX_IF_ON_DEVICE(CODE)
Definition AMReX_GpuQualifiers.H:56
#define AMREX_IF_ON_HOST(CODE)
Definition AMReX_GpuQualifiers.H:58
#define AMREX_GPU_HOST_DEVICE
Definition AMReX_GpuQualifiers.H:20
__host__ __device__ ItType upper_bound(ItType first, ItType last, const ValType &val)
Return an iterator to the first element greater than a given value.
Definition AMReX_Algorithm.H:259
__host__ __device__ void logspace(ItType first, const ItType &last, const ValType &start, const ValType &stop, const ValType &base)
Fill a range with logarithmically spaced values over a closed interval.
Definition AMReX_Algorithm.H:379
__host__ __device__ void Swap(T &t1, T &t2) noexcept
Definition AMReX_Algorithm.H:110
__host__ __device__ T bisect(T lo, T hi, F f, T tol=1e-12, int max_iter=100)
Find a root of a scalar function on a bracketing interval using bisection.
Definition AMReX_Algorithm.H:170
__host__ __device__ constexpr T elemwiseMax(T const &a, T const &b) noexcept
Definition AMReX_Algorithm.H:92
__host__ __device__ constexpr const T & min(const T &a, const T &b) noexcept
Definition AMReX_Algorithm.H:31
__host__ __device__ ItType lower_bound(ItType first, ItType last, const ValType &val)
Return an iterator to the first element not less than a given value.
Definition AMReX_Algorithm.H:299
__host__ __device__ void linspace(ItType first, const ItType &last, const ValType &start, const ValType &stop)
Fill a range with linearly spaced values over a closed interval.
Definition AMReX_Algorithm.H:345
__host__ __device__ constexpr const T & max(const T &a, const T &b) noexcept
Definition AMReX_Algorithm.H:54
__host__ __device__ bool almostEqual(T x, T y, int ulp=2)
Definition AMReX_Algorithm.H:140
__host__ __device__ constexpr T Clamp(const T &v, const T &lo, const T &hi)
Definition AMReX_Algorithm.H:123
__host__ __device__ constexpr T elemwiseMin(T const &a, T const &b) noexcept
Definition AMReX_Algorithm.H:75
Definition AMReX_Amr.cpp:50
@ F
Definition AMReX_Order.H:7
@ y
Definition AMReX_Orientation.H:14
@ x
Definition AMReX_Orientation.H:14