ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
ERFPhysBCFunct_cons Class Reference

#include <ERF_PhysBCFunct.H>

Collaboration diagram for ERFPhysBCFunct_cons:

Public Member Functions

 ERFPhysBCFunct_cons (const int lev, const amrex::Geometry &geom, const amrex::Vector< amrex::BCRec > &domain_bcs_type, const amrex::Gpu::DeviceVector< amrex::BCRec > &domain_bcs_type_d, amrex::Array< amrex::Array< amrex::Real, AMREX_SPACEDIM *2 >, AMREX_SPACEDIM+NVAR_max > bc_extdir_vals, amrex::Array< amrex::Array< amrex::Real, AMREX_SPACEDIM *2 >, AMREX_SPACEDIM+NVAR_max > bc_neumann_vals, std::unique_ptr< amrex::MultiFab > &z_phys_nd, const bool use_real_bcs)
 
 ~ERFPhysBCFunct_cons ()
 
void operator() (amrex::MultiFab &mf, int icomp, int ncomp, amrex::IntVect const &nghost, const amrex::Real time, int bccomp_cons)
 
void impose_lateral_cons_bcs (const amrex::Array4< amrex::Real > &dest_arr, const amrex::Box &bx, const amrex::Box &domain, int icomp, int ncomp, int bccomp)
 
void impose_vertical_cons_bcs (const amrex::Array4< amrex::Real > &dest_arr, const amrex::Box &bx, const amrex::Box &domain, const amrex::Array4< amrex::Real const > &z_nd, const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > dxInv, int icomp, int ncomp, int bccomp)
 

Private Attributes

int m_lev
 
amrex::Geometry m_geom
 
amrex::Vector< amrex::BCRec > m_domain_bcs_type
 
amrex::Gpu::DeviceVector< amrex::BCRec > m_domain_bcs_type_d
 
amrex::Array< amrex::Array< amrex::Real, AMREX_SPACEDIM *2 >, AMREX_SPACEDIM+NVAR_maxm_bc_extdir_vals
 
amrex::Array< amrex::Array< amrex::Real, AMREX_SPACEDIM *2 >, AMREX_SPACEDIM+NVAR_maxm_bc_neumann_vals
 
amrex::MultiFab * m_z_phys_nd
 
bool m_use_real_bcs
 

Constructor & Destructor Documentation

◆ ERFPhysBCFunct_cons()

ERFPhysBCFunct_cons::ERFPhysBCFunct_cons ( const int  lev,
const amrex::Geometry &  geom,
const amrex::Vector< amrex::BCRec > &  domain_bcs_type,
const amrex::Gpu::DeviceVector< amrex::BCRec > &  domain_bcs_type_d,
amrex::Array< amrex::Array< amrex::Real, AMREX_SPACEDIM *2 >, AMREX_SPACEDIM+NVAR_max bc_extdir_vals,
amrex::Array< amrex::Array< amrex::Real, AMREX_SPACEDIM *2 >, AMREX_SPACEDIM+NVAR_max bc_neumann_vals,
std::unique_ptr< amrex::MultiFab > &  z_phys_nd,
const bool  use_real_bcs 
)
inline
33  : m_lev(lev), m_geom(geom),
34  m_domain_bcs_type(domain_bcs_type),
35  m_domain_bcs_type_d(domain_bcs_type_d),
36  m_bc_extdir_vals(bc_extdir_vals),
37  m_bc_neumann_vals(bc_neumann_vals),
38  m_z_phys_nd(z_phys_nd.get()),
39  m_use_real_bcs(use_real_bcs)
40  {}
bool m_use_real_bcs
Definition: ERF_PhysBCFunct.H:74
amrex::Geometry m_geom
Definition: ERF_PhysBCFunct.H:68
amrex::Array< amrex::Array< amrex::Real, AMREX_SPACEDIM *2 >, AMREX_SPACEDIM+NVAR_max > m_bc_neumann_vals
Definition: ERF_PhysBCFunct.H:72
amrex::Array< amrex::Array< amrex::Real, AMREX_SPACEDIM *2 >, AMREX_SPACEDIM+NVAR_max > m_bc_extdir_vals
Definition: ERF_PhysBCFunct.H:71
amrex::Gpu::DeviceVector< amrex::BCRec > m_domain_bcs_type_d
Definition: ERF_PhysBCFunct.H:70
amrex::Vector< amrex::BCRec > m_domain_bcs_type
Definition: ERF_PhysBCFunct.H:69
amrex::MultiFab * m_z_phys_nd
Definition: ERF_PhysBCFunct.H:73
int m_lev
Definition: ERF_PhysBCFunct.H:67

◆ ~ERFPhysBCFunct_cons()

ERFPhysBCFunct_cons::~ERFPhysBCFunct_cons ( )
inline
42 {}

Member Function Documentation

◆ impose_lateral_cons_bcs()

void ERFPhysBCFunct_cons::impose_lateral_cons_bcs ( const amrex::Array4< amrex::Real > &  dest_arr,
const amrex::Box &  bx,
const amrex::Box &  domain,
int  icomp,
int  ncomp,
int  bccomp 
)
20 {
21  BL_PROFILE_VAR("impose_lateral_cons_bcs()",impose_lateral_cons_bcs);
22  const auto& dom_lo = lbound(domain);
23  const auto& dom_hi = ubound(domain);
24 
25  // xlo: ori = 0
26  // ylo: ori = 1
27  // zlo: ori = 2
28  // xhi: ori = 3
29  // yhi: ori = 4
30  // zhi: ori = 5
31 
32  // Based on BCRec for the domain, we need to make BCRec for this Box
33  // bccomp is used as starting index for m_domain_bcs_type
34  // 0 is used as starting index for bcrs
35  Vector<BCRec> bcrs(icomp+ncomp);
36  setBC(bx, domain, bccomp, 0, icomp+ncomp, m_domain_bcs_type, bcrs);
37 
38  Gpu::DeviceVector<BCRec> bcrs_d(icomp+ncomp);
39  Gpu::copyAsync(Gpu::hostToDevice, bcrs.begin(), bcrs.end(), bcrs_d.begin());
40  const BCRec* bc_ptr = bcrs_d.data();
41 
42  GpuArray<GpuArray<Real, AMREX_SPACEDIM*2>,AMREX_SPACEDIM+NVAR_max> l_bc_extdir_vals_d;
43  for (int i = 0; i < icomp+ncomp; i++)
44  for (int ori = 0; ori < 2*AMREX_SPACEDIM; ori++)
45  l_bc_extdir_vals_d[i][ori] = m_bc_extdir_vals[bccomp+i][ori];
46 
47  GpuArray<GpuArray<Real, AMREX_SPACEDIM*2>,AMREX_SPACEDIM+NVAR_max> l_bc_neumann_vals_d;
48  for (int i = 0; i < icomp+ncomp; i++)
49  for (int ori = 0; ori < 2*AMREX_SPACEDIM; ori++)
50  l_bc_neumann_vals_d[i][ori] = m_bc_neumann_vals[bccomp+i][ori];
51 
52  GeometryData const& geomdata = m_geom.data();
53  bool is_periodic_in_x = geomdata.isPeriodic(0);
54  bool is_periodic_in_y = geomdata.isPeriodic(1);
55 
56  // First do all ext_dir bcs
57  if (!is_periodic_in_x)
58  {
59  Box bx_xlo(bx); bx_xlo.setBig (0,dom_lo.x-1);
60  Box bx_xhi(bx); bx_xhi.setSmall(0,dom_hi.x+1);
61  ParallelFor(
62  bx_xlo, ncomp, [=] AMREX_GPU_DEVICE (int i, int j, int k, int n) {
63  if (bc_ptr[icomp+n].lo(0) == ERFBCType::ext_dir) {
64  dest_arr(i,j,k,icomp+n) = l_bc_extdir_vals_d[icomp+n][0];
65  }
66  },
67  bx_xhi, ncomp, [=] AMREX_GPU_DEVICE (int i, int j, int k, int n) {
68  if (bc_ptr[icomp+n].hi(0) == ERFBCType::ext_dir) {
69  dest_arr(i,j,k,icomp+n) = l_bc_extdir_vals_d[icomp+n][3];
70  }
71  }
72  );
73  }
74 
75  if (!is_periodic_in_y)
76  {
77  Box bx_ylo(bx); bx_ylo.setBig (1,dom_lo.y-1);
78  Box bx_yhi(bx); bx_yhi.setSmall(1,dom_hi.y+1);
79  ParallelFor(
80  bx_ylo, ncomp, [=] AMREX_GPU_DEVICE (int i, int j, int k, int n) {
81  if (bc_ptr[icomp+n].lo(1) == ERFBCType::ext_dir) {
82  dest_arr(i,j,k,icomp+n) = l_bc_extdir_vals_d[icomp+n][1];
83  }
84  },
85  bx_yhi, ncomp, [=] AMREX_GPU_DEVICE (int i, int j, int k, int n) {
86  if (bc_ptr[icomp+n].hi(1) == ERFBCType::ext_dir) {
87  dest_arr(i,j,k,icomp+n) = l_bc_extdir_vals_d[icomp+n][4];
88  }
89  }
90  );
91  }
92 
93  // Next do ghost cells in x-direction but not reaching out in y
94  // The corners we miss here will be covered in the y-loop below or by periodicity
95  if (!is_periodic_in_x)
96  {
97  // Populate ghost cells on lo-x and hi-x domain boundaries
98  Box bx_xlo(bx); bx_xlo.setBig (0,dom_lo.x-1);
99  Box bx_xhi(bx); bx_xhi.setSmall(0,dom_hi.x+1);
100  ParallelFor(
101  bx_xlo, ncomp, [=] AMREX_GPU_DEVICE (int i, int j, int k, int n) {
102  int iflip = dom_lo.x - 1 - i;
103  if (bc_ptr[icomp+n].lo(0) == ERFBCType::foextrap) {
104  dest_arr(i,j,k,icomp+n) = dest_arr(dom_lo.x,j,k,icomp+n);
105  } else if (bc_ptr[icomp+n].lo(0) == ERFBCType::open) {
106  dest_arr(i,j,k,icomp+n) = dest_arr(dom_lo.x,j,k,icomp+n);
107  } else if (bc_ptr[icomp+n].lo(0) == ERFBCType::reflect_even) {
108  dest_arr(i,j,k,icomp+n) = dest_arr(iflip,j,k,icomp+n);
109  } else if (bc_ptr[icomp+n].lo(0) == ERFBCType::reflect_odd) {
110  dest_arr(i,j,k,icomp+n) = -dest_arr(iflip,j,k,icomp+n);
111  } else if (bc_ptr[icomp+n].lo(0) == ERFBCType::hoextrapcc) {
112  dest_arr(i,j,k,icomp+n) = 2.0*dest_arr(dom_lo.x,j,k,icomp+n) - dest_arr(dom_lo.x+1,j,k,icomp+n) ;
113  }
114  },
115  bx_xhi, ncomp, [=] AMREX_GPU_DEVICE (int i, int j, int k, int n) {
116  int iflip = 2*dom_hi.x + 1 - i;
117  if (bc_ptr[icomp+n].hi(0) == ERFBCType::foextrap) {
118  dest_arr(i,j,k,icomp+n) = dest_arr(dom_hi.x,j,k,icomp+n);
119  } else if (bc_ptr[icomp+n].hi(0) == ERFBCType::open) {
120  dest_arr(i,j,k,icomp+n) = dest_arr(dom_hi.x,j,k,icomp+n);
121  } else if (bc_ptr[icomp+n].hi(0) == ERFBCType::reflect_even) {
122  dest_arr(i,j,k,icomp+n) = dest_arr(iflip,j,k,icomp+n);
123  } else if (bc_ptr[icomp+n].hi(0) == ERFBCType::reflect_odd) {
124  dest_arr(i,j,k,icomp+n) = -dest_arr(iflip,j,k,icomp+n);
125  } else if (bc_ptr[icomp+n].hi(0) == ERFBCType::hoextrapcc) {
126  dest_arr(i,j,k,icomp+n) = 2.0*dest_arr(dom_hi.x,j,k,icomp+n) - dest_arr(dom_hi.x-1,j,k,icomp+n) ;
127  }
128  }
129  );
130  }
131 
132  if (!is_periodic_in_y)
133  {
134  // Populate ghost cells on lo-y and hi-y domain boundaries
135  Box bx_ylo(bx); bx_ylo.setBig (1,dom_lo.y-1);
136  Box bx_yhi(bx); bx_yhi.setSmall(1,dom_hi.y+1);
137  ParallelFor(
138  bx_ylo, ncomp, [=] AMREX_GPU_DEVICE (int i, int j, int k, int n) {
139  int jflip = dom_lo.y - 1 - j;
140  if (bc_ptr[icomp+n].lo(1) == ERFBCType::foextrap) {
141  dest_arr(i,j,k,icomp+n) = dest_arr(i,dom_lo.y,k,icomp+n);
142  } else if (bc_ptr[icomp+n].lo(1) == ERFBCType::open) {
143  dest_arr(i,j,k,icomp+n) = dest_arr(i,dom_lo.y,k,icomp+n);
144  } else if (bc_ptr[icomp+n].lo(1) == ERFBCType::reflect_even) {
145  dest_arr(i,j,k,icomp+n) = dest_arr(i,jflip,k,icomp+n);
146  } else if (bc_ptr[icomp+n].lo(1) == ERFBCType::reflect_odd) {
147  dest_arr(i,j,k,icomp+n) = -dest_arr(i,jflip,k,icomp+n);
148  } else if (bc_ptr[icomp+n].lo(1) == ERFBCType::hoextrapcc) {
149  dest_arr(i,j,k,icomp+n) = 2.0*dest_arr(i,dom_lo.y,k,icomp+n) - dest_arr(i,dom_lo.y+1,k,icomp+n) ;
150  }
151 
152  },
153  bx_yhi, ncomp, [=] AMREX_GPU_DEVICE (int i, int j, int k, int n) {
154  int jflip = 2*dom_hi.y + 1 - j;
155  if (bc_ptr[icomp+n].hi(1) == ERFBCType::foextrap) {
156  dest_arr(i,j,k,icomp+n) = dest_arr(i,dom_hi.y,k,icomp+n);
157  } else if (bc_ptr[icomp+n].hi(1) == ERFBCType::open) {
158  dest_arr(i,j,k,icomp+n) = dest_arr(i,dom_hi.y,k,icomp+n);
159  } else if (bc_ptr[icomp+n].hi(1) == ERFBCType::reflect_even) {
160  dest_arr(i,j,k,icomp+n) = dest_arr(i,jflip,k,icomp+n);
161  } else if (bc_ptr[icomp+n].hi(1) == ERFBCType::reflect_odd) {
162  dest_arr(i,j,k,icomp+n) = -dest_arr(i,jflip,k,icomp+n);
163  } else if (bc_ptr[icomp+n].hi(1) == ERFBCType::hoextrapcc) {
164  dest_arr(i,j,k,icomp+n) = 2.0*dest_arr(i,dom_hi.y,k,icomp+n) - dest_arr(i,dom_hi.y-1,k,icomp+n);
165  }
166  }
167  );
168  }
169  Gpu::streamSynchronize();
170 }
#define NVAR_max
Definition: IndexDefines.H:27
void impose_lateral_cons_bcs(const amrex::Array4< amrex::Real > &dest_arr, const amrex::Box &bx, const amrex::Box &domain, int icomp, int ncomp, int bccomp)
Definition: BoundaryConditions_cons.cpp:18
@ open
Definition: IndexDefines.H:157
@ reflect_odd
Definition: IndexDefines.H:148
@ foextrap
Definition: IndexDefines.H:151
@ ext_dir
Definition: IndexDefines.H:152
@ hoextrapcc
Definition: IndexDefines.H:158
@ reflect_even
Definition: IndexDefines.H:150

◆ impose_vertical_cons_bcs()

void ERFPhysBCFunct_cons::impose_vertical_cons_bcs ( const amrex::Array4< amrex::Real > &  dest_arr,
const amrex::Box &  bx,
const amrex::Box &  domain,
const amrex::Array4< amrex::Real const > &  z_nd,
const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM >  dxInv,
int  icomp,
int  ncomp,
int  bccomp 
)
190 {
191  BL_PROFILE_VAR("impose_lateral_cons_bcs()",impose_lateral_cons_bcs);
192  const auto& dom_lo = lbound(domain);
193  const auto& dom_hi = ubound(domain);
194 
195  GeometryData const& geomdata = m_geom.data();
196 
197  // xlo: ori = 0
198  // ylo: ori = 1
199  // zlo: ori = 2
200  // xhi: ori = 3
201  // yhi: ori = 4
202  // zhi: ori = 5
203 
204  // Based on BCRec for the domain, we need to make BCRec for this Box
205  // bccomp is used as starting index for m_domain_bcs_type
206  // 0 is used as starting index for bcrs
207  Vector<BCRec> bcrs(icomp+ncomp);
208  setBC(bx, domain, bccomp, 0, icomp+ncomp, m_domain_bcs_type, bcrs);
209 
210  Gpu::DeviceVector<BCRec> bcrs_d(icomp+ncomp);
211  Gpu::copyAsync(Gpu::hostToDevice, bcrs.begin(), bcrs.end(), bcrs_d.begin());
212  const BCRec* bc_ptr = bcrs_d.data();
213 
214  GpuArray<GpuArray<Real, AMREX_SPACEDIM*2>,AMREX_SPACEDIM+NVAR_max> l_bc_extdir_vals_d;
215  for (int i = 0; i < icomp+ncomp; i++)
216  for (int ori = 0; ori < 2*AMREX_SPACEDIM; ori++)
217  l_bc_extdir_vals_d[i][ori] = m_bc_extdir_vals[bccomp+i][ori];
218 
219  GpuArray<GpuArray<Real, AMREX_SPACEDIM*2>,AMREX_SPACEDIM+NVAR_max> l_bc_neumann_vals_d;
220  for (int i = 0; i < icomp+ncomp; i++)
221  for (int ori = 0; ori < 2*AMREX_SPACEDIM; ori++)
222  l_bc_neumann_vals_d[i][ori] = m_bc_neumann_vals[bccomp+i][ori];
223 
224 
225  {
226  Box bx_zlo(bx); bx_zlo.setBig (2,dom_lo.z-1);
227  Box bx_zhi(bx); bx_zhi.setSmall(2,dom_hi.z+1);
228  ParallelFor(
229  bx_zlo, ncomp, [=] AMREX_GPU_DEVICE (int i, int j, int k, int n) {
230  if (bc_ptr[icomp+n].lo(2) == ERFBCType::ext_dir) {
231  dest_arr(i,j,k,icomp+n) = l_bc_extdir_vals_d[icomp+n][2];
232  }
233  },
234  bx_zhi, ncomp, [=] AMREX_GPU_DEVICE (int i, int j, int k, int n) {
235  if (bc_ptr[icomp+n].hi(2) == ERFBCType::ext_dir) {
236  dest_arr(i,j,k,icomp+n) = l_bc_extdir_vals_d[icomp+n][5];
237  }
238  }
239  );
240  }
241 
242  {
243  Box bx_zlo(bx); bx_zlo.setBig (2,dom_lo.z-1);
244  Box bx_zhi(bx); bx_zhi.setSmall(2,dom_hi.z+1);
245  // Populate ghost cells on lo-z and hi-z domain boundaries
246  ParallelFor(
247  bx_zlo, ncomp, [=] AMREX_GPU_DEVICE (int i, int j, int k, int n) {
248  int kflip = dom_lo.z - 1 - i;
249  if (bc_ptr[icomp+n].lo(2) == ERFBCType::foextrap) {
250  dest_arr(i,j,k,icomp+n) = dest_arr(i,j,dom_lo.z,icomp+n);
251  } else if (bc_ptr[icomp+n].lo(2) == ERFBCType::open) {
252  dest_arr(i,j,k,icomp+n) = dest_arr(i,j,dom_lo.z,icomp+n);
253  } else if (bc_ptr[icomp+n].lo(2) == ERFBCType::reflect_even) {
254  dest_arr(i,j,k,icomp+n) = dest_arr(i,j,kflip,icomp+n);
255  } else if (bc_ptr[icomp+n].lo(2) == ERFBCType::reflect_odd) {
256  dest_arr(i,j,k,icomp+n) = -dest_arr(i,j,kflip,icomp+n);
257  } else if (bc_ptr[icomp+n].lo(2) == ERFBCType::neumann) {
258  Real delta_z = (dom_lo.z - k) / dxInv[2];
259  dest_arr(i,j,k,icomp+n) = dest_arr(i,j,dom_lo.z,icomp+n) -
260  delta_z*l_bc_neumann_vals_d[icomp+n][2]*dest_arr(i,j,dom_lo.z,Rho_comp);
261  } else if (bc_ptr[icomp+n].lo(2) == ERFBCType::hoextrapcc) {
262  dest_arr(i,j,k,icomp+n) = 2.0*dest_arr(i,j,dom_lo.z,icomp+n) - dest_arr(i,j,dom_lo.z+1,icomp+n);
263  }
264  },
265  bx_zhi, ncomp, [=] AMREX_GPU_DEVICE (int i, int j, int k, int n) {
266  int kflip = 2*dom_hi.z + 1 - i;
267  if (bc_ptr[icomp+n].hi(2) == ERFBCType::foextrap) {
268  dest_arr(i,j,k,icomp+n) = dest_arr(i,j,dom_hi.z,icomp+n);
269  } else if (bc_ptr[icomp+n].hi(2) == ERFBCType::open) {
270  dest_arr(i,j,k,icomp+n) = dest_arr(i,j,dom_hi.z,icomp+n);
271  } else if (bc_ptr[icomp+n].hi(2) == ERFBCType::reflect_even) {
272  dest_arr(i,j,k,icomp+n) = dest_arr(i,j,kflip,icomp+n);
273  } else if (bc_ptr[icomp+n].hi(2) == ERFBCType::reflect_odd) {
274  dest_arr(i,j,k,icomp+n) = -dest_arr(i,j,kflip,icomp+n);
275  } else if (bc_ptr[icomp+n].hi(2) == ERFBCType::neumann) {
276  Real delta_z = (k - dom_hi.z) / dxInv[2];
277  if( (icomp+n) == Rho_comp ) {
278  dest_arr(i,j,k,icomp+n) = dest_arr(i,j,dom_hi.z,icomp+n) +
279  delta_z*l_bc_neumann_vals_d[icomp+n][5];
280  } else {
281  dest_arr(i,j,k,icomp+n) = dest_arr(i,j,dom_hi.z,icomp+n) +
282  delta_z*l_bc_neumann_vals_d[icomp+n][5]*dest_arr(i,j,dom_hi.z,Rho_comp);
283  }
284  } else if (bc_ptr[icomp+n].hi(2) == ERFBCType::hoextrapcc){
285  dest_arr(i,j,k,icomp+n) = 2.0*dest_arr(i,j,dom_hi.z,icomp+n) - dest_arr(i,j,dom_hi.z-1,icomp+n);
286  }
287  }
288  );
289  }
290 
291  if (m_z_phys_nd) {
292  const auto& bx_lo = lbound(bx);
293  const auto& bx_hi = ubound(bx);
294 
295  // Neumann conditions (d<var>/dn = 0) must be aware of the surface normal with terrain.
296  // An additional source term arises from d<var>/dx & d<var>/dy & met_h_xi/eta/zeta.
297  //=====================================================================================
298  // Only modify scalars, U, or V
299  // Loop over each component
300  for (int n = icomp; n < icomp+ncomp; n++) {
301  // Hit for Neumann condition at kmin
302  if( bcrs[n].lo(2) == ERFBCType::foextrap)
303  {
304  // Loop over ghost cells in bottom XY-plane (valid box)
305  Box xybx = bx;
306 
307  int k0 = 0;
308  if (xybx.smallEnd(2) < 0) {
309 
310  xybx.setBig(2,dom_lo.z-1);
311  xybx.setSmall(2,bx.smallEnd()[2]);
312 
313  // Get the dz cell size
314  Real dz = geomdata.CellSize(2);
315 
316  // Fill all the Neumann srcs with terrain
317  ParallelFor(xybx, [=] AMREX_GPU_DEVICE (int i, int j, int k)
318  {
319  // Clip indices for ghost-cells
320  int ii = amrex::min(amrex::max(i,dom_lo.x),dom_hi.x);
321  int jj = amrex::min(amrex::max(j,dom_lo.y),dom_hi.y);
322 
323  // Get metrics
324  Real met_h_xi = Compute_h_xi_AtCellCenter (ii,jj,k0,dxInv,z_phys_nd);
325  Real met_h_eta = Compute_h_eta_AtCellCenter (ii,jj,k0,dxInv,z_phys_nd);
326  Real met_h_zeta = Compute_h_zeta_AtCellCenter(ii,jj,k0,dxInv,z_phys_nd);
327 
328  // GradX at IJK location inside domain -- this relies on the assumption that we have
329  // used foextrap for cell-centered quantities outside the domain to define the gradient as zero
330  Real GradVarx, GradVary;
331  if (i < dom_lo.x-1 || i > dom_hi.x+1) {
332  GradVarx = 0.0;
333  } else if (i+1 > bx_hi.x) {
334  GradVarx = dxInv[0] * (dest_arr(i ,j,k0,n) - dest_arr(i-1,j,k0,n));
335  } else if (i-1 < bx_lo.x) {
336  GradVarx = dxInv[0] * (dest_arr(i+1,j,k0,n) - dest_arr(i ,j,k0,n));
337  } else {
338  GradVarx = 0.5 * dxInv[0] * (dest_arr(i+1,j,k0,n) - dest_arr(i-1,j,k0,n));
339  }
340 
341  // GradY at IJK location inside domain -- this relies on the assumption that we have
342  // used foextrap for cell-centered quantities outside the domain to define the gradient as zero
343  if (j < dom_lo.y-1 || j > dom_hi.y+1) {
344  GradVary = 0.0;
345  } else if (j+1 > bx_hi.y) {
346  GradVary = dxInv[1] * (dest_arr(i,j ,k0,n) - dest_arr(i,j-1,k0,n));
347  } else if (j-1 < bx_lo.y) {
348  GradVary = dxInv[1] * (dest_arr(i,j+1,k0,n) - dest_arr(i,j ,k0,n));
349  } else {
350  GradVary = 0.5 * dxInv[1] * (dest_arr(i,j+1,k0,n) - dest_arr(i,j-1,k0,n));
351  }
352 
353  // Prefactor
354  Real met_fac = met_h_zeta / ( met_h_xi*met_h_xi + met_h_eta*met_h_eta + 1. );
355 
356  // Accumulate in bottom ghost cell (EXTRAP already populated)
357  dest_arr(i,j,k,n) -= dz * met_fac * ( met_h_xi * GradVarx + met_h_eta * GradVary );
358  });
359  } // box includes k0
360  } // foextrap
361  } // ncomp
362  } // m_z_phys_nd
363  Gpu::streamSynchronize();
364 }
#define Rho_comp
Definition: IndexDefines.H:12
AMREX_FORCE_INLINE AMREX_GPU_DEVICE amrex::Real Compute_h_zeta_AtCellCenter(const int &i, const int &j, const int &k, const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &cellSizeInv, const amrex::Array4< const amrex::Real > &z_nd)
Definition: TerrainMetrics.H:31
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real Compute_h_eta_AtCellCenter(const int &i, const int &j, const int &k, const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &cellSizeInv, const amrex::Array4< const amrex::Real > &z_nd)
Definition: TerrainMetrics.H:61
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real Compute_h_xi_AtCellCenter(const int &i, const int &j, const int &k, const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &cellSizeInv, const amrex::Array4< const amrex::Real > &z_nd)
Definition: TerrainMetrics.H:46
@ neumann
Definition: IndexDefines.H:155
Here is the call graph for this function:

◆ operator()()

void ERFPhysBCFunct_cons::operator() ( amrex::MultiFab &  mf,
int  icomp,
int  ncomp,
amrex::IntVect const &  nghost,
const amrex::Real  time,
int  bccomp_cons 
)
18 {
19  BL_PROFILE("ERFPhysBCFunct_cons::()");
20 
21  if (m_geom.isAllPeriodic()) return;
22 
23  const auto& domain = m_geom.Domain();
24  const auto dxInv = m_geom.InvCellSizeArray();
25 
26  // Create a grown domain box containing valid + periodic cells
27  Box gdomain = domain;
28  for (int i = 0; i < AMREX_SPACEDIM; ++i) {
29  if (m_geom.isPeriodic(i)) {
30  gdomain.grow(i, nghost[i]);
31  }
32  }
33 
34 #ifdef AMREX_USE_OMP
35 #pragma omp parallel if (Gpu::notInLaunchRegion())
36 #endif
37  {
38  for (MFIter mfi(mf,false); mfi.isValid(); ++mfi)
39  {
40  //
41  // This is the box we pass to the different routines
42  // NOTE -- this is the full grid box NOT the tile box
43  //
44  Box bx = mfi.validbox();
45 
46  //
47  // These are the boxes we use to test on relative to the domain
48  //
49  Box cbx1 = bx; cbx1.grow(IntVect(nghost[0],nghost[1],0));
50  Box cbx2 = bx; cbx2.grow(nghost);
51 
52  Array4<const Real> z_nd_arr;
53 
54  if (m_z_phys_nd)
55  {
56  z_nd_arr = m_z_phys_nd->const_array(mfi);
57  }
58 
59  if (!gdomain.contains(cbx2))
60  {
61  const Array4<Real> cons_arr = mf.array(mfi);;
62 
63  if (!m_use_real_bcs)
64  {
65  impose_lateral_cons_bcs(cons_arr,cbx1,domain,icomp,ncomp,bccomp);
66  }
67 
68  impose_vertical_cons_bcs(cons_arr,cbx2,domain,z_nd_arr,dxInv,icomp,ncomp,bccomp);
69  }
70 
71  } // MFIter
72  } // OpenMP
73 } // operator()
void impose_vertical_cons_bcs(const amrex::Array4< amrex::Real > &dest_arr, const amrex::Box &bx, const amrex::Box &domain, const amrex::Array4< amrex::Real const > &z_nd, const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > dxInv, int icomp, int ncomp, int bccomp)
Definition: BoundaryConditions_cons.cpp:186

Member Data Documentation

◆ m_bc_extdir_vals

amrex::Array<amrex::Array<amrex::Real, AMREX_SPACEDIM*2>,AMREX_SPACEDIM+NVAR_max> ERFPhysBCFunct_cons::m_bc_extdir_vals
private

◆ m_bc_neumann_vals

amrex::Array<amrex::Array<amrex::Real, AMREX_SPACEDIM*2>,AMREX_SPACEDIM+NVAR_max> ERFPhysBCFunct_cons::m_bc_neumann_vals
private

◆ m_domain_bcs_type

amrex::Vector<amrex::BCRec> ERFPhysBCFunct_cons::m_domain_bcs_type
private

◆ m_domain_bcs_type_d

amrex::Gpu::DeviceVector<amrex::BCRec> ERFPhysBCFunct_cons::m_domain_bcs_type_d
private

◆ m_geom

amrex::Geometry ERFPhysBCFunct_cons::m_geom
private

◆ m_lev

int ERFPhysBCFunct_cons::m_lev
private

◆ m_use_real_bcs

bool ERFPhysBCFunct_cons::m_use_real_bcs
private

◆ m_z_phys_nd

amrex::MultiFab* ERFPhysBCFunct_cons::m_z_phys_nd
private

The documentation for this class was generated from the following files: