Open-source project
CliMA/Oceananigans.jl avatar
CliMA/Oceananigans.jl

Oceananigans.jl: Finite Volume Boussinesq Simulations in Julia on CPU and GPU

🌊 Julia software for fast, friendly, flexible, ocean-flavored fluid dynamics on CPUs and GPUs

1,412 stars296 forksJuliaMIT

At a glance

What is it?
Oceananigans.jl solves the nonhydrostatic and hydrostatic Boussinesq equations with finite volumes on CPUs and GPUs. Its appeal is a user interface flexible enough for creative configurations, and that same flexibility is where the learning curve sits.
Who is it for?
Adopt Oceananigans if you write Julia, need to modify the governing equations or parameterisations, and want the same script to run on a laptop CPU and a CUDA GPU by swapping CPU() for GPU(). Do not adopt it if your workflow is built around a Fortran configuration file, or if you need a mature, widely documented ecosystem of published setups.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly Julia, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The gap Oceananigans fills between hand-written solvers and packaged climate models

The README describes Oceananigans as a package for finite volume simulations of the nonhydrostatic and hydrostatic Boussinesq equations on CPUs and GPUs. That sentence contains the whole positioning. It is not a full Earth system model and it is not a general-purpose CFD suite. It is a solver for one family of equations, written so that the equations and their discretisation stay visible and editable in user code. The stated audience is the person who needs to change the physics, not just the parameters. The README says development is community-driven with contributors from academia and industry, and points to a jobs discussion category for developer and user opportunities, which suggests a research group culture rather than a product team. If your problem is incompressible stratified flow in a Cartesian box or a spherical shell, and you want to express your configuration as Julia code rather than as a namelist, this is the target use case. If you need biogeochemistry coupled to a full general circulation model, look elsewhere first.

How a model is assembled: grid, model, simulation

The mechanism is visible in the README's first example. Four objects carry the whole workflow. RectilinearGrid(CPU(), size=(128, 128), x=(0, 2π), y=(0, 2π), topology=(Periodic, Periodic, Flat)) defines the domain, the resolution, the extents and the boundary topology per axis, with Flat collapsing a dimension. NonhydrostaticModel(grid; advection=WENO()) attaches a set of equations and a numerical scheme to that grid. set!(model, u=ϵ, v=ϵ) writes initial conditions directly into the model fields, here from a closure that returns 2rand() - 1 per point. Simulation(model; Δt=0.01, stop_time=4) wraps the model with a time step and a stopping criterion, and run!(simulation) executes it. The data flow is therefore: grid supplies geometry, model holds state and tendencies, set! populates state, simulation owns the time loop. Nothing about that sequence is hidden behind a configuration file, which is the point. It also means the user is responsible for choosing Δt and for knowing whether the advection scheme suits the flow. WENO() is selected explicitly in the example, so the default is not being relied on there.

CPU to GPU is a one-token change, with conditions attached

The README states that loading CUDA.jl via using CUDA and changing CPU() to GPU() makes the example run on a CUDA-enabled Nvidia GPU. That is an unusually small migration step, and it is the clearest concrete advantage the package claims. The conditions are implicit but real. The change is CUDA-specific, so this is not a vendor-neutral accelerator story; the README names Nvidia and CUDA.jl and nothing else. The grid constructor is where the device is chosen, so every place a grid is built is a place the choice must be made consistently. And the README links a performance dashboard and a paper on GPU performance rather than quoting a speedup figure, which is the honest way to present it: the magnitude depends on the problem, and the repository does not put a number in the README. Anyone evaluating this should treat the GPU path as a documented capability with a documented entry point, not as a guaranteed multiplier.

Installing it, and the version trap in Pkg.add

Installation is the standard registered-package route. Download Julia, version 1.10 or later per the README, then run using Pkg followed by Pkg.add("Oceananigans"). The README is explicit that this installs the latest version compatible with your current environment, and it follows that with a warning to check which Oceananigans you installed using Pkg.status("Oceananigans"). That warning is worth taking literally. The release list shows a rapid cadence: v0.112.0 on 2026-09-08, v0.111.0 on 2026-08-31, v0.110.20 on 2026-08-27. Three releases in under two weeks, all in the 0.x series. There is no 1.0, so the API carries no stability promise, and a script written against one minor version may need edits against the next. Pinning the version in your project environment, and recording it alongside results, is the practical response. The package is MIT licensed, which is permissive and places few obligations on redistribution, but the licence text itself is the authority and this is not legal advice.

Where the flexibility turns into a cost

The README's own framing is that the interface makes simple simulations easy and complex, creative simulations possible. The second half of that sentence is the limitation. A creative interface means fewer guardrails. The example sets Δt=0.01 and stop_time=4 by hand with no stability guidance attached to those numbers, and it builds initial conditions from a random closure. Nothing in the supplied material tells you how to diagnose a blow-up, how to choose between advection schemes, or what the defaults are when advection is not passed. The knowledge base section points to discussions covering computational science and experimental features, the latter described as new and sparsely-documented features. That is a candid admission that parts of the surface area are ahead of the documentation. The second constraint is language. Oceananigans is Julia, and adopting it means your team writes Julia, debugs Julia type and compilation behaviour, and manages Julia environments. A group whose tooling and staff are Fortran-first will pay a real transition cost that has nothing to do with fluid dynamics. The third is scope: Cartesian and spherical shell domains, incompressible, Boussinesq. Problems outside that envelope are not a configuration change away.

Compared with the MITgcm route

The natural alternative for someone reading this is MITgcm, the long-established Fortran solver for ocean and atmosphere problems. The difference is not performance, which neither README lets you compare directly. The difference is where the configuration lives. MITgcm setups are assembled from Fortran source and runtime parameter files, and a large body of published configurations exists in that form, which is a genuine advantage when you want to reproduce someone else's experiment. Oceananigans puts the configuration in the same language as the solver, so a custom tracer, a modified boundary condition or a new parameterisation is a Julia function rather than a source patch and a rebuild. That is a better fit for method development and a worse fit for reproducing a legacy setup unchanged. The GPU story differs too: the README presents CPU-to-GPU as a constructor argument, whereas the Fortran route typically means a separate build and a different code path. Neither approach is universally right; the deciding question is whether your work is mostly reconfiguring an established model or mostly writing new physics.

Maintenance burden and what the release cadence implies

The material supports a rough maintenance estimate without any guesswork. Three 0.x releases in the final two weeks of the recorded period, and a last push date of 2026-09-10, indicate active development rather than a frozen codebase. For a user, that means upgrade work is ongoing, not occasional. The mitigation is Julia's own tooling: a project environment that pins Oceananigans to a specific version, and Pkg.status to confirm what is actually loaded, both of which the README already puts in front of you. Budget for reading release notes before bumping the version in a production setup. On licensing, MIT is permissive and imposes essentially no constraint on how you use or redistribute the software, but dependencies pulled in through Pkg.add carry their own licences, and those are not described in the README. If you are shipping a product rather than publishing a paper, audit the full dependency tree in your Manifest.toml rather than assuming the top-level MIT badge covers everything.

Editorial conclusion

Adopt Oceananigans if you write Julia, need to modify the governing equations or parameterisations, and want the same script to run on a laptop CPU and a CUDA GPU by swapping CPU() for GPU(). Do not adopt it if your workflow is built around a Fortran configuration file, or if you need a mature, widely documented ecosystem of published setups. Before committing, verify that your Julia version is 1.10 or later, check which Oceananigans version Pkg.status reports, and confirm that the advection scheme and grid topology you need are covered by the current documentation rather than by an experimental-features discussion thread.

Official sources

  1. CliMA/Oceananigans.jl on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
Community notes

Community notes