Skip to content

Commit 2823180

Browse files
Merge branch 'main' into ss-nc/fix-climatoloy-experiment
2 parents ac25d0a + 9dc402c commit 2823180

File tree

8 files changed

+63
-33
lines changed

8 files changed

+63
-33
lines changed

src/ClimaOcean.jl

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,21 +53,20 @@ const SKOFTS = SomeKindOfFieldTimeSeries
5353
@inline stateindex(a::AbstractArray, i, j, k, args...) = @inbounds a[i, j, k]
5454
@inline stateindex(a::SKOFTS, i, j, k, grid, time, args...) = @inbounds a[i, j, k, time]
5555

56-
@inline function stateindex(a::Function, i, j, k, grid, time, loc)
57-
LX, LY, LZ = loc
56+
@inline function stateindex(a::Function, i, j, k, grid, time, (LX, LY, LZ), args...)
5857
λ, φ, z = node(i, j, k, grid, LX(), LY(), LZ())
5958
return a(λ, φ, z, time)
6059
end
6160

62-
@inline function stateindex(a::Tuple, i, j, k, grid, time)
61+
@inline function stateindex(a::Tuple, i, j, k, grid, time, args...)
6362
N = length(a)
6463
ntuple(Val(N)) do n
65-
stateindex(a[n], i, j, k, grid, time)
64+
stateindex(a[n], i, j, k, grid, time, args...)
6665
end
6766
end
6867

69-
@inline function stateindex(a::NamedTuple, i, j, k, grid, time)
70-
vals = stateindex(values(a), i, j, k, grid, time)
68+
@inline function stateindex(a::NamedTuple, i, j, k, grid, time, args...)
69+
vals = stateindex(values(a), i, j, k, grid, time, args...)
7170
names = keys(a)
7271
return NamedTuple{names}(vals)
7372
end

src/OceanSeaIceModels/InterfaceComputations/assemble_net_fluxes.jl

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -100,14 +100,15 @@ end
100100

101101
# Compute radiation fluxes
102102
σ = atmos_ocean_properties.radiation.σ
103-
α = stateindex(atmos_ocean_properties.radiation.α, i, j, kᴺ, grid, time)
104-
ϵ = stateindex(atmos_ocean_properties.radiation.ϵ, i, j, kᴺ, grid, time)
105-
Qu = upwelling_radiation(Tₛ, σ, ϵ)
106-
Qdℓ = downwelling_longwave_radiation(Qℓ, ϵ)
107-
Qds = downwelling_shortwave_radiation(Qs, α)
103+
α = atmos_ocean_properties.radiation.α
104+
ϵ = atmos_ocean_properties.radiation.ϵ
105+
Qu = upwelling_radiation(i, j, kᴺ, grid, time, Tₛ, σ, ϵ)
106+
Qdℓ = downwelling_longwave_radiation(i, j, kᴺ, grid, time, ϵ, Qℓ)
107+
Qds = downwelling_shortwave_radiation(i, j, kᴺ, grid, time, α, Qs)
108108
ΣQao = Qu + Qc + Qv + Qdℓ + Qds
109109

110110
@inbounds begin
111+
# Write radiative components of the heat flux for diagnostic purposes
111112
atmos_ocean_fluxes.upwelling_longwave[i, j, 1] = Qu
112113
atmos_ocean_fluxes.downwelling_longwave[i, j, 1] = Qdℓ
113114
atmos_ocean_fluxes.downwelling_shortwave[i, j, 1] = Qds
@@ -244,10 +245,10 @@ end
244245

245246
# Compute radiation fluxes
246247
σ = atmos_sea_ice_properties.radiation.σ
247-
α = stateindex(atmos_sea_ice_properties.radiation.α, i, j, kᴺ, grid, time)
248-
ϵ = stateindex(atmos_sea_ice_properties.radiation.ϵ, i, j, kᴺ, grid, time)
249-
Qu = upwelling_radiation(Ts, σ, ϵ)
250-
Qd = net_downwelling_radiation(i, j, grid, time, α, ϵ, Qs, Qℓ)
248+
α = atmos_sea_ice_properties.radiation.α
249+
ϵ = atmos_sea_ice_properties.radiation.ϵ
250+
Qu = upwelling_radiation(i, j, kᴺ, grid, time, Ts, σ, ϵ)
251+
Qd = net_downwelling_radiation(i, j, kᴺ, grid, time, α, ϵ, Qs, Qℓ)
251252

252253
ΣQt = (Qd + Qu + Qc + Qv) * ℵi # If ℵi == 0 there is no heat flux from the top!
253254
ΣQb = Qf + Qi

src/OceanSeaIceModels/InterfaceComputations/atmosphere_ocean_fluxes.jl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,16 @@ end
122122
needs_to_converge = stop_criteria isa ConvergenceStopCriteria
123123
not_water = inactive_node(i, j, kᴺ, grid, Center(), Center(), Center())
124124

125+
# Compute local radiative properties and rebuild the interface properties
126+
α = stateindex(interface_properties.radiation.α, i, j, kᴺ, grid, time, (Center, Center, Center), Qs)
127+
ϵ = stateindex(interface_properties.radiation.ϵ, i, j, kᴺ, grid, time, (Center, Center, Center))
128+
σ = interface_properties.radiation.σ
129+
130+
interface_properties = InterfaceProperties((; α, ϵ, σ),
131+
interface_properties.specific_humidity_formulation,
132+
interface_properties.temperature_formulation,
133+
interface_properties.velocity_formulation)
134+
125135
if needs_to_converge && not_water
126136
interface_state = zero_interface_state(FT)
127137
else

src/OceanSeaIceModels/InterfaceComputations/interface_states.jl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,8 +299,10 @@ end
299299
ϵ = interface_properties.radiation.ϵ
300300
α = interface_properties.radiation.α
301301

302+
Qs = downwelling_radiation.Qs
303+
Qℓ = downwelling_radiation.Qℓ
302304
Qu = upwelling_radiation(Tₛ⁻, σ, ϵ)
303-
Qd = net_downwelling_radiation(downwelling_radiation, α, ϵ)
305+
Qd = net_downwelling_radiation(Qs, Qℓ, α, ϵ)
304306

305307
u★ = interface_state.u★
306308
θ★ = interface_state.θ★

src/OceanSeaIceModels/InterfaceComputations/latitude_dependent_albedo.jl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using Oceananigans.Grids: ηnode
2+
using Oceananigans.Fields: instantiate
23

34
struct LatitudeDependentAlbedo{FT}
45
direct :: FT
@@ -45,8 +46,8 @@ end
4546

4647
Base.show(io::IO, α::LatitudeDependentAlbedo) = print(io, summary(α))
4748

48-
@inline function stateindex::LatitudeDependentAlbedo, i, j, k, grid, time)
49-
φ = ηnode(i, j, k, grid, Center(), Center(), Center())
49+
@inline function stateindex::LatitudeDependentAlbedo, i, j, k, grid, time, (LX, LY, LZ), args...)
50+
φ = ηnode(i, j, k, grid, LX(), LY(), LZ())
5051
α₀ = α.diffuse
5152
α₁ = α.direct
5253
return α₀ - α₁ * hack_cosd(2φ)

src/OceanSeaIceModels/InterfaceComputations/radiation.jl

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ Adapt.adapt_structure(to, r :: Radiation) = Radiation(Adapt.adapt(to, r.emissio
1717
Radiation([arch = CPU(), FT=Float64];
1818
ocean_emissivity = 0.97,
1919
sea_ice_emissivity = 1.0,
20-
ocean_albedo = LatitudeDependentAlbedo(FT),
20+
ocean_albedo = 0.05,
2121
sea_ice_albedo = 0.7,
2222
stefan_boltzmann_constant = 5.67e-8)
2323
@@ -34,14 +34,14 @@ Keyword Arguments
3434
3535
- `ocean_emissivity`: The emissivity of the ocean surface. Default: `0.97`.
3636
- `sea_ice_emissivity`: The emissivity of the sea ice surface. Default: `1.0`.
37-
- `ocean_albedo`: The albedo of the ocean surface. Default: `LatitudeDependentAlbedo(FT)`.
37+
- `ocean_albedo`: The albedo of the ocean surface. Default: `0.05`.
3838
- `sea_ice_albedo`: The albedo of the sea ice surface. Default: `0.7`.
3939
- `stefan_boltzmann_constant`: The Stefan-Boltzmann constant. Default: `5.67e-8`.
4040
"""
4141
function Radiation(arch = CPU(), FT=Oceananigans.defaults.FloatType;
4242
ocean_emissivity = 0.97,
4343
sea_ice_emissivity = 1.0,
44-
ocean_albedo = LatitudeDependentAlbedo(FT),
44+
ocean_albedo = 0.05,
4545
sea_ice_albedo = 0.7,
4646
stefan_boltzmann_constant = 5.67e-8)
4747

@@ -90,10 +90,30 @@ function Base.show(io::IO, properties::SurfaceProperties)
9090
print(io, "└── sea_ice: ", summary(properties.sea_ice))
9191
end
9292

93-
@inline upwelling_radiation(T, σ, ϵ) = σ * ϵ * T^4
94-
@inline net_downwelling_radiation(i, j, grid, time, α, ϵ, Qs, Qℓ) = - (1 - α) * Qs - ϵ * Qℓ
95-
@inline net_downwelling_radiation(r, α, ϵ) = - (1 - α) * r.Qs - ϵ * r.Qℓ
93+
const CCC = (Center, Center, Center)
94+
95+
@inline function upwelling_radiation(i, j, k, grid, time, T, σ, ϵ)
96+
ϵi = stateindex(ϵ, i, j, k, grid, time, CCC)
97+
return σ * ϵi * T^4
98+
end
9699

97100
# Split the individual bands
98-
@inline downwelling_longwave_radiation(Qℓ, ϵ) = - ϵ * Qℓ
99-
@inline downwelling_shortwave_radiation(Qs, α) = - (1 - α) * Qs
101+
@inline function downwelling_longwave_radiation(i, j, k, grid, time, ϵ, Qℓ)
102+
ϵi = stateindex(ϵ, i, j, k, grid, time, CCC)
103+
return - ϵi * Qℓ
104+
end
105+
106+
@inline function downwelling_shortwave_radiation(i, j, k, grid, time, α, Qs)
107+
αi = stateindex(α, i, j, k, grid, time, CCC, Qs)
108+
return - (1 - αi) * Qs
109+
end
110+
111+
@inline net_downwelling_radiation(i, j, k, grid, time, α, ϵ, Qs, Qℓ) =
112+
downwelling_shortwave_radiation(i, j, k, grid, time, α, Qs) +
113+
downwelling_longwave_radiation(i, j, k, grid, time, ϵ, Qℓ)
114+
115+
# Inside the solver we lose both spatial and temporal information, but the
116+
# radiative properties have already been computed correctly
117+
@inline net_downwelling_radiation(Qs, Qℓ, α, ϵ) = - (1 - α) * Qs - ϵ * Qℓ
118+
119+
@inline upwelling_radiation(T, σ, ϵ) = σ * ϵ * T^4

src/OceanSeaIceModels/InterfaceComputations/similarity_theory_turbulent_fluxes.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ These stability functions are obtained by regression to experimental data.
277277
The stability parameter for stable atmospheric conditions is defined as
278278
```math
279279
dζ = min(ζmax, Aˢζ)
280-
ψₛ = - (ζ +( ζ - Dˢ ) ) exp( - dζ) - Cˢ Dˢ
280+
ψₛ = - Bˢ * ζ⁺ -* (ζ⁺ - Dˢ) * exp(- dζ) - Cˢ *
281281
```
282282
283283
While the stability parameter for unstable atmospheric conditions is calculated

src/OceanSeaIceModels/InterfaceComputations/tabulated_albedo.jl

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -115,10 +115,9 @@ Base.show(io::IO, α::TabulatedAlbedo) = print(io, summary(α))
115115
@inline simulation_day(time::Time{<:Number}) = time.time ÷ 86400
116116
@inline seconds_in_day(time::Time{<:Number}, day) = time.time - day * 86400
117117

118-
@inline function net_downwelling_radiation(i, j, grid, time, radiation::Radiation{<:Any, <:Any, <:SurfaceProperties{<:TabulatedAlbedo}}, Qs, Qℓ)
119-
α = radiation.reflection.ocean
118+
@inline function stateindex::TabulatedAlbedo, i, j, k, grid, time, loc, Qs)
120119
FT = eltype(α)
121-
λ, φ, z = _node(i, j, 1, grid, Center(), Center(), Center())
120+
λ, φ, z = _node(i, j, k, grid, Center(), Center(), Center())
122121

123122
φ = deg2rad(φ)
124123
λ = deg2rad(λ)
@@ -164,8 +163,6 @@ Base.show(io::IO, α::TabulatedAlbedo) = print(io, summary(α))
164163
ϕ₃(ξ, η) * getindex.α_table, i⁺, j⁻) +
165164
ϕ₄(ξ, η) * getindex.α_table, i⁺, j⁺)
166165

167-
ϵ = stateindex(radiation.emission.ocean, i, j, 1, grid, time)
168-
169-
return - (1 - α) * Qs - ϵ * Qℓ
166+
return α
170167
end
171168

0 commit comments

Comments
 (0)