ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
ERF_ColumnBands.cpp File Reference
#include <set>
#include <AMReX_BoxList.H>
#include <AMReX_DistributionMapping.H>
#include <AMReX_MFIter.H>
#include <AMReX_Periodicity.H>
#include "ERF_ColumnBands.H"
Include dependency graph for ERF_ColumnBands.cpp:

Functions

Vector< int > column_bands (const BoxArray &ba)
 
void fill_below_band (MultiFab &mf, int icomp, int ncomp, int klo_band, const IntVect &lateral_ng, const Geometry &geom)
 

Function Documentation

◆ column_bands()

Vector<int> column_bands ( const BoxArray &  ba)
14 {
15  std::set<int> klo;
16  for (int ib = 0; ib < static_cast<int>(ba.size()); ++ib) {
17  klo.insert(ba[ib].smallEnd(2));
18  }
19  return Vector<int>(klo.begin(), klo.end());
20 }
const int klo
Definition: ERF_InitCustomPert_ABL.H:75

Referenced by ERF::erf_enforce_hse(), erf_init_dens_hse_dry(), and rebalance_columns().

Here is the caller graph for this function:

◆ fill_below_band()

void fill_below_band ( MultiFab &  mf,
int  icomp,
int  ncomp,
int  klo_band,
const IntVect &  lateral_ng,
const Geometry &  geom 
)
25 {
26  AMREX_ALWAYS_ASSERT(lateral_ng[2] == 0);
27  AMREX_ALWAYS_ASSERT(mf.nGrowVect().allGE(lateral_ng + IntVect(0,0,1)));
28 
29  const BoxArray& ba = mf.boxArray();
30  const DistributionMapping& dm = mf.DistributionMap();
31 
32  // The slab just below each box of the band, on the rank that owns that box
33  BoxList slabs;
34  Vector<int> ranks;
35  Vector<int> owner;
36  for (int ib = 0; ib < static_cast<int>(ba.size()); ++ib) {
37  if (ba[ib].smallEnd(2) == klo_band) {
38  Box slab = amrex::grow(ba[ib], lateral_ng);
39  slab.setRange(2, klo_band-1);
40  slabs.push_back(slab);
41  ranks.push_back(dm[ib]);
42  owner.push_back(ib);
43  }
44  }
45  if (slabs.isEmpty()) { return; }
46 
47  MultiFab below(BoxArray(std::move(slabs)), DistributionMapping(std::move(ranks)), ncomp, 0);
48 
49  // A cell with no box of this level below it keeps the value it has
50  for (MFIter mfi(below); mfi.isValid(); ++mfi) {
51  const Box& bx = mfi.validbox();
52  below[mfi].copy<RunOn::Device>(mf[owner[mfi.index()]], bx, icomp, bx, 0, ncomp);
53  }
54 
55  //
56  // Only a box below the band reaches a slab: a box of the band or above starts at klo_band or
57  // higher, and neither its lateral ghost cells nor its lateral periodic images extend below
58  // that. So both copies read columns that are already integrated. The lateral ghost cells
59  // of the boxes below go first, so that a cell inside a box below then takes that box's own
60  // value. The periodicity is lateral only: a periodic image in z would bring a box from the
61  // top of the domain below the band.
62  //
63  const Box& domain = geom.Domain();
64  const Periodicity lateral_period(IntVect(geom.isPeriodic(0) ? domain.length(0) : 0,
65  geom.isPeriodic(1) ? domain.length(1) : 0,
66  0));
67  below.ParallelCopy(mf, icomp, 0, ncomp, lateral_ng, IntVect(0), lateral_period);
68  below.ParallelCopy(mf, icomp, 0, ncomp, IntVect(0), IntVect(0), lateral_period);
69 
70  for (MFIter mfi(below); mfi.isValid(); ++mfi) {
71  const Box& bx = mfi.validbox();
72  mf[owner[mfi.index()]].copy<RunOn::Device>(below[mfi], bx, 0, bx, icomp, ncomp);
73  }
74 }
AMREX_ALWAYS_ASSERT(bx.length()[2]==khi+1)

Referenced by ERF::erf_enforce_hse(), and erf_init_dens_hse_dry().

Here is the call graph for this function:
Here is the caller graph for this function: