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.
272  : qv(qv_comp), qc(qc_comp), qi(qi_comp), qr(qr_comp), qs(qs_comp), qg(qg_comp),
273  nc(nc_comp), ni(ni_comp), nr(nr_comp), ns(ns_comp), ng(ng_comp),
274  nn(nn_comp) {}
int nc
cloud liquid water number
Definition: ERF_DataStruct.H:216
int qs
snow
Definition: ERF_DataStruct.H:210
int nn
CCN / total aerosol number.
Definition: ERF_DataStruct.H:226
int qr
rain
Definition: ERF_DataStruct.H:209
int qi
cloud ice
Definition: ERF_DataStruct.H:208
int ni
cloud ice number
Definition: ERF_DataStruct.H:217
int qv
water vapor
Definition: ERF_DataStruct.H:206
int nr
rain number
Definition: ERF_DataStruct.H:218
int qc
cloud liquid water
Definition: ERF_DataStruct.H:207
int ng
graupel number
Definition: ERF_DataStruct.H:220
int qg
graupel
Definition: ERF_DataStruct.H:211
int ns
snow number
Definition: ERF_DataStruct.H:219

◆ 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.
525  {
526  if (name == "qv") { return qv; }
527  if (name == "qc") { return qc; }
528  if (name == "qi") { return qi; }
529  if (name == "qrain") { return qr; }
530  if (name == "qsnow") { return qs; }
531  if (name == "qgraup") { return qg; }
532  if (name == "nc") { return nc; }
533  if (name == "ni") { return ni; }
534  if (name == "nr") { return nr; }
535  if (name == "ns") { return ns; }
536  if (name == "ng") { return ng; }
537  if (name == "nn") { return nn; }
538  return absent;
539  }
std::string name
Definition: ERF_Plotfile2DCatalog.cpp:101
static constexpr int absent
not carried by the active scheme
Definition: ERF_DataStruct.H:198

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

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.
296  {
298 
299  switch (moisture_type) {
300 
301  case MoistureType::None:
302  // Dry: no moisture data of any kind.
303  break;
304 
305  case MoistureType::MoistNoCondensation:
306  case MoistureType::SAM_NoPrecip_NoIce:
307  case MoistureType::Kessler_NoRain:
308  // Vapor plus suspended cloud water, no precipitation and no
309  // accumulation diagnostics.
310  mi.qv = RhoQ1_comp;
311  mi.qc = RhoQ2_comp;
312  break;
313 
314  case MoistureType::SatAdj:
315  // As above, but relative humidity is recovered from the state at
316  // output time rather than stored: SatAdj publishes no qmoist arrays.
317  mi.qv = RhoQ1_comp;
318  mi.qc = RhoQ2_comp;
320  break;
321 
322  case MoistureType::Kessler:
323  // Warm rain in three moist components; qmoist is {rain_accum}.
324  mi.qv = RhoQ1_comp;
325  mi.qc = RhoQ2_comp;
326  mi.qr = RhoQ3_comp;
327  mi.rain_accum = 0;
328  break;
329 
330  case MoistureType::SAM_NoIce:
331  // The SAM class always allocates six moist components, so rain sits
332  // in the fourth slot even with the ice species switched off.
333  mi.qv = RhoQ1_comp;
334  mi.qc = RhoQ2_comp;
335  mi.qr = RhoQ4_comp;
336  mi.rain_accum = 0;
337  break;
338 
339  case MoistureType::SAM:
340  case MoistureType::WSM6:
341  // Single-moment mixed phase; qmoist is
342  // {rain_accum, snow_accum, graup_accum}.
343  mi.qv = RhoQ1_comp;
344  mi.qc = RhoQ2_comp;
345  mi.qi = RhoQ3_comp;
346  mi.qr = RhoQ4_comp;
347  mi.qs = RhoQ5_comp;
348  mi.qg = RhoQ6_comp;
349  mi.rain_accum = 0;
350  mi.snow_accum = 1;
351  mi.graup_accum = 2;
352  break;
353 
354  case MoistureType::Morrison:
355  // Two-moment mixed phase: six mass species followed by five number
356  // concentrations.
357  mi.qv = RhoQ1_comp;
358  mi.qc = RhoQ2_comp;
359  mi.qi = RhoQ3_comp;
360  mi.qr = RhoQ4_comp;
361  mi.qs = RhoQ5_comp;
362  mi.qg = RhoQ6_comp;
363  mi.nc = RhoQ7_comp;
364  mi.ni = RhoQ8_comp;
365  mi.nr = RhoQ9_comp;
366  mi.ns = RhoQ10_comp;
367  mi.ng = RhoQ11_comp;
368  mi.rain_accum = 0;
369  mi.snow_accum = 1;
370  mi.graup_accum = 2;
371  break;
372 
373  case MoistureType::Morrison_NoIce:
374  // Liquid-only Morrison: the class still allocates all eleven moist
375  // components, but only vapor, cloud water and rain -- and the cloud
376  // and rain numbers -- are integrated, so the frozen species and
377  // their numbers stay absent here.
378  mi.qv = RhoQ1_comp;
379  mi.qc = RhoQ2_comp;
380  mi.qr = RhoQ4_comp;
381  mi.nc = RhoQ7_comp;
382  mi.nr = RhoQ9_comp;
383  mi.rain_accum = 0;
384  break;
385 
386  case MoistureType::WDM6:
387  // Double-moment warm phase on top of single-moment ice: nn is the
388  // aerosol reservoir and takes the slot Morrison uses for ice number,
389  // and there are no snow or graupel numbers.
390  mi.qv = RhoQ1_comp;
391  mi.qc = RhoQ2_comp;
392  mi.qi = RhoQ3_comp;
393  mi.qr = RhoQ4_comp;
394  mi.qs = RhoQ5_comp;
395  mi.qg = RhoQ6_comp;
396  mi.nc = RhoQ7_comp;
397  mi.nn = RhoQ8_comp;
398  mi.nr = RhoQ9_comp;
399  mi.rain_accum = 0;
400  mi.snow_accum = 1;
401  mi.graup_accum = 2;
402  break;
403 
404  case MoistureType::SuperDroplets:
405  // Lagrangian microphysics that still carries the six Eulerian mass
406  // species. Its qmoist layout is its own (see the MicVarMap in
407  // SuperDropletsMoist::Init): the graupel accumulation slot exists
408  // but is never filled, so it stays absent.
409  mi.qv = RhoQ1_comp;
410  mi.qc = RhoQ2_comp;
411  mi.qi = RhoQ3_comp;
412  mi.qr = RhoQ4_comp;
413  mi.qs = RhoQ5_comp;
414  mi.qg = RhoQ6_comp;
415  mi.cond_rate = 3;
416  mi.rel_hum = 7;
417  mi.rain_accum = 8;
418  mi.snow_accum = 10;
419  break;
420 
421  default:
422  amrex::Abort("Unknown MoistureType in MoistureComponentIndices::from_moisture_model");
423  }
424 
425  return mi;
426  }
#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:195
int cond_rate
condensation rate
Definition: ERF_DataStruct.H:239
int graup_accum
accumulated surface graupel
Definition: ERF_DataStruct.H:237
int rel_hum
relative humidity
Definition: ERF_DataStruct.H:238
static constexpr int computed_from_state
Definition: ERF_DataStruct.H:199
int rain_accum
accumulated surface rain
Definition: ERF_DataStruct.H:235
int snow_accum
accumulated surface snow
Definition: ERF_DataStruct.H:236

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.
487  {
488  return ( (comp >= 0) &&
489  ( (comp == qv) || (comp == qc) || (comp == qi) ||
490  (comp == qr) || (comp == qs) || (comp == qg) ||
491  (comp == nc) || (comp == ni) || (comp == nr) ||
492  (comp == ns) || (comp == ng) || (comp == nn) ) );
493  }

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.
624  {
625  const VarAvailability status = query_var(name);
626  return (!status.governed) || status.available;
627  }
VarAvailability query_var(const std::string &name) const
Classify an output variable name against this index map.
Definition: ERF_DataStruct.H:579

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.

513 { return (qv >= 0); }

Referenced by query_var(), ERF::setSubVolVariables(), ERF::Write3DPlotFile(), 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.

503  {
504  return ( (qr == RhoQ4_comp) && (qs == RhoQ5_comp) && (qg == RhoQ6_comp) );
505  }

◆ 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".

463  {
464  CompList list;
465  list.append(qv); list.append(qc); list.append(qi);
466  return list;
467  }

Referenced by ERF::Write3DPlotFile().

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.

472  {
473  CompList list;
474  list.append(qr); list.append(qs); list.append(qg);
475  return list;
476  }

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

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.
550  {
551  if (name == "rain_accum") { return rain_accum; }
552  if (name == "snow_accum") { return snow_accum; }
553  if (name == "graup_accum") { return graup_accum; }
554  if (name == "rel_humidity") { return rel_hum; }
555  if (name == "condensation_rate") { return cond_rate; }
556  return absent;
557  }

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

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.
579  {
580 
581  // Single species, taken straight from the conserved state
582  if ( (name == "qv") || (name == "qc") || (name == "qi") ||
583  (name == "qrain") || (name == "qsnow") || (name == "qgraup") ||
584  (name == "nc") || (name == "ni") || (name == "nr") ||
585  (name == "ns") || (name == "ng") || (name == "nn") ) {
586  return {true, comp_for_var(name) >= 0};
587  }
588 
589  // Moist diagnostics, either from a qmoist array or derived at output time
590  if ( (name == "rain_accum") || (name == "snow_accum") ||
591  (name == "graup_accum") || (name == "rel_humidity") ||
592  (name == "condensation_rate") ) {
593  return {true, qmoist_index_for_var(name) != absent};
594  }
595 
596  // Aggregates over several species
597  if (name == "qt") { return {true, !total_water_comps().empty()}; }
598  if (name == "qp") { return {true, !precipitating_comps().empty()}; }
599 
600  // Non-precipitating water is vapor plus the suspended condensate, and
601  // moist density adds that same sum to the dry density
602  if ( (name == "qn") || (name == "moist_density") ) {
603  return {true, (qv >= 0) && (qc >= 0)};
604  }
605 
606  // Column and thermodynamic diagnostics that read vapor only
607  if ( (name == "qsat") || (name == "precipitable") ) {
608  return {true, has_moisture()};
609  }
610 
611  return {false, false};
612  }
bool empty() const
Definition: ERF_DataStruct.H:444
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:525
CompList total_water_comps() const
Components summed for total water, "qt": every mass mixing ratio.
Definition: ERF_DataStruct.H:452
CompList precipitating_comps() const
Components summed for precipitating water, "qp": the falling species.
Definition: ERF_DataStruct.H:472
bool has_moisture() const
Test whether the active scheme carries any moisture at all.
Definition: ERF_DataStruct.H:513
int qmoist_index_for_var(const std::string &name) const
The qmoist slot behind a moist diagnostic output name.
Definition: ERF_DataStruct.H:550

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.

452  {
453  CompList list;
454  list.append(qv); list.append(qc); list.append(qi);
455  list.append(qr); list.append(qs); list.append(qg);
456  return list;
457  }

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

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 from_moisture_model(), and ERF::Write3DPlotFile().

◆ 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

◆ 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: