Biogeochemistry in submesoscale eddies in the Eady model
In this example we setup a 3D model with a constant background buoyancy gradient with associated thermal wind (the Eady model) with the LOBSTER biogeochemical model. This example demonstrates how to use biogeochemistry in a more complicated physical model. The parameters in this example correspond roughly to those used by Taylor (2016) and result to the generation of a single submesoscale eddy.
Install dependencies
First we ensure we have the required dependencies installed
using Pkg
pkg "add OceanBioME, Oceananigans, CairoMakie"Model setup
We load the required packages. Although not required, we also set the random seed to ensure reproducibility of the results.
using OceanBioME, Oceananigans, Printf, CairoMakie
using Oceananigans.Units
using Random
Random.seed!(11)Random.TaskLocalRNG()Construct a grid with uniform grid spacing on CPU
grid = RectilinearGrid(size = (32, 32, 8),
extent = (1kilometer, 1kilometer, 100meters))32×32×8 RectilinearGrid{Float64, Periodic, Periodic, Bounded} on CPU with 3×3×3 halo
├── Periodic x ∈ [0.0, 1000.0) regularly spaced with Δx=31.25
├── Periodic y ∈ [0.0, 1000.0) regularly spaced with Δy=31.25
└── Bounded z ∈ [-100.0, 0.0] regularly spaced with Δz=12.5Set the Coriolis and buoyancy models.
coriolis = FPlane(f = 1e-4) # [s⁻¹]
buoyancy = SeawaterBuoyancy()SeawaterBuoyancy{Float64}:
├── gravitational_acceleration: 9.80665
└── equation_of_state: LinearEquationOfState(thermal_expansion=0.000167, haline_contraction=0.00078)Specify parameters that are used to construct the background state.
background_state_parameters = (M = 1e-4, # s⁻¹, geostrophic shear
f = coriolis.f, # s⁻¹, Coriolis parameter
N = 1e-4, # s⁻¹, buoyancy frequency
H = grid.Lz,
g = buoyancy.gravitational_acceleration,
α = buoyancy.equation_of_state.thermal_expansion)(M = 0.0001, f = 0.0001, N = 0.0001, H = 100.0, g = 9.80665, α = 0.000167)We assume a background buoyancy $B$ with a constant stratification and also a constant lateral gradient (in the zonal direction). The background velocity components $U$ and $V$ are prescribed so that the thermal wind relationship is satisfied, that is, $f \partial_z U = - \partial_y B$ and $f \partial_z V = \partial_x B$.
T(x, y, z, t, p) = (p.M^2 * x + p.N^2 * (z + p.H)) / (p.g * p.α)
V(x, y, z, t, p) = p.M^2 / p.f * (z + p.H)
V_field = BackgroundField(V, parameters = background_state_parameters)
T_field = BackgroundField(T, parameters = background_state_parameters)BackgroundField{typeof(Main.var"##142".T), @NamedTuple{M::Float64, f::Float64, N::Float64, H::Float64, g::Float64, α::Float64}}
├── func: T (generic function with 1 method)
└── parameters: (M = 0.0001, f = 0.0001, N = 0.0001, H = 100.0, g = 9.80665, α = 0.000167)Specify some horizontal and vertical viscosity and diffusivity.
νᵥ = κᵥ = 1e-4 # [m² s⁻¹]
vertical_diffusivity = VerticalScalarDiffusivity(ν = νᵥ, κ = κᵥ)VerticalScalarDiffusivity{ExplicitTimeDiscretization}(ν=0.0001, κ=0.0001)Setup the biogeochemical model with optional carbonate chemistry turned on.
biogeochemistry = LOBSTER(grid;
inorganic_carbon = CarbonateSystem(),
scale_negatives = true)
DIC_bcs = FieldBoundaryConditions(top = CarbonDioxideGasExchangeBoundaryCondition())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: DiscreteBoundaryFunction with GasExchange
└── immersed: DefaultBoundaryCondition (FluxBoundaryCondition: nothing)Model instantiation
model = NonhydrostaticModel(grid;
biogeochemistry,
boundary_conditions = (DIC = DIC_bcs, ),
advection = WENO(),
coriolis,
tracers = (:T, :S),
buoyancy,
background_fields = (T = T_field, v = V_field),
closure = vertical_diffusivity)NonhydrostaticModel{CPU, RectilinearGrid}(time = 0 seconds, iteration = 0)
├── grid: 32×32×8 RectilinearGrid{Float64, Periodic, Periodic, Bounded} on CPU with 3×3×3 halo
├── timestepper: RungeKutta3TimeStepper
├── advection scheme:
│ ├── momentum: WENO{3, Float64, Oceananigans.Utils.BackendOptimizedDivision}(order=5)
│ ├── T: WENO{3, Float64, Oceananigans.Utils.BackendOptimizedDivision}(order=5)
│ ├── S: WENO{3, Float64, Oceananigans.Utils.BackendOptimizedDivision}(order=5)
│ ├── NO₃: WENO{3, Float64, Oceananigans.Utils.BackendOptimizedDivision}(order=5)
│ ├── NH₄: WENO{3, Float64, Oceananigans.Utils.BackendOptimizedDivision}(order=5)
│ ├── P: WENO{3, Float64, Oceananigans.Utils.BackendOptimizedDivision}(order=5)
│ ├── Z: WENO{3, Float64, Oceananigans.Utils.BackendOptimizedDivision}(order=5)
│ ├── DOM: WENO{3, Float64, Oceananigans.Utils.BackendOptimizedDivision}(order=5)
│ ├── sPOM: WENO{3, Float64, Oceananigans.Utils.BackendOptimizedDivision}(order=5)
│ ├── bPOM: WENO{3, Float64, Oceananigans.Utils.BackendOptimizedDivision}(order=5)
│ ├── DIC: WENO{3, Float64, Oceananigans.Utils.BackendOptimizedDivision}(order=5)
│ └── Alk: WENO{3, Float64, Oceananigans.Utils.BackendOptimizedDivision}(order=5)
├── tracers: (T, S, NO₃, NH₄, P, Z, DOM, sPOM, bPOM, DIC, Alk)
├── closure: VerticalScalarDiffusivity{ExplicitTimeDiscretization}(ν=0.0001, κ=(T=0.0001, S=0.0001, NO₃=0.0001, NH₄=0.0001, P=0.0001, Z=0.0001, DOM=0.0001, sPOM=0.0001, bPOM=0.0001, DIC=0.0001, Alk=0.0001))
├── buoyancy: SeawaterBuoyancy with g=9.80665 and LinearEquationOfState(thermal_expansion=0.000167, haline_contraction=0.00078) with ĝ = NegativeZDirection()
└── coriolis: FPlane{Float64}(f=0.0001)Initial conditions
Start with a bit of random noise added to the background thermal wind and an arbitary biogeochemical state.
Ξ(z) = randn() * z / grid.Lz * (z / grid.Lz + 1)
Ũ = 1e-3
uᵢ(x, y, z) = Ũ * Ξ(z)
vᵢ(x, y, z) = Ũ * Ξ(z)
set!(model, u=uᵢ, v=vᵢ, P = 0.03, Z = 0.03, NO₃ = 4.0, NH₄ = 0.05, DIC = 2200.0, Alk = 2409.0, S = 35, T = 20)Setup the simulation
Choose an appropriate initial timestep for this resolution and set up the simulation
Δx = minimum_xspacing(grid, Center(), Center(), Center())
Δy = minimum_yspacing(grid, Center(), Center(), Center())
Δz = minimum_zspacing(grid, Center(), Center(), Center())
Δt₀ = 0.5 * min(Δx, Δy, Δz) / V(0, 0, 0, 0, background_state_parameters)
simulation = Simulation(model, Δt = Δt₀, stop_time = 10days)Simulation of NonhydrostaticModel{CPU, RectilinearGrid}(time = 0 seconds, iteration = 0)
├── Next time step: 10.417 minutes
├── run_wall_time: 0 seconds
├── run_wall_time / iteration: NaN days
├── stop_time: 10 days
├── 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 entriesAdapt the time step while keeping the CFL number fixed.
wizard = TimeStepWizard(cfl = 0.5, diffusive_cfl = 0.5, max_Δt = 30minutes)
simulation.callbacks[:wizard] = Callback(wizard, IterationInterval(5))Create a progress message.
progress(sim) = @printf("i: % 6d, sim time: % 10s, wall time: % 10s, Δt: % 10s, CFL: %.2e\n",
sim.model.clock.iteration,
prettytime(sim.model.clock.time),
prettytime(sim.run_wall_time),
prettytime(sim.Δt),
AdvectiveCFL(sim.Δt)(sim.model))
simulation.callbacks[:progress] = Callback(progress, IterationInterval(20))Callback of progress on IterationInterval(20)Here, we add some diagnostics to calculate and output.
u, v, w = model.velocities # unpack velocity `Field`sNamedTuple with 3 Fields on 32×32×8 RectilinearGrid{Float64, Periodic, Periodic, Bounded} on CPU with 3×3×3 halo:
├── u: 32×32×8 Field{Face, Center, Center} on RectilinearGrid on CPU
├── v: 32×32×8 Field{Center, Face, Center} on RectilinearGrid on CPU
└── w: 32×32×9 Field{Center, Center, Face} on RectilinearGrid on CPUand also calculate the vertical vorticity.
ζ = Field(∂x(v) - ∂y(u))32×32×8 Field{Face, Face, Center} on RectilinearGrid on CPU
├── grid: 32×32×8 RectilinearGrid{Float64, Periodic, Periodic, Bounded} on CPU with 3×3×3 halo
├── boundary conditions: FieldBoundaryConditions
│ └── west: Periodic, east: Periodic, south: Periodic, north: Periodic, bottom: ZeroFlux, top: ZeroFlux, immersed: Nothing
├── operand: BinaryOperation at (Face, Face, Center)
├── status: time=0.0
└── data: 38×38×14 OffsetArray(::Array{Float64, 3}, -2:35, -2:35, -2:11) with eltype Float64 with indices -2:35×-2:35×-2:11
└── max=4.88217e-5, min=-4.88463e-5, mean=7.65142e-24Periodically save the velocities and vorticity to a file.
simulation.output_writers[:fields] = JLD2Writer(model, merge(model.tracers, (; u, v, w, ζ));
schedule = TimeInterval(2hours),
filename = "eady_turbulence_bgc",
overwrite_files = true)
Run the simulation
run!(simulation)[ Info: Initializing simulation...
i: 0, sim time: 0 seconds, wall time: 0 seconds, Δt: 11.458 minutes, CFL: 2.17e-01
[ Info: ... simulation initialization complete (16.289 seconds)
[ Info: Executing initial time step...
[ Info: ... initial time step complete (1.588 seconds).
i: 20, sim time: 4.254 hours, wall time: 18.500 seconds, Δt: 16.776 minutes, CFL: 3.13e-01
i: 40, sim time: 10 hours, wall time: 19.200 seconds, Δt: 24.562 minutes, CFL: 4.66e-01
i: 60, sim time: 18 hours, wall time: 19.884 seconds, Δt: 25.213 minutes, CFL: 5.00e-01
i: 80, sim time: 1.082 days, wall time: 20.726 seconds, Δt: 23.606 minutes, CFL: 5.00e-01
i: 100, sim time: 1.350 days, wall time: 21.404 seconds, Δt: 23.733 minutes, CFL: 5.00e-01
i: 120, sim time: 1.632 days, wall time: 22.057 seconds, Δt: 23.224 minutes, CFL: 5.00e-01
i: 140, sim time: 1.911 days, wall time: 22.708 seconds, Δt: 21.906 minutes, CFL: 5.00e-01
i: 160, sim time: 2.182 days, wall time: 23.375 seconds, Δt: 21.011 minutes, CFL: 5.00e-01
i: 180, sim time: 2.443 days, wall time: 24.006 seconds, Δt: 18.832 minutes, CFL: 5.00e-01
i: 200, sim time: 2.679 days, wall time: 24.589 seconds, Δt: 16.676 minutes, CFL: 5.00e-01
i: 220, sim time: 2.887 days, wall time: 25.149 seconds, Δt: 14.988 minutes, CFL: 5.00e-01
i: 240, sim time: 3.078 days, wall time: 25.711 seconds, Δt: 13.396 minutes, CFL: 5.00e-01
i: 260, sim time: 3.244 days, wall time: 26.274 seconds, Δt: 11.870 minutes, CFL: 5.00e-01
i: 280, sim time: 3.393 days, wall time: 26.853 seconds, Δt: 10.587 minutes, CFL: 5.00e-01
i: 300, sim time: 3.527 days, wall time: 27.453 seconds, Δt: 9.913 minutes, CFL: 5.00e-01
i: 320, sim time: 3.655 days, wall time: 27.997 seconds, Δt: 9.371 minutes, CFL: 5.00e-01
i: 340, sim time: 3.775 days, wall time: 28.671 seconds, Δt: 8.650 minutes, CFL: 5.00e-01
i: 360, sim time: 3.892 days, wall time: 29.275 seconds, Δt: 8.412 minutes, CFL: 5.00e-01
i: 380, sim time: 4 days, wall time: 29.878 seconds, Δt: 8.320 minutes, CFL: 5.00e-01
i: 400, sim time: 4.111 days, wall time: 30.505 seconds, Δt: 7.907 minutes, CFL: 5.00e-01
i: 420, sim time: 4.214 days, wall time: 31.107 seconds, Δt: 7.480 minutes, CFL: 5.00e-01
i: 440, sim time: 4.318 days, wall time: 31.683 seconds, Δt: 7.526 minutes, CFL: 5.00e-01
i: 460, sim time: 4.422 days, wall time: 32.289 seconds, Δt: 7.871 minutes, CFL: 5.00e-01
i: 480, sim time: 4.527 days, wall time: 32.869 seconds, Δt: 8.097 minutes, CFL: 5.00e-01
i: 500, sim time: 4.639 days, wall time: 33.472 seconds, Δt: 7.984 minutes, CFL: 5.00e-01
i: 520, sim time: 4.750 days, wall time: 34.073 seconds, Δt: 8.011 minutes, CFL: 5.00e-01
i: 540, sim time: 4.861 days, wall time: 34.692 seconds, Δt: 8.154 minutes, CFL: 5.00e-01
i: 560, sim time: 4.974 days, wall time: 35.292 seconds, Δt: 8.200 minutes, CFL: 5.00e-01
i: 580, sim time: 5.083 days, wall time: 35.893 seconds, Δt: 8.269 minutes, CFL: 5.00e-01
i: 600, sim time: 5.196 days, wall time: 36.518 seconds, Δt: 8.354 minutes, CFL: 5.00e-01
i: 620, sim time: 5.310 days, wall time: 37.120 seconds, Δt: 8.920 minutes, CFL: 5.00e-01
i: 640, sim time: 5.422 days, wall time: 37.745 seconds, Δt: 8.347 minutes, CFL: 5.00e-01
i: 660, sim time: 5.534 days, wall time: 38.344 seconds, Δt: 8.411 minutes, CFL: 5.00e-01
i: 680, sim time: 5.649 days, wall time: 38.943 seconds, Δt: 8.843 minutes, CFL: 5.00e-01
i: 700, sim time: 5.768 days, wall time: 39.566 seconds, Δt: 8.812 minutes, CFL: 5.00e-01
i: 720, sim time: 5.891 days, wall time: 40.163 seconds, Δt: 9.249 minutes, CFL: 5.00e-01
i: 740, sim time: 6.006 days, wall time: 40.787 seconds, Δt: 9.183 minutes, CFL: 5.00e-01
i: 760, sim time: 6.128 days, wall time: 41.388 seconds, Δt: 8.891 minutes, CFL: 5.00e-01
i: 780, sim time: 6.244 days, wall time: 41.986 seconds, Δt: 8.231 minutes, CFL: 5.00e-01
i: 800, sim time: 6.350 days, wall time: 42.609 seconds, Δt: 7.611 minutes, CFL: 5.00e-01
i: 820, sim time: 6.452 days, wall time: 43.208 seconds, Δt: 6.961 minutes, CFL: 5.00e-01
i: 840, sim time: 6.541 days, wall time: 43.808 seconds, Δt: 6.371 minutes, CFL: 5.00e-01
i: 860, sim time: 6.625 days, wall time: 44.407 seconds, Δt: 5.858 minutes, CFL: 5.00e-01
i: 880, sim time: 6.702 days, wall time: 45.005 seconds, Δt: 5.618 minutes, CFL: 5.00e-01
i: 900, sim time: 6.777 days, wall time: 45.609 seconds, Δt: 5.491 minutes, CFL: 5.00e-01
i: 920, sim time: 6.848 days, wall time: 46.209 seconds, Δt: 5.380 minutes, CFL: 5.00e-01
i: 940, sim time: 6.920 days, wall time: 46.810 seconds, Δt: 5.594 minutes, CFL: 5.00e-01
i: 960, sim time: 6.999 days, wall time: 47.387 seconds, Δt: 5.838 minutes, CFL: 5.00e-01
i: 980, sim time: 7.079 days, wall time: 47.988 seconds, Δt: 6.216 minutes, CFL: 5.00e-01
i: 1000, sim time: 7.166 days, wall time: 48.585 seconds, Δt: 6.438 minutes, CFL: 5.00e-01
i: 1020, sim time: 7.250 days, wall time: 49.186 seconds, Δt: 6.484 minutes, CFL: 5.00e-01
i: 1040, sim time: 7.333 days, wall time: 49.785 seconds, Δt: 6.003 minutes, CFL: 5.00e-01
i: 1060, sim time: 7.414 days, wall time: 50.386 seconds, Δt: 5.493 minutes, CFL: 5.00e-01
i: 1080, sim time: 7.488 days, wall time: 50.985 seconds, Δt: 5.218 minutes, CFL: 5.00e-01
i: 1100, sim time: 7.557 days, wall time: 51.587 seconds, Δt: 5.007 minutes, CFL: 5.00e-01
i: 1120, sim time: 7.624 days, wall time: 52.186 seconds, Δt: 4.821 minutes, CFL: 5.00e-01
i: 1140, sim time: 7.690 days, wall time: 52.789 seconds, Δt: 4.893 minutes, CFL: 5.00e-01
i: 1160, sim time: 7.757 days, wall time: 53.387 seconds, Δt: 5.068 minutes, CFL: 5.00e-01
i: 1180, sim time: 7.825 days, wall time: 53.960 seconds, Δt: 4.714 minutes, CFL: 5.00e-01
i: 1200, sim time: 7.888 days, wall time: 54.555 seconds, Δt: 4.634 minutes, CFL: 5.00e-01
i: 1220, sim time: 7.951 days, wall time: 55.156 seconds, Δt: 4.362 minutes, CFL: 5.00e-01
i: 1240, sim time: 8.009 days, wall time: 55.753 seconds, Δt: 4.225 minutes, CFL: 5.00e-01
i: 1260, sim time: 8.068 days, wall time: 56.334 seconds, Δt: 4.295 minutes, CFL: 5.00e-01
i: 1280, sim time: 8.126 days, wall time: 56.934 seconds, Δt: 4.490 minutes, CFL: 5.00e-01
i: 1300, sim time: 8.186 days, wall time: 57.533 seconds, Δt: 4.547 minutes, CFL: 5.00e-01
i: 1320, sim time: 8.249 days, wall time: 58.103 seconds, Δt: 4.673 minutes, CFL: 5.00e-01
i: 1340, sim time: 8.312 days, wall time: 58.689 seconds, Δt: 4.785 minutes, CFL: 5.00e-01
i: 1360, sim time: 8.377 days, wall time: 59.285 seconds, Δt: 4.861 minutes, CFL: 5.00e-01
i: 1380, sim time: 8.444 days, wall time: 59.873 seconds, Δt: 4.913 minutes, CFL: 5.00e-01
i: 1400, sim time: 8.510 days, wall time: 1.008 minutes, Δt: 5.043 minutes, CFL: 5.00e-01
i: 1420, sim time: 8.581 days, wall time: 1.017 minutes, Δt: 5.255 minutes, CFL: 5.00e-01
i: 1440, sim time: 8.655 days, wall time: 1.027 minutes, Δt: 5.641 minutes, CFL: 5.00e-01
i: 1460, sim time: 8.731 days, wall time: 1.037 minutes, Δt: 5.806 minutes, CFL: 5.00e-01
i: 1480, sim time: 8.812 days, wall time: 1.047 minutes, Δt: 5.957 minutes, CFL: 5.00e-01
i: 1500, sim time: 8.890 days, wall time: 1.057 minutes, Δt: 5.752 minutes, CFL: 5.00e-01
i: 1520, sim time: 8.967 days, wall time: 1.067 minutes, Δt: 5.507 minutes, CFL: 5.00e-01
i: 1540, sim time: 9.042 days, wall time: 1.077 minutes, Δt: 5.519 minutes, CFL: 5.00e-01
i: 1560, sim time: 9.117 days, wall time: 1.087 minutes, Δt: 5.435 minutes, CFL: 5.00e-01
i: 1580, sim time: 9.189 days, wall time: 1.097 minutes, Δt: 5.387 minutes, CFL: 5.00e-01
i: 1600, sim time: 9.261 days, wall time: 1.106 minutes, Δt: 5.404 minutes, CFL: 5.00e-01
i: 1620, sim time: 9.333 days, wall time: 1.116 minutes, Δt: 5.404 minutes, CFL: 5.00e-01
i: 1640, sim time: 9.408 days, wall time: 1.126 minutes, Δt: 5.412 minutes, CFL: 5.00e-01
i: 1660, sim time: 9.481 days, wall time: 1.136 minutes, Δt: 5.496 minutes, CFL: 5.00e-01
i: 1680, sim time: 9.554 days, wall time: 1.146 minutes, Δt: 5.575 minutes, CFL: 5.00e-01
i: 1700, sim time: 9.631 days, wall time: 1.156 minutes, Δt: 5.960 minutes, CFL: 5.00e-01
i: 1720, sim time: 9.712 days, wall time: 1.166 minutes, Δt: 5.975 minutes, CFL: 5.00e-01
i: 1740, sim time: 9.791 days, wall time: 1.176 minutes, Δt: 5.856 minutes, CFL: 5.00e-01
i: 1760, sim time: 9.869 days, wall time: 1.186 minutes, Δt: 5.720 minutes, CFL: 5.00e-01
i: 1780, sim time: 9.944 days, wall time: 1.196 minutes, Δt: 5.459 minutes, CFL: 5.00e-01
[ Info: Simulation is stopping after running for 1.203 minutes.
[ Info: Simulation time 10 days equals or exceeds stop time 10 days.
Now load the saved output,
ζ = FieldTimeSeries("eady_turbulence_bgc.jld2", "ζ")
P = FieldTimeSeries("eady_turbulence_bgc.jld2", "P")
NO₃ = FieldTimeSeries("eady_turbulence_bgc.jld2", "NO₃")
NH₄ = FieldTimeSeries("eady_turbulence_bgc.jld2", "NH₄")
DIC = FieldTimeSeries("eady_turbulence_bgc.jld2", "DIC")
times = ζ.times
xζ, yζ, zζ = nodes(ζ)
xc, yc, zc = nodes(P)and build the frames,
n = Observable(1)
Nz = grid.Nz
ζₙ = @lift interior( ζ[$n], :, :, Nz)
Nₙ = @lift interior(NO₃[$n], :, :, Nz) .+ interior(NH₄[$n], :, :, Nz)
Pₙ = @lift interior( P[$n], :, :, Nz)
DICₙ = @lift interior(DIC[$n], :, :, Nz)Observable([2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0; 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0; 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0; 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0; 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0; 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0; 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0; 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0; 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0; 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0; 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0; 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0; 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0; 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0; 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0; 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0; 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0; 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0; 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0; 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0; 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0; 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0; 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0; 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0; 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0; 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0; 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0; 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0; 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0; 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0; 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0; 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0 2200.0])
now plot
fig = Figure(size = (1600, 1600), fontsize = 20)
lims = [(minimum(T), maximum(T)) for T in ( ζ[:, :, Nz, :],
NO₃[:, :, Nz, :] .+ NH₄[:, :, Nz, :],
P[:, :, Nz, :],
DIC[:, :, Nz, :])]
axis_kwargs = (xlabel = "x (m)", ylabel = "y (m)", aspect = DataAspect())
ax1 = Axis(fig[1, 1]; title = "Vertical vorticity (1 / s)", axis_kwargs...)
hm1 = heatmap!(ax1, xζ, yζ, ζₙ, colormap = :balance, colorrange = lims[1])
Colorbar(fig[1, 2], hm1)
ax2 = Axis(fig[1, 3]; title = "Nutrient (NO₃ + NH₄) concentration (mmol N / m³)", axis_kwargs...)
hm2 = heatmap!(ax2, xc, yc, Nₙ, colormap = Reverse(:bamako), colorrange = lims[2])
Colorbar(fig[1, 4], hm2)
ax3 = Axis(fig[2, 1]; title = "Phytoplankton concentration (mmol N / m³)", axis_kwargs...)
hm3 = heatmap!(ax3, xc, yc, Pₙ, colormap = Reverse(:batlow), colorrange = lims[3])
Colorbar(fig[2, 2], hm3)
ax4 = Axis(fig[2, 3]; title = "Dissolved inorganic carbon (mmol C / m³)", axis_kwargs...)
hm4 = heatmap!(ax4, xc, yc, DICₙ, colormap = Reverse(:devon), colorrange = lims[4])
Colorbar(fig[2, 4], hm4)
title = @lift "t = $(prettytime(times[$n]))"
Label(fig[0, :], title, fontsize = 30)Label()and record the movie
record(fig, "eady.mp4", 1:length(times), framerate = 12) do i
n[] = i
end"eady.mp4"This page was generated using Literate.jl.