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

#include <ERF_PhysBCFunct.H>

Collaboration diagram for ERFPhysBCFunct_w_no_terrain:

Public Member Functions

 ERFPhysBCFunct_w_no_terrain (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, const bool use_real_bcs)
 
 ~ERFPhysBCFunct_w_no_terrain ()
 
void operator() (amrex::MultiFab &mf, int icomp, int ncomp, amrex::IntVect const &nghost, const amrex::Real time, int bccomp_w)
 
void impose_lateral_zvel_bcs (const amrex::Array4< amrex::Real > &dest_arr, const amrex::Box &bx, const amrex::Box &domain, int bccomp_w)
 
void impose_vertical_zvel_bcs (const amrex::Array4< amrex::Real > &dest_arr, const amrex::Box &bx, const amrex::Box &domain, int bccomp_w)
 

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
 
bool m_use_real_bcs
 

Constructor & Destructor Documentation

◆ ERFPhysBCFunct_w_no_terrain()

ERFPhysBCFunct_w_no_terrain::ERFPhysBCFunct_w_no_terrain ( 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,
const bool  use_real_bcs 
)
inline
258  : m_lev(lev),
259  m_geom(geom), m_domain_bcs_type(domain_bcs_type),
260  m_domain_bcs_type_d(domain_bcs_type_d),
261  m_bc_extdir_vals(bc_extdir_vals),
262  m_bc_neumann_vals(bc_neumann_vals),
263  m_use_real_bcs(use_real_bcs)
264  {}
amrex::Vector< amrex::BCRec > m_domain_bcs_type
Definition: ERF_PhysBCFunct.H:291
int m_lev
Definition: ERF_PhysBCFunct.H:289
amrex::Array< amrex::Array< amrex::Real, AMREX_SPACEDIM *2 >, AMREX_SPACEDIM+NVAR_max > m_bc_neumann_vals
Definition: ERF_PhysBCFunct.H:294
bool m_use_real_bcs
Definition: ERF_PhysBCFunct.H:295
amrex::Geometry m_geom
Definition: ERF_PhysBCFunct.H:290
amrex::Gpu::DeviceVector< amrex::BCRec > m_domain_bcs_type_d
Definition: ERF_PhysBCFunct.H:292
amrex::Array< amrex::Array< amrex::Real, AMREX_SPACEDIM *2 >, AMREX_SPACEDIM+NVAR_max > m_bc_extdir_vals
Definition: ERF_PhysBCFunct.H:293

◆ ~ERFPhysBCFunct_w_no_terrain()

ERFPhysBCFunct_w_no_terrain::~ERFPhysBCFunct_w_no_terrain ( )
inline
266 {}

Member Function Documentation

◆ impose_lateral_zvel_bcs()

void ERFPhysBCFunct_w_no_terrain::impose_lateral_zvel_bcs ( const amrex::Array4< amrex::Real > &  dest_arr,
const amrex::Box &  bx,
const amrex::Box &  domain,
int  bccomp_w 
)
297 {
298  BL_PROFILE_VAR("impose_lateral_zvel_bcs()",impose_lateral_zvel_bcs);
299  const auto& dom_lo = lbound(domain);
300  const auto& dom_hi = ubound(domain);
301 
302  // Based on BCRec for the domain, we need to make BCRec for this Box
303  // bccomp is used as starting index for m_domain_bcs_type
304  // 0 is used as starting index for bcrs
305  int ncomp = 1;
306  Vector<BCRec> bcrs_w(1);
307  setBC(enclosedCells(bx), domain, bccomp, 0, 1, m_domain_bcs_type, bcrs_w);
308 
309  // xlo: ori = 0
310  // ylo: ori = 1
311  // zlo: ori = 2
312  // xhi: ori = 3
313  // yhi: ori = 4
314  // zhi: ori = 5
315 
316  Gpu::DeviceVector<BCRec> bcrs_w_d(ncomp);
317  Gpu::copyAsync(Gpu::hostToDevice, bcrs_w.begin(), bcrs_w.end(), bcrs_w_d.begin());
318  const BCRec* bc_ptr_w = bcrs_w_d.data();
319 
320  GpuArray<GpuArray<Real, AMREX_SPACEDIM*2>,AMREX_SPACEDIM+NVAR_max> l_bc_extdir_vals_d;
321 
322  for (int i = 0; i < ncomp; i++)
323  for (int ori = 0; ori < 2*AMREX_SPACEDIM; ori++)
324  l_bc_extdir_vals_d[i][ori] = m_bc_extdir_vals[bccomp+i][ori];
325 
326  GeometryData const& geomdata = m_geom.data();
327  bool is_periodic_in_x = geomdata.isPeriodic(0);
328  bool is_periodic_in_y = geomdata.isPeriodic(1);
329 
330  FArrayBox dhdtfab;
331 
332  // First do all ext_dir bcs
333  if (!is_periodic_in_x)
334  {
335  Box bx_xlo(bx); bx_xlo.setBig (0,dom_lo.x-1);
336  Box bx_xhi(bx); bx_xhi.setSmall(0,dom_hi.x+1);
337  ParallelFor(
338  bx_xlo, ncomp, [=] AMREX_GPU_DEVICE (int i, int j, int k, int n) {
339  int iflip = dom_lo.x - 1 - i;
340  if (bc_ptr_w[n].lo(0) == ERFBCType::ext_dir) {
341  dest_arr(i,j,k) = l_bc_extdir_vals_d[n][0];
342  } else if (bc_ptr_w[n].lo(0) == ERFBCType::foextrap) {
343  dest_arr(i,j,k) = dest_arr(dom_lo.x,j,k);
344  } else if (bc_ptr_w[n].lo(0) == ERFBCType::open) {
345  dest_arr(i,j,k) = dest_arr(dom_lo.x,j,k);
346  } else if (bc_ptr_w[n].lo(0) == ERFBCType::reflect_even) {
347  dest_arr(i,j,k) = dest_arr(iflip,j,k);
348  } else if (bc_ptr_w[n].lo(0) == ERFBCType::reflect_odd) {
349  dest_arr(i,j,k) = -dest_arr(iflip,j,k);
350  }
351  },
352  bx_xhi, ncomp, [=] AMREX_GPU_DEVICE (int i, int j, int k, int n) {
353  int iflip = 2*dom_hi.x + 1 - i;
354  if (bc_ptr_w[n].hi(0) == ERFBCType::ext_dir) {
355  dest_arr(i,j,k) = l_bc_extdir_vals_d[n][3];
356  } else if (bc_ptr_w[n].hi(0) == ERFBCType::foextrap) {
357  dest_arr(i,j,k) = dest_arr(dom_hi.x,j,k);
358  } else if (bc_ptr_w[n].hi(0) == ERFBCType::open) {
359  dest_arr(i,j,k) = dest_arr(dom_hi.x,j,k);
360  } else if (bc_ptr_w[n].hi(0) == ERFBCType::reflect_even) {
361  dest_arr(i,j,k) = dest_arr(iflip,j,k);
362  } else if (bc_ptr_w[n].hi(0) == ERFBCType::reflect_odd) {
363  dest_arr(i,j,k) = -dest_arr(iflip,j,k);
364  }
365  }
366  );
367  }
368 
369  // First do all ext_dir bcs
370  if (!is_periodic_in_y)
371  {
372  Box bx_ylo(bx); bx_ylo.setBig (1,dom_lo.y-1);
373  Box bx_yhi(bx); bx_yhi.setSmall(1,dom_hi.y+1);
374  ParallelFor(bx_ylo, ncomp, [=] AMREX_GPU_DEVICE (int i, int j, int k, int n) {
375  int jflip = dom_lo.y - 1 - j;
376  if (bc_ptr_w[n].lo(1) == ERFBCType::ext_dir) {
377  dest_arr(i,j,k) = l_bc_extdir_vals_d[n][1];
378  } else if (bc_ptr_w[n].lo(1) == ERFBCType::foextrap) {
379  dest_arr(i,j,k) = dest_arr(i,dom_lo.y,k);
380  } else if (bc_ptr_w[n].lo(1) == ERFBCType::open) {
381  dest_arr(i,j,k) = dest_arr(i,dom_lo.y,k);
382  } else if (bc_ptr_w[n].lo(1) == ERFBCType::reflect_even) {
383  dest_arr(i,j,k) = dest_arr(i,jflip,k);
384  } else if (bc_ptr_w[n].lo(1) == ERFBCType::reflect_odd) {
385  dest_arr(i,j,k) = -dest_arr(i,jflip,k);
386  }
387  },
388  bx_yhi, ncomp, [=] AMREX_GPU_DEVICE (int i, int j, int k, int n) {
389  int jflip = 2*dom_hi.y + 1 - j;
390  if (bc_ptr_w[n].hi(1) == ERFBCType::ext_dir) {
391  dest_arr(i,j,k) = l_bc_extdir_vals_d[n][4];
392  } else if (bc_ptr_w[n].hi(1) == ERFBCType::foextrap) {
393  dest_arr(i,j,k) = dest_arr(i,dom_hi.y,k);
394  } else if (bc_ptr_w[n].hi(1) == ERFBCType::open) {
395  dest_arr(i,j,k) = dest_arr(i,dom_hi.y,k);
396  } else if (bc_ptr_w[n].hi(1) == ERFBCType::reflect_even) {
397  dest_arr(i,j,k) = dest_arr(i,jflip,k);
398  } else if (bc_ptr_w[n].hi(1) == ERFBCType::reflect_odd) {
399  dest_arr(i,j,k) = -dest_arr(i,jflip,k);
400  }
401  });
402  }
403 
404  Gpu::streamSynchronize();
405 }
#define NVAR_max
Definition: IndexDefines.H:27
void impose_lateral_zvel_bcs(const amrex::Array4< amrex::Real > &dest_arr, const amrex::Box &bx, const amrex::Box &domain, int bccomp_w)
Definition: BoundaryConditions_zvel.cpp:294
@ open
Definition: IndexDefines.H:157
@ reflect_odd
Definition: IndexDefines.H:148
@ foextrap
Definition: IndexDefines.H:151
@ ext_dir
Definition: IndexDefines.H:152
@ reflect_even
Definition: IndexDefines.H:150

◆ impose_vertical_zvel_bcs()

void ERFPhysBCFunct_w_no_terrain::impose_vertical_zvel_bcs ( const amrex::Array4< amrex::Real > &  dest_arr,
const amrex::Box &  bx,
const amrex::Box &  domain,
int  bccomp_w 
)
419 {
420  BL_PROFILE_VAR("impose_vertical_zvel_bcs()",impose_vertical_zvel_bcs);
421  const auto& dom_lo = lbound(domain);
422  const auto& dom_hi = ubound(domain);
423 
424  // xlo: ori = 0
425  // ylo: ori = 1
426  // zlo: ori = 2
427  // xhi: ori = 3
428  // yhi: ori = 4
429  // zhi: ori = 5
430 
431  // Based on BCRec for the domain, we need to make BCRec for this Box
432  // bccomp is used as starting index for m_domain_bcs_type
433  // 0 is used as starting index for bcrs
434  int ncomp = 1;
435  Vector<BCRec> bcrs_w(1);
436  setBC(enclosedCells(bx), domain, bccomp_w, 0, 1, m_domain_bcs_type, bcrs_w);
437 
438  // We use these for the asserts below
439  const BCRec* bc_ptr_w_h = bcrs_w.data();
440 
441  GpuArray<GpuArray<Real, AMREX_SPACEDIM*2>,AMREX_SPACEDIM+NVAR_max> l_bc_extdir_vals_d;
442 
443  for (int i = 0; i < ncomp; i++) {
444  for (int ori = 0; ori < 2*AMREX_SPACEDIM; ori++) {
445  l_bc_extdir_vals_d[i][ori] = m_bc_extdir_vals[bccomp_w+i][ori];
446  }
447  }
448 
449  // *******************************************************
450  // Bottom boundary
451  // *******************************************************
452 
453  if (bx.smallEnd(2) == dom_lo.z) {
454  AMREX_ALWAYS_ASSERT(bc_ptr_w_h[0].lo(2) == ERFBCType::ext_dir);
455  ParallelFor(makeSlab(bx,2,dom_lo.z), [=] AMREX_GPU_DEVICE (int i, int j, int k) {
456  dest_arr(i,j,k) = l_bc_extdir_vals_d[0][2];
457  });
458  }
459 
460  // *******************************************************
461  // Top boundary
462  // *******************************************************
463 
464  // NOTE: if we set SlipWall at top, that generates ERFBCType::ext_dir which sets w=0 here
465  // NOTE: if we set Outflow at top, that generates ERFBCType::foextrap which doesn't touch w here
466  if (bx.bigEnd(2) == dom_hi.z+1) {
467  AMREX_ALWAYS_ASSERT(bc_ptr_w_h[0].hi(2) == ERFBCType::ext_dir ||
468  bc_ptr_w_h[0].hi(2) == ERFBCType::neumann_int);
469  if (bc_ptr_w_h[0].hi(2) == ERFBCType::ext_dir) {
470  ParallelFor(makeSlab(bx,2,dom_hi.z+1), [=] AMREX_GPU_DEVICE (int i, int j, int k)
471  {
472  dest_arr(i,j,k) = l_bc_extdir_vals_d[0][5];
473  });
474  } else if (bc_ptr_w_h[0].hi(2) == ERFBCType::neumann_int) {
475  ParallelFor(makeSlab(bx,2,dom_hi.z+1), [=] AMREX_GPU_DEVICE (int i, int j, int k)
476  {
477  dest_arr(i,j,k) = (4.0*dest_arr(i,j,dom_hi.z) - dest_arr(i,j,dom_hi.z-1))/3.0;
478  });
479  }
480  }
481  Gpu::streamSynchronize();
482 }
void impose_vertical_zvel_bcs(const amrex::Array4< amrex::Real > &dest_arr, const amrex::Box &bx, const amrex::Box &domain, int bccomp_w)
Definition: BoundaryConditions_zvel.cpp:416
@ neumann_int
Definition: IndexDefines.H:156

◆ operator()()

void ERFPhysBCFunct_w_no_terrain::operator() ( amrex::MultiFab &  mf,
int  icomp,
int  ncomp,
amrex::IntVect const &  nghost,
const amrex::Real  time,
int  bccomp_w 
)
260 {
261  BL_PROFILE("ERFPhysBCFunct_w::()");
262 
263  if (m_geom.isAllPeriodic()) return;
264 
265  const auto& domain = m_geom.Domain();
266 
267  Box gdomainz = surroundingNodes(domain,2);
268  for (int i = 0; i < AMREX_SPACEDIM; ++i) {
269  if (m_geom.isPeriodic(i)) {
270  gdomainz.grow(i, nghost[i]);
271  }
272  }
273 
274 #ifdef AMREX_USE_OMP
275 #pragma omp parallel if (Gpu::notInLaunchRegion())
276 #endif
277  {
278  for (MFIter mfi(mf,false); mfi.isValid(); ++mfi)
279  {
280  //
281  // This is the box we pass to the different routines
282  // NOTE -- this is the full grid NOT the tile box
283  //
284  Box bx = mfi.validbox();
285 
286  //
287  // These are the boxes we use to test on relative to the domain
288  //
289  Box zbx = surroundingNodes(bx,2); zbx.grow(0,nghost[0]);
290  zbx.grow(1,nghost[1]);
291 
292  if (!m_use_real_bcs)
293  {
294  Array4< Real> const& velz_arr = mf.array(mfi);;
295  if (!gdomainz.contains(zbx))
296  {
297  impose_lateral_zvel_bcs(velz_arr,zbx,domain,bccomp);
298  }
299  } // m_use_real_bcs
300 
301  const Array4< Real> velz_arr = mf.array(mfi);;
302  if (!gdomainz.contains(zbx)) {
303  impose_vertical_zvel_bcs(velz_arr,zbx,domain,bccomp);
304  }
305 
306  } // MFIter
307  } // OpenMP
308 } // operator()

Member Data Documentation

◆ m_bc_extdir_vals

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

◆ m_bc_neumann_vals

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

◆ m_domain_bcs_type

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

◆ m_domain_bcs_type_d

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

◆ m_geom

amrex::Geometry ERFPhysBCFunct_w_no_terrain::m_geom
private

◆ m_lev

int ERFPhysBCFunct_w_no_terrain::m_lev
private

◆ m_use_real_bcs

bool ERFPhysBCFunct_w_no_terrain::m_use_real_bcs
private

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