Skip to content

feat: adding LandSurfaceTemperature module for LST modeling - #633

Draft
michaelohanrahan wants to merge 84 commits into
mainfrom
landsurfacetemp
Draft

feat: adding LandSurfaceTemperature module for LST modeling#633
michaelohanrahan wants to merge 84 commits into
mainfrom
landsurfacetemp

Conversation

@michaelohanrahan

@michaelohanrahan michaelohanrahan commented Jun 12, 2025

Copy link
Copy Markdown
Collaborator

Explanation

Working towards implementation of the methods from the Devi Purnamasari et al. 2025 paper: "Identifying irrigated areas using land surface temperature and hydrological modelling: application to the Rhine basin" doi

Implementation details:

The land surface temperature (LST) module is an optional component of the SBM land hydrology model, controlled by the land_surface_temperature__flag in the model config. When enabled, a LandSurfaceTemperatureModel is created and stored as a field in LandHydrologySBM, alongside interception, snow, soil, and other land processes. The LST model uses atmospheric forcing (temperature, wind speed, net radiation), soil actual evapotranspiration, and vegetation parameters (e.g. canopy height) to compute aerodynamic resistance, sensible heat flux, and land surface temperature per cell. It is updated each timestep in the land model update! sequence, after soil and before interception is added to actual evaporation. When the flag is off, a NoLandSurfaceTemperatureModel is used instead, and the LST update is skipped.

Checklist

  • [ x ] Updated tests or added new tests
  • [ ] Branch is up to date with master
  • [ ] Tests & pre-commit hooks pass
  • [ ] Updated documentation if needed
  • [ ] Updated changelog.qmd if needed

The module sets up the first keyword parameter. serves as foundation to implement the methods from the Devi Purnamasari et al. 2025
doi: https://doi.org/10.5194/hess-29-1483-2025
-add read_lst_inputs function handling global data ie radiation, albedo and crop type
-probably add emissivity later
- read inputs from read lst inputs
- initialize and empty grid
-requires {model:{lst__flag:true}}
-following SnowModel if do_lst will initialize LSTModel or not
@vers-w vers-w linked an issue Jun 13, 2025 that may be closed by this pull request
Add energy balance calculations with radiation and heat fluxes
Integrate atmospheric forcing and SBM soil model coupling
Implement detailed LST calculations following Purnamasari et al. 2025

@vers-w vers-w left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice start with this new feature @michaelohanrahan !

I added some comments, main suggestion is to include this new feature as part of LandHydrologySBM, make use of variables and parameter fields in the model struct, to move some parameters or forcing to other structs (e.g. for shared land parameters) and to check/discuss what hydromt_wflow should compute.

Comment thread Wflow/src/land_surface_temperature.jl Outdated
Comment thread Wflow/src/land_surface_temperature.jl Outdated
Comment thread Wflow/src/land_surface_temperature.jl Outdated
Comment thread Wflow/src/land_surface_temperature.jl Outdated
Comment thread Wflow/src/land_surface_temperature.jl Outdated
Comment thread Wflow/src/land_surface_temperature.jl Outdated
Comment thread Wflow/src/land_surface_temperature.jl Outdated
Comment thread Wflow/src/land_surface_temperature.jl Outdated
Comment thread Wflow/src/land_surface_temperature.jl Outdated
Comment thread Wflow/src/land_surface_temperature.jl Outdated
Add albedo, shortwave radiation (RS_in), and 2m wind speed (u2m) to forcing
Support land surface temperature model requirements
Add LST, radiation fluxes, and aerodynamic resistance with proper units
Maintain Celsius temperature scale for land surface temperature
…d surface temperature

- Use explicit LandSurfaceTemperature* names for model, parameters, and variables
- Clean up struct definitions for clarity and maintainability
- Update to handle expanded atmospheric forcing structure
Add LST model update call in main timestep loop after soil model updates
Include land_surface_temperature flag in model configuration for SBM GWF model
Include land_surface_temperature flag in model configuration for SBM model

@vers-w vers-w left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the changes @michaelohanrahan ! Some additional comments from my side.

Comment thread Wflow/src/land_surface_temperature.jl Outdated
Comment thread Wflow/src/forcing.jl Outdated
Comment thread Wflow/src/forcing.jl Outdated
Comment thread Wflow/src/forcing.jl Outdated
Comment thread Wflow/src/land_surface_temperature.jl Outdated
Comment thread Wflow/src/land_surface_temperature.jl Outdated
Comment thread Wflow/src/land_surface_temperature.jl Outdated
Comment thread Wflow/src/land_surface_temperature.jl Outdated
Comment thread Wflow/src/sbm_gwf_model.jl Outdated
Comment thread Wflow/src/sbm_model.jl Outdated
Comment thread Wflow/src/sbm.jl Outdated
Comment thread Wflow/src/standard_name.jl Outdated
- Remove LandSurfaceTemperatureParameters struct entirely
- Update LandSurfaceTemperatureModel to only contain variables (no parameters)
- Modify update_timestep_land_surface_temperature function to accept network::NetworkLand and vegetation_parameters::VegetationParameters as parameters
- Update function to use network.latitude[i] instead of land_surface_temperature_model.parameters.latitude[i]
- Update function to use vegetation_parameters.canopy_height[i] instead of land_surface_temperature_model.parameters.crop_height[i]
- Add aerodynamic resistance calculation within the update function
- Fix bug in calculate_land_surface_temperature function to use correct constant name cp
- Update both update! function signatures to include new parameters
- Update all land surface temperature variable mappings to use new variable names:
  * LST → land_surface_temperature
  * RSN → net_shortwave_radiation
  * RLN → net_longwave_radiation
  * Rnet → net_radiation
  * LE → latent_heat_flux
  * H → sensible_heat_flux
  * ra → aerodynamic_resistance
…on params. Removing clock and dt from model update
Comment thread Wflow/src/land_surface_temperature.jl Outdated
Comment thread Wflow/src/land_surface_temperature.jl Outdated
wind_speed_measured::Float64,
z_measured::Float64,
canopy_height::Float64;
zm_ref::Float64 = 2.0, # reference height for wind speed (m)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand that the reference height zm_ref of 2 m is based on the FAO approach, related to the Penman-Monteith equation for a reference surface.

Based on the work of Zink et al. (2018) and other literature I think we can deviate from this reference height of 2 m. My recommendation would be to use a reference height of ~2 m above the canopy (add 2 m to the average canopy height and round to nearest meter). Additionally, I would recommend to stick to the aerodynamic resistance equation based on Thom’s equation (Thom, 1975) and to remove the alternative aerodynamic conductance calculation from AWRA05. And for now just use the default values:

dh_ratio = 2.0 / 3.0
z0m_ratio = 0.123
z0h_ratio = 0.1

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reference height is now set to skin_layer_height + ~2.0 m. Additionally, the resistance equation is now only based on Thom’s equation (Thom, 1975), including the part for heat transfer.

Comment thread Wflow/src/land_surface_temperature.jl Outdated
)
# Handle measurement height below canopy
if z_measured < canopy_height
z_measured = canopy_height

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe better to check if z_measured is smaller than the zero plane displacement height, and than move it to canopy_height?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed the check for z_measured. The expectation is that the provided wind speed (and measurement height) is consistent with d0 and z0m. Need to decide if validation of this input is needed (e.g. measurement height should be higher than d0 + z0m).

Comment thread Wflow/src/land_surface_temperature.jl Outdated

# Wind speed conversion to reference height (2m) for consistency with FAO-56
wind_speed_ref =
max(wind_speed_measured * (log(zm_ref / z0m) / log(z_measured / z0m)), 0.5)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed that a minimum wind speed of 0.5 is mentioned in Purnamasari et al. (2025) based on Allen et al., (1998) but cannot find it. Do you know where this is mentioned in Allen et al., (1998)?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to decide if we want to stick with this minimum wind speed value of 0.5 m/s.

Comment thread Wflow/src/land_surface_temperature.jl Outdated
if canopy_height < 1.0
# Aerodynamic resistance using reference height
# ra = (log((zm_ref - d) / z0m)) * (log((zm_ref - d) / z0h)) / (k^2 * wind_speed_ref)
ra = log((zm_ref - d) / z0m) / (k^2 * wind_speed_ref)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this not missing the inclusion of z0h in the equation?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now using Thom’s equation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support land surface temperature (LST) computation

2 participants