Block-Structured AMR Software Framework
AMReX_EB2_IF_Rotation.H
Go to the documentation of this file.
1 #ifndef AMREX_EB2_IF_ROTATION_H_
2 #define AMREX_EB2_IF_ROTATION_H_
3 #include <AMReX_Config.H>
4 
5 #include <AMReX_EB2_IF_Base.H>
6 #include <AMReX_Array.H>
7 #include <type_traits>
8 #include <cmath>
9 
10 // For all implicit functions, >0: body; =0: boundary; <0: fluid
11 
12 namespace amrex::EB2 {
13 
14 template <class F>
16 {
17 public:
18 
19  RotationIF (F a_f, Real angle, int dir)
20  : m_f(std::move(a_f)),
21  m_cos_angle(std::cos(angle)),
22  m_sin_angle(std::sin(angle)),
23  m_dir(dir)
24  {}
25 
26 // Note that angle is measured in radians
27 #if (AMREX_SPACEDIM==2)
28  [[nodiscard]] inline Real operator() (const RealArray& p) const noexcept
29  {
30  Real x = p[0]*m_cos_angle + p[1]*m_sin_angle;
31  Real y = -p[0]*m_sin_angle + p[1]*m_cos_angle;
32  return m_f({x, y});
33  }
34 
35  template <class U=F, std::enable_if_t<IsGPUable<U>::value,int> = 0>
36  [[nodiscard]] AMREX_GPU_HOST_DEVICE inline
37  Real operator() (Real x, Real y) const noexcept
38  {
39  return m_f( x*m_cos_angle + y*m_sin_angle,
40  -x*m_sin_angle + y*m_cos_angle);
41  }
42 #endif
43 
44 #if (AMREX_SPACEDIM==3)
45  [[nodiscard]] inline Real operator() (const RealArray& p) const noexcept
46  {
47  switch(m_dir) {
48  case(0):
49  {
50  Real y = p[1]*m_cos_angle + p[2]*m_sin_angle;
51  Real z = -p[1]*m_sin_angle + p[2]*m_cos_angle;
52  return m_f({p[0], y, z});
53  }
54  case(1):
55  {
56  Real x = p[0]*m_cos_angle - p[2]*m_sin_angle;
57  Real z = p[0]*m_sin_angle + p[2]*m_cos_angle;
58  return m_f({x, p[1], z});
59  }
60  default:
61  {
62  Real x = p[0]*m_cos_angle + p[1]*m_sin_angle;
63  Real y = -p[0]*m_sin_angle + p[1]*m_cos_angle;
64  return m_f({x, y, p[2]});
65  }
66  }
67  }
68 
69  template <class U=F, std::enable_if_t<IsGPUable<U>::value,int> = 0>
70  [[nodiscard]] AMREX_GPU_HOST_DEVICE inline
71  Real operator() (Real x, Real y, Real z) const noexcept
72  {
73  switch(m_dir) {
74  case(0):
75  {
76  return m_f(x,
78  -y*m_sin_angle + z*m_cos_angle);
79  }
80  case(1):
81  {
82  return m_f(x*m_cos_angle - z*m_sin_angle,
83  y,
84  x*m_sin_angle + z*m_cos_angle);
85  }
86  default:
87  {
88  return m_f( x*m_cos_angle + y*m_sin_angle,
89  -x*m_sin_angle + y*m_cos_angle,
90  z);
91  }
92  }
93  }
94 #endif
95 
96 protected:
97 
98  F m_f;
101  int m_dir;
102 };
103 
104 template <class F>
105 struct IsGPUable<RotationIF<F>, std::enable_if_t<IsGPUable<F>::value>>
106  : std::true_type {};
107 
108 template <class F>
110 rotate (F&&f, const Real angle, const int dir)
111 {
112  return RotationIF<std::decay_t<F>>(std::forward<F>(f),angle, dir);
113 }
114 
115 }
116 
117 #endif
#define AMREX_GPU_HOST_DEVICE
Definition: AMReX_GpuQualifiers.H:20
Definition: AMReX_EB2_IF_Rotation.H:16
int m_dir
Definition: AMReX_EB2_IF_Rotation.H:101
Real m_sin_angle
Definition: AMReX_EB2_IF_Rotation.H:100
Real m_cos_angle
Definition: AMReX_EB2_IF_Rotation.H:99
F m_f
Definition: AMReX_EB2_IF_Rotation.H:98
RotationIF(F a_f, Real angle, int dir)
Definition: AMReX_EB2_IF_Rotation.H:19
Definition: AMReX_FabArrayBase.H:32
constexpr RotationIF< std::decay_t< F > > rotate(F &&f, const Real angle, const int dir)
Definition: AMReX_EB2_IF_Rotation.H:110
static int f(amrex::Real t, N_Vector y_data, N_Vector y_rhs, void *user_data)
Definition: AMReX_SundialsIntegrator.H:44
Array< Real, AMREX_SPACEDIM > RealArray
Definition: AMReX_Array.H:25
Definition: AMReX_EB2_IF_Base.H:15