Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
16 changes: 8 additions & 8 deletions src/boundary_layer.jl
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
function allocate_profile(heights)
wind_speed = similar(heights, typeof(0.0u"m/s")) # output wind speeds
height_array = similar(heights, typeof(0.0u"m"))
height_array[end:-1:begin] .= heights
height_array[end:-1:begin] .= heights
air_temperature = similar(heights, typeof(0.0u"K")) # output temperatures, need to do this otherwise get InexactError
relative_humidity = similar(heights, Float64) # output relative humidities
return (; heights, height_array, air_temperature, wind_speed, relative_humidity)
obukhov_length_prev = Ref(-0.3u"m") # warm-start across timesteps
return (; heights, height_array, air_temperature, wind_speed, relative_humidity, obukhov_length_prev)
end

"""
Expand Down Expand Up @@ -91,7 +92,7 @@ function atmospheric_surface_profile!(buffers;
(; roughness_height, karman_constant, dyer_constant, elevation) = micro_terrain
(; atmospheric_pressure, reference_temperature, reference_wind_speed, reference_humidity, zenith_angle) = environment_instant

(; heights, height_array, air_temperature, wind_speed, relative_humidity) = buffers
(; heights, height_array, air_temperature, wind_speed, relative_humidity, obukhov_length_prev) = buffers
N_heights = length(heights)
if minimum(heights) < roughness_height
throw(ArgumentError("The minimum height is not greater than the roughness height."))
Expand Down Expand Up @@ -138,10 +139,9 @@ function atmospheric_surface_profile!(buffers;
air_temperature[i] = roughness_height_temp + (reference_temp - roughness_height_temp) * log(height_array[i] / z0 + 1.0) / log_z_ratio
end
else
obukhov_length = -0.3u"m" # initialise Obukhov length
# TODO just pass the environment_instant through here
Obukhov_out = calc_Obukhov_length(reference_temp, surface_temp, v_ref_height, z0, z, ρcpTκg, κ, log_z_ratio, ΔT, ρ_cp; max_iter=30, tol=1e-2)
Obukhov_out = calc_Obukhov_length(reference_temp, surface_temp, v_ref_height, z0, z, ρcpTκg, κ, log_z_ratio, ΔT, ρ_cp; max_iter=30, tol=1e-2, initial_obukhov_length=obukhov_length_prev[])
obukhov_length = Obukhov_out.obukhov_length
obukhov_length_prev[] = obukhov_length
roughness_height_temp = Obukhov_out.roughness_height_temperature
convective_heat_flux = Obukhov_out.convective_heat_flux
u_star = Obukhov_out.u_star
Expand Down Expand Up @@ -415,9 +415,9 @@ Iteratively solve for Monin-Obukhov length and convective heat flux.
"""
@inline function calc_Obukhov_length(
reference_temp, surface_temp, v_ref_height, z0, z, ρcpTκg, κ, log_z_ratio, ΔT, ρ_cp;
γ=16.0, max_iter=30, tol=1e-2
γ=16.0, max_iter=30, tol=1e-2, initial_obukhov_length=-0.3u"m"
)
obukhov_length = -0.3u"m" # initial Monin-Obukhov length
obukhov_length = initial_obukhov_length

# initialise with zeros
convective_heat_flux = 0.0u"W/m^2"
Expand Down
6 changes: 3 additions & 3 deletions src/simulation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,7 @@ function solve_soil!(output::MicroResult, mp::MicroProblem, solar_radiation_out;
T0 = temperature
end
end
init_soil_obukhov!(buffers, forcing, micro_terrain, heights, T0, i)
rain = hourly_rainfall ? mp.environment_hourly.rainfall[step] : environment_instant.rainfall
pool = clamp(pool + rain, 0.0u"kg/m^2", soil_moisture_model.maxpool)
if runmoist
Expand All @@ -456,9 +457,8 @@ function solve_soil!(output::MicroResult, mp::MicroProblem, solar_radiation_out;
output.surface_water[step] = pool
output.soil_temperature[step, :] .= T0
output.sky_temperature[step] = longwave_sky.sky_temperature
environment_instant = get_instant(environment_day, mp.environment_hourly, output, soil_moisture, step)

update_soil_properties!(output, buffers.soil_properties, soil_thermal_model;
environment_instant = get_instant(environment_day, mp.environment_hourly, output, soil_moisture, step)
update_soil_properties!(output, buffers.soil_properties, soil_thermal_model;
soil_temperature=T0, soil_moisture, atmospheric_pressure=environment_instant.atmospheric_pressure, step, vapour_pressure_equation
)
end
Expand Down
27 changes: 23 additions & 4 deletions src/soil_balance.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ function allocate_soil_energy_balance(num_nodes::Int)
layer_depths = fill(0.0u"cm", num_nodes + 1)
heat_capacity = fill(1.0u"J/K/m^2", num_nodes)
thermal_conductance = fill(1.0u"W/K/m^2", num_nodes)
return (; layer_depths, heat_capacity, thermal_conductance)
obukhov_length_prev = Ref(-0.3u"m") # warm-start across hourly ODE solves
return (; layer_depths, heat_capacity, thermal_conductance, obukhov_length_prev)
end

# This is a 3-parameters OrdinaryDiffEq function
Expand Down Expand Up @@ -70,9 +71,7 @@ function soil_energy_balance(
u_star = calc_u_star(; reference_wind_speed=wind_speed, log_z_ratio, κ=karman_constant)
convective_heat_flux = calc_convection(; u_star, log_z_ratio, ΔT, ρ_cp, z0=roughness_height)
else
# compute ρcpTκg (was a constant in original Fortran version)
ρcpTκg = 6.003e-8u"cal*minute^2/cm^4"
Obukhov_out = calc_Obukhov_length(air_temperature, surface_temperature, wind_speed, roughness_height, reference_height, ρcpTκg, karman_constant, log_z_ratio, ΔT, ρ_cp)
Obukhov_out = calc_soil_obukhov(air_temperature, surface_temperature, wind_speed, roughness_height, reference_height, karman_constant; initial_obukhov_length=buffers.soil_energy_balance.obukhov_length_prev[])
convective_heat_flux = Obukhov_out.convective_heat_flux
end
heat_transfer_coefficient = max(abs(convective_heat_flux / (soil_temperature[1] - air_temperature)), 0.5u"W/m^2/K")
Expand Down Expand Up @@ -108,6 +107,26 @@ function soil_energy_balance(
end


function calc_soil_obukhov(air_temperature, surface_temperature, wind_speed, roughness_height, reference_height, karman_constant; initial_obukhov_length)
log_z_ratio = log(reference_height / roughness_height + 1)
ΔT = air_temperature - surface_temperature
ρ_cp = calc_ρ_cp((surface_temperature + air_temperature) / 2)
ρcpTκg = 6.003e-8u"cal*minute^2/cm^4"
return calc_Obukhov_length(air_temperature, surface_temperature, wind_speed, roughness_height, reference_height, ρcpTκg, karman_constant, log_z_ratio, ΔT, ρ_cp; initial_obukhov_length)
end

function init_soil_obukhov!(buffers, forcing, micro_terrain, heights, T0, i)
t_next = ((i - 1) * 60)u"minute"
(; air_temperature, wind_speed, zenith_angle) = interpolate_forcings(forcing, t_next)
surface_temperature = T0[1]
if air_temperature < surface_temperature && zenith_angle < 90u"°"
(; roughness_height, karman_constant) = micro_terrain
reference_height = last(heights)
Obukhov_out = calc_soil_obukhov(air_temperature, surface_temperature, wind_speed, roughness_height, reference_height, karman_constant; initial_obukhov_length=buffers.soil_energy_balance.obukhov_length_prev[])
buffers.soil_energy_balance.obukhov_length_prev[] = Obukhov_out.obukhov_length
end
end

function interpolate_forcings(f, t)
t_m = ustrip(u"minute", t)
return (;
Expand Down
Loading