From 2d3e2395e45d01333b5c0e5faa41e46198f8b887 Mon Sep 17 00:00:00 2001 From: Simone Silvestri Date: Wed, 15 Apr 2026 12:51:06 +0200 Subject: [PATCH] Partition ocean freshwater: rain through ice, snow to open water only MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Split the ocean freshwater budget so that: - Rain reaches the ocean everywhere (runs through cracks in ice) - Snow only reaches the ocean through the open-water fraction (1-ℵ); snow on ice is routed to the sea ice model as snowfall - Evaporation is from the open-water fraction (1-ℵ) The total freshwater flux ΣFao now has ice-partitioning built in, so the salinity flux Jˢao = -S × ΣFao no longer needs an additional (1-ℵ) scaling. Requires the Jˢⁿ (interpolated snowfall) field from PR #4. --- src/Oceans/assemble_net_ocean_fluxes.jl | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/Oceans/assemble_net_ocean_fluxes.jl b/src/Oceans/assemble_net_ocean_fluxes.jl index a1b1d0dcd..b7e118e89 100644 --- a/src/Oceans/assemble_net_ocean_fluxes.jl +++ b/src/Oceans/assemble_net_ocean_fluxes.jl @@ -44,6 +44,7 @@ function update_net_ocean_fluxes!(coupled_model, ocean_model, grid) ℐꜜˡʷ = atmosphere_fields.ℐꜜˡʷ.data) freshwater_flux = atmosphere_fields.Jᶜ.data + snowfall_flux = atmosphere_fields.Jˢⁿ.data ice_concentration = sea_ice_concentration(sea_ice) ocean_surface_salinity = EarthSystemModels.ocean_surface_salinity(ocean_model) @@ -66,6 +67,7 @@ function update_net_ocean_fluxes!(coupled_model, ocean_model, grid) ice_concentration, downwelling_radiation, freshwater_flux, + snowfall_flux, atmos_ocean_properties, ocean_properties) @@ -83,6 +85,7 @@ end sea_ice_concentration, downwelling_radiation, freshwater_flux, + snowfall_flux, atmos_ocean_properties, ocean_properties) @@ -100,7 +103,8 @@ end Tₛ = ocean_surface_temperature[i, j, 1] Tₛ = convert_to_kelvin(ocean_properties.temperature_units, Tₛ) - Jᶜ = freshwater_flux[i, j, 1] # Prescribed freshwater (condensate) flux + Jᶜ = freshwater_flux[i, j, 1] # Total precipitation (rain + snow, positive down) + Jˢⁿ = snowfall_flux[i, j, 1] # Snow only (positive down) ℐꜜˢʷ = downwelling_radiation.ℐꜜˢʷ[i, j, 1] # Downwelling shortwave radiation ℐꜜˡʷ = downwelling_radiation.ℐꜜˡʷ[i, j, 1] # Downwelling longwave radiation 𝒬ᵀ = get_possibly_zero_flux(atmos_ocean_fluxes, :sensible_heat)[i, j, 1] # sensible or "conductive" heat flux @@ -133,16 +137,14 @@ end 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. + # Freshwater flux to the ocean per unit cell area (volume flux, positive up = leaving ocean). + # - Rain and rivers, reach the ocean everywhere (runs through cracks in ice or below ice) + # - Snow only reaches the ocean through the open-water fraction (1 - ℵ); + # snow on ice is routed to the sea ice model as snowfall + # - Evaporation is from the open-water fraction (1 - ℵ) ρᵒᶜ⁻¹ = 1 / ocean_properties.reference_density - ΣFao = - Jᶜ * ρᵒᶜ⁻¹ - - # Add the contribution from the turbulent water vapor flux, which has - # a different sign convention as the prescribed water mass fluxes (positive upwards) - Jᵛᵒᶜ = Jᵛ * ρᵒᶜ⁻¹ - ΣFao += Jᵛᵒᶜ + Jʳⁿ = Jᶜ - Jˢⁿ # remove snow since snow is multiplied by concentration (positive down) + ΣFao = - (Jʳⁿ + (1 - ℵᵢ) * Jˢⁿ) * ρᵒᶜ⁻¹ + (1 - ℵᵢ) * Jᵛ * ρᵒᶜ⁻¹ # Compute fluxes for u, v, T, and S from momentum, heat, and freshwater fluxes τˣ = net_ocean_fluxes.u @@ -173,6 +175,6 @@ end # Tracer fluxes Jᵀ[i, j, 1] = ifelse(inactive, zero(grid), Jᵀao + Jᵀio) # Jᵀao is already multiplied by the sea ice concentration - Jˢ[i, j, 1] = ifelse(inactive, zero(grid), (1 - ℵᵢ) * Jˢao + Jˢio) + Jˢ[i, j, 1] = ifelse(inactive, zero(grid), Jˢao + Jˢio) end end