parcel#

Parcel Lifters#

struct lifter_wobus#

A functor that calls the Wobus Wetlift funtion.

Author

Kelton Halbert - NWS Storm Prediction Center

This functor is used to wrap the Wobus Wetlift function for parcel lifting routines. Functors - classes with their operator() overloaded - are used so that functions can be passed to templates in a way that the compiler can still optimize, rather than using function pointers or lambdas.

Specifically, this functor is designed to be passed as a template argument to sharp::Parcel::lift_parcel, so that the method of computing moist adiabats can be changed without changing the overall parcel lifting code. The reason this is awesome is that the compiler can still optimize and inline this code, while the user can configure the parcel lifting algorithm to their specifications.

Public Functions

inline void setup(const float lcl_pres, const float lcl_tmpk) const#

Perform the setup step for the parcel lifter.

Some parcel lifters require setup in order to handle adiabatic ascent and tracking of vapor, liquid, and ice mixing ratios. The Wobus lifter does not require this, however, so this function does nothing.

inline float operator()(const float pres, const float tmpk, const float new_pres) const#

Overloads operator() to call sharp::wetlift.

Parameters:
  • presParcel pressure (Pa)

  • tmpkParcel temperature (K)

  • new_pres – Final level of parcel after lift (Pa)

Returns:

The temperature of the lifted parcel

inline float parcel_virtual_temperature(const float pres, const float tmpk) const#

Computes the virtual temperature of the parcel.

Parameters:
  • presParcel pressure (Pa)

  • tmpkParcel temperature (K)

Returns:

The virtual temperature of the parcel

Public Members

float converge = 0.001f#

The iterative convergence criteria (K)

struct lifter_cm1#

A functor that calls the CM1 moist adiabat solver.

Author

Kelton Halbert - NWS Storm Prediction Center

This functor is used to wrap the CM1 moist adiabat function for parcel lifting routines. Functors - classes with their operator() overloaded - are used so that functions can be passed to templates in a way that the compiler can still optimize, rather than using function pointers or lambdas.

Specifically, this functor is designed to be passed as a template argument to sharp::Parcel::lift_parcel, so that the method of computing moist adiabats can be changed without changing the overall parcel lifting code. The reason this is awesome is that the compiler can still optimize and inline this code, while the user can configure the parcel lifting algorithm to their specifications.

Public Functions

inline void setup(const float lcl_pres, const float lcl_tmpk)#

perform the necessary setup for parcel ascent.

This function sets the total water mixing ratio for adiabatic parcel ascent, and zeroes out the vapor, liquid, and ice mixing ratios from previous parcel ascents.

inline float operator()(const float pres, const float tmpk, const float new_pres)#

Overloads operator() to call sharp::moist_adiabat_cm1.

Parameters:
  • presParcel pressure (Pa)

  • tmpkParcel temperature (K)

  • new_pres – Final level of parcel after lift (Pa)

Returns:

The temperature of the lifted parcel

inline float parcel_virtual_temperature(const float pres, const float tmpk) const#

Computes the virtual temperature of the parcel.

Parameters:
  • presParcel pressure (Pa)

  • tmpkParcel temperature (K)

Returns:

The virtual temperature of the parcel

Public Members

adiabat ma_type = adiabat::pseudo_liq#

The type of moist adiabat to use, as defined by sharp::adiabat.

float pressure_incr = 500.0f#

The pressure increment (Pa) to use for the iterative solver.

float converge = 0.001f#

The iterative convergence criteria (K)

float rv_total = MISSING#

Used to keep track of mixing ratio for conserved/adiabatic lifting.

float rv = MISSING#

Water vapor mixing ratio variable updated during parcel lifts.

float rl = MISSING#

Liquid water mixing ratio variable updated during parcel lifts.

float ri = MISSING#

Ice water mixing ratio variable updated during parcel lifts.

Parcels#

enum class sharp::LPL : int#

Enum that defines the lifted parcel level (LPL) of origin.

The SFC parcel is a surface-based parcel, where the parcel initial attributes are set to the surface pressure, temperature, and dewpoint.

The FCST parcel is a forecast-surface-based parcel, in which the afternoon surface temperature and dewpoint are estimated and set as the parcel starting values.

The MU parcel is the most unstable parcel, in which the parcel attributes are set to the pressure, temperature, and dewpoint of the maximum Theta-E level within the bottom 400 hPa of the profile.

The ML parcel is the mixed-layer parcel, in which the mean theta and water vapor mixing ratio within the lowest 100 hPa are used to estimate a boundary layer mean, and lifted from the surface.

The USR parcel means that the parcel initial lifting attributes have already been set by the programmer or user, and there is no need for them to be set or modified.

Values:

enumerator SFC#

Surface Based Parcel.

enumerator FCST#

Forecast Surface Parcel.

enumerator MU#

Most Unstable Parcel.

enumerator ML#

Mixed Layer Parcel.

enumerator USR#

User-defined Parcel.

enumerator END#
struct Parcel#

Data that defines a Parcel, its attributes, and derived quantities.

Author

Kelton Halbert - NWS Storm Prediction Center

Contains information about a Parcel’s starting level and thermodynamic attributes, as well as paramaters computed using the parcel.

Public Functions

template<typename Lft>
inline void lift_parcel(Lft &liftpcl, const float pressure_arr[], float pcl_vtmpk_arr[], const std::ptrdiff_t N)#

Lifts a sharp::Parcel to compute its virtual temperature.

Author

Kelton Halbert - NWS Storm Prediction Center

Lifts a sharp::Parcel dry adiabatically from its sharp::LPL to its LCL dry adiabatically, and then moist adiabatically from the LCL to the top of the profile. The moist adiabat used is determined bu the type of lifting functor passed to the function (i.e. sharp::lifter_wobus or sharp::lifter_cm1).

Parameters:
  • liftpclParcel lifting function/functor

  • pressure_arr – Array of env pressure (Pa)

  • pcl_vtmpk_arr – The array to fill with virtual temp (K)

  • N – The length of the arrays

void find_lfc_el(const float pres_arr[], const float hght_arr[], const float buoy_arr[], const std::ptrdiff_t N)#

Find the LFC and EL that bounds the layer with the maximum CAPE.

Author

Kelton Halbert - NWS Storm Prediction Center

Searches the buoyancy array for the LFC and EL combination that results in the most CAPE in the given profile. The buoyancy array is typically computed by calling sharp::Parcel::lift_parcel. Once the LFC and EL are found, the values are set in sharp::Parcel::lfc_pres and sharp::Parcel::eql_pres.

The value of sharp::Parcel::eql_pres is sharp::MISSING if there there is no qualifying level found within the data bounds (e.g. incomplete data, or an EL above the available data). Any calls to sharp::Parcel::cape_cinh will still compute CAPE without the presence of an EL, using the best-available data.

Parameters:
  • pres_arr – The pressure coordinate array (Pa)

  • hght_arr – The height coordinate array (meters)

  • buoy_arr – The profile buoyancy array (m/s^2)

  • N – The length of the arrays

float maximum_parcel_level(const float pres_arr[], const float hght_arr[], const float buoy_arr[], const std::ptrdiff_t N)#

Find the pressure of the Maximum Parcel Level (MPL).

Author

Kelton Halbert - NWS Storm Prediction Center

The Maximum Parcel Level (MPL) is the level a parcel would reach if it expended all of its integrated positive buoyancy past the Eqilibrium Level. It is found by integrating negatively buoyant area above the Equilibrium Level until the integrated negative buoyancy is equal in magnitude to the Convective Available Potential Energy betwee the Level of Free Convection and the Equilibrium Level.

For valid calculations, sharp::Parcel::cape_cinh must be called first, or sharp::Parcel::cape and sharp::Parcel::eql_pressure must be set.

A value of sharp::MISSING is returned if:

In addition to being returned, the result is stored inside of sharp::Parcel::mpl_pressure.

Parameters:
  • pres_arr – Array of pressure (Pa)

  • hght_arr – Array of height (meters)

  • buoy_arr – Array of buoyancy (m/s^2)

  • N – Lengh of arrays

Returns:

Maximum Parcel Level (MPL) Pressure (Pa)

void cape_cinh(const float pres_arr[], const float hght_arr[], const float buoy_arr[], const std::ptrdiff_t N)#

Compute CAPE and CINH for a previously lifted sharp::Parcel.

Author

Kelton Halbert - NWS Storm Prediction Center

Assuming that sharp::Parcel::lift_parcel has been called, cape_cinh will integrate the area between the LFC and EL to compute CAPE, and integrate the area between the LPL and LCL to compute CINH.

If sharp::Parcel::eql_pressure is sharp::MISSING, but the sharp::Parcel::lfc_pressure is defined, the routine will compute CAPE with the available data despite the lack of a defined equilibrium level. This is useful for incomplete profile data, or pressure-level data where the EL is above the top pressure value.

The results are set in pcl->cape and pcl->cinh.

Parameters:
  • pres_arr – Array of pressure (Pa)

  • hght_arr – Array of height (meters)

  • buoy_arr – Array of buoyancy (m/s^2)

  • N – Length of arrays

Public Members

float pres = MISSING#

Parcel starting pressure (Pa)

float tmpk = MISSING#

Parcel starting temperature (K)

float dwpk = MISSING#

Parcel starting dewpoint (K)

float lcl_pressure = MISSING#

Pressure at the Lifted Condensation Level (Pa)

float lfc_pressure = MISSING#

Pressure at the Level of Free Convection (Pa)

float eql_pressure = MISSING#

Pressure at the parcel Equilibrium Level (Pa)

float mpl_pressure = MISSING#

Pressure at the Maximum Parcel Level (MPL) (Pa)

float cape = 0.0#

Parcel Convective Available Potential Energy (J/kg) between the LFC and EL.

float cinh = std::nanf("")#

Parcel Convective Inhibition (J/kg) between the LFC and EL.

LPL source#

The type of parcel this is.

Public Static Functions

static inline Parcel surface_parcel(const float pressure, const float temperature, const float dewpoint) noexcept#

Construct and return a surface-based Parcel.

Author

Kelton Halbert - NWS Storm Prediction Center

Given input values of surface pressure, temperature, and dewpoint temperature, construct and return a Surface Based Parcel.

Parameters:
  • pressure – Surface pressure (Pa)

  • temperature – Surface temperature (K)

  • dewpoint – Surface dewpoint (K)

Returns:

sharp::Parcel with surface values

template<typename Lyr>
static inline Parcel mixed_layer_parcel(Lyr &mix_layer, const float pressure[], const float height[], const float pot_temperature[], const float wv_mixratio[], const std::ptrdiff_t N) noexcept#

Construct and return a mixed-layer Parcel.

Author

Kelton Halbert - NWS Storm Prediction Center

Given input arrays of pressure, height, potential temperature, and water vapor mixing ratio, as well as a defined sharp::PressureLayer or sharp::HeightLayer, compute and return a mixed-layer Parcel.

Parameters:
  • mix_layersharp::PressureLayer or sharp::HeightLayer

  • pressure – Array of pressure (Pa)

  • height – Array of height (meters)

  • pot_temperature – Array of potential temperature (K)

  • wv_mixratio – Array of water vapor mixing ratio (unitless)

  • N – Length of arrays

Returns:

sharp::Parcel with mixed-layer values

template<typename Lyr, typename Lft>
static inline Parcel most_unstable_parcel(Lyr &search_layer, Lft &lifter, const float pressure[], const float height[], const float temperature[], const float virtemp[], const float dewpoint[], float pcl_virtemp[], float buoy_arr[], const std::ptrdiff_t N) noexcept#

Construct and return a most-unstable Parcel.

Author

Kelton Halbert - NWS Storm Prediction Center

Given input arrays of pressure, height, temperature, virtual temperature, and dewpoint, a scratch/working array to store values of buoyancy, and a defined sharp::PressureLayer or sharp::HeightLayer to search over, find and return the most-unstable parcel.

Parameters:
  • pressure – Array of pressure (Pa)

  • height – Array of height (meters)

  • temperature – Array of temperature (K)

  • virtemp – Array of virtual temperature (K)

  • dewpoint – Array of dewpoint temperature (K)

  • pcl_virtemp – Writeable array for parcel lifting calcs (K)

  • buoy_arr – Writeable array for buoyancy calcs (m/s^2)

  • N – Length of arrays

  • search_layersharp::PressureLayer or sharp::HeightLay

  • lifter – The parcel moist adiabatic ascent function

Returns:

The most unstable sharp::Parcel within the search layer

struct DowndraftParcel#

Data that defines a DowndraftParcel, its attributes, and derived quantities.

Author

Kelton Halbert - NWS Storm Prediction Center

Contains information about a DowndraftParcel’s starting level and thermodynamic attributes, as well as paramaters computed using the parcel.

Public Functions

template<typename Lft>
inline void lower_parcel(Lft &liftpcl, const float pressure_arr[], float pcl_tmpk_arr[], const std::ptrdiff_t N)#

Lowers a saturated sharp::Parcel.

Author

Kelton Halbert - NWS Storm Prediction Center

Lowers a saturated sharp::Parcel moist adiabatically from its sharp::LPL to the surface. The moist adiabat used is determined bu the type of lifting functor passed to the function (i.e. sharp::lifter_wobus or sharp::lifter_cm1).

Unlike sharp::lift_parcel, the virtual temperature correction is not used for downdraft parcels.

Parameters:
  • liftpclParcel lifting function/functor

  • pressure_arr – Array of env pressure (Pa)

  • pcl_tmpk_arr – The array to fill with parcel temperature (K)

  • N – The length of the arrays

void cape_cinh(const float pres_arr[], const float hght_arr[], const float buoy_arr[], const ptrdiff_t N)#

Compute CAPE and CINH for a previously lowered sharp::DowndraftParcel.

Author

Kelton Halbert - NWS Storm Prediction Center

Assuming that sharp::DowndraftParcel::lower_parcel has been called, cape_cinh will integrate the area between the LPL and the surface to compute downdraft CAPE and downdraft CINH.

The results are set in sharp::DowndraftParcel::cape and sharp::DowndraftParcel::cinh.

Parameters:
  • pres_arr – Array of pressure (Pa)

  • hght_arr – Array of height (meters)

  • buoy_arr – Array of buoyancy (m/s^2)

  • N – Length of arrays

Public Members

float pres = MISSING#

DowndraftParcel starting pressure (Pa)

float tmpk = MISSING#

DowndraftParcel starting temperature (K)

float dwpk = MISSING#

DowndraftParcel starting dewpoint (K)

float cape = 0.0#

DowndraftParcel Convective Available Potential Energy (J/kg) between the LFC and EL.

float cinh = std::nanf("")#

DowndraftParcel Convective Inhibition (J/kg) between the LFC and EL.

Public Static Functions

static inline DowndraftParcel min_thetae(sharp::PressureLayer &search_layer, const float pressure[], const float temperature[], const float dewpoint[], const float thetae[], const std::ptrdiff_t N, const float mean_depth = 10000.0f)#

Define a downdraft parcel.

Author

Kelton Halbert - NWS Storm Prediction Center

Defines a downdraft parcel within a given search layer. The downdraft parcel is defined as the mimumim layer-mean equivalent potential temperature (Theta-E) within the search layer. Typical values are to search within the lowest 400 hPa of the profile, and a mean depth of 100 hPa.

Parameters:
  • search_layersharp::PressureLayer to search

  • pressure – (Pa)

  • temperature – (K)

  • dewpoint – (K)

  • thetae – (K)

  • N – (length of arrays)

  • mean_depth – (Pa)

Returns:

the sharp::DowndraftParcel defining a downdraft parcel.