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

#include <ERF_FillPatcher.H>

Collaboration diagram for ERFFillPatcher:

Public Member Functions

 ERFFillPatcher (amrex::BoxArray const &fba, amrex::DistributionMapping const &fdm, amrex::Geometry const &fgeom, amrex::BoxArray const &cba, amrex::DistributionMapping const &cdm, amrex::Geometry const &cgeom, int nghost, int nghost_set, int ncomp, amrex::InterpBase *interp)
 
void Define (amrex::BoxArray const &fba, amrex::DistributionMapping const &fdm, amrex::Geometry const &fgeom, amrex::BoxArray const &cba, amrex::DistributionMapping const &cdm, amrex::Geometry const &cgeom, int nghost, int nghost_set, int ncomp, amrex::InterpBase *interp)
 
void BuildMask (amrex::BoxArray const &fba, int nghost, int nghost_set)
 
void RegisterCoarseData (amrex::Vector< amrex::MultiFab const * > const &crse_data, amrex::Vector< double > const &crse_time)
 
void InterpFace (amrex::MultiFab &fine, amrex::MultiFab const &crse, int mask_val)
 
void InterpCell (amrex::MultiFab &fine, amrex::MultiFab const &crse, amrex::Vector< amrex::BCRec > const &bcr, int mask_val)
 
int GetSetMaskVal ()
 
int GetRelaxMaskVal ()
 
amrex::iMultiFab * GetMask ()
 
template<typename BC >
void FillSet (amrex::MultiFab &mf, double time, BC &cbc, amrex::Vector< amrex::BCRec > const &bcs)
 
template<typename BC >
void FillRelax (amrex::MultiFab &mf, double time, BC &cbc, amrex::Vector< amrex::BCRec > const &bcs)
 
template<typename BC >
void Fill (amrex::MultiFab &mf, double time, BC &cbc, amrex::Vector< amrex::BCRec > const &bcs, int mask_val)
 

Private Attributes

amrex::BoxArray m_fba
 
amrex::BoxArray m_cba
 
amrex::DistributionMapping m_fdm
 
amrex::DistributionMapping m_cdm
 
amrex::Geometry m_fgeom
 
amrex::Geometry m_cgeom
 
int m_nghost
 
int m_nghost_subset
 
int m_ncomp
 
amrex::InterpBase * m_interp
 
amrex::IntVect m_ratio
 
std::unique_ptr< amrex::MultiFab > m_cf_crse_data_old
 
std::unique_ptr< amrex::MultiFab > m_cf_crse_data_new
 
std::unique_ptr< amrex::iMultiFab > m_cf_mask
 
amrex::Vector< double > m_crse_times
 
double m_dt_crse
 
int m_set_mask {2}
 
int m_relax_mask {1}
 

Constructor & Destructor Documentation

◆ ERFFillPatcher()

ERFFillPatcher::ERFFillPatcher ( amrex::BoxArray const &  fba,
amrex::DistributionMapping const &  fdm,
amrex::Geometry const &  fgeom,
amrex::BoxArray const &  cba,
amrex::DistributionMapping const &  cdm,
amrex::Geometry const &  cgeom,
int  nghost,
int  nghost_set,
int  ncomp,
amrex::InterpBase *  interp 
)

Construct a coarse-fine fill patcher.

Parameters
[in]fbafine-level BoxArray
[in]fdmfine-level DistributionMapping
[in]fgeomfine-level Geometry
[in]cbacoarse-level BoxArray
[in]cdmcoarse-level DistributionMapping
[in]cgeomcoarse-level Geometry
[in]nghostnumber of ghost cells in the fill region
[in]nghost_setnumber of ghost cells in the set region
[in]ncompnumber of components
[in]interpinterpolation operator

Fill valid and ghost data with the "state data" at the given time

Parameters
[in]fbaBoxArray of data to be filled at fine level
[in]fdmDistributionMapping of data to be filled at fine level
[in]fgeomcontainer of geometry information at fine level
[in]cbaBoxArray of data to be filled at coarse level
[in]cdmDistributionMapping of data to be filled at coarse level
[in]cgeomcontainer of geometry information at coarse level
[in]nghostnumber of ghost cells to be filled
[in]nghost_setnumber of ghost cells in the set region
[in]ncompnumber of components to be filled
[in]interpinterpolation operator to be used
28  : m_fba(fba),
29  m_cba(cba),
30  m_fdm(fdm),
31  m_cdm(cdm),
32  m_fgeom(fgeom),
33  m_cgeom(cgeom)
34 {
35  AMREX_ALWAYS_ASSERT(fba.ixType() == cba.ixType());
36 
37  // Vector to hold times for coarse data
38  m_crse_times.resize(2);
39 
40  // Define the coarse and fine MFs
41  Define(fba, fdm, fgeom, cba, cdm, cgeom,nghost, nghost_set, ncomp, interp);
42 }
AMREX_ALWAYS_ASSERT(bx.length()[2]==khi+1)
amrex::Geometry m_fgeom
Definition: ERF_FillPatcher.H:153
amrex::BoxArray m_fba
Definition: ERF_FillPatcher.H:149
amrex::BoxArray m_cba
Definition: ERF_FillPatcher.H:150
void Define(amrex::BoxArray const &fba, amrex::DistributionMapping const &fdm, amrex::Geometry const &fgeom, amrex::BoxArray const &cba, amrex::DistributionMapping const &cdm, amrex::Geometry const &cgeom, int nghost, int nghost_set, int ncomp, amrex::InterpBase *interp)
Definition: ERF_FillPatcher.cpp:59
amrex::DistributionMapping m_cdm
Definition: ERF_FillPatcher.H:152
amrex::Geometry m_cgeom
Definition: ERF_FillPatcher.H:154
amrex::Vector< double > m_crse_times
Definition: ERF_FillPatcher.H:163
amrex::DistributionMapping m_fdm
Definition: ERF_FillPatcher.H:151
Here is the call graph for this function:

Member Function Documentation

◆ BuildMask()

void ERFFillPatcher::BuildMask ( amrex::BoxArray const &  fba,
int  nghost,
int  nghost_set 
)

Build the coarse-fine mask.

Parameters
[in]fbafine-level BoxArray
[in]nghostnumber of ghost cells in the fill region
[in]nghost_setnumber of ghost cells in the set region

Build the coarse-fine mask for set and relax regions.

Parameters
[in]fbaBoxArray of data to be filled at fine level
[in]nghostnumber of ghost cells defining the region width
[in]mask_valvalue assigned to selected mask cells
131 {
132  // Minimal bounding box of fine BA plus a halo cell
133  Box fba_bnd = grow(fba.minimalBox(), IntVect(1,1,1));
134 
135  BoxArray fba_per;
136  Box fdomain = m_fgeom.Domain();
137  // Here we add additional boxes that are periodic wraparounds of existing boxes
138  if (m_fgeom.isAnyPeriodic())
139  {
140  Box domain_cc(fdomain); domain_cc.enclosedCells();
141  BoxList bl_mf = fba.boxList();
142  BoxList bl_mf_new;
143  for (auto& b : bl_mf) {
144  for (int dim = 0; dim < AMREX_SPACEDIM; dim++) {
145  if (m_fgeom.isPeriodic(dim)) {
146  int n = domain_cc.length(dim);
147  if (b.smallEnd(dim) == fdomain.smallEnd(dim)) {
148  Box bb_lo(b); bb_lo.enclosedCells(); bb_lo.shift(dim,n); bb_lo.setType(b.ixType());
149  bb_lo &= fba_bnd;
150  bl_mf_new.push_back(bb_lo);
151  }
152  Box bb_hi(b); bb_hi.enclosedCells();
153  if (bb_hi.bigEnd(dim) == fdomain.bigEnd(dim)) {
154  bb_hi.shift(dim,-n); bb_hi.setType(b.ixType());
155  bb_hi &= fba_bnd;
156  bl_mf_new.push_back(bb_hi);
157  }
158  } // periodic
159  } // dim
160  } // bl_mf
161 
162  for (auto& b : bl_mf_new) {
163  bl_mf.push_back(b);
164  } // bl_mf
165  fba_per.define(std::move(bl_mf));
166 
167  } else {
168  fba_per = fba;
169  }
170 
171  // BoxList and BoxArray to store complement
172  BoxList com_bl; BoxArray com_ba;
173 
174  // Compute the complement
175  fba_per.complementIn(com_bl,fba_bnd);
176 
177  // com_bl cannot be null since we grew with halo cells
178  AMREX_ALWAYS_ASSERT(com_bl.size() > 0);
179 
180  IntVect box_grow_vect(-nghost,-nghost,0);
181 
182  // cf_set_width = cf_width = 0 is a special case
183  // In this case we set only the normal velocities
184  // (not any cell-centered quantities) and only
185  // on the coarse-fine boundary itself
186  if (nghost == 0) {
187  if (fba.ixType()[0] == IndexType::NODE) {
188  box_grow_vect = IntVect(1,0,0);
189  } else if (fba.ixType()[1] == IndexType::NODE) {
190  box_grow_vect = IntVect(0,1,0);
191  } else if (fba.ixType()[2] == IndexType::NODE) {
192  box_grow_vect = IntVect(0,0,1);
193  }
194  }
195 
196  // Grow the complement boxes and trim with the bounding box
197  Vector<Box>& com_bl_v = com_bl.data();
198  for (int i(0); i<com_bl.size(); ++i) {
199  Box& bx = com_bl_v[i];
200  bx.grow(box_grow_vect);
201  bx &= fba_bnd;
202  }
203 
204 
205  // Do second complement with the grown boxes
206  com_ba.define(std::move(com_bl));
207  com_ba.complementIn(com_bl, fba_bnd);
208 
209  // Fill mask based upon the com_bl BoxList
210  for (MFIter mfi(*m_cf_mask); mfi.isValid(); ++mfi) {
211  const Box& vbx = mfi.validbox();
212  const Array4<int>& mask_arr = m_cf_mask->array(mfi);
213 
214  for (auto const& b : com_bl) {
215  Box com_bx = vbx & b;
216  ParallelFor(com_bx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept
217  {
218  mask_arr(i,j,k) = mask_val;
219  });
220  }
221  }
222 }
ParallelFor(fab_box, [=] AMREX_GPU_DEVICE(int i, int j, int k) { qrcuten_arr(i, j, k)=Real(0);qscuten_arr(i, j, k)=Real(0);qicuten_arr(i, j, k)=Real(0);})
std::unique_ptr< amrex::iMultiFab > m_cf_mask
Definition: ERF_FillPatcher.H:162

Referenced by Define().

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

◆ Define()

void ERFFillPatcher::Define ( amrex::BoxArray const &  fba,
amrex::DistributionMapping const &  fdm,
amrex::Geometry const &  fgeom,
amrex::BoxArray const &  cba,
amrex::DistributionMapping const &  cdm,
amrex::Geometry const &  cgeom,
int  nghost,
int  nghost_set,
int  ncomp,
amrex::InterpBase *  interp 
)

Define the coarse-fine fill patcher.

Parameters
[in]fbafine-level BoxArray
[in]fdmfine-level DistributionMapping
[in]fgeomfine-level Geometry
[in]cbacoarse-level BoxArray
[in]cdmcoarse-level DistributionMapping
[in]cgeomcoarse-level Geometry
[in]nghostnumber of ghost cells in the fill region
[in]nghost_setnumber of ghost cells in the set region
[in]ncompnumber of components
[in]interpinterpolation operator

Redefine the coarse and fine patch MultiFabs.

Parameters
[in]fbaBoxArray of data to be filled at fine level
[in]fdmDistributionMapping of data to be filled at fine level
[in]fgeomcontainer of geometry information at fine level
[in]cbaBoxArray of data to be filled at coarse level
[in]cdmDistributionMapping of data to be filled at coarse level
[in]cgeomcontainer of geometry information at coarse level
[in]nghostnumber of ghost cells to be filled
[in]nghost_setnumber of ghost cells in the set region
[in]ncompnumber of components to be filled
[in]interpinterpolation operator to be used
65 {
66  AMREX_ALWAYS_ASSERT(nghost <= 0);
67  AMREX_ALWAYS_ASSERT(nghost_set <= 0);
68  AMREX_ALWAYS_ASSERT(nghost <= nghost_set);
69 
70  // Set data members
71  m_fba = fba; m_cba = cba;
72  m_fdm = fdm; m_cdm = cdm;
73  m_fgeom = fgeom; m_cgeom = cgeom;
74  m_nghost = nghost; m_nghost_subset = nghost_set;
75  m_ncomp = ncomp; m_interp = interp;
76 
77  // Delete old MFs if they exist
80  if (m_cf_mask) m_cf_mask.reset();
81 
82  // Index type for the BL/BA
83  IndexType m_ixt = fba.ixType();
84 
85  // Refinement ratios
86  for (int idim = 0; idim < AMREX_SPACEDIM; ++idim) {
87  m_ratio[idim] = m_fgeom.Domain().length(idim) / m_cgeom.Domain().length(idim);
88  }
89 
90  // Coarse box list
91  // NOTE: if we use face_cons_linear_interp then CoarseBox returns the grown box
92  // so we don't need to manually grow it here
93  BoxList cbl;
94  cbl.set(m_ixt);
95  cbl.reserve(fba.size());
96  for (int i(0); i < fba.size(); ++i) {
97  Box coarse_box(interp->CoarseBox(fba[i], m_ratio));
98  cbl.push_back(coarse_box);
99  }
100 
101  // Box arrays for the coarse data
102  BoxArray cf_cba(std::move(cbl));
103 
104  // Two coarse patches to hold the data to be interpolated
105  m_cf_crse_data_old = std::make_unique<MultiFab> (cf_cba, fdm, m_ncomp, 0);
106  m_cf_crse_data_new = std::make_unique<MultiFab> (cf_cba, fdm, m_ncomp, 0);
107 
108  // Integer masking array
109  m_cf_mask = std::make_unique<iMultiFab> (fba, fdm, 1, 0);
110 
111  // Populate mask array
112  if (nghost_set <= 0) {
113  m_cf_mask->setVal(m_set_mask);
114  BuildMask(fba,nghost_set,m_set_mask-1);
115  } else {
116  m_cf_mask->setVal(m_relax_mask);
117  BuildMask(fba,nghost,m_relax_mask-1);
118  }
119 }
amrex::InterpBase * m_interp
Definition: ERF_FillPatcher.H:158
int m_ncomp
Definition: ERF_FillPatcher.H:157
int m_nghost_subset
Definition: ERF_FillPatcher.H:156
std::unique_ptr< amrex::MultiFab > m_cf_crse_data_new
Definition: ERF_FillPatcher.H:161
int m_set_mask
Definition: ERF_FillPatcher.H:165
amrex::IntVect m_ratio
Definition: ERF_FillPatcher.H:159
int m_relax_mask
Definition: ERF_FillPatcher.H:166
void BuildMask(amrex::BoxArray const &fba, int nghost, int nghost_set)
Definition: ERF_FillPatcher.cpp:128
std::unique_ptr< amrex::MultiFab > m_cf_crse_data_old
Definition: ERF_FillPatcher.H:160
int m_nghost
Definition: ERF_FillPatcher.H:155

Referenced by ERFFillPatcher().

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

◆ Fill()

template<typename BC >
void ERFFillPatcher::Fill ( amrex::MultiFab &  mf,
double  time_d,
BC &  cbc,
amrex::Vector< amrex::BCRec > const &  bcs,
int  mask_val 
)

Fill fine data in the selected mask region.

Parameters
[in,out]mfMultiFab to be filled
[in]timetime at which to fill data
[in]cbccoarse boundary condition
[in]bcsvector of boundary conditions
[in]mask_valmask value selecting cells to fill

Fill fine data in the relax region

Parameters
[in,out]mfMultiFab to be filled
[in]time_dTime at which to fill data
[in]cbcCoarse boundary condition
[in]bcsVector of boundary conditions
[in]mask_valMask value selecting cells to fill
214 {
215  constexpr double eps = std::numeric_limits<float>::epsilon();
216 
217  AMREX_ALWAYS_ASSERT((time_d >= m_crse_times[0]-eps) && (time_d <= m_crse_times[1]+eps));
218 
219  amrex::Real time = static_cast<amrex::Real>(time_d);
220 
221  // Time interpolation factors
222  amrex::Real fac_new = amrex::Real(0);
223  amrex::Real fac_old = amrex::Real(1);
224  if (amrex::Math::abs(m_dt_crse) > eps) {
225  fac_new = static_cast<amrex::Real>((time_d - m_crse_times[0]) / m_dt_crse);
226  fac_old = amrex::Real(1) - fac_new;
227  }
228 
229  // Boundary condition operator
230  cbc(*(m_cf_crse_data_old), 0, m_ncomp, amrex::IntVect(0), time, 0);
231 
232  // Coarse MF to hold time interpolated data
233  amrex::MultiFab crse_data_time_interp(m_cf_crse_data_old->boxArray(),
234  m_cf_crse_data_old->DistributionMap(),
235  m_ncomp, amrex::IntVect{0});
236 
237  // Time interpolate the coarse data
238  amrex::MultiFab::LinComb(crse_data_time_interp,
239  fac_old, *(m_cf_crse_data_old), 0,
240  fac_new, *(m_cf_crse_data_new), 0,
241  0, m_ncomp, amrex::IntVect{0});
242 
243  // Call correct spatial interpolation type
244  amrex::IndexType m_ixt = mf.boxArray().ixType();
245  int ixt_sum = m_ixt[0]+m_ixt[1]+m_ixt[2];
246  if (ixt_sum == 0) {
247  InterpCell(mf,crse_data_time_interp,bcs,mask_val);
248  } else if (ixt_sum == 1) {
249  InterpFace(mf,crse_data_time_interp,mask_val);
250  } else {
251  amrex::Abort("ERF_FillPatcher only supports face linear and cell cons linear interp!");
252  }
253 }
amrex::Real Real
Definition: ERF_ShocInterface.H:19
void InterpFace(amrex::MultiFab &fine, amrex::MultiFab const &crse, int mask_val)
Definition: ERF_FillPatcher.cpp:262
void InterpCell(amrex::MultiFab &fine, amrex::MultiFab const &crse, amrex::Vector< amrex::BCRec > const &bcr, int mask_val)
Definition: ERF_FillPatcher.cpp:388
double m_dt_crse
Definition: ERF_FillPatcher.H:164
real(c_double), parameter epsilon
Definition: ERF_module_model_constants.F90:12

Referenced by FillRelax(), and FillSet().

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

◆ FillRelax()

template<typename BC >
void ERFFillPatcher::FillRelax ( amrex::MultiFab &  mf,
double  time,
BC &  cbc,
amrex::Vector< amrex::BCRec > const &  bcs 
)

Fill fine data in the relax region.

Parameters
[in,out]mfMultiFab to be filled
[in]timetime at which to fill data
[in]cbccoarse boundary condition
[in]bcsvector of boundary conditions

Fill fine data in the relax region

Parameters
[in,out]mfMultiFab to be filled
[in]timeTime at which to fill data
[in]cbcCoarse boundary condition
[in]bcsVector of boundary conditions
197 {
198  Fill(mf,time,cbc,bcs,m_relax_mask);
199 }
void Fill(amrex::MultiFab &mf, double time, BC &cbc, amrex::Vector< amrex::BCRec > const &bcs, int mask_val)
Definition: ERF_FillPatcher.H:212

Referenced by fine_compute_interior_ghost_rhs().

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

◆ FillSet()

template<typename BC >
void ERFFillPatcher::FillSet ( amrex::MultiFab &  mf,
double  time,
BC &  cbc,
amrex::Vector< amrex::BCRec > const &  bcs 
)

Fill fine data in the set region.

Parameters
[in,out]mfMultiFab to be filled
[in]timetime at which to fill data
[in]cbccoarse boundary condition
[in]bcsvector of boundary conditions

Fill fine data in the set region

Parameters
[in,out]mfMultiFab to be filled
[in]timeTime at which to fill data
[in]cbcCoarse boundary condition
[in]bcsVector of boundary conditions
181 {
182  Fill(mf,time,cbc,bcs,m_set_mask);
183 }
Here is the call graph for this function:

◆ GetMask()

amrex::iMultiFab* ERFFillPatcher::GetMask ( )
inline

Return the coarse-fine mask.

108 { return m_cf_mask.get(); }

Referenced by fine_compute_interior_ghost_rhs().

Here is the caller graph for this function:

◆ GetRelaxMaskVal()

int ERFFillPatcher::GetRelaxMaskVal ( )
inline

Return the mask value for the relax region.

103 { return m_relax_mask; }

Referenced by fine_compute_interior_ghost_rhs().

Here is the caller graph for this function:

◆ GetSetMaskVal()

int ERFFillPatcher::GetSetMaskVal ( )
inline

Return the mask value for the set region.

98 { return m_set_mask; }

Referenced by fine_compute_interior_ghost_rhs().

Here is the caller graph for this function:

◆ InterpCell()

void ERFFillPatcher::InterpCell ( amrex::MultiFab &  fine,
amrex::MultiFab const &  crse,
amrex::Vector< amrex::BCRec > const &  bcr,
int  mask_val 
)

Interpolate coarse data to fine cell-centered data.

Parameters
[in,out]finefine-level data to fill
[in]crsecoarse-level source data
[in]bcrboundary-condition records
[in]mask_valmask value selecting cells to fill

Interpolate coarse data to fine cell-centered data selected by the mask.

Parameters
[in,out]finefine-level data to fill
[in]crsecoarse-level data to interpolate from
[in]bcrboundary-condition records used by the interpolater
[in]mask_valmask value selecting cells to fill
392 {
393  int ncomp = m_ncomp;
394  IntVect ratio = m_ratio;
395  IndexType m_ixt = fine.boxArray().ixType();
396  Box const& cdomain = convert(m_cgeom.Domain(), m_ixt);
397 
398  for (MFIter mfi(fine); mfi.isValid(); ++mfi) {
399  Box const& fbx = mfi.validbox();
400 
401  Array4<Real> const& fine_arr = fine.array(mfi);
402  Array4<Real const> const& crse_arr = crse.const_array(mfi);
403  Array4<int const> const& mask_arr = m_cf_mask->const_array(mfi);
404 
405  bool run_on_gpu = Gpu::inLaunchRegion();
406  amrex::ignore_unused(run_on_gpu);
407 
408  amrex::ignore_unused(m_fgeom);
409 
410  const Box& crse_region = m_interp->CoarseBox(fbx,ratio);
411  Box cslope_bx(crse_region);
412  for (int dim = 0; dim < AMREX_SPACEDIM; dim++) {
413  if (ratio[dim] > 1) {
414  cslope_bx.grow(dim,-1);
415  }
416  }
417 
418  FArrayBox ccfab(cslope_bx, ncomp*AMREX_SPACEDIM, The_Async_Arena());
419  Array4<Real> const& tmp = ccfab.array();
420  Array4<Real const> const& ctmp = ccfab.const_array();
421 
422 #ifdef AMREX_USE_GPU
423  AsyncArray<BCRec> async_bcr(bcr.data(), (run_on_gpu) ? ncomp : 0);
424  BCRec const* bcrp = (run_on_gpu) ? async_bcr.data() : bcr.data();
425 #else
426  BCRec const* bcrp = bcr.data();
427 #endif
428 
429  AMREX_HOST_DEVICE_PARALLEL_FOR_4D_FLAG(RunOn::Gpu, cslope_bx, ncomp, i, j, k, n,
430  {
431  mf_cell_cons_lin_interp_mcslope(i,j,k,n, tmp, crse_arr, 0, ncomp,
432  cdomain, ratio, bcrp);
433  });
434 
435  AMREX_HOST_DEVICE_PARALLEL_FOR_4D_FLAG(RunOn::Gpu, fbx, ncomp, i, j, k, n,
436  {
437  if (mask_arr(i,j,k) == mask_val) mf_cell_cons_lin_interp(i,j,k,n, fine_arr, 0, ctmp,
438  crse_arr, 0, ncomp, ratio);
439  });
440  } // MFIter
441 }
@ tmp
Definition: ERF_AdvanceWSM6.cpp:114

Referenced by Fill().

Here is the caller graph for this function:

◆ InterpFace()

void ERFFillPatcher::InterpFace ( amrex::MultiFab &  fine,
amrex::MultiFab const &  crse,
int  mask_val 
)

Interpolate coarse data to fine face data.

Parameters
[in,out]finefine-level data to fill
[in]crsecoarse-level source data
[in]mask_valmask value selecting cells to fill

Interpolate coarse data to fine face-centered data selected by the mask.

Parameters
[in,out]finefine-level data to fill
[in]crsecoarse-level data to interpolate from
[in]mask_valmask value selecting cells to fill
265 {
266  int ncomp = 1;
267  IntVect ratio = m_ratio;
268 
269  FArrayBox slope;
270 
271  //
272  // This box is only used to make sure we don't look outside
273  // the domain for computing the slopes in the interpolation
274  // We need it to be of the type of the faces being filled
275  //
276  // IndexType ixt = fine.boxArray().ixType();
277  // Box const& domface = convert(m_cgeom.Domain(), ixt);
278 
279  // We don't need to worry about face-based domain because this is only used in the tangential interpolation
280  Box per_grown_domain = m_cgeom.Domain();
281  for (int dim = 0; dim < AMREX_SPACEDIM; dim++) {
282  if (m_cgeom.isPeriodic(dim)) {
283  per_grown_domain.grow(dim,1);
284  }
285  }
286 
287  for (MFIter mfi(fine); mfi.isValid(); ++mfi)
288  {
289  Box const& fbx = mfi.validbox();
290 
291  slope.resize(fbx,ncomp,The_Async_Arena());
292 
293  Array4<Real> const& fine_arr = fine.array(mfi);
294  Array4<Real> const& slope_arr = slope.array();
295  Array4<Real const> const& crse_arr = crse.const_array(mfi);
296  Array4<int const> const& mask_arr = m_cf_mask->const_array(mfi);
297 
298  if (fbx.type(0) == IndexType::NODE) // x-faces
299  {
300  // Here do interpolation in the tangential directions
301  AMREX_HOST_DEVICE_PARALLEL_FOR_3D_FLAG(RunOn::Gpu,fbx,i,j,k,
302  {
303  if (mask_arr(i,j,k) == mask_val) { // x-faces
304  const int ii = coarsen(i,ratio[0]);
305  if (i-ii*ratio[0] == 0) {
306  interp_face_reg(i,j,k,ratio,fine_arr,0,crse_arr,slope_arr,ncomp,per_grown_domain,0);
307  }
308  }
309  });
310 
311  // Here do interpolation in the normal direction
312  // using the fine values that have already been filled
313  AMREX_HOST_DEVICE_PARALLEL_FOR_3D_FLAG(RunOn::Gpu,fbx,i,j,k,
314  {
315  if (mask_arr(i,j,k) == mask_val) {
316  const int ii = coarsen(i,ratio[0]);
317  if (i-ii*ratio[0] != 0) {
318  Real const w = static_cast<Real>(i-ii*ratio[0]) * (Real(1.0)/Real(ratio[0]));
319  fine_arr(i,j,k,0) = (Real(1.0)-w) * fine_arr(ii*ratio[0],j,k,0) + w * fine_arr((ii+1)*ratio[0],j,k,0);
320  }
321  }
322  });
323 
324  }
325  else if (fbx.type(1) == IndexType::NODE) // y-faces
326  {
327  // Here do interpolation in the tangential directions
328  AMREX_HOST_DEVICE_PARALLEL_FOR_3D_FLAG(RunOn::Gpu,fbx,i,j,k,
329  {
330  if (mask_arr(i,j,k) == mask_val) {
331  const int jj = coarsen(j,ratio[1]);
332  if (j-jj*ratio[1] == 0) {
333  interp_face_reg(i,j,k,ratio,fine_arr,0,crse_arr,slope_arr,ncomp,per_grown_domain,1);
334  }
335  }
336  });
337 
338  // Here do interpolation in the normal direction
339  // using the fine values that have already been filled
340  AMREX_HOST_DEVICE_PARALLEL_FOR_3D_FLAG(RunOn::Gpu,fbx,i,j,k,
341  {
342  if (mask_arr(i,j,k) == mask_val) {
343  const int jj = coarsen(j,ratio[1]);
344  if (j-jj*ratio[1] != 0) {
345  Real const w = static_cast<Real>(j-jj*ratio[1]) * (Real(1.0)/Real(ratio[1]));
346  fine_arr(i,j,k,0) = (Real(1.0)-w) * fine_arr(i,jj*ratio[1],k,0) + w * fine_arr(i,(jj+1)*ratio[1],k,0);
347  }
348  }
349  });
350  }
351  else // z-faces
352  {
353  // Here do interpolation in the tangential directions
354  AMREX_HOST_DEVICE_PARALLEL_FOR_3D_FLAG(RunOn::Gpu,fbx,i,j,k,
355  {
356  if (mask_arr(i,j,k) == mask_val) {
357  const int kk = coarsen(k,ratio[2]);
358  if (k-kk*ratio[2] == 0) {
359  interp_face_reg(i,j,k,ratio,fine_arr,0,crse_arr,slope_arr,1,per_grown_domain,2);
360  }
361  }
362  });
363 
364  // Here do interpolation in the normal direction
365  // using the fine values that have already been filled
366  AMREX_HOST_DEVICE_PARALLEL_FOR_3D_FLAG(RunOn::Gpu,fbx,i,j,k,
367  {
368  if (mask_arr(i,j,k) == mask_val) {
369  const int kk = coarsen(k,ratio[2]);
370  if (k-kk*ratio[2] != 0) {
371  Real const w = static_cast<Real>(k-kk*ratio[2]) * (Real(1.0)/Real(ratio[2]));
372  fine_arr(i,j,k,0) = (Real(1.0)-w) * fine_arr(i,j,kk*ratio[2],0) + w * fine_arr(i,j,(kk+1)*ratio[2],0);
373  }
374  }
375  });
376  } // IndexType::NODE
377  } // MFiter
378 }
Real w
Definition: ERF_Plotfile2DInterpolator.cpp:22

Referenced by Fill().

Here is the caller graph for this function:

◆ RegisterCoarseData()

void ERFFillPatcher::RegisterCoarseData ( amrex::Vector< amrex::MultiFab const * > const &  crse_data,
amrex::Vector< double > const &  crse_time 
)

Register coarse data bracketing the fill time.

Parameters
[in]crse_datacoarse MultiFabs
[in]crse_timetimes associated with crse_data

Register the coarse data to be used by the ERFFillPatcher

Parameters
[in]crse_datadata at old and new time at coarse level
[in]crse_timetimes at which crse_data is defined
233 {
234  AMREX_ALWAYS_ASSERT(crse_data.size() == 2); // old and new
235  AMREX_ALWAYS_ASSERT(crse_time[1] >= crse_time[0]);
236 
237  // NOTE: CoarseBox with CellConsLinear interpolation grows the
238  // box by 1 in all directions. This pushes the domain for
239  // m_cf_crse_data into ghost cells in the z-dir. So we need
240  // to include ghost cells for crse_data when doing the copy
241  IntVect src_ng = crse_data[0]->nGrowVect();
242  IntVect dst_ng = m_cf_crse_data_old->nGrowVect();
243 
244  m_cf_crse_data_old->ParallelCopy(*(crse_data[0]), 0, 0, m_ncomp,
245  src_ng, dst_ng, m_cgeom.periodicity()); // old data
246  m_cf_crse_data_new->ParallelCopy(*(crse_data[1]), 0, 0, m_ncomp,
247  src_ng, dst_ng, m_cgeom.periodicity()); // new data
248 
249  m_crse_times[0] = crse_time[0]; // time of "old" coarse data
250  m_crse_times[1] = crse_time[1]; // time of "new" coarse data
251 
252  m_dt_crse = crse_time[1] - crse_time[0];
253 }
Here is the call graph for this function:

Member Data Documentation

◆ m_cba

amrex::BoxArray ERFFillPatcher::m_cba
private

Referenced by Define().

◆ m_cdm

amrex::DistributionMapping ERFFillPatcher::m_cdm
private

Referenced by Define().

◆ m_cf_crse_data_new

std::unique_ptr<amrex::MultiFab> ERFFillPatcher::m_cf_crse_data_new
private

Referenced by Define(), Fill(), and RegisterCoarseData().

◆ m_cf_crse_data_old

std::unique_ptr<amrex::MultiFab> ERFFillPatcher::m_cf_crse_data_old
private

Referenced by Define(), Fill(), and RegisterCoarseData().

◆ m_cf_mask

std::unique_ptr<amrex::iMultiFab> ERFFillPatcher::m_cf_mask
private

◆ m_cgeom

amrex::Geometry ERFFillPatcher::m_cgeom
private

◆ m_crse_times

amrex::Vector<double> ERFFillPatcher::m_crse_times
private

◆ m_dt_crse

double ERFFillPatcher::m_dt_crse
private

Referenced by Fill(), and RegisterCoarseData().

◆ m_fba

amrex::BoxArray ERFFillPatcher::m_fba
private

Referenced by Define().

◆ m_fdm

amrex::DistributionMapping ERFFillPatcher::m_fdm
private

Referenced by Define().

◆ m_fgeom

amrex::Geometry ERFFillPatcher::m_fgeom
private

Referenced by BuildMask(), Define(), and InterpCell().

◆ m_interp

amrex::InterpBase* ERFFillPatcher::m_interp
private

Referenced by Define(), and InterpCell().

◆ m_ncomp

int ERFFillPatcher::m_ncomp
private

◆ m_nghost

int ERFFillPatcher::m_nghost
private

Referenced by Define().

◆ m_nghost_subset

int ERFFillPatcher::m_nghost_subset
private

Referenced by Define().

◆ m_ratio

amrex::IntVect ERFFillPatcher::m_ratio
private

Referenced by Define(), InterpCell(), and InterpFace().

◆ m_relax_mask

int ERFFillPatcher::m_relax_mask {1}
private

Referenced by Define(), FillRelax(), and GetRelaxMaskVal().

◆ m_set_mask

int ERFFillPatcher::m_set_mask {2}
private

Referenced by Define(), FillSet(), and GetSetMaskVal().


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