ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
ERF_ParFunctions.H File Reference
#include <limits>
#include <memory>
#include <AMReX_MultiFab.H>
#include <AMReX_ParallelDescriptor.H>
#include <AMReX_Reduce.H>
Include dependency graph for ERF_ParFunctions.H:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

AMREX_FORCE_INLINE void reduce_to_max_per_height (amrex::Vector< amrex::Real > &v, std::unique_ptr< amrex::MultiFab > &mf, const amrex::Vector< amrex::Real > &zlevels_stag)
 

Function Documentation

◆ reduce_to_max_per_height()

AMREX_FORCE_INLINE void reduce_to_max_per_height ( amrex::Vector< amrex::Real > &  v,
std::unique_ptr< amrex::MultiFab > &  mf,
const amrex::Vector< amrex::Real > &  zlevels_stag 
)

Reduce a multifab of heights to a vector of max values at each height: v[k] is the largest valid value of mf at index k over all boxes of the level. A box contributes only the k it holds, since the boxes of a level need not span the column (a refined region that does not reach the top or the ground, or grids split in z). A k that no box holds gets the nominal height of the level from zlevels_stag (the face height if mf is nodal in z, the mean of the two faces otherwise), so every entry of v is a height and no caller has to test for a k that is not covered.

Parameters
[out]vmax of mf per k
[in]mfheights (z_phys_cc or z_phys_nd of a level)
[in]zlevels_stagnominal heights of the z faces of the level
28 {
29  const int nk = static_cast<int>(v.size());
30  const bool nodal_z = mf->ixType().nodeCentered(2);
31  AMREX_ALWAYS_ASSERT_WITH_MESSAGE(static_cast<int>(zlevels_stag.size()) >= (nodal_z ? nk : nk+1),
32  "reduce_to_max_per_height: zlevels_stag is shorter than the column");
33 
34  // the identity of ReduceOpMax: the value of a k that no box holds
35  constexpr amrex::Real not_covered = std::numeric_limits<amrex::Real>::lowest();
36 
37  for (int k = 0; k < nk; k++) {
38  amrex::ReduceOps<amrex::ReduceOpMax> reduce_op;
39  amrex::ReduceData<amrex::Real> reduce_data(reduce_op);
40  using ReduceTuple = typename decltype(reduce_data)::Type;
41  for (amrex::MFIter mfi(*mf); mfi.isValid(); ++mfi) {
42  amrex::Box bx = mfi.validbox();
43  if (k < bx.smallEnd(2) || k > bx.bigEnd(2)) { continue; }
44  bx.setSmall(2, k);
45  bx.setBig(2, k);
46  const amrex::Array4<amrex::Real const> a = mf->const_array(mfi);
47  reduce_op.eval(bx, reduce_data,
48  [=] AMREX_GPU_DEVICE (int i, int j, int kk) noexcept -> ReduceTuple
49  {
50  return { a(i,j,kk) };
51  });
52  }
53  v[k] = amrex::get<0>(reduce_data.value(reduce_op));
54  }
55  amrex::ParallelDescriptor::ReduceRealMax(v.data(), nk);
56 
57  for (int k = 0; k < nk; k++) {
58  if (v[k] == not_covered) {
59  v[k] = nodal_z ? zlevels_stag[k]
60  : amrex::Real(0.5) * (zlevels_stag[k] + zlevels_stag[k+1]);
61  }
62  }
63 }
AMREX_ALWAYS_ASSERT_WITH_MESSAGE(m_cloud_chamber_config.active, "Cloud Chamber: initializer reached without a parsed configuration")
amrex::Real Real
Definition: ERF_ShocInterface.H:19

Referenced by ERF::setSpongeRefFromSounding().

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