Subfilter kinetic energy equation
The SubFilterKineticEnergyEquation module provides diagnostics for the kinetic energy budget of the subfilter scales: the scales that a low-pass spatial filter $\overline{(\,\cdot\,)}$ removes from the flow. It is the companion of the Filtered kinetic energy equation, which budgets the kinetic energy $e_k^l = \tfrac{1}{2}\,\bar u_i\,\bar u_i$ of the scales the filter keeps.
The subfilter kinetic energy budget
The subfilter kinetic energy is half the trace of the subfilter stress tensor $\tau^r_{ij} = \overline{u_i u_j} - \bar u_i \bar u_j$ (subfilter_stress_tensor),
\[e_k^s = \tfrac{1}{2}\,\tau^r_{ii} = \tfrac{1}{2}\left(\tau^r_{11} + \tau^r_{22} + \tau^r_{33}\right) ,\]
computed by SubFilterKineticEnergy. Following the filtering framework of Aluie et al. (2018), its volume-integrated budget (with the transport terms vanishing over a closed or periodic domain) reads
\[\frac{d}{dt} \int e_k^s\, \mathrm{d}V = \int \Pi_k\, \mathrm{d}V + \int \tau^l(w, b_r)\, \mathrm{d}V - \int \varepsilon_k^s\, \mathrm{d}V ,\]
with two sources and one sink:
- $\Pi_k$ (
KineticEnergyCrossScaleFlux) is the cross-scale kinetic-energy flux, the rate at which the filtered scales hand kinetic energy down to the subfilter scales. It is the sink of the filtered-flow budget and the source of this one. - $\tau^l(w, b_r) = \overline{w b_r} - \bar w\,b_r^l$ (
SubFilterAvailablePotentialToKineticEnergyConversion) is the subfilter buoyancy flux, which converts subfilter available potential energy into subfilter kinetic energy. It is defined in the Subfilter available potential energy equation, whose budget it is the sink of, and is re-exported here. - $\varepsilon_k^s = \overline{\varepsilon_k} - \varepsilon_k^l$ is the subfilter dissipation (
SubFilterKineticEnergyDissipationRate): the filtered total dissipation $\overline{\varepsilon_k}$ (KineticEnergyDissipationRate) minus the dissipation $\varepsilon_k^l$ of the filtered flow (FilteredKineticEnergyDissipationRate).
The Rayleigh-Taylor instability example closes this budget for a large-eddy simulation.
Subfilter kinetic energy
Oceanostics.SubFilterKineticEnergyEquation.SubFilterKineticEnergy — Type
SubFilterKineticEnergy(model, filter)
Return the subfilter-scale (SFS) kinetic energy eₖˢ, the kinetic energy carried by the scales that a low-pass filter removes from the flow — the filtered full kinetic energy minus the kinetic energy of the filtered flow:
eₖˢ = filter(eₖ) - eₖˡ , eₖ = ½ uᵢuᵢ , eₖˡ = ½ ūᵢūᵢ , ūᵢ = filter(uᵢ)equivalently eₖˢ = ½ τᵢᵢ with the subfilter stress τᵢⱼ = filter(uᵢuⱼ) - ūᵢūⱼ (filtering framework of Aluie et al., 2018, J. Phys. Oceanogr., doi:10.1175/JPO-D-17-0100.1). It is assembled from the full kinetic energy eₖ and FilteredKineticEnergy eₖˡ, which share the same interpolate-the-square (½⟨uᵢ²⟩) discretization, so the discrete decomposition filter(eₖ) = eₖˡ + eₖˢ holds exactly by construction (on any grid, not just where the filter and interpolation commute).
filter is any callable mapping a field to its low-pass-filtered counterpart, e.g. a reusable GaussianFilter or BoxFilter. The full kinetic energy is materialized as a Field before it is filtered (so the separable filter takes its fast staged path); the result lives at (Center, Center, Center), per unit mass (units m² s⁻²):
using Oceananigans, Oceanosticsgrid = RectilinearGrid(size=(4, 4, 4), extent=(1, 1, 1), topology=(Periodic, Periodic, Bounded))model = NonhydrostaticModel(grid)filter = GaussianFilter(; dims=(1, 2, 3), σ=0.1)SubFilterKineticEnergy(model, filter)# outputSubFilterKineticEnergy KernelFunctionOperation at (Center, Center, Center)├── grid: 4×4×4 RectilinearGrid{Float64, Periodic, Periodic, Bounded} on CPU with 3×3×3 halo├── kernel_function: subfilter_kinetic_energy_ccc (generic function with 1 method)└── arguments: ("Field", "Field", "Field", "Field")└── computes: subfilter kinetic energy ½τᵢᵢA convenience method SubFilterKineticEnergy(model; σ, dims, boundary, N) builds the Gaussian filter for you from a standard deviation σ (with σ = ℓ / (2√(2 ln 2)) for a FWHM ℓ).
Subfilter kinetic energy dissipation
Oceanostics.SubFilterKineticEnergyEquation.SubFilterKineticEnergyDissipationRate — Type
SubFilterKineticEnergyDissipationRate(model, filter)
Return the subfilter-scale (SFS) kinetic-energy dissipation rate εₖˢ, the viscous dissipation carried by the scales that a low-pass filter removes:
εₖˢ = filter(εₖ) - εₖˡwhere εₖ is the dissipation rate of the full flow (KineticEnergyDissipationRate) and εₖˡ is the dissipation rate of the filtered flow (FilteredKineticEnergyDissipationRate). It is the viscous sink in the budget of the subfilter kinetic energy eₖˢ (SubFilterKineticEnergy; filtering framework of Aluie et al., 2018, J. Phys. Oceanogr., doi:10.1175/JPO-D-17-0100.1). For a constant viscosity it reduces to 2ν[filter(SᵢⱼSᵢⱼ) - S̄ᵢⱼ S̄ᵢⱼ] ≥ 0, a strictly positive sink.
filter is any callable mapping a field to its low-pass-filtered counterpart, e.g. a reusable GaussianFilter or BoxFilter. Following the KineticEnergyCrossScaleFlux pattern, the result is a single KernelFunctionOperation whose kernel indexes a pre-assembled operation with materialized filtered Field leaves (the full-flow dissipation εₖ is materialized before it is filtered, and the filtered result is wrapped in a Field so the separable filter takes its fast staged path). It lives at (Center, Center, Center), per unit mass (units m² s⁻³). The model needs a closure whose viscous fluxes are defined, exactly as FilteredKineticEnergyDissipationRate requires:
using Oceananigans, Oceanosticsgrid = RectilinearGrid(size=(4, 4, 4), extent=(1, 1, 1), topology=(Periodic, Periodic, Bounded))model = NonhydrostaticModel(grid; closure=ScalarDiffusivity(ν=1e-4))filter = GaussianFilter(; dims=(1, 2, 3), σ=0.1)SubFilterKineticEnergyDissipationRate(model, filter)# outputSubFilterKineticEnergyDissipationRate KernelFunctionOperation at (Center, Center, Center)├── grid: 4×4×4 RectilinearGrid{Float64, Periodic, Periodic, Bounded} on CPU with 3×3×3 halo├── kernel_function: subfilter_ke_dissipation_rate_ccc (generic function with 1 method)└── arguments: ("Oceananigans.AbstractOperations.BinaryOperation",)└── computes: subfilter kinetic energy dissipation rate filter(εₖ) - εₖˡA convenience method SubFilterKineticEnergyDissipationRate(model; σ, dims, boundary, N) builds the Gaussian filter for you from a standard deviation σ (with σ = ℓ / (2√(2 ln 2)) for a FWHM ℓ).