Externalised public API

This page lists the public API of externalised modules, which are not part of the core package. These modules are optional and can be used to extend the functionality of FastIsostasy.jl by using pkg with pkg the package that triggers the extension.

Makie utilities

FastIsostasy.plot_transectFunction
plot_transect(sim::Simulation, vars;
    ii = sim.domain.mx:sim.domain.nx,
    jj = sim.domain.my,
    analytic_cylinder_solution = false)

Plot the results of a FastIsostasy simulation along a transect. The transect is defined by the indices ii and jj, which specify the range of grid points to plot. The vars argument specifies which variables to plot (e.g., :u, :h, etc.). If analytic_cylinder_solution is set to true, the function will also plot the analytical solution for a cylindrical load.

source
FastIsostasy.plot_loadFunction
plot_load(domain, H_ice)

Plot the ice load as a function of position. The domain argument specifies the spatial domain of the simulation, and H_ice is a matrix representing the ice thickness at each grid point.

source
FastIsostasy.plot_earthFunction
plot_earth(sim::Simulation)
plot_earth(domain, solidearth)

Plot the solid-Earth parameters used in the simulation.

source
FastIsostasy.plot_out_at_timeFunction
plot_out_at_time(sim, vars, t)

Plot the output of a FastIsostasy simulation at a specific time t. The vars argument specifies which variables to plot.

source
FastIsostasy.plot_out_over_timeFunction
plot_out_over_time(sim, var, t_vec, copts)

Plot the output of a FastIsostasy simulation for a specific variable var over a range of times specified in t_vec. The copts argument can be used to customize the plot (e.g., colors, line styles, etc.).

source
FastIsostasy.plot_computation_timeFunction
plot_computation_time(sim)

Plot the simulation year as a function of computation time. This can be useful for assessing the performance of the simulation.

source

AD and inversion

FastIsostasy can be differentiated with Enzyme and run backwards: given observations of the surface, infer the ice load or the solid-Earth parameters that produced them. Loading Enzyme activates the AD extension; reverse mode additionally needs Checkpointing, and solve! needs Optim. Worked examples: Inverse ice history, Inverse calibration and Full-field viscosity inversion.

Note that AD requires a fixed-step integrator (EulerIntegrator) and a SmoothTransition.

Inversion problems

FastIsostasy.IceLoadInversionType
IceLoadInversion(sim, encoding, observations; regularizations = (),
    diffmode = TangentMode(), lossmodel = DefaultLoss())

Infer an unknown ice load (and, jointly, solid-Earth parameters) from surface observations. encoding maps the parameter vector θ onto the ice-thickness snapshots and any other model inputs via reconstruct! — e.g. Test1Encoding, which writes time-varying Vialov domes plus a viscosity field.

Arguments and keywords are shared with ParameterInversion:

See also loss, gradient!, solve!.

source
FastIsostasy.ParameterInversionType
ParameterInversion(sim, encoding, observations; regularizations = (),
    diffmode = TangentMode(), lossmodel = DefaultLoss())

Calibrate solid-Earth parameters (mantle viscosity, densities, …) against observed deformation, with the ice load held known and fixed. Same fields and keywords as IceLoadInversion; the two differ only in intent.

The encoding decides the parameterization:

  • an AbstractEncoding such as Test2Encoding reduces the unknowns to a handful of numbers (a background viscosity plus Gaussian anomalies and densities), which suits TangentMode;
  • nothing selects full-field control: θ is the flattened log10 effective-viscosity field (column-major, so reshape(θ, size(domain.X)) is the map) and the physical field is 10^θ. There is then one unknown per grid cell, which is only affordable with AdjointMode, whose gradient cost is independent of length(θ).

See also loss, gradient!, solve!.

source
FastIsostasy.lossFunction
loss(prob, θ) -> scalar

Decode θ into prob.sim, run the forward model to every observation time, and return misfit(prob.lossmodel, preds, prob.observations) plus the regularization penalties. This is the AD-free objective the diff engines differentiate.

source
FastIsostasy.gradient!Function
gradient!(g, prob, θ)

In-place gradient of loss(prob, θ) w.r.t. θ. Dispatches on prob.diffmode (TangentMode → forward, AdjointMode → checkpointed reverse), implemented by the Enzyme extension. The 3-arg dispatcher lives in core (so it always resolves); the mode-specific 4-arg method falls back to an informative error here and is overridden by the extension once loaded.

source
FastIsostasy.loss_and_gradient!Function
loss_and_gradient!(g, prob, θ) -> loss_value

In-place gradient of loss(prob, θ) w.r.t. θ, written into g, returning the loss value alongside it. Under TangentMode the primal falls out of the same forward pass that computes each directional tangent (Enzyme.ForwardWithPrimal), so this is one fewer forward run per optimizer iteration than calling loss and gradient! separately. Implemented by the Enzyme extension; see gradient! for the dispatcher/fallback split.

source
FastIsostasy.solve!Function
solve!(prob, optimizer; kwargs...)

Run the inversion with optimizer. Implemented by the Optim extension.

source

Differentiation modes

FastIsostasy.AbstractDiffModeType
AbstractDiffMode

Supertype of the differentiation modes, TangentMode (forward) and AdjointMode (reverse). A diff mode carries policy — which Enzyme mode to use, the tangent batch size / checkpoint schedule, and whether a low-dimensional encoding is required — without referencing Enzyme, so the core package stays AD-free; the extensions map it onto the actual engine.

Rule of thumb: forward mode costs one forward run per parameter, so it suits encoded (low-dimensional) θ; reverse mode costs one checkpointed sweep regardless of length(θ), so it is what makes full-field inversion feasible.

source
FastIsostasy.TangentModeType
TangentMode(; batch = 8)

Forward-mode (tangent) differentiation. Cost scales with the number of parameters, so it requires a low number of parameter to estimate (which can be achieved via a low-dimensional encoding). batch is the number of tangent directions propagated together (chunking).

source
FastIsostasy.AdjointModeType
AdjointMode(; checkpoint_every = 10)

Reverse-mode (adjoint) differentiation with periodic checkpointing. Cost is roughly independent of the parameter dimension, so full 2-D fields can be inverted without an encoding. checkpoint_every is the number of save/output intervals between stored state snapshots.

source

Observables

FastIsostasy.AbstractObservableType
AbstractObservable

Supertype of the observable tags — lightweight, field-free types naming what is measured, which an Observation pairs with where and when.

Available tags: VerticalUpliftObservable (u + ue), VerticalUpliftRateObservable (dudt) and RelativeSeaLevelObservable ((z_ss − z_ss_ref) − (u + ue)).

One observable type per inversion

All observations passed to an inversion must currently share the same tag. A mixed collection is abstractly typed, which makes the per-observation field lookup dynamically dispatched inside the differentiated forward run and trips Enzyme.

source
FastIsostasy.ObservationType
Observation(tag, points, times, data; σ = 1)

A set of measurements of tag::AbstractObservable at grid points (Vector{CartesianIndex{2}}) and times. data is ordered points-fastest, then times: [p1@t1, p2@t1, …, p1@t2, …], i.e. length npoints * ntimes. σ is a scalar or a per-entry vector of the same length.

source
FastIsostasy.SimulatedObservableType
SimulatedObservable(tag, points, times, sim)

A virtual station recording tag::AbstractObservable at grid points (Vector{CartesianIndex{2}}) and times during a forward run. data is flat, points-fastest then times (Observation's convention); k is the cursor index into times of the next pending recording. Construct after sim exists (its linear indices are backend-promoted onto sim's field array family), then attach with attach_simobs!(sim, tag, points, times).

source
FastIsostasy.attach_simobs!Function
attach_simobs!(sim, tag, points, times) -> SimulatedObservable

Build a SimulatedObservable from sim's current field layout and append it to sim.simobs; run!/step! then record it automatically at each of times.

source

Encodings

FastIsostasy.AbstractEncodingType
AbstractEncoding{T}

Supertype of the encodings, which map a low-dimensional parameter vector θ onto the high-dimensional model inputs (effective viscosity, densities, ice-thickness snapshots) through reconstruct!. Encoding the unknowns is what makes forward-mode (TangentMode) inversion affordable.

Concrete encodings: Test1Encoding (joint Vialov ice + bimodal viscosity), Test2Encoding (4-Gaussian viscosity + densities). EOFEncoding / AutoEncoding / VariationalAutoEncoding are stubs for trained decoders.

Passing encoding = nothing to an inversion instead selects full-field control (one unknown per grid cell); see ParameterInversion.

An encoding must be Enzyme-legal: indexed reads of θ and in-place broadcasts into sim fields, no closures over untracked state.

source
FastIsostasy.nparamsFunction
nparams(encoding) -> Int

The number of parameters the encoding expects, i.e. the required length(θ).

source
FastIsostasy.reconstruct!Function
reconstruct!(sim, params, reduction)

Reconstruct the parameter values from reduction and update sim accordingly.

source
FastIsostasy.Test1EncodingType
Test1Encoding(knot_times, radii, visc_amps; scale = ones)

Encoding for Test 1. Fixed config: knot_times (K ice-interpolation times), radii (the 3 fixed Vialov radii Lᵢ), visc_amps (the 2 fixed log10 anomaly amplitudes, e.g. (-1, +1) decades).

θ layout (length 3K + 13): [Hc₁(1:K), Hc₂(1:K), Hc₃(1:K), x₁,y₁, x₂,y₂, x₃,y₃, log10η_bg, μ₁ₓ,μ₁ᵧ,σ₁, μ₂ₓ,μ₂ᵧ,σ₂].

scale (length 3K + 13, default all-ones) rescales each parameter before it is used: the physical value is θ[i] * scale[i]. This lets the optimization variable θ be dimensionless and O(1) even though the physical parameters span many orders of magnitude (metres of thickness, metres of position, decades of viscosity) — essential for L-BFGS conditioning. With the default ones, θ is the physical parameter vector directly. The mapping is a plain broadcast, so it stays Enzyme-legal.

source
FastIsostasy.Test2EncodingType
Test2Encoding(; scale = ones(19))

Encoding for Test 2. θ layout (length 19): [log10η_bg, (μₓ,μᵧ,σ,amp)×4, ρ_uppermantle, ρ_litho]. Ice thickness is not touched (assumed known). Concrete Float64 (the inversion-run precision decision, §1 Precision row).

scale (length 19, default all-ones) rescales each parameter before use: the physical value is θ[i] * scale[i]. As with Test1Encoding, this lets the optimization variable θ be dimensionless and O(1) even though the physical parameters span decades of viscosity, metres of anomaly position/width and thousands of kg/m³ of density — essential for L-BFGS conditioning. The mapping is a plain broadcast, so it stays Enzyme-legal.

source
FastIsostasy.EOFEncodingType
EOFEncoding

Empirical-orthogonal-function (linear) decoder: field = mean + Modes * θ. Stub — the decoder application must be implemented Enzyme-legally.

source

Loss models

FastIsostasy.AbstractLossType
AbstractLoss

Supertype of the loss models, which customize only the misfit term of loss — the norm applied to the (prediction, data, σ) triples — via misfit(lossmodel, preds, observations). The default is DefaultLoss.

A loss model is stored as a field of the inversion problem (like diffmode), so any arrays it carries (e.g. a noise-covariance factor) are picked up automatically by the AD engines. Implement a new one by subtyping and adding a misfit method.

source
FastIsostasy.misfitFunction
misfit(lossmodel, preds, observations) -> scalar

The data-misfit term of loss: the norm of the residual between the predictions preds (one vector per observation, already gathered by the forward run) and the observed data. Extension point of AbstractLoss — subtype it and add a method here to plug in a custom norm.

source

Regularization and bounds

FastIsostasy.AbstractRegularizationType
AbstractRegularization

Supertype of the regularizers and soft bounds added to the data misfit in loss. Each implements penalty(reg, sim, θ), evaluated with sim already holding the decoded parameters, so field-based penalties can read the model state directly.

Concrete types: TikhonovReg (the one configurable regularizer, with the L2Reg and SurfaceSmoothnessReg shorthands) and DecodedBounds (soft two-sided hinge bounds).

source
FastIsostasy.TikhonovRegType
TikhonovReg(target::AbstractRegTarget, order::AbstractRegOrder = Order0();
    λ = 1, weights = nothing)

One configurable Tikhonov-style regularizer; see the module docstring above for target/order. weights, if given, must match the target's shape/length and only applies under Order0().

source
FastIsostasy.L2RegFunction
L2Reg(λ)

Thin constructor over TikhonovReg: magnitude penalty on the full raw parameter vector, λ · ‖θ‖².

source
FastIsostasy.DecodedBoundsType
DecodedBounds(quantity, lo, hi, λ)

Soft two-sided hinge penalty keeping a decoded quantity within [lo, hi]: λ · Σ [relu(lo − d)² + relu(d − hi)²], where d = decoded(quantity, sim) is either a field or a scalar. quantity is a BoundedQuantity (Log10Viscosity, UpperMantleDensity, LithoDensity).

source
FastIsostasy.ThetaTargetType
ThetaTarget(idx = Colon())

Regularization target: the raw parameter vector θ (encoded space), or a subset of it selected by idx (anything that indexes a vector — Colon(), UnitRange, Vector{Int}). Only meaningful with Order0()θ has no spatial structure to take a gradient of.

source
FastIsostasy.FieldTargetType
FieldTarget(quantity::BoundedQuantity)

Regularization target: a decoded field or scalar, decoded(quantity, sim). quantity is one of the BoundedQuantity selectors shared with DecodedBounds (Log10Viscosity, UpperMantleDensity, LithoDensity).

source
FastIsostasy.SurfaceTargetType
SurfaceTarget()

Regularization target: the implied ice surface s = Hₖ + b_ref at every ice snapshot Hₖ (IceLoadInversion), with a fixed reference bed b_ref = sim.ref.z_b. Order1() gives the original SurfaceSmoothnessReg penalty.

source
FastIsostasy.AbstractRegOrderType
AbstractRegOrder

Supertype of the TikhonovReg orders, i.e. how the target is penalised: Order0 penalises magnitude, Order1 penalises the spatial gradient (smoothness).

Order1 carries physical units

The gradient penalty Σ‖∇x‖² is evaluated with the finite-difference stencils, so it is measured in (units of x) per metre squared. On a coarse grid ∇x is tiny and λ must be correspondingly large (it carries m²) for the penalty to matter — this is a units artifact, not a pathology.

source

State snapshots

FastIsostasy.StateSnapshotType
StateSnapshot(sim)

Allocate a buffer holding a full copy of sim's mutable state (its CurrentState, its barystatic-sea-level object, and the clock). Reuse it across many snapshot!/restore! calls.

source
FastIsostasy.snapshot!Function
snapshot!(buf::StateSnapshot, sim) -> buf

Copy sim's current mutable state into the preallocated buf.

source
FastIsostasy.restore!Function
restore!(sim, buf::StateSnapshot) -> sim

Write the state stored in buf back into sim, so a forward run resumed from here reproduces the trajectory captured at snapshot! time.

source