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

The moisture data carried by the active microphysics scheme. More...

#include <ERF_DataStruct.H>

Collaboration diagram for MoistureComponentIndices:

Classes

struct  CompList
 An ordered list of conserved-state components forming an aggregate moisture output variable (qt, qn, qp, moist_density). More...
 
struct  VarAvailability
 Whether this map decides a variable's availability, and if so whether the variable is available. More...
 

Public Member Functions

 MoistureComponentIndices (int qv_comp, int qc_comp, int qi_comp=absent, int qr_comp=absent, int qs_comp=absent, int qg_comp=absent, int nc_comp=absent, int ni_comp=absent, int nr_comp=absent, int ns_comp=absent, int ng_comp=absent, int nn_comp=absent)
 Construct the conserved-state component map. More...
 
 MoistureComponentIndices ()=default
 Construct an empty map, i.e. a dry run. More...
 
CompList total_water_comps () const
 Components summed for total water, "qt": every mass mixing ratio. More...
 
CompList nonprecipitating_comps () const
 Components summed for non-precipitating water, "qn": vapor plus the suspended condensate. Also the moist part of "moist_density". More...
 
CompList precipitating_comps () const
 Components summed for precipitating water, "qp": the falling species. More...
 
bool has_comp (int comp) const
 Test whether a conserved-state component holds one of the moisture variables this scheme carries. More...
 
bool has_reflectivity_species () const
 Test whether the active scheme carries rain, snow and graupel in the RhoQ4/RhoQ5/RhoQ6 slots assumed by erf_derreflectivity and erf_dermaxreflectivity. More...
 
bool has_moisture () const
 Test whether the active scheme carries any moisture at all. More...
 
int comp_for_var (const std::string &name) const
 The conserved-state component behind a single-species output name, or absent if the name is not a single species or the scheme does not carry it. More...
 
int qmoist_index_for_var (const std::string &name) const
 The qmoist slot behind a moist diagnostic output name. More...
 
VarAvailability query_var (const std::string &name) const
 Classify an output variable name against this index map. More...
 
bool has_derived_var (const std::string &name) const
 Test whether the moist species behind a derived/plot variable name is carried by the active scheme. More...
 

Static Public Member Functions

static MoistureComponentIndices from_moisture_model (const MoistureType moisture_type)
 Build the complete index map – conserved-state components and qmoist diagnostic slots – for a moisture model. More...
 

Public Attributes

int qv = absent
 water vapor More...
 
int qc = absent
 cloud liquid water More...
 
int qi = absent
 cloud ice More...
 
int qr = absent
 rain More...
 
int qs = absent
 snow More...
 
int qg = absent
 graupel More...
 
int nc = absent
 cloud liquid water number More...
 
int ni = absent
 cloud ice number More...
 
int nr = absent
 rain number More...
 
int ns = absent
 snow number More...
 
int ng = absent
 graupel number More...
 
int nn = absent
 CCN / total aerosol number. More...
 
int rain_accum = absent
 accumulated surface rain More...
 
int snow_accum = absent
 accumulated surface snow More...
 
int graup_accum = absent
 accumulated surface graupel More...
 
int rel_hum = absent
 relative humidity More...
 
int cond_rate = absent
 condensation rate More...
 

Static Public Attributes

static constexpr int absent = -1
 not carried by the active scheme More...
 
static constexpr int computed_from_state = -2
 

Detailed Description

The moisture data carried by the active microphysics scheme.

This struct is the single source of truth for the question "which moisture quantities does this run actually have?". Everything downstream of the microphysics – source terms, turbulence closures, and every output path (3D plotfiles, 2D plotfiles, subvolumes) – answers that question by querying this struct instead of enumerating MoistureType values, so a newly added scheme only has to declare its layout once, in from_moisture_model() below.

Two kinds of index live here:

  1. Conserved-state components (qv ... nn). Absolute component indices into the conserved state array, i.e. one of RhoQ1_comp ... RhoQ11_comp. They name the rho-weighted species: state(i,j,k,qv) is rho*qv, so an output path must divide by Rho_comp to recover the mixing ratio.
  2. qmoist diagnostic slots (rain_accum ... cond_rate). Indices into the per-level qmoist vector that is filled from Microphysics::Get_Qmoist_Ptr(lev,idx). Each scheme chooses that layout independently, so the slot numbers differ between schemes and are recorded per scheme below.

In both cases the value is absent when the active scheme does not carry the quantity, so index >= 0 is the criterion for "this exists and is meaningful to write". That is deliberately not the same test as "the storage is allocated": several schemes allocate a wider state than they integrate (the Morrison class always allocates eleven moist components, so Morrison_NoIce owns ice slots it never fills), and writing those slots to a plotfile would publish untouched memory as if it were data.

Constructor & Destructor Documentation

◆ MoistureComponentIndices() [1/2]

MoistureComponentIndices::MoistureComponentIndices ( int  qv_comp,
int  qc_comp,
int  qi_comp = absent,
int  qr_comp = absent,
int  qs_comp = absent,
int  qg_comp = absent,
int  nc_comp = absent,
int  ni_comp = absent,
int  nr_comp = absent,
int  ns_comp = absent,
int  ng_comp = absent,
int  nn_comp = absent 
)
inline

Construct the conserved-state component map.

Prefer from_moisture_model() for production code: it fills in the qmoist diagnostic slots as well. This constructor exists for the callers – unit tests and kernels exercised in isolation – that only need the state map.

Parameters
qv_compWater vapor component index.
qc_compCloud liquid water component index.
qi_compCloud ice component index.
qr_compRain component index.
qs_compSnow component index.
qg_compGraupel component index.
nc_compCloud liquid water number concentration component index.
ni_compCloud ice number concentration component index.
nr_compRain number concentration component index.
ns_compSnow number concentration component index.
ng_compGraupel number concentration component index.
nn_compCCN / total aerosol number concentration component index.
300  : qv(qv_comp), qc(qc_comp), qi(qi_comp), qr(qr_comp), qs(qs_comp), qg(qg_comp),
301  nc(nc_comp), ni(ni_comp), nr(nr_comp), ns(ns_comp), ng(ng_comp),
302  nn(nn_comp) {}
int nc
cloud liquid water number
Definition: ERF_DataStruct.H:244
int qs
snow
Definition: ERF_DataStruct.H:238
int nn
CCN / total aerosol number.
Definition: ERF_DataStruct.H:254
int qr
rain
Definition: ERF_DataStruct.H:237
int qi
cloud ice
Definition: ERF_DataStruct.H:236
int ni
cloud ice number
Definition: ERF_DataStruct.H:245
int qv
water vapor
Definition: ERF_DataStruct.H:234
int nr
rain number
Definition: ERF_DataStruct.H:246
int qc
cloud liquid water
Definition: ERF_DataStruct.H:235
int ng
graupel number
Definition: ERF_DataStruct.H:248
int qg
graupel
Definition: ERF_DataStruct.H:239
int ns
snow number
Definition: ERF_DataStruct.H:247

◆ MoistureComponentIndices() [2/2]

MoistureComponentIndices::MoistureComponentIndices ( )
default

Construct an empty map, i.e. a dry run.

Member Function Documentation

◆ comp_for_var()

int MoistureComponentIndices::comp_for_var ( const std::string &  name) const
inline

The conserved-state component behind a single-species output name, or absent if the name is not a single species or the scheme does not carry it.

An output path can use this to copy a species without repeating the name-to-component mapping.

Parameters
nameDerived or plot variable name.
553  {
554  if (name == "qv") { return qv; }
555  if (name == "qc") { return qc; }
556  if (name == "qi") { return qi; }
557  if (name == "qrain") { return qr; }
558  if (name == "qsnow") { return qs; }
559  if (name == "qgraup") { return qg; }
560  if (name == "nc") { return nc; }
561  if (name == "ni") { return ni; }
562  if (name == "nr") { return nr; }
563  if (name == "ns") { return ns; }
564  if (name == "ng") { return ng; }
565  if (name == "nn") { return nn; }
566  return absent;
567  }
std::string name
Definition: ERF_Plotfile2DCatalog.cpp:101
static constexpr int absent
not carried by the active scheme
Definition: ERF_DataStruct.H:226

Referenced by ERF::FillPlot3DVars(), and query_var().

Here is the caller graph for this function:

◆ from_moisture_model()

static MoistureComponentIndices MoistureComponentIndices::from_moisture_model ( const MoistureType  moisture_type)
inlinestatic

Build the complete index map – conserved-state components and qmoist diagnostic slots – for a moisture model.

This is the one place a scheme declares what it carries. The conserved layout must match the component the scheme reads and writes in its Copy_State_to_Micro / Copy_Micro_to_State pair, and the qmoist slots must match the order the scheme installs in its MicVarMap. A slot that a scheme allocates but never fills is left absent on purpose: see the class comment for why allocation is not the criterion here.

Parameters
moisture_typeActive moisture/microphysics model.
324  {
326 
327  switch (moisture_type) {
328 
329  case MoistureType::None:
330  // Dry: no moisture data of any kind.
331  break;
332 
333  case MoistureType::MoistNoCondensation:
334  case MoistureType::SAM_NoPrecip_NoIce:
335  case MoistureType::Kessler_NoRain:
336  // Vapor plus suspended cloud water, no precipitation and no
337  // accumulation diagnostics.
338  mi.qv = RhoQ1_comp;
339  mi.qc = RhoQ2_comp;
340  break;
341 
342  case MoistureType::SatAdj:
343  // As above, but relative humidity is recovered from the state at
344  // output time rather than stored: SatAdj publishes no qmoist arrays.
345  mi.qv = RhoQ1_comp;
346  mi.qc = RhoQ2_comp;
348  break;
349 
350  case MoistureType::Kessler:
351  // Warm rain in three moist components; qmoist is {rain_accum}.
352  mi.qv = RhoQ1_comp;
353  mi.qc = RhoQ2_comp;
354  mi.qr = RhoQ3_comp;
355  mi.rain_accum = 0;
356  break;
357 
358  case MoistureType::SAM_NoIce:
359  // The SAM class always allocates six moist components, so rain sits
360  // in the fourth slot even with the ice species switched off.
361  mi.qv = RhoQ1_comp;
362  mi.qc = RhoQ2_comp;
363  mi.qr = RhoQ4_comp;
364  mi.rain_accum = 0;
365  break;
366 
367  case MoistureType::SAM:
368  case MoistureType::WSM6:
369  // Single-moment mixed phase; qmoist is
370  // {rain_accum, snow_accum, graup_accum}.
371  mi.qv = RhoQ1_comp;
372  mi.qc = RhoQ2_comp;
373  mi.qi = RhoQ3_comp;
374  mi.qr = RhoQ4_comp;
375  mi.qs = RhoQ5_comp;
376  mi.qg = RhoQ6_comp;
377  mi.rain_accum = 0;
378  mi.snow_accum = 1;
379  mi.graup_accum = 2;
380  break;
381 
382  case MoistureType::Morrison:
383  // Two-moment mixed phase: six mass species followed by five number
384  // concentrations.
385  mi.qv = RhoQ1_comp;
386  mi.qc = RhoQ2_comp;
387  mi.qi = RhoQ3_comp;
388  mi.qr = RhoQ4_comp;
389  mi.qs = RhoQ5_comp;
390  mi.qg = RhoQ6_comp;
391  mi.nc = RhoQ7_comp;
392  mi.ni = RhoQ8_comp;
393  mi.nr = RhoQ9_comp;
394  mi.ns = RhoQ10_comp;
395  mi.ng = RhoQ11_comp;
396  mi.rain_accum = 0;
397  mi.snow_accum = 1;
398  mi.graup_accum = 2;
399  break;
400 
401  case MoistureType::Morrison_NoIce:
402  // Liquid-only Morrison: the class still allocates all eleven moist
403  // components, but only vapor, cloud water and rain -- and the cloud
404  // and rain numbers -- are integrated, so the frozen species and
405  // their numbers stay absent here.
406  mi.qv = RhoQ1_comp;
407  mi.qc = RhoQ2_comp;
408  mi.qr = RhoQ4_comp;
409  mi.nc = RhoQ7_comp;
410  mi.nr = RhoQ9_comp;
411  mi.rain_accum = 0;
412  break;
413 
414  case MoistureType::WDM6:
415  // Double-moment warm phase on top of single-moment ice: nn is the
416  // aerosol reservoir and takes the slot Morrison uses for ice number,
417  // and there are no snow or graupel numbers.
418  mi.qv = RhoQ1_comp;
419  mi.qc = RhoQ2_comp;
420  mi.qi = RhoQ3_comp;
421  mi.qr = RhoQ4_comp;
422  mi.qs = RhoQ5_comp;
423  mi.qg = RhoQ6_comp;
424  mi.nc = RhoQ7_comp;
425  mi.nn = RhoQ8_comp;
426  mi.nr = RhoQ9_comp;
427  mi.rain_accum = 0;
428  mi.snow_accum = 1;
429  mi.graup_accum = 2;
430  break;
431 
432  case MoistureType::SuperDroplets:
433  // Lagrangian microphysics that still carries the six Eulerian mass
434  // species. Its qmoist layout is its own (see the MicVarMap in
435  // SuperDropletsMoist::Init): the graupel accumulation slot exists
436  // but is never filled, so it stays absent.
437  mi.qv = RhoQ1_comp;
438  mi.qc = RhoQ2_comp;
439  mi.qi = RhoQ3_comp;
440  mi.qr = RhoQ4_comp;
441  mi.qs = RhoQ5_comp;
442  mi.qg = RhoQ6_comp;
443  mi.cond_rate = 3;
444  mi.rel_hum = 7;
445  mi.rain_accum = 8;
446  mi.snow_accum = 10;
447  break;
448 
449  default:
450  amrex::Abort("Unknown MoistureType in MoistureComponentIndices::from_moisture_model");
451  }
452 
453  return mi;
454  }
#define RhoQ4_comp
Definition: ERF_IndexDefines.H:48
#define RhoQ2_comp
Definition: ERF_IndexDefines.H:46
#define RhoQ3_comp
Definition: ERF_IndexDefines.H:47
#define RhoQ11_comp
Definition: ERF_IndexDefines.H:55
#define RhoQ9_comp
Definition: ERF_IndexDefines.H:53
#define RhoQ1_comp
Definition: ERF_IndexDefines.H:45
#define RhoQ6_comp
Definition: ERF_IndexDefines.H:50
#define RhoQ8_comp
Definition: ERF_IndexDefines.H:52
#define RhoQ5_comp
Definition: ERF_IndexDefines.H:49
#define RhoQ7_comp
Definition: ERF_IndexDefines.H:51
#define RhoQ10_comp
Definition: ERF_IndexDefines.H:54
The moisture data carried by the active microphysics scheme.
Definition: ERF_DataStruct.H:223
int cond_rate
condensation rate
Definition: ERF_DataStruct.H:267
int graup_accum
accumulated surface graupel
Definition: ERF_DataStruct.H:265
int rel_hum
relative humidity
Definition: ERF_DataStruct.H:266
static constexpr int computed_from_state
Definition: ERF_DataStruct.H:227
int rain_accum
accumulated surface rain
Definition: ERF_DataStruct.H:263
int snow_accum
accumulated surface snow
Definition: ERF_DataStruct.H:264

Referenced by SolverChoice::init_params().

Here is the caller graph for this function:

◆ has_comp()

bool MoistureComponentIndices::has_comp ( int  comp) const
inline

Test whether a conserved-state component holds one of the moisture variables this scheme carries.

Use this rather than enumerating moisture models when deciding whether a "rhoQn" state component is meaningful for the active scheme.

Parameters
compAbsolute component index into the conserved state array.
515  {
516  return ( (comp >= 0) &&
517  ( (comp == qv) || (comp == qc) || (comp == qi) ||
518  (comp == qr) || (comp == qs) || (comp == qg) ||
519  (comp == nc) || (comp == ni) || (comp == nr) ||
520  (comp == ns) || (comp == ng) || (comp == nn) ) );
521  }

Referenced by erf_plotfile::plot3d_fixed_variable_available().

Here is the caller graph for this function:

◆ has_derived_var()

bool MoistureComponentIndices::has_derived_var ( const std::string &  name) const
inline

Test whether the moist species behind a derived/plot variable name is carried by the active scheme.

Names this map does not govern return true, so this can be used directly as a filter over a mixed list of variable names. Use query_var() instead when the caller needs to distinguish "not a moisture variable" from "available".

Parameters
nameDerived or plot variable name.
652  {
653  const VarAvailability status = query_var(name);
654  return (!status.governed) || status.available;
655  }
VarAvailability query_var(const std::string &name) const
Classify an output variable name against this index map.
Definition: ERF_DataStruct.H:607

Referenced by ERF::setSubVolVariables().

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

◆ has_moisture()

bool MoistureComponentIndices::has_moisture ( ) const
inline

Test whether the active scheme carries any moisture at all.

Every moist scheme allocates water vapor, so this is equivalent to testing moisture_type != MoistureType::None without needing the enum.

541 { return (qv >= 0); }

Referenced by ERF::FillPlot3DVars(), query_var(), ERF::setSubVolVariables(), and ERF::WriteSubvolume().

Here is the caller graph for this function:

◆ has_reflectivity_species()

bool MoistureComponentIndices::has_reflectivity_species ( ) const
inline

Test whether the active scheme carries rain, snow and graupel in the RhoQ4/RhoQ5/RhoQ6 slots assumed by erf_derreflectivity and erf_dermaxreflectivity.

Those kernels read the precipitating species by hardcoded component, so this checks the layout and not just the presence of the species.

531  {
532  return ( (qr == RhoQ4_comp) && (qs == RhoQ5_comp) && (qg == RhoQ6_comp) );
533  }

◆ nonprecipitating_comps()

CompList MoistureComponentIndices::nonprecipitating_comps ( ) const
inline

Components summed for non-precipitating water, "qn": vapor plus the suspended condensate. Also the moist part of "moist_density".

491  {
492  CompList list;
493  list.append(qv); list.append(qc); list.append(qi);
494  return list;
495  }

Referenced by ERF::FillPlot3DVars().

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

◆ precipitating_comps()

CompList MoistureComponentIndices::precipitating_comps ( ) const
inline

Components summed for precipitating water, "qp": the falling species.

500  {
501  CompList list;
502  list.append(qr); list.append(qs); list.append(qg);
503  return list;
504  }

Referenced by ERF::FillPlot3DVars(), and query_var().

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

◆ qmoist_index_for_var()

int MoistureComponentIndices::qmoist_index_for_var ( const std::string &  name) const
inline

The qmoist slot behind a moist diagnostic output name.

Returns absent when the scheme does not provide the diagnostic, and computed_from_state when it does provide it but not through a qmoist array – in that case the caller must derive it from the conserved state.

Parameters
nameDerived or plot variable name.
578  {
579  if (name == "rain_accum") { return rain_accum; }
580  if (name == "snow_accum") { return snow_accum; }
581  if (name == "graup_accum") { return graup_accum; }
582  if (name == "rel_humidity") { return rel_hum; }
583  if (name == "condensation_rate") { return cond_rate; }
584  return absent;
585  }

Referenced by ERF::FillPlot3DVars(), and query_var().

Here is the caller graph for this function:

◆ query_var()

VarAvailability MoistureComponentIndices::query_var ( const std::string &  name) const
inline

Classify an output variable name against this index map.

This is the one table pairing output names with the data behind them. It is driven off the scheme's index map rather than an enumerated list of moisture models, so it stays correct as schemes are added. Names with no moisture dependence come back not-governed, which lets a caller walk a mixed list of variable names and only defer to this map where it applies.

Parameters
nameDerived or plot variable name.
607  {
608 
609  // Single species, taken straight from the conserved state
610  if ( (name == "qv") || (name == "qc") || (name == "qi") ||
611  (name == "qrain") || (name == "qsnow") || (name == "qgraup") ||
612  (name == "nc") || (name == "ni") || (name == "nr") ||
613  (name == "ns") || (name == "ng") || (name == "nn") ) {
614  return {true, comp_for_var(name) >= 0};
615  }
616 
617  // Moist diagnostics, either from a qmoist array or derived at output time
618  if ( (name == "rain_accum") || (name == "snow_accum") ||
619  (name == "graup_accum") || (name == "rel_humidity") ||
620  (name == "condensation_rate") ) {
621  return {true, qmoist_index_for_var(name) != absent};
622  }
623 
624  // Aggregates over several species
625  if (name == "qt") { return {true, !total_water_comps().empty()}; }
626  if (name == "qp") { return {true, !precipitating_comps().empty()}; }
627 
628  // Non-precipitating water is vapor plus the suspended condensate, and
629  // moist density adds that same sum to the dry density
630  if ( (name == "qn") || (name == "moist_density") ) {
631  return {true, (qv >= 0) && (qc >= 0)};
632  }
633 
634  // Column and thermodynamic diagnostics that read vapor only
635  if ( (name == "qsat") || (name == "precipitable") ) {
636  return {true, has_moisture()};
637  }
638 
639  return {false, false};
640  }
bool empty() const
Definition: ERF_DataStruct.H:472
int comp_for_var(const std::string &name) const
The conserved-state component behind a single-species output name, or absent if the name is not a sin...
Definition: ERF_DataStruct.H:553
CompList total_water_comps() const
Components summed for total water, "qt": every mass mixing ratio.
Definition: ERF_DataStruct.H:480
CompList precipitating_comps() const
Components summed for precipitating water, "qp": the falling species.
Definition: ERF_DataStruct.H:500
bool has_moisture() const
Test whether the active scheme carries any moisture at all.
Definition: ERF_DataStruct.H:541
int qmoist_index_for_var(const std::string &name) const
The qmoist slot behind a moist diagnostic output name.
Definition: ERF_DataStruct.H:578

Referenced by has_derived_var(), and erf_plotfile::plot3d_fixed_variable_available().

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

◆ total_water_comps()

CompList MoistureComponentIndices::total_water_comps ( ) const
inline

Components summed for total water, "qt": every mass mixing ratio.

Number concentrations are excluded – they are counts, not masses.

480  {
481  CompList list;
482  list.append(qv); list.append(qc); list.append(qi);
483  list.append(qr); list.append(qs); list.append(qg);
484  return list;
485  }

Referenced by ERF::FillPlot3DVars(), and query_var().

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

Member Data Documentation

◆ absent

constexpr int MoistureComponentIndices::absent = -1
staticconstexpr

not carried by the active scheme

Referenced by comp_for_var(), qmoist_index_for_var(), and query_var().

◆ computed_from_state

constexpr int MoistureComponentIndices::computed_from_state = -2
staticconstexpr

carried, but derived at output time from the conserved state rather than read from a qmoist slot

Referenced by ERF::FillPlot3DVars(), and from_moisture_model().

◆ cond_rate

int MoistureComponentIndices::cond_rate = absent

condensation rate

Referenced by from_moisture_model(), and qmoist_index_for_var().

◆ graup_accum

int MoistureComponentIndices::graup_accum = absent

accumulated surface graupel

Referenced by from_moisture_model(), and qmoist_index_for_var().

◆ nc

int MoistureComponentIndices::nc = absent

cloud liquid water number

Referenced by comp_for_var(), from_moisture_model(), and has_comp().

◆ ng

int MoistureComponentIndices::ng = absent

graupel number

Referenced by comp_for_var(), from_moisture_model(), and has_comp().

◆ ni

int MoistureComponentIndices::ni = absent

cloud ice number

Referenced by comp_for_var(), from_moisture_model(), and has_comp().

◆ nn

int MoistureComponentIndices::nn = absent

CCN / total aerosol number.

Referenced by comp_for_var(), from_moisture_model(), and has_comp().

◆ nr

int MoistureComponentIndices::nr = absent

rain number

Referenced by comp_for_var(), from_moisture_model(), and has_comp().

◆ ns

int MoistureComponentIndices::ns = absent

snow number

Referenced by comp_for_var(), from_moisture_model(), and has_comp().

◆ qc

◆ qg

◆ qi

◆ qr

◆ qs

◆ qv

◆ rain_accum

int MoistureComponentIndices::rain_accum = absent

accumulated surface rain

Referenced by from_moisture_model(), and qmoist_index_for_var().

◆ rel_hum

int MoistureComponentIndices::rel_hum = absent

relative humidity

Referenced by ERF::FillPlot3DVars(), from_moisture_model(), and qmoist_index_for_var().

◆ snow_accum

int MoistureComponentIndices::snow_accum = absent

accumulated surface snow

Referenced by from_moisture_model(), and qmoist_index_for_var().


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