Skip to content

Closing Kinetic Energy budget #170

@zhihua-zheng

Description

@zhihua-zheng

This is meant to be a discussion. I need some help to interpret my KE ($k = u_i u_i /2$) budget calculations, which follow this equation:

$$\frac{\partial k}{\partial t} = -\frac{\partial u_j k}{\partial x_j} - \frac{\partial u_i p}{\partial x_i} + u_i b_i - u_i\frac{\partial \tau_{ij}}{\partial x_j}$$

These 5 terms correspond to the KineticEnergyTendency, AdvectionTerm, PressureRedistributionTerm, BuoyancyProductionTerm, KineticEnergyStressTerm in Oceanostics' TKEBudgetTerms, respectively.

When integrated in volume for the entire domain, this becomes

$$\frac{\partial (\int k dV)}{\partial t} = -\int u_j k \cdot n_j dS - \int u_i p \cdot n_i dS + \int u_i b_i dV - \int u_i\frac{\partial \tau_{ij}}{\partial x_j} dV$$

For horizontally periodic, vertically bounded domain, the integrated AdvectionTerm and PressureRedistributionTerm should be zero.

This is the code I used:

using Oceananigans
using Oceananigans.Units: minutes, days
using Statistics
using Oceanostics
using Oceanostics.TKEBudgetTerms: KineticEnergyTendency, AdvectionTerm, KineticEnergyStressTerm,
                                  PressureRedistributionTerm, BuoyancyProductionTerm

grid = RectilinearGrid(GPU(), size=(32, 32, 32), extent=(128, 128, 64),
                       topology=(Periodic, Periodic, Bounded))

const hᵢ = 20
const Qᵘ = -3.72e-5
const= 1.936e-5 # s⁻², initial and bottom buoyancy gradient
b_boundary_conditions = FieldBoundaryConditions(bottom = GradientBoundaryCondition(N²))
u_boundary_conditions = FieldBoundaryConditions(top = FluxBoundaryCondition(Qᵘ))

model = NonhydrostaticModel(; grid,
                            advection = WENO(),
                            timestepper = :RungeKutta3,
                            tracers = :b,
                            buoyancy = BuoyancyTracer(),
                            closure = AnisotropicMinimumDissipation(),
                            boundary_conditions = (b=b_boundary_conditions, u=u_boundary_conditions))

@inline Ξ(z) = randn() * exp(z / 4)
@inline stratification(z) = z < - hᵢ ?* z :* (-hᵢ)
@inline bᵢ(x, y, z) = stratification(z) + 1e-1 * Ξ(z) ** model.grid.Lz
@inline uᵢ(x, y, z) = 1e-1 * Ξ(z)
@inline wᵢ(x, y, z) = 1e-1 * Ξ(z)
set!(model, u=uᵢ, w=wᵢ, b=bᵢ)

simulation = Simulation(model, Δt=45, stop_time=2days)
wizard = TimeStepWizard(cfl=0.65, diffusive_cfl=0.65)
simulation.callbacks[:wizard] = Callback(wizard, IterationInterval(5))

## KE budget using resolved velocities
KE = Field(Integral(KineticEnergy(model)))
KE_tendency = Field(Integral(KineticEnergyTendency(model)))
KE_advection = Field(Integral(AdvectionTerm(model)))
KE_stress = Field(Integral(KineticEnergyStressTerm(model)))
KE_pressure = Field(Integral(PressureRedistributionTerm(model)))
KE_buoyancy = Field(Integral(BuoyancyProductionTerm(model)))
outputs = (; KE, KE_tendency, KE_advection, KE_stress, KE_pressure, KE_buoyancy)

output_interval = 5minutes 
simulation.output_writers[:fields] =
     NetCDFOutputWriter(model, outputs,
                     schedule = TimeInterval(output_interval),
                     filename = "mwe_KE_budget.nc",
                     overwrite_existing = true)
run!(simulation)

mwe_KE_budgets

The result from the simulation is shown above. The residual is nearly 0. I mainly have two points of confusion:

  1. The nonzero integral of AdvectionTerm conflicts with what I imagined from the equation.
  2. The KineticEnergyTendency being mostly negative conflicts with the fact that the integral of KE grows with time.

I could have overlooked something here, please let me know what you think.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions