Ocean Biogeochemical Modelling Environment - OceanBioME
OceanBioME.jl is a fast and flexible ocean biogeochemical modelling environment. It is highly modular and is designed to make it easy to implement and use a variety of biogeochemical and physical models. OceanBioME is built to be coupled with physics models from Oceananigans.jl allowing simulations across a wide range of spatial scales ranging from a global hydrostatic free surface model to non-hydrostatic large-eddy simulations. OceanBioME was designed specifically for ocean carbon dioxide removal applications. Notably, it includes active particles which allow individual-based models to be seamlessly coupled with the flow physics, ecosystem models, and carbonate chemistry.
OceanBioME.jl currently provides a core of several biogeochemical models (Nutrient–Phytoplankton–Zooplankton–Detritus (NPZD) and LOBSTER, a medium complexity model, air-sea gas exchange models to provide appropriate top boundary conditions, and sediment models to for the benthic boundary. PISCES and other higher complexity models are in our future development plans.
OceanBioME.jl includes a framework for integrating the growth of biological/active Lagrangian particles which move around and can interact with the (Eulerian) tracer fields - for example, consuming nutrients and carbon dioxide while releasing dissolved organic material. A growth model for sugar kelp is currently implemented using active particles, and this model can be used in a variety of dynamical scenarios including free-floating or bottom-attached particles.
Quick install
OceanBioME is a registered Julia package. So to install it,
Launch Julia and type
julia> using Pkg
julia> Pkg.add("OceanBioME")
OceanBioME.jl requires Julia version 1.9 or later.
Running your first model
As a simple example lets run a Nutrient-Phytoplankton-Zooplankton-Detritus (NPZD) model in a two-dimensional simulation of a buoyancy front. This example requires Oceananigans, so we install that first:
using Pkg; Pkg.add("Oceananigans")
using OceanBioME, Oceananigans
using Oceananigans.Units
grid = RectilinearGrid(CPU(), size = (160, 32), extent = (10000meters, 500meters), topology = (Bounded, Flat, Bounded))
biogeochemistry = NutrientPhytoplanktonZooplanktonDetritus(; grid)
model = NonhydrostaticModel(; grid, biogeochemistry,
advection = WENO(; grid),
closure = AnisotropicMinimumDissipation(),
buoyancy = SeawaterBuoyancy(constant_salinity = true))
@inline front(x, z, μ, δ) = μ + δ * tanh((x - 7000 + 4 * z) / 500)
Pᵢ(x, y, z) = ifelse(z > -50, 0.03, 0.01)
Nᵢ(x, y, z) = front(x, z, 2.5, -2)
Tᵢ(x, y, z) = front(x, z, 9, 0.05)
set!(model, N = Nᵢ, P = Pᵢ, Z = Pᵢ, T = Tᵢ)
simulation = Simulation(model; Δt = 50, stop_time = 4days)
simulation.output_writers[:tracers] = JLD2OutputWriter(model, model.tracers,
filename = "buoyancy_front.jld2",
schedule = TimeInterval(24minute),
overwrite_existing = true)
run!(simulation)
Updating registry at `~/.julia/registries/General.toml`
Resolving package versions...
No Changes to `~/work/OceanBioME.jl/OceanBioME.jl/docs/Project.toml`
No Changes to `~/work/OceanBioME.jl/OceanBioME.jl/docs/Manifest.toml`
[ Info: Initializing simulation...
[ Info: ... simulation initialization complete (1.834 seconds)
[ Info: Executing initial time step...
[ Info: ... initial time step complete (32.766 seconds).
[ Info: Simulation is stopping after running for 3.440 minutes.
[ Info: Simulation time 4 days equals or exceeds stop time 4 days.
We can then load the saved output and visualize it:
T = FieldTimeSeries("buoyancy_front.jld2", "T")
N = FieldTimeSeries("buoyancy_front.jld2", "N")
P = FieldTimeSeries("buoyancy_front.jld2", "P")
xc, yc, zc = nodes(T)
times = T.times
using CairoMakie
n = Observable(1)
T_lims = (8.94, 9.06)
N_lims = (0, 4.5)
P_lims = (0.007, 0.02)
Tₙ = @lift interior(T[$n], :, 1, :)
Nₙ = @lift interior(N[$n], :, 1, :)
Pₙ = @lift interior(P[$n], :, 1, :)
fig = Figure(resolution = (1000, 520), fontsize = 20)
title = @lift "t = $(prettytime(times[$n]))"
Label(fig[0, :], title)
axis_kwargs = (xlabel = "x (m)", ylabel = "z (m)", width = 770, yticks = [-400, -200, 0])
ax1 = Axis(fig[1, 1]; title = "Temperature (°C)", axis_kwargs...)
ax2 = Axis(fig[2, 1]; title = "Nutrients concentration (mmol N / m³)",axis_kwargs...)
ax3 = Axis(fig[3, 1]; title = "Phytoplankton concentration (mmol N / m³)", axis_kwargs...)
hm1 = heatmap!(ax1, xc, zc, Tₙ, colorrange = T_lims, colormap = Reverse(:lajolla), interpolate = true)
hm2 = heatmap!(ax2, xc, zc, Nₙ, colorrange = N_lims, colormap = Reverse(:bamako), interpolate = true)
hm3 = heatmap!(ax3, xc, zc, Pₙ, colorrange = P_lims, colormap = Reverse(:bamako), interpolate = true)
Colorbar(fig[1, 2], hm1, ticks = [8.95, 9.0, 9.05])
Colorbar(fig[2, 2], hm2, ticks = [0, 2, 4])
Colorbar(fig[3, 2], hm3, ticks = [0.01, 0.02, 0.03])
rowgap!(fig.layout, 0)
record(fig, "buoyancy_front.mp4", 1:length(times)) do i
n[] = i
end
In the example above, OceanBioME.jl
provides the biogeochemistry
and everything else is taken care of by Oceananigans.jl
. For comprehensive documentation of the physics modelling see Oceananigans' Documentation; for biogeochemistry and other features we provide read below.
Places to find OceanBioME information
This documentation, which provides
- documented examples (browse them starting, e.g., from the single-column model),
- explanations of model implementation methods,
- details of currently implemented models, and
- a library documenting all user-facing objects and functions.
Discussions on the OceanBioME github
If you've got a question or something to talk about, don't hesitate to start a new discussion!
Issues and pull requests also contain lots of information about problems we've found, solutions we're trying to implement, and ideas for the future.
Getting in touch
Whether you need help getting started with OceanBioME, found a bug, want OceanBioME to be more expanded, or just want to chat about our project, you can:
- Start a discussion.
- Open an issue. Issues are best if you think the OceanBioME source code needs attention: a bug, a sign error, an important missing feature, or a typo in the documentation.
Citing
If you use OceanBioME as part of your research, teaching, or other activities, we would be grateful if you could cite our work and mention OceanBioME by name, as well as citing and acknowledging Oceananigans as without them this package would not be possible.
We do not currently have a citation for OceanBioME so please reach out if you wish to cite it, and we will expedite the process of making it citable.
Funding
OceanBioME.jl is supported through grants from the Center for Climate Repair at Cambridge and the Gordon and Betty Moore Foundation.