Block-Structured AMR Software Framework
 
Loading...
Searching...
No Matches
AMReX_EB2_IF_Union.H
Go to the documentation of this file.
1#ifndef AMREX_EB2_IF_UNION_H_
2#define AMREX_EB2_IF_UNION_H_
3#include <AMReX_Config.H>
4
5#include <AMReX_EB2_IF_Base.H>
6#include <AMReX_Array.H>
7#include <AMReX_Tuple.H>
8
9#include <algorithm>
10#include <utility>
11
12namespace amrex::EB2 {
13
14// For all implicit functions, >0: body; =0: boundary; <0: fluid
15
16// Union of bodies
17
19namespace UIF_detail {
20 template <typename F>
21 [[nodiscard]] inline Real do_max (const RealArray& p, F&& f) noexcept
22 {
23 return std::forward<F>(f)(p);
24 }
25
26 template <typename F, typename... Fs>
27 [[nodiscard]] inline Real do_max (const RealArray& p, F&& f, Fs&... fs) noexcept
28 {
29 return amrex::max(std::forward<F>(f)(p), do_max(p, std::forward<Fs>(fs)...));
30 }
31
32 template <typename F>
33 [[nodiscard]] AMREX_GPU_HOST_DEVICE inline
34 Real do_max (AMREX_D_DECL(Real x, Real y, Real z), F&& f) noexcept
35 {
36 return std::forward<F>(f)(AMREX_D_DECL(x,y,z));
37 }
38
39 template <typename F, typename... Fs>
40 [[nodiscard]] AMREX_GPU_HOST_DEVICE inline
41 Real do_max (AMREX_D_DECL(Real x, Real y, Real z), F&& f, Fs&... fs) noexcept
42 {
43 return amrex::max(std::forward<F>(f)(AMREX_D_DECL(x,y,z)), do_max(AMREX_D_DECL(x,y,z), std::forward<Fs>(fs)...));
44 }
45}
47
48template <class... Fs>
50 : public GpuTuple<Fs...>
51{
52public:
53 using GpuTuple<Fs...>::GpuTuple;
54
55 [[nodiscard]] inline Real operator() (const RealArray& p) const noexcept
56 {
57 return op_impl(p, std::make_index_sequence<sizeof...(Fs)>());
58 }
59
60 template <class U=UnionIF<Fs...>, std::enable_if_t<IsGPUable<U>::value,int> = 0>
61 [[nodiscard]] AMREX_GPU_HOST_DEVICE inline
63 {
64 return op_impl(AMREX_D_DECL(x,y,z), std::make_index_sequence<sizeof...(Fs)>());
65 }
66
67protected:
68
69 template <std::size_t... Is>
70 [[nodiscard]] inline Real op_impl (const RealArray& p, std::index_sequence<Is...>) const noexcept
71 {
72 return UIF_detail::do_max(p, amrex::get<Is>(*this)...);
73 }
74
75 template <std::size_t... Is>
76 [[nodiscard]] AMREX_GPU_HOST_DEVICE inline
77 Real op_impl (AMREX_D_DECL(Real x, Real y, Real z), std::index_sequence<Is...>) const noexcept
78 {
79 return UIF_detail::do_max(AMREX_D_DECL(x,y,z), amrex::get<Is>(*this)...);
80 }
81};
82
83template <class Head, class... Tail>
84struct IsGPUable<UnionIF<Head, Tail...>, std::enable_if_t<IsGPUable<Head>::value>>
85 : IsGPUable<UnionIF<Tail...> > {};
86
87template <class F>
88struct IsGPUable<UnionIF<F>, std::enable_if_t<IsGPUable<F>::value>>
89 : std::true_type {};
90
91template <class... Fs>
92constexpr UnionIF<std::decay_t<Fs> ...>
93makeUnion (Fs&&... fs)
94{
95 return UnionIF<std::decay_t<Fs> ...>(std::forward<Fs>(fs)...);
96}
97
98}
99
100#endif
#define AMREX_GPU_HOST_DEVICE
Definition AMReX_GpuQualifiers.H:20
#define AMREX_D_DECL(a, b, c)
Definition AMReX_SPACE.H:171
Definition AMReX_EB2_IF_Union.H:51
__host__ __device__ Real op_impl(Real x, Real y, Real z, std::index_sequence< Is... >) const noexcept
Definition AMReX_EB2_IF_Union.H:77
Real operator()(const RealArray &p) const noexcept
Definition AMReX_EB2_IF_Union.H:55
Real op_impl(const RealArray &p, std::index_sequence< Is... >) const noexcept
Definition AMReX_EB2_IF_Union.H:70
GPU-compatible tuple.
Definition AMReX_Tuple.H:98
__host__ __device__ constexpr GpuTuple()=default
amrex_real Real
Floating Point Type for Fields.
Definition AMReX_REAL.H:79
Definition AMReX_FabArrayBase.H:33
constexpr UnionIF< std::decay_t< Fs > ... > makeUnion(Fs &&... fs)
Definition AMReX_EB2_IF_Union.H:93
__host__ __device__ constexpr const T & max(const T &a, const T &b) noexcept
Definition AMReX_Algorithm.H:35
Array< Real, 3 > RealArray
Definition AMReX_Array.H:27
Definition AMReX_EB2_IF_Base.H:15