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.3e-05 ms⁻¹, wall time: 0 seconds
[ Info: ... simulation initialization complete (7.740 seconds)
[ Info: Executing initial time step...
[ Info: ... initial time step complete (8.521 seconds).
Iteration: 0040, time: 6.394 minutes, Δt: 6.380 seconds, max(|w|) = 6.5e-06 ms⁻¹, wall time: 19.904 seconds
Iteration: 0080, time: 9.825 minutes, Δt: 4.112 seconds, max(|w|) = 9.6e-06 ms⁻¹, wall time: 23.462 seconds
Iteration: 0120, time: 12.230 minutes, Δt: 3.281 seconds, max(|w|) = 1.0e-05 ms⁻¹, wall time: 27.033 seconds
Iteration: 0160, time: 14.242 minutes, Δt: 2.802 seconds, max(|w|) = 9.0e-06 ms⁻¹, wall time: 30.708 seconds
Iteration: 0200, time: 15.999 minutes, Δt: 2.482 seconds, max(|w|) = 7.7e-06 ms⁻¹, wall time: 34.335 seconds
Iteration: 0240, time: 17.542 minutes, Δt: 2.255 seconds, max(|w|) = 1.0e-05 ms⁻¹, wall time: 37.988 seconds
Iteration: 0280, time: 18.971 minutes, Δt: 2.077 seconds, max(|w|) = 2.1e-05 ms⁻¹, wall time: 41.585 seconds
Iteration: 0320, time: 20.295 minutes, Δt: 1.934 seconds, max(|w|) = 4.6e-05 ms⁻¹, wall time: 45.296 seconds
Iteration: 0360, time: 21.526 minutes, Δt: 1.816 seconds, max(|w|) = 9.0e-05 ms⁻¹, wall time: 49.003 seconds
Iteration: 0400, time: 22.703 minutes, Δt: 1.715 seconds, max(|w|) = 2.0e-04 ms⁻¹, wall time: 52.560 seconds
Iteration: 0440, time: 23.807 minutes, Δt: 1.628 seconds, max(|w|) = 4.1e-04 ms⁻¹, wall time: 56.167 seconds
Iteration: 0480, time: 24.849 minutes, Δt: 1.550 seconds, max(|w|) = 8.0e-04 ms⁻¹, wall time: 59.698 seconds
Iteration: 0520, time: 25.859 minutes, Δt: 1.474 seconds, max(|w|) = 1.5e-03 ms⁻¹, wall time: 1.057 minutes
Iteration: 0560, time: 26.817 minutes, Δt: 1.402 seconds, max(|w|) = 2.7e-03 ms⁻¹, wall time: 1.116 minutes
Iteration: 0600, time: 27.729 minutes, Δt: 1.322 seconds, max(|w|) = 5.2e-03 ms⁻¹, wall time: 1.176 minutes
Iteration: 0640, time: 28.574 minutes, Δt: 1.229 seconds, max(|w|) = 1.0e-02 ms⁻¹, wall time: 1.237 minutes
Iteration: 0680, time: 29.350 minutes, Δt: 1.132 seconds, max(|w|) = 1.7e-02 ms⁻¹, wall time: 1.299 minutes
Iteration: 0720, time: 30.071 minutes, Δt: 1.039 seconds, max(|w|) = 2.4e-02 ms⁻¹, wall time: 1.359 minutes
Iteration: 0760, time: 30.743 minutes, Δt: 950.828 ms, max(|w|) = 3.0e-02 ms⁻¹, wall time: 1.419 minutes
Iteration: 0800, time: 31.343 minutes, Δt: 853.871 ms, max(|w|) = 1.0e-01 ms⁻¹, wall time: 1.479 minutes
Iteration: 0840, time: 31.778 minutes, Δt: 480.349 ms, max(|w|) = 4.3e-01 ms⁻¹, wall time: 1.538 minutes
Iteration: 0880, time: 32.092 minutes, Δt: 438.068 ms, max(|w|) = 4.9e-01 ms⁻¹, wall time: 1.627 minutes
Iteration: 0920, time: 32.380 minutes, Δt: 458.339 ms, max(|w|) = 5.1e-01 ms⁻¹, wall time: 1.744 minutes
Iteration: 0960, time: 32.663 minutes, Δt: 436.509 ms, max(|w|) = 7.7e-01 ms⁻¹, wall time: 1.859 minutes
Iteration: 1000, time: 32.930 minutes, Δt: 388.767 ms, max(|w|) = 6.0e-01 ms⁻¹, wall time: 1.975 minutes
Iteration: 1040, time: 33.175 minutes, Δt: 358.542 ms, max(|w|) = 5.9e-01 ms⁻¹, wall time: 2.093 minutes
Iteration: 1080, time: 33.430 minutes, Δt: 399.012 ms, max(|w|) = 6.1e-01 ms⁻¹, wall time: 2.209 minutes
Iteration: 1120, time: 33.666 minutes, Δt: 375.820 ms, max(|w|) = 5.9e-01 ms⁻¹, wall time: 2.324 minutes
Iteration: 1160, time: 33.909 minutes, Δt: 396.519 ms, max(|w|) = 6.2e-01 ms⁻¹, wall time: 2.439 minutes
Iteration: 1200, time: 34.178 minutes, Δt: 357.204 ms, max(|w|) = 6.9e-01 ms⁻¹, wall time: 2.555 minutes
Iteration: 1240, time: 34.433 minutes, Δt: 422.339 ms, max(|w|) = 5.9e-01 ms⁻¹, wall time: 2.643 minutes
Iteration: 1280, time: 34.710 minutes, Δt: 454.014 ms, max(|w|) = 5.7e-01 ms⁻¹, wall time: 2.702 minutes
Iteration: 1320, time: 34.985 minutes, Δt: 378.450 ms, max(|w|) = 6.5e-01 ms⁻¹, wall time: 2.763 minutes
Iteration: 1360, time: 35.265 minutes, Δt: 438.283 ms, max(|w|) = 5.7e-01 ms⁻¹, wall time: 2.823 minutes
Iteration: 1400, time: 35.589 minutes, Δt: 539.809 ms, max(|w|) = 5.6e-01 ms⁻¹, wall time: 2.883 minutes
Iteration: 1440, time: 35.927 minutes, Δt: 533.432 ms, max(|w|) = 6.5e-01 ms⁻¹, wall time: 2.937 minutes
Iteration: 1480, time: 36.292 minutes, Δt: 593.186 ms, max(|w|) = 5.6e-01 ms⁻¹, wall time: 2.985 minutes
Iteration: 1520, time: 36.660 minutes, Δt: 565.554 ms, max(|w|) = 4.9e-01 ms⁻¹, wall time: 3.034 minutes
Iteration: 1560, time: 37.040 minutes, Δt: 594.879 ms, max(|w|) = 5.0e-01 ms⁻¹, wall time: 3.083 minutes
Iteration: 1600, time: 37.433 minutes, Δt: 611.998 ms, max(|w|) = 5.0e-01 ms⁻¹, wall time: 3.132 minutes
Iteration: 1640, time: 37.832 minutes, Δt: 587.498 ms, max(|w|) = 4.5e-01 ms⁻¹, wall time: 3.183 minutes
Iteration: 1680, time: 38.219 minutes, Δt: 618.521 ms, max(|w|) = 4.8e-01 ms⁻¹, wall time: 3.233 minutes
Iteration: 1720, time: 38.630 minutes, Δt: 603.555 ms, max(|w|) = 4.6e-01 ms⁻¹, wall time: 3.283 minutes
Iteration: 1760, time: 39.043 minutes, Δt: 647.621 ms, max(|w|) = 5.1e-01 ms⁻¹, wall time: 3.334 minutes
Iteration: 1800, time: 39.468 minutes, Δt: 637.389 ms, max(|w|) = 4.4e-01 ms⁻¹, wall time: 3.386 minutes
Iteration: 1840, time: 39.887 minutes, Δt: 649.524 ms, max(|w|) = 5.5e-01 ms⁻¹, wall time: 3.435 minutes
Iteration: 1880, time: 40.323 minutes, Δt: 715.681 ms, max(|w|) = 4.5e-01 ms⁻¹, wall time: 3.490 minutes
Iteration: 1920, time: 40.723 minutes, Δt: 586.794 ms, max(|w|) = 4.8e-01 ms⁻¹, wall time: 3.550 minutes
Iteration: 1960, time: 41.133 minutes, Δt: 588.563 ms, max(|w|) = 4.6e-01 ms⁻¹, wall time: 3.609 minutes
Iteration: 2000, time: 41.547 minutes, Δt: 687.001 ms, max(|w|) = 4.2e-01 ms⁻¹, wall time: 3.670 minutes
Iteration: 2040, time: 41.996 minutes, Δt: 707.992 ms, max(|w|) = 4.4e-01 ms⁻¹, wall time: 3.730 minutes
Iteration: 2080, time: 42.446 minutes, Δt: 637.869 ms, max(|w|) = 5.3e-01 ms⁻¹, wall time: 3.793 minutes
Iteration: 2120, time: 42.880 minutes, Δt: 654.582 ms, max(|w|) = 4.5e-01 ms⁻¹, wall time: 3.852 minutes
Iteration: 2160, time: 43.301 minutes, Δt: 571.717 ms, max(|w|) = 4.1e-01 ms⁻¹, wall time: 3.914 minutes
Iteration: 2200, time: 43.723 minutes, Δt: 712.810 ms, max(|w|) = 4.0e-01 ms⁻¹, wall time: 3.975 minutes
Iteration: 2240, time: 44.171 minutes, Δt: 687.556 ms, max(|w|) = 4.7e-01 ms⁻¹, wall time: 4.037 minutes
Iteration: 2280, time: 44.643 minutes, Δt: 692.685 ms, max(|w|) = 4.1e-01 ms⁻¹, wall time: 4.100 minutes
Iteration: 2320, time: 45.114 minutes, Δt: 701.177 ms, max(|w|) = 4.4e-01 ms⁻¹, wall time: 4.162 minutes
Iteration: 2360, time: 45.592 minutes, Δt: 622.804 ms, max(|w|) = 4.3e-01 ms⁻¹, wall time: 4.224 minutes
Iteration: 2400, time: 46.037 minutes, Δt: 707.145 ms, max(|w|) = 3.9e-01 ms⁻¹, wall time: 4.287 minutes
Iteration: 2440, time: 46.505 minutes, Δt: 683.979 ms, max(|w|) = 4.6e-01 ms⁻¹, wall time: 4.348 minutes
Iteration: 2480, time: 46.993 minutes, Δt: 685.925 ms, max(|w|) = 4.1e-01 ms⁻¹, wall time: 4.409 minutes
Iteration: 2520, time: 47.464 minutes, Δt: 757.572 ms, max(|w|) = 3.9e-01 ms⁻¹, wall time: 4.470 minutes
Iteration: 2560, time: 47.960 minutes, Δt: 676.606 ms, max(|w|) = 4.0e-01 ms⁻¹, wall time: 4.534 minutes
Iteration: 2600, time: 48.433 minutes, Δt: 767.891 ms, max(|w|) = 3.9e-01 ms⁻¹, wall time: 4.596 minutes
Iteration: 2640, time: 48.927 minutes, Δt: 731.288 ms, max(|w|) = 4.3e-01 ms⁻¹, wall time: 4.658 minutes
Iteration: 2680, time: 49.387 minutes, Δt: 732.040 ms, max(|w|) = 4.0e-01 ms⁻¹, wall time: 4.719 minutes
Iteration: 2720, time: 49.873 minutes, Δt: 748.798 ms, max(|w|) = 4.1e-01 ms⁻¹, wall time: 4.781 minutes
Iteration: 2760, time: 50.357 minutes, Δt: 796.194 ms, max(|w|) = 4.0e-01 ms⁻¹, wall time: 4.843 minutes
Iteration: 2800, time: 50.877 minutes, Δt: 736.371 ms, max(|w|) = 4.0e-01 ms⁻¹, wall time: 4.906 minutes
Iteration: 2840, time: 51.367 minutes, Δt: 728.172 ms, max(|w|) = 4.1e-01 ms⁻¹, wall time: 4.969 minutes
Iteration: 2880, time: 51.849 minutes, Δt: 736.997 ms, max(|w|) = 3.7e-01 ms⁻¹, wall time: 5.030 minutes
Iteration: 2920, time: 52.318 minutes, Δt: 739.140 ms, max(|w|) = 3.8e-01 ms⁻¹, wall time: 5.094 minutes
Iteration: 2960, time: 52.822 minutes, Δt: 786.347 ms, max(|w|) = 3.6e-01 ms⁻¹, wall time: 5.156 minutes
Iteration: 3000, time: 53.339 minutes, Δt: 740.989 ms, max(|w|) = 3.9e-01 ms⁻¹, wall time: 5.217 minutes
Iteration: 3040, time: 53.849 minutes, Δt: 713.856 ms, max(|w|) = 3.6e-01 ms⁻¹, wall time: 5.279 minutes
Iteration: 3080, time: 54.343 minutes, Δt: 753.024 ms, max(|w|) = 4.1e-01 ms⁻¹, wall time: 5.340 minutes
Iteration: 3120, time: 54.849 minutes, Δt: 803.215 ms, max(|w|) = 3.8e-01 ms⁻¹, wall time: 5.402 minutes
Iteration: 3160, time: 55.334 minutes, Δt: 704.568 ms, max(|w|) = 3.7e-01 ms⁻¹, wall time: 5.465 minutes
Iteration: 3200, time: 55.837 minutes, Δt: 809.654 ms, max(|w|) = 3.7e-01 ms⁻¹, wall time: 5.527 minutes
Iteration: 3240, time: 56.353 minutes, Δt: 798.988 ms, max(|w|) = 4.0e-01 ms⁻¹, wall time: 5.589 minutes
Iteration: 3280, time: 56.873 minutes, Δt: 731.520 ms, max(|w|) = 4.2e-01 ms⁻¹, wall time: 5.651 minutes
Iteration: 3320, time: 57.383 minutes, Δt: 801.124 ms, max(|w|) = 3.8e-01 ms⁻¹, wall time: 5.714 minutes
Iteration: 3360, time: 57.905 minutes, Δt: 764.261 ms, max(|w|) = 3.6e-01 ms⁻¹, wall time: 5.777 minutes
Iteration: 3400, time: 58.422 minutes, Δt: 817.513 ms, max(|w|) = 3.7e-01 ms⁻¹, wall time: 5.838 minutes
Iteration: 3440, time: 58.952 minutes, Δt: 817.271 ms, max(|w|) = 3.8e-01 ms⁻¹, wall time: 5.901 minutes
Iteration: 3480, time: 59.471 minutes, Δt: 765.675 ms, max(|w|) = 4.4e-01 ms⁻¹, wall time: 5.965 minutes
Iteration: 3520, time: 1 hour, Δt: 786.456 ms, max(|w|) = 3.7e-01 ms⁻¹, wall time: 6.026 minutes
Iteration: 3560, time: 1.008 hours, Δt: 729.875 ms, max(|w|) = 3.8e-01 ms⁻¹, wall time: 6.089 minutes
Iteration: 3600, time: 1.017 hours, Δt: 752.155 ms, max(|w|) = 4.1e-01 ms⁻¹, wall time: 6.158 minutes
Iteration: 3640, time: 1.025 hours, Δt: 739.271 ms, max(|w|) = 3.7e-01 ms⁻¹, wall time: 6.235 minutes
Iteration: 3680, time: 1.034 hours, Δt: 790.517 ms, max(|w|) = 3.8e-01 ms⁻¹, wall time: 6.306 minutes
Iteration: 3720, time: 1.042 hours, Δt: 781.631 ms, max(|w|) = 3.7e-01 ms⁻¹, wall time: 6.376 minutes
Iteration: 3760, time: 1.051 hours, Δt: 845.022 ms, max(|w|) = 4.0e-01 ms⁻¹, wall time: 6.443 minutes
Iteration: 3800, time: 1.060 hours, Δt: 800.026 ms, max(|w|) = 3.9e-01 ms⁻¹, wall time: 6.504 minutes
Iteration: 3840, time: 1.068 hours, Δt: 796.174 ms, max(|w|) = 3.8e-01 ms⁻¹, wall time: 6.569 minutes
Iteration: 3880, time: 1.077 hours, Δt: 761.643 ms, max(|w|) = 3.8e-01 ms⁻¹, wall time: 6.631 minutes
Iteration: 3920, time: 1.086 hours, Δt: 770.552 ms, max(|w|) = 3.7e-01 ms⁻¹, wall time: 6.692 minutes
Iteration: 3960, time: 1.095 hours, Δt: 828.916 ms, max(|w|) = 3.5e-01 ms⁻¹, wall time: 6.755 minutes
Iteration: 4000, time: 1.104 hours, Δt: 844.471 ms, max(|w|) = 3.9e-01 ms⁻¹, wall time: 6.818 minutes
Iteration: 4040, time: 1.113 hours, Δt: 830.030 ms, max(|w|) = 3.5e-01 ms⁻¹, wall time: 6.880 minutes
Iteration: 4080, time: 1.121 hours, Δt: 798.850 ms, max(|w|) = 3.5e-01 ms⁻¹, wall time: 6.941 minutes
Iteration: 4120, time: 1.130 hours, Δt: 825.848 ms, max(|w|) = 3.7e-01 ms⁻¹, wall time: 7.002 minutes
Iteration: 4160, time: 1.139 hours, Δt: 788.753 ms, max(|w|) = 3.5e-01 ms⁻¹, wall time: 7.064 minutes
Iteration: 4200, time: 1.147 hours, Δt: 753.870 ms, max(|w|) = 3.5e-01 ms⁻¹, wall time: 7.127 minutes
Iteration: 4240, time: 1.156 hours, Δt: 827.944 ms, max(|w|) = 4.3e-01 ms⁻¹, wall time: 7.192 minutes
Iteration: 4280, time: 1.165 hours, Δt: 827.952 ms, max(|w|) = 3.9e-01 ms⁻¹, wall time: 7.254 minutes
Iteration: 4320, time: 1.174 hours, Δt: 834.704 ms, max(|w|) = 3.7e-01 ms⁻¹, wall time: 7.316 minutes
Iteration: 4360, time: 1.182 hours, Δt: 747.397 ms, max(|w|) = 3.5e-01 ms⁻¹, wall time: 7.378 minutes
Iteration: 4400, time: 1.191 hours, Δt: 763.621 ms, max(|w|) = 4.1e-01 ms⁻¹, wall time: 7.441 minutes
Iteration: 4440, time: 1.199 hours, Δt: 810.727 ms, max(|w|) = 3.5e-01 ms⁻¹, wall time: 7.504 minutes
Iteration: 4480, time: 1.208 hours, Δt: 796.182 ms, max(|w|) = 3.7e-01 ms⁻¹, wall time: 7.567 minutes
Iteration: 4520, time: 1.217 hours, Δt: 793.068 ms, max(|w|) = 3.9e-01 ms⁻¹, wall time: 7.630 minutes
Iteration: 4560, time: 1.226 hours, Δt: 714.715 ms, max(|w|) = 4.0e-01 ms⁻¹, wall time: 7.692 minutes
Iteration: 4600, time: 1.235 hours, Δt: 818.195 ms, max(|w|) = 4.1e-01 ms⁻¹, wall time: 7.755 minutes
Iteration: 4640, time: 1.244 hours, Δt: 766.368 ms, max(|w|) = 3.5e-01 ms⁻¹, wall time: 7.816 minutes
Iteration: 4680, time: 1.253 hours, Δt: 828.533 ms, max(|w|) = 3.8e-01 ms⁻¹, wall time: 7.885 minutes
Iteration: 4720, time: 1.261 hours, Δt: 794.148 ms, max(|w|) = 3.5e-01 ms⁻¹, wall time: 7.953 minutes
Iteration: 4760, time: 1.270 hours, Δt: 861.917 ms, max(|w|) = 3.8e-01 ms⁻¹, wall time: 8.020 minutes
Iteration: 4800, time: 1.279 hours, Δt: 767.546 ms, max(|w|) = 3.6e-01 ms⁻¹, wall time: 8.082 minutes
Iteration: 4840, time: 1.288 hours, Δt: 812.425 ms, max(|w|) = 3.6e-01 ms⁻¹, wall time: 8.144 minutes
Iteration: 4880, time: 1.297 hours, Δt: 795.191 ms, max(|w|) = 3.6e-01 ms⁻¹, wall time: 8.206 minutes
Iteration: 4920, time: 1.305 hours, Δt: 824.099 ms, max(|w|) = 3.5e-01 ms⁻¹, wall time: 8.268 minutes
Iteration: 4960, time: 1.314 hours, Δt: 828.677 ms, max(|w|) = 4.0e-01 ms⁻¹, wall time: 8.330 minutes
Iteration: 5000, time: 1.323 hours, Δt: 754.955 ms, max(|w|) = 4.0e-01 ms⁻¹, wall time: 8.392 minutes
Iteration: 5040, time: 1.332 hours, Δt: 834.353 ms, max(|w|) = 3.3e-01 ms⁻¹, wall time: 8.453 minutes
Iteration: 5080, time: 1.341 hours, Δt: 847.714 ms, max(|w|) = 3.4e-01 ms⁻¹, wall time: 8.515 minutes
Iteration: 5120, time: 1.350 hours, Δt: 799.129 ms, max(|w|) = 3.8e-01 ms⁻¹, wall time: 8.578 minutes
Iteration: 5160, time: 1.359 hours, Δt: 823.049 ms, max(|w|) = 3.5e-01 ms⁻¹, wall time: 8.640 minutes
Iteration: 5200, time: 1.368 hours, Δt: 841.138 ms, max(|w|) = 3.4e-01 ms⁻¹, wall time: 8.702 minutes
Iteration: 5240, time: 1.377 hours, Δt: 836.018 ms, max(|w|) = 3.6e-01 ms⁻¹, wall time: 8.766 minutes
Iteration: 5280, time: 1.386 hours, Δt: 727.201 ms, max(|w|) = 4.2e-01 ms⁻¹, wall time: 8.829 minutes
Iteration: 5320, time: 1.395 hours, Δt: 748.425 ms, max(|w|) = 3.4e-01 ms⁻¹, wall time: 8.892 minutes
Iteration: 5360, time: 1.403 hours, Δt: 806.428 ms, max(|w|) = 3.8e-01 ms⁻¹, wall time: 8.954 minutes
Iteration: 5400, time: 1.412 hours, Δt: 741.470 ms, max(|w|) = 3.4e-01 ms⁻¹, wall time: 9.016 minutes
Iteration: 5440, time: 1.420 hours, Δt: 836.759 ms, max(|w|) = 3.4e-01 ms⁻¹, wall time: 9.080 minutes
Iteration: 5480, time: 1.429 hours, Δt: 784.617 ms, max(|w|) = 3.5e-01 ms⁻¹, wall time: 9.141 minutes
Iteration: 5520, time: 1.437 hours, Δt: 830.590 ms, max(|w|) = 3.4e-01 ms⁻¹, wall time: 9.204 minutes
Iteration: 5560, time: 1.447 hours, Δt: 843.621 ms, max(|w|) = 3.4e-01 ms⁻¹, wall time: 9.265 minutes
Iteration: 5600, time: 1.455 hours, Δt: 763.887 ms, max(|w|) = 3.5e-01 ms⁻¹, wall time: 9.328 minutes
Iteration: 5640, time: 1.464 hours, Δt: 839.307 ms, max(|w|) = 3.4e-01 ms⁻¹, wall time: 9.390 minutes
Iteration: 5680, time: 1.473 hours, Δt: 726.259 ms, max(|w|) = 3.5e-01 ms⁻¹, wall time: 9.462 minutes
Iteration: 5720, time: 1.482 hours, Δt: 836.275 ms, max(|w|) = 3.5e-01 ms⁻¹, wall time: 9.525 minutes
Iteration: 5760, time: 1.491 hours, Δt: 834.119 ms, max(|w|) = 3.6e-01 ms⁻¹, wall time: 9.586 minutes
Iteration: 5800, time: 1.500 hours, Δt: 849.745 ms, max(|w|) = 3.9e-01 ms⁻¹, wall time: 9.647 minutes
Iteration: 5840, time: 1.509 hours, Δt: 762.607 ms, max(|w|) = 3.6e-01 ms⁻¹, wall time: 9.709 minutes
Iteration: 5880, time: 1.517 hours, Δt: 823.696 ms, max(|w|) = 3.7e-01 ms⁻¹, wall time: 9.773 minutes
Iteration: 5920, time: 1.526 hours, Δt: 734.049 ms, max(|w|) = 3.7e-01 ms⁻¹, wall time: 9.835 minutes
Iteration: 5960, time: 1.534 hours, Δt: 773.850 ms, max(|w|) = 3.6e-01 ms⁻¹, wall time: 9.897 minutes
Iteration: 6000, time: 1.543 hours, Δt: 731.385 ms, max(|w|) = 3.8e-01 ms⁻¹, wall time: 9.961 minutes
Iteration: 6040, time: 1.551 hours, Δt: 824.546 ms, max(|w|) = 3.5e-01 ms⁻¹, wall time: 10.024 minutes
Iteration: 6080, time: 1.560 hours, Δt: 813.278 ms, max(|w|) = 3.5e-01 ms⁻¹, wall time: 10.085 minutes
Iteration: 6120, time: 1.569 hours, Δt: 764.336 ms, max(|w|) = 3.9e-01 ms⁻¹, wall time: 10.147 minutes
Iteration: 6160, time: 1.578 hours, Δt: 794.899 ms, max(|w|) = 3.5e-01 ms⁻¹, wall time: 10.210 minutes
Iteration: 6200, time: 1.586 hours, Δt: 805.473 ms, max(|w|) = 3.5e-01 ms⁻¹, wall time: 10.273 minutes
Iteration: 6240, time: 1.595 hours, Δt: 740.834 ms, max(|w|) = 3.7e-01 ms⁻¹, wall time: 10.336 minutes
Iteration: 6280, time: 1.604 hours, Δt: 836.500 ms, max(|w|) = 3.6e-01 ms⁻¹, wall time: 10.399 minutes
Iteration: 6320, time: 1.613 hours, Δt: 727.960 ms, max(|w|) = 4.2e-01 ms⁻¹, wall time: 10.461 minutes
Iteration: 6360, time: 1.621 hours, Δt: 782.409 ms, max(|w|) = 3.6e-01 ms⁻¹, wall time: 10.522 minutes
Iteration: 6400, time: 1.630 hours, Δt: 827.816 ms, max(|w|) = 3.4e-01 ms⁻¹, wall time: 10.584 minutes
Iteration: 6440, time: 1.639 hours, Δt: 821.351 ms, max(|w|) = 3.6e-01 ms⁻¹, wall time: 10.646 minutes
Iteration: 6480, time: 1.648 hours, Δt: 813.947 ms, max(|w|) = 3.5e-01 ms⁻¹, wall time: 10.707 minutes
Iteration: 6520, time: 1.656 hours, Δt: 803.917 ms, max(|w|) = 3.7e-01 ms⁻¹, wall time: 10.769 minutes
Iteration: 6560, time: 1.665 hours, Δt: 766.209 ms, max(|w|) = 4.0e-01 ms⁻¹, wall time: 10.831 minutes
Iteration: 6600, time: 1.674 hours, Δt: 809.097 ms, max(|w|) = 4.3e-01 ms⁻¹, wall time: 10.896 minutes
Iteration: 6640, time: 1.682 hours, Δt: 762.402 ms, max(|w|) = 3.4e-01 ms⁻¹, wall time: 10.958 minutes
Iteration: 6680, time: 1.691 hours, Δt: 774.674 ms, max(|w|) = 3.8e-01 ms⁻¹, wall time: 11.021 minutes
Iteration: 6720, time: 1.700 hours, Δt: 814.001 ms, max(|w|) = 3.8e-01 ms⁻¹, wall time: 11.082 minutes
Iteration: 6760, time: 1.709 hours, Δt: 782.447 ms, max(|w|) = 3.7e-01 ms⁻¹, wall time: 11.144 minutes
Iteration: 6800, time: 1.717 hours, Δt: 837.576 ms, max(|w|) = 3.5e-01 ms⁻¹, wall time: 11.208 minutes
Iteration: 6840, time: 1.726 hours, Δt: 817.821 ms, max(|w|) = 3.5e-01 ms⁻¹, wall time: 11.271 minutes
Iteration: 6880, time: 1.735 hours, Δt: 806.993 ms, max(|w|) = 3.5e-01 ms⁻¹, wall time: 11.335 minutes
Iteration: 6920, time: 1.744 hours, Δt: 738.333 ms, max(|w|) = 3.7e-01 ms⁻¹, wall time: 11.397 minutes
Iteration: 6960, time: 1.752 hours, Δt: 769.757 ms, max(|w|) = 3.9e-01 ms⁻¹, wall time: 11.460 minutes
Iteration: 7000, time: 1.761 hours, Δt: 781.014 ms, max(|w|) = 3.4e-01 ms⁻¹, wall time: 11.522 minutes
Iteration: 7040, time: 1.769 hours, Δt: 817.568 ms, max(|w|) = 3.5e-01 ms⁻¹, wall time: 11.584 minutes
Iteration: 7080, time: 1.778 hours, Δt: 737.044 ms, max(|w|) = 3.6e-01 ms⁻¹, wall time: 11.646 minutes
Iteration: 7120, time: 1.787 hours, Δt: 820.970 ms, max(|w|) = 3.5e-01 ms⁻¹, wall time: 11.709 minutes
Iteration: 7160, time: 1.795 hours, Δt: 763.551 ms, max(|w|) = 3.6e-01 ms⁻¹, wall time: 11.771 minutes
Iteration: 7200, time: 1.804 hours, Δt: 783.490 ms, max(|w|) = 3.4e-01 ms⁻¹, wall time: 11.833 minutes
Iteration: 7240, time: 1.812 hours, Δt: 804.468 ms, max(|w|) = 3.4e-01 ms⁻¹, wall time: 11.896 minutes
Iteration: 7280, time: 1.821 hours, Δt: 772.008 ms, max(|w|) = 3.5e-01 ms⁻¹, wall time: 11.958 minutes
Iteration: 7320, time: 1.830 hours, Δt: 791.517 ms, max(|w|) = 3.5e-01 ms⁻¹, wall time: 12.020 minutes
Iteration: 7360, time: 1.838 hours, Δt: 840.431 ms, max(|w|) = 3.5e-01 ms⁻¹, wall time: 12.086 minutes
Iteration: 7400, time: 1.847 hours, Δt: 765.696 ms, max(|w|) = 3.4e-01 ms⁻¹, wall time: 12.148 minutes
Iteration: 7440, time: 1.856 hours, Δt: 711.813 ms, max(|w|) = 3.6e-01 ms⁻¹, wall time: 12.211 minutes
Iteration: 7480, time: 1.864 hours, Δt: 801.113 ms, max(|w|) = 3.4e-01 ms⁻¹, wall time: 12.274 minutes
Iteration: 7520, time: 1.873 hours, Δt: 790.549 ms, max(|w|) = 4.0e-01 ms⁻¹, wall time: 12.336 minutes
Iteration: 7560, time: 1.881 hours, Δt: 775.264 ms, max(|w|) = 3.7e-01 ms⁻¹, wall time: 12.398 minutes
Iteration: 7600, time: 1.890 hours, Δt: 786.636 ms, max(|w|) = 3.3e-01 ms⁻¹, wall time: 12.467 minutes
Iteration: 7640, time: 1.899 hours, Δt: 764.930 ms, max(|w|) = 4.3e-01 ms⁻¹, wall time: 12.530 minutes
Iteration: 7680, time: 1.907 hours, Δt: 810.768 ms, max(|w|) = 3.8e-01 ms⁻¹, wall time: 12.598 minutes
Iteration: 7720, time: 1.916 hours, Δt: 827.320 ms, max(|w|) = 3.4e-01 ms⁻¹, wall time: 12.665 minutes
Iteration: 7760, time: 1.925 hours, Δt: 765.804 ms, max(|w|) = 3.9e-01 ms⁻¹, wall time: 12.729 minutes
Iteration: 7800, time: 1.934 hours, Δt: 807.967 ms, max(|w|) = 3.7e-01 ms⁻¹, wall time: 12.804 minutes
Iteration: 7840, time: 1.942 hours, Δt: 789.084 ms, max(|w|) = 3.5e-01 ms⁻¹, wall time: 12.869 minutes
Iteration: 7880, time: 1.951 hours, Δt: 721.545 ms, max(|w|) = 3.6e-01 ms⁻¹, wall time: 12.936 minutes
Iteration: 7920, time: 1.959 hours, Δt: 733.606 ms, max(|w|) = 3.7e-01 ms⁻¹, wall time: 13.001 minutes
Iteration: 7960, time: 1.968 hours, Δt: 763.305 ms, max(|w|) = 4.2e-01 ms⁻¹, wall time: 13.068 minutes
Iteration: 8000, time: 1.976 hours, Δt: 783.890 ms, max(|w|) = 3.5e-01 ms⁻¹, wall time: 13.135 minutes
Iteration: 8040, time: 1.984 hours, Δt: 801.099 ms, max(|w|) = 3.5e-01 ms⁻¹, wall time: 13.201 minutes
Iteration: 8080, time: 1.993 hours, Δt: 776.349 ms, max(|w|) = 4.3e-01 ms⁻¹, wall time: 13.268 minutes
[ Info: Simulation is stopping after running for 13.322 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.521195, min=-0.519754, mean=9.2543e-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.1305, min=0.0, mean=18.588, 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.045, 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-28770/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-28770/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-28770/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.10
[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.