ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
ERF_FirePrecip.H File Reference

Rain per column for the fuel moisture model from the microphysics surface precipitation accumulators, for an engine that reads the rain (FireEngine::wants_surface_precip). More...

#include <AMReX_GpuQualifiers.H>
#include <AMReX_MultiFab.H>
#include <AMReX_MFIter.H>
#include <AMReX_REAL.H>
#include <ERF_SurfacePrecipitation.H>
Include dependency graph for ERF_FirePrecip.H:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real fire_precip_rate_mm_hr (amrex::Real accum_now_kgm2, amrex::Real accum_prev_kgm2, amrex::Real dt_s) noexcept
 Rain rate [mm/hr] from the change of the surface accumulation over one step. More...
 
void fire_surface_precip_accum_k0 (amrex::MultiFab &accum_2d, const SurfacePrecipAccumulationSources &sources, int klo)
 Total liquid-water-equivalent surface precipitation accumulation [kg/m2] of every column, from the scheme-native accumulators. More...
 
void fire_precip_rate_from_accum (amrex::MultiFab &rate_2d, amrex::MultiFab &prev_2d, const amrex::MultiFab &now_2d, amrex::Real dt_s, bool prev_valid)
 Rain rate [mm/hr] of every column over the step just taken, and roll the snapshot forward. More...
 

Detailed Description

Rain per column for the fuel moisture model from the microphysics surface precipitation accumulators, for an engine that reads the rain (FireEngine::wants_surface_precip).

Every Eulerian microphysics scheme with precipitation keeps a cumulative surface accumulator per atmospheric column (Kessler's rain_accum, SAM's and Morrison's rain, snow and graupel accumulations, ...), exposed through Microphysics::Get_Surface_Precip_Accumulation_Ptrs() with a factor that turns the scheme's native unit into kg/m2 of liquid water. One kg/m2 of liquid water is one millimetre of depth, so the change of the accumulation over a step, divided by the step, is the rain rate in mm/hr that the time-lag and stick moisture updates take. The fire layer keeps the accumulation it saw at the end of its previous step (checkpointed) and forms that difference every step; a fresh start begins at zero, which is where every scheme starts its accumulators.

Snow, graupel and hail count with their liquid-water equivalent: the fuel models have no frozen-precipitation branch. There is no canopy interception.

Function Documentation

◆ fire_precip_rate_from_accum()

void fire_precip_rate_from_accum ( amrex::MultiFab &  rate_2d,
amrex::MultiFab &  prev_2d,
const amrex::MultiFab &  now_2d,
amrex::Real  dt_s,
bool  prev_valid 
)
inline

Rain rate [mm/hr] of every column over the step just taken, and roll the snapshot forward.

rate_2d = fire_precip_rate_mm_hr(now, prev, dt) per column when prev_valid, zero otherwise (a restart from a checkpoint without the snapshot); then prev_2d = now_2d. All three MultiFabs share boxes and distribution.

120 {
121  using namespace amrex;
122  for (MFIter mfi(rate_2d, false); mfi.isValid(); ++mfi) {
123  Array4<Real> r = rate_2d.array(mfi);
124  Array4<Real> p = prev_2d.array(mfi);
125  Array4<const Real> n = now_2d.const_array(mfi);
126  ParallelFor(mfi.tilebox(), [=] AMREX_GPU_DEVICE (const IntVect& iv) noexcept
127  {
128  const int i = iv[0], j = iv[1];
129  r(i, j, 0) = prev_valid ? fire_precip_rate_mm_hr(n(i, j, 0), p(i, j, 0), dt_s) : Real(0.0);
130  p(i, j, 0) = n(i, j, 0);
131  });
132  }
133 }
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real fire_precip_rate_mm_hr(amrex::Real accum_now_kgm2, amrex::Real accum_prev_kgm2, amrex::Real dt_s) noexcept
Rain rate [mm/hr] from the change of the surface accumulation over one step.
Definition: ERF_FirePrecip.H:42
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);})
amrex::Real Real
Definition: ERF_ShocInterface.H:19
@ p
Definition: ERF_WSM6.H:301
Definition: ERF_ConsoleIO.cpp:17
Here is the call graph for this function:

◆ fire_precip_rate_mm_hr()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real fire_precip_rate_mm_hr ( amrex::Real  accum_now_kgm2,
amrex::Real  accum_prev_kgm2,
amrex::Real  dt_s 
)
noexcept

Rain rate [mm/hr] from the change of the surface accumulation over one step.

Parameters
[in]accum_now_kgm2accumulation at the end of the step [kg/m2 == mm]
[in]accum_prev_kgm2accumulation at the end of the previous step [kg/m2]
[in]dt_sthe step [s]
Returns
(now - prev) * 3600 / dt; zero for a non-positive step or a non-positive change (an accumulator that was reset, or round-off), and zero for NaN.
45 {
46  if (!(dt_s > amrex::Real(0.0))) { return amrex::Real(0.0); }
47  const amrex::Real d = accum_now_kgm2 - accum_prev_kgm2;
48  if (!(d > amrex::Real(0.0))) { return amrex::Real(0.0); }
49  return d * amrex::Real(3600.0) / dt_s;
50 }

Referenced by fire_precip_rate_from_accum().

Here is the caller graph for this function:

◆ fire_surface_precip_accum_k0()

void fire_surface_precip_accum_k0 ( amrex::MultiFab &  accum_2d,
const SurfacePrecipAccumulationSources &  sources,
int  klo 
)
inline

Total liquid-water-equivalent surface precipitation accumulation [kg/m2] of every column, from the scheme-native accumulators.

Fills accum_2d, a one-component MultiFab on the level's boxes coarsened to one cell in z (box n of accum_2d is box n of the accumulators, with the same owner), from the k = klo plane of the sources. Schemes that provide a total give it directly; schemes that provide the species give their sum, so nothing is counted twice (the same rule as the 2D plotfile precipitation diagnostics). Without any source the field is zero.

66 {
67  using namespace amrex;
68  accum_2d.setVal(Real(0.0));
69  if (!surface_precip_has_any_source(sources)) { return; }
70 
71  const bool has_total = surface_precip_has_source(sources.total);
72  const bool has_rain = surface_precip_has_source(sources.rain);
73  const bool has_snow = surface_precip_has_source(sources.snow);
74  const bool has_graupel = surface_precip_has_source(sources.graupel);
75  const bool has_hail = surface_precip_has_source(sources.hail);
76  const Real f_total = sources.total.native_to_kg_m2;
77  const Real f_rain = sources.rain.native_to_kg_m2;
78  const Real f_snow = sources.snow.native_to_kg_m2;
79  const Real f_graupel = sources.graupel.native_to_kg_m2;
80  const Real f_hail = sources.hail.native_to_kg_m2;
81 
82  for (MFIter mfi(accum_2d, false); mfi.isValid(); ++mfi) {
83  Array4<Real> a = accum_2d.array(mfi);
84  Array4<const Real> total = has_total ? sources.total.accum->const_array(mfi) : Array4<const Real>{};
85  Array4<const Real> rain = has_rain ? sources.rain.accum->const_array(mfi) : Array4<const Real>{};
86  Array4<const Real> snow = has_snow ? sources.snow.accum->const_array(mfi) : Array4<const Real>{};
87  Array4<const Real> graupel = has_graupel ? sources.graupel.accum->const_array(mfi) : Array4<const Real>{};
88  Array4<const Real> hail = has_hail ? sources.hail.accum->const_array(mfi) : Array4<const Real>{};
89  ParallelFor(mfi.tilebox(), [=] AMREX_GPU_DEVICE (const IntVect& iv) noexcept
90  {
91  const int i = iv[0], j = iv[1];
92  Real v;
93  if (has_total) {
94  v = total(i, j, klo) * f_total;
95  } else {
96  v = Real(0.0);
97  if (has_rain) { v += rain(i, j, klo) * f_rain; }
98  if (has_snow) { v += snow(i, j, klo) * f_snow; }
99  if (has_graupel) { v += graupel(i, j, klo) * f_graupel; }
100  if (has_hail) { v += hail(i, j, klo) * f_hail; }
101  }
102  a(i, j, 0) = v;
103  });
104  }
105 }
const int klo
Definition: ERF_InitCustomPert_KE.H:9
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool surface_precip_has_source(const SurfacePrecipAccumulationSource &src) noexcept
Definition: ERF_SurfacePrecipitation.H:43
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool surface_precip_has_any_source(const SurfacePrecipAccumulationSources &src) noexcept
Definition: ERF_SurfacePrecipitation.H:61
@ graupel
Definition: ERF_NOAHMP_Fields.H:140
@ rain
Definition: ERF_NOAHMP_Fields.H:138
@ total
Definition: ERF_NOAHMP_Fields.H:137
@ hail
Definition: ERF_NOAHMP_Fields.H:141
@ snow
Definition: ERF_NOAHMP_Fields.H:139
const amrex::MultiFab * accum
Definition: ERF_SurfacePrecipitation.H:21
amrex::Real native_to_kg_m2
Definition: ERF_SurfacePrecipitation.H:22
SurfacePrecipAccumulationSource rain
Definition: ERF_SurfacePrecipitation.H:36
SurfacePrecipAccumulationSource snow
Definition: ERF_SurfacePrecipitation.H:37
SurfacePrecipAccumulationSource hail
Definition: ERF_SurfacePrecipitation.H:39
SurfacePrecipAccumulationSource total
Definition: ERF_SurfacePrecipitation.H:35
SurfacePrecipAccumulationSource graupel
Definition: ERF_SurfacePrecipitation.H:38

Referenced by FireCoupler::advance().

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