@@ -143,7 +143,7 @@ function atmospheric_surface_profile!(bl::MoninObukhov, buffers;
143143 # ρcpTκg = u"cal*minute^2/cm^4"(ρ * c_p * T_ref_height / (κ * g_n))
144144 ρcpTκg = u " J*s^2/m^4" (6.003e-8 u " cal*minute^2/cm^4" )
145145
146- log_z_ratio = log (z / z0 + 1 )
146+ log_z_ratio = log (z / z0)
147147 ΔT = reference_temp - surface_temp
148148 mean_temp = (surface_temp + reference_temp) / 2
149149 # TODO call calc_ρ_cp method specific to elevation and RH in final version but do it this way for NicheMapR comparison
@@ -156,11 +156,11 @@ function atmospheric_surface_profile!(bl::MoninObukhov, buffers;
156156 convective_heat_flux = calc_convection (; friction_velocity, log_z_ratio, ΔT, ρ_cp, z0)
157157 roughness_height_temp = (reference_temp * bulk_stanton (log_z_ratio) + surface_temp * sublayer_stanton (z0, friction_velocity)) / (bulk_stanton (log_z_ratio) + sublayer_stanton (z0, friction_velocity))
158158 for i in 2 : N_heights
159- wind_speed[i] = calc_wind (height_array[i], z0, κ, friction_velocity, 1 .0 )
160- air_temperature[i] = roughness_height_temp + (reference_temp - roughness_height_temp) * log (height_array[i] / z0 + 1.0 ) / log_z_ratio
159+ wind_speed[i] = calc_wind (height_array[i], z0, κ, friction_velocity, 0 .0 )
160+ air_temperature[i] = roughness_height_temp + (reference_temp - roughness_height_temp) * log (height_array[i] / z0) / log_z_ratio
161161 end
162162 else # unstable conditions during daytime, need to solve iteratively for Obukhov length
163- 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[])
163+ Obukhov_out = calc_Obukhov_length (reference_temp, surface_temp, v_ref_height, z0, z, ρcpTκg, κ, ΔT, ρ_cp; max_iter= 30 , tol= 1e-2 , initial_obukhov_length= obukhov_length_prev[])
164164 obukhov_length = Obukhov_out. obukhov_length
165165 obukhov_length_prev[] = obukhov_length
166166 roughness_height_temp = Obukhov_out. roughness_height_temperature
@@ -172,12 +172,12 @@ function atmospheric_surface_profile!(bl::MoninObukhov, buffers;
172172 ψ_m1 = calc_ψ_m (φ_m1)
173173 ψ_h2 = calc_ψ_h (φ_m1)
174174 h_ratio = height_array[i] / z0 # dimensionless h/z0
175- # Clamp log arguments to a small positive value to prevent NaN when
176- # stability corrections exceed h/z0 at near-surface heights (e.g. 0.01 m) .
177- wind_log_arg = max (h_ratio - ψ_m1, 1e-6 )
178- wind_speed[i] = (friction_velocity / κ) * log ( wind_log_arg)
179- temp_log_arg = max (h_ratio - ψ_h2, 1e-6 )
180- air_temperature[i] = roughness_height_temp + (reference_temp - roughness_height_temp) * log ( temp_log_arg) / log (z / z0 - ψ_h)
175+ # Clamp to a small positive value to prevent non-physical results when
176+ # stability corrections are large near the surface .
177+ wind_log_arg = max (log ( h_ratio) - ψ_m1, 1e-6 )
178+ wind_speed[i] = (friction_velocity / κ) * wind_log_arg
179+ temp_log_arg = max (log ( h_ratio) - ψ_h2, 1e-6 )
180+ air_temperature[i] = roughness_height_temp + (reference_temp - roughness_height_temp) * temp_log_arg / ( log (z / z0) - ψ_h)
181181 end
182182 end
183183 reverse! (wind_speed)
@@ -199,7 +199,7 @@ function surface_fluxes(bl::MoninObukhov;
199199 roughness_height, reference_height, obukhov_length_prev= nothing ,
200200)
201201 κ = bl. karman_constant
202- log_z_ratio = log (reference_height / roughness_height + 1 )
202+ log_z_ratio = log (reference_height / roughness_height)
203203 ΔT = air_temperature - surface_temperature
204204 ρ_cp = calc_ρ_cp ((surface_temperature + air_temperature) / 2 )
205205
@@ -217,7 +217,7 @@ function surface_fluxes(bl::MoninObukhov;
217217 L0_raw = isnothing (obukhov_length_prev) ? - 0.3 u " m" : obukhov_length_prev[]
218218 L0 = L0_raw >= 0.0 u " m" ? - 0.3 u " m" : L0_raw
219219 out = calc_Obukhov_length (air_temperature, surface_temperature, wind_speed,
220- roughness_height, reference_height, ρcpTκg, κ, log_z_ratio, ΔT, ρ_cp;
220+ roughness_height, reference_height, ρcpTκg, κ, ΔT, ρ_cp;
221221 initial_obukhov_length= L0)
222222 friction_velocity = out. friction_velocity
223223 convective_heat_flux = out. convective_heat_flux
@@ -234,14 +234,13 @@ function init_surface_fluxes!(bl::MoninObukhov, buffers, forcing, site, heights,
234234 κ = bl. karman_constant
235235 roughness_height = site. roughness_height
236236 reference_height = last (heights)
237- log_z_ratio = log (reference_height / roughness_height + 1 )
238237 ΔT = air_temperature - surface_temperature
239238 ρ_cp = calc_ρ_cp ((surface_temperature + air_temperature) / 2 )
240239 ρcpTκg = 6.003e-8 u " cal*minute^2/cm^4"
241240 L0_raw = buffers. soil_energy_balance. obukhov_length_prev[]
242241 L0 = L0_raw >= 0.0 u " m" ? - 0.3 u " m" : L0_raw
243242 out = calc_Obukhov_length (air_temperature, surface_temperature, wind_speed,
244- roughness_height, reference_height, ρcpTκg, κ, log_z_ratio, ΔT, ρ_cp;
243+ roughness_height, reference_height, ρcpTκg, κ, ΔT, ρ_cp;
245244 initial_obukhov_length= L0)
246245 buffers. soil_energy_balance. obukhov_length_prev[] = out. obukhov_length end
247246end
@@ -430,11 +429,14 @@ Stability correction function φ for momentum in Monin–Obukhov similarity theo
430429# Returns
431430- Dimensionless stability correction factor φ.
432431
433- This corresponds to the Businger–Dyer formulation for unstable stratification:
434-
435- φₘ = (1 - γ z / L)^(1/4)
432+ Returns the Paulson (1970) x-substitution variable x = (1 - γ z / L)^(1/4),
433+ used as the argument to `calc_ψ_m` and `calc_ψ_h`. Note this is the reciprocal
434+ of the true Businger–Dyer φₘ stability function, φₘ = (1 - γ z / L)^(- 1/4).
436435
437436# References
437+ - Paulson, C. A. (1970). The mathematical representation of wind speed and
438+ temperature profiles in the unstable atmospheric surface layer.
439+ *Journal of Applied Meteorology*, 9(6), 857–861.
438440- Businger, J. A., Wyngaard, J. C., Izumi, Y., & Bradley, E. F. (1971).
439441 Flux–profile relationships in the atmospheric surface layer.
440442 *Journal of the Atmospheric Sciences*, 28(2), 181–189.
505507Iteratively solve for Monin-Obukhov length and convective heat flux.
506508"""
507509@inline function calc_Obukhov_length (
508- reference_temp, surface_temp, v_ref_height, z0, z, ρcpTκg, κ, log_z_ratio, ΔT, ρ_cp;
510+ reference_temp, surface_temp, v_ref_height, z0, z, ρcpTκg, κ, ΔT, ρ_cp;
509511 γ= 16.0 , max_iter= 30 , tol= 1e-2 , initial_obukhov_length= - 0.3 u " m"
510512)
511513 obukhov_length = initial_obukhov_length
0 commit comments