Skip to content
Draft
Show file tree
Hide file tree
Changes from 66 commits
Commits
Show all changes
85 commits
Select commit Hold shift + click to select a range
85fcf2f
feat: adding LandSurfaceTemperature module
michaelohanrahan Jun 12, 2025
7c4f1e7
feat: add LST input reading function to io module
michaelohanrahan Jun 12, 2025
5a6024a
feat: add initialisation function for lst module
michaelohanrahan Jun 13, 2025
6aac3d3
fix: correct the params expected in the LandSurfaceTemperature input …
michaelohanrahan Jun 13, 2025
d550d96
feat: add model initialization to sbm
michaelohanrahan Jun 13, 2025
5ce76f3
feat: implement comprehensive land surface temperature model
michaelohanrahan Jun 13, 2025
7a9475f
feat: add land surface temperature module
michaelohanrahan Jun 13, 2025
0dd05f9
fix: remove unneccessary io read function
michaelohanrahan Jun 13, 2025
56b8726
feat: expand atmospheric forcing with radiation and surface parameters
michaelohanrahan Jun 18, 2025
ee954f9
feat: add land surface temperature model outputs to standard names
michaelohanrahan Jun 18, 2025
84f9947
chore: clean up header and remove module wrapper from land_surface_te…
michaelohanrahan Jun 18, 2025
58db082
refactor: clarify parameter/variable structs and model naming for lan…
michaelohanrahan Jun 18, 2025
de9c5a3
eat: integrate land surface temperature updates into SBM workflow
michaelohanrahan Jun 18, 2025
ed8d495
feat: add LST flag to SBM GWF model settings
michaelohanrahan Jun 18, 2025
ccd3435
feat: add LST flag to SBM model settings
michaelohanrahan Jun 18, 2025
a55e29f
feat: add latitude to the NetworkLand structure
michaelohanrahan Jun 19, 2025
7d13095
feat: added canopy_height to VegetationParameters struct
michaelohanrahan Jun 19, 2025
4c71995
refactor: update LandSurfaceTemperatureModel to use shared parameters
michaelohanrahan Jun 19, 2025
e4330d0
feat: update land surface temperature standard name mappings
michaelohanrahan Jun 19, 2025
813f1a3
refactor: update to sbm to use land network for latitude and vegetati…
michaelohanrahan Jun 19, 2025
49018ef
refactor: rename land surface temperature update function
michaelohanrahan Jun 19, 2025
5539b23
refactor: update land surface temperature configuration flag name
michaelohanrahan Jun 19, 2025
fc8baa5
refactor: move LST update from sbm_gwf_model to LandHydrologySBM
michaelohanrahan Jun 19, 2025
c4d03af
refactor: consolidate LST updates in LandHydrologySBM
michaelohanrahan Jun 19, 2025
72a74e9
feat: implement albedo fallback mechanism for LST model
michaelohanrahan Jun 19, 2025
18d8c52
fix: aligning AtmosphericForcing struct with the explicit-style varia…
michaelohanrahan Jun 19, 2025
5078d82
fix: consistency in temperature naming
michaelohanrahan Jun 19, 2025
3c13111
fix: standard naming
michaelohanrahan Jun 19, 2025
91a1b16
Remove `albedo` from `AtmosphericForcing`
vers-w Jun 23, 2025
6d5a3f2
Rename standard name for wind speed
vers-w Jun 23, 2025
9345906
Remove unused args init function `LandSurfaceTemperatureModel`
vers-w Jun 23, 2025
f848fc4
Replace `calculate` with `compute` in functions
vers-w Jun 23, 2025
a42c853
feat: Add shortwave radiation to standard name mapping
michaelohanrahan Jun 27, 2025
eb2dee4
fix: Add vegetation parameters to land surface temperature update
michaelohanrahan Jun 27, 2025
5706d31
temporary handle clock
michaelohanrahan Jun 27, 2025
13ab8b0
temporary handle latitude
michaelohanrahan Jun 27, 2025
319746c
temporary handle clock
michaelohanrahan Jun 27, 2025
69856b3
temporary handle clock
michaelohanrahan Jun 27, 2025
1094551
wind speed and net rad standardise, in forcing struct
michaelohanrahan Jul 8, 2025
f0362af
move global constants to utils
michaelohanrahan Jul 8, 2025
6584e19
net rad and wind speed standardise names
michaelohanrahan Jul 8, 2025
3fa17d3
switch clock for config, moving net rad to hydromt_wflow preprocessing
michaelohanrahan Jul 8, 2025
6a6e6dd
more explicit constants, whitespace
michaelohanrahan Jul 8, 2025
5d4b2ec
Refactor aerodynamic resistance calculation for robustness across can…
michaelohanrahan Jul 8, 2025
72c0088
bugfix: net_radiation had two definitions, leading to redefining with…
Jul 9, 2025
acde30e
bugfix: remove clock from update
Jul 9, 2025
90116f5
bugfix: remove clock from update
Jul 9, 2025
ced5e1c
fix: Ra values and wind correction to ref. now accounting well for ca…
Jul 14, 2025
f1aaa85
Update Wflow/src/standard_name.jl
michaelohanrahan Jul 14, 2025
d133977
refactor standard naming
Jul 14, 2025
29f8696
Merge branch 'landsurfacetemp' of https://github.com/Deltares/Wflow.j…
Jul 14, 2025
ab645b0
refactor: remove dead code latitude
michaelohanrahan Jul 21, 2025
c81220e
Merge branch 'landsurfacetemp' of https://github.com/Deltares/Wflow.j…
michaelohanrahan Jul 21, 2025
f6a234f
refactor: remove latitude from NetworkLand struct
michaelohanrahan Jul 21, 2025
c2bef5b
refactor: moving LST constants to local function level definition
michaelohanrahan Jul 21, 2025
eca6543
refactor: cleaning up comments
michaelohanrahan Jul 21, 2025
a883e65
Update Wflow/src/vegetation/parameters.jl
michaelohanrahan Jul 21, 2025
5e06908
make compatible with current RC3 naming
michaelohanrahan Nov 18, 2025
9257c0d
remove division by 10 (mistaken unit conversion)
michaelohanrahan Nov 20, 2025
754db31
comments addressed
michaelohanrahan Feb 13, 2026
40a5fd9
testing passed
michaelohanrahan Feb 13, 2026
ff4b23a
Merge branch 'landsurfacetemp' of https://github.com/Deltares/Wflow.j…
michaelohanrahan Feb 13, 2026
756cce2
Merge branch 'master' into landsurfacetemp
vers-w Feb 16, 2026
af1da9f
Some updates for consistency with other code
vers-w Feb 16, 2026
f06139d
Fix config setting `wind_altitude`
vers-w Feb 16, 2026
1e50fb2
Fix unit test land surface temperature
vers-w Feb 16, 2026
e893139
Remove unused wrapper methods
vers-w Feb 16, 2026
187a103
added more realistic floor for aerodynamic resistance output
michaelohanrahan Feb 20, 2026
7b16eda
remove redundant nan check from net rad
michaelohanrahan Feb 20, 2026
7147f7a
Merge branch 'master' into landsurfacetemp
vers-w Feb 20, 2026
280de00
Merge branch 'master' into landsurfacetemp
vers-w Jun 18, 2026
e0d97f5
Uncomment prek typos
vers-w Jun 18, 2026
0856896
Make prek happy
vers-w Jun 18, 2026
9d1c586
Merge branch 'master' into landsurfacetemp
vers-w Jun 25, 2026
5c75a6f
Remove unused variables
vers-w Jul 1, 2026
05fe0ae
Add input parameters for LST
vers-w Jul 1, 2026
5b89813
Update metadata json
vers-w Jul 1, 2026
42de5e3
Add variable for land surface "skin" layer height
vers-w Jul 2, 2026
d118fbf
Merge branch 'master' into landsurfacetemp
vers-w Jul 20, 2026
9322ee9
Merge branch 'master' into landsurfacetemp
vers-w Jul 22, 2026
818d7fa
Update computation aerodynamic resistance
vers-w Jul 22, 2026
b55b5e4
Merge branch 'master' into landsurfacetemp
vers-w Jul 22, 2026
14b6b8e
Improve docstrings
vers-w Jul 23, 2026
04686f2
Fix test
vers-w Jul 23, 2026
31f99eb
Merge branch 'main' into landsurfacetemp
vers-w Aug 24, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Wflow/src/Wflow.jl
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ const VERSION =
VersionNumber(TOML.parsefile(joinpath(@__DIR__, "..", "Project.toml"))["version"])

const GRAVITATIONAL_ACCELERATION = 9.80665 # m s⁻²
const WATER_DENSITY = 1e3 # [kg m⁻³]
const WATER_KINEMATIC_VISCOSITY = 1.16e-6 # [m² s⁻¹]

mutable struct Clock{T}
time::T
Expand Down Expand Up @@ -195,6 +197,7 @@ include("glacier/glacier.jl")
include("surfacewater/runoff.jl")
include("soil/soil.jl")
include("soil/soil_process.jl")
include("land_surface_temperature.jl")
include("sbm.jl")
include("routing/timestepping.jl")
include("groundwater/connectivity.jl")
Expand Down
3 changes: 3 additions & 0 deletions Wflow/src/config_structure.jl
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ end
saturated_hydraulic_conductivity_profile::VerticalConductivityProfile.T =
VerticalConductivityProfile.exponential
water_mass_balance__flag::Bool = false
# Land surface temperature
land_surface_temperature__flag::Bool = false
land_surface_wind__speed_reference_height::Float64 = 10.0
# Routing method
land_routing::RoutingType.T = RoutingType.kinematic_wave
river_routing::RoutingType.T = RoutingType.kinematic_wave
Expand Down
22 changes: 22 additions & 0 deletions Wflow/src/domain.jl
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
river_fraction::Vector{Float64} = Float64[]
# fraction of open water (excluding rivers) [-]
water_fraction::Vector{Float64} = Float64[]
# Surface albedo [-]
albedo::Vector{Float64} = Float64[]
end

"Struct to store (shared) river parameters"
Expand Down Expand Up @@ -196,13 +198,23 @@ function LandParameters(dataset::NCDataset, config::Config, network::NetworkLand
reservoir_coverage = reservoir_mask(dataset, config, network; region = "area")
river_location = river_mask(dataset, config, network)

albedo = ncread(
dataset,
config,
land_surface__albedo;
sel = network.indices,
defaults = 0.2,
type = Float64,
)

land_parameters = LandParameters(;
area,
flow_width,
slope,
reservoir_outlet,
reservoir_coverage,
river_location,
albedo,
)
return land_parameters
end
Expand Down Expand Up @@ -235,6 +247,15 @@ function LandParameters(dataset::NCDataset, config::Config, domain::Domain)
reservoir_outlet = reservoir_mask(dataset, config, network)
reservoir_coverage = reservoir_mask(dataset, config, network; region = "area")

albedo = ncread(
dataset,
config,
"land_surface__albedo";
sel = network.indices,
defaults = 0.2,
type = Float64,
)

land_parameters = LandParameters(;
x_length,
y_length,
Expand All @@ -249,6 +270,7 @@ function LandParameters(dataset::NCDataset, config::Config, domain::Domain)
reservoir_coverage,
river_fraction,
water_fraction,
albedo,
)
return land_parameters
end
Expand Down
6 changes: 6 additions & 0 deletions Wflow/src/forcing.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@
potential_evaporation::Vector{Float64} = fill(MISSING_VALUE, n)
# Temperature [ᵒC]
temperature::Vector{Float64} = fill(MISSING_VALUE, n)
# Downward shortwave radiation [W m-2]
shortwave_radiation_in::Vector{Float64} = Float64[]
# Wind speed [m s-1]
wind_speed::Vector{Float64} = Float64[]
# Net radiation [W m-2]
net_radiation::Vector{Float64} = Float64[]
end

"Struct to store hydrological forcing variables"
Expand Down
212 changes: 212 additions & 0 deletions Wflow/src/land_surface_temperature.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
# after Devi Purnamasari et al. 2025
# https://doi.org/10.5194/hess-29-1483-2025

abstract type AbstractLandSurfaceTemperatureModel end
struct NoLandSurfaceTemperatureModel <: AbstractLandSurfaceTemperatureModel end

"Struct for storing land surface temperature model variables"
@with_kw struct LandSurfaceTemperatureVariables
n::Int
aerodynamic_resistance::Vector{Float64} = fill(MISSING_VALUE, n) # Aerodynamic resistance (s/m)
latent_heat_flux::Vector{Float64} = fill(MISSING_VALUE, n) # Latent heat flux (W/m2)
sensible_heat_flux::Vector{Float64} = fill(MISSING_VALUE, n) # Sensible heat flux (W/m2)
latent_heat_of_vaporization::Vector{Float64} = fill(MISSING_VALUE, n) # Latent heat of vaporization (J/kg)
land_surface_temperature::Vector{Float64} = fill(MISSING_VALUE, n) # Land surface temperature (K)
net_radiation::Vector{Float64} = fill(MISSING_VALUE, n) # Net radiation (W/m2)
net_shortwave_radiation::Vector{Float64} = fill(MISSING_VALUE, n) # Net shortwave radiation (W/m2)
net_longwave_radiation::Vector{Float64} = fill(MISSING_VALUE, n) # Net longwave radiation (W/m2)
end

@with_kw struct LandSurfaceTemperatureModel <: AbstractLandSurfaceTemperatureModel
variables::LandSurfaceTemperatureVariables
end

"Initialize land surface temperature model."
function LandSurfaceTemperatureModel(n::Int)
variables = LandSurfaceTemperatureVariables(; n)
lst_model = LandSurfaceTemperatureModel(; variables)
return lst_model
end

"Update land surface temperarure model for a single timestep."
function update_land_surface_temperature!(
land_surface_temperature_model::LandSurfaceTemperatureModel,
soil_model::SbmSoilModel,
atmospheric_forcing::AtmosphericForcing,
vegetation_parameters::VegetationParameters,
wind_measurement_height::Float64,
dt::Float64,
)
n = length(land_surface_temperature_model.variables.land_surface_temperature)

for i in 1:n
# Use pre-calculated net radiation from forcing
land_surface_temperature_model.variables.latent_heat_of_vaporization[i] =
compute_latent_heat_of_vaporization(atmospheric_forcing.temperature[i])

land_surface_temperature_model.variables.latent_heat_flux[i] =
compute_latent_heat_flux(
atmospheric_forcing.temperature[i],
soil_model.variables.actevap[i],
dt,
)

# Calculate sensible heat flux
land_surface_temperature_model.variables.sensible_heat_flux[i] =
compute_sensible_heat_flux(
atmospheric_forcing.net_radiation[i],
land_surface_temperature_model.variables.latent_heat_flux[i],
)

# Calculate aerodynamic resistance using wind speed at canopy height
canopy_height = max(vegetation_parameters.canopy_height[i], 0.12)
land_surface_temperature_model.variables.aerodynamic_resistance[i] =
wind_and_aero_resistance(
atmospheric_forcing.wind_speed[i],
wind_measurement_height,
canopy_height,
)

# Calculate land surface temperature
land_surface_temperature_model.variables.land_surface_temperature[i] =
compute_land_surface_temperature(
land_surface_temperature_model.variables.sensible_heat_flux[i],
land_surface_temperature_model.variables.aerodynamic_resistance[i],
atmospheric_forcing.temperature[i],
)
end

return nothing
end

function update_land_surface_temperature!(
model::NoLandSurfaceTemperatureModel,
soil_model::SbmSoilModel,
atmospheric_forcing::AtmosphericForcing,
vegetation_parameters::VegetationParameters,
wind_measurement_height::Float64,
dt::Float64,
)
return nothing
end

# wrapper methods
get_land_surface_temperature(model::NoLandSurfaceTemperatureModel) = 0.0
get_land_surface_temperature(model::AbstractLandSurfaceTemperatureModel) =
model.variables.land_surface_temperature

""" 'latent heat of vaporization' :: λ=2501 - 2.375 Ta (A1) """
function compute_latent_heat_of_vaporization(air_temperature::Float64)
return (2501.0 - 2.375 * air_temperature) * 1000.0 # J/kg converted fro kj.kg
end

""" 'latent heat flux' :: LE=λ x ρwater x ET (3)"""
function compute_latent_heat_flux(
air_temperature::Float64,
actual_evapotranspiration::Float64,
dt::Float64,
)
latent_heat_of_vaporization = compute_latent_heat_of_vaporization(air_temperature)
# Convert actual_evapotranspiration from mm/Δt to m/s
actual_evapotranspiration_ms = (actual_evapotranspiration / 1000.0) / dt
latent_heat_flux =
latent_heat_of_vaporization * WATER_DENSITY * actual_evapotranspiration_ms
return latent_heat_flux
end

""" 'sensible heat flux' :: H ≈ RNet - LE - G"""
function compute_sensible_heat_flux(net_radiation::Float64, latent_heat_flux::Float64)
# Handle NaN values in net radiation
if isnan(net_radiation)
return 0.0
end
Comment thread
vers-w marked this conversation as resolved.
Outdated
#TODO:run the snow module assimilate soil temperature
# allowing a better estimate for G, currently G is daytime proportional to (0.1 nighttime, 0.5 daytime)
G = 0.1 * net_radiation
sensible_heat_flux = net_radiation - latent_heat_flux - G
return sensible_heat_flux
end

"""
'aerodynamic resistance' :: ra = (ln(z/z0m) - psi_m) / (k^2 * u)
no clean way yet to deal with variable canopy height empirically

| Cover type | Typical d/h | Reference |
| ----------------- | ------------- | -------------------------------------------- |
| Short grass | 0.67 | Allen et al. (1998), Brutsaert (1982) |
| Wheat, shrubs | 0.65 | Brutsaert (1982); Thom (1975); Shuttleworth |
| Tall crops (corn) | 0.6 | Monteith & Unsworth (1990) |
| Forest | 0.5 (capped) | Garratt (1992); Shuttleworth & Gurney (1990) |

Sensitive to canopy density & LAI

Seasonal and structural variability

Forest cap avoids z - d < 0 issues
Alternative aerodynamic conductance calculation from AWRA05
https://www.researchgate.net/publication/233757155_AWRA_Technical_Report_3_Landscape_Model_version_05_Technical_Description

"""
function wind_and_aero_resistance(
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.

k::Float64 = 0.41, # von Kármán constant
)
# 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).

end

# Simplified empirical d/h ratios and roughness height adjustments
if canopy_height < 1.0
ref_h = 0.12
dh_ratio = 2.0 / 3.0
z0m_ratio = 1.23e-1
z0h_ratio = 0.1

elseif canopy_height >= 1.0
z0m_ratio = 1.23e-1 * (canopy_height / 2.0) #z0m increases with canopy height
ref_h = 0.33
dh_ratio = 2.0 / 3.0
z0h_ratio = 0.2
end

# Calculate canopy height and roughness height
d = dh_ratio * ref_h
z0m = z0m_ratio * ref_h
z0h = z0h_ratio * z0m # Canopy sublayer roughness

# 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.


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.

elseif canopy_height >= 1.0
#AWRA05
f_h = log((813 / canopy_height) - 5.45)
ku = 0.305 / (f_h * (f_h + 2.3))
ga = ku * wind_speed_ref
ra = 1 / ga
end

return max(ra, 1.0)
end

""" 'land surface temperature' :: Ts=(H ra) /(ρacp)+Ta,(4)"""
function compute_land_surface_temperature(
sensible_heat_flux::Float64,
aerodynamic_resistance::Float64,
air_temperature::Float64;
density_air::Float64 = 1.225,
specific_heat_capacity_air::Float64 = 1005.0,
)
land_surface_temperature =
(sensible_heat_flux * aerodynamic_resistance) /
(density_air * specific_heat_capacity_air) + air_temperature
return land_surface_temperature
end
40 changes: 38 additions & 2 deletions Wflow/src/sbm.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ abstract type AbstractAllocationModel end
vegetation_parameters::VegetationParameters
interception::AbstractInterceptionModel
snow::AbstractSnowModel
land_surface_temperature::AbstractLandSurfaceTemperatureModel
glacier::AbstractGlacierModel
runoff::AbstractRunoffModel
soil::SbmSoilModel
Expand All @@ -22,6 +23,12 @@ function LandHydrologySBM(dataset::NCDataset, config::Config, domain::DomainLand
n = length(indices)

atmospheric_forcing = AtmosphericForcing(; n)
do_land_surface_temperature = config.model.land_surface_temperature__flag
if do_land_surface_temperature
@reset atmospheric_forcing.shortwave_radiation_in = fill(MISSING_VALUE, n)
@reset atmospheric_forcing.wind_speed = fill(MISSING_VALUE, n)
@reset atmospheric_forcing.net_radiation = fill(MISSING_VALUE, n)
end
vegetation_parameters = VegetationParameters(dataset, config, indices)
if dt >= Hour(23)
interception =
Expand Down Expand Up @@ -64,12 +71,18 @@ function LandHydrologySBM(dataset::NCDataset, config::Config, domain::DomainLand
allocation = NoAllocationLand(n)
demand = NoDemand(; n)
end
if do_land_surface_temperature
land_surface_temperature = LandSurfaceTemperatureModel(n)
else
land_surface_temperature = NoLandSurfaceTemperatureModel()
end

land_hydrology_model = LandHydrologySBM(;
atmospheric_forcing,
vegetation_parameters,
interception,
snow,
land_surface_temperature,
glacier,
runoff,
soil,
Expand All @@ -88,8 +101,17 @@ function update!(
dt::Float64,
)
(; parameters) = domain.land
(; glacier, snow, interception, runoff, soil, demand, allocation, atmospheric_forcing) =
model
(;
glacier,
snow,
land_surface_temperature,
interception,
runoff,
soil,
demand,
allocation,
atmospheric_forcing,
) = model

update!(interception, atmospheric_forcing)

Expand Down Expand Up @@ -126,6 +148,20 @@ function update!(
)

update!(soil, atmospheric_forcing, (; snow, runoff, demand), config, dt)

# Update land surface temperature if enabled
if config.model.land_surface_temperature__flag
wind_measurement_height = config.model.land_surface_wind__speed_reference_height
update_land_surface_temperature!(
land_surface_temperature,
soil,
atmospheric_forcing,
model.vegetation_parameters,
wind_measurement_height,
dt,
)
end

@. soil.variables.actevap += interception.variables.interception_rate
return nothing
end
Expand Down
1 change: 1 addition & 0 deletions Wflow/src/sbm_model.jl
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ function update_until_recharge!(model::AbstractModel{<:SbmModel})
(; routing, land, domain, clock, config) = model
dt = tosecond(clock.dt)
update!(land, routing, domain, config, dt)

return nothing
end

Expand Down
Loading