CloudToppedMixedLayerModel
ConceptualClimateModels.CloudToppedMixedLayerModel
— ModuleCloudToppedMixedLayerModel
Submodule providing processes about cloud topped mixed layer models (MLMs). This combines existing equations on MLM by (Stevens, 2006) and (Bretherton and Wyant, 1997), with surface energy balance and dynamic cloud equations. It is developed as part of the research article (Datseris, 2025). If you use this submodule, please cite the paper.
The organization is as follows:
- All important variables and parameters (participate in many processes) are defined in the module file and as module-level scoped variables (global variables). Click the "source" of this docstring to access the module file.
- All processes (physical equations) are defined in their respective files such as
free_troposhere.jl
, etc. Docstrings of important processes are expanded in the docs here. You will notice that all functions that return processes (equations) utilize these global variables and global parameters. Many of these functions will also define local variables and parameters. All noteworthy processes have docstrings that are expanded in the submodule online documentation. However, the majority of docstrings do not actually list the equations themselves. Simply click the "source code" button on the bottom right of each docstring to go to the source code. Because this package is written in Julia, and because it uses symbolic expressions throughout, reading the source code is truly as straight forward as reading Latex-rendered equations. - The
default.jl
file defines default processes for many global variables. These are also expanded in the docs.
Throughout the submodule time is in units of days, specific humidity is in units of g/kg, liquid water static energy is in units of K (i.e., normalized by cₚ), height in meters, temperature in K, and all energy quantities are in W/m².
To learn how to use this submodule visit first the general tutorial of ConceptualClimateModels.jl and then the dedicated example on a cloudy mixed layer model. The module purposefully does not export any names, so the recommended way to use it is by an alias: import ConceptualClimateModels.CloudToppedMixedLayerModel as CTMLM
.
Mixed layer
ConceptualClimateModels.CloudToppedMixedLayerModel.mlm_dynamic
— Functionmlm_dynamic()
Provide equations 1-3 in (Datseris, 2025) (or, 31-33 in (Stevens, 2006)) defining the bulk boundary layer dynamics. An additional auxilary velocity $-w_m$ is added in the equation for $z_b$ and two auxilary export terms $q_x, s_x$ are added to the equations for $q_b, s_b$. All these auxilarity terms are 0 by default (otherwise, assign a process to them).
ConceptualClimateModels.CloudToppedMixedLayerModel.bbl_stevens2006_steadystate
— Functionbbl_stevens2006_steadystate(fixed; z_b, q_b, s_b, CLT)
Return the equations 35-38 in (Stevens, 2006) describing the analytically solved steady state of the MLM. These equations could be coupled to other parts of module but we have a problem of circular dependency for the steady state of $z_b$. If we attempt to couple them with the dynamic equations for $C$, then the following:
z_b ~ h⃰ * (e_e*σ_38)/(1 + σ_38 - e_e),
σ_38 ~ V*Δs*cₚ/(ΔF/ρ₀),
yields a circular dependency: z_b
depends on σ_38
which depends on ΔF
which depends on T_t
which depends on z_b
. To resolve this a fixed
option is given, which can be any of: ΔF, z_b, w_s, T_t
. This quantity is set fixed and becomes a parameter so that the equation for z_b
is closed.
ConceptualClimateModels.CloudToppedMixedLayerModel.temperature_exact
— Functiontemperature_exact(z, s, q)
Use root-finding to find the temperature at height z
given the liquid water static energy and total specific humidity, as described by (Stevens, 2006). This is the default equation used for T_t ~ temperature_exact(z_b, s_b, q_b)
.
ConceptualClimateModels.CloudToppedMixedLayerModel.entrainment_velocity
— Functionentrainment_velocity(version = :Stevens2006; use_augmentation = true)
Return an equation for the entrainment velocity $w_e$. Versions are :Stevens2006, :Gesso2014, :LL96
. Keyword use_augmentation
adds the decoupling-based augmentation described in (Datseris, 2025).
ConceptualClimateModels.CloudToppedMixedLayerModel.q_liquid
— Functionq_liquid(T, q, z)
liquid specific humidity given temperature total water specific humidity and height. 0.0 if below saturation.
ConceptualClimateModels.CloudToppedMixedLayerModel.q_saturation
— Functionq_saturation(T, z)
Saturation specific humidity given temperature and height. Height is transformed to pressure via hydrostatic approximation.
ConceptualClimateModels.CloudToppedMixedLayerModel.pressure
— Functionpressure(z, T)
Use hydrostatic balance and ideal gas law to get pressure at height z given temperature at height z. The equation is often called the "Hypsometric equation" with the factor (RdT/g) called the scale height. Note that normally using Rd requires usage of Tv (virtual temperature), defined as Tv = T(1 + 0.608*q) with q the specific humidity of water vapor. In the codebase we practically always approximate Tv by T.
ConceptualClimateModels.CloudToppedMixedLayerModel.sst_dynamic
— FunctionReturn τSST * d(SST)/dt = ASW - Lnet - LHF - SHF + SST_X .
Clouds and decoupling
ConceptualClimateModels.CloudToppedMixedLayerModel.cf_dynamic
— Functioncf_dynamic()
Provide the equations $\tau_C dC/dt = C_\mathcal{D} - C$ as well as the equation that defines $C_\mathcal{D}$ as a function of the decoupling variable $\mathcal{D}$. The function uses the curve fitted to data in (Datseris, 2025).
ConceptualClimateModels.CloudToppedMixedLayerModel.cloud_emission_temperature
— Functioncloud_emission_temperature(version = :mean)
Return a process for $T_C$. Versions are :top, :base, :mean
.
ConceptualClimateModels.CloudToppedMixedLayerModel.cloud_emissivity
— Functioncloud_emissivity(version = 1.0; fraction = true)
Provide an equation for the effective emissivity of the cloud layer. Options for version
:
:clt
: inspired by (Randall and Suarez, 1984), emissivity scales with the depth of the cloud layer.:liquid_water_path
: Exponential of LWP.<: Number
: emissiviy is just the provided number or symbolic expression.
If fraction = true
the emissivity is further multiplied by the cloud fraction.
ConceptualClimateModels.CloudToppedMixedLayerModel.cloud_layer_thickness
— Functioncloud_layer_thickness(version = :exact)
Provide an equation for the relative/normalized cloud layer thickness CLT. The options for version are:
:exact
: exact estimation by figuring out whenq_liquid
first becomes positive. Computationally costly as it requires interpolations.:Bolton1980
: Well known approximate expression by Bolton, 1980.
ConceptualClimateModels.CloudToppedMixedLayerModel.decoupling_variable
— Functiondecoupling_variable(version = :Bretherton1997)
Return an equation for $\mathcal{D}$, the decoupling variable.
ConceptualClimateModels.CloudToppedMixedLayerModel.decoupling_ratios
— Functiondecoupling_ratios()
Return equations for $\mathcal{d}_q, \mathcal{d}_s$ as in (Datseris, 2025).
Radiation
ConceptualClimateModels.CloudToppedMixedLayerModel.cloud_shortwave_warming
— Functioncloud_shortwave_warming()
Provide an equation for CTRC_sw which by default is 0.04*C*S
.
ConceptualClimateModels.CloudToppedMixedLayerModel.cloud_longwave_cooling
— Functioncloud_longwave_cooling()
Provide an equation for CTRC_lw.
ConceptualClimateModels.CloudToppedMixedLayerModel.mlm_radiative_cooling
— Functionmlm_radiative_cooling(version = :three_layer)
Provide an equation for $\Delta F_s$, the radiative cooling of the boundary layer (assumming $\Delta F_q = 0$). Versions are: :three_layer, :ctrc, :Gesso2014
as in (Datseris, 2025).
ConceptualClimateModels.CloudToppedMixedLayerModel.downwards_longwave_radiation
— Functiondownwards_longwave_radiation([version])
Provide equation for $L_d, L_{net}$, the incoming longwave radiation or the net longwave radiative cooling of the surface. See the source code for possible versions.
ConceptualClimateModels.CloudToppedMixedLayerModel.albedo
— FunctionReturn an equation for α
the total albedo perceived by the surface.
ConceptualClimateModels.CloudToppedMixedLayerModel.matsunobu_emissivity
— Functionmatsunobu_emissivity(RH, T, H = 0)
Return emissivity at given relative humidity and temperature as defined by (Matsunobu and Coimbra, 2024).
Free troposphere
ConceptualClimateModels.CloudToppedMixedLayerModel.free_troposphere_emission_temperature
— Functionfree_troposphere_emission_temperature(γ = 1.0; add_co2 = true)
Return an equation for $T_{FTR}$. γ
is as in (Datseris, 2025). add_co2
will add an additional warming term ECS_CO2*log2(CO2/400)
.
ConceptualClimateModels.CloudToppedMixedLayerModel.mlm_s₊
— Functionmlm_s₊(
version = :difference;
cloud_effect = false,
CO2_effect = false,
)
Provide equation for $s_+$. To do this, a boundary condition must be provided that is a fixed parameter. version
argument decides this:
:difference
: the starting temperature difference across inversion is a fixed parameter.:temperature
: the starting temperature after the inversion is a fixed parameter.:static_energy
: the starting moist static energy after the inversion is a fixed parameter.
Besides these, we can also specify whether CO2 increase also increases temperature difference, and whether decreasing $C$ decreases temperature difference due to cloud thinning as in (Singer and Schneider, apr 2023).
ConceptualClimateModels.CloudToppedMixedLayerModel.mlm_q₊
— Functionmlm_q₊(version = :relative)
Provide equation for $q_+$. If version = :relative
then make free tropospheric relative humidity a free parameter. Else if version = :constant
then make $q_+$ itself a parameter.
Default processes
using ConceptualClimateModels
import ConceptualClimateModels.CloudToppedMixedLayerModel as CTMLM
default_processes_eqs(CTMLM)
\[ \begin{align} S\left( t \right) &= \mathtt{S\_0} \\ \mathtt{\rho_0}\left( t \right) &= \frac{1.0178 \cdot 10^{5}}{287 \mathtt{SST}\left( t \right)} \\ \mathtt{q\_x}\left( t \right) &= 0 \\ \mathtt{L_0}\left( t \right) &= 5.6704 \cdot 10^{-8} \left( \mathtt{SST}\left( t \right) \right)^{4} \\ \mathtt{L\_b}\left( t \right) &= 5.6704 \cdot 10^{-8} \left( \mathtt{T\_b}\left( t \right) \right)^{4} \mathtt{\varepsilon\_b}\left( t \right) \\ \mathtt{T\_t}\left( t \right) &= temperature\_exact\left( \mathtt{z\_b}\left( t \right), \mathtt{s\_b}\left( t \right), \mathtt{q\_b}\left( t \right) \right) \\ \mathtt{\Delta.s}\left( t \right) &= - \mathtt{s\_b}\left( t \right) + \mathtt{s.}\left( t \right) \\ \mathtt{s\_x}\left( t \right) &= 0 \\ \mathtt{s_0}\left( t \right) &= \mathtt{SST}\left( t \right) \\ \mathtt{\Delta_{0}q}\left( t \right) &= \mathtt{q\_b}\left( t \right) - \mathtt{q_0}\left( t \right) \\ \mathtt{L\_c}\left( t \right) &= 5.6704 \cdot 10^{-8} \left( \mathtt{T\_c}\left( t \right) \right)^{4} \mathtt{\varepsilon\_c}\left( t \right) \\ \alpha\left( t \right) &= 1 - \left( 1 - C\left( t \right) \mathtt{\alpha\_C} \right) \left( 1 - \mathtt{\alpha\_a} \right) \left( 1 - \mathtt{\alpha\_s} \right) \\ \zeta\left( t \right) &= 0 \\ \mathtt{RH\_b}\left( t \right) &= \frac{\mathtt{q\_b}\left( t \right)}{\mathtt{q_0}\left( t \right)} \\ V\left( t \right) &= U \mathtt{c\_d} \\ \mathtt{LHF}\left( t \right) &= - 2530 \mathtt{\Delta_{0}q}\left( t \right) V\left( t \right) \mathtt{\rho_0}\left( t \right) \\ \mathtt{w\_v}\left( t \right) &= 0 \\ \mathtt{\varepsilon\_FTR}\left( t \right) &= clamp\left( 0.62 + 1.642 \sqrt{0.0060026 \mathtt{RH.} e^{\frac{17.625 \left( -273.15 + \mathtt{T\_FTR}\left( t \right) \right)}{-30.11 + \mathtt{T\_FTR}\left( t \right)}}}, 0, 1 \right) \\ \mathtt{T\_c}\left( t \right) &= \frac{1}{2} \left( \mathtt{T\_t}\left( t \right) + \mathtt{T\_lcl}\left( t \right) \right) \\ \mathtt{w\_m}\left( t \right) &= 0 \\ \mathtt{CTRC}\left( t \right) &= \mathtt{CTRClw}\left( t \right) - \mathtt{CRCsw}\left( t \right) \\ \mathtt{T\_b}\left( t \right) &= \left( 1 - \mathtt{h\_b} \right) \mathtt{s\_b}\left( t \right) + \mathtt{h\_b} \mathtt{T\_lcl}\left( t \right) \\ \mathtt{\Delta.q}\left( t \right) &= - \mathtt{q\_b}\left( t \right) + \mathtt{q.}\left( t \right) \\ \mathtt{CRC}\left( t \right) &= \mathtt{CRClw}\left( t \right) - \mathtt{CRCsw}\left( t \right) \\ \mathtt{ASW}\left( t \right) &= - \mathtt{CRCsw}\left( t \right) + S\left( t \right) \left( 1 - \alpha\left( t \right) \right) \\ \mathtt{\varepsilon\_b}\left( t \right) &= clamp\left( 0.62 + 1.642 \sqrt{0.0060026 e^{\frac{17.625 \left( -273.15 + \mathtt{T\_b}\left( t \right) \right)}{-30.11 + \mathtt{T\_b}\left( t \right)}} \mathtt{RH\_b}\left( t \right)}, 0, 1 \right) \\ \mathtt{q_0}\left( t \right) &= \frac{3.8025 \cdot 10^{5} e^{ - 5488.1 \left( -0.0036609 + \frac{1}{\mathtt{SST}\left( t \right)} \right)}}{1.0178 \cdot 10^{5} - 610.78 e^{ - 5488.1 \left( -0.0036609 + \frac{1}{\mathtt{SST}\left( t \right)} \right)}} \\ \mathtt{Lnet}\left( t \right) &= \mathtt{L_0}\left( t \right) - \mathtt{Ld}\left( t \right) \\ \mathtt{LWP}\left( t \right) &= liquid\_water\_path\left( \mathtt{T\_t}\left( t \right), \mathtt{CLT}\left( t \right), \mathtt{z\_b}\left( t \right), \mathtt{s\_b}\left( t \right), \mathtt{q\_b}\left( t \right) \right) \\ \mathtt{SHF}\left( t \right) &= - 1004 V\left( t \right) \mathtt{\rho_0}\left( t \right) \mathtt{\Delta_{0}s}\left( t \right) \\ \mathtt{\mathscr{d}\_q}\left( t \right) &= 0 \\ \mathtt{\mathscr{d}\_s}\left( t \right) &= 0 \\ \mathtt{SST\_X}\left( t \right) &= \mathtt{SST\_X\_0} \\ \mathtt{\Delta_{0}s}\left( t \right) &= \mathtt{s\_b}\left( t \right) - \mathtt{s_0}\left( t \right) \\ \mathtt{T\_lcl}\left( t \right) &= \mathtt{s\_b}\left( t \right) - 0.009761 \mathtt{CLT}\left( t \right) \mathtt{z\_b}\left( t \right) \\ \mathtt{L\_FTR}\left( t \right) &= 5.6704 \cdot 10^{-8} \left( \mathtt{T\_FTR}\left( t \right) \right)^{4} \mathtt{\varepsilon\_FTR}\left( t \right) \end{align} \]