ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
BelowGroundGhostSync Struct Reference

#include <ERF_PhysBCFunct.H>

Collaboration diagram for BelowGroundGhostSync:

Public Member Functions

void operator() (amrex::MultiFab &mf, int icomp, int ncomp, const amrex::IntVect &nghost, const amrex::Geometry &geom)
 

Private Attributes

amrex::BoxArray m_src_ba
 
amrex::DistributionMapping m_src_dm
 
amrex::IntVect m_nghost
 
amrex::BoxArray m_slab_ba
 
amrex::DistributionMapping m_slab_dm
 
amrex::Vector< int > m_src_index
 

Detailed Description

Make the ghost cells below the bottom of the domain agree between boxes.

On a terrain-fitted mesh the zero-gradient condition at the bottom is corrected by the slope of the terrain times the lateral gradient of the variable at the first cell (impose_vertical_*_bcs). Each box computes that for its own ghost cells, and in the outermost ring of its lateral ghost cells the gradient can only be one-sided, so the same ghost cell below the ground holds different values in different boxes. The fill of a finer level copies ghost cells of this level, taking whichever box's copy it meets, so the finer level then depends on the box decomposition.

This replaces every ghost cell below the domain with the value computed by the box whose valid columns contain it (or, outside the domain laterally, the box at that boundary), where the lateral stencil is always centred. Values in the owning box are unchanged. The layout of the owning slabs is cached.

Member Function Documentation

◆ operator()()

void BelowGroundGhostSync::operator() ( amrex::MultiFab &  mf,
int  icomp,
int  ncomp,
const amrex::IntVect &  nghost,
const amrex::Geometry &  geom 
)
21 {
22  if (nghost[2] <= 0 || geom.isPeriodic(2)) { return; }
23 
24  const IndexType typ = mf.ixType();
25  const Box dom = amrex::convert(geom.Domain(), typ);
26  const int klo = dom.smallEnd(2);
27 
28  // The owning slab of each box that reaches the bottom of the domain: the
29  // cells below the domain under its valid columns, extended laterally over
30  // the ghost columns outside a non-periodic side of the domain that the box
31  // touches. The slabs of different boxes meet only where face-centred boxes
32  // share a face, and there both compute the value with a centred stencil.
33  // A box that starts above the bottom (a refined level that does not reach
34  // the ground) owns no cells below it and is left out.
35  if (!(m_src_ba == mf.boxArray()) || !(m_src_dm == mf.DistributionMap()) || m_nghost != nghost)
36  {
37  const BoxArray& ba = mf.boxArray();
38  const DistributionMapping& dm = mf.DistributionMap();
39  BoxList bl(typ);
40  Vector<int> pmap;
41  m_src_index.clear();
42  for (int n = 0; n < static_cast<int>(ba.size()); ++n) {
43  Box b = ba[n];
44  if (b.smallEnd(2) != klo) { continue; }
45  for (int d = 0; d < 2; ++d) {
46  if (geom.isPeriodic(d)) { continue; }
47  if (b.smallEnd(d) == dom.smallEnd(d)) { b.growLo(d, nghost[d]); }
48  if (b.bigEnd(d) == dom.bigEnd(d)) { b.growHi(d, nghost[d]); }
49  }
50  b.setRange(2, klo - nghost[2], nghost[2]);
51  bl.push_back(b);
52  pmap.push_back(dm[n]);
53  m_src_index.push_back(n);
54  }
55  m_slab_ba = BoxArray(std::move(bl));
56  m_slab_dm = pmap.empty() ? DistributionMapping() : DistributionMapping(std::move(pmap));
57  m_src_ba = mf.boxArray();
58  m_src_dm = mf.DistributionMap();
59  m_nghost = nghost;
60  }
61 
62  if (m_src_index.empty()) { return; }
63 
64  MultiFab slab(m_slab_ba, m_slab_dm, ncomp, 0);
65  for (MFIter mfi(slab); mfi.isValid(); ++mfi) {
66  const Box& sbx = mfi.validbox();
67  slab[mfi].template copy<RunOn::Device>(mf[m_src_index[mfi.index()]], sbx, icomp, sbx, 0, ncomp);
68  }
69  mf.ParallelCopy(slab, 0, icomp, ncomp, IntVect(0), nghost, geom.periodicity());
70 }
const int klo
Definition: ERF_InitCustomPert_ABL.H:75
amrex::BoxArray m_slab_ba
Definition: ERF_PhysBCFunct.H:49
amrex::IntVect m_nghost
Definition: ERF_PhysBCFunct.H:48
amrex::DistributionMapping m_src_dm
Definition: ERF_PhysBCFunct.H:47
amrex::BoxArray m_src_ba
Definition: ERF_PhysBCFunct.H:46
amrex::DistributionMapping m_slab_dm
Definition: ERF_PhysBCFunct.H:50
amrex::Vector< int > m_src_index
Definition: ERF_PhysBCFunct.H:51

Member Data Documentation

◆ m_nghost

amrex::IntVect BelowGroundGhostSync::m_nghost
private

◆ m_slab_ba

amrex::BoxArray BelowGroundGhostSync::m_slab_ba
private

◆ m_slab_dm

amrex::DistributionMapping BelowGroundGhostSync::m_slab_dm
private

◆ m_src_ba

amrex::BoxArray BelowGroundGhostSync::m_src_ba
private

◆ m_src_dm

amrex::DistributionMapping BelowGroundGhostSync::m_src_dm
private

◆ m_src_index

amrex::Vector<int> BelowGroundGhostSync::m_src_index
private

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