"from moist_thermodynamics import functions as mt\n",
"from moist_thermodynamics import constants"
]
},
{
"cell_type": "markdown",
"id": "9d38216a-175f-4c09-958b-56537aa8834f",
"metadata": {},
"source": [
"# Examples\n",
"\n",
"Usage of the moist thermodynamic functions is documented through a number of examples\n",
"\n",
"1. constructing a moist adiabat.\n",
"2. sensitivity of moist adiabat on saturation vapor pressure \n",
"3. lcl computations\n",
"\n",
"## 1. Constructing a moist adiabat\n",
"\n",
"This shows how simple it is to construct a moist adiabat. For the example it is constructed by assuming a constant $\\theta_\\mathrm{l}$ but the same answer (with the caveats of the next example) would arise if we were to define it in terms of constant $\\theta_\\mathrm{e}$ or $\\theta_\\mathrm{s}$"
"## 2. Sensitivity (small) of moist adiabat on saturation vapor pressure \n",
"\n",
"The derivation of the moist potential temperatures assumes a Rankine fluid, i.e., constant specific heats. Specific heats vary with temperature however, especially $c_i$. This variation is encoded in the best fits to the saturation vapor pressure, so that an adiabat defined in terms of a best fit saturation vapor pressure will differ depending on whether it assumes $\\theta_\\mathrm{e},$ $\\theta_\\mathrm{l},$ or $\\theta_\\mathrm{s}.$ This sensitivity vanishes (right plot, note $x$-axis scale) when we replace the more accurate saturation vapor pressures with less accurate expressions, albeit consistent with a Rankine fluid."
"## 3. Calculations of lifting condensation level\n",
"\n",
"We compare three different formulations of the lifting condensation level, one due to Romps (2017) is not included in the moist_thermodynamics library, but is included here for sake of comparision. The analysis shows that the simple bolton approximations work very well, as well as those of Romps if one uses the wagner saturation vapor pressure data. Had we performed this comparison with the analytic formula using the specific heats specified by Romps, the comparison would have been more favorable for the Romps formulation."
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "a53539ae-7920-41b9-aa41-fed0031ce16b",
"metadata": {},
"outputs": [],
"source": [
"# Version 1.0 released by David Romps on September 12, 2017.\n",
"# \n",
"# When using this code, please cite:\n",
"# \n",
"# @article{16lcl,\n",
"# Title = {Exact expression for the lifting condensation level},\n",
"# Author = {David M. Romps},\n",
"# Journal = {Journal of the Atmospheric Sciences},\n",
"# Year = {2017},\n",
"# Volume = {in press},\n",
"# }\n",
"#\n",
"# This lcl function returns the height of the lifting condensation level\n",
"# (LCL) in meters. The inputs are:\n",
"# - p in Pascals\n",
"# - T in Kelvins\n",
"# - Exactly one of rh, rhl, and rhs (dimensionless, from 0 to 1):\n",
"# * The value of rh is interpreted to be the relative humidity with\n",
"# respect to liquid water if T >= 273.15 K and with respect to ice if\n",
"# T < 273.15 K. \n",
"# * The value of rhl is interpreted to be the relative humidity with\n",
"# respect to liquid water\n",
"# * The value of rhs is interpreted to be the relative humidity with\n",
"# respect to ice\n",
"# - ldl is an optional logical flag. If true, the lifting deposition\n",
"# level (LDL) is returned instead of the LCL. \n",
"# - min_lcl_ldl is an optional logical flag. If true, the minimum of the\n",
" X = bL/(aL*scipy.special.lambertw(bL/aL*cL**(1/aL),-1).real)\n",
" Y = bS/(aS*scipy.special.lambertw(bS/aS*cS**(1/aS),-1).real) \n",
" \n",
" lcl = cpm*T/ggr*( 1 - X)\n",
" ldl = cpm*T/ggr*( 1 - Y)\n",
"\n",
" # Modifications of the code to output Plcl or Pldl\n",
" Plcl = PPa * X**(cpm/rgasm)\n",
" Pldl = PPa * X**(cpm/rgasm)\n",
" # Return either lcl or ldl\n",
" if return_ldl and return_min_lcl_ldl:\n",
" exit('return_ldl and return_min_lcl_ldl cannot both be true')\n",
" elif return_ldl:\n",
" return Pldl\n",
" elif return_min_lcl_ldl:\n",
" return min(Plcl,Pldl)\n",
" else:\n",
" return Plcl"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "9b2830db-855d-467d-ac66-cc9154ab7caa",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/Users/m219063/opt/miniforge3/lib/python3.9/site-packages/scipy/optimize/_minpack_py.py:175: RuntimeWarning: The iteration is not making good progress, as measured by the \n",
" improvement from the last ten iterations.\n",
" warnings.warn(msg, RuntimeWarning)\n",
"/Users/m219063/opt/miniforge3/lib/python3.9/site-packages/scipy/optimize/_minpack_py.py:175: RuntimeWarning: The iteration is not making good progress, as measured by the \n",
Usage of the moist thermodynamic functions is documented through a number of examples
1. constructing a moist adiabat.
2. sensitivity of moist adiabat on saturation vapor pressure
3. lcl computations
## 1. Constructing a moist adiabat
This shows how simple it is to construct a moist adiabat. For the example it is constructed by assuming a constant $\theta_\mathrm{l}$ but the same answer (with the caveats of the next example) would arise if we were to define it in terms of constant $\theta_\mathrm{e}$ or $\theta_\mathrm{s}$
## 2. Sensitivity (small) of moist adiabat on saturation vapor pressure
The derivation of the moist potential temperatures assumes a Rankine fluid, i.e., constant specific heats. Specific heats vary with temperature however, especially $c_i$. This variation is encoded in the best fits to the saturation vapor pressure, so that an adiabat defined in terms of a best fit saturation vapor pressure will differ depending on whether it assumes $\theta_\mathrm{e},$ $\theta_\mathrm{l},$ or $\theta_\mathrm{s}.$ This sensitivity vanishes (right plot, note $x$-axis scale) when we replace the more accurate saturation vapor pressures with less accurate expressions, albeit consistent with a Rankine fluid.
We compare three different formulations of the lifting condensation level, one due to Romps (2017) is not included in the moist_thermodynamics library, but is included here for sake of comparision. The analysis shows that the simple bolton approximations work very well, as well as those of Romps if one uses the wagner saturation vapor pressure data. Had we performed this comparison with the analytic formula using the specific heats specified by Romps, the comparison would have been more favorable for the Romps formulation.
/Users/m219063/opt/miniforge3/lib/python3.9/site-packages/scipy/optimize/_minpack_py.py:175: RuntimeWarning: The iteration is not making good progress, as measured by the
improvement from the last ten iterations.
warnings.warn(msg, RuntimeWarning)
/Users/m219063/opt/miniforge3/lib/python3.9/site-packages/scipy/optimize/_minpack_py.py:175: RuntimeWarning: The iteration is not making good progress, as measured by the