Skip to content

Commit 955e464

Browse files
simone-silvestrinavidcyglwagner
authored
Add wind-dependent Charnock coefficient (#520)
* try it out * wind-dependent charnock * Update roughness_lengths.jl * Update roughness_lengths.jl * Update roughness_lengths.jl * Update roughness_lengths.jl * Update roughness_lengths.jl * Update similarity_theory_turbulent_fluxes.jl * just a test * another test * Update roughness_lengths.jl * Apply suggestions from code review Co-authored-by: Gregory L. Wagner <[email protected]> * docstring defaults mirror the actual defaults * C -> ℂ * WindDependentGravityWaveParameter -> WindDependentWaveFormulation * Update roughness_lengths.jl * correct wave formulation * gravity_waves -> wave_formulation * fixes * leave wave_formulation = 0.011 as default * fix docstring * back to gustiness_parameter = 1 --------- Co-authored-by: Navid C. Constantinou <[email protected]> Co-authored-by: Gregory L. Wagner <[email protected]>
1 parent 86b22e2 commit 955e464

File tree

2 files changed

+67
-45
lines changed

2 files changed

+67
-45
lines changed

src/OceanSeaIceModels/InterfaceComputations/roughness_lengths.jl

Lines changed: 55 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
struct MomentumRoughnessLength{FT, V}
1+
struct MomentumRoughnessLength{FT, G, V}
22
gravitational_acceleration :: FT
33
air_kinematic_viscosity :: V
4-
gravity_wave_parameter :: FT
4+
wave_formulation :: G
55
laminar_parameter :: FT
66
maximum_roughness_length :: FT
77
end
@@ -12,17 +12,37 @@ struct ScalarRoughnessLength{FT, V, R}
1212
maximum_roughness_length :: FT
1313
end
1414

15+
struct WindDependentWaveFormulation{FT}
16+
Umax :: FT
17+
ℂ₁ :: FT
18+
ℂ₂ :: FT
19+
end
20+
21+
"""
22+
WindDependentWaveFormulation(FT = Oceananigans.defaults.FloatType;
23+
Umax = 19, ℂ₁ = 0.0017, ℂ₂ = -0.005)
24+
25+
A gravity wave parameter based on the wind speed `ΔU` with the formula `ℂ₁ * max(ΔU, Umax) + ℂ₂`.
26+
"""
27+
WindDependentWaveFormulation(FT=Oceananigans.defaults.FloatType; Umax = 19, ℂ₁ = 0.0017, ℂ₂ = -0.005) =
28+
WindDependentWaveFormulation(convert(FT, Umax),
29+
convert(FT, ℂ₁),
30+
convert(FT, ℂ₂))
31+
32+
gravity_wave_parameter::Number, args...) = α
33+
gravity_wave_parameter::WindDependentWaveFormulation, ΔU) = α.ℂ₁ * max(ΔU, α.Umax) + α.ℂ₂
34+
1535
"""
1636
ScalarRoughnessLength(FT = Float64;
1737
air_kinematic_viscosity = temperature_dependent_viscosity,
1838
reynolds_number_scaling_function = empirical_scaling_function,
1939
maximum_roughness_length = 1.6e-4)
2040
21-
Constructs a `ScalarRoughnessLength` object that represents the scalar roughness length
41+
Construct a `ScalarRoughnessLength` object that represents the scalar roughness length
2242
that regulates the exchange of heat and water vapor between the ocean and the atmosphere.
2343
2444
Keyword Arguments
25-
==================
45+
=================
2646
2747
- `air_kinematic_viscosity::Function`: The function to compute the air kinematic viscosity.
2848
- `reynolds_number_scaling_function::Function`: The function to compute the Reynolds number scaling factor.
@@ -43,7 +63,7 @@ end
4363
gravitational_acceleration = default_gravitational_acceleration,
4464
maximum_roughness_length = 1.0,
4565
air_kinematic_viscosity = TemperatureDependentAirViscosity(FT),
46-
gravity_wave_parameter = 0.011,
66+
wave_formulation = 0.011,
4767
laminar_parameter = 0.11)
4868
4969
Construct a `MomentumRoughnessLength` object that represents the momentum roughness length that
@@ -55,21 +75,21 @@ Keyword Arguments
5575
- `gravitational_acceleration`: The gravitational acceleration. Default: `default_gravitational_acceleration`.
5676
- `maximum_roughness_length`: The maximum roughness length. Default: 1.0.
5777
- `air_kinematic_viscosity`: The air kinematic viscosity. Default: `TemperatureDependentAirViscosity(FT)`.
58-
- `gravity_wave_parameter`: The wave parameter. Default: 0.011.
78+
- `wave_formulation`: The wave parameter. Either constant or `WindDependentWaveFormulation(FT)`. Default: 0.011.
5979
- `laminar_parameter`: The laminar parameter. Default: 0.11.
6080
"""
6181
function MomentumRoughnessLength(FT=Oceananigans.defaults.FloatType;
6282
gravitational_acceleration = default_gravitational_acceleration,
6383
maximum_roughness_length = 1.0, # An estimate?
6484
air_kinematic_viscosity = TemperatureDependentAirViscosity(FT),
65-
gravity_wave_parameter = 0.011,
85+
wave_formulation = 0.011,
6686
laminar_parameter = 0.11)
6787

6888
return MomentumRoughnessLength(convert(FT, gravitational_acceleration),
69-
air_kinematic_viscosity,
70-
convert(FT, gravity_wave_parameter),
71-
convert(FT, laminar_parameter),
72-
convert(FT, maximum_roughness_length))
89+
air_kinematic_viscosity,
90+
wave_formulation,
91+
convert(FT, laminar_parameter),
92+
convert(FT, maximum_roughness_length))
7393
end
7494

7595
function default_roughness_lengths(FT=Oceananigans.defaults.FloatType)
@@ -81,42 +101,43 @@ end
81101

82102
# Temperature-dependent viscosity law
83103
struct TemperatureDependentAirViscosity{FT}
84-
C:: FT
85-
C:: FT
86-
C:: FT
87-
C:: FT
104+
:: FT
105+
:: FT
106+
:: FT
107+
:: FT
88108
end
89109

90110
"""
91111
TemperatureDependentAirViscosity([FT = Oceananigans.defaults.FloatType;
92-
C₀ = 1.326e-5,
93-
C₁ = C₀ * 6.542e-3,
94-
C₂ = C₀ * 8.301e-6,
95-
C₃ = - C₀ * 4.84e-9])
112+
₀ = 1.326e-5,
113+
₁ = ₀ * 6.542e-3,
114+
₂ = ₀ * 8.301e-6,
115+
₃ = - ₀ * 4.84e-9])
96116
97-
Constructs a `TemperatureDependentAirViscosity` object that calculates the kinematic
117+
Construct a `TemperatureDependentAirViscosity` object that calculates the kinematic
98118
viscosity of air as
119+
99120
```math
100-
C₀ + C₁ T + C₂ T^2 + C₃ T^3.
121+
₀ + ₁ T + ₂ T^2 + ₃ T^3
101122
```
102123
"""
103124
function TemperatureDependentAirViscosity(FT = Oceananigans.defaults.FloatType;
104-
C= 1.326e-5,
105-
C= C* 6.542e-3,
106-
C= C* 8.301e-6,
107-
C= - C* 4.84e-9)
108-
109-
return TemperatureDependentAirViscosity(convert(FT, C₀),
110-
convert(FT, C₁),
111-
convert(FT, C₂),
112-
convert(FT, C₃))
125+
= 1.326e-5,
126+
= * 6.542e-3,
127+
= * 8.301e-6,
128+
= - * 4.84e-9)
129+
130+
return TemperatureDependentAirViscosity(convert(FT, ₀),
131+
convert(FT, ₁),
132+
convert(FT, ₂),
133+
convert(FT, ₃))
113134
end
114135

115136
""" Calculate the air viscosity based on the temperature θ in Celsius. """
116137
@inline function::TemperatureDependentAirViscosity)(θ)
117-
FT = eltype.C₀)
138+
FT = eltype.₀)
118139
T = convert(FT, θ - celsius_to_kelvin)
119-
return ν.C+ ν.C* T + ν.C* T^2 + ν.C* T^3
140+
return ν.+ ν.* T + ν.* T^2 + ν.* T^3
120141
end
121142

122143
# Fallbacks for constant roughness length!
@@ -125,11 +146,11 @@ end
125146

126147
# Momentum roughness length should be different from scalar roughness length.
127148
# Temperature and water vapor can be considered the same (Edson et al 2013)
128-
@inline function roughness_length(ℓ::MomentumRoughnessLength{FT}, u★, 𝒬, ℂ) where FT
149+
@inline function roughness_length(ℓ::MomentumRoughnessLength{FT}, ΔU, u★, 𝒬, ℂ) where FT
129150
g =.gravitational_acceleration
130-
α =.gravity_wave_parameter
131151
β =.laminar_parameter
132152
ℓm =.maximum_roughness_length
153+
α = gravity_wave_parameter(ℓ.wave_formulation, ΔU)
133154

134155
θ₀ = AtmosphericThermodynamics.air_temperature(ℂ, 𝒬)
135156
ν =.air_kinematic_viscosity(θ₀)
@@ -178,4 +199,3 @@ ReynoldsScalingFunction(FT = Oceananigans.defaults.FloatType; A = 5.85e-5, b = 0
178199

179200
return min(ℓq, ℓm)
180201
end
181-

src/OceanSeaIceModels/InterfaceComputations/similarity_theory_turbulent_fluxes.jl

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -181,16 +181,6 @@ function iterate_interface_fluxes(flux_formulation::SimilarityTheoryFluxes,
181181
ϰ = flux_formulation.von_karman_constant
182182
L★ = ifelse(b★ == 0, Inf, - u★^2 /* b★))
183183

184-
# Compute roughness length scales
185-
ℓu₀ = roughness_length(ℓu, u★, 𝒬ₛ, ℂₐ)
186-
ℓq₀ = roughness_length(ℓq, ℓu₀, u★, 𝒬ₛ, ℂₐ)
187-
ℓθ₀ = roughness_length(ℓθ, ℓu₀, u★, 𝒬ₛ, ℂₐ)
188-
189-
# Transfer coefficients at height `h`
190-
form = flux_formulation.similarity_form
191-
χu = ϰ / similarity_profile(form, ψu, Δh, ℓu₀, L★)
192-
χθ = ϰ / similarity_profile(form, ψθ, Δh, ℓθ₀, L★)
193-
χq = ϰ / similarity_profile(form, ψq, Δh, ℓq₀, L★)
194184

195185
# Buoyancy flux characteristic scale for gustiness (Edson 2013)
196186
h_bℓ = atmosphere_state.h_bℓ
@@ -201,8 +191,20 @@ function iterate_interface_fluxes(flux_formulation::SimilarityTheoryFluxes,
201191
Δu, Δv = velocity_difference(interface_properties.velocity_formulation,
202192
atmosphere_state,
203193
approximate_interface_state)
194+
204195
ΔU = sqrt(Δu^2 + Δv^2 + Uᴳ^2)
205196

197+
# Compute roughness length scales
198+
ℓu₀ = roughness_length(ℓu, ΔU, u★, 𝒬ₛ, ℂₐ)
199+
ℓq₀ = roughness_length(ℓq, ℓu₀, u★, 𝒬ₛ, ℂₐ)
200+
ℓθ₀ = roughness_length(ℓθ, ℓu₀, u★, 𝒬ₛ, ℂₐ)
201+
202+
# Transfer coefficients at height `h`
203+
form = flux_formulation.similarity_form
204+
χu = ϰ / similarity_profile(form, ψu, Δh, ℓu₀, L★)
205+
χθ = ϰ / similarity_profile(form, ψθ, Δh, ℓθ₀, L★)
206+
χq = ϰ / similarity_profile(form, ψq, Δh, ℓq₀, L★)
207+
206208
# Recompute
207209
u★ = χu * ΔU
208210
θ★ = χθ * Δθ

0 commit comments

Comments
 (0)