Breeze.jl
Fast, friendly atmosphere simulations on CPUs and GPUs.
Breeze provides software for flexible software package for finite-volume atmosphere simulations on CPUs and GPUs, based on Oceananigans. Like Oceananigans, it provides a radically productive user interface that makes simple simulations easy, and complex, creative simulations possible.
Features
Breeze provides two ways to simulate moist atmospheres:
An
AtmosphereModelwhich currently supports anelastic approximation following Pauluis (2008):AtmosphereModelhas simple warm-phase saturation adjustment microphysicsAtmosphereModelis being rapidly developed and changes day-to-day!- A roadmap is coming soon, and will include radiation, bulk, bin, and superdroplet microphysics, a fully compressible formulation, and more
A
MoistAirBuoyancybuoyancy implementation that can be used with Oceananigans'NonhydrostaticModelto simulate atmospheric flows with the Boussinesq approximation:MoistAirBuoyancyincludes a warm-phase saturation adjustment implementation- Note that our attention is focused on
AtmosphereModel!
Installation
Breeze is a registered Julia package. First install Julia; suggested version 1.12. See juliaup README for how to install 1.12 and make that version the default.
Then launch Julia and type
julia> using Pkg
julia> Pkg.add("Breeze")which will install the latest stable version of Breeze that's compatible with your current environment.
You can check which version of Breeze you got via
Pkg.status("Breeze")If you want to live on the cutting edge, you can use, e.g., Pkg.add(; url="https://github.com/NumericalEarth/Breeze.jl.git", rev="main") to install the latest version of Breeze from main branch. For more information, see the Pkg.jl documentation.
Quick Start
A basic free convection simulation with an AtmosphereModel:
using Breeze
using Oceananigans.Units
using CairoMakie
using Random: seed!
# Fix the seed to generate the noise, for reproducible simulations.
# You can try different seeds to explore different noise patterns.
seed!(42)
Nx = Nz = 64
Lz = 4 * 1024
grid = RectilinearGrid(size=(Nx, Nz), x=(0, 2Lz), z=(0, Lz), topology=(Periodic, Flat, Bounded))
p₀, θ₀ = 1e5, 288 # reference state parameters
reference_state = ReferenceState(grid, surface_pressure=p₀, potential_temperature=θ₀)
dynamics = AnelasticDynamics(reference_state)
Q₀ = 1000 # heat flux in W / m²
thermodynamic_constants = ThermodynamicConstants()
cᵖᵈ = thermodynamic_constants.dry_air.heat_capacity
ρθ_bcs = FieldBoundaryConditions(bottom=FluxBoundaryCondition(Q₀ / cᵖᵈ))
ρqᵗ_bcs = FieldBoundaryConditions(bottom=FluxBoundaryCondition(1e-2))
advection = WENO()
model = AtmosphereModel(grid; advection, dynamics, thermodynamic_constants,
boundary_conditions = (ρθ=ρθ_bcs, ρqᵗ=ρqᵗ_bcs))
Δθ = 2 # ᵒK
Tₛ = reference_state.potential_temperature # K
θᵢ(x, z) = Tₛ + Δθ * z / grid.Lz + 2e-2 * Δθ * (rand() - 0.5)
set!(model, θ=θᵢ)
simulation = Simulation(model, Δt=10, stop_time=2hours)
conjure_time_step_wizard!(simulation, cfl=0.7)
run!(simulation)
heatmap(PotentialTemperature(model), colormap=:thermal)
Due to their chaotic nature, even the smallest numerical differences can cause nonlinear systems, such as atmospheric models, not to be reproducible on different systems, therefore the figures you will get by running the simulations in this manual may not match the figures shown here. For more information about this, see the section about reproducibility.