Two dimensional turbulence example
In this example, we initialize a random velocity field and observe its turbulent decay in a two-dimensional domain. This example demonstrates:
- How to run a model with no buoyancy equation or tracers;
- How to create user-defined fields
- How to use differentiation functions
- How to save a computed field
Model setup
We instantiate the model with a simple isotropic diffusivity. We also use a 4-th order advection scheme and Runge-Kutta 3rd order time-stepping scheme.
using Oceananigans, Oceananigans.Advection
model = IncompressibleModel(
grid = RegularCartesianGrid(size=(128, 128, 1), halo=(2, 2, 2), extent=(2π, 2π, 2π)),
timestepper = :RungeKutta3,
advection = CenteredFourthOrder(),
buoyancy = nothing,
tracers = nothing,
closure = IsotropicDiffusivity(ν=1e-4)
)Setting initial conditions
Our initial condition randomizes u and v. We also ensure that both have zero mean for purely aesthetic reasons.
using Statistics
u₀ = rand(size(model.grid)...)
u₀ .-= mean(u₀)
set!(model, u=u₀, v=u₀)Calculating vorticity
using Oceananigans.Fields, Oceananigans.AbstractOperationsNext we create an object called an ComputedField that calculates vorticity. We'll use this object to calculate vorticity on-line and output it as the simulation progresses.
u, v, w = model.velocities
ω = ComputedField(∂x(v) - ∂y(u))Now we construct a simulation.
simulation = Simulation(model, Δt=0.1, stop_iteration=2000)Simulation{IncompressibleModel{CPU, Float64}}
├── Model clock: time = 0 seconds, iteration = 0
├── Next time step (Float64): 100 ms
├── Iteration interval: 1
├── Stop criteria: Any[Oceananigans.Simulations.iteration_limit_exceeded, Oceananigans.Simulations.stop_time_exceeded, Oceananigans.Simulations.wall_time_limit_exceeded]
├── Run time: 0 seconds, wall time limit: Inf
├── Stop time: Inf years, stop iteration: 2000
├── Diagnostics: OrderedCollections.OrderedDict with no entries
└── Output writers: OrderedCollections.OrderedDict with no entriesOutput
We set up an output writer for the simulation that saves the vorticity every 20 iterations.
using Oceananigans.OutputWriters
simulation.output_writers[:fields] =
JLD2OutputWriter(model, (ω = ω,), schedule=IterationInterval(20),
prefix = "2d_turbulence_vorticity", force = true)JLD2OutputWriter scheduled on IterationInterval(20):
├── filepath: ./2d_turbulence_vorticity.jld2
├── 1 outputs: (:ω,)
├── field slicer: FieldSlicer(:, :, :, with_halos=false)
├── array type: Array{Float32}
├── including: [:grid, :coriolis, :buoyancy, :closure]
└── max filesize: Inf YiBRunning the simulation
Finally, we run the simulation.
run!(simulation)[ Info: Simulation is stopping. Model iteration 2000 has hit or exceeded simulation stop iteration 2000.
Visualizing the results
We load the output and make a movie.
using JLD2
file = jldopen(simulation.output_writers[:fields].filepath)
iterations = parse.(Int, keys(file["timeseries/t"]))Construct the $x$, $y$ grid for plotting purposes,
using Oceananigans.Grids
x, y = xnodes(ω)[:], ynodes(ω)[:]and animate the vorticity.
using Plots
anim = @animate for iteration in iterations
ω_snapshot = file["timeseries/ω/$iteration"][:, :, 1]
heatmap(x, y, ω_snapshot',
xlabel="x", ylabel="y",
aspectratio=1,
color=:balance,
clims=(-0.2, 0.2),
xlims=(0, model.grid.Lx),
ylims=(0, model.grid.Ly))
endThis page was generated using Literate.jl.