soil_heat.wang_and_yang

Python translation of every numbered equation in:

> Yang, K., & Wang, J. (2008). A temperature prediction‑correction method for > estimating surface soil heat flux from soil temperature and moisture data. > *Science in China Series D: Earth Sciences, 51*(5), 721‑729. > https://doi.org/10.1007/s11430‑008‑0036‑1

The paper introduces a Temperature‑Diffusion plus Error‑Correction (TDEC) approach for estimating surface soil heat flux. This module provides a direct one‑to‑one mapping from each equation in the paper (Eqs. 1–12) to a Python function. Helper utilities required by those equations—matrix creators, grid stretching, tridiagonal solvers, etc.—are also included.

All functions accept NumPy arrays or scalars where applicable and are fully type‑annotated. Docstrings use the NumPy docstring standard so they can be rendered by Sphinx‑napoleon.

Functions

soil_heat_flux(→ numpy.ndarray)

Compute heat flux G at cell interfaces using Fourier’s law.

integrated_soil_heat_flux(→ numpy.ndarray)

Calculate the soil heat flux profile by integrating the change in

volumetric_heat_capacity(→ numpy.ndarray)

Calculate the volumetric heat capacity of moist soil based on its

stretched_grid(→ numpy.ndarray)

Generate layer thicknesses for a vertically stretched grid.

solve_tde(→ numpy.ndarray)

Solve the 1D thermal diffusion equation for one time step using an

correct_profile(→ numpy.ndarray)

Correct a modeled temperature profile using observed temperatures.

surface_temperature_longwave(→ float)

Calculate surface temperature from upward and downward long-wave

thermal_conductivity_yang2008(→ numpy.ndarray)

Estimate soil thermal conductivity based on soil moisture and dry

flux_error_linear(→ numpy.ndarray)

Calculate the diagnostic error in heat flux that arises from assuming

surface_energy_residual(→ float)

Calculate the residual of the surface energy budget (Yang & Wang 2008, Eq. 12).

tdec_step(→ Tuple[numpy.ndarray, numpy.ndarray])

Perform a single integration step of the TDEC (Temperature Diffusion

Module Contents

soil_heat.wang_and_yang.soil_heat_flux(Tz: ArrayLike, dz: ArrayLike, lambda_s: ArrayLike | float) numpy.ndarray[source]

Compute heat flux G at cell interfaces using Fourier’s law.

This function calculates the conductive heat flux between soil layers based on the temperature gradient and thermal conductivity.

\[G = -\lambda_s \frac{\partial T}{\partial z}\]
Parameters:
  • Tz (ArrayLike) – A 1D array of temperatures at the centre of each soil layer (K).

  • dz (ArrayLike) – A 1D array of the thickness of each soil layer (m).

  • lambda_s (ArrayLike or float) – Thermal conductivity for each layer (W m⁻¹ K⁻¹). Can be a single value (for homogeneous soil) or an array matching Tz.

Returns:

An array of heat fluxes (W m⁻²) at the interfaces between layers, including the surface and bottom boundaries. The length of the output is len(Tz) + 1. Positive values indicate downward flux.

Return type:

numpy.ndarray

soil_heat.wang_and_yang.integrated_soil_heat_flux(rho_c: ArrayLike, T_before: ArrayLike, T_after: ArrayLike, dz: ArrayLike, dt: float, G_ref: float = 0.0) numpy.ndarray[source]

Calculate the soil heat flux profile by integrating the change in heat storage upwards from a reference depth (Yang & Wang 2008, Eq. 5).

\[G(z_i) = G(z_{ref}) + \int_{z_i}^{z_{ref}} \rho_s c_s \frac{\partial T}{\partial t} dz\]
Parameters:
  • rho_c (ArrayLike) – A 1D array of volumetric heat capacity (ρ_s c_s) for each soil layer (J m⁻³ K⁻¹).

  • T_before (ArrayLike) – A 1D array of temperatures at the start of the time step (K).

  • T_after (ArrayLike) – A 1D array of temperatures at the end of the time step (K).

  • dz (ArrayLike) – A 1D array of layer thicknesses (m).

  • dt (float) – The duration of the time step (s).

  • G_ref (float, optional) – The heat flux at the lower reference depth z_ref (W m⁻²). This is typically assumed to be zero at a sufficient depth, by default 0.0.

Returns:

An array of heat fluxes (W m⁻²) at the upper interface of each layer, with a size of len(dz).

Return type:

numpy.ndarray

soil_heat.wang_and_yang.volumetric_heat_capacity(theta: ArrayLike, theta_sat: float | ArrayLike) numpy.ndarray[source]

Calculate the volumetric heat capacity of moist soil based on its water content (Yang & Wang 2008, Eq. 4).

\[\rho_s c_s = (1 - \theta_{sat}) \rho_{d}c_{d} + \theta \rho_w c_w\]
Parameters:
  • theta (ArrayLike) – Volumetric water content (m³ m⁻³).

  • theta_sat (float or ArrayLike) – Soil porosity, i.e., saturated volumetric water content (m³ m⁻³).

Returns:

The volumetric heat capacity ρ_s c_s (J m⁻³ K⁻¹).

Return type:

numpy.ndarray

soil_heat.wang_and_yang.stretched_grid(n: int, D: float, xi: float) numpy.ndarray[source]

Generate layer thicknesses for a vertically stretched grid.

The grid layer thickness increases exponentially with depth, allowing for higher resolution near the surface.

\[\Delta z_i = \Delta z_0 \exp(\xi (i-1))\]
Parameters:
  • n (int) – The number of soil layers.

  • D (float) – The total depth of the soil domain (m).

  • xi (float) – The stretching parameter. xi = 0 results in a uniform grid. xi > 0 results in a grid that is finer at the top.

Returns:

A 1D array of thickness Δz_i for each of the n layers (m).

Return type:

numpy.ndarray

soil_heat.wang_and_yang.solve_tde(T_prev: ArrayLike, dz: ArrayLike, rho_c: ArrayLike, lambda_s: ArrayLike | float, Tsfc: float, Tbot: float, dt: float) numpy.ndarray[source]

Solve the 1D thermal diffusion equation for one time step using an implicit Crank-Nicolson scheme (Yang & Wang 2008, Eq. 7).

This function sets up and solves the tridiagonal system of linear equations M * T_new = D to find the temperature profile at the next time step.

Parameters:
  • T_prev (ArrayLike) – Temperature profile at the previous time step (K).

  • dz (ArrayLike) – Layer thicknesses (m).

  • rho_c (ArrayLike) – Volumetric heat capacity of each layer (J m⁻³ K⁻¹).

  • lambda_s (ArrayLike or float) – Thermal conductivity of each layer (W m⁻¹ K⁻¹).

  • Tsfc (float) – Surface temperature boundary condition (K).

  • Tbot (float) – Bottom temperature boundary condition (K).

  • dt (float) – Time step (s).

Returns:

The new temperature profile at t + dt, including boundary nodes.

Return type:

numpy.ndarray

soil_heat.wang_and_yang.correct_profile(T_model: ArrayLike, depths_model: ArrayLike, T_obs: ArrayLike, depths_obs: ArrayLike) numpy.ndarray[source]

Correct a modeled temperature profile using observed temperatures.

This function calculates the bias (error) between the model and observations at the observation depths, then linearly interpolates this bias across the entire model grid to correct the profile.

Parameters:
  • T_model (ArrayLike) – The modeled temperature profile (K).

  • depths_model (ArrayLike) – The depths corresponding to T_model (m).

  • T_obs (ArrayLike) – The observed temperatures (K).

  • depths_obs (ArrayLike) – The depths of the observations (m).

Returns:

The corrected temperature profile.

Return type:

numpy.ndarray

soil_heat.wang_and_yang.surface_temperature_longwave(R_lw_up: float, R_lw_dn: float, emissivity: float = 0.98) float[source]

Calculate surface temperature from upward and downward long-wave radiation measurements using the Stefan-Boltzmann law (Yang & Wang 2008, Eq. 8).

\[T_s = \left[ \frac{R_{lw}^{\uparrow} - (1 - \epsilon) R_{lw}^{\downarrow}} {\epsilon \sigma} \right]^{1/4}\]
Parameters:
  • R_lw_up (float) – Upwelling long-wave radiation (W m⁻²).

  • R_lw_dn (float) – Downwelling long-wave radiation (W m⁻²).

  • emissivity (float, optional) – Surface emissivity (dimensionless), by default 0.98.

Returns:

The calculated surface temperature (K).

Return type:

float

soil_heat.wang_and_yang.thermal_conductivity_yang2008(theta: ArrayLike, theta_sat: float, rho_dry: float | ArrayLike) numpy.ndarray[source]

Estimate soil thermal conductivity based on soil moisture and dry density, following Yang et al. (2005) as cited in Yang & Wang (2008, Eq. 9).

Parameters:
  • theta (ArrayLike) – Volumetric water content (m³ m⁻³).

  • theta_sat (float) – Saturated volumetric water content (porosity) (m³ m⁻³).

  • rho_dry (float or ArrayLike) – Dry soil bulk density (kg m⁻³).

Returns:

The estimated soil thermal conductivity λ_s (W m⁻¹ K⁻¹).

Return type:

numpy.ndarray

soil_heat.wang_and_yang.flux_error_linear(rho_c: ArrayLike, S2_minus_S1: ArrayLike, dt: float) numpy.ndarray[source]

Calculate the diagnostic error in heat flux that arises from assuming a linear temperature profile between measurement points (Yang & Wang 2008, Eq. 11).

\[\Delta G_i = \frac{\rho_s c_s (S_{i,2} - S_{i,1})}{\Delta t}\]
Parameters:
  • rho_c (ArrayLike) – Volumetric heat capacity for each layer (J m⁻³ K⁻¹).

  • S2_minus_S1 (ArrayLike) – The area difference representing the deviation from linearity.

  • dt (float) – The time step (s).

Returns:

The flux error for each layer (W m⁻²).

Return type:

numpy.ndarray

soil_heat.wang_and_yang.surface_energy_residual(R_net: float, H: float, LE: float, G0: float) float[source]

Calculate the residual of the surface energy budget (Yang & Wang 2008, Eq. 12).

\[\Delta E = R_{net} - (H + LE + G_0)\]
Parameters:
  • R_net (float) – Net radiation (W m⁻²).

  • H (float) – Sensible heat flux (W m⁻²).

  • LE (float) – Latent heat flux (W m⁻²).

  • G0 (float) – Surface ground heat flux (W m⁻²).

Returns:

The energy balance residual ΔE (W m⁻²).

Return type:

float

soil_heat.wang_and_yang.tdec_step(T_prev: ArrayLike, dz: ArrayLike, theta: ArrayLike, theta_sat: float, rho_dry: float, lambda_const: float, Tsfc: float, Tbot: float, dt: float, depths_model: ArrayLike, T_obs: ArrayLike, depths_obs: ArrayLike) Tuple[numpy.ndarray, numpy.ndarray][source]

Perform a single integration step of the TDEC (Temperature Diffusion Error Correction) scheme.

This function encapsulates the predict-correct sequence for one time step.

Parameters:
  • T_prev (ArrayLike) – Temperature profile from the previous time step (K).

  • dz (ArrayLike) – Layer thicknesses (m).

  • theta (ArrayLike) – Volumetric water content profile (m³ m⁻³).

  • theta_sat (float) – Soil porosity (m³ m⁻³).

  • rho_dry (float) – Dry soil bulk density (kg m⁻³).

  • lambda_const (float) – A constant thermal conductivity for the prediction step (W m⁻¹ K⁻¹).

  • Tsfc (float) – Surface temperature boundary condition (K).

  • Tbot (float) – Bottom temperature boundary condition (K).

  • dt (float) – Time step (s).

  • depths_model (ArrayLike) – Depths of the model grid nodes (m).

  • T_obs (ArrayLike) – Observed temperatures for the correction step (K).

  • depths_obs (ArrayLike) – Depths of the observed temperatures (m).

Returns:

A tuple containing: - T_corr: The corrected temperature profile at t + dt. - G_prof: The corresponding heat flux profile (W m⁻²) at layer interfaces.

Return type:

Tuple[np.ndarray, np.ndarray]