API for the wind module

The wind module calculates the above- and within-canopy wind profile for the Virtual Ecosystem. The wind profile determines the exchange of heat, water, and \(CO_{2}\) between soil and atmosphere below the canopy as well as the exchange with the atmosphere above the canopy.

TODO replace leaf area index by plant area index when we have more info about vertical distribution of leaf and woody parts TODO change temperatures to Kelvin

Functions:

calculate_diabatic_correction_above(...)

Calculate the diabatic correction factors for momentum and heat above canopy.

calculate_diabatic_correction_canopy(...)

Calculate diabatic correction factors for momentum and heat in canopy.

calculate_friction_velocity_reference_height(...)

Calculate friction velocity from wind speed at reference height, [m s-1].

calculate_mean_mixing_length(canopy_height, ...)

Calculate mixing length for canopy air transport, [m].

calculate_roughness_length_momentum(...)

Calculate roughness length governing momentum transfer, [m].

calculate_wind_above_canopy(...)

Calculate wind speed above canopy from wind speed at reference height, [m s-1].

calculate_wind_attenuation_coefficient(...)

Calculate wind attenuation coefficient, dimensionless.

calculate_wind_canopy(...)

Calculate wind speed in a multi-layer canopy, [m s-1].

calculate_wind_profile(canopy_height, ...)

Calculate wind speed above and below the canopy, [m s-1].

calculate_zero_plane_displacement(...)

Calculate zero plane displacement height, [m].

generate_relative_turbulence_intensity(...)

Generate relative turbulence intensity profile, dimensionless.

wind_log_profile(height, ...)

Calculate logarithmic wind profile.

virtual_ecosystem.models.abiotic.wind.calculate_diabatic_correction_above(molar_density_air: float | ndarray[Any, dtype[float32]], specific_heat_air: float | ndarray[Any, dtype[float32]], temperature: ndarray[Any, dtype[float32]], sensible_heat_flux: ndarray[Any, dtype[float32]], friction_velocity: ndarray[Any, dtype[float32]], wind_heights: ndarray[Any, dtype[float32]], zero_plane_displacement: ndarray[Any, dtype[float32]], celsius_to_kelvin: float, von_karmans_constant: float, yasuda_stability_parameters: list[float], diabatic_heat_momentum_ratio: float) dict[str, ndarray[Any, dtype[float32]]]

Calculate the diabatic correction factors for momentum and heat above canopy.

Diabatic correction factors for heat and momentum are used to adjust wind profiles for surface heating and cooling (Maclean and Klinges, 2021). When the surface is strongly heated, the diabatic correction factor for momentum \(\Psi_{M}\) becomes negative and drops to values of around -1.5. In contrast, when the surface is much cooler than the air above it, it increases to values around 4.

Parameters:
  • molar_density_air – Molar density of air above canopy, [mol m-3]

  • specific_heat_air – Specific heat of air above canopy, [J mol-1 K-1]

  • temperature – 2 m temperature above canopy, [C]

  • sensible_heat_flux – Sensible heat flux from canopy to atmosphere above, [W m-2]

  • friction_velocity – Friction velocity above canopy, [m s-1]

  • wind_heights – Height for which wind speed is calculated, [m]

  • zero_plane_displacement – Height above ground within the canopy where the wind profile extrapolates to zero, [m]

  • celsius_to_kelvin – Factor to convert temperature in Celsius to absolute temperature in Kelvin

  • von_karmans_constant – Von Karman’s constant, dimensionless constant describing the logarithmic velocity profile of a turbulent fluid near a no-slip boundary.

  • yasuda_stability_parameters – Parameters to approximate diabatic correction factors for heat and momentum after Yasuda (1988)

  • diabatic_heat_momentum_ratio – Factor that relates diabatic correction factors for heat and momentum after Yasuda (1988)

Returns:

Diabatic correction factors for heat \(\Psi_{H}\) and momentum \(\Psi_{M}\) transfer

virtual_ecosystem.models.abiotic.wind.calculate_diabatic_correction_canopy(air_temperature: ndarray[Any, dtype[float32]], wind_speed: ndarray[Any, dtype[float32]], layer_heights: ndarray[Any, dtype[float32]], mean_mixing_length: ndarray[Any, dtype[float32]], stable_temperature_gradient_intercept: float, stable_wind_shear_slope: float, yasuda_stability_parameters: list[float], richardson_bounds: list[float], gravity: float, celsius_to_kelvin: float) dict[str, ndarray[Any, dtype[float32]]]

Calculate diabatic correction factors for momentum and heat in canopy.

This function calculates the diabatic correction factors for heat and momentum used in adjustment of wind profiles and calculation of turbulent conductivity within the canopy. Momentum and heat correction factors should be greater than or equal to 1 under stable conditions and smaller than 1 under unstable conditions. From Goudriaan (1977) it is assumed that \(\Phi_{H}\) remains relatively constant within the canopy. Thus, the function returns a mean value for the whole canopy and below. Implementation after Maclean and Klinges (2021).

Parameters:
  • air_temperature – Air temperature, [C]

  • wind_speed – Wind speed, [m s-1]

  • layer_heights – Layer heights, [m]

  • mean_mixing_length – Mean mixing length, [m]

  • stable_temperature_gradient_intercept – Temperature gradient intercept under stable athmospheric conditions after Goudriaan (1977).

  • stable_wind_shear_slope – Wind shear slope under stable atmospheric conditions after Goudriaan (1977).

  • richardson_bounds – Minimum and maximum value for Richardson number

  • yasuda_stability_parameters – Parameters to approximate diabatic correction factors for heat and momentum after Yasuda (1988)

  • gravity – Newtonian constant of gravitation, [m s-1]

  • celsius_to_kelvin – Factor to convert between Celsius and Kelvin

Returns:

diabatic correction factor for momentum \(\Phi_{M}\) and heat \(\Phi_{H}\) transfer

virtual_ecosystem.models.abiotic.wind.calculate_friction_velocity_reference_height(wind_speed_ref: ndarray[Any, dtype[float32]], reference_height: float | ndarray[Any, dtype[float32]], zeroplane_displacement: ndarray[Any, dtype[float32]], roughness_length_momentum: ndarray[Any, dtype[float32]], diabatic_correction_momentum: float | ndarray[Any, dtype[float32]], von_karmans_constant: float, min_friction_velocity: float) ndarray[Any, dtype[float32]]

Calculate friction velocity from wind speed at reference height, [m s-1].

Parameters:
  • wind_speed_ref – Wind speed at reference height, [m s-1]

  • reference_height – Height of wind measurement, [m]

  • zero_plane_displacement – Height above ground within the canopy where the wind profile extrapolates to zero, [m]

  • roughness_length_momentum – Momentum roughness length, [m]

  • diabatic_correction_momentum – Diabatic correction factor for momentum as returned by calculate_diabatic_correction_above()

  • von_karmans_constant – Von Karman’s constant, dimensionless constant describing the logarithmic velocity profile of a turbulent fluid near a no-slip boundary.

  • min_friction_velocity – Minimum friction velocity, [m s-1]

Returns:

Friction velocity, [m s-1]

virtual_ecosystem.models.abiotic.wind.calculate_mean_mixing_length(canopy_height: ndarray[Any, dtype[float32]], zero_plane_displacement: ndarray[Any, dtype[float32]], roughness_length_momentum: ndarray[Any, dtype[float32]], mixing_length_factor: float) ndarray[Any, dtype[float32]]

Calculate mixing length for canopy air transport, [m].

The mean mixing length is used to calculate turbulent air transport inside vegetated canopies. It is made equivalent to the above canopy value at the canopy surface. In absence of vegetation, it is set to zero. Implementation after Maclean and Klinges (2021).

Parameters:
  • canopy_height – Canopy height, [m]

  • zero_plane_displacement – Height above ground within the canopy where the wind profile extrapolates to zero, [m]

  • roughness_length_momentum – Momentum roughness length, [m]

  • mixing_length_factor – Factor in calculation of mean mixing length, dimensionless

Returns:

Mixing length for canopy air transport, [m]

virtual_ecosystem.models.abiotic.wind.calculate_roughness_length_momentum(canopy_height: ndarray[Any, dtype[float32]], leaf_area_index: ndarray[Any, dtype[float32]], zero_plane_displacement: ndarray[Any, dtype[float32]], substrate_surface_drag_coefficient: float, roughness_element_drag_coefficient: float, roughness_sublayer_depth_parameter: float, max_ratio_wind_to_friction_velocity: float, min_roughness_length: float, von_karman_constant: float) ndarray[Any, dtype[float32]]

Calculate roughness length governing momentum transfer, [m].

Roughness length is defined as the height at which the mean velocity is zero due to substrate roughness. Real surfaces such as the ground or vegetation are not smooth and often have varying degrees of roughness. Roughness length accounts for that effect. Implementation after Maclean and Klinges (2021).

Parameters:
  • canopy_height – Canopy height, [m]

  • leaf_area_index – Total leaf area index, [m m-1]

  • zero_plane_displacement – Height above ground within the canopy where the wind profile extrapolates to zero, [m]

  • substrate_surface_drag_coefficient – Substrate-surface drag coefficient, dimensionless

  • roughness_element_drag_coefficient – Roughness-element drag coefficient

  • roughness_sublayer_depth_parameter – Parameter that characterizes the roughness sublayer depth, dimensionless

  • max_ratio_wind_to_friction_velocity – Maximum ratio of wind velocity to friction velocity, dimensionless

  • min_roughness_length – Minimum roughness length, [m]

  • von_karman_constant – Von Karman’s constant, dimensionless constant describing the logarithmic velocity profile of a turbulent fluid near a no-slip boundary.

Returns:

Momentum roughness length, [m]

virtual_ecosystem.models.abiotic.wind.calculate_wind_above_canopy(friction_velocity: ndarray[Any, dtype[float32]], wind_height_above: ndarray[Any, dtype[float32]], zeroplane_displacement: ndarray[Any, dtype[float32]], roughness_length_momentum: ndarray[Any, dtype[float32]], diabatic_correction_momentum: ndarray[Any, dtype[float32]], von_karmans_constant: float, min_wind_speed_above_canopy: float) ndarray[Any, dtype[float32]]

Calculate wind speed above canopy from wind speed at reference height, [m s-1].

Wind speed above the canopy dictates heat and vapour exchange between the canopy and the air above it, and therefore ultimately determines temperature and vapour profiles. The wind profile above canopy typically follows a logarithmic height profile, which extrapolates to zero roughly two thirds of the way to the top of the canopy. The profile itself is thus dependent on the height of the canopy, but also on the roughness of the vegetation layer, which causes wind shear. We follow the implementation by Campbell and Norman (1998) as described in Maclean and Klinges (2021).

Parameters:
  • friction_velocity – friction velocity, [m s-1]

  • wind_height_above – Heights above canopy for which wind speed is required, [m]. For use in the calculation of the full wind profiles, this typically includes two values: the height of the first layer (‘above’) and the first canopy layer which corresponds to the canopy height.

  • zero_plane_displacement – Height above ground within the canopy where the wind profile extrapolates to zero, [m]

  • roughness_length_momentum – Momentum roughness length, [m]

  • diabatic_correction_momentum – Diabatic correction factor for momentum as returned by calculate_diabatic_correction_above()

  • von_karmans_constant – Von Karman’s constant, dimensionless constant describing the logarithmic velocity profile of a turbulent fluid near a no-slip boundary.

  • min_wind_speed_above_canopy – Minimum wind speed above canopy, [m s-1]

Returns:

wind speed at required heights above canopy, [m s-1]

virtual_ecosystem.models.abiotic.wind.calculate_wind_attenuation_coefficient(canopy_height: ndarray[Any, dtype[float32]], leaf_area_index: ndarray[Any, dtype[float32]], mean_mixing_length: ndarray[Any, dtype[float32]], drag_coefficient: float, relative_turbulence_intensity: ndarray[Any, dtype[float32]]) ndarray[Any, dtype[float32]]

Calculate wind attenuation coefficient, dimensionless.

The wind attenuation coefficient describes how wind is slowed down by the presence of vegetation. In absence of vegetation, the coefficient is set to zero. Implementation after Maclean and Klinges (2021).

Parameters:
  • canopy_height – Canopy height, [m]

  • leaf_area_index – Leaf area index, [m m-1]

  • mean_mixing_length – Mixing length for canopy air transport, [m]

  • drag_coefficient – Drag coefficient, dimensionless

  • relative_turbulence_intensity – Relative turbulence intensity, dimensionless

Returns:

Wind attenuation coefficient, dimensionless

virtual_ecosystem.models.abiotic.wind.calculate_wind_canopy(top_of_canopy_wind_speed: ndarray[Any, dtype[float32]], wind_layer_heights: ndarray[Any, dtype[float32]], canopy_height: ndarray[Any, dtype[float32]], attenuation_coefficient: ndarray[Any, dtype[float32]]) ndarray[Any, dtype[float32]]

Calculate wind speed in a multi-layer canopy, [m s-1].

This function can be extended to account for edge distance effects.

Parameters:
  • top_of_canopy_wind_speed – Wind speed at top of canopy layer, [m s-1]

  • wind_layer_heights – Heights of canopy layers, [m]

  • canopy_height – Height to top of canopy layer, [m]

  • attenuation_coefficient – Mean attenuation coefficient based on the profile calculated by calculate_wind_attenuation_coefficient()

  • min_windspeed_below_canopy – Minimum wind speed below the canopy or in absence of vegetation, [m/s]. This value is set to avoid dividion by zero.

Returns:

wind speed at height of canopy layers, [m s-1]

virtual_ecosystem.models.abiotic.wind.calculate_wind_profile(canopy_height: ndarray[Any, dtype[float32]], wind_height_above: ndarray[Any, dtype[float32]], wind_layer_heights: ndarray[Any, dtype[float32]], leaf_area_index: ndarray[Any, dtype[float32]], air_temperature: ndarray[Any, dtype[float32]], atmospheric_pressure: ndarray[Any, dtype[float32]], sensible_heat_flux_topofcanopy: ndarray[Any, dtype[float32]], wind_speed_ref: ndarray[Any, dtype[float32]], wind_reference_height: float | ndarray[Any, dtype[float32]], abiotic_constants: AbioticConsts, core_constants: CoreConsts) dict[str, ndarray[Any, dtype[float32]]]

Calculate wind speed above and below the canopy, [m s-1].

The wind profile above the canopy is described as follows (based on (Campbell and Norman, 1998) as implemented in Maclean and Klinges (2021)):

\(u_z = \frac{u^{*}}{0.4} ln \frac{z-d}{z_M} + \Psi_M\)

where \(u_z\) is wind speed at height \(z\) above the canopy, \(d\) is the height above ground within the canopy where the wind profile extrapolates to zero, \(z_m\) the roughness length for momentum, \(\Psi_M\) is a diabatic correction for momentum and \(u^{*}\) is the friction velocity, which gives the wind speed at height \(d + z_m\).

The wind profile below canopy is derived as follows:

\(u_z = u_h exp(a(\frac{z}{h} - 1))\)

where \(u_z\) is wind speed at height \(z\) within the canopy, \(u_h\) is wind speed at the top of the canopy at height \(h\), and \(a\) is a wind attenuation coefficient given by \(a = 2 l_m i_w\), where \(c_d\) is a drag coefficient that varies with leaf inclination and shape, \(i_w\) is a coefficient describing relative turbulence intensity and \(l_m\) is the mean mixing length, equivalent to the free space between the leaves and stems. For details, see Maclean and Klinges (2021).

Parameters:
  • canopy_height – Canopy height, [m]

  • wind_height_above – Heights above canopy for which wind speed is required, [m]. For use in the calculation of the full wind profiles, this typically includes two values: the height of the first layer (‘above’) and the first canopy layer which corresponds to the canopy height.

  • wind_layer_heights – Layer heights above ground, [m]

  • leaf_area_index – Leaf area index, [m m-1]

  • air_temperature – Air temperature, [C]

  • atmospheric_pressure – Atmospheric pressure, [kPa]

  • sensible_heat_flux_topofcanopy – Sensible heat flux from the top of the canopy to the atmosphere, [W m-2],

  • wind_speed_ref – Wind speed at reference height, [m s-1]

  • wind_reference_height – Reference height for wind measurement, [m]

  • diabatic_correction_parameters – Set of parameters for diabatic correction calculations in canopy

  • abiotic_constants – Specific constants for the abiotic model

  • core_constants – Universal constants shared across all models

Returns:

Dictionnary that contains wind speed and friction velocity, [m s-1] and diabatic correction factors for heat and momentum transfer

virtual_ecosystem.models.abiotic.wind.calculate_zero_plane_displacement(canopy_height: ndarray[Any, dtype[float32]], leaf_area_index: ndarray[Any, dtype[float32]], zero_plane_scaling_parameter: float) ndarray[Any, dtype[float32]]

Calculate zero plane displacement height, [m].

The zero plane displacement height is a concept used in micrometeorology to describe the flow of air near the ground or over surfaces like a forest canopy or crops. It represents the height above the actual ground where the wind speed is theoretically reduced to zero due to the obstruction caused by the roughness elements (like trees or buildings). Implementation after Maclean and Klinges (2021).

Parameters:
  • canopy_height – Canopy height, [m]

  • leaf_area_index – Total leaf area index, [m m-1]

  • zero_plane_scaling_parameter – Control parameter for scaling d/h, dimensionless (Raupach, 1994)

Returns:

Zero plane displacement height, [m]

virtual_ecosystem.models.abiotic.wind.generate_relative_turbulence_intensity(layer_heights: ndarray[Any, dtype[float32]], min_relative_turbulence_intensity: float, max_relative_turbulence_intensity: float, increasing_with_height: bool) ndarray[Any, dtype[float32]]

Generate relative turbulence intensity profile, dimensionless.

At the moment, default values are for a maize crop Shaw et al (1974) Agricultural Meteorology, 13: 419-425. TODO adjust default to environment

Parameters:
  • layer_heights – Heights of above ground layers, [m]

  • min_relative_turbulence_intensity – Minimum relative turbulence intensity, dimensionless

  • max_relative_turbulence_intensity – Maximum relative turbulence intensity, dimensionless

  • increasing_with_height – Increasing logical indicating whether turbulence intensity increases (TRUE) or decreases (FALSE) with height

Returns:

Relative turbulence intensity for each node, dimensionless

virtual_ecosystem.models.abiotic.wind.wind_log_profile(height: float | ndarray[Any, dtype[float32]], zeroplane_displacement: float | ndarray[Any, dtype[float32]], roughness_length_momentum: float | ndarray[Any, dtype[float32]], diabatic_correction_momentum: float | ndarray[Any, dtype[float32]]) ndarray[Any, dtype[float32]]

Calculate logarithmic wind profile.

Note that this function can return NaN, this is not corrected here because it might cause division by zero later on in the work flow.

Parameters:
  • height – Array of heights for which wind speed is calculated, [m]

  • zeroplane_displacement – Height above ground within the canopy where the wind profile extrapolates to zero, [m]

  • roughness_length_momentum – Momentum roughness length, [m]

  • diabatic_correction_momentum – Diabatic correction factor for momentum

Returns:

logarithmic wind profile