Solver & Timestep
The main GeoDynamo module exports the high-level simulation API — grids, the physical model, the simulation driver — together with the time-integration and output utilities.
At a Glance
GeoDynamo
├── Types
│ ├── SphericalShellGrid # Shell grid
│ ├── SphericalBallGrid # Ball grid
│ ├── GeodynamoModel # Physical model
│ ├── Clock # Tracks time and iteration count
│ └── Simulation # Time integration wrapper
│
├── Simulation
│ ├── run! # Main time loop
│ ├── time_step! # Advance a single step
│ ├── set! # Set initial conditions by field name
│ ├── fields # NamedTuple of all model fields
│ ├── prognostic_fields # NamedTuple of prognostic fields only
│ ├── add_callback! # Register a scheduled callback
│ ├── Callback # Scheduled callbacks
│ └── FieldWriter # Scheduled field output
│
├── GPU Backend
│ ├── register_gpu_backend! # Install a backend implementation
│ ├── with_gpu_backend # Scoped backend override
│ └── gpu_backend_loaded # Inspect backend availability
│
├── I/O
│ ├── write_fields! # Output to NetCDF
│ ├── read_restart! # Load checkpoint
│ └── CheckpointWriter # Scheduled checkpoint output
│
└── Transforms
├── shtnskit_synthesis! # Spectral → Physical
├── shtnskit_analysis! # Physical → Spectral
└── get_shtnskit_version_infowith_gpu_backend(...) can override transform and workspace hooks used by GPU-marked solver runtimes during tests or experimental backend integrations.
Public Solver API
GeoDynamo.SphericalShellGrid — Type
SphericalShellGrid(arch=CPU(); lmax, nr, mmax=lmax, nlat=3lmax÷2,
nlon=2nlat, nr_inner=max(2, nr÷4),
r_inner=0.35, r_outer=1.0)Spherical shell geometry: fluid contained between two concentric spheres (r_inner < r < r_outer), like Earth's outer core. This is the grid passed to GeodynamoModel.
Arguments
arch: compute architecture,CPU()orGPU(positional orarch=).lmax: maximum spherical-harmonic degree (required).nr: number of radial points (required).mmax: maximum order (defaults tolmax).nlat,nlon: latitude/longitude grid sizes (defaults follow the transform's anti-aliasing rule).nr_inner: radial points resolving the inner-core region.r_inner,r_outer: dimensionless shell radii (0 < r_inner < r_outer).
Example
grid = SphericalShellGrid(lmax = 31, nr = 64)GeoDynamo.SphericalBallGrid — Type
SphericalBallGrid(arch=CPU(); lmax, nr, mmax=lmax, nlat=3lmax÷2, nlon=2nlat)Full-sphere geometry: fluid filling a ball (0 ≤ r ≤ 1) with no inner boundary, like a stellar core or early planetary interior. This is the grid passed to GeodynamoModel.
Arguments
arch: compute architecture,CPU()orGPU(positional orarch=).lmax: maximum spherical-harmonic degree (required).nr: number of radial points (required).mmax: maximum order (defaults tolmax).nlat,nlon: latitude/longitude grid sizes (defaults follow the transform's anti-aliasing rule).
Unlike SphericalShellGrid there is no r_inner/nr_inner; regularity at the origin is enforced by the ball solver.
Example
grid = SphericalBallGrid(lmax = 31, nr = 48)GeoDynamo.GeodynamoModel — Type
GeodynamoModel(grid; T=Float64, Ek=1e-4, Pr=1.0, Pm=1.0, Sc=1.0, Ra=1e6,
velocity_bcs, temperature_bcs, composition_bcs,
boundary_conditions=nothing,
include_magnetic=false, include_composition=false,
initial_conditions=nothing, kwargs...)Physical model built on a SphericalShellGrid or SphericalBallGrid. It bundles the solver state, the grid, and a Clock, and is the object handed to a Simulation.
Arguments
grid: aSphericalShellGridorSphericalBallGrid.T: floating-point element type (Float64by default).Ek,Pr,Pm,Sc,Ra: Ekman, Prandtl, magnetic-Prandtl, Schmidt, and Rayleigh numbers.velocity_bcs,temperature_bcs,composition_bcs: per-field inner/outerBoundaryConditions(convenience kwargs, aliases for the NamedTuple form).boundary_conditions: Oceananigans-styleNamedTupleof BCs, e.g.(temperature = FieldBoundaryConditions(inner=…, outer=…),). Keys must be a subset of(:velocity, :temperature, :composition). Passing the same field through bothboundary_conditionsand a per-field kwarg is an error.include_magnetic,include_composition: enable the magnetic / compositional equations.initial_conditions: initial-condition spec, ornothingto start from rest.
Topography- and Stefan-coupling keywords (topography_enabled, topography_epsilon, stefan_enabled, …) are also accepted; see the configuration guide.
Example
grid = SphericalShellGrid(lmax = 31, nr = 64)
model = GeodynamoModel(grid; Ra = 1e6, include_magnetic = true)
# Oceananigans-style boundary conditions:
t_bcs = FieldBoundaryConditions(inner = ValueBoundaryCondition(1.0),
outer = ValueBoundaryCondition(0.0))
model = GeodynamoModel(grid; Ra = 1e6, boundary_conditions = (temperature = t_bcs,))GeoDynamo.Simulation — Type
mutable struct Simulation{M,C,O}Holds a GeodynamoModel together with time-stepping controls, callbacks, and output writers. Create with Simulation(model; Δt, ...) and advance with run!(sim).
GeoDynamo.Clock — Type
mutable struct Clock{T}Oceananigans-style tracker for simulation time, iteration, integrator stage, and the last timestep last_dt. A Clock is attached to each GeodynamoModel and synced after every advance via sync_clock!.
The authoritative time/step live on the solver state; this Clock is a mirror. It is correct to read between steps, not mid-step.
stage mirrors Oceananigans' multi-stage field and is reserved for future use; the current drivers are single-stage, so it stays 0.
GeoDynamo.run! — Function
run!(sim::Simulation)Advance the simulation until a stop criterion fires. Stop conditions (stop_time, stop_iteration, wall_time_limit, NaN detection) are enforced by the default callbacks registered at construction; any callback may halt the run by setting sim.running = false. Callbacks (including stop conditions) fire after each step.
GeoDynamo.time_step! — Function
time_step!(model::GeodynamoModel, dt)Advance the model by one step with timestep dt, then sync the clock.
time_step!(sim::Simulation)Advance the simulation by one step at sim.dt, firing callbacks and writers.
GeoDynamo.set! — Function
set!(model::GeodynamoModel; field = ic, ...)Oceananigans-canonical initial-condition setter. Each keyword names a field (velocity, temperature, magnetic, composition) and its value is an IC descriptor (RandomPerturbation, AnalyticIC, FileIC, ZeroIC). Dispatches each to set_initial_condition!. Returns model.
set!(model; temperature = RandomPerturbation(amplitude=0.1, lmax=10),
magnetic = AnalyticIC(:dipole; amplitude=1.0))GeoDynamo.fields — Function
fields(model::GeodynamoModel)Return a NamedTuple of all model fields: (velocity, temperature, magnetic, composition). Disabled fields are nothing.
GeoDynamo.prognostic_fields — Function
prognostic_fields(model::GeodynamoModel)Like fields but with disabled (nothing) fields removed.
GeoDynamo.add_callback! — Function
add_callback!(sim, func; schedule, name=auto)Register func(sim) to fire on schedule. Returns sim.
Lower-Level Solver API
The procedural entry points underlying the high-level Simulation/run! API.
GeoDynamo.initialize_simulation — Function
initialize_simulation(T, params::SolverParameters)Public entry point for creating a rewritten solver state with numeric element type T.
initialize_simulation(params::SolverParameters)Convenience wrapper for initialize_simulation(Float64, params).
GeoDynamo.run_simulation! — Function
run_simulation!(state::SolverState; restart_file="", restart_dir="", restart_time=0.0)Public package-facing loop driver for SolverState.
This intentionally rejects the legacy restart keywords on the rewritten solver path, because restart handling is configured directly on the new state/runtime objects before calling run_solver!.
GeoDynamo.create_solver_backend — Function
create_solver_backend(params)Validate the requested architecture and construct the backend description for a solver run.
This is the main low-level builder behind initialize_solver_state(...) and is useful for advanced workflows that want to inspect or customize backend setup before allocating fields.
GeoDynamo.initialize_solver_state — Function
initialize_solver_state([T=Float64]; params=create_solver_parameters())Construct a fully configured SolverState{T} for the rewritten solver path.
This synchronizes the public SolverParameters into the shared backend layer, builds the backend/runtime objects, activates topography, and prepares the field views and timestep caches used by the main loop.
GeoDynamo.solver_step! — Function
solver_step!(state)Advance the rewritten solver by one timestep.
The step order is:
- compute nonlinear terms
- apply topographic corrections
- apply the IMEX/ERK2 timestep update
- finalize time/step bookkeeping and diagnostics
GeoDynamo.run_solver! — Function
run_solver!(state)Run the rewritten solver until state.parameters.end_time or state.parameters.stop_iteration is reached.
Timestep And Output API
GeoDynamo.TimestepState — Type
TimestepStateLegacy-compatible timestep bookkeeping state.
This small mutable container tracks the current simulation clock, timestep, step counters, and simple convergence/error flags. It remains part of the public API because restart/output helpers and older workflows still use it even though the rewritten solver also exposes SolverTimestepState.
GeoDynamo.SHTnsImplicitMatrices — Type
SHTnsImplicitMatrices{T}Precomputed linear operators for one implicit timestep solve family.
The matrices are stored per spherical-harmonic degree l so CNAB2/IMEX style updates can reuse banded system matrices and their factorizations across many timesteps.
GeoDynamo.create_shtns_timestepping_matrices — Function
create_shtns_timestepping_matrices(config, domain, diffusivity, dt; theta=0.5, mass_coeff=1.0, T=Float64)Build the per-l implicit matrices used by the standard scalar/vector timestep operators.
The result includes the linear operator, the shifted system matrix, and a banded factorization for each spherical-harmonic degree present in config.
GeoDynamo.apply_explicit_operator! — Function
apply_explicit_operator!(output, input, nonlinear, domain, diffusivity, dt; nl_prev=nothing, matrices=nothing)Assemble the explicit right-hand side for one timestep update.
When nl_prev and matrices are supplied this builds the CNAB2/IMEX right-hand side. Otherwise it falls back to a simpler backward-Euler style explicit term used by older paths and tests.
GeoDynamo.solve_implicit_step! — Function
solve_implicit_step!(solution, rhs, matrices)Solve the implicit banded radial systems for every spherical-harmonic mode in rhs and write the updated coefficients into solution.
GeoDynamo.compute_timestep_error — Function
compute_timestep_error(new_field, old_field)Compute a simple relative update norm between two spectral fields.
This is primarily used by timestep-control and diagnostics code to quantify how large one update was compared with the previous state.
GeoDynamo.OutputConfig — Type
OutputConfigConfiguration for NetCDF history/restart output.
This groups together output layout, file naming, metadata toggles, precision, and time-based write cadence so a simulation can keep one explicit output policy object.
GeoDynamo.default_config — Function
default_config(; precision=Float64)
default_config(T)Return the default OutputConfig used by GeoDynamo’s NetCDF writer.
The positional default_config(T) form is kept as a convenience alias for call sites that already pass a floating-point type.
GeoDynamo.output_config_from_parameters — Function
output_config_from_parameters(; base_config=default_config(), output_precision=:float32, output_interval=1.0)Create an OutputConfig using simulation parameters as the source of truth for runtime-controlled output settings.
GeoDynamo.TimeTracker — Type
TimeTrackerTracks when history and restart files should next be written.
The output layer keeps this separate from the main solver state so output cadence can be tested and advanced independently from the physics timestep logic.
GeoDynamo.create_time_tracker — Function
create_time_tracker(config[, start_time=0.0])Construct a TimeTracker initialized for a run that starts at start_time.
GeoDynamo.should_output_now — Function
should_output_now(tracker, current_time, config)Return true when a history/output write should occur at current_time.
GeoDynamo.should_restart_now — Function
should_restart_now(tracker, current_time, config)Return true when a restart/checkpoint write should occur at current_time.
GeoDynamo.FieldInfo — Type
FieldInfoCompact description of the field dimensions, coordinates, and optional pencil metadata needed by the NetCDF writer.
extract_field_info(...) builds this from a field snapshot and optional transform/pencil metadata.