-
Notifications
You must be signed in to change notification settings - Fork 6
Add meridional heat transport diagnostic via ocean heat uptake method #89
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
1c09a4d
2cc2ca9
ff5c5a7
ed0fccd
9fa7f18
c1ff6e8
079d4e3
0bb0c13
7108fa5
8976ca4
dadec35
c65cde6
762fded
4b7a2b6
ca29e04
8f8232a
bbb39bf
73ad7d5
c5a2560
a09ee3a
56322f4
c5da190
2a23b79
841607a
b8c0022
c815495
38d18ab
77d518a
59073a2
81d1cff
cafa9c6
f650205
11106cc
eb920b8
84ab336
5260063
411e5b3
c646272
8f1340f
84e1a99
17cdf75
8563019
59f1bdb
576d0bc
9b18f26
34332ed
94ca98a
d1b8174
2d74185
dda8eb2
6e4794b
b7b924a
d505092
ad87f02
20dea9a
61bded3
72d9e4f
032c9c9
9a3ee99
8863581
ba466fd
545be9b
d4e1d1a
cadcdd8
bde7d08
46efae2
5f4558f
45eb5c6
debc404
368d6a1
45a6601
898b811
c369138
9c608e2
658923d
8db34f8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,20 +1,16 @@ | ||
| using Oceananigans.TimeSteppers: SplitRungeKuttaTimeStepper, QuasiAdamsBashforth2TimeStepper | ||
| using ..EarthSystemModels: EarthSystemModel, reference_density, heat_capacity | ||
|
|
||
| struct MeridionalFluxMethod end | ||
| struct TendencyMethod end | ||
|
|
||
| """ | ||
| meridional_heat_transport(esm::EarthSystemModel; | ||
| meridional_heat_transport(esm::EarthSystemModel, MeridionalFluxMethod(); | ||
| reference_temperature = 0) | ||
|
|
||
| Return the meridional heat transport for the coupled `esm::EarthSystemModel` by computing | ||
| the meridional heat flux. | ||
|
|
||
| The meridional heat transport is computed via: | ||
|
|
||
| ```math | ||
| \\mathrm{MHT} ≡ ρᵒᶜ cᵒᶜ ∫ v (T - T_{\\rm ref}) \\, \\mathrm{d}x \\, \\mathrm{d}z | ||
| ``` | ||
|
|
||
| Above, ``T_{\\rm ref}`` is a reference temperature and ``ρᵒᶜ`` and ``cᵒᶜ`` are the | ||
| ocean reference density and specific heat capacity respectively. | ||
| Return the meridional heat transport for the coupled `esm::EarthSystemModel` using either | ||
| two methods: either by directly computing the meridional heat flux or indirectly using | ||
| the total ocean heat content and the ocean heat uptake. | ||
|
|
||
| !!! warning "Only works on LatitudeLongitudeGrid" | ||
|
|
||
|
|
@@ -26,11 +22,93 @@ Arguments | |
|
|
||
| * `esm`: An EarthSystemModel. | ||
|
|
||
| * The method for the computation. Available options are: `MeridionalFluxMethod()` (default) | ||
| and `TendencyMethod()`. | ||
|
|
||
| `MeridionalFluxMethod()` computes the meridional heat transport directly by summing | ||
| the meridional heat flux; `TendencyMethod()` computes the meridional heat | ||
| transport indirectly using the ocean heat content. | ||
|
|
||
| 1. For `MeridionalFluxMethod()`, the meridional heat transport is computed via: | ||
|
|
||
| ```math | ||
| \\mathrm{MHT} ≡ ρᵒᶜ cᵒᶜ ∫ v (T - T_{\\rm ref}) \\, \\mathrm{d}x \\, \\mathrm{d}z | ||
| ``` | ||
|
|
||
| Above, ``T_{\\rm ref}`` is a reference temperature and ``ρᵒᶜ`` and ``cᵒᶜ`` are the | ||
| ocean reference density and specific heat capacity respectively. | ||
|
|
||
| 2. For `TendencyMethod()` we have: | ||
|
|
||
| Let ``T`` be three-dimensional (potential) temperature, ``ρᵒᶜ`` the ocean reference | ||
| density, ``cᵒᶜ`` the specific heat capacity, ``H`` the resting depth, and ``η`` the | ||
| free-surface elevation. | ||
|
|
||
| The column heat content per unit horizontal area (units of J m⁻²) is: | ||
|
|
||
| ```math | ||
| ℋ = ρᵒᶜ cᵒᶜ ∫_{-H}^{η} T \\, \\mathrm{d}z | ||
| ``` | ||
|
|
||
| and its time-derivative is a heat flux, ``𝒬 ≡ ∂ℋ/∂t``. | ||
|
|
||
| The vertically-integrated heat budget is | ||
|
|
||
| ```math | ||
| 𝒬 = \\frac{∂ℋ}{∂t} = - \\boldsymbol{∇}_h \\cdot \\boldsymbol{F}_h - 𝒬ᵃᵒ_{\\rm net} + ℛ | ||
| ``` | ||
|
|
||
| where | ||
|
|
||
| * ``\\boldsymbol{F}_h`` is the depth-integrated horizontal heat flux vector (units W m⁻¹), | ||
| that includes advection and any parameterized lateral/eddy fluxes, | ||
| * ``𝒬ᵃᵒ_{\\rm net}`` is the [net ocean surface heat flux](@ref NumericalEarth.Diagnostics.net_ocean_heat_flux) | ||
| (units W m⁻²), and | ||
| * ``ℛ`` is the residual sources/sinks and non-closed terms (e.g. numerics, unaccounted | ||
| physics, mass/volume effects). | ||
|
|
||
| The total ocean heat content (OHC) South of latitude ``φ`` is: | ||
|
|
||
| ```math | ||
| \\mathrm{OHC}_S(φ, t) ≡ ∫_{A(φ)} ℋ \\, \\mathrm{d}A | ||
| ``` | ||
|
|
||
| where ``A(φ)`` is the ocean area South of latitude ``φ``. | ||
|
|
||
| Integrating the vertically-integrated heat budget over ``A(φ)`` and using the divergence | ||
| theorem we get | ||
|
|
||
| ```math | ||
| \\frac{\\mathrm{d}}{\\mathrm{d}t} \\, \\mathrm{OHC}_S(φ, t) = | ||
| - ∮_{∂A(φ)} \\boldsymbol{F}_h \\cdot \\hat{\\boldsymbol{n}} \\, \\mathrm{d}ℓ | ||
| - ∫_{A(φ)} 𝒬ᵃᵒ_{\\rm net} \\, \\mathrm{d}A | ||
| + ∫_{A(φ)} ℛ \\, \\mathrm{d}A | ||
| ``` | ||
|
|
||
| where ``∂A(φ)`` is the boundary of ``A(φ)``, i.e., the circle at latitude ``φ``. | ||
|
|
||
| The northward meridional heat transport across latitude ``φ`` is | ||
|
|
||
| ```math | ||
| \\mathrm{MHT}(φ, t) ≡ ∮_{\\mathrm{lat}=φ} \\boldsymbol{F}_h \\cdot \\hat{\\boldsymbol{n}} \\, \\mathrm{d}ℓ | ||
| ``` | ||
|
|
||
| with the understanding that ``\\mathrm{MHT} > 0`` implies northward heat transport. | ||
|
|
||
| Ignoring the residual ``ℛ``, the OHC-based diagnostic relation is | ||
|
|
||
| ```math | ||
| \\begin{align*} | ||
| \\mathrm{MHT} & = - ∫_{A(φ)} 𝒬ᵃᵒ_{\\rm net} \\, \\mathrm{d}A | ||
| - \\frac{\\mathrm{d}}{\\mathrm{d}t} \\, \\mathrm{OHC}_S \\\\ | ||
| & = - ∫_{A(φ)} \\left( 𝒬ᵃᵒ_{\\rm net} + 𝒬 \\right) \\, \\mathrm{d}A | ||
| \\end{align*} | ||
| ``` | ||
|
|
||
| Keyword Arguments | ||
| ================= | ||
|
|
||
| * `reference_temperature`: The reference temperature (in ᵒC) used for the calculation; default: 0 ᵒC. | ||
| * `reference_temperature`: The reference temperature (in ᵒC) used for `MeridionalFluxMethod()`; default: 0 ᵒC. | ||
|
|
||
| !!! info "Reference temperature" | ||
|
|
||
|
|
@@ -72,7 +150,8 @@ Integral of BinaryOperation at (Center, Face, Center) over dims (1, 3) | |
| └── grid: 4×5×2 RectilinearGrid{Float64, Periodic, Bounded, Bounded} on CPU with 3×3×2 halo | ||
| ``` | ||
| """ | ||
| function meridional_heat_transport(esm::EarthSystemModel; reference_temperature=0) | ||
| function meridional_heat_transport(esm::EarthSystemModel, method=MeridionalFluxMethod(); | ||
| reference_temperature=0) | ||
|
|
||
| grid = esm.ocean.model.grid | ||
|
|
||
|
|
@@ -81,15 +160,48 @@ function meridional_heat_transport(esm::EarthSystemModel; reference_temperature= | |
| grid isa OrthogonalSphericalShellGrid && | ||
| throw(ArgumentError("meridional_heat_transport diagnostic does not work on OrthogonalSphericalShellGrid at the moment; use LatitudeLongitudeGrid.")) | ||
|
|
||
| FT = eltype(esm) | ||
| reference_temperature = convert(FT, reference_temperature) | ||
| if method isa MeridionalFluxMethod | ||
| FT = eltype(esm) | ||
| reference_temperature = convert(FT, reference_temperature) | ||
| return meridional_heat_transport_via_meridional_heat_flux(esm; reference_temperature) | ||
| elseif method isa TendencyMethod | ||
| @warn """ | ||
| Computing the meridional heat transport via the TendencyMethod | ||
| does not ensure the heat budget is closed! | ||
| If you require a closed heat budget, then use the MeridionalFluxMethod. | ||
| """ | ||
| return meridional_heat_transport_via_ocean_heat_content(esm) | ||
| else | ||
| throw(ArgumentError("Unknown method $(method); choose either MeridionalFluxMethod() or TendencyMethod().")) | ||
| end | ||
| end | ||
|
|
||
| function meridional_heat_transport_via_meridional_heat_flux(esm; reference_temperature) | ||
| ρᵒᶜ = reference_density(esm.ocean) | ||
| cᵒᶜ = heat_capacity(esm.ocean) | ||
|
|
||
| T = esm.ocean.model.tracers.T | ||
| v = esm.ocean.model.velocities.v | ||
|
|
||
| MHT = Integral(ρᵒᶜ * cᵒᶜ * v * (T - reference_temperature), dims=(1, 3)) | ||
| return MHT | ||
| end | ||
|
|
||
| function meridional_heat_transport_via_ocean_heat_content(esm) | ||
| ρᵒᶜ = reference_density(esm.ocean) | ||
| cᵒᶜ = heat_capacity(esm.ocean) | ||
| ∂t_T = temperature_tendency(esm.ocean.model.timestepper) | ||
| 𝒬ᵃᵒₙₑₜ = net_ocean_heat_flux(esm) |> Field | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what is the difference between
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it's part of the discussion why the budget doesn't close; there might be a difference or there may be a double counting of some parts. But if there isn't any in the end, we should drop the "net". |
||
|
|
||
| 𝒬 = Integral(ρᵒᶜ * cᵒᶜ * ∂t_T, dims=3) |> Field | ||
| ∫Σ𝒬_dx = Integral(𝒬ᵃᵒₙₑₜ + 𝒬, dims=1) |> Field | ||
| MHT = CumulativeIntegral(- ∫Σ𝒬_dx, dims=2) | ||
| return MHT | ||
| end | ||
|
navidcy marked this conversation as resolved.
|
||
|
|
||
| temperature_tendency(timestepper::SplitRungeKuttaTimeStepper) = timestepper.Gⁿ.T | ||
|
|
||
| function temperature_tendency(timestepper::QuasiAdamsBashforth2TimeStepper) | ||
| Gᵀⁿ = timestepper.Gⁿ.T | ||
| Gᵀ⁻ = timestepper.G⁻.T | ||
| χ = timestepper.χ | ||
| return (3/2 + χ) * Gᵀⁿ - (1/2 + χ) * Gᵀ⁻ | ||
| end | ||
Uh oh!
There was an error while loading. Please reload this page.