Surface roughness

Reynolds_Number(Tair,pressure,ustar,z0m; constants)

calculates the Roughness Reynolds Number.


  • Tair : Air temperature (deg C)
  • pressure : Atmospheric pressure (kPa)
  • ustar : Friction velocity (m s-1)
  • z0m : Roughness length (m)



The Roughness Reynolds Number is calculated as in Massman 1999a: $Re = z0m * ustar / v$, where v is the kinematic viscosity (m2 s-1).


Roughness Reynolds Number (-)


Massman, W_J., 1999a: A model study of kB H- 1 for vegetated surfaces using 'localized near-field' Lagrangian theory. Journal of Hydrology 223, 27-43.

Tair,pressure,ustar,z0m = 25,100,0.5,0.5
R = Reynolds_Number(Tair,pressure,ustar,z0m)                             
≈(R, 15870, rtol=1e-3)
roughness_parameters(::Val{:canopy_height}    , zh; frac_d=0.7, frac_z0m=0.1)
roughness_parameters(::Val{:canopy_height_LAI}, zh, LAI; cd=0.2, hs=0.01)
roughness_parameters(::Val{:wind_profile}     , ustar, wind, psi_m; 
  zh, zr, d = 0.7*zh, constants)

roughness_parameters(method::Val{:wind_profile}, utar, wind, Tair, pressure, H; 
  zh, zr, d = 0.7*zh, stab_formulation=Val(:Dyer_1970), constants)
roughness_parameters(method::Val{:wind_profile}, df::DFTable; ...)

A approximations of the two roughness parameters displacement height (d) and roughness length for momentum (z0m).


By canopy height:

  • frac_d : Fraction of displacement height on canopy height (-)
  • frac_z0m : Fraction of roughness length on canopy height (-)

By canopy height and LAI

  • LAI : Leaf area index (-)
  • cd : Mean drag coefficient for individual leaves. Defaults to 0.2.
  • hs : roughness length of the soil surface (m).

By wind profile

  • wind : Wind speed at height zr (m s-1)
  • ustar : Friction velocity (m s-1)
  • zr : Instrument (reference) height (m)
  • d : Zero-plane displacement height (-)
  • psi_m : value of the stability function for heat, see stability_correction

Another variant estimates of psi_m by stability_correction, which requires further input arguments. For convenience, these arguments can be provided using a DataFrame, however, the result then is not type stable.


The two main roughness parameters, the displacement height (d) and the roughness length for momentum (z0m) can be estimated from simple empirical relationships with canopy height (zh). If method = Val(:canopy_height), the following formulas are used:

$d = frac_d * zh$

$z0m = frac_{z0m} * zh$

where $frac_d$ defaults to 0.7 and $frac_{z0m}$ to 0.1.

Alternatively, d and z0m can be estimated from both canopy height and LAI (If method = Val(:canopy_height_LAI)). Based on data from Shaw & Pereira 1982, Choudhury & Monteith 1988 proposed the following semi-empirical relations:

$X = cd * LAI$

$d = 1.1 * zh * ln(1 + X^{1/4})$

$z0m = hs + 0.3 * zh * X^{1/2}$ for $0 <= X <= 0.2$

$z0m = hs * zh * (1 - d/zh)$ for $0.2 < X$

If method = Val(:wind_profile), z0m is estimated by solving the wind speed profile for z0m:

$z0m = median((zr - d) * exp(-k*wind / ustar - psi_m)$

By default, d in this equation is fixed to 0.7*zh, but can be set to any other value.


a NamedTuple with the following components:

  • d: Zero-plane displacement height (m)
  • z0m: Roughness length for momentum (m)
  • z0m_se: Only if method = wind_profile: Standard Error of the median for z0m (m)


  • Choudhury, B. J., Monteith J_L., 1988: A four-layer model for the heat budget of homogeneous land surfaces. Q. J. R. Meteorol. Soc. 114, 373-398.
  • Shaw, R. H., Pereira, A., 1982: Aerodynamic roughness of a plant canopy: a numerical experiment. Agricultural Meteorology, 26, 51-65.

See also


using DataFrames
# estimate d and z0m from canopy height for a dense (LAI=5) and open (LAI=2) canopy
zh = 25.0
# fix d to 0.7*zh and estimate z0m from the wind profile
df = DataFrame(Tair=[25,25,25],pressure=100,wind=[3,4,5],ustar=[0.5,0.6,0.65],H=200)

# assume d = 0.8*zh
rp = roughness_parameters(Val(:wind_profile),df;zh,zr=40,d=0.8*zh)
≈(rp.z0m, 0.55, rtol=0.1)
wind_profile(z::Number, ustar, d, z0m, psi_m = zero(z); constants)
wind_profile(z, df::AbstractDataFrame, d, z0m, psi_m::AbstractVector; constants)
wind_profile(z, df::DFTable, d, z0m; psi_m = nothing,
  stab_formulation = Val(:Dyer_1970), constants)

Wind speed at a given height above the canopy estimated from single-level measurements of wind speed.


  • z : Height above ground for which wind speed is calculated.
  • ustar : Friction velocity (m s-1)
  • d : Zero-plane displacement height (-)
  • z0m : Roughness length (m)
  • constants=bigleaf_constants()

For DataFrame variant with supplying stability_parameter

  • df: : DataFrame with columns
    • ustar : Friction velocity (m s-1)
  • psi_m : value of the stability function for heat, see stability_correction Pass psi_m = 0.0 to neglect stability correction.

For DataFrame varinat where psi_m is to be estimated


The underlying assumption is the existence of a logarithmic wind profile above the height d + z0m (the height at which wind speed mathematically reaches zero according to the Monin-Obhukov similarity theory). In this case, the wind speed at a given height z is given by:

$u(z) = (ustar/k) * (ln((z - d) / z0m) - \psi_m$

The roughness parameters zero-plane displacement height (d) and roughness length (z0m) can be approximated from roughness_parameters. $\psi_m$ is the stability correction. Set it to zero (not recommended) to neglect statbility correction. By default it is estimated from wind profile using stability_correction


Note that this equation is only valid for z >= d + z0m, and it is not meaningful to calculate values closely above d + z0m. All values in heights smaller than d + z0m will return 0.


wind speed at given height z.


  • Monteith, JL., Unsworth, MH., 2008: Principles of Environmental Physics. 3rd edition. Academic Press, London.
  • Newman, JF., Klein, PM., 2014: The impacts of atmospheric stability on the accuracy of wind speed extrapolation methods. Resources 3, 81-105.

See also


using DataFrames
heights = 18:2:40  # heights above ground for which to calculate wind speed
df = DataFrame(Tair=25,pressure=100,wind=[3,4,5],ustar=[0.5,0.6,0.65],H=[200,230,250]) 
# z0m and MOL are independent of height, compute before
MOL = Monin_Obukhov_length.(df.Tair, df.pressure, df.ustar, df.H)
z0m = roughness_parameters(
  Val(:wind_profile), df.ustar, df.wind, df.Tair, df.pressure, df.H; zh, zr).z0m 
ws = map(heights) do z
  wind_profile(z,df,d,z0m; MOL)
using Plots # plot wind profiles for the three rows in df
plot(first.(ws), heights, ylab = "height (m)", xlab = "wind speed (m/s)", legend=:topleft)
plot!(getindex.(ws, 2), heights)
plot!(getindex.(ws, 3), heights)
# output