Class hillSLP#
- class sed.hillslope.hillSLP(*args, **kwargs)[source]#
This class encapsulates all the functions related to hillslope (soil creep) processes (both linear and non-linear cases are implemented).
Methods
This function is the main entry point to compute linear and non-linear hillslope processes.
Initialise
__init__(*args, **kwargs)The initialisation of hillSLP class consists in the declaration of several PETSc vectors.
Public Methods
This function is the main entry point to compute linear and non-linear hillslope processes.
Private Methods
_hillSlope([smooth])This function computes hillslope using a linear diffusion law commonly referred to as soil creep:
_buildDiffMat(Kd)Assemble the implicit linear-diffusion operator \((I - L)\) for the finite-volume Laplacian, given per-node coefficients
Kd(m², i.e. a diffusivity × time, or the mesh-size-based marine-smoothing coefficientN · cell_area)._assembleDiffMat(coeffs)Assemble a PETSc finite-volume stencil matrix from a per-node coefficient array
coeffsof shape(lpoints, 1 + maxnb): column 0 is the diagonal, columns1..maxnbare the off-diagonal entries for themaxnbneighbours inself.FVmesh_ngbID._assembleDiffMatCSR(coeffs)Single-pass CSR assembly of the FV stencil matrix from
coeffs(lpoints, 1+maxnb)(col 0 = diagonal, cols1..maxnb= neighbour entries forself.FVmesh_ngbID)._makeDiffusionKSP(prefix)Create a cached KSP for a linear diffusion / smoothing solve: PETSc Richardson + block-Jacobi (matching
flowplex._solve_KSP), nonzero initial guess, with the per-rank ILU pivots shifted so the block-JacobiPCSetUpcannot fail on a degenerate / ocean-only partition._solveSmooth(rhs, sol)Solve one implicit step of the cached marine-smoothing diffusion operator (see
_hillSlopesmooth=2)._diff_nl_monitor(snes, its, norm)Non-linear diffusion solver convergence evaluation.
_form_residual_nl_hillslope(snes, h, F)The nonlinear system (SNES) at each time step is solved iteratively by assessing the residual of the hillslope equation.
This function computes hillslope using a non-linear diffusion law:
_evalFunctionMardDiff(ts, t, x, xdot, f)The non-linear system for freshly-deposited marine sediments diffusion at each time step is solved iteratively using PETSc time stepping and SNES solution and is based on Rosenbrock W-scheme (
rosw)._evalJacobianMardDiff(ts, t, x, xdot, a, A, B)The non-linear system for freshly-deposited marine sediments diffusion at each time step is solved iteratively using PETSc time stepping and SNES solution and is based on Rosenbrock W-scheme (
rosw)._evalSolutionMardDiff(t, x)Evaluate the initial solution of the SNES system.
_diffuseOcean(dh)For river-transported sediments reaching the marine realm, this function computes the related marine deposition diffusion.
_diffuseImplicit(dh, mask, Cd_val[, label])Solve the non-linear thickness diffusion equation
_diffuseImplicitPicard(dh, mask, Cd_val[, label])Lagged-diffusivity (Picard) alternative to
_diffuseImplicitfor the non-linear thickness diffusion \(\partial_t h = \nabla\cdot(C_d(h) \nabla h)\) over one model step.
Public functions#
Private functions#
- hillSLP._hillSlope(smooth=0)[source]#
This function computes hillslope using a linear diffusion law commonly referred to as soil creep:
\[\frac{\partial z}{\partial t}= \kappa_{D} \nabla^2 z\]in which \(\kappa_{D}\) is the diffusion coefficient and can be defined with different values for the marine and land environments (set with hillslopeKa and hillslopeKm in the YAML input file). It encapsulates, in a simple formulation, processes operating on superficial sedimentary layers. Main controls on variations of \(\kappa_{D}\) include substrate, lithology, soil depth, climate and biological activity.
Note
The hillslope processes in goSPL are considered to be happening at the same rate for coarse and fine sediment sizes.
- Parameters:
smooth – smoothing mode.
0(default) computes linear soil-creep hillslope and updates the elevation in place.1returns a one-off smoothed copy of the ice-surface proxy used to derive glacial flow directions.2returns a smoothed bathymetry used only to derive coherent marine flow directions in_matOcean— it never alters the elevation. Thesmooth=2operator uses a mesh-size- based, timestep-independent diffusivity (seeMARINE_SMOOTH_N_*) and is cached + reused across steps, rebuilt only when the coastline moves.
Note
This method uses scratch Vecs
self.tmp/self.tmpL(and, forsmooth=1,self.tmp1as the input field).smooth=0also usesself.hOld.
- hillSLP._buildDiffMat(Kd)[source]#
Assemble the implicit linear-diffusion operator \((I - L)\) for the finite-volume Laplacian, given per-node coefficients
Kd(m², i.e. a diffusivity × time, or the mesh-size-based marine-smoothing coefficientN · cell_area).Shared by the linear hillslope (
smooth=0), the ice-surface smoothing (smooth=1) and the cached marine-smoothing operator (smooth=2).- Parameters:
Kd – per-node diffusion coefficient array (
lpoints, m²).- Returns:
the assembled PETSc diffusion matrix (caller owns it; the
smooth=0/1callers destroy it after the solve, thesmooth=2caller caches it).
- hillSLP._assembleDiffMat(coeffs)[source]#
Assemble a PETSc finite-volume stencil matrix from a per-node coefficient array
coeffsof shape(lpoints, 1 + maxnb): column 0 is the diagonal, columns1..maxnbare the off-diagonal entries for themaxnbneighbours inself.FVmesh_ngbID. Used by_buildDiffMat(sethillslopecoeffoutput) and the lagged- diffusivity marine solver (jacobiancoeffoutput, scaled toI + dt·L).- Parameters:
coeffs –
(lpoints, 1+maxnb)diagonal + neighbour coefficients.- Returns:
the assembled PETSc matrix (caller owns / destroys it).
- hillSLP._assembleDiffMatCSR(coeffs)[source]#
Single-pass CSR assembly of the FV stencil matrix from
coeffs(lpoints, 1+maxnb)(col 0 = diagonal, cols1..maxnb= neighbour entries forself.FVmesh_ngbID). Equivalent to_assembleDiffMat(diag + per-neighbour axpy) but builds the matrix in ONEsetValuesLocalCSRpass —ADD_VALUESsums shared columns exactly, mirroringseaplex._matOcean(#450). Much cheaper than the 12-axpy loop, used in the Picard hot loop (_diffuseImplicitPicard), which rebuilds the operator every iteration._buildDiffMatdeliberately keeps the 12-axpy_assembleDiffMatso the bit-faithful cached smoother / linear-hillslope operators (#457 / #459) are not perturbed by a different floating-point summation order.- Parameters:
coeffs –
(lpoints, 1+maxnb)diagonal + neighbour coefficients.- Returns:
the assembled PETSc matrix (caller owns / destroys it).
- hillSLP._makeDiffusionKSP(prefix)[source]#
Create a cached KSP for a linear diffusion / smoothing solve: PETSc Richardson + block-Jacobi (matching
flowplex._solve_KSP), nonzero initial guess, with the per-rank ILU pivots shifted so the block-JacobiPCSetUpcannot fail on a degenerate / ocean-only partition. The options prefix scopes that shift (and any user override) to this solver only. Shared by the cached marine smoother (_solveSmooth) and the cached linear hillslope (_hillSlopesmooth=0).- Parameters:
prefix – PETSc options prefix for this KSP (e.g.
"marsmooth_").- Returns:
the configured PETSc KSP (caller caches and owns it).
- hillSLP._solveSmooth(rhs, sol)[source]#
Solve one implicit step of the cached marine-smoothing diffusion operator (see
_hillSlopesmooth=2).The operator (
self._smoothMat) is rebuilt only when the coastline moves, so the block-Jacobi/ILU preconditioner is factorised once and reused across every step with an unchanged land/sea mask — that factorisation (not the 1-iteration Richardson solve) was the dominant per-step cost of the previous build-from-scratch approach.- Parameters:
rhs – PETSc global Vec — the field to smooth (read).
sol – PETSc global Vec — the smoothed result (written; scratch
self.tmpat the call site).
- hillSLP._diff_nl_monitor(snes, its, norm)[source]#
Non-linear diffusion solver convergence evaluation.
- hillSLP._form_residual_nl_hillslope(snes, h, F)[source]#
The nonlinear system (SNES) at each time step is solved iteratively by assessing the residual of the hillslope equation.
- hillSLP._hillSlopeNL()[source]#
This function computes hillslope using a non-linear diffusion law:
\[\frac{\partial h}{\partial t}= \nabla \cdot \left( C_d(h) \nabla h \right)\]Two flavors of non-linear diffusion are possible based on user defined parameters:
a non-critical hillslope model following the work of Wang et al. (2024).
a non-linear depth-dependent creep law as described in Barnhart et al. (2019) (section 3.4.5).
Note
In this implementation of the SNES, we do not form the Jacobian and PETSc calculates it based on the residual function. Here, a Nonlinear Generalized Minimum Residual method is used
ngmres, a Preconditioned Conjugate Gradientcgmethod is defined for the KSP and the preconditioner allows for multi-grid methods based on the HYPRE BoomerAMG approach.
- hillSLP._evalFunctionMardDiff(ts, t, x, xdot, f)[source]#
The non-linear system for freshly-deposited marine sediments diffusion at each time step is solved iteratively using PETSc time stepping and SNES solution and is based on Rosenbrock W-scheme (
rosw).Here we evaluate the residual function on a DMPlex for an implicit time-stepping method.
- hillSLP._evalJacobianMardDiff(ts, t, x, xdot, a, A, B)[source]#
The non-linear system for freshly-deposited marine sediments diffusion at each time step is solved iteratively using PETSc time stepping and SNES solution and is based on Rosenbrock W-scheme (
rosw).Here, we define the Jacobian matrix A and the preconditioner matrix B on a DMPlex.
- hillSLP._diffuseOcean(dh)[source]#
For river-transported sediments reaching the marine realm, this function computes the related marine deposition diffusion. It is based on a non-linear diffusion approach.
\[\frac{\partial h}{\partial t}= \nabla \cdot \left( C_d(h) \nabla h \right)\]It calls the following private functions:
_evalFunctionMardDiff
_evalJacobianMardDiff
_evalSolutionMardDiff
Note
PETSc SNES and time stepping TS approaches are used to solve the non-linear equation above over the considered time step.
- Parameters:
dh – Numpy Array of incoming marine depositional thicknesses
- hillSLP._diffuseImplicit(dh, mask, Cd_val, label='diffusion')[source]#
Solve the non-linear thickness diffusion equation
\[\partial_t h = \nabla \cdot (C_d(h) \nabla h)\]on the cells indicated by
maskfor one global timestepself.dt. Cells outsidemaskget a zero diffusion coefficient and therefore do not move. The cached PETSc TS (rosw) solver is reused across calls;self.Cdandself.minDiff_vecare swapped in-place so the same solver can be applied to marine sediments, lake sediments, or any other sub-domain.- Parameters:
dh – per-node initial deposit thickness (m)
mask – bool array (lpoints) or integer index array; cells where diffusion is active.
Cd_val – scalar non-linear diffusion coefficient (m^2/yr)
label – log label (e.g. “marine” or “lake”) for the timing print
- Returns:
ndepo - smoothed deposit thickness (m), zeroed where negative
- hillSLP._diffuseImplicitPicard(dh, mask, Cd_val, label='diffusion')[source]#
Lagged-diffusivity (Picard) alternative to
_diffuseImplicitfor the non-linear thickness diffusion \(\partial_t h = \nabla\cdot(C_d(h) \nabla h)\) over one model step.Instead of the adaptive non-linear TS, this takes
self.picardSubbackward-Euler sub-steps of sizedt/picardSub; within each sub-step it freezes the diffusivity \(C_d(h^k)\) and solves the resulting linear system \((I + \Delta t_{sub} L(C_d^k)) h^{k+1} = h^{start}\) withself.picardItsPicard updates. The operatorLis built fromjacobiancoeffwith a zero derivative term (Kp=0), so it is the exact linear \(\nabla\cdot(C_d\nabla)\) operator consistent with the TS residualfctcoeff— including the “no flux across a zero- diffusivity face” marine-mask gating.Each solve is linear (a cached richardson+bjacobi KSP, no SNES) and, because \(C_d\) is frozen, smooth — so it avoids the error-estimate rejections the adaptive TS hits at the \(C_d\) kink (
dh<0.1).picardSubis the accuracy/speed knob. Same signature / return as_diffuseImplicit.- Parameters:
dh – per-node initial deposit thickness (m)
mask – cells where diffusion is active
Cd_val – scalar non-linear diffusion coefficient (m^2/yr)
label – log label
- Returns:
ndepo - smoothed deposit thickness (m), zeroed where negative