Wind- and convection-driven mixing in an ocean surface boundary layer
This example simulates mixing by three-dimensional turbulence in an ocean surface boundary layer driven by atmospheric winds and convection. It demonstrates:
- How to set-up a grid with varying spacing in the vertical direction
- How to use the
SeawaterBuoyancymodel for buoyancy withTEOS10EquationOfState. - How to use a turbulence closure for large eddy simulation.
- How to use a function to impose a boundary condition.
Install dependencies
First let's make sure we have all required packages installed.
using Pkg
pkg"add Oceananigans, CairoMakie, SeawaterPolynomials, CUDA"We start by importing all of the packages and functions that we'll need for this example.
using Oceananigans
using Oceananigans.Units
using CUDA
using Random
using Printf
using CairoMakie
using SeawaterPolynomials.TEOS10: TEOS10EquationOfStateThe grid
We use 128²×64 grid points with 1 m grid spacing in the horizontal and varying spacing in the vertical, with higher resolution closer to the surface. Here we use a stretching function for the vertical nodes that maintains relatively constant vertical spacing in the mixed layer, which is desirable from a numerical standpoint:
Nx = Ny = 128 # number of points in each of horizontal directions
Nz = 64 # number of points in the vertical direction
Lx = Ly = 128 # (m) domain horizontal extents
Lz = 64 # (m) domain depth
refinement = 1.2 # controls spacing near surface (higher means finer spaced)
stretching = 12 # controls rate of stretching at bottom
# Normalized height ranging from 0 to 1
h(k) = (k - 1) / Nz
# Linear near-surface generator
ζ₀(k) = 1 + (h(k) - 1) / refinement
# Bottom-intensified stretching function
Σ(k) = (1 - exp(-stretching * h(k))) / (1 - exp(-stretching))
# Generating function
z_interfaces(k) = Lz * (ζ₀(k) * Σ(k) - 1)
grid = RectilinearGrid(GPU(),
size = (Nx, Nx, Nz),
x = (0, Lx),
y = (0, Ly),
z = z_interfaces)128×128×64 RectilinearGrid{Float64, Periodic, Periodic, Bounded} on CUDAGPU with 3×3×3 halo
├── Periodic x ∈ [0.0, 128.0) regularly spaced with Δx=1.0
├── Periodic y ∈ [0.0, 128.0) regularly spaced with Δy=1.0
└── Bounded z ∈ [-64.0, 0.0] variably spaced with min(Δz)=0.833413, max(Δz)=1.96618We plot vertical spacing versus depth to inspect the prescribed grid stretching:
fig = Figure(size=(1200, 800))
ax = Axis(fig[1, 1], ylabel = "z (m)", xlabel = "Vertical spacing (m)")
lines!(ax, zspacings(grid, Center()))
scatter!(ax, zspacings(grid, Center()))
figBuoyancy that depends on temperature and salinity
We use the SeawaterBuoyancy model with the TEOS10 equation of state,
ρₒ = 1026 # kg m⁻³, average density at the surface of the world ocean
equation_of_state = TEOS10EquationOfState(reference_density=ρₒ)
buoyancy = SeawaterBuoyancy(; equation_of_state)SeawaterBuoyancy{Float64}:
├── gravitational_acceleration: 9.80665
└── equation_of_state: BoussinesqEquationOfState{Float64}Boundary conditions
We calculate the surface temperature flux associated with surface cooling of 200 W m⁻², reference density ρₒ, and heat capacity cᴾ,
Q = 200 # W m⁻², surface _heat_ flux
cᴾ = 3991 # J K⁻¹ kg⁻¹, typical heat capacity for seawater
Jᵀ = Q / (ρₒ * cᴾ) # K m s⁻¹, surface _temperature_ flux4.884283985946938e-5Finally, we impose a temperature gradient dTdz both initially (see "Initial conditions" section below) and at the bottom of the domain, culminating in the boundary conditions on temperature,
dTdz = 0.01 # K m⁻¹
T_bcs = FieldBoundaryConditions(top = FluxBoundaryCondition(Jᵀ),
bottom = GradientBoundaryCondition(dTdz))Oceananigans.FieldBoundaryConditions, with boundary conditions
├── west: DefaultBoundaryCondition (FluxBoundaryCondition: Nothing)
├── east: DefaultBoundaryCondition (FluxBoundaryCondition: Nothing)
├── south: DefaultBoundaryCondition (FluxBoundaryCondition: Nothing)
├── north: DefaultBoundaryCondition (FluxBoundaryCondition: Nothing)
├── bottom: GradientBoundaryCondition: 0.01
├── top: FluxBoundaryCondition: 4.88428e-5
└── immersed: DefaultBoundaryCondition (FluxBoundaryCondition: Nothing)Note that a positive temperature flux at the surface of the ocean implies cooling. This is because a positive temperature flux implies that temperature is fluxed upwards, out of the ocean.
For the velocity field, we imagine a wind blowing over the ocean surface with an average velocity at 10 meters u₁₀, and use a drag coefficient cᴰ to estimate the kinematic stress (that is, stress divided by density) exerted by the wind on the ocean:
u₁₀ = 10 # m s⁻¹, average wind velocity 10 meters above the ocean
cᴰ = 2e-3 # dimensionless drag coefficient
ρₐ = 1.2 # kg m⁻³, approximate average density of air at sea-level
τx = - ρₐ / ρₒ * cᴰ * u₁₀ * abs(u₁₀) # m² s⁻²-0.00023391812865497074The boundary conditions on u are thus
u_bcs = FieldBoundaryConditions(top = FluxBoundaryCondition(τx))Oceananigans.FieldBoundaryConditions, with boundary conditions
├── west: DefaultBoundaryCondition (FluxBoundaryCondition: Nothing)
├── east: DefaultBoundaryCondition (FluxBoundaryCondition: Nothing)
├── south: DefaultBoundaryCondition (FluxBoundaryCondition: Nothing)
├── north: DefaultBoundaryCondition (FluxBoundaryCondition: Nothing)
├── bottom: DefaultBoundaryCondition (FluxBoundaryCondition: Nothing)
├── top: FluxBoundaryCondition: -0.000233918
└── immersed: DefaultBoundaryCondition (FluxBoundaryCondition: Nothing)For salinity, S, we impose an evaporative flux of the form
@inline Jˢ(x, y, t, S, evaporation_rate) = - evaporation_rate * S # [salinity unit] m s⁻¹where S is salinity. We use an evaporation rate of 1 millimeter per hour,
evaporation_rate = 1e-3 / hour # m s⁻¹2.7777777777777776e-7We build the Flux evaporation BoundaryCondition with the function Jˢ, indicating that Jˢ depends on salinity S and passing the parameter evaporation_rate,
evaporation_bc = FluxBoundaryCondition(Jˢ, field_dependencies=:S, parameters=evaporation_rate)FluxBoundaryCondition: ContinuousBoundaryFunction Jˢ at (Nothing, Nothing, Nothing)The full salinity boundary conditions are
S_bcs = FieldBoundaryConditions(top=evaporation_bc)Oceananigans.FieldBoundaryConditions, with boundary conditions
├── west: DefaultBoundaryCondition (FluxBoundaryCondition: Nothing)
├── east: DefaultBoundaryCondition (FluxBoundaryCondition: Nothing)
├── south: DefaultBoundaryCondition (FluxBoundaryCondition: Nothing)
├── north: DefaultBoundaryCondition (FluxBoundaryCondition: Nothing)
├── bottom: DefaultBoundaryCondition (FluxBoundaryCondition: Nothing)
├── top: FluxBoundaryCondition: ContinuousBoundaryFunction Jˢ at (Nothing, Nothing, Nothing)
└── immersed: DefaultBoundaryCondition (FluxBoundaryCondition: Nothing)Model instantiation
We fill in the final details of the model here, i.e., Coriolis forces, and use the (scale-invariant) DynamicSmagorinsky closure for large eddy simulation to model the effect of turbulent motions at scales smaller than the grid scale that are not explicitly resolved.
model = NonhydrostaticModel(grid; buoyancy,
tracers = (:T, :S),
coriolis = FPlane(f=1e-4),
closure = DynamicSmagorinsky(),
boundary_conditions = (u=u_bcs, T=T_bcs, S=S_bcs))NonhydrostaticModel{CUDAGPU, RectilinearGrid}(time = 0 seconds, iteration = 0)
├── grid: 128×128×64 RectilinearGrid{Float64, Periodic, Periodic, Bounded} on CUDAGPU with 3×3×3 halo
├── timestepper: RungeKutta3TimeStepper
├── advection scheme: Centered(order=2)
├── tracers: (T, S)
├── closure: Smagorinsky with coefficient = DynamicCoefficient(averaging = LagrangianAveraging(), schedule = IterationInterval(1, 0)), Pr=(T = 1.0, S = 1.0)
├── buoyancy: SeawaterBuoyancy with g=9.80665 and BoussinesqEquationOfState{Float64} with ĝ = NegativeZDirection()
└── coriolis: FPlane{Float64}(f=0.0001)Note: To use the (constant-coefficient) Smagorinsky-Lilly turbulence closure rather than DynamicSmagorinsky, use closure = SmagorinskyLilly() in the model constructor.
Initial conditions
Our initial condition for temperature consists of a linear stratification superposed with random noise damped at the walls, while our initial condition for velocity consists only of random noise.
# Random noise damped at top and bottom
Ξ(z) = randn() * z / model.grid.Lz * (1 + z / model.grid.Lz) # noise
# Temperature initial condition: a stable density gradient with random noise superposed.
Tᵢ(x, y, z) = 20 + dTdz * z + dTdz * model.grid.Lz * 1e-6 * Ξ(z)
# Velocity initial condition: random noise scaled by the friction velocity.
uᵢ(x, y, z) = sqrt(abs(τx)) * 1e-3 * Ξ(z)
# `set!` the `model` fields using functions or constants:
set!(model, u=uᵢ, w=uᵢ, T=Tᵢ, S=35)Setting up a simulation
We set-up a simulation with an initial time-step of 10 seconds that stops at 2 hours, with adaptive time-stepping and progress printing.
simulation = Simulation(model, Δt=10, stop_time=2hours)Simulation of NonhydrostaticModel{CUDAGPU, RectilinearGrid}(time = 0 seconds, iteration = 0)
├── Next time step: 10 seconds
├── run_wall_time: 0 seconds
├── run_wall_time / iteration: NaN days
├── stop_time: 2 hours
├── stop_iteration: Inf
├── wall_time_limit: Inf
├── minimum_relative_step: 0.0
├── callbacks: OrderedDict with 4 entries:
│ ├── stop_time_exceeded => Callback of stop_time_exceeded on IterationInterval(1)
│ ├── stop_iteration_exceeded => Callback of stop_iteration_exceeded on IterationInterval(1)
│ ├── wall_time_limit_exceeded => Callback of wall_time_limit_exceeded on IterationInterval(1)
│ └── nan_checker => Callback of NaNChecker for u on IterationInterval(100)
└── output_writers: OrderedDict with no entriesThe TimeStepWizard helps ensure stable time-stepping with a Courant-Freidrichs-Lewy (CFL) number of 0.7.
conjure_time_step_wizard!(simulation, cfl=0.7)Nice progress messaging is helpful:
# Print a progress message
progress_message(sim) = @printf("Iteration: %04d, time: %s, Δt: %s, max(|w|) = %.1e ms⁻¹, wall time: %s\n",
iteration(sim), prettytime(sim), prettytime(sim.Δt),
maximum(abs, sim.model.velocities.w), prettytime(sim.run_wall_time))
add_callback!(simulation, progress_message, IterationInterval(40))We then set up the simulation:
Output
We use the JLD2Writer to save $x, z$ slices of the velocity fields, tracer fields, and eddy diffusivities. The prefix keyword argument to JLD2Writer indicates that output will be saved in ocean_wind_mixing_and_convection.jld2.
# Create a NamedTuple with eddy viscosity
eddy_viscosity = (; νₑ = model.closure_fields.νₑ)
filename = "ocean_wind_mixing_and_convection"
simulation.output_writers[:slices] =
JLD2Writer(model, merge(model.velocities, model.tracers, eddy_viscosity),
filename = filename * ".jld2",
indices = (:, grid.Ny/2, :),
schedule = TimeInterval(1minute),
overwrite_existing = true)JLD2Writer scheduled on TimeInterval(1 minute):
├── filepath: ocean_wind_mixing_and_convection.jld2
├── 6 outputs: (u, v, w, T, S, νₑ)
├── array_type: Array{Float32}
├── including: [:grid, :coriolis, :buoyancy, :closure]
├── file_splitting: NoFileSplitting
└── file size: 0 bytes (file not yet created)We're ready:
run!(simulation)[ Info: Initializing simulation...
Iteration: 0000, time: 0 seconds, Δt: 11 seconds, max(|w|) = 1.4e-05 ms⁻¹, wall time: 0 seconds
[ Info: ... simulation initialization complete (15.376 seconds)
[ Info: Executing initial time step...
[ Info: ... initial time step complete (9.249 seconds).
Iteration: 0040, time: 6.394 minutes, Δt: 6.380 seconds, max(|w|) = 7.2e-06 ms⁻¹, wall time: 28.016 seconds
Iteration: 0080, time: 9.825 minutes, Δt: 4.112 seconds, max(|w|) = 9.9e-06 ms⁻¹, wall time: 31.698 seconds
Iteration: 0120, time: 12.230 minutes, Δt: 3.281 seconds, max(|w|) = 1.0e-05 ms⁻¹, wall time: 35.413 seconds
Iteration: 0160, time: 14.242 minutes, Δt: 2.802 seconds, max(|w|) = 9.2e-06 ms⁻¹, wall time: 39.232 seconds
Iteration: 0200, time: 15.999 minutes, Δt: 2.482 seconds, max(|w|) = 7.7e-06 ms⁻¹, wall time: 42.880 seconds
Iteration: 0240, time: 17.542 minutes, Δt: 2.254 seconds, max(|w|) = 1.2e-05 ms⁻¹, wall time: 46.674 seconds
Iteration: 0280, time: 18.971 minutes, Δt: 2.077 seconds, max(|w|) = 1.9e-05 ms⁻¹, wall time: 50.337 seconds
Iteration: 0320, time: 20.295 minutes, Δt: 1.934 seconds, max(|w|) = 4.3e-05 ms⁻¹, wall time: 53.646 seconds
Iteration: 0360, time: 21.526 minutes, Δt: 1.816 seconds, max(|w|) = 9.8e-05 ms⁻¹, wall time: 56.639 seconds
Iteration: 0400, time: 22.703 minutes, Δt: 1.714 seconds, max(|w|) = 2.1e-04 ms⁻¹, wall time: 59.882 seconds
Iteration: 0440, time: 23.806 minutes, Δt: 1.626 seconds, max(|w|) = 3.9e-04 ms⁻¹, wall time: 1.060 minutes
Iteration: 0480, time: 24.848 minutes, Δt: 1.547 seconds, max(|w|) = 7.4e-04 ms⁻¹, wall time: 1.115 minutes
Iteration: 0520, time: 25.857 minutes, Δt: 1.471 seconds, max(|w|) = 1.5e-03 ms⁻¹, wall time: 1.176 minutes
Iteration: 0560, time: 26.815 minutes, Δt: 1.397 seconds, max(|w|) = 3.0e-03 ms⁻¹, wall time: 1.245 minutes
Iteration: 0600, time: 27.726 minutes, Δt: 1.319 seconds, max(|w|) = 5.8e-03 ms⁻¹, wall time: 1.308 minutes
Iteration: 0640, time: 28.574 minutes, Δt: 1.230 seconds, max(|w|) = 1.0e-02 ms⁻¹, wall time: 1.358 minutes
Iteration: 0680, time: 29.349 minutes, Δt: 1.125 seconds, max(|w|) = 1.5e-02 ms⁻¹, wall time: 1.407 minutes
Iteration: 0720, time: 30.070 minutes, Δt: 1.027 seconds, max(|w|) = 2.3e-02 ms⁻¹, wall time: 1.484 minutes
Iteration: 0760, time: 30.735 minutes, Δt: 938.397 ms, max(|w|) = 3.2e-02 ms⁻¹, wall time: 1.547 minutes
Iteration: 0800, time: 31.324 minutes, Δt: 851.471 ms, max(|w|) = 3.9e-02 ms⁻¹, wall time: 1.621 minutes
Iteration: 0840, time: 31.849 minutes, Δt: 537.933 ms, max(|w|) = 3.4e-01 ms⁻¹, wall time: 1.684 minutes
Iteration: 0880, time: 32.202 minutes, Δt: 449.732 ms, max(|w|) = 4.1e-01 ms⁻¹, wall time: 1.737 minutes
Iteration: 0920, time: 32.495 minutes, Δt: 378.028 ms, max(|w|) = 6.1e-01 ms⁻¹, wall time: 1.805 minutes
Iteration: 0960, time: 32.749 minutes, Δt: 331.245 ms, max(|w|) = 5.8e-01 ms⁻¹, wall time: 1.874 minutes
Iteration: 1000, time: 32.978 minutes, Δt: 339.460 ms, max(|w|) = 6.0e-01 ms⁻¹, wall time: 1.926 minutes
Iteration: 1040, time: 33.220 minutes, Δt: 396.891 ms, max(|w|) = 6.0e-01 ms⁻¹, wall time: 1.989 minutes
Iteration: 1080, time: 33.475 minutes, Δt: 358.088 ms, max(|w|) = 6.2e-01 ms⁻¹, wall time: 2.040 minutes
Iteration: 1120, time: 33.715 minutes, Δt: 406.611 ms, max(|w|) = 6.7e-01 ms⁻¹, wall time: 2.096 minutes
Iteration: 1160, time: 33.970 minutes, Δt: 404.156 ms, max(|w|) = 6.1e-01 ms⁻¹, wall time: 2.146 minutes
Iteration: 1200, time: 34.241 minutes, Δt: 460.566 ms, max(|w|) = 6.3e-01 ms⁻¹, wall time: 2.197 minutes
Iteration: 1240, time: 34.544 minutes, Δt: 460.138 ms, max(|w|) = 6.6e-01 ms⁻¹, wall time: 2.248 minutes
Iteration: 1280, time: 34.851 minutes, Δt: 476.165 ms, max(|w|) = 6.5e-01 ms⁻¹, wall time: 2.304 minutes
Iteration: 1320, time: 35.170 minutes, Δt: 491.057 ms, max(|w|) = 5.9e-01 ms⁻¹, wall time: 2.357 minutes
Iteration: 1360, time: 35.503 minutes, Δt: 509.165 ms, max(|w|) = 5.8e-01 ms⁻¹, wall time: 2.406 minutes
Iteration: 1400, time: 35.846 minutes, Δt: 531.923 ms, max(|w|) = 5.5e-01 ms⁻¹, wall time: 2.455 minutes
Iteration: 1440, time: 36.200 minutes, Δt: 577.747 ms, max(|w|) = 4.7e-01 ms⁻¹, wall time: 2.508 minutes
Iteration: 1480, time: 36.581 minutes, Δt: 547.537 ms, max(|w|) = 4.9e-01 ms⁻¹, wall time: 2.564 minutes
Iteration: 1520, time: 36.952 minutes, Δt: 593.578 ms, max(|w|) = 5.4e-01 ms⁻¹, wall time: 2.613 minutes
Iteration: 1560, time: 37.338 minutes, Δt: 543.414 ms, max(|w|) = 5.0e-01 ms⁻¹, wall time: 2.662 minutes
Iteration: 1600, time: 37.735 minutes, Δt: 576.771 ms, max(|w|) = 5.6e-01 ms⁻¹, wall time: 2.712 minutes
Iteration: 1640, time: 38.139 minutes, Δt: 602.317 ms, max(|w|) = 4.8e-01 ms⁻¹, wall time: 2.761 minutes
Iteration: 1680, time: 38.556 minutes, Δt: 657.930 ms, max(|w|) = 4.9e-01 ms⁻¹, wall time: 2.812 minutes
Iteration: 1720, time: 38.979 minutes, Δt: 667.695 ms, max(|w|) = 4.6e-01 ms⁻¹, wall time: 2.862 minutes
Iteration: 1760, time: 39.397 minutes, Δt: 650.579 ms, max(|w|) = 4.5e-01 ms⁻¹, wall time: 2.912 minutes
Iteration: 1800, time: 39.821 minutes, Δt: 641.755 ms, max(|w|) = 5.3e-01 ms⁻¹, wall time: 2.965 minutes
Iteration: 1840, time: 40.241 minutes, Δt: 607.815 ms, max(|w|) = 4.7e-01 ms⁻¹, wall time: 3.025 minutes
Iteration: 1880, time: 40.662 minutes, Δt: 608.146 ms, max(|w|) = 4.5e-01 ms⁻¹, wall time: 3.085 minutes
Iteration: 1920, time: 41.070 minutes, Δt: 662.118 ms, max(|w|) = 4.7e-01 ms⁻¹, wall time: 3.146 minutes
Iteration: 1960, time: 41.508 minutes, Δt: 676.956 ms, max(|w|) = 4.2e-01 ms⁻¹, wall time: 3.207 minutes
Iteration: 2000, time: 41.955 minutes, Δt: 701.586 ms, max(|w|) = 4.7e-01 ms⁻¹, wall time: 3.258 minutes
Iteration: 2040, time: 42.425 minutes, Δt: 664.034 ms, max(|w|) = 4.3e-01 ms⁻¹, wall time: 3.309 minutes
Iteration: 2080, time: 42.879 minutes, Δt: 727.918 ms, max(|w|) = 4.4e-01 ms⁻¹, wall time: 3.358 minutes
Iteration: 2120, time: 43.330 minutes, Δt: 721.832 ms, max(|w|) = 3.9e-01 ms⁻¹, wall time: 3.411 minutes
Iteration: 2160, time: 43.803 minutes, Δt: 667.655 ms, max(|w|) = 4.0e-01 ms⁻¹, wall time: 3.462 minutes
Iteration: 2200, time: 44.257 minutes, Δt: 696.307 ms, max(|w|) = 4.8e-01 ms⁻¹, wall time: 3.514 minutes
Iteration: 2240, time: 44.744 minutes, Δt: 751.894 ms, max(|w|) = 4.0e-01 ms⁻¹, wall time: 3.565 minutes
Iteration: 2280, time: 45.196 minutes, Δt: 700.750 ms, max(|w|) = 4.2e-01 ms⁻¹, wall time: 3.619 minutes
Iteration: 2320, time: 45.657 minutes, Δt: 697.896 ms, max(|w|) = 4.0e-01 ms⁻¹, wall time: 3.670 minutes
Iteration: 2360, time: 46.117 minutes, Δt: 740.853 ms, max(|w|) = 4.0e-01 ms⁻¹, wall time: 3.720 minutes
Iteration: 2400, time: 46.608 minutes, Δt: 772.080 ms, max(|w|) = 4.2e-01 ms⁻¹, wall time: 3.770 minutes
Iteration: 2440, time: 47.086 minutes, Δt: 709.731 ms, max(|w|) = 4.3e-01 ms⁻¹, wall time: 3.819 minutes
Iteration: 2480, time: 47.575 minutes, Δt: 792.569 ms, max(|w|) = 4.0e-01 ms⁻¹, wall time: 3.869 minutes
Iteration: 2520, time: 48.064 minutes, Δt: 715.233 ms, max(|w|) = 4.1e-01 ms⁻¹, wall time: 3.919 minutes
Iteration: 2560, time: 48.572 minutes, Δt: 777.199 ms, max(|w|) = 4.2e-01 ms⁻¹, wall time: 3.969 minutes
Iteration: 2600, time: 49.064 minutes, Δt: 729.358 ms, max(|w|) = 4.1e-01 ms⁻¹, wall time: 4.019 minutes
Iteration: 2640, time: 49.556 minutes, Δt: 712.496 ms, max(|w|) = 4.3e-01 ms⁻¹, wall time: 4.068 minutes
Iteration: 2680, time: 50.054 minutes, Δt: 713.345 ms, max(|w|) = 4.7e-01 ms⁻¹, wall time: 4.122 minutes
Iteration: 2720, time: 50.546 minutes, Δt: 776.642 ms, max(|w|) = 3.8e-01 ms⁻¹, wall time: 4.179 minutes
Iteration: 2760, time: 51.047 minutes, Δt: 775.103 ms, max(|w|) = 4.1e-01 ms⁻¹, wall time: 4.240 minutes
Iteration: 2800, time: 51.555 minutes, Δt: 792.785 ms, max(|w|) = 4.0e-01 ms⁻¹, wall time: 4.299 minutes
Iteration: 2840, time: 52.065 minutes, Δt: 768.588 ms, max(|w|) = 4.0e-01 ms⁻¹, wall time: 4.358 minutes
Iteration: 2880, time: 52.583 minutes, Δt: 709.775 ms, max(|w|) = 3.9e-01 ms⁻¹, wall time: 4.417 minutes
Iteration: 2920, time: 53.063 minutes, Δt: 716.017 ms, max(|w|) = 4.2e-01 ms⁻¹, wall time: 4.478 minutes
Iteration: 2960, time: 53.545 minutes, Δt: 703.101 ms, max(|w|) = 3.7e-01 ms⁻¹, wall time: 4.537 minutes
Iteration: 3000, time: 54 minutes, Δt: 742.676 ms, max(|w|) = 4.1e-01 ms⁻¹, wall time: 4.594 minutes
Iteration: 3040, time: 54.510 minutes, Δt: 760.961 ms, max(|w|) = 3.8e-01 ms⁻¹, wall time: 4.667 minutes
Iteration: 3080, time: 55.013 minutes, Δt: 824.897 ms, max(|w|) = 3.7e-01 ms⁻¹, wall time: 4.728 minutes
Iteration: 3120, time: 55.520 minutes, Δt: 732.937 ms, max(|w|) = 3.8e-01 ms⁻¹, wall time: 4.785 minutes
Iteration: 3160, time: 56.012 minutes, Δt: 780.247 ms, max(|w|) = 3.7e-01 ms⁻¹, wall time: 4.845 minutes
Iteration: 3200, time: 56.509 minutes, Δt: 766.737 ms, max(|w|) = 4.1e-01 ms⁻¹, wall time: 4.902 minutes
Iteration: 3240, time: 57.014 minutes, Δt: 716.721 ms, max(|w|) = 4.0e-01 ms⁻¹, wall time: 4.962 minutes
Iteration: 3280, time: 57.513 minutes, Δt: 821.167 ms, max(|w|) = 3.4e-01 ms⁻¹, wall time: 5.010 minutes
Iteration: 3320, time: 58.041 minutes, Δt: 794.438 ms, max(|w|) = 3.6e-01 ms⁻¹, wall time: 5.059 minutes
Iteration: 3360, time: 58.559 minutes, Δt: 748.008 ms, max(|w|) = 3.9e-01 ms⁻¹, wall time: 5.108 minutes
Iteration: 3400, time: 59.065 minutes, Δt: 742.468 ms, max(|w|) = 3.6e-01 ms⁻¹, wall time: 5.158 minutes
Iteration: 3440, time: 59.564 minutes, Δt: 725.681 ms, max(|w|) = 4.0e-01 ms⁻¹, wall time: 5.217 minutes
Iteration: 3480, time: 1.001 hours, Δt: 799.198 ms, max(|w|) = 3.5e-01 ms⁻¹, wall time: 5.276 minutes
Iteration: 3520, time: 1.010 hours, Δt: 702.975 ms, max(|w|) = 3.8e-01 ms⁻¹, wall time: 5.335 minutes
Iteration: 3560, time: 1.018 hours, Δt: 842.275 ms, max(|w|) = 3.9e-01 ms⁻¹, wall time: 5.395 minutes
Iteration: 3600, time: 1.027 hours, Δt: 825.154 ms, max(|w|) = 3.9e-01 ms⁻¹, wall time: 5.455 minutes
Iteration: 3640, time: 1.036 hours, Δt: 712.716 ms, max(|w|) = 3.7e-01 ms⁻¹, wall time: 5.515 minutes
Iteration: 3680, time: 1.044 hours, Δt: 752.771 ms, max(|w|) = 4.0e-01 ms⁻¹, wall time: 5.574 minutes
Iteration: 3720, time: 1.053 hours, Δt: 804.547 ms, max(|w|) = 4.3e-01 ms⁻¹, wall time: 5.635 minutes
Iteration: 3760, time: 1.061 hours, Δt: 684.890 ms, max(|w|) = 3.9e-01 ms⁻¹, wall time: 5.695 minutes
Iteration: 3800, time: 1.070 hours, Δt: 829.223 ms, max(|w|) = 3.7e-01 ms⁻¹, wall time: 5.755 minutes
Iteration: 3840, time: 1.079 hours, Δt: 788.227 ms, max(|w|) = 3.9e-01 ms⁻¹, wall time: 5.814 minutes
Iteration: 3880, time: 1.088 hours, Δt: 760.521 ms, max(|w|) = 3.6e-01 ms⁻¹, wall time: 5.875 minutes
Iteration: 3920, time: 1.097 hours, Δt: 835.962 ms, max(|w|) = 3.6e-01 ms⁻¹, wall time: 5.934 minutes
Iteration: 3960, time: 1.106 hours, Δt: 793.534 ms, max(|w|) = 3.8e-01 ms⁻¹, wall time: 5.995 minutes
Iteration: 4000, time: 1.114 hours, Δt: 876.609 ms, max(|w|) = 3.7e-01 ms⁻¹, wall time: 6.054 minutes
Iteration: 4040, time: 1.123 hours, Δt: 811.903 ms, max(|w|) = 3.7e-01 ms⁻¹, wall time: 6.116 minutes
Iteration: 4080, time: 1.132 hours, Δt: 723.880 ms, max(|w|) = 3.6e-01 ms⁻¹, wall time: 6.175 minutes
Iteration: 4120, time: 1.141 hours, Δt: 787.314 ms, max(|w|) = 3.5e-01 ms⁻¹, wall time: 6.236 minutes
Iteration: 4160, time: 1.150 hours, Δt: 816.549 ms, max(|w|) = 3.5e-01 ms⁻¹, wall time: 6.295 minutes
Iteration: 4200, time: 1.159 hours, Δt: 801.842 ms, max(|w|) = 3.6e-01 ms⁻¹, wall time: 6.356 minutes
Iteration: 4240, time: 1.168 hours, Δt: 787.535 ms, max(|w|) = 3.8e-01 ms⁻¹, wall time: 6.414 minutes
Iteration: 4280, time: 1.177 hours, Δt: 757.322 ms, max(|w|) = 3.7e-01 ms⁻¹, wall time: 6.463 minutes
Iteration: 4320, time: 1.185 hours, Δt: 812.536 ms, max(|w|) = 4.2e-01 ms⁻¹, wall time: 6.514 minutes
Iteration: 4360, time: 1.194 hours, Δt: 808.106 ms, max(|w|) = 3.9e-01 ms⁻¹, wall time: 6.563 minutes
Iteration: 4400, time: 1.203 hours, Δt: 827.419 ms, max(|w|) = 3.7e-01 ms⁻¹, wall time: 6.612 minutes
Iteration: 4440, time: 1.212 hours, Δt: 777.720 ms, max(|w|) = 3.4e-01 ms⁻¹, wall time: 6.660 minutes
Iteration: 4480, time: 1.221 hours, Δt: 734.389 ms, max(|w|) = 3.4e-01 ms⁻¹, wall time: 6.709 minutes
Iteration: 4520, time: 1.229 hours, Δt: 801.538 ms, max(|w|) = 3.7e-01 ms⁻¹, wall time: 6.758 minutes
Iteration: 4560, time: 1.238 hours, Δt: 833.503 ms, max(|w|) = 3.5e-01 ms⁻¹, wall time: 6.817 minutes
Iteration: 4600, time: 1.247 hours, Δt: 780.159 ms, max(|w|) = 3.8e-01 ms⁻¹, wall time: 6.876 minutes
Iteration: 4640, time: 1.256 hours, Δt: 838.121 ms, max(|w|) = 3.6e-01 ms⁻¹, wall time: 6.935 minutes
Iteration: 4680, time: 1.265 hours, Δt: 819.928 ms, max(|w|) = 3.6e-01 ms⁻¹, wall time: 6.996 minutes
Iteration: 4720, time: 1.274 hours, Δt: 798.864 ms, max(|w|) = 3.4e-01 ms⁻¹, wall time: 7.086 minutes
Iteration: 4760, time: 1.282 hours, Δt: 734.511 ms, max(|w|) = 3.8e-01 ms⁻¹, wall time: 7.145 minutes
Iteration: 4800, time: 1.291 hours, Δt: 816.541 ms, max(|w|) = 3.6e-01 ms⁻¹, wall time: 7.206 minutes
Iteration: 4840, time: 1.300 hours, Δt: 792.652 ms, max(|w|) = 3.7e-01 ms⁻¹, wall time: 7.265 minutes
Iteration: 4880, time: 1.309 hours, Δt: 820.493 ms, max(|w|) = 3.7e-01 ms⁻¹, wall time: 7.326 minutes
Iteration: 4920, time: 1.318 hours, Δt: 699.926 ms, max(|w|) = 3.7e-01 ms⁻¹, wall time: 7.386 minutes
Iteration: 4960, time: 1.326 hours, Δt: 796.310 ms, max(|w|) = 3.7e-01 ms⁻¹, wall time: 7.447 minutes
Iteration: 5000, time: 1.335 hours, Δt: 775.917 ms, max(|w|) = 3.5e-01 ms⁻¹, wall time: 7.530 minutes
Iteration: 5040, time: 1.344 hours, Δt: 739.733 ms, max(|w|) = 4.0e-01 ms⁻¹, wall time: 7.593 minutes
Iteration: 5080, time: 1.352 hours, Δt: 798.280 ms, max(|w|) = 3.6e-01 ms⁻¹, wall time: 7.656 minutes
Iteration: 5120, time: 1.360 hours, Δt: 791.093 ms, max(|w|) = 3.7e-01 ms⁻¹, wall time: 7.717 minutes
Iteration: 5160, time: 1.369 hours, Δt: 792.332 ms, max(|w|) = 3.7e-01 ms⁻¹, wall time: 7.780 minutes
Iteration: 5200, time: 1.378 hours, Δt: 798.632 ms, max(|w|) = 3.6e-01 ms⁻¹, wall time: 7.842 minutes
Iteration: 5240, time: 1.387 hours, Δt: 847.037 ms, max(|w|) = 3.9e-01 ms⁻¹, wall time: 7.905 minutes
Iteration: 5280, time: 1.396 hours, Δt: 740.008 ms, max(|w|) = 3.9e-01 ms⁻¹, wall time: 7.966 minutes
Iteration: 5320, time: 1.405 hours, Δt: 860.274 ms, max(|w|) = 3.7e-01 ms⁻¹, wall time: 8.069 minutes
Iteration: 5360, time: 1.413 hours, Δt: 785.411 ms, max(|w|) = 3.5e-01 ms⁻¹, wall time: 8.131 minutes
Iteration: 5400, time: 1.422 hours, Δt: 828.893 ms, max(|w|) = 3.4e-01 ms⁻¹, wall time: 8.195 minutes
Iteration: 5440, time: 1.431 hours, Δt: 834.942 ms, max(|w|) = 3.6e-01 ms⁻¹, wall time: 8.257 minutes
Iteration: 5480, time: 1.440 hours, Δt: 757.061 ms, max(|w|) = 3.5e-01 ms⁻¹, wall time: 8.320 minutes
Iteration: 5520, time: 1.449 hours, Δt: 839.976 ms, max(|w|) = 3.6e-01 ms⁻¹, wall time: 8.382 minutes
Iteration: 5560, time: 1.457 hours, Δt: 753.349 ms, max(|w|) = 3.6e-01 ms⁻¹, wall time: 8.443 minutes
Iteration: 5600, time: 1.466 hours, Δt: 790.263 ms, max(|w|) = 3.4e-01 ms⁻¹, wall time: 8.505 minutes
Iteration: 5640, time: 1.475 hours, Δt: 826.378 ms, max(|w|) = 3.4e-01 ms⁻¹, wall time: 8.586 minutes
Iteration: 5680, time: 1.484 hours, Δt: 807.405 ms, max(|w|) = 4.1e-01 ms⁻¹, wall time: 8.648 minutes
Iteration: 5720, time: 1.493 hours, Δt: 828.138 ms, max(|w|) = 3.9e-01 ms⁻¹, wall time: 8.710 minutes
Iteration: 5760, time: 1.501 hours, Δt: 755.299 ms, max(|w|) = 3.8e-01 ms⁻¹, wall time: 8.772 minutes
Iteration: 5800, time: 1.510 hours, Δt: 796.172 ms, max(|w|) = 3.6e-01 ms⁻¹, wall time: 8.833 minutes
Iteration: 5840, time: 1.518 hours, Δt: 750.107 ms, max(|w|) = 3.6e-01 ms⁻¹, wall time: 8.893 minutes
Iteration: 5880, time: 1.527 hours, Δt: 751.024 ms, max(|w|) = 3.9e-01 ms⁻¹, wall time: 8.953 minutes
Iteration: 5920, time: 1.535 hours, Δt: 752.698 ms, max(|w|) = 3.7e-01 ms⁻¹, wall time: 9.013 minutes
Iteration: 5960, time: 1.544 hours, Δt: 840.300 ms, max(|w|) = 3.5e-01 ms⁻¹, wall time: 9.073 minutes
Iteration: 6000, time: 1.553 hours, Δt: 785.989 ms, max(|w|) = 3.5e-01 ms⁻¹, wall time: 9.134 minutes
Iteration: 6040, time: 1.561 hours, Δt: 824.061 ms, max(|w|) = 3.3e-01 ms⁻¹, wall time: 9.194 minutes
Iteration: 6080, time: 1.570 hours, Δt: 813.670 ms, max(|w|) = 4.0e-01 ms⁻¹, wall time: 9.257 minutes
Iteration: 6120, time: 1.579 hours, Δt: 750.376 ms, max(|w|) = 3.9e-01 ms⁻¹, wall time: 9.312 minutes
Iteration: 6160, time: 1.588 hours, Δt: 808.627 ms, max(|w|) = 3.5e-01 ms⁻¹, wall time: 9.372 minutes
Iteration: 6200, time: 1.596 hours, Δt: 800.330 ms, max(|w|) = 3.6e-01 ms⁻¹, wall time: 9.432 minutes
Iteration: 6240, time: 1.605 hours, Δt: 781.240 ms, max(|w|) = 3.4e-01 ms⁻¹, wall time: 9.493 minutes
Iteration: 6280, time: 1.614 hours, Δt: 752.790 ms, max(|w|) = 3.3e-01 ms⁻¹, wall time: 9.551 minutes
Iteration: 6320, time: 1.622 hours, Δt: 804.488 ms, max(|w|) = 3.6e-01 ms⁻¹, wall time: 9.611 minutes
Iteration: 6360, time: 1.631 hours, Δt: 689.825 ms, max(|w|) = 3.4e-01 ms⁻¹, wall time: 9.672 minutes
Iteration: 6400, time: 1.639 hours, Δt: 820.181 ms, max(|w|) = 3.5e-01 ms⁻¹, wall time: 9.731 minutes
Iteration: 6440, time: 1.648 hours, Δt: 760.961 ms, max(|w|) = 3.8e-01 ms⁻¹, wall time: 9.791 minutes
Iteration: 6480, time: 1.657 hours, Δt: 829.662 ms, max(|w|) = 3.7e-01 ms⁻¹, wall time: 9.852 minutes
Iteration: 6520, time: 1.666 hours, Δt: 804.645 ms, max(|w|) = 3.5e-01 ms⁻¹, wall time: 9.911 minutes
Iteration: 6560, time: 1.674 hours, Δt: 762.430 ms, max(|w|) = 3.8e-01 ms⁻¹, wall time: 9.971 minutes
Iteration: 6600, time: 1.683 hours, Δt: 782.164 ms, max(|w|) = 3.8e-01 ms⁻¹, wall time: 10.032 minutes
Iteration: 6640, time: 1.691 hours, Δt: 820.897 ms, max(|w|) = 3.7e-01 ms⁻¹, wall time: 10.092 minutes
Iteration: 6680, time: 1.700 hours, Δt: 754.834 ms, max(|w|) = 3.6e-01 ms⁻¹, wall time: 10.177 minutes
Iteration: 6720, time: 1.709 hours, Δt: 752.495 ms, max(|w|) = 3.7e-01 ms⁻¹, wall time: 10.235 minutes
Iteration: 6760, time: 1.718 hours, Δt: 801.215 ms, max(|w|) = 3.6e-01 ms⁻¹, wall time: 10.346 minutes
Iteration: 6800, time: 1.726 hours, Δt: 809.254 ms, max(|w|) = 3.6e-01 ms⁻¹, wall time: 10.459 minutes
Iteration: 6840, time: 1.735 hours, Δt: 763.345 ms, max(|w|) = 3.6e-01 ms⁻¹, wall time: 10.574 minutes
Iteration: 6880, time: 1.744 hours, Δt: 745.199 ms, max(|w|) = 4.3e-01 ms⁻¹, wall time: 10.689 minutes
Iteration: 6920, time: 1.752 hours, Δt: 769.612 ms, max(|w|) = 3.4e-01 ms⁻¹, wall time: 10.805 minutes
Iteration: 6960, time: 1.761 hours, Δt: 802.267 ms, max(|w|) = 3.4e-01 ms⁻¹, wall time: 10.916 minutes
Iteration: 7000, time: 1.770 hours, Δt: 753.093 ms, max(|w|) = 3.3e-01 ms⁻¹, wall time: 11.030 minutes
Iteration: 7040, time: 1.778 hours, Δt: 786.925 ms, max(|w|) = 3.8e-01 ms⁻¹, wall time: 11.092 minutes
Iteration: 7080, time: 1.787 hours, Δt: 758.119 ms, max(|w|) = 3.3e-01 ms⁻¹, wall time: 11.151 minutes
Iteration: 7120, time: 1.796 hours, Δt: 760.433 ms, max(|w|) = 3.8e-01 ms⁻¹, wall time: 11.211 minutes
Iteration: 7160, time: 1.805 hours, Δt: 657.262 ms, max(|w|) = 3.7e-01 ms⁻¹, wall time: 11.271 minutes
Iteration: 7200, time: 1.813 hours, Δt: 773.169 ms, max(|w|) = 3.6e-01 ms⁻¹, wall time: 11.330 minutes
Iteration: 7240, time: 1.822 hours, Δt: 801.743 ms, max(|w|) = 4.0e-01 ms⁻¹, wall time: 11.390 minutes
Iteration: 7280, time: 1.830 hours, Δt: 770.461 ms, max(|w|) = 3.7e-01 ms⁻¹, wall time: 11.450 minutes
Iteration: 7320, time: 1.839 hours, Δt: 811.641 ms, max(|w|) = 3.6e-01 ms⁻¹, wall time: 11.510 minutes
Iteration: 7360, time: 1.848 hours, Δt: 754.602 ms, max(|w|) = 3.7e-01 ms⁻¹, wall time: 11.570 minutes
Iteration: 7400, time: 1.856 hours, Δt: 814.472 ms, max(|w|) = 3.5e-01 ms⁻¹, wall time: 11.631 minutes
Iteration: 7440, time: 1.865 hours, Δt: 758.449 ms, max(|w|) = 3.4e-01 ms⁻¹, wall time: 11.690 minutes
Iteration: 7480, time: 1.874 hours, Δt: 734.106 ms, max(|w|) = 3.8e-01 ms⁻¹, wall time: 11.751 minutes
Iteration: 7520, time: 1.882 hours, Δt: 694.904 ms, max(|w|) = 3.6e-01 ms⁻¹, wall time: 11.811 minutes
Iteration: 7560, time: 1.890 hours, Δt: 775.176 ms, max(|w|) = 3.5e-01 ms⁻¹, wall time: 11.871 minutes
Iteration: 7600, time: 1.899 hours, Δt: 803.740 ms, max(|w|) = 3.7e-01 ms⁻¹, wall time: 11.931 minutes
Iteration: 7640, time: 1.907 hours, Δt: 741.784 ms, max(|w|) = 3.6e-01 ms⁻¹, wall time: 11.991 minutes
Iteration: 7680, time: 1.916 hours, Δt: 717.213 ms, max(|w|) = 3.9e-01 ms⁻¹, wall time: 12.051 minutes
Iteration: 7720, time: 1.924 hours, Δt: 802.918 ms, max(|w|) = 3.9e-01 ms⁻¹, wall time: 12.111 minutes
Iteration: 7760, time: 1.932 hours, Δt: 810.824 ms, max(|w|) = 3.7e-01 ms⁻¹, wall time: 12.171 minutes
Iteration: 7800, time: 1.941 hours, Δt: 821.583 ms, max(|w|) = 3.6e-01 ms⁻¹, wall time: 12.230 minutes
Iteration: 7840, time: 1.949 hours, Δt: 728.131 ms, max(|w|) = 3.7e-01 ms⁻¹, wall time: 12.289 minutes
Iteration: 7880, time: 1.958 hours, Δt: 795.058 ms, max(|w|) = 3.8e-01 ms⁻¹, wall time: 12.349 minutes
Iteration: 7920, time: 1.966 hours, Δt: 705.681 ms, max(|w|) = 3.7e-01 ms⁻¹, wall time: 12.409 minutes
Iteration: 7960, time: 1.974 hours, Δt: 768.637 ms, max(|w|) = 3.7e-01 ms⁻¹, wall time: 12.469 minutes
Iteration: 8000, time: 1.983 hours, Δt: 784.756 ms, max(|w|) = 3.7e-01 ms⁻¹, wall time: 12.529 minutes
Iteration: 8040, time: 1.991 hours, Δt: 758.418 ms, max(|w|) = 4.3e-01 ms⁻¹, wall time: 12.590 minutes
Iteration: 8080, time: 2.000 hours, Δt: 804.205 ms, max(|w|) = 4.1e-01 ms⁻¹, wall time: 12.650 minutes
[ Info: Simulation is stopping after running for 12.653 minutes.
[ Info: Simulation time 2 hours equals or exceeds stop time 2 hours.
Turbulence visualization
We animate the data saved in ocean_wind_mixing_and_convection.jld2. We prepare for animating the flow by loading the data into FieldTimeSeries and defining functions for computing colorbar limits.
filepath = filename * ".jld2"
time_series = (w = FieldTimeSeries(filepath, "w"),
T = FieldTimeSeries(filepath, "T"),
S = FieldTimeSeries(filepath, "S"),
νₑ = FieldTimeSeries(filepath, "νₑ"))(w = 128×1×65×121 FieldTimeSeries{InMemory} located at (Center, Center, Face) of w at ocean_wind_mixing_and_convection.jld2
├── grid: 128×128×64 RectilinearGrid{Float64, Periodic, Periodic, Bounded} on CPU with 3×3×3 halo
├── indices: (:, 64:64, :)
├── time_indexing: Linear()
├── backend: InMemory()
├── path: ocean_wind_mixing_and_convection.jld2
├── name: w
└── data: 134×1×71×121 OffsetArray(::Array{Float64, 4}, -2:131, 64:64, -2:68, 1:121) with eltype Float64 with indices -2:131×64:64×-2:68×1:121
└── max=0.382226, min=-0.454915, mean=1.21091e-5, T = 128×1×64×121 FieldTimeSeries{InMemory} located at (Center, Center, Center) of T at ocean_wind_mixing_and_convection.jld2
├── grid: 128×128×64 RectilinearGrid{Float64, Periodic, Periodic, Bounded} on CPU with 3×3×3 halo
├── indices: (:, 64:64, :)
├── time_indexing: Linear()
├── backend: InMemory()
├── path: ocean_wind_mixing_and_convection.jld2
├── name: T
└── data: 134×1×70×121 OffsetArray(::Array{Float64, 4}, -2:131, 64:64, -2:67, 1:121) with eltype Float64 with indices -2:131×64:64×-2:67×1:121
└── max=20.1496, min=0.0, mean=18.5883, S = 128×1×64×121 FieldTimeSeries{InMemory} located at (Center, Center, Center) of S at ocean_wind_mixing_and_convection.jld2
├── grid: 128×128×64 RectilinearGrid{Float64, Periodic, Periodic, Bounded} on CPU with 3×3×3 halo
├── indices: (:, 64:64, :)
├── time_indexing: Linear()
├── backend: InMemory()
├── path: ocean_wind_mixing_and_convection.jld2
├── name: S
└── data: 134×1×70×121 OffsetArray(::Array{Float64, 4}, -2:131, 64:64, -2:67, 1:121) with eltype Float64 with indices -2:131×64:64×-2:67×1:121
└── max=35.0401, min=0.0, mean=33.0007, νₑ = 128×1×64×121 FieldTimeSeries{InMemory} located at (Center, Center, Center) of νₑ at ocean_wind_mixing_and_convection.jld2
├── grid: 128×128×64 RectilinearGrid{Float64, Periodic, Periodic, Bounded} on CPU with 3×3×3 halo
├── indices: (:, 64:64, :)
├── time_indexing: Linear()
├── backend: InMemory()
├── path: ocean_wind_mixing_and_convection.jld2
├── name: νₑ
└── data: 134×1×70×121 OffsetArray(::Array{Float64, 4}, -2:131, 64:64, -2:67, 1:121) with eltype Float64 with indices -2:131×64:64×-2:67×1:121
└── max=0.0, min=0.0, mean=0.0)We start the animation at $t = 10$ minutes since things are pretty boring till then:
times = time_series.w.times
intro = searchsortedfirst(times, 10minutes)11We are now ready to animate using Makie. We use Makie's Observable to animate the data. To dive into how Observables work we refer to Makie.jl's Documentation.
n = Observable(intro)
wₙ = @lift time_series.w[$n]
Tₙ = @lift time_series.T[$n]
Sₙ = @lift time_series.S[$n]
νₑₙ = @lift time_series.νₑ[$n]
fig = Figure(size = (1800, 900))
axis_kwargs = (xlabel="x (m)",
ylabel="z (m)",
aspect = AxisAspect(grid.Lx/grid.Lz),
limits = ((0, grid.Lx), (-grid.Lz, 0)))
ax_w = Axis(fig[2, 1]; title = "Vertical velocity", axis_kwargs...)
ax_T = Axis(fig[2, 3]; title = "Temperature", axis_kwargs...)
ax_S = Axis(fig[3, 1]; title = "Salinity", axis_kwargs...)
ax_νₑ = Axis(fig[3, 3]; title = "Eddy viscocity", axis_kwargs...)
title = @lift @sprintf("t = %s", prettytime(times[$n]))
wlims = (-0.05, 0.05)
Tlims = (19.7, 19.99)
Slims = (35, 35.005)
νₑlims = (1e-6, 5e-3)
hm_w = heatmap!(ax_w, wₙ; colormap = :balance, colorrange = wlims)
Colorbar(fig[2, 2], hm_w; label = "m s⁻¹")
hm_T = heatmap!(ax_T, Tₙ; colormap = :thermal, colorrange = Tlims)
Colorbar(fig[2, 4], hm_T; label = "ᵒC")
hm_S = heatmap!(ax_S, Sₙ; colormap = :haline, colorrange = Slims)
Colorbar(fig[3, 2], hm_S; label = "g / kg")
hm_νₑ = heatmap!(ax_νₑ, νₑₙ; colormap = :thermal, colorrange = νₑlims)
Colorbar(fig[3, 4], hm_νₑ; label = "m s⁻²")
fig[1, 1:4] = Label(fig, title, fontsize=24, tellwidth=false)
figAnd now record a movie.
frames = intro:length(times)
@info "Making a motion picture of ocean wind mixing and convection..."
CairoMakie.record(fig, filename * ".mp4", frames, framerate=8) do i
n[] = i
end[ Info: Making a motion picture of ocean wind mixing and convection...
Julia version and environment information
This example was executed with the following version of Julia:
using InteractiveUtils: versioninfo
versioninfo()Julia Version 1.12.4
Commit 01a2eadb047 (2026-01-06 16:56 UTC)
Build Info:
Official https://julialang.org release
Platform Info:
OS: Linux (x86_64-linux-gnu)
CPU: 128 × AMD EPYC 9374F 32-Core Processor
WORD_SIZE: 64
LLVM: libLLVM-18.1.7 (ORCJIT, znver4)
GC: Built with stock GC
Threads: 1 default, 1 interactive, 1 GC (on 128 virtual cores)
Environment:
LD_LIBRARY_PATH =
JULIA_PKG_SERVER_REGISTRY_PREFERENCE = eager
JULIA_DEPOT_PATH = /var/lib/buildkite-agent/.julia-oceananigans
JULIA_PROJECT = /var/lib/buildkite-agent/Oceananigans.jl-29074/docs/
JULIA_VERSION = 1.12.4
JULIA_LOAD_PATH = @:@v#.#:@stdlib
JULIA_VERSION_ENZYME = 1.10.10
JULIA_PYTHONCALL_EXE = /var/lib/buildkite-agent/Oceananigans.jl-29074/docs/.CondaPkg/.pixi/envs/default/bin/python
JULIA_DEBUG = Literate
These were the top-level packages installed in the environment:
import Pkg
Pkg.status()Status `~/Oceananigans.jl-29074/docs/Project.toml`
[79e6a3ab] Adapt v4.4.0
[052768ef] CUDA v5.9.6
[13f3f980] CairoMakie v0.15.8
[e30172f5] Documenter v1.16.1
[daee34ce] DocumenterCitations v1.4.1
[033835bb] JLD2 v0.6.3
[63c18a36] KernelAbstractions v0.9.39
[98b081ad] Literate v2.21.0
[da04e1cc] MPI v0.20.23
[85f8d34a] NCDatasets v0.14.11
[9e8cae18] Oceananigans v0.104.2 `..`
[f27b6e38] Polynomials v4.1.0
[6038ab10] Rotations v1.7.1
[d496a93d] SeawaterPolynomials v0.3.10
[09ab397b] StructArrays v0.7.2
[bdfc003b] TimesDates v0.3.3
[2e0b0046] XESMF v0.1.6
[b77e0a4c] InteractiveUtils v1.11.0
[37e2e46d] LinearAlgebra v1.12.0
[44cfe95a] Pkg v1.12.1
This page was generated using Literate.jl.