Block-Structured AMR Software Framework
AMReX_EBData.H
Go to the documentation of this file.
1 #ifndef AMREX_EB_DATA_H_
2 #define AMREX_EB_DATA_H_
3 #include <AMReX_Config.H>
4 
5 #include <AMReX_EBCellFlag.H>
6 #include <AMReX_Random.H>
7 
8 namespace amrex
9 {
10 
11 enum struct EBData_t : int
12 {
13  levelset, // level set
14  volfrac, // volume fraction
15  centroid, // volume centroid
16  bndrycent, // boundary centroid
17  bndrynorm, // boundary normal
18  bndryarea, // boundary area
19  AMREX_D_DECL(apx, apy, apz), // area fraction
20  AMREX_D_DECL(fcx, fcy, fcz), // face centroid
21  AMREX_D_DECL(ecx, ecy, ecz), // edge centroid
22  cellflag // EBCellFlag
23 };
24 
25 struct EBData
26 {
27  template <EBData_t T>
29  auto get (int i, int j, int k) const noexcept
30  {
31  if constexpr (T == EBData_t::cellflag) {
32  return (*m_cell_flag)(i,j,k);
33  } else {
34  return m_real_data[static_cast<int>(T)](i,j,k);
35  }
36  }
37 
38  template <EBData_t T, std::enable_if_t< T == EBData_t::centroid
39  || T == EBData_t::bndrycent
40  || T == EBData_t::bndrynorm
41  AMREX_D_TERM(|| T==EBData_t::fcx,
42  || T==EBData_t::fcy,
43  || T==EBData_t::fcz), int> = 0>
45  auto get (int i, int j, int k, int n) const noexcept
46  {
47  return m_real_data[static_cast<int>(T)](i,j,k,n);
48  }
49 
52  randomPointOnEB (int i, int j, int k, RandomEngine const& engine) const
53  {
54  Real nx = this->get<EBData_t::bndrynorm>(i,j,k,0);
55  Real ny = this->get<EBData_t::bndrynorm>(i,j,k,1);
56  Real bcx = this->get<EBData_t::bndrycent>(i,j,k,0);
57  Real bcy = this->get<EBData_t::bndrycent>(i,j,k,1);
58  int dir = (std::abs(nx) >= std::abs(ny)) ? 0 : 1;
59 #if (AMREX_SPACEDIM == 2)
60  auto f = [&] (Real n0, Real n1, Real bc0, Real bc1)
61  {
62  Real rn = amrex::Random(engine);
63  if (n1 == 0) {
64  return amrex::makeTuple(bc0, rn-Real(0.5));
65  } else {
66  Real nn = n0/n1; // Note that we have n0 >= n1. So nn != 0.
67  Real ym = bc1+nn*(bc0-Real(-0.5)); // where x=-0.5 and EB intersects
68  Real yp = bc1+nn*(bc0-Real( 0.5)); // where x= 0.5 and EB intersects
69  Real ymin = std::min(ym,yp);
70  Real ymax = std::max(ym,yp);
71  ymin = std::max(ymin, Real(-0.5));
72  ymax = std::min(ymax, Real( 0.5));
73  Real y = rn/(ymax-ymin) + ymin;
74  Real x = bc0 - (y-bc1)*n1/n0;
75  return amrex::makeTuple(x,y);
76  }
77  };
78 
79  if (dir == 0) {
80  auto [x,y] = f( nx, ny,
81  bcx,bcy);
82  return GpuArray<Real,2>{x,y};
83  } else {
84  auto [y,x] = f( ny, nx,
85  bcy,bcx);
86  return GpuArray<Real,2>{x,y};
87  }
88 #else
89  Real nz = this->get<EBData_t::bndrynorm>(i,j,k,2);
90  Real bcz = this->get<EBData_t::bndrycent>(i,j,k,2);
91  if (std::abs(nz) > std::abs(nx) && std::abs(nz) > std::abs(ny)) {
92  dir = 2;
93  }
94  auto f = [&] (Real n0, Real n1, Real n2, Real bc0, Real bc1, Real bc2)
95  { // Note that n0 >= n1 >= n2;
96  if (n1 == 0 && n2 == 0) {
97  return amrex::makeTuple(bc0,
98  amrex::Random(engine)-Real(0.5),
99  amrex::Random(engine)-Real(0.5));
100  } else if (n2 == 0) {
101  Real nn = n0/n1;
102  Real ym = bc1+nn*(bc0-Real(-0.5));
103  Real yp = bc1+nn*(bc0-Real( 0.5));
104  Real ymin = std::min(ym,yp);
105  Real ymax = std::max(ym,yp);
106  ymin = std::max(ymin, Real(-0.5));
107  ymax = std::min(ymax, Real( 0.5));
108  Real y = amrex::Random(engine)/(ymax-ymin) + ymin;
109  Real z = amrex::Random(engine) - Real(0.5);
110  Real x = bc0 - ((y-bc1)*n1+(z-bc2)*n2)/n0;
111  return amrex::makeTuple(x,y,z);
112  } else {
113  Real y0 = bc1 - ((Real(-0.5)-bc0)*n0+(Real(-0.5)-bc2)*n2)/n1;
114  Real y1 = bc1 - ((Real( 0.5)-bc0)*n0+(Real(-0.5)-bc2)*n2)/n1;
115  Real y2 = bc1 - ((Real(-0.5)-bc0)*n0+(Real( 0.5)-bc2)*n2)/n1;
116  Real y3 = bc1 - ((Real( 0.5)-bc0)*n0+(Real( 0.5)-bc2)*n2)/n1;
117  Real ymin = std::min({y0,y1,y2,y3});
118  Real ymax = std::max({y0,y1,y2,y3});
119  ymin = std::max(ymin, Real(-0.5));
120  ymax = std::min(ymax, Real( 0.5));
121  Real z0 = bc2 - ((Real(-0.5)-bc0)*n0+(Real(-0.5)-bc1)*n1)/n2;
122  Real z1 = bc2 - ((Real( 0.5)-bc0)*n0+(Real(-0.5)-bc1)*n1)/n2;
123  Real z2 = bc2 - ((Real(-0.5)-bc0)*n0+(Real( 0.5)-bc1)*n1)/n2;
124  Real z3 = bc2 - ((Real( 0.5)-bc0)*n0+(Real( 0.5)-bc1)*n1)/n2;
125  Real zmin = std::min({z0,z1,z2,z3});
126  Real zmax = std::max({z0,z1,z2,z3});
127  zmin = std::max(zmin, Real(-0.5));
128  zmax = std::min(zmax, Real( 0.5));
129  Real x, y, z;
130  do {
131  y = amrex::Random(engine)/(ymax-ymin) + ymin;
132  z = amrex::Random(engine)/(zmax-zmin) + zmin;
133  x = bc0 - ((y-bc1)*n1+(z-bc2)*n2)/n0;
134  } while (x > Real(0.5) || x < Real(-0.5));
135  return amrex::makeTuple(x,y,z);
136  }
137  };
138  if (dir == 0) {
139  if (std::abs(ny) >= std::abs(nz)) {
140  auto [x,y,z] = f( nx, ny, nz,
141  bcx,bcy,bcz);
142  return GpuArray<Real,3>{x, y, z};
143  } else {
144  auto [x,z,y] = f( nx, nz, ny,
145  bcx,bcz,bcy);
146  return GpuArray<Real,3>{x, y, z};
147  }
148  } else if (dir == 1) {
149  if (std::abs(nx) >= std::abs(nz)) {
150  auto [y,x,z] = f( ny, nx, nz,
151  bcy,bcx,bcz);
152  return GpuArray<Real,3>{x, y, z};
153  } else {
154  auto [y,z,x] = f( ny, nz, nx,
155  bcy,bcz,bcx);
156  return GpuArray<Real,3>{x, y, z};
157  }
158  } else {
159  if (std::abs(nx) >= std::abs(ny)) {
160  auto [z,x,y] = f( nz, nx, ny,
161  bcz,bcx,bcy);
162  return GpuArray<Real,3>{x, y, z};
163  } else {
164  auto [z,y,x] = f( nz, ny, nx,
165  bcz,bcy,bcx);
166  return GpuArray<Real,3>{x, y, z};
167  }
168  }
169 #endif
170  }
171 
172  static constexpr int real_data_size = static_cast<int>(EBData_t::cellflag);
173 
175  Array4<Real const> const* m_real_data = nullptr;
176 };
177 
178 }
179 #endif
#define AMREX_FORCE_INLINE
Definition: AMReX_Extension.H:119
#define AMREX_GPU_HOST_DEVICE
Definition: AMReX_GpuQualifiers.H:20
#define AMREX_D_TERM(a, b, c)
Definition: AMReX_SPACE.H:129
static int f(amrex::Real t, N_Vector y_data, N_Vector y_rhs, void *user_data)
Definition: AMReX_SundialsIntegrator.H:44
@ min
Definition: AMReX_ParallelReduce.H:18
@ max
Definition: AMReX_ParallelReduce.H:17
Definition: AMReX_Amr.cpp:49
Real Random()
Generate a psuedo-random double from uniform distribution.
Definition: AMReX_Random.cpp:123
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE T abs(const GpuComplex< T > &a_z) noexcept
Return the absolute value of a complex number.
Definition: AMReX_GpuComplex.H:356
constexpr AMREX_GPU_HOST_DEVICE GpuTuple< detail::tuple_decay_t< Ts >... > makeTuple(Ts &&... args)
Definition: AMReX_Tuple.H:252
const int[]
Definition: AMReX_BLProfiler.cpp:1664
EBData_t
Definition: AMReX_EBData.H:12
Definition: AMReX_Array4.H:61
Definition: AMReX_EBData.H:26
Array4< EBCellFlag const > const * m_cell_flag
Definition: AMReX_EBData.H:174
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE GpuArray< Real, AMREX_SPACEDIM > randomPointOnEB(int i, int j, int k, RandomEngine const &engine) const
Definition: AMReX_EBData.H:52
static constexpr int real_data_size
Definition: AMReX_EBData.H:172
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE auto get(int i, int j, int k) const noexcept
Definition: AMReX_EBData.H:29
Array4< Real const > const * m_real_data
Definition: AMReX_EBData.H:175
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE auto get(int i, int j, int k, int n) const noexcept
Definition: AMReX_EBData.H:45
Definition: AMReX_RandomEngine.H:57