From f5e9464277a55c4b319c52dadf3948131dcd8d42 Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Wed, 4 Mar 2026 06:03:05 +0100 Subject: [PATCH 01/13] diagnostics return AbstractOperations --- src/Diagnostics/interface_fluxes.jl | 45 +++++++++-------------------- 1 file changed, 14 insertions(+), 31 deletions(-) diff --git a/src/Diagnostics/interface_fluxes.jl b/src/Diagnostics/interface_fluxes.jl index 4d144d84c..c1fb9a593 100644 --- a/src/Diagnostics/interface_fluxes.jl +++ b/src/Diagnostics/interface_fluxes.jl @@ -11,8 +11,7 @@ Return the two-dimensional frazil temperature flux (K m s⁻¹) in a coupled `es function frazil_temperature_flux(esm::EarthSystemModel) ρᵒᶜ = esm.interfaces.ocean_properties.reference_density cᵒᶜ = esm.interfaces.ocean_properties.heat_capacity - frazil_temperature_flux = 1 / (ρᵒᶜ * cᵒᶜ) * frazil_heat_flux(esm) - return Field(frazil_temperature_flux) + return 1 / (ρᵒᶜ * cᵒᶜ) * frazil_heat_flux(esm) end """ @@ -22,8 +21,7 @@ Return the net temperature flux (K m s⁻¹) at the ocean's surface in a coupled """ function net_ocean_temperature_flux(esm::EarthSystemModel) Jᵀ = esm.ocean.model.tracers.T.boundary_conditions.top.condition - net_ocean_temperature_flux = Jᵀ + frazil_temperature_flux(esm) - return Field(net_ocean_temperature_flux) + return Jᵀ + frazil_temperature_flux(esm) end @@ -36,8 +34,7 @@ in a coupled `esm`. function sea_ice_ocean_temperature_flux(esm::EarthSystemModel) ρᵒᶜ = esm.interfaces.ocean_properties.reference_density cᵒᶜ = esm.interfaces.ocean_properties.heat_capacity - sea_ice_ocean_temperature_flux = 1 / (ρᵒᶜ * cᵒᶜ) * sea_ice_ocean_heat_flux(esm) - return Field(sea_ice_ocean_temperature_flux) + return 1 / (ρᵒᶜ * cᵒᶜ) * sea_ice_ocean_heat_flux(esm) end @@ -48,9 +45,7 @@ Return the atmosphere-ocean temperature flux (K m s⁻¹) at the atmosphere-ocea interface in a coupled `esm`. """ function atmosphere_ocean_temperature_flux(esm::EarthSystemModel) - atmosphere_ocean_temperature_flux = - net_ocean_temperature_flux(esm) - sea_ice_ocean_temperature_flux(esm) - return Field(atmosphere_ocean_temperature_flux) + return net_ocean_temperature_flux(esm) - sea_ice_ocean_temperature_flux(esm) end @@ -64,8 +59,7 @@ end Return the two-dimensional frazil heat flux (W m⁻²) in a coupled `esm`. """ function frazil_heat_flux(esm::EarthSystemModel) - frazil_heat_flux = esm.interfaces.sea_ice_ocean_interface.fluxes.frazil_heat - return frazil_heat_flux + return esm.interfaces.sea_ice_ocean_interface.fluxes.frazil_heat end """ @@ -76,8 +70,7 @@ Return the net heat flux (W m⁻²) at the ocean's surface in a coupled `esm`. function net_ocean_heat_flux(esm::EarthSystemModel) ρᵒᶜ = esm.interfaces.ocean_properties.reference_density cᵒᶜ = esm.interfaces.ocean_properties.heat_capacity - net_ocean_heat_flux = ρᵒᶜ * cᵒᶜ * net_ocean_temperature_flux(esm) - return Field(net_ocean_heat_flux) + return ρᵒᶜ * cᵒᶜ * net_ocean_temperature_flux(esm) end """ @@ -87,9 +80,7 @@ Return the sea ice-ocean heat flux (W m⁻²) at the sea ice-ocean interface in a coupled `esm`. """ function sea_ice_ocean_heat_flux(esm::EarthSystemModel) - sea_ice_ocean_heat_flux = - esm.interfaces.sea_ice_ocean_interface.fluxes.interface_heat + frazil_heat_flux(esm) - return Field(sea_ice_ocean_heat_flux) + return esm.interfaces.sea_ice_ocean_interface.fluxes.interface_heat + frazil_heat_flux(esm) end """ @@ -101,8 +92,7 @@ interface in a coupled `esm`. function atmosphere_ocean_heat_flux(esm::EarthSystemModel) ρᵒᶜ = esm.interfaces.ocean_properties.reference_density cᵒᶜ = esm.interfaces.ocean_properties.heat_capacity - atmosphere_ocean_heat_flux = ρᵒᶜ * cᵒᶜ * atmosphere_ocean_temperature_flux(esm) - return Field(atmosphere_ocean_heat_flux) + return ρᵒᶜ * cᵒᶜ * atmosphere_ocean_temperature_flux(esm) end @@ -116,8 +106,7 @@ end Return the net salinity flux (g/kg m s⁻¹) at the ocean's surface in a coupled `esm`. """ function net_ocean_salinity_flux(esm::EarthSystemModel) - Jˢ = esm.ocean.model.tracers.S.boundary_conditions.top.condition - return Jˢ + return esm.ocean.model.tracers.S.boundary_conditions.top.condition end @@ -128,8 +117,7 @@ Return the sea ice-ocean salinity flux (g/kg m s⁻¹) at the sea ice-ocean inte in a coupled `esm`. """ function sea_ice_ocean_salinity_flux(esm::EarthSystemModel) - sea_ice_ocean_salinity_flux = esm.interfaces.sea_ice_ocean_interface.fluxes.salt - return sea_ice_ocean_salinity_flux + return esm.interfaces.sea_ice_ocean_interface.fluxes.salt end """ @@ -139,9 +127,7 @@ Return the atmosphere-ocean salinity flux (g/kg m s⁻¹) at the atmosphere-ocea interface in a coupled `esm`. """ function atmosphere_ocean_salinity_flux(esm::EarthSystemModel) - atmosphere_ocean_salinity_flux = - net_ocean_salinity_flux(esm) - sea_ice_ocean_salinity_flux(esm) - return Field(atmosphere_ocean_salinity_flux) + return net_ocean_salinity_flux(esm) - sea_ice_ocean_salinity_flux(esm) end @@ -157,8 +143,7 @@ Return the net freshwater mass flux (kg m⁻² s⁻¹) at the ocean's surface in function net_ocean_freshwater_flux(esm::EarthSystemModel; reference_salinity = 35) ρᵒᶜ = esm.interfaces.ocean_properties.reference_density S₀ = convert(typeof(ρᵒᶜ), reference_salinity) - net_ocean_frashwater_flux = - ρᵒᶜ / S₀ * net_ocean_salinity_flux(esm) - return Field(net_ocean_frashwater_flux) + return - ρᵒᶜ / S₀ * net_ocean_salinity_flux(esm) end """ @@ -170,8 +155,7 @@ in a coupled `esm`. function sea_ice_ocean_freshwater_flux(esm::EarthSystemModel; reference_salinity = 35) ρᵒᶜ = esm.interfaces.ocean_properties.reference_density S₀ = convert(typeof(ρᵒᶜ), reference_salinity) - sea_ice_ocean_freshwater_flux = - ρᵒᶜ / S₀ * sea_ice_ocean_salinity_flux(esm) - return Field(sea_ice_ocean_freshwater_flux) + return - ρᵒᶜ / S₀ * sea_ice_ocean_salinity_flux(esm) end """ @@ -183,6 +167,5 @@ interface in a coupled `esm`. function atmosphere_ocean_freshwater_flux(esm::EarthSystemModel; reference_salinity = 35) ρᵒᶜ = esm.interfaces.ocean_properties.reference_density S₀ = convert(typeof(ρᵒᶜ), reference_salinity) - atmosphere_ocean_freshwater_flux = - ρᵒᶜ / S₀ * atmosphere_ocean_salinity_flux(esm) - return Field(atmosphere_ocean_freshwater_flux) + return - ρᵒᶜ / S₀ * atmosphere_ocean_salinity_flux(esm) end From a9d7255b8a41fc3197751664ddc08c0b70a0e2a7 Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Wed, 4 Mar 2026 06:25:03 +0100 Subject: [PATCH 02/13] drop temperature flux diags --- src/Diagnostics/interface_fluxes.jl | 57 ++--------------------------- test/test_diagnostics.jl | 32 +++++++--------- 2 files changed, 16 insertions(+), 73 deletions(-) diff --git a/src/Diagnostics/interface_fluxes.jl b/src/Diagnostics/interface_fluxes.jl index c1fb9a593..658abc8ad 100644 --- a/src/Diagnostics/interface_fluxes.jl +++ b/src/Diagnostics/interface_fluxes.jl @@ -1,54 +1,4 @@ -########################### -### Temperature fluxes -########################### - -""" - frazil_temperature_flux(esm::EarthSystemModel) - -Return the two-dimensional frazil temperature flux (K m s⁻¹) in a coupled `esm`. -""" -function frazil_temperature_flux(esm::EarthSystemModel) - ρᵒᶜ = esm.interfaces.ocean_properties.reference_density - cᵒᶜ = esm.interfaces.ocean_properties.heat_capacity - return 1 / (ρᵒᶜ * cᵒᶜ) * frazil_heat_flux(esm) -end - -""" - net_ocean_temperature_flux(esm::EarthSystemModel) - -Return the net temperature flux (K m s⁻¹) at the ocean's surface in a coupled `esm`. -""" -function net_ocean_temperature_flux(esm::EarthSystemModel) - Jᵀ = esm.ocean.model.tracers.T.boundary_conditions.top.condition - return Jᵀ + frazil_temperature_flux(esm) -end - - -""" - sea_ice_ocean_temperature_flux(esm::EarthSystemModel) - -Return the sea ice-ocean temperature flux (K m s⁻¹) at the sea ice-ocean interface -in a coupled `esm`. -""" -function sea_ice_ocean_temperature_flux(esm::EarthSystemModel) - ρᵒᶜ = esm.interfaces.ocean_properties.reference_density - cᵒᶜ = esm.interfaces.ocean_properties.heat_capacity - return 1 / (ρᵒᶜ * cᵒᶜ) * sea_ice_ocean_heat_flux(esm) -end - - -""" - atmosphere_ocean_temperature_flux(esm::EarthSystemModel) - -Return the atmosphere-ocean temperature flux (K m s⁻¹) at the atmosphere-ocean -interface in a coupled `esm`. -""" -function atmosphere_ocean_temperature_flux(esm::EarthSystemModel) - return net_ocean_temperature_flux(esm) - sea_ice_ocean_temperature_flux(esm) -end - - ########################### ### Heat fluxes ########################### @@ -68,9 +18,10 @@ end Return the net heat flux (W m⁻²) at the ocean's surface in a coupled `esm`. """ function net_ocean_heat_flux(esm::EarthSystemModel) + Jᵀ = esm.ocean.model.tracers.T.boundary_conditions.top.condition ρᵒᶜ = esm.interfaces.ocean_properties.reference_density cᵒᶜ = esm.interfaces.ocean_properties.heat_capacity - return ρᵒᶜ * cᵒᶜ * net_ocean_temperature_flux(esm) + return ρᵒᶜ * cᵒᶜ * Jᵀ + frazil_heat_flux(esm) end """ @@ -90,9 +41,7 @@ Return the atmosphere-ocean heat flux (W m⁻²) at the atmosphere-ocean interface in a coupled `esm`. """ function atmosphere_ocean_heat_flux(esm::EarthSystemModel) - ρᵒᶜ = esm.interfaces.ocean_properties.reference_density - cᵒᶜ = esm.interfaces.ocean_properties.heat_capacity - return ρᵒᶜ * cᵒᶜ * atmosphere_ocean_temperature_flux(esm) + return net_ocean_heat_flux(esm) - sea_ice_ocean_heat_flux(esm) end diff --git a/test/test_diagnostics.jl b/test/test_diagnostics.jl index 7d55c7d37..b7283abf9 100644 --- a/test/test_diagnostics.jl +++ b/test/test_diagnostics.jl @@ -5,6 +5,7 @@ using Oceananigans.Models: buoyancy_operation using NumericalEarth.Diagnostics: MixedLayerDepthField, MixedLayerDepthOperand using SeawaterPolynomials: TEOS10EquationOfState +#= for arch in test_architectures, dataset in (ECCO4Monthly(),) A = typeof(arch) @info "Testing MixedLayerDepthField with $(typeof(dataset)) on $A" @@ -56,12 +57,13 @@ for arch in test_architectures, dataset in (ECCO4Monthly(),) end end end +=# for arch in test_architectures A = typeof(arch) - @info "Testing InterfaceFluxOutputs on $A" + @info "Testing interface fluxes diagnostics on $A" - @testset "InterfaceFluxOutputs on $A" begin + @testset "Interface fluxes diagnostics on $A" begin grid = RectilinearGrid(arch; size = (4, 4, 2), extent = (1, 1, 1), @@ -97,10 +99,6 @@ for arch in test_architectures cᵒᶜ = esm.interfaces.ocean_properties.heat_capacity S₀ = 35.0 - frazil_temperature = frazil_temperature_flux(esm) - net_ocean_temperature = net_ocean_temperature_flux(esm) - sea_ice_ocean_temperature = sea_ice_ocean_temperature_flux(esm) - atmosphere_ocean_temperature = atmosphere_ocean_temperature_flux(esm) frazil_heat = frazil_heat_flux(esm) net_ocean_heat = net_ocean_heat_flux(esm) sea_ice_ocean_heat = sea_ice_ocean_heat_flux(esm) @@ -112,15 +110,16 @@ for arch in test_architectures sea_ice_ocean_freshwater = sea_ice_ocean_freshwater_flux(esm; reference_salinity = 35) atmosphere_ocean_freshwater = atmosphere_ocean_freshwater_flux(esm; reference_salinity = 35) - for f in (frazil_temperature, net_ocean_temperature, sea_ice_ocean_temperature, - atmosphere_ocean_temperature, frazil_heat, net_ocean_heat, sea_ice_ocean_heat, - atmosphere_ocean_heat, net_ocean_salinity, sea_ice_ocean_salinity, - atmosphere_ocean_salinity, net_ocean_freshwater, sea_ice_ocean_freshwater, - atmosphere_ocean_freshwater) + diags = (frazil_heat, net_ocean_heat, sea_ice_ocean_heat, + atmosphere_ocean_heat, net_ocean_salinity, sea_ice_ocean_salinity, + atmosphere_ocean_salinity, net_ocean_freshwater, sea_ice_ocean_freshwater, + atmosphere_ocean_freshwater) - @test f isa Field - @test location(f) == (Center, Center, Nothing) - compute!(f) + for d in diags + @test d isa Oceananigans.Fields.AbstractField + @test location(d) == (Center, Center, Nothing) + d |> Field + compute!(d) end @allowscalar begin @@ -134,11 +133,6 @@ for arch in test_architectures @test atmosphere_ocean_freshwater[1, 1, 1] ≈ - ρᵒᶜ / S₀ * (S_flux_value - sea_ice_ocean_salt_flux_value) @test net_ocean_freshwater[1, 1, 1] ≈ atmosphere_ocean_freshwater[1, 1, 1] + sea_ice_ocean_freshwater[1, 1, 1] - @test net_ocean_temperature[1, 1, 1] ≈ T_flux_value + 1 / (ρᵒᶜ * cᵒᶜ) * frazil_heat_flux_value - @test atmosphere_ocean_temperature[1, 1, 1] ≈ T_flux_value - 1 / (ρᵒᶜ * cᵒᶜ) * interface_heat_flux_value - @test sea_ice_ocean_temperature[1, 1, 1] ≈ 1 / (ρᵒᶜ * cᵒᶜ) * (frazil_heat_flux_value + interface_heat_flux_value) - @test net_ocean_temperature[1, 1, 1] ≈ atmosphere_ocean_temperature[1, 1, 1] + sea_ice_ocean_temperature[1, 1, 1] - @test net_ocean_freshwater[1, 1, 1] ≈ - ρᵒᶜ / S₀ * S_flux_value @test sea_ice_ocean_freshwater[1, 1, 1] ≈ - ρᵒᶜ / S₀ * sea_ice_ocean_salt_flux_value @test atmosphere_ocean_freshwater[1, 1, 1] ≈ - ρᵒᶜ / S₀ * (S_flux_value - sea_ice_ocean_salt_flux_value) From e2d86ff850c3fa105ce7a8b383f65fdd1ca321bb Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Wed, 4 Mar 2026 11:36:10 +0100 Subject: [PATCH 03/13] drop salinity fluxes --- src/Diagnostics/interface_fluxes.jl | 45 ++++------------------------- test/test_diagnostics.jl | 7 ----- 2 files changed, 5 insertions(+), 47 deletions(-) diff --git a/src/Diagnostics/interface_fluxes.jl b/src/Diagnostics/interface_fluxes.jl index 658abc8ad..4d76f9d58 100644 --- a/src/Diagnostics/interface_fluxes.jl +++ b/src/Diagnostics/interface_fluxes.jl @@ -45,41 +45,6 @@ function atmosphere_ocean_heat_flux(esm::EarthSystemModel) end -########################### -### Salinity fluxes -########################### - -""" - net_ocean_salinity_flux(esm::EarthSystemModel) - -Return the net salinity flux (g/kg m s⁻¹) at the ocean's surface in a coupled `esm`. -""" -function net_ocean_salinity_flux(esm::EarthSystemModel) - return esm.ocean.model.tracers.S.boundary_conditions.top.condition -end - - -""" - sea_ice_ocean_salinity_flux(esm::EarthSystemModel) - -Return the sea ice-ocean salinity flux (g/kg m s⁻¹) at the sea ice-ocean interface -in a coupled `esm`. -""" -function sea_ice_ocean_salinity_flux(esm::EarthSystemModel) - return esm.interfaces.sea_ice_ocean_interface.fluxes.salt -end - -""" - atmosphere_ocean_salinity_flux(esm::EarthSystemModel) - -Return the atmosphere-ocean salinity flux (g/kg m s⁻¹) at the atmosphere-ocean -interface in a coupled `esm`. -""" -function atmosphere_ocean_salinity_flux(esm::EarthSystemModel) - return net_ocean_salinity_flux(esm) - sea_ice_ocean_salinity_flux(esm) -end - - ########################### ### Freshwater mass fluxes ########################### @@ -90,9 +55,10 @@ end Return the net freshwater mass flux (kg m⁻² s⁻¹) at the ocean's surface in a coupled `esm`. """ function net_ocean_freshwater_flux(esm::EarthSystemModel; reference_salinity = 35) + Jˢ = esm.ocean.model.tracers.S.boundary_conditions.top.condition ρᵒᶜ = esm.interfaces.ocean_properties.reference_density S₀ = convert(typeof(ρᵒᶜ), reference_salinity) - return - ρᵒᶜ / S₀ * net_ocean_salinity_flux(esm) + return - ρᵒᶜ / S₀ * Jˢ end """ @@ -102,9 +68,10 @@ Return the sea ice-ocean freshwater mass flux (kg m⁻² s⁻¹) at the sea ice- in a coupled `esm`. """ function sea_ice_ocean_freshwater_flux(esm::EarthSystemModel; reference_salinity = 35) + Jˢⁱᵒ = esm.interfaces.sea_ice_ocean_interface.fluxes.salt ρᵒᶜ = esm.interfaces.ocean_properties.reference_density S₀ = convert(typeof(ρᵒᶜ), reference_salinity) - return - ρᵒᶜ / S₀ * sea_ice_ocean_salinity_flux(esm) + return - ρᵒᶜ / S₀ * Jˢⁱᵒ end """ @@ -114,7 +81,5 @@ Return the atmosphere-ocean freshwater mass flux (kg m⁻² s⁻¹) at the atmos interface in a coupled `esm`. """ function atmosphere_ocean_freshwater_flux(esm::EarthSystemModel; reference_salinity = 35) - ρᵒᶜ = esm.interfaces.ocean_properties.reference_density - S₀ = convert(typeof(ρᵒᶜ), reference_salinity) - return - ρᵒᶜ / S₀ * atmosphere_ocean_salinity_flux(esm) + return net_ocean_freshwater_flux(esm) - sea_ice_ocean_freshwater_flux(esm) end diff --git a/test/test_diagnostics.jl b/test/test_diagnostics.jl index b7283abf9..d052b787a 100644 --- a/test/test_diagnostics.jl +++ b/test/test_diagnostics.jl @@ -5,7 +5,6 @@ using Oceananigans.Models: buoyancy_operation using NumericalEarth.Diagnostics: MixedLayerDepthField, MixedLayerDepthOperand using SeawaterPolynomials: TEOS10EquationOfState -#= for arch in test_architectures, dataset in (ECCO4Monthly(),) A = typeof(arch) @info "Testing MixedLayerDepthField with $(typeof(dataset)) on $A" @@ -57,7 +56,6 @@ for arch in test_architectures, dataset in (ECCO4Monthly(),) end end end -=# for arch in test_architectures A = typeof(arch) @@ -132,11 +130,6 @@ for arch in test_architectures @test sea_ice_ocean_freshwater[1, 1, 1] ≈ - ρᵒᶜ / S₀ * sea_ice_ocean_salt_flux_value @test atmosphere_ocean_freshwater[1, 1, 1] ≈ - ρᵒᶜ / S₀ * (S_flux_value - sea_ice_ocean_salt_flux_value) @test net_ocean_freshwater[1, 1, 1] ≈ atmosphere_ocean_freshwater[1, 1, 1] + sea_ice_ocean_freshwater[1, 1, 1] - - @test net_ocean_freshwater[1, 1, 1] ≈ - ρᵒᶜ / S₀ * S_flux_value - @test sea_ice_ocean_freshwater[1, 1, 1] ≈ - ρᵒᶜ / S₀ * sea_ice_ocean_salt_flux_value - @test atmosphere_ocean_freshwater[1, 1, 1] ≈ - ρᵒᶜ / S₀ * (S_flux_value - sea_ice_ocean_salt_flux_value) - @test net_ocean_freshwater[1, 1, 1] ≈ atmosphere_ocean_freshwater[1, 1, 1] + sea_ice_ocean_freshwater[1, 1, 1] end end end From c934dc92824d2f9ad97aa3d24a62429d47c16197 Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Wed, 4 Mar 2026 11:37:40 +0100 Subject: [PATCH 04/13] drop salinity fluxes.. --- src/Diagnostics/Diagnostics.jl | 4 +--- src/NumericalEarth.jl | 2 -- test/test_diagnostics.jl | 9 ++------- 3 files changed, 3 insertions(+), 12 deletions(-) diff --git a/src/Diagnostics/Diagnostics.jl b/src/Diagnostics/Diagnostics.jl index 86cb7446a..4c8994a2f 100644 --- a/src/Diagnostics/Diagnostics.jl +++ b/src/Diagnostics/Diagnostics.jl @@ -1,9 +1,7 @@ module Diagnostics export MixedLayerDepthField, MixedLayerDepthOperand -export frazil_temperature_flux, net_ocean_temperature_flux, sea_ice_ocean_temperature_flux, atmosphere_ocean_temperature_flux, - frazil_heat_flux, net_ocean_heat_flux, sea_ice_ocean_heat_flux, atmosphere_ocean_heat_flux, - net_ocean_salinity_flux, sea_ice_ocean_salinity_flux, atmosphere_ocean_salinity_flux, +export frazil_heat_flux, net_ocean_heat_flux, sea_ice_ocean_heat_flux, atmosphere_ocean_heat_flux, net_ocean_freshwater_flux, sea_ice_ocean_freshwater_flux, atmosphere_ocean_freshwater_flux using Oceananigans diff --git a/src/NumericalEarth.jl b/src/NumericalEarth.jl index b6b2850c7..9b0824883 100644 --- a/src/NumericalEarth.jl +++ b/src/NumericalEarth.jl @@ -52,9 +52,7 @@ export atmosphere_simulation, sea_ice_dynamics, initialize!, - frazil_temperature_flux, net_ocean_temperature_flux, sea_ice_ocean_temperature_flux, atmosphere_ocean_temperature_flux, frazil_heat_flux, net_ocean_heat_flux, sea_ice_ocean_heat_flux, atmosphere_ocean_heat_flux, - net_ocean_salinity_flux, sea_ice_ocean_salinity_flux, atmosphere_ocean_salinity_flux, net_ocean_freshwater_flux, sea_ice_ocean_freshwater_flux, atmosphere_ocean_freshwater_flux using Oceananigans diff --git a/test/test_diagnostics.jl b/test/test_diagnostics.jl index d052b787a..565c763f1 100644 --- a/test/test_diagnostics.jl +++ b/test/test_diagnostics.jl @@ -101,17 +101,12 @@ for arch in test_architectures net_ocean_heat = net_ocean_heat_flux(esm) sea_ice_ocean_heat = sea_ice_ocean_heat_flux(esm) atmosphere_ocean_heat = atmosphere_ocean_heat_flux(esm) - net_ocean_salinity = net_ocean_salinity_flux(esm) - sea_ice_ocean_salinity = sea_ice_ocean_salinity_flux(esm) - atmosphere_ocean_salinity = atmosphere_ocean_salinity_flux(esm) net_ocean_freshwater = net_ocean_freshwater_flux(esm; reference_salinity = 35) sea_ice_ocean_freshwater = sea_ice_ocean_freshwater_flux(esm; reference_salinity = 35) atmosphere_ocean_freshwater = atmosphere_ocean_freshwater_flux(esm; reference_salinity = 35) - diags = (frazil_heat, net_ocean_heat, sea_ice_ocean_heat, - atmosphere_ocean_heat, net_ocean_salinity, sea_ice_ocean_salinity, - atmosphere_ocean_salinity, net_ocean_freshwater, sea_ice_ocean_freshwater, - atmosphere_ocean_freshwater) + diags = (frazil_heat, net_ocean_heat, sea_ice_ocean_heat, atmosphere_ocean_heat, + net_ocean_freshwater, sea_ice_ocean_freshwater, atmosphere_ocean_freshwater) for d in diags @test d isa Oceananigans.Fields.AbstractField From fe8bb330376f484b49c696877b2f1847cf7d8dca Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Wed, 4 Mar 2026 11:48:01 +0100 Subject: [PATCH 05/13] cleanup --- src/Diagnostics/interface_fluxes.jl | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/src/Diagnostics/interface_fluxes.jl b/src/Diagnostics/interface_fluxes.jl index 4d76f9d58..a7c51c255 100644 --- a/src/Diagnostics/interface_fluxes.jl +++ b/src/Diagnostics/interface_fluxes.jl @@ -8,9 +8,8 @@ Return the two-dimensional frazil heat flux (W m⁻²) in a coupled `esm`. """ -function frazil_heat_flux(esm::EarthSystemModel) - return esm.interfaces.sea_ice_ocean_interface.fluxes.frazil_heat -end +frazil_heat_flux(esm::EarthSystemModel) = + esm.interfaces.sea_ice_ocean_interface.fluxes.frazil_heat """ net_ocean_heat_flux(esm::EarthSystemModel) @@ -30,9 +29,8 @@ end Return the sea ice-ocean heat flux (W m⁻²) at the sea ice-ocean interface in a coupled `esm`. """ -function sea_ice_ocean_heat_flux(esm::EarthSystemModel) - return esm.interfaces.sea_ice_ocean_interface.fluxes.interface_heat + frazil_heat_flux(esm) -end +sea_ice_ocean_heat_flux(esm::EarthSystemModel) = + esm.interfaces.sea_ice_ocean_interface.fluxes.interface_heat + frazil_heat_flux(esm) """ atmosphere_ocean_heat_flux(esm::EarthSystemModel) @@ -40,9 +38,8 @@ end Return the atmosphere-ocean heat flux (W m⁻²) at the atmosphere-ocean interface in a coupled `esm`. """ -function atmosphere_ocean_heat_flux(esm::EarthSystemModel) - return net_ocean_heat_flux(esm) - sea_ice_ocean_heat_flux(esm) -end +atmosphere_ocean_heat_flux(esm::EarthSystemModel) = + net_ocean_heat_flux(esm) - sea_ice_ocean_heat_flux(esm) ########################### @@ -80,6 +77,5 @@ end Return the atmosphere-ocean freshwater mass flux (kg m⁻² s⁻¹) at the atmosphere-ocean interface in a coupled `esm`. """ -function atmosphere_ocean_freshwater_flux(esm::EarthSystemModel; reference_salinity = 35) - return net_ocean_freshwater_flux(esm) - sea_ice_ocean_freshwater_flux(esm) -end +atmosphere_ocean_freshwater_flux(esm::EarthSystemModel; reference_salinity = 35) + = net_ocean_freshwater_flux(esm) - sea_ice_ocean_freshwater_flux(esm) From e08da888adf394736c4ff5d540fc2544c5eafdbf Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Wed, 4 Mar 2026 11:49:27 +0100 Subject: [PATCH 06/13] pass reference_salinity further down --- src/Diagnostics/interface_fluxes.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Diagnostics/interface_fluxes.jl b/src/Diagnostics/interface_fluxes.jl index a7c51c255..59f2e3bbe 100644 --- a/src/Diagnostics/interface_fluxes.jl +++ b/src/Diagnostics/interface_fluxes.jl @@ -77,5 +77,5 @@ end Return the atmosphere-ocean freshwater mass flux (kg m⁻² s⁻¹) at the atmosphere-ocean interface in a coupled `esm`. """ -atmosphere_ocean_freshwater_flux(esm::EarthSystemModel; reference_salinity = 35) - = net_ocean_freshwater_flux(esm) - sea_ice_ocean_freshwater_flux(esm) +atmosphere_ocean_freshwater_flux(esm::EarthSystemModel; reference_salinity = 35) = + net_ocean_freshwater_flux(esm; reference_salinity) - sea_ice_ocean_freshwater_flux(esm; reference_salinity) From e9b0a46508e304c80ed5a2b7d04750722cf43ff7 Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Wed, 4 Mar 2026 11:51:27 +0100 Subject: [PATCH 07/13] ensure we test for reference salinity --- test/test_diagnostics.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/test_diagnostics.jl b/test/test_diagnostics.jl index 565c763f1..3ae1e0908 100644 --- a/test/test_diagnostics.jl +++ b/test/test_diagnostics.jl @@ -95,15 +95,15 @@ for arch in test_architectures ρᵒᶜ = esm.interfaces.ocean_properties.reference_density cᵒᶜ = esm.interfaces.ocean_properties.heat_capacity - S₀ = 35.0 + S₀ = 34.0 # different than the default frazil_heat = frazil_heat_flux(esm) net_ocean_heat = net_ocean_heat_flux(esm) sea_ice_ocean_heat = sea_ice_ocean_heat_flux(esm) atmosphere_ocean_heat = atmosphere_ocean_heat_flux(esm) - net_ocean_freshwater = net_ocean_freshwater_flux(esm; reference_salinity = 35) - sea_ice_ocean_freshwater = sea_ice_ocean_freshwater_flux(esm; reference_salinity = 35) - atmosphere_ocean_freshwater = atmosphere_ocean_freshwater_flux(esm; reference_salinity = 35) + net_ocean_freshwater = net_ocean_freshwater_flux(esm; reference_salinity = S₀) + sea_ice_ocean_freshwater = sea_ice_ocean_freshwater_flux(esm; reference_salinity = S₀) + atmosphere_ocean_freshwater = atmosphere_ocean_freshwater_flux(esm; reference_salinity = S₀) diags = (frazil_heat, net_ocean_heat, sea_ice_ocean_heat, atmosphere_ocean_heat, net_ocean_freshwater, sea_ice_ocean_freshwater, atmosphere_ocean_freshwater) From ec708fdd0182d6a2c5f315ad406687df3a25b4bc Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Wed, 4 Mar 2026 11:52:08 +0100 Subject: [PATCH 08/13] rephrase --- test/test_diagnostics.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_diagnostics.jl b/test/test_diagnostics.jl index 3ae1e0908..a94c9ac3e 100644 --- a/test/test_diagnostics.jl +++ b/test/test_diagnostics.jl @@ -95,7 +95,7 @@ for arch in test_architectures ρᵒᶜ = esm.interfaces.ocean_properties.reference_density cᵒᶜ = esm.interfaces.ocean_properties.heat_capacity - S₀ = 34.0 # different than the default + S₀ = 34.0 # different from the default value frazil_heat = frazil_heat_flux(esm) net_ocean_heat = net_ocean_heat_flux(esm) From 2850600a9134294bf759c0b16fd0116727a98f35 Mon Sep 17 00:00:00 2001 From: Taimoor Sohail Date: Wed, 4 Mar 2026 12:59:58 +0100 Subject: [PATCH 09/13] Inferred salt fluxes --> Freshwater volume fluxes (#99) * Modified freshwater flux definitions to match volume fluxes from interfaces * Update freshwater diagnostics docs and calls * Align freshwater diagnostics to mass flux units * Remove redundant sea-ice freshwater write in net ocean assembly * Apply suggestions from code review --------- Co-authored-by: Navid C. Constantinou --- src/Diagnostics/interface_fluxes.jl | 21 +++++++------------ .../component_interfaces.jl | 7 +++++++ .../sea_ice_ocean_fluxes.jl | 5 ++++- src/Oceans/assemble_net_ocean_fluxes.jl | 14 ++++++------- test/test_diagnostics.jl | 18 +++++++++------- 5 files changed, 36 insertions(+), 29 deletions(-) diff --git a/src/Diagnostics/interface_fluxes.jl b/src/Diagnostics/interface_fluxes.jl index 59f2e3bbe..f4b1725ef 100644 --- a/src/Diagnostics/interface_fluxes.jl +++ b/src/Diagnostics/interface_fluxes.jl @@ -51,12 +51,8 @@ atmosphere_ocean_heat_flux(esm::EarthSystemModel) = Return the net freshwater mass flux (kg m⁻² s⁻¹) at the ocean's surface in a coupled `esm`. """ -function net_ocean_freshwater_flux(esm::EarthSystemModel; reference_salinity = 35) - Jˢ = esm.ocean.model.tracers.S.boundary_conditions.top.condition - ρᵒᶜ = esm.interfaces.ocean_properties.reference_density - S₀ = convert(typeof(ρᵒᶜ), reference_salinity) - return - ρᵒᶜ / S₀ * Jˢ -end +net_ocean_freshwater_flux(esm::EarthSystemModel) = + sea_ice_ocean_freshwater_flux(esm) + atmosphere_ocean_freshwater_flux(esm) """ sea_ice_ocean_freshwater_flux(esm::EarthSystemModel) @@ -64,12 +60,8 @@ end Return the sea ice-ocean freshwater mass flux (kg m⁻² s⁻¹) at the sea ice-ocean interface in a coupled `esm`. """ -function sea_ice_ocean_freshwater_flux(esm::EarthSystemModel; reference_salinity = 35) - Jˢⁱᵒ = esm.interfaces.sea_ice_ocean_interface.fluxes.salt - ρᵒᶜ = esm.interfaces.ocean_properties.reference_density - S₀ = convert(typeof(ρᵒᶜ), reference_salinity) - return - ρᵒᶜ / S₀ * Jˢⁱᵒ -end +sea_ice_ocean_freshwater_flux(esm::EarthSystemModel) = + esm.interfaces.sea_ice_ocean_interface.fluxes.freshwater_flux """ atmosphere_ocean_freshwater_flux(esm::EarthSystemModel) @@ -77,5 +69,6 @@ end Return the atmosphere-ocean freshwater mass flux (kg m⁻² s⁻¹) at the atmosphere-ocean interface in a coupled `esm`. """ -atmosphere_ocean_freshwater_flux(esm::EarthSystemModel; reference_salinity = 35) = - net_ocean_freshwater_flux(esm; reference_salinity) - sea_ice_ocean_freshwater_flux(esm; reference_salinity) +atmosphere_ocean_freshwater_flux(esm::EarthSystemModel) = + esm.interfaces.ocean_properties.reference_density * + esm.interfaces.atmosphere_ocean_interface.fluxes.freshwater_flux diff --git a/src/EarthSystemModels/InterfaceComputations/component_interfaces.jl b/src/EarthSystemModels/InterfaceComputations/component_interfaces.jl index f58f607aa..0200f64eb 100644 --- a/src/EarthSystemModels/InterfaceComputations/component_interfaces.jl +++ b/src/EarthSystemModels/InterfaceComputations/component_interfaces.jl @@ -45,6 +45,7 @@ Fields ====== - `fluxes::J`: named tuple of flux fields (interface_heat, frazil_heat, salt, x_momentum, y_momentum) + and freshwater_flux. - `flux_formulation::F`: heat flux formulation (`IceBathHeatFlux` or `ThreeEquationHeatFlux`) - `temperature::T`: interface temperature field (ocean surface view or computed field) - `salinity::S`: interface salinity field (ocean surface view or computed field) @@ -109,6 +110,7 @@ function atmosphere_ocean_interface(grid, friction_velocity = Field{Center, Center, Nothing}(grid) temperature_scale = Field{Center, Center, Nothing}(grid) water_vapor_scale = Field{Center, Center, Nothing}(grid) + freshwater_flux = Field{Center, Center, Nothing}(grid) upwelling_longwave = Field{Center, Center, Nothing}(grid) downwelling_longwave = Field{Center, Center, Nothing}(grid) downwelling_shortwave = Field{Center, Center, Nothing}(grid) @@ -121,6 +123,7 @@ function atmosphere_ocean_interface(grid, friction_velocity, temperature_scale, water_vapor_scale, + freshwater_flux, upwelling_longwave, downwelling_longwave, downwelling_shortwave) @@ -216,12 +219,14 @@ function sea_ice_ocean_interface(grid, sea_ice, ocean, flux_formulation) io_bottom_heat_flux = Field{Center, Center, Nothing}(grid) io_frazil_heat_flux = Field{Center, Center, Nothing}(grid) io_salt_flux = Field{Center, Center, Nothing}(grid) + io_freshwater_flux = Field{Center, Center, Nothing}(grid) x_momentum = Field{Face, Center, Nothing}(grid) y_momentum = Field{Center, Face, Nothing}(grid) io_fluxes = (interface_heat = io_bottom_heat_flux, frazil_heat = io_frazil_heat_flux, salt = io_salt_flux, + freshwater_flux = io_freshwater_flux, x_momentum = x_momentum, y_momentum = y_momentum) @@ -237,12 +242,14 @@ function sea_ice_ocean_interface(grid, sea_ice, ocean, flux_formulation::ThreeEq io_bottom_heat_flux = Field{Center, Center, Nothing}(grid) io_frazil_heat_flux = Field{Center, Center, Nothing}(grid) io_salt_flux = Field{Center, Center, Nothing}(grid) + io_freshwater_flux = Field{Center, Center, Nothing}(grid) x_momentum = Field{Face, Center, Nothing}(grid) y_momentum = Field{Center, Face, Nothing}(grid) io_fluxes = (interface_heat = io_bottom_heat_flux, frazil_heat = io_frazil_heat_flux, salt = io_salt_flux, + freshwater_flux = io_freshwater_flux, x_momentum = x_momentum, y_momentum = y_momentum) diff --git a/src/EarthSystemModels/InterfaceComputations/sea_ice_ocean_fluxes.jl b/src/EarthSystemModels/InterfaceComputations/sea_ice_ocean_fluxes.jl index ddc5f7bbf..617fb95fd 100644 --- a/src/EarthSystemModels/InterfaceComputations/sea_ice_ocean_fluxes.jl +++ b/src/EarthSystemModels/InterfaceComputations/sea_ice_ocean_fluxes.jl @@ -123,6 +123,7 @@ end 𝒬ᶠʳᶻ = fluxes.frazil_heat 𝒬ⁱⁿᵗ = fluxes.interface_heat Jˢ = fluxes.salt + ΣF = fluxes.freshwater_flux τˣ = fluxes.x_momentum τʸ = fluxes.y_momentum T★ = interface_temperature @@ -212,5 +213,7 @@ end # Salt flux from melting/freezing: # - during ice melt (qᵐ > 0), fresh meltwater dilutes the ocean # - during ice growth (qᶠ < 0), brine rejection adds salt to ocean - @inbounds Jˢ[i, j, 1] = (qᵐ + qᶠ) / ρᵒᶜ * (Sᴺ - Sˢⁱ) + ΣFio = qᵐ + qᶠ + @inbounds Jˢ[i, j, 1] = ΣFio / ρᵒᶜ * (Sᴺ - Sˢⁱ) + @inbounds ΣF[i, j, 1] = ΣFio end diff --git a/src/Oceans/assemble_net_ocean_fluxes.jl b/src/Oceans/assemble_net_ocean_fluxes.jl index a1b1d0dcd..6d3c8af45 100644 --- a/src/Oceans/assemble_net_ocean_fluxes.jl +++ b/src/Oceans/assemble_net_ocean_fluxes.jl @@ -126,13 +126,6 @@ end # Compute the total heat flux ΣQao = (ℐꜛˡʷ + 𝒬ᵀ + 𝒬ᵛ) * (1 - ℵᵢ) + ℐₐˡʷ + Qss - @inbounds begin - # Write radiative components of the heat flux for diagnostic purposes - atmos_ocean_fluxes.upwelling_longwave[i, j, 1] = ℐꜛˡʷ - atmos_ocean_fluxes.downwelling_longwave[i, j, 1] = - ℐₐˡʷ - atmos_ocean_fluxes.downwelling_shortwave[i, j, 1] = - ℐₜˢʷ - end - # Convert from a mass flux to a volume flux (aka velocity) # by dividing with the ocean reference density. # Also switch the sign, for some reason we are given freshwater flux as positive down. @@ -143,6 +136,13 @@ end # a different sign convention as the prescribed water mass fluxes (positive upwards) Jᵛᵒᶜ = Jᵛ * ρᵒᶜ⁻¹ ΣFao += Jᵛᵒᶜ + @inbounds begin + # Write radiative components of the heat flux for diagnostic purposes + atmos_ocean_fluxes.upwelling_longwave[i, j, 1] = ℐꜛˡʷ + atmos_ocean_fluxes.downwelling_longwave[i, j, 1] = - ℐₐˡʷ + atmos_ocean_fluxes.downwelling_shortwave[i, j, 1] = - ℐₜˢʷ + atmos_ocean_fluxes.freshwater_flux[i, j, 1] = ΣFao + end # Compute fluxes for u, v, T, and S from momentum, heat, and freshwater fluxes τˣ = net_ocean_fluxes.u diff --git a/test/test_diagnostics.jl b/test/test_diagnostics.jl index a94c9ac3e..62383fc0a 100644 --- a/test/test_diagnostics.jl +++ b/test/test_diagnostics.jl @@ -80,18 +80,23 @@ for arch in test_architectures T_flux = ocean.model.tracers.T.boundary_conditions.top.condition S_flux = ocean.model.tracers.S.boundary_conditions.top.condition sea_ice_ocean_fluxes = esm.interfaces.sea_ice_ocean_interface.fluxes + atmosphere_ocean_fluxes = esm.interfaces.atmosphere_ocean_interface.fluxes T_flux_value = 2.0 S_flux_value = 5.0 frazil_heat_flux_value = 0.2 interface_heat_flux_value = 0.3 sea_ice_ocean_salt_flux_value = 0.9 + sea_ice_ocean_freshwater_flux_value = 0.8 + atmosphere_ocean_freshwater_flux_value = 1.7 fill!(T_flux, T_flux_value) fill!(S_flux, S_flux_value) fill!(sea_ice_ocean_fluxes.frazil_heat, frazil_heat_flux_value) fill!(sea_ice_ocean_fluxes.interface_heat, interface_heat_flux_value) fill!(sea_ice_ocean_fluxes.salt, sea_ice_ocean_salt_flux_value) + fill!(sea_ice_ocean_fluxes.freshwater_flux, sea_ice_ocean_freshwater_flux_value) + fill!(atmosphere_ocean_fluxes.freshwater_flux, atmosphere_ocean_freshwater_flux_value) ρᵒᶜ = esm.interfaces.ocean_properties.reference_density cᵒᶜ = esm.interfaces.ocean_properties.heat_capacity @@ -101,9 +106,9 @@ for arch in test_architectures net_ocean_heat = net_ocean_heat_flux(esm) sea_ice_ocean_heat = sea_ice_ocean_heat_flux(esm) atmosphere_ocean_heat = atmosphere_ocean_heat_flux(esm) - net_ocean_freshwater = net_ocean_freshwater_flux(esm; reference_salinity = S₀) - sea_ice_ocean_freshwater = sea_ice_ocean_freshwater_flux(esm; reference_salinity = S₀) - atmosphere_ocean_freshwater = atmosphere_ocean_freshwater_flux(esm; reference_salinity = S₀) + net_ocean_freshwater = net_ocean_freshwater_flux(esm) + sea_ice_ocean_freshwater = sea_ice_ocean_freshwater_flux(esm) + atmosphere_ocean_freshwater = atmosphere_ocean_freshwater_flux(esm) diags = (frazil_heat, net_ocean_heat, sea_ice_ocean_heat, atmosphere_ocean_heat, net_ocean_freshwater, sea_ice_ocean_freshwater, atmosphere_ocean_freshwater) @@ -121,10 +126,9 @@ for arch in test_architectures @test sea_ice_ocean_heat[1, 1, 1] ≈ frazil_heat_flux_value + interface_heat_flux_value @test net_ocean_heat[1, 1, 1] ≈ atmosphere_ocean_heat[1, 1, 1] + sea_ice_ocean_heat[1, 1, 1] - @test net_ocean_freshwater[1, 1, 1] ≈ - ρᵒᶜ / S₀ * S_flux_value - @test sea_ice_ocean_freshwater[1, 1, 1] ≈ - ρᵒᶜ / S₀ * sea_ice_ocean_salt_flux_value - @test atmosphere_ocean_freshwater[1, 1, 1] ≈ - ρᵒᶜ / S₀ * (S_flux_value - sea_ice_ocean_salt_flux_value) - @test net_ocean_freshwater[1, 1, 1] ≈ atmosphere_ocean_freshwater[1, 1, 1] + sea_ice_ocean_freshwater[1, 1, 1] + @test net_ocean_freshwater[1, 1, 1] ≈ sea_ice_ocean_freshwater_flux_value + ρᵒᶜ * atmosphere_ocean_freshwater_flux_value + @test sea_ice_ocean_freshwater[1, 1, 1] ≈ sea_ice_ocean_freshwater_flux_value + @test atmosphere_ocean_freshwater[1, 1, 1] ≈ ρᵒᶜ * atmosphere_ocean_freshwater_flux_value end end end From e1b5fd35646eb3481a2fa26d2c281de5351b385f Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Wed, 4 Mar 2026 13:07:19 +0100 Subject: [PATCH 10/13] fix tests --- src/Diagnostics/interface_fluxes.jl | 9 +++++---- test/test_diagnostics.jl | 4 ---- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/Diagnostics/interface_fluxes.jl b/src/Diagnostics/interface_fluxes.jl index f4b1725ef..1cfc47089 100644 --- a/src/Diagnostics/interface_fluxes.jl +++ b/src/Diagnostics/interface_fluxes.jl @@ -17,7 +17,7 @@ frazil_heat_flux(esm::EarthSystemModel) = Return the net heat flux (W m⁻²) at the ocean's surface in a coupled `esm`. """ function net_ocean_heat_flux(esm::EarthSystemModel) - Jᵀ = esm.ocean.model.tracers.T.boundary_conditions.top.condition + Jᵀ = esm.ocean.model.tracers.T.boundary_conditions.top.condition # temperature flux ρᵒᶜ = esm.interfaces.ocean_properties.reference_density cᵒᶜ = esm.interfaces.ocean_properties.heat_capacity return ρᵒᶜ * cᵒᶜ * Jᵀ + frazil_heat_flux(esm) @@ -69,6 +69,7 @@ sea_ice_ocean_freshwater_flux(esm::EarthSystemModel) = Return the atmosphere-ocean freshwater mass flux (kg m⁻² s⁻¹) at the atmosphere-ocean interface in a coupled `esm`. """ -atmosphere_ocean_freshwater_flux(esm::EarthSystemModel) = - esm.interfaces.ocean_properties.reference_density * - esm.interfaces.atmosphere_ocean_interface.fluxes.freshwater_flux +function atmosphere_ocean_freshwater_flux(esm::EarthSystemModel) + ρᵒᶜ = esm.interfaces.ocean_properties.reference_density + return ρᵒᶜ * esm.interfaces.atmosphere_ocean_interface.fluxes.freshwater_flux +end diff --git a/test/test_diagnostics.jl b/test/test_diagnostics.jl index 62383fc0a..46137ee9b 100644 --- a/test/test_diagnostics.jl +++ b/test/test_diagnostics.jl @@ -78,12 +78,10 @@ for arch in test_architectures esm = OceanSeaIceModel(ocean, sea_ice; atmosphere, radiation = Radiation()) T_flux = ocean.model.tracers.T.boundary_conditions.top.condition - S_flux = ocean.model.tracers.S.boundary_conditions.top.condition sea_ice_ocean_fluxes = esm.interfaces.sea_ice_ocean_interface.fluxes atmosphere_ocean_fluxes = esm.interfaces.atmosphere_ocean_interface.fluxes T_flux_value = 2.0 - S_flux_value = 5.0 frazil_heat_flux_value = 0.2 interface_heat_flux_value = 0.3 sea_ice_ocean_salt_flux_value = 0.9 @@ -91,7 +89,6 @@ for arch in test_architectures atmosphere_ocean_freshwater_flux_value = 1.7 fill!(T_flux, T_flux_value) - fill!(S_flux, S_flux_value) fill!(sea_ice_ocean_fluxes.frazil_heat, frazil_heat_flux_value) fill!(sea_ice_ocean_fluxes.interface_heat, interface_heat_flux_value) fill!(sea_ice_ocean_fluxes.salt, sea_ice_ocean_salt_flux_value) @@ -100,7 +97,6 @@ for arch in test_architectures ρᵒᶜ = esm.interfaces.ocean_properties.reference_density cᵒᶜ = esm.interfaces.ocean_properties.heat_capacity - S₀ = 34.0 # different from the default value frazil_heat = frazil_heat_flux(esm) net_ocean_heat = net_ocean_heat_flux(esm) From 786456b8179c552cce559313a3c3f8c339dd52f1 Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Wed, 4 Mar 2026 13:16:05 +0100 Subject: [PATCH 11/13] don't expose frazil_heat_flux to users --- src/Diagnostics/Diagnostics.jl | 2 +- src/Diagnostics/interface_fluxes.jl | 17 ++++++----------- src/NumericalEarth.jl | 2 +- test/test_diagnostics.jl | 3 +-- 4 files changed, 9 insertions(+), 15 deletions(-) diff --git a/src/Diagnostics/Diagnostics.jl b/src/Diagnostics/Diagnostics.jl index 4c8994a2f..723e81c05 100644 --- a/src/Diagnostics/Diagnostics.jl +++ b/src/Diagnostics/Diagnostics.jl @@ -1,7 +1,7 @@ module Diagnostics export MixedLayerDepthField, MixedLayerDepthOperand -export frazil_heat_flux, net_ocean_heat_flux, sea_ice_ocean_heat_flux, atmosphere_ocean_heat_flux, +export net_ocean_heat_flux, sea_ice_ocean_heat_flux, atmosphere_ocean_heat_flux, net_ocean_freshwater_flux, sea_ice_ocean_freshwater_flux, atmosphere_ocean_freshwater_flux using Oceananigans diff --git a/src/Diagnostics/interface_fluxes.jl b/src/Diagnostics/interface_fluxes.jl index 1cfc47089..e3f0cae87 100644 --- a/src/Diagnostics/interface_fluxes.jl +++ b/src/Diagnostics/interface_fluxes.jl @@ -3,14 +3,6 @@ ### Heat fluxes ########################### -""" - frazil_heat_flux(esm::EarthSystemModel) - -Return the two-dimensional frazil heat flux (W m⁻²) in a coupled `esm`. -""" -frazil_heat_flux(esm::EarthSystemModel) = - esm.interfaces.sea_ice_ocean_interface.fluxes.frazil_heat - """ net_ocean_heat_flux(esm::EarthSystemModel) @@ -20,7 +12,8 @@ function net_ocean_heat_flux(esm::EarthSystemModel) Jᵀ = esm.ocean.model.tracers.T.boundary_conditions.top.condition # temperature flux ρᵒᶜ = esm.interfaces.ocean_properties.reference_density cᵒᶜ = esm.interfaces.ocean_properties.heat_capacity - return ρᵒᶜ * cᵒᶜ * Jᵀ + frazil_heat_flux(esm) + frazil_heat_flux = esm.interfaces.sea_ice_ocean_interface.fluxes.frazil_heat + return ρᵒᶜ * cᵒᶜ * Jᵀ + frazil_heat_flux end """ @@ -29,8 +22,10 @@ end Return the sea ice-ocean heat flux (W m⁻²) at the sea ice-ocean interface in a coupled `esm`. """ -sea_ice_ocean_heat_flux(esm::EarthSystemModel) = - esm.interfaces.sea_ice_ocean_interface.fluxes.interface_heat + frazil_heat_flux(esm) +function sea_ice_ocean_heat_flux(esm::EarthSystemModel) + frazil_heat_flux = esm.interfaces.sea_ice_ocean_interface.fluxes.frazil_heat + return esm.interfaces.sea_ice_ocean_interface.fluxes.interface_heat + frazil_heat_flux +end """ atmosphere_ocean_heat_flux(esm::EarthSystemModel) diff --git a/src/NumericalEarth.jl b/src/NumericalEarth.jl index 9b0824883..681da6cb5 100644 --- a/src/NumericalEarth.jl +++ b/src/NumericalEarth.jl @@ -52,7 +52,7 @@ export atmosphere_simulation, sea_ice_dynamics, initialize!, - frazil_heat_flux, net_ocean_heat_flux, sea_ice_ocean_heat_flux, atmosphere_ocean_heat_flux, + net_ocean_heat_flux, sea_ice_ocean_heat_flux, atmosphere_ocean_heat_flux, net_ocean_freshwater_flux, sea_ice_ocean_freshwater_flux, atmosphere_ocean_freshwater_flux using Oceananigans diff --git a/test/test_diagnostics.jl b/test/test_diagnostics.jl index 46137ee9b..d2d8f38e4 100644 --- a/test/test_diagnostics.jl +++ b/test/test_diagnostics.jl @@ -98,7 +98,6 @@ for arch in test_architectures ρᵒᶜ = esm.interfaces.ocean_properties.reference_density cᵒᶜ = esm.interfaces.ocean_properties.heat_capacity - frazil_heat = frazil_heat_flux(esm) net_ocean_heat = net_ocean_heat_flux(esm) sea_ice_ocean_heat = sea_ice_ocean_heat_flux(esm) atmosphere_ocean_heat = atmosphere_ocean_heat_flux(esm) @@ -106,7 +105,7 @@ for arch in test_architectures sea_ice_ocean_freshwater = sea_ice_ocean_freshwater_flux(esm) atmosphere_ocean_freshwater = atmosphere_ocean_freshwater_flux(esm) - diags = (frazil_heat, net_ocean_heat, sea_ice_ocean_heat, atmosphere_ocean_heat, + diags = (net_ocean_heat, sea_ice_ocean_heat, atmosphere_ocean_heat, net_ocean_freshwater, sea_ice_ocean_freshwater, atmosphere_ocean_freshwater) for d in diags From ccedd0143c64849596b9b101bf21c1f7cacfb677 Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Wed, 4 Mar 2026 13:21:44 +0100 Subject: [PATCH 12/13] code alignment --- .../sea_ice_ocean_fluxes.jl | 24 +++++++++---------- .../sea_ice_ocean_heat_flux_formulations.jl | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/EarthSystemModels/InterfaceComputations/sea_ice_ocean_fluxes.jl b/src/EarthSystemModels/InterfaceComputations/sea_ice_ocean_fluxes.jl index 617fb95fd..388b358c4 100644 --- a/src/EarthSystemModels/InterfaceComputations/sea_ice_ocean_fluxes.jl +++ b/src/EarthSystemModels/InterfaceComputations/sea_ice_ocean_fluxes.jl @@ -70,9 +70,9 @@ function compute_sea_ice_ocean_fluxes!(interface, ocean, sea_ice, ocean_properti return nothing end -@kernel function _compute_sea_ice_ocean_stress!(fluxes, - grid, - clock, +@kernel function _compute_sea_ice_ocean_stress!(fluxes, + grid, + clock, ice_thickness, ice_concentration, sea_ice_u_velocity, @@ -83,7 +83,7 @@ end τˣ = fluxes.x_momentum τʸ = fluxes.y_momentum Nz = size(grid, 3) - + uˢⁱ = sea_ice_u_velocity vˢⁱ = sea_ice_v_velocity hˢⁱ = ice_thickness @@ -176,12 +176,12 @@ end qᶠ = δ𝒬ᶠʳᶻ / ℰ @inbounds begin - Tᴺ = Tᵒᶜ[i, j, Nz] - Sᴺ = Sᵒᶜ[i, j, Nz] - Sˢⁱ = ice_salinity[i, j, 1] - hˢⁱ = ice_thickness[i, j, 1] - ℵᵢ = ice_concentration[i, j, 1] - hc = ice_consolidation_thickness[i, j, 1] + Tᴺ = Tᵒᶜ[i, j, Nz] + Sᴺ = Sᵒᶜ[i, j, Nz] + Sˢⁱ = ice_salinity[i, j, 1] + hˢⁱ = ice_thickness[i, j, 1] + ℵᵢ = ice_concentration[i, j, 1] + hc = ice_consolidation_thickness[i, j, 1] end # Extract internal temperature (for ConductiveFluxTEF, zero otherwise) @@ -199,8 +199,8 @@ end # ============================================= # Returns interfacial heat flux, melt rate qᵐ, and interface T, S 𝒬ⁱᵒ, qᵐ, Tᵦ, Sᵦ = compute_interface_heat_flux(flux_formulation, - ocean_surface_state, ice_state, - liquidus, ocean_properties, ℰ, u★) + ocean_surface_state, ice_state, + liquidus, ocean_properties, ℰ, u★) # Store interface values and heat flux @inbounds T★[i, j, 1] = Tᵦ diff --git a/src/EarthSystemModels/InterfaceComputations/sea_ice_ocean_heat_flux_formulations.jl b/src/EarthSystemModels/InterfaceComputations/sea_ice_ocean_heat_flux_formulations.jl index b8f2638bc..f9345b024 100644 --- a/src/EarthSystemModels/InterfaceComputations/sea_ice_ocean_heat_flux_formulations.jl +++ b/src/EarthSystemModels/InterfaceComputations/sea_ice_ocean_heat_flux_formulations.jl @@ -124,7 +124,7 @@ struct ThreeEquationHeatFlux{F, T, FT, U} friction_velocity :: U end -Adapt.adapt_structure(to, f::ThreeEquationHeatFlux) = +Adapt.adapt_structure(to, f::ThreeEquationHeatFlux) = ThreeEquationHeatFlux(Adapt.adapt(to, f.conductive_flux), Adapt.adapt(to, f.internal_temperature), f.heat_transfer_coefficient, From 9dc7ac9b2e8779217f4c2d8a04f28b88ec9a3d6c Mon Sep 17 00:00:00 2001 From: "Navid C. Constantinou" Date: Wed, 4 Mar 2026 13:22:17 +0100 Subject: [PATCH 13/13] Apply suggestions from code review --- .../InterfaceComputations/component_interfaces.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/EarthSystemModels/InterfaceComputations/component_interfaces.jl b/src/EarthSystemModels/InterfaceComputations/component_interfaces.jl index 0200f64eb..fb6921f98 100644 --- a/src/EarthSystemModels/InterfaceComputations/component_interfaces.jl +++ b/src/EarthSystemModels/InterfaceComputations/component_interfaces.jl @@ -44,7 +44,7 @@ Container for sea ice-ocean interface data including fluxes, formulation, and in Fields ====== -- `fluxes::J`: named tuple of flux fields (interface_heat, frazil_heat, salt, x_momentum, y_momentum) +- `fluxes::J`: named tuple of flux fields (interface_heat, frazil_heat, salt, x_momentum, y_momentum), and freshwater_flux. - `flux_formulation::F`: heat flux formulation (`IceBathHeatFlux` or `ThreeEquationHeatFlux`) - `temperature::T`: interface temperature field (ocean surface view or computed field)