Skip to content

Commit a2693a5

Browse files
authored
Merge pull request #88 from BiophysicalEcology/use_previous_obukhov
Use previous obukhov length
2 parents f5741d2 + f409b81 commit a2693a5

3 files changed

Lines changed: 34 additions & 15 deletions

File tree

src/boundary_layer.jl

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
function allocate_profile(heights)
22
wind_speed = similar(heights, typeof(0.0u"m/s")) # output wind speeds
33
height_array = similar(heights, typeof(0.0u"m"))
4-
height_array[end:-1:begin] .= heights
4+
height_array[end:-1:begin] .= heights
55
air_temperature = similar(heights, typeof(0.0u"K")) # output temperatures, need to do this otherwise get InexactError
66
relative_humidity = similar(heights, Float64) # output relative humidities
7-
return (; heights, height_array, air_temperature, wind_speed, relative_humidity)
7+
obukhov_length_prev = Ref(-0.3u"m") # warm-start across timesteps
8+
return (; heights, height_array, air_temperature, wind_speed, relative_humidity, obukhov_length_prev)
89
end
910

1011
"""
@@ -91,7 +92,7 @@ function atmospheric_surface_profile!(buffers;
9192
(; roughness_height, karman_constant, dyer_constant, elevation) = micro_terrain
9293
(; atmospheric_pressure, reference_temperature, reference_wind_speed, reference_humidity, zenith_angle) = environment_instant
9394

94-
(; heights, height_array, air_temperature, wind_speed, relative_humidity) = buffers
95+
(; heights, height_array, air_temperature, wind_speed, relative_humidity, obukhov_length_prev) = buffers
9596
N_heights = length(heights)
9697
if minimum(heights) < roughness_height
9798
throw(ArgumentError("The minimum height is not greater than the roughness height."))
@@ -138,10 +139,9 @@ function atmospheric_surface_profile!(buffers;
138139
air_temperature[i] = roughness_height_temp + (reference_temp - roughness_height_temp) * log(height_array[i] / z0 + 1.0) / log_z_ratio
139140
end
140141
else
141-
obukhov_length = -0.3u"m" # initialise Obukhov length
142-
# TODO just pass the environment_instant through here
143-
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)
142+
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[])
144143
obukhov_length = Obukhov_out.obukhov_length
144+
obukhov_length_prev[] = obukhov_length
145145
roughness_height_temp = Obukhov_out.roughness_height_temperature
146146
convective_heat_flux = Obukhov_out.convective_heat_flux
147147
u_star = Obukhov_out.u_star
@@ -415,9 +415,9 @@ Iteratively solve for Monin-Obukhov length and convective heat flux.
415415
"""
416416
@inline function calc_Obukhov_length(
417417
reference_temp, surface_temp, v_ref_height, z0, z, ρcpTκg, κ, log_z_ratio, ΔT, ρ_cp;
418-
γ=16.0, max_iter=30, tol=1e-2
418+
γ=16.0, max_iter=30, tol=1e-2, initial_obukhov_length=-0.3u"m"
419419
)
420-
obukhov_length = -0.3u"m" # initial Monin-Obukhov length
420+
obukhov_length = initial_obukhov_length
421421

422422
# initialise with zeros
423423
convective_heat_flux = 0.0u"W/m^2"

src/simulation.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,7 @@ function solve_soil!(output::MicroResult, mp::MicroProblem, solar_radiation_out;
442442
T0 = temperature
443443
end
444444
end
445+
init_soil_obukhov!(buffers, forcing, micro_terrain, heights, T0, i)
445446
rain = hourly_rainfall ? mp.environment_hourly.rainfall[step] : environment_instant.rainfall
446447
pool = clamp(pool + rain, 0.0u"kg/m^2", soil_moisture_model.maxpool)
447448
if runmoist
@@ -456,9 +457,8 @@ function solve_soil!(output::MicroResult, mp::MicroProblem, solar_radiation_out;
456457
output.surface_water[step] = pool
457458
output.soil_temperature[step, :] .= T0
458459
output.sky_temperature[step] = longwave_sky.sky_temperature
459-
environment_instant = get_instant(environment_day, mp.environment_hourly, output, soil_moisture, step)
460-
461-
update_soil_properties!(output, buffers.soil_properties, soil_thermal_model;
460+
environment_instant = get_instant(environment_day, mp.environment_hourly, output, soil_moisture, step)
461+
update_soil_properties!(output, buffers.soil_properties, soil_thermal_model;
462462
soil_temperature=T0, soil_moisture, atmospheric_pressure=environment_instant.atmospheric_pressure, step, vapour_pressure_equation
463463
)
464464
end

src/soil_balance.jl

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ function allocate_soil_energy_balance(num_nodes::Int)
22
layer_depths = fill(0.0u"cm", num_nodes + 1)
33
heat_capacity = fill(1.0u"J/K/m^2", num_nodes)
44
thermal_conductance = fill(1.0u"W/K/m^2", num_nodes)
5-
return (; layer_depths, heat_capacity, thermal_conductance)
5+
obukhov_length_prev = Ref(-0.3u"m") # warm-start across hourly ODE solves
6+
return (; layer_depths, heat_capacity, thermal_conductance, obukhov_length_prev)
67
end
78

89
# This is a 3-parameters OrdinaryDiffEq function
@@ -70,9 +71,7 @@ function soil_energy_balance(
7071
u_star = calc_u_star(; reference_wind_speed=wind_speed, log_z_ratio, κ=karman_constant)
7172
convective_heat_flux = calc_convection(; u_star, log_z_ratio, ΔT, ρ_cp, z0=roughness_height)
7273
else
73-
# compute ρcpTκg (was a constant in original Fortran version)
74-
ρcpTκg = 6.003e-8u"cal*minute^2/cm^4"
75-
Obukhov_out = calc_Obukhov_length(air_temperature, surface_temperature, wind_speed, roughness_height, reference_height, ρcpTκg, karman_constant, log_z_ratio, ΔT, ρ_cp)
74+
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[])
7675
convective_heat_flux = Obukhov_out.convective_heat_flux
7776
end
7877
heat_transfer_coefficient = max(abs(convective_heat_flux / (soil_temperature[1] - air_temperature)), 0.5u"W/m^2/K")
@@ -108,6 +107,26 @@ function soil_energy_balance(
108107
end
109108

110109

110+
function calc_soil_obukhov(air_temperature, surface_temperature, wind_speed, roughness_height, reference_height, karman_constant; initial_obukhov_length)
111+
log_z_ratio = log(reference_height / roughness_height + 1)
112+
ΔT = air_temperature - surface_temperature
113+
ρ_cp = calc_ρ_cp((surface_temperature + air_temperature) / 2)
114+
ρcpTκg = 6.003e-8u"cal*minute^2/cm^4"
115+
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)
116+
end
117+
118+
function init_soil_obukhov!(buffers, forcing, micro_terrain, heights, T0, i)
119+
t_next = ((i - 1) * 60)u"minute"
120+
(; air_temperature, wind_speed, zenith_angle) = interpolate_forcings(forcing, t_next)
121+
surface_temperature = T0[1]
122+
if air_temperature < surface_temperature && zenith_angle < 90u"°"
123+
(; roughness_height, karman_constant) = micro_terrain
124+
reference_height = last(heights)
125+
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[])
126+
buffers.soil_energy_balance.obukhov_length_prev[] = Obukhov_out.obukhov_length
127+
end
128+
end
129+
111130
function interpolate_forcings(f, t)
112131
t_m = ustrip(u"minute", t)
113132
return (;

0 commit comments

Comments
 (0)