CLI reference: lsdtt-lem
Landscape evolution model combining implicit stream-power fluvial incision, hillslope sediment transport, and uniform tectonic uplift. Evolved from MuddPILE and DONKmodel. Supports both time-stepping and analytical steady-state modes, with optional hillslope steady-state solvers.
Usage
lsdtt-lem <path> <parameter_file>
lsdtt-lem <parameter_file> # path defaults to ./
lsdtt-lem -h # print help and exit
lsdtt-lem -v # print version and exit
lsdtt-lem -c # print citation and exit
# Lines beginning with # are comments.
key: value
Pipeline overview
Two mutually exclusive modes are available. Select one by setting run_steady_state.
Analytical steady-state mode (run_steady_state: true)
| Stage |
Description |
| 1 |
Build or load initial DEM |
| 2 |
Pit-fill and build flow routing |
| 3 |
Compute fluvial steady-state elevations (one or more snapping cycles) |
| 4 |
Write _steady_state_elevation raster and optional hillshade PNG |
| 5 |
Solve hillslope steady state (optional, requires run_hillslope_steady_state) |
| 6 |
Write _hillslope_steady_state_elevation raster and optional hillshade PNG |
Stage 3 has two implementations. The default is the legacy snapping loop, which
runs exactly steady_state_n_cycles cycles. Setting
use_landscape_equilibration_cycle: true selects the equilibration cycle
instead, which adds per-cycle divide diagnostics, convergence-based early
stopping, and the option to re-solve the hillslopes on every cycle so the divide
is tested under re-routing. See Landscape equilibration cycle below.
Time-stepping mode (run_steady_state: false, default)
| Stage |
Description |
| 1 |
Build or load initial DEM |
| 2 |
Apply surface conditioning (parabola, breach, noise, fill) |
| 3 |
Write _initial_topography raster |
| 4 |
Time loop: fluvial incision → hillslope transport → uplift |
| 5 |
Write intermediate rasters at frequency_of_output_writing (optional) |
| 6 |
Write _modelled_topography and _model_elevation_stats.csv |
| Parameter |
Type |
Default |
Description |
read_path |
string |
directory of parameter file |
Directory containing the input DEM. |
read_fname |
string |
parameter file stem |
Input raster filename (without extension). |
write_path |
string |
same as read_path |
Directory for output files. |
write_fname |
string |
same as read_fname |
Output filename stem. |
write_output_format |
string |
cog |
Output raster format. cog, gtiff, same_as_input, or png. PNG produces 8-bit greyscale; float32 elevation is normalised to 1–255 (nodata→0). A worldfile (.pgw) and GDAL PAM sidecar (.png.aux.xml) are written alongside for georeferencing. Use cog/gtiff for analysis. |
Threading
| Parameter |
Type |
Default |
Description |
n_threads |
int |
0 |
Number of OpenMP threads. 0 uses all available hardware threads. |
Initial surface
Loading from file
| Parameter |
Type |
Default |
Description |
read_initial_dem |
bool |
false |
Load initial topography from read_fname instead of building a synthetic surface. |
Synthetic surface (when read_initial_dem: false)
| Parameter |
Type |
Default |
Description |
n_rows |
int |
200 |
Number of rows in the model domain. Former nrows is an unchanged-value alias. |
n_cols |
int |
400 |
Number of columns in the model domain. Former ncols is an unchanged-value alias. |
cell_size_metres |
float |
30 |
Cell size in metres. Former grid_resolution is an unchanged-value alias. |
noise_type |
string |
flat |
Surface type: flat, white_noise, red_noise, diamond_square. Former initial_surface_type is an unchanged-value alias. |
max_initial_elevation |
float |
1.0 |
Maximum elevation (m) of a white_noise surface. Minimum is 0. |
noise_target_stddev_metres |
float |
1.0 |
Target standard deviation for red_noise and diamond_square surfaces. Former noise_target_stddev is an unchanged-value alias. |
noise_blur_passes |
int |
6 |
Number of blur passes for red_noise surface generation. |
diamond_square_roughness |
float |
0.55 |
Roughness exponent (0–1) for diamond_square. Higher = rougher. |
random_seed |
int |
33 |
Random seed for initial noise surface. |
synthetic_crs_wkt |
string |
empty |
CRS of the synthetic grid. Empty (default): the grid is centred on "Watopia" (Teanu Island, Solomon Islands) in EPSG:32758, WGS 84 / UTM zone 58S. A supplied WKT puts the lower-left corner at (0, 0). Parameter values cannot contain spaces, so remove the spaces inside the WKT's quoted names. |
Since October 2026 the default synthetic georeference is Watopia. Before then
lsdtt-lem placed synthetic grids at UTM zone 1N, origin (500000, 0).
Elevations, routing and statistics do not depend on the georeference.
Surface conditioning (applied to synthetic surfaces only)
| Parameter |
Type |
Default |
Description |
initial_surface_slope |
float |
0.0001 |
Regional slope added toward the nearest declared open (o/b) edge. Prevents unresolved synthetic flats and gives initial flow a boundary-consistent direction. Set to 0 to disable. Closed and periodic domains are unchanged. |
parabola_relief |
float |
0 |
Peak elevation (m) of a north–south parabola added to the initial surface. Biases drainage toward north and south boundaries. Set > 0 to enable. |
post_breach_noise_relief |
float |
0 |
Half-amplitude (m) of uniform noise added after depression breaching. Breaks up post-breach flats. Set > 0 to enable. |
fill_initial_surface |
bool |
false |
Apply pit-filling to the initial surface. Applied after breaching and post-breach noise. |
fill_min_slope |
float |
0.0001 |
Minimum slope imposed by pit-filling. |
Process switches
| Parameter |
Type |
Default |
Description |
enable_d8_fluvial_erosion |
bool |
true |
Enable D8 stream-power fluvial incision (O'Callaghan & Mark 1984). |
enable_dinf_fluvial_erosion |
bool |
false |
Enable D-infinity stream-power fluvial incision (Tarboton 1997). |
enable_hillslope_transport |
bool |
false |
Enable hillslope sediment transport. |
enable_nonlinear_hillslopes |
bool |
false |
Use nonlinear (Roering 1999) transport within roering and cidre hillslope models. |
enable_uplift |
bool |
true |
Apply uniform tectonic uplift. |
Fluvial parameters
| Parameter |
Type |
Default |
Description |
erodibility |
float |
1e-3 |
Stream-power erodibility K. Must be > 0 (K = 0 would mean no fluvial erosion: switch fluvial erosion off instead). Units m^(1−m) yr⁻¹ with divide_area_by_dx: true (the default), m^(1−2m) yr⁻¹ without; see K units and the cell size below. With erodibility_fname it is the reference K the raster is scaled relative to. |
m_exponent |
float |
0.45 |
Drainage-area exponent m. |
n_exponent |
float |
1.0 |
Slope exponent n. n=1 uses a closed-form solver; n≠1 uses Newton–Raphson. |
incision_threshold_specific_area |
float |
0 |
With divide_area_by_dx: true (default): specific catchment area A/dx in metres. With false: total map area A in m². 0 = no threshold. Also defines channel pixels for hillslope coupling. The former incision_threshold_area spelling is an unchanged-value alias. |
divide_area_by_dx |
bool |
true |
Divide drainage area by cell size to obtain specific area before comparing against incision_threshold_specific_area. |
drainage_area_moving_average_kernel_size_pixels |
int |
1 |
Odd-sized square moving-average kernel applied to drainage area before stream-power incision and channel-threshold testing. 1 disables filtering; positive odd values are required. |
slope_clamp |
float |
1e-5 |
Minimum slope used as Newton–Raphson fallback in the stream-power solver. |
K units and the cell size
The incision law is E = K a^m S^n. With divide_area_by_dx: true (the default)
a is the specific area A/dx in metres, so K has units m^(1−m) yr⁻¹. Because a
channel's drainage area A is physical, the same river needs
K_specific = K_map × dx^m
so a specific-area K belongs to the cell size it was calibrated at: 1e-5 on a
10 m grid is a different erodibility from 1e-5 on a 30 m grid (a factor
3^0.45 = 1.64 at m = 0.45). With divide_area_by_dx: false, a is the map area A
in m² and K has units m^(1−2m) yr⁻¹ and no cell-size dependence. K also depends
on m: never reuse a K calibrated for a different m.
Spatially varying erodibility
erodibility_fname replaces the scalar K in the fluvial step with a raster of
absolute K, one value per pixel. Every DEM-valid pixel needs a finite K > 0:
a zero, negative or non-finite value, or a nodata pixel inside the model domain,
is refused with the pixel's (row, col). The raster must lie on the model grid or
be placed on it (see Model grid and input rasters below); it is never
resampled inside the model.
| Parameter |
Type |
Default |
Description |
erodibility_fname |
string |
empty |
K raster (in read_path). Empty = the scalar erodibility everywhere. |
erodibility_raster_m_exponent |
float |
-1 |
The m the raster was calibrated for (< 0 = not stated). A different m from m_exponent is fatal; an unstated one gives a warning. |
erodibility_raster_n_exponent |
float |
-1 |
The same for n. |
erodibility_raster_area_convention |
string |
unstated |
map_area, specific_area or unstated. |
erodibility_raster_calibration_cell_size_metres |
float |
-1 |
The cell size a specific_area raster was calibrated at. |
write_erodibility_raster |
bool |
false |
Write the K that drove the model (see Output files). |
Conversions. The raster is converted once, at load, into the run's
convention, and the header prints the factor and the K range before and after:
| Raster states |
Run uses |
Factor applied |
map_area |
specific area at dx |
dx^m |
specific_area at dx_cal |
specific area at dx |
(dx/dx_cal)^m |
specific_area at dx_cal |
map area |
dx_cal^(−m) |
specific_area, no cell size |
specific area |
1 (assumed calibrated at dx; warning) |
specific_area, no cell size |
map area |
fatal: cannot convert |
unstated |
either |
1, with a warning naming the factor that would apply if it were map-area K |
A typical median K more than 100 times away from the scalar erodibility also
gives a warning: it is usually a units mistake.
Forcing history. If forcing_history_fname has an erodibility column, the
column scales the whole raster in time:
K(x, t) = K_raster(x) × K_forcing(t) / erodibility
so a rock-strength pattern is kept while, for example, a climate change makes
every rock twice as erodible. The forcing summary prints the factor
(-> x0.5 on the erodibility raster). With a K raster and a forcing
erodibility column you must supply erodibility in the parameter file (it is
what the raster is relative to); omitting it is fatal. An explicit 0 in the
forcing column is refused; an empty cell keeps the previous K.
Analytical steady state. The steady state honours the field through a
K-weighted chi (see the landscape evolution modelling design notes). In
steady_state_mode: relief the whole field is scaled by one factor to reach
target_relief; the header prints it as erodibility_field_scale. The initial
snap (snap_initial_surface_to_steady_state) uses the forcing history's K at
t = 0 when one is given, as it already did for U.
model_grid_source decides what defines the model grid, and
input_raster_placement how every input raster (erodibility_fname and
channel_mask_fname) is put on it.
model_grid_source |
The model grid |
Placements allowed |
auto (default) |
dem with read_initial_dem: true, else parameters |
as below |
parameters |
n_rows, n_cols, cell_size_metres on the synthetic georeference |
all five |
dem |
the loaded DEM |
as_georeferenced, warp_to_model_grid |
erodibility_raster |
the K raster itself |
as_georeferenced (a real place) or relabel_whole_raster (its dimensions only) |
input_raster_placement |
What happens |
as_georeferenced (default) |
The raster must already be on the model grid: same rows, cols, cell size, origin and CRS. A raster with no CRS but the same geometry is accepted with a warning. |
warp_to_model_grid |
The raster is warped onto the model grid (both need a CRS) with input_raster_resampling_method. Refused if they do not overlap. |
relabel_whole_raster |
Same rows, cols and cell size as the synthetic grid; the values are copied unchanged and the raster's georeference is discarded. |
relabel_centre_clip |
An n_rows × n_cols window at the model cell size, centred on (input_raster_clip_easting_metres, input_raster_clip_northing_metres) in the raster's CRS, placed on the synthetic grid. |
relabel_lower_left_clip |
The same window with its lower-left corner at that point. |
The relabel_* placements discard the raster's georeference, so they need a
synthetic grid: on a loaded DEM they are refused. A clip never rescales: the
window has the model's cell size, so feature widths stay true. If the raster's
cell size differs, it is resampled to the model's (input_raster_resampling_method;
the channel mask always uses near). A window that runs off the raster is
refused. The clip point must be in a projected CRS in metres.
Rasters whose projection distorts distance by more than 1 % on the grid are
refused, both as the model grid and as a clip source: Web Mercator (EPSG:3857)
by name, and any CRS whose scale factor at the grid's centre or corners is off by
more than 1 % (for example UTM used far outside its zone). A geographic (degree)
raster cannot define the grid; reproject it first with
lsdtt-raster-preprocessing.
Worked examples
All five use the same kind of source: a K raster k_map.tif, 100 rows × 80
cols at 10 m in UTM zone 32N, lower-left corner (500000, 5000000).
Already on the DEM grid (as_georeferenced). The K raster was made for the
DEM (same rows, cols, cell size, origin and CRS):
read_initial_dem: true
read_fname: dem.tif
erodibility_fname: k_on_dem_grid.tif
A raster half a cell off is refused, naming input_raster_placement.
A real place without a DEM (model_grid_source: erodibility_raster). The
grid is the K raster's: 100 × 80 at 10 m, in UTM 32N at its true origin, and the
synthetic starting surface is generated on it:
model_grid_source: erodibility_raster
erodibility_fname: k_map.tif
n_rows, n_cols, cell_size_metres and synthetic_crs_wkt conflict with
this and are refused. Nodata in the K raster becomes nodata in the model, so the
domain takes the map's footprint; on o/b sides the footprint edge is a fixed
base level (rivers drain out where the map ends), exactly as for a DEM with a
nodata border.
A loaded DEM and a K raster on another grid (warp_to_model_grid).
read_initial_dem: true
read_fname: dem.tif
erodibility_fname: k_map.tif
input_raster_placement: warp_to_model_grid
input_raster_resampling_method: near
The map's pattern on the synthetic grid (relabel_whole_raster). The grid
takes the raster's 100 × 80 at 10 m, but sits at the synthetic (Watopia)
georeference; the values are copied pixel for pixel:
model_grid_source: erodibility_raster
input_raster_placement: relabel_whole_raster
erodibility_fname: k_map.tif
A window of the map around a point (relabel_centre_clip). A 20 × 30 synthetic
grid at 10 m takes the 20 × 30 pixels around (500405, 5000495), the centre of
source pixel (row 50, col 40):
n_rows: 20
n_cols: 30
cell_size_metres: 10
erodibility_fname: k_map.tif
input_raster_placement: relabel_centre_clip
input_raster_clip_easting_metres: 500405
input_raster_clip_northing_metres: 5000495
The pixel containing the point becomes window pixel (n_rows/2, n_cols/2). A
point exactly on a grid line belongs to the pixel to its north or east.
A window from a corner (relabel_lower_left_clip). The same grid with its
lower-left corner at (500300, 5000400):
input_raster_placement: relabel_lower_left_clip
input_raster_clip_easting_metres: 500300
input_raster_clip_northing_metres: 5000400
Had k_map.tif been at 4 m, either clip would resample it to 10 m (the
header prints resampled from cell size 4 to 10), keeping the true size of the
map's features.
The channel mask follows the same rules
channel_mask_fname is placed exactly like the K raster. Since October 2026 it
must lie on the model grid (rows, cols, cell size, origin and CRS) or be placed
there; before, only its dimensions were checked, so a mask that matches the DEM's
dimensions but not its origin or CRS is now refused unless a placement allows it.
The raster loader refuses rotated rasters, rasters stored south-up, and projected
rasters whose pixels are not square, for every CLI: they would otherwise be read
with the wrong coordinates. Geographic rasters still open (so
lsdtt-raster-preprocessing can reproject them), and each analysis tool refuses
them itself.
Run errors
A failure inside a time step (for example a K raster scaled by the forcing
history beyond the float range) ends the run with
FATAL: time step failed at iter=<i> t=<t>: <reason> and exit code 1. The final
outputs are not written.
Hillslope transport parameters
| Parameter |
Type |
Default |
Description |
hillslope_model |
string |
cidre |
cellular: fast conservative soft-critical face transfers with optional nonlocal transport/tracing. cidre: graph-routed Carretier transport. roering_implicit: Newton backward Euler. adi: linear ADI. |
hillslope_diffusivity |
float |
1e-3 |
Hillslope diffusivity κ (m² yr⁻¹). |
critical_hillslope_slope |
float |
0.8 |
Critical slope Sc (m/m) for nonlinear hillslope transport. |
channel_mask_fname |
string |
`` |
Optional raster (in read_path) whose cells > 0.5 are fixed-elevation channel pixels for the hillslope Dirichlet set, overriding the drainage-area threshold. Must lie on the model grid or be placed on it by input_raster_placement (see Model grid and input rasters). Empty = derive channels from drainage area. |
channel_mask_threshold_specific_area |
float |
0 |
With divide_area_by_dx: true (default): A/dx in metres. With false: map area A in m². Threshold for a written channel mask; 0 uses incision_threshold_specific_area. The former channel_mask_threshold_area spelling is an unchanged-value alias. |
The drainage-area filter follows the same convention as lsdtt-advection-diffusion:
the kernel is a square, odd number of pixels on a side, and the default value of
1 disables smoothing. Filtering is applied to the drainage area used by both
stream-power incision and area-threshold channel identification.
cellular transport and tracing
| Parameter |
Type |
Default |
Description |
cellular_r_match |
float |
0.85 |
Roering/finite-continuation matching slope ratio. |
cellular_cfl_safety |
float |
0.8 |
Explicit stability safety factor (0,1]. |
cellular_nonlocal_fraction |
float |
0 |
Fraction [0,1] of near-critical excess flux routed nonlocally. |
cellular_nonlocal_activation_ratio |
float |
0.8 |
Slope ratio where nonlocal routing begins. |
cellular_nonlocal_deposition_probability |
float |
0.5 |
Geometric deposition probability per cell. |
cellular_nonlocal_max_hops |
int |
4 |
Maximum nonlocal distance in cells, at least 2 when enabled. |
enable_cellular_particles |
bool |
false |
Enable sparse Lagrangian superparticles. |
cellular_particle_inverse_density |
int |
100 |
Active cells per seeded particle. |
cellular_particle_mixing_depth |
float |
1 |
Well-mixed active-layer depth (m). |
cellular_particle_seed |
int |
1 |
Deterministic sampling seed. |
cellular_particle_restart_fname |
string |
`` |
Restart CSV in read_path; empty seeds new particles. |
Tracing writes <write_fname>_cellular_particles.csv. Reusing it as a restart preserves the RNG
substep counter, provenance, ages and distances.
roering_implicit solver knobs
These only apply when hillslope_model: roering_implicit.
| Parameter |
Type |
Default |
Description |
hillslope_implicit_time_integrator |
int |
0 |
Time integrator: 0 = backward Euler (1st order, robust), 1 = TR-BDF2 (2nd order, L-stable, embedded-error PI step control — use for time-accurate transients). |
hillslope_implicit_error_tolerance_metres |
float |
0 |
TR-BDF2 embedded-error tolerance (elevation units) for the PI step controller (0 = auto = a small fraction of the relief). Only used when time_integrator = 1. |
hillslope_implicit_solver_choice |
int |
0 |
Linear solver: 0 = SimplicialLDLT (robust, moderate grids), 1 = CG + IncompleteCholesky (scales better on very large grids). |
hillslope_implicit_relaxation_omega |
float |
0.7 |
Damped-Picard relaxation factor ω (≤ 1) for the nonlinear iteration. |
hillslope_implicit_picard_tolerance_metres |
float |
1e-4 |
Picard convergence tolerance on max|Δz| between iterates. |
hillslope_implicit_picard_max_iter |
int |
50 |
Maximum Picard iterations per sub-step. |
hillslope_implicit_slope_ratio_cap |
float |
0.99 |
Regularised slope-ratio cap r_max (< 1) bounding D_eff near Sc. |
hillslope_implicit_dt_init |
float |
0 |
Initial adaptive sub-step (0 = auto = the LEM timestep). |
hillslope_implicit_dt_min |
float |
0 |
Floor on the adaptive sub-step (0 = auto). |
hillslope_implicit_dt_max |
float |
0 |
Cap on the adaptive sub-step (0 = the LEM timestep). |
Uplift parameters
| Parameter |
Type |
Default |
Description |
uplift_rate |
float |
1e-4 |
Tectonic uplift rate (m yr⁻¹). Applied uniformly to all valid pixels. |
Routing
| Parameter |
Type |
Default |
Description |
boundary_conditions |
string |
oooo |
Flow-routing boundary conditions: four characters for north, east, south, west. o = open, n = no-flux, p = periodic, b = forced outlet. |
Analytical steady-state mode
| Parameter |
Type |
Default |
Description |
run_steady_state |
bool |
false |
Compute analytical fluvial steady-state topography. Exits after writing output. |
steady_state_mode |
string |
K |
K: erodibility is specified by the user. relief: target relief is specified and K is back-calculated. |
target_relief |
float |
1000 |
Target maximum relief (m) for relief-mode. The highest point will be baselevel_elevation + target_relief. |
baselevel_elevation |
float |
0 |
Elevation (m) assigned to outlet nodes in the steady-state solution. |
steady_state_n_cycles |
int |
1 |
Number of snapping cycles. Each cycle recomputes flow routing from the previous cycle's elevations, allowing drainage divides to migrate. Iterating 5–20 cycles smooths sharp elevation breaks across divides. When steady_state_check_convergence: true this becomes a maximum, not a fixed count — the run may stop earlier. |
Landscape equilibration cycle
An alternative implementation of the snapping loop, enabled with
use_landscape_equilibration_cycle: true (requires run_steady_state: true).
It adds per-cycle divide diagnostics, convergence-based early stopping, and the
option to solve hillslopes on every cycle rather than only the last.
A single-pass snap leaves a sharp elevation break along drainage divides, because
each side is built by integrating up from its own channel with nothing forcing
the two to meet. Cycling re-routes and re-snaps so the divide can migrate; the
diagnostics below are how you tell whether it actually settled.
D-infinity is refused, not silently downgraded. The equilibration cycle
routes D8 only. Setting both enable_dinf_fluvial_erosion: true and
use_landscape_equilibration_cycle: true is a fatal error naming both
parameters, rather than a quiet fall back to D8 — silently routing D8 when
D-infinity was requested is the one failure here that could mislead a science
result.
| Parameter |
Type |
Default |
Description |
use_landscape_equilibration_cycle |
bool |
false |
Route analytical steady state through the equilibration-cycle module. false keeps the legacy steady-state behaviour unchanged. |
divide_merge_search_steps |
int |
5 |
Downstream search depth for the divide diagnostics. Two adjacent pixels are a divide pair when their flow paths do not meet within this many receiver steps. Must be > 0. |
divide_use_d8_diagonals |
bool |
true |
Include diagonal neighbours when enumerating divide pairs (D8 adjacency). Affects the diagnostics and convergence checks only, not the routing. |
divide_gradient_target |
float |
0 |
Reporting-only acceptance target. When > 0, the final cycle reports whether the median divide gradient is at or below this value. It does not change stopping. |
Convergence and early stopping
Off by default: with steady_state_check_convergence: false the run always
executes steady_state_n_cycles cycles.
| Parameter |
Type |
Default |
Description |
steady_state_check_convergence |
bool |
false |
Enable convergence-based early stopping. |
steady_state_tolerance_dz_over_relief |
float |
1e-3 |
Convergence tolerance on max|Δz|/relief between cycles. Used when steady_state_tolerance_dz_metres is 0. |
steady_state_tolerance_dz_metres |
float |
0 |
Absolute tolerance on max|Δz| (m) between cycles. When > 0 this overrides steady_state_tolerance_dz_over_relief. |
steady_state_tolerance_receiver_fraction |
float |
1e-3 |
Convergence tolerance on the fraction of pixels changing receiver each cycle. Set <= 0 to disable this criterion. |
steady_state_convergence_patience |
int |
2 |
Consecutive converged cycles required before stopping. Cycle 1 is never eligible, since there is no previous cycle to compare against. |
A cycle counts as converged only when the elevation criterion and the
receiver-fraction criterion both hold; a criterion whose tolerance is disabled
(<= 0) is treated as satisfied. The count must be consecutive — any cycle
that fails resets the streak to zero.
The two criteria are not redundant: a landscape can stop moving vertically while
divides are still migrating, so max|Δz| alone can look converged while the flow
graph is still changing. That is the failure the receiver-fraction criterion
exists to catch. Disabling both leaves nothing but patience, which is why cycle 1
is excluded — it has no predecessor, frac_receiver_changed is forced to 0.0,
and a patience-1 run would otherwise declare convergence having compared nothing.
Hillslope steady-state
| Parameter |
Type |
Default |
Description |
run_hillslope_steady_state |
bool |
false |
Solve hillslope steady-state elevations after fluvial steady-state. Requires run_steady_state: true and incision_threshold_specific_area > 0. Channel pixels become Dirichlet boundary conditions. |
hillslope_ss_model |
string |
roering |
Hillslope steady-state solver. linear: Red-Black SOR solving D·∇²z = −U. roering: Red-Black SOR solving the nonlinear Roering (1999) law. cidre: pseudo-transient Carretier (2016) iterated to steady state (rebuilds D-inf flow graph each iteration). At steady state the nonlinear Roering and Cidre solvers produce the same elevation field. |
hillslope_ss_tolerance |
float |
1e-4 |
Convergence criterion: max |
hillslope_ss_max_iterations |
int |
10000 |
Maximum iterations for the hillslope steady-state solver. |
hillslope_sor_omega |
float |
0 |
SOR relaxation factor ω (used by linear and roering solvers). 0 = auto-estimate from grid size (capped at 1.95). Reduce toward 1.3 if the nonlinear solver diverges. |
Inside the equilibration cycle
These apply only when use_landscape_equilibration_cycle and
run_hillslope_steady_state are both true.
| Parameter |
Type |
Default |
Description |
hillslope_every_cycle |
bool |
true |
Solve the hillslopes on every cycle, not just the last one. Costs one extra solve per cycle, but it is the only way to show the divide is stable under re-routing — with false the hillslopes are solved once on the delivered surface, so a divide that would move if the hillslopes were re-solved never gets the chance to. |
channel_hysteresis_factor |
float |
0.5 |
Hysteresis on the channel (Dirichlet) set between cycles. A pixel already flagged as channel stays channel until its drainage area falls below channel_hysteresis_factor × incision_threshold_specific_area. Stops the Dirichlet set flickering from cycle to cycle. 1.0 disables the hysteresis. |
If the nonlinear solver diverges, set hillslope_sor_omega manually. With
hillslope_ss_model: roering the auto-omega estimate has been observed to
diverge at every diffusivity and tolerance tried — running to the iteration cap
with a residual of order hundreds of metres, and producing correspondingly
meaningless divide diagnostics. hillslope_sor_omega: 1.3 converges. The
auto-estimate is tuned for the linear solver; it is not a safe default for the
nonlinear one.
Hillshade output (steady-state only)
| Parameter |
Type |
Default |
Description |
write_hillshade_png |
bool |
false |
Write a Horn (1981) hillshade of the final steady-state surface as PNG. If run_hillslope_steady_state is also true, a second hillshade of the combined surface is written. PNG is always used regardless of write_output_format. |
hillshade_azimuth |
float |
315 |
Sun azimuth, degrees clockwise from north. 315 = northwest (ESRI/QGIS default). |
hillshade_altitude |
float |
45 |
Sun altitude above the horizon, degrees. |
hillshade_z_factor |
float |
1.0 |
Vertical exaggeration applied before computing the hillshade. |
Time-stepping
| Parameter |
Type |
Default |
Description |
timestep |
float |
100 |
Model timestep (yr). |
number_of_iterations |
int |
100 |
Number of timesteps. Ignored when stop_at_steady_state is true. |
stop_at_steady_state |
bool |
false |
Stop when mean erosion rate is within 1 % of uplift rate for 100 consecutive steps, then run 20× that step count more before stopping. |
frequency_of_output_writing |
int |
0 |
Write an intermediate raster every N iterations. 0 = write final only. |
When frequency_of_output_writing is greater than zero, optional PNG
diagnostics can be written at the same checkpoints as the elevation snapshots.
The D-infinity diagnostic is log10 drainage area with an inverted grayscale
mapping, so larger drainage areas are darker. The diagnostics are also written
for the initial and final modelled topographies. PNG georeferencing sidecars are
removed by default because these files are intended for visual inspection.
| Parameter |
Type |
Default |
Description |
write_intermediate_hillshade_png |
bool |
false |
Write an intermediate hillshade PNG at every output checkpoint. |
intermediate_hillshade_write_path |
string |
empty |
Optional directory for intermediate hillshade PNGs; empty uses write_path. |
write_intermediate_log10_dinf_drainage_area_png |
bool |
false |
Write an inverted-grayscale log10 D-infinity drainage-area PNG at every output checkpoint. |
intermediate_drainage_area_write_path |
string |
empty |
Optional directory for intermediate D-infinity area PNGs; empty uses write_path. |
write_intermediate_png_sidecars |
bool |
false |
Keep PNG georeferencing sidecars (.pgw and .aux.xml) instead of removing them. |
Output files
| Parameter |
Type |
Default |
Output file |
write_elevation_stats_csv |
bool |
true |
<write_fname>_model_elevation_stats.csv — per-timestep elevation statistics. |
Steady-state outputs (when run_steady_state: true)
| File |
Description |
<write_fname>_steady_state_elevation.tif |
Fluvial steady-state elevation raster. |
<write_fname>_steady_state_stats.csv |
Steady-state solver diagnostics (K, relief, mode). Written when write_elevation_stats_csv: true. |
<write_fname>_steady_state_hillshade.png |
Hillshade PNG of fluvial steady-state surface (when write_hillshade_png: true). |
<write_fname>_hillslope_steady_state_elevation.tif |
Combined fluvial + hillslope steady-state elevation (when run_hillslope_steady_state: true). |
<write_fname>_hillslope_steady_state_stats.csv |
Hillslope solver diagnostics. Written when write_elevation_stats_csv: true. |
<write_fname>_hillslope_steady_state_hillshade.png |
Hillshade PNG of combined surface (when write_hillshade_png: true). |
<write_fname>_steady_state_erodibility.tif |
The K field the steady state used (scaled by erodibility_field_scale in relief mode), when write_erodibility_raster: true. |
Equilibration-cycle outputs
Both require run_steady_state and use_landscape_equilibration_cycle to be true.
| Parameter |
Type |
Default |
Output file |
write_snap_convergence_csv |
bool |
true |
<write_fname>_snap_convergence.csv — one row per cycle. This is the file to read when a run does not converge. |
write_divide_step_raster |
bool |
false |
<write_fname>_divide_step.<ext> (extension from write_output_format) — the per-pixel elevation contrast across divide pairs on the final DEM, for locating where a residual divide step sits rather than just its distribution. |
_snap_convergence.csv columns, grouped:
| Group |
Columns |
| identity / cost |
cycle, seconds |
| elevation change |
max_abs_dz_m, mean_abs_dz_m, rms_dz_m, max_dz_over_relief |
| routing change |
n_receiver_changed, frac_receiver_changed, n_receiver_changed_hillslope, frac_receiver_changed_hillslope, n_hillslope_compared |
| cross-divide drainage |
n_cross_divide, frac_cross_divide |
| divide step |
divide_n_divide_pairs, divide_step_median_m, divide_step_p90_m, divide_step_max_m, K_used, computed_relief |
| divide gradient target |
divide_gradient_median, divide_gradient_p90, divide_gradient_target_used, divide_gradient_target_margin, divide_gradient_target_met |
| limit cycle |
receiver_hash, limit_cycle_detected, limit_cycle_period, limit_cycle_first |
The limit-cycle columns matter because a snapping run need not converge to a
fixed point at all — it can settle into a repeating orbit of flow graphs.
receiver_hash identifies the flow graph each cycle; a repeat means the
iteration has closed an orbit, and limit_cycle_period is its length
(1 = a genuine fixed point). Critical-slope hillslopes are the case to watch:
they can wander indefinitely without ever closing an orbit, in which case
nothing is detected and the run simply stops at steady_state_n_cycles. An
elliptic hillslope solve (linear or roering) reaches a period-1 fixed point
instead, which is the practical reason to prefer one.
Time-stepping outputs
| File |
Description |
<write_fname>_initial_topography.tif |
Initial surface written before the time loop. |
<write_fname>_model_iteration_N.tif |
Intermediate snapshot written every frequency_of_output_writing steps. |
<write_fname>_modelled_topography.tif |
Final topography after the run completes. |
<write_fname>_model_elevation_stats.csv |
Per-timestep statistics: iteration, time, delta max/mean elevation, max/mean erosion rate. |
<write_fname>_erodibility.tif |
The K that drove the last step, when write_erodibility_raster: true: the raster as scaled by the forcing history, or a uniform raster of the scalar K. DEM nodata is nodata. |
<write_fname>_model_iteration_N_erodibility.tif |
The K that drove step N, at every output frame. |
With erodibility_fname, the stats CSV gains erodibility_field_min,
erodibility_field_mean and erodibility_field_max (the K applied that step).
Example parameter files
Analytical fluvial steady state
read_path: /data/dems/
read_fname: initial_dem
write_path: /data/output/
write_fname: run01
run_steady_state: true
steady_state_mode: K
steady_state_n_cycles: 10
enable_d8_fluvial_erosion: true
erodibility: 0.0005
m_exponent: 0.45
n_exponent: 1.0
uplift_rate: 0.0001
write_output_format: cog
write_hillshade_png: true
Fluvial + nonlinear hillslope steady state
read_path: /data/dems/
read_fname: initial_dem
write_path: /data/output/
write_fname: run02
run_steady_state: true
run_hillslope_steady_state: true
steady_state_n_cycles: 10
erodibility: 0.0005
uplift_rate: 0.0001
incision_threshold_specific_area: 1000000
hillslope_ss_model: roering
hillslope_diffusivity: 0.005
critical_hillslope_slope: 0.8
hillslope_ss_max_iterations: 20000
hillslope_ss_tolerance: 0.0001
write_hillshade_png: true
Equilibrated steady state with divide diagnostics
Cycles until the divides stop moving rather than for a fixed count, solving the
hillslopes every cycle so the divide position is tested under re-routing.
steady_state_n_cycles is the cap, not the target.
read_path: /data/dems/
read_fname: initial_dem
write_path: /data/output/
write_fname: run03
run_steady_state: true
use_landscape_equilibration_cycle: true
steady_state_n_cycles: 40
erodibility: 0.0005
uplift_rate: 0.0001
incision_threshold_specific_area: 1000000
steady_state_check_convergence: true
steady_state_tolerance_dz_over_relief: 0.001
steady_state_tolerance_receiver_fraction: 0.001
steady_state_convergence_patience: 3
run_hillslope_steady_state: true
hillslope_ss_model: roering
hillslope_diffusivity: 0.005
critical_hillslope_slope: 0.8
hillslope_sor_omega: 1.3
hillslope_every_cycle: true
divide_merge_search_steps: 5
divide_gradient_target: 0.5
write_snap_convergence_csv: true
write_divide_step_raster: true
Note hillslope_sor_omega: 1.3 rather than the 0 auto-estimate — see the
warning under Hillslope steady-state. Leave enable_dinf_fluvial_erosion off:
combining it with the equilibration cycle is a fatal error, not a fallback.
Time-stepping LEM with Cidre hillslope transport
write_path: /data/output/
write_fname: lem_run
n_rows: 200
n_cols: 400
cell_size_metres: 30
noise_type: white_noise
max_initial_elevation: 1.0
parabola_relief: 5.0
post_breach_noise_relief: 0.05
random_seed: 42
enable_d8_fluvial_erosion: true
enable_hillslope_transport: true
enable_nonlinear_hillslopes: true
hillslope_model: cidre
enable_uplift: true
erodibility: 0.001
m_exponent: 0.45
n_exponent: 1.0
hillslope_diffusivity: 0.005
critical_hillslope_slope: 0.8
uplift_rate: 0.0001
incision_threshold_specific_area: 500000
timestep: 500
number_of_iterations: 2000
frequency_of_output_writing: 200
write_elevation_stats_csv: true
Parameters
This section is generated from the executable's -h json registry. Do not edit it manually.
Status: experimental. This CLI is not yet fully tested.
File I/O
| Parameter |
Type |
Default |
Role |
Parent |
Description |
Guidance |
read_path |
string |
./ |
io |
- |
Directory from which input files are read. |
Defaults to the directory holding the parameter file. |
read_fname |
string |
- |
io |
- |
Input filename, with or without extension (e.g. my_dem.tif). |
Read from read_path. lsdtt3 uses GDAL, so any GDAL-readable raster format works. If empty, defaults to the parameter filename stem. |
write_path |
string |
- |
io |
- |
Directory to which output files are written. |
Defaults to read_path when not set. |
write_fname |
string |
- |
io |
- |
Output filename prefix (no path, no extension). |
All outputs are named <write_fname>_<descriptor>.<ext>. Defaults to the stem of read_fname when not set. |
DEM loading vs synthetic surface
| Parameter |
Type |
Default |
Role |
Parent |
Description |
Guidance |
read_initial_dem |
bool |
false |
param |
- |
Load initial topography from read_fname instead of building a synthetic surface. |
If true, the read_path / read_fname / read_ext from the parameter file are used. |
Synthetic domain
| Parameter |
Type |
Default |
Role |
Parent |
Description |
Guidance |
n_rows |
int |
200 |
param |
- |
Number of rows in the synthetic model domain. |
Used only when the domain is generated rather than read from a DEM. |
n_cols |
int |
400 |
param |
- |
Number of columns in the synthetic model domain. |
Used only when the domain is generated rather than read from a DEM. |
cell_size_metres |
float |
30 |
param |
- |
Cell size of the synthetic model domain in metres. |
Sets the map scale of the generated surface. Anything expressed as a pixel count (for example threshold_contributing_pixels) corresponds to a different ground area as this changes. |
random_seed |
int |
33 |
param |
- |
Seed for every stochastic generator used to build the domain. |
A fixed seed makes a run reproducible. Change it to draw a different realisation of the same statistical surface. |
Grid (when not loading a DEM)
| Parameter |
Type |
Default |
Role |
Parent |
Description |
Guidance |
synthetic_crs_wkt |
string |
- |
param |
- |
Coordinate Reference System WKT string for synthetic surfaces. |
If left empty (the default), the grid is centred on Watopia (Teanu Island) in EPSG:32758 (WGS 84 / UTM zone 58S). A supplied WKT puts the lower-left corner at 0E, 0N. |
model_grid_source |
string |
auto |
param |
- |
What defines the model grid: auto, parameters, dem or erodibility_raster. |
auto = the DEM with read_initial_dem, else parameters (n_rows, n_cols, cell_size_metres on the synthetic georeference). erodibility_raster with input_raster_placement: as_georeferenced runs a real place: the grid takes the K raster's CRS, origin, cell size, rows and cols, and its nodata footprint becomes the model domain (the footprint edge is a fixed base level on o/b sides). With relabel_whole_raster it takes only the raster's dimensions, on the synthetic georeference. erodibility_raster conflicts with n_rows, n_cols and cell_size_metres. |
input_raster_placement |
string |
as_georeferenced |
param |
- |
How input rasters (erodibility_fname, channel_mask_fname) are placed on the model grid. |
as_georeferenced: already on the grid (strict check). warp_to_model_grid: warped onto the grid (both need a CRS). relabel_whole_raster: same rows, cols and cell size, georeference discarded. relabel_centre_clip / relabel_lower_left_clip: an n_rows x n_cols window at the model cell size around / from (input_raster_clip_easting_metres, input_raster_clip_northing_metres) in the raster's CRS, relabelled onto the synthetic grid; never rescaled, resampled to the model cell size if needed, refused if it runs off the raster. relabel_* placements need a synthetic grid. |
input_raster_clip_easting_metres |
double |
nan |
param |
input_raster_placement |
Easting of the clip centre (relabel_centre_clip) or lower-left corner (relabel_lower_left_clip), in the input raster's projected CRS. |
Required for the clip placements; fatal if given otherwise. |
input_raster_clip_northing_metres |
double |
nan |
param |
input_raster_placement |
Northing of the clip centre or lower-left corner, in the input raster's CRS. |
Required for the clip placements; fatal if given otherwise. |
input_raster_resampling_method |
string |
near |
param |
input_raster_placement |
Resampling for warp_to_model_grid and for clips whose cell size differs from the model's: near, bilinear, average or mode. |
The channel mask is categorical: near or mode when warped, always near in a clip. |
Synthetic noise
| Parameter |
Type |
Default |
Role |
Parent |
Description |
Guidance |
noise_type |
string |
flat |
param |
- |
Type of noise surface to generate: flat, white_noise, red_noise, diamond_square. |
flat = all zeros, i.e. no noise; white_noise = uniform random, equal power at every wavelength; red_noise = low-frequency dominated; diamond_square = fractal terrain whose roughness is set by diamond_square_roughness. |
noise_target_stddev_metres |
float |
1.0 |
param |
- |
Target standard deviation of the generated noise surface (metres). |
The raw surface is rescaled to this standard deviation. Used when noise_type is red_noise or diamond_square. |
Initial conditions
| Parameter |
Type |
Default |
Role |
Parent |
Description |
Guidance |
max_initial_elevation |
float |
1.0 |
param |
- |
Max elevation of white-noise surface (m). Min is 0. |
Used when noise_type is white_noise. |
noise_blur_passes |
int |
6 |
param |
- |
Number of blur passes for red_noise surface generation. |
- |
diamond_square_roughness |
float |
0.55 |
param |
- |
Roughness exponent (0-1) for diamond-square surface. Higher = rougher. |
- |
parabola_relief |
float |
0 |
param |
- |
Peak elevation (m) of a N-S parabola added to random initial surfaces. |
The parabola is zero at the north and south boundaries and peaks at the centre row. Adding it biases drainage toward both N/S boundaries, reducing internal basins. Set > 0 to enable; typical values 2-5x the noise relief. |
initial_surface_slope |
float |
0.0001 |
param |
- |
Small regional slope added to generated surfaces toward the nearest declared open boundary. Prevents unresolved flats and gives initial flow a boundary-consistent direction. Set to 0 to disable. |
- |
post_breach_noise_relief |
float |
0 |
param |
- |
Half-amplitude (m) of uniform noise added after breaching the initial surface. |
Breaking up post-breach flats prevents unnaturally regular drainage. Set > 0 to enable; typical values 0.01-0.1 m. Breaching is performed whenever parabola_relief > 0 or post_breach_noise_relief > 0. |
fill_initial_surface |
bool |
false |
param |
- |
Apply pit-filling to the initial surface before running. |
Applied after breaching/noise conditioning when those are also enabled. |
fill_min_slope |
float |
0.0001 |
param |
- |
Minimum slope imposed by pit filling. |
Used when fill_initial_surface is true. |
Sinuous Boundaries
| Parameter |
Type |
Default |
Role |
Parent |
Description |
Guidance |
enable_sinuous_n_boundary |
bool |
false |
switch |
- |
Apply a sinuous (sine wave) mask to the North domain boundary. |
- |
sinuous_n_amplitude_fraction |
float |
0.25 |
param |
- |
Amplitude of the North sinuous boundary as a fraction of total N-S domain length. |
This can max be 0.25, as it create waves that span half the N-S domain. |
sinuous_n_n_waves |
int |
1 |
param |
- |
Number of complete sine waves along the North boundary. |
- |
sinuous_n_phase_offset |
float |
0.0 |
param |
- |
Phase offset of the North sinuous boundary as a fractional value [0, 1]. |
- |
enable_sinuous_s_boundary |
bool |
false |
switch |
- |
Apply a sinuous (sine wave) mask to the South domain boundary. |
- |
sinuous_s_amplitude_fraction |
float |
0.25 |
param |
- |
Amplitude of the South sinuous boundary as a fraction of total N-S domain length. |
This can max be 0.25, as it create waves that span half the N-S domain. |
sinuous_s_n_waves |
int |
1 |
param |
- |
Number of complete sine waves along the South boundary. |
- |
sinuous_s_phase_offset |
float |
0.0 |
param |
- |
Phase offset of the South sinuous boundary as a fractional value [0, 1]. |
- |
Process switches
| Parameter |
Type |
Default |
Role |
Parent |
Description |
Guidance |
enable_d8_fluvial_erosion |
bool |
true |
switch |
- |
Enable D8 stream-power fluvial incision. |
D8 with n=1 always uses closed-form and is therefore very stable. For other n uses Newton-Raphson. |
enable_dinf_fluvial_erosion |
bool |
false |
switch |
- |
Enable D-infinity stream-power fluvial incision. |
Uses stable closed-form for n=1 only on nodes that have only a single receiver, otherwise uses Newton-Raphson. |
enable_hillslope_transport |
bool |
false |
switch |
- |
Enable Cidre hillslope diffusion. |
- |
enable_nonlinear_hillslopes |
bool |
false |
switch |
- |
Use nonlinear transport (Roering 1999 or Carretier et al. 2016 depending on hillslope_model). |
Requires enable_hillslope_transport. |
critical_slope_clamp_only |
bool |
false |
switch |
- |
With hillslope_ss_model: critical_slope, LOWER cells above the target gradient instead of imposing it everywhere. |
The default imposes z = z_receiver + dx*S_c on every hillslope cell, manufacturing a landscape of uniform critical slopes and destroying whatever form the input had. Clamping preserves the input wherever it is already admissible and cuts back only the super-critical parts. Intended for handing an equilibrated LINEAR landscape to a Roering run: linear diffusion has no critical slope, so its steady state routinely carries gradients above S_c where the Roering flux law is singular. NOTE this limits the gradient ALONG THE FLOW PATH, not the full gradient magnitude the flux law uses -- cross-slope can still exceed S_c, so use critical_slope_clamp_fraction to leave headroom. |
critical_slope_clamp_fraction |
float |
0 |
param |
- |
Multiply S_c by this before clamping. 0 = use S_c unchanged. |
Clamping to exactly S_c leaves the Roering flux law at its singularity, where alpha = 1/(1-(S/S_c)^2) diverges. Clamping to 0.9 S_c gives alpha ~ 5, and 0.8 gives alpha ~ 2.8 -- both comfortably solvable. It also leaves headroom for the cross-slope component that the along-flow clamp does not control. |
hillslope_force_sor |
bool |
false |
switch |
- |
Force the legacy SOR + Picard steady-state solver instead of Newton. |
Steady-state hillslope solves default to Newton, which is faster and more accurate for the linear problem and converges near Sc where Picard limit-cycles. SOR is still used automatically when Newton is unavailable (a build without Eigen) or fails to converge; this switch forces it for comparison or reproduction of an older run. With SOR the nonlinear operator needs hillslope_sor_omega set low (0.3-0.5); the auto value is the LINEAR optimum and diverges. |
hillslope_model |
string |
cidre |
param |
- |
Hillslope transport model: cellular, roering_implicit, cidre, or adi. |
cellular: conservative soft-critical face transfers with optional bounded nonlocal transport and sparse Lagrangian tracing; permits finite-lived slopes above Sc and is the recommended fast nonlinear transient model. roering_implicit: unconditionally-stable implicit solver for the Roering (1999) nonlinear law. Steady-state runs use Newton; transient runs use backward Euler with adaptive sub-stepping. Channels are Dirichlet sinks from the area threshold or channel_mask_fname; needs a non-empty channel set or the step is skipped. Set enable_nonlinear_hillslopes false for linear diffusion. cidre: Carretier et al. (2016) finite-volume forward sweep using D-inf routing; explicit, so CFL-limited, but stable as slopes approach Sc via slope-restoration. Works with an emergent channel network (incision_threshold_specific_area = 0); since 2026-08-27 roering_implicit does too, for transient runs. adi: Crank-Nicolson implicit linear diffusion using uncoupled ADI sweeps (transient only; steady-state runs use Newton regardless). NOTE: 'linear' and 'roering' select EXPLICIT solvers and are run as asked: they are CFL-limited and less stable than the implicit path, and are retained for testing and for builds without Eigen. They are NOT redirected to roering_implicit -- if you want the implicit solver, ask for it by name. Requires enable_hillslope_transport. |
Timestep control
| Parameter |
Type |
Default |
Role |
Parent |
Description |
Guidance |
adaptive_timestep |
bool |
false |
switch |
- |
Adapt the LEM timestep to keep the coupled solve accurate. |
Both halves of a coupled run can be unconditionally STABLE and the run still be wrong at a large timestep: stability describes one operator, accuracy of an operator-split PAIR is a different question. The controller keys on the achieved maximum local elevation change of each step against the relief across one cell (dx * median gradient), holding that ratio near timestep_target_ratio. It shrinks faster than it grows, because an oversized step corrupts the landscape while an undersized one only costs time. timestep becomes the starting value. |
timestep_target_ratio |
float |
0.7 |
param |
- |
Target for (elevation change per step) / (relief across one cell). |
Measured on a 200x200 grid at 5 m: ratios of 0.13-0.67 gave 4-5% grid-scale roughness and a stable hillslope length; 2.67 gave 12.2% roughness and a hillslope length wrong by 5.7x, while still converging and still reporting ~99% of the uplift rate. Used both by the pre-run check and, with adaptive_timestep, by the controller. |
steady_state_dz_tolerance |
float |
0.0001 |
param |
- |
Stop early when no cell moves more than this in one step (m). |
The run ends at whichever comes first: this steady-state criterion or run_until_time / number_of_iterations. Convergence is REFUSED while the timestep is below steady_state_min_dt_fraction of its initial value, because an absolute per-step tolerance is trivially met by a collapsing timestep while the landscape is still evolving as fast as ever. Set 0 to disable early stopping. |
steady_state_rate_tolerance |
float |
0 |
param |
- |
Steady state as a RATE (m/yr), dt-independent. 0 = use the per-step tolerance alone. |
The per-step tolerance is dt-dependent: halving the timestep halves every change without the landscape being any steadier (the same relaxed landscape measured 0.006 m/step at dt = 250 and 0.029 m/step at dt = 2000). A rate means the same thing at any timestep. The measured floor for a coupled run is 1.4e-5 to 2.8e-5 m/yr -- 3.6-7.0% of the uplift rate -- set by continual reorganisation of the drainage network, so a tolerance below that cannot be met however long the run goes. A sensible choice is a small fraction of uplift_rate. |
steady_state_patience |
int |
5 |
param |
- |
Consecutive steps below tolerance before declaring steady state. |
One quiet step can happen by accident. |
steady_state_min_dt_fraction |
float |
0.25 |
param |
- |
Refuse to declare steady state while dt is below this fraction of its initial value. |
Guards against a collapsing adaptive timestep faking convergence. |
stop_on_stall |
bool |
false |
switch |
- |
End the run when a stall or oscillation is detected, rather than warning. |
Off by default: stall detection is heuristic, and a false positive throws away a healthy run while a false negative only costs the time the run was going to take anyway. Convergence is a definite test and always stops the run; a stall only warns unless this is set. |
stall_window |
int |
1000 |
param |
- |
Steps over which a lack of progress is judged (0 disables). |
If max|dz| has not fallen over this window while still above tolerance, the run is reported as STALLED, and as OSCILLATING when the step-to-step changes alternate in sign -- a period-2 cycle, which points at the numerics (timestep too large, or a limit cycle in the nonlinear solve) rather than at needing more model time. A stalled run is NOT a converged one and must not be reported as steady state. |
run_until_time |
float |
0 |
param |
- |
Run until this much model time has elapsed (yr). 0 = use number_of_iterations instead. |
With a FIXED timestep the two are equivalent, but with adaptive_timestep they are not: if the controller shrinks dt, a fixed iteration count covers proportionally less model time, and different runs in a sweep end at different times. Measured on a 7-run sweep intended to cover 6 Myr each: the runs actually reached 0.70, 1.12 and 1.26 Myr because dt fell by up to 15x. Set this instead of number_of_iterations whenever the timestep adapts. number_of_iterations then acts as a safety cap. |
timestep_min |
float |
0 |
param |
- |
Floor for the adaptive timestep (yr). 0 = timestep / 100. |
- |
timestep_max |
float |
0 |
param |
- |
Ceiling for the adaptive timestep (yr). 0 = timestep * 100. |
- |
Cellular hillslopes
| Parameter |
Type |
Default |
Role |
Parent |
Description |
Guidance |
cellular_r_match |
float |
0.85 |
param |
hillslope_model |
Slope ratio below which cellular transport exactly follows Roering. |
Above this ratio the mobility follows a finite tangent continuation. Only used when hillslope_model is cellular. |
cellular_cfl_safety |
float |
0.8 |
param |
hillslope_model |
Explicit cellular stability safety factor in (0,1]. |
Only used when hillslope_model is cellular. |
cellular_nonlocal_fraction |
float |
0 |
param |
hillslope_model |
Fraction [0,1] of near-critical excess flux routed nonlocally. |
Zero gives local soft-critical transport. Only used when hillslope_model is cellular. |
cellular_nonlocal_activation_ratio |
float |
0.8 |
param |
cellular_nonlocal_fraction |
Slope ratio at which nonlocal routing begins. |
Only used when cellular_nonlocal_fraction is greater than 0. |
cellular_nonlocal_deposition_probability |
float |
0.5 |
param |
cellular_nonlocal_fraction |
Per-cell geometric deposition probability for nonlocal volume. |
Only used when cellular_nonlocal_fraction is greater than 0. |
cellular_nonlocal_max_hops |
int |
4 |
param |
cellular_nonlocal_fraction |
Maximum nonlocal travel distance in cells (>=2). |
Only used when cellular_nonlocal_fraction is greater than 0. |
Cellular particle tracing
| Parameter |
Type |
Default |
Role |
Parent |
Description |
Guidance |
enable_cellular_particles |
bool |
false |
switch |
hillslope_model |
Track sparse Lagrangian sediment superparticles. |
Only valid when hillslope_model is cellular. |
cellular_particle_inverse_density |
int |
100 |
param |
enable_cellular_particles |
Active cells represented per seeded superparticle. |
100 is the validated standard; smaller values seed more particles. |
cellular_particle_mixing_depth |
float |
1 |
param |
enable_cellular_particles |
Well-mixed active-layer depth represented by particles (m). |
- |
cellular_particle_seed |
int |
1 |
param |
enable_cellular_particles |
Deterministic particle sampling seed. |
- |
cellular_particle_restart_fname |
string |
- |
file |
enable_cellular_particles |
Particle CSV to restart from, relative to read_path. |
Empty seeds a new population. |
roering_implicit solver knobs (used only when hillslope_model = roering_implicit)
| Parameter |
Type |
Default |
Role |
Parent |
Description |
Guidance |
hillslope_implicit_relaxation_omega |
float |
0.7 |
param |
- |
Damped-Picard relaxation factor omega (0<omega<=1) for roering_implicit. |
Values below 1 stabilise the nonlinear iteration near Sc; the controller auto-tunes it down further on divergence. Ignored by other hillslope models. |
hillslope_implicit_picard_tolerance_metres |
float |
1e-4 |
param |
- |
Convergence tolerance max|delta_z| for the Picard iteration (roering_implicit). |
- |
hillslope_implicit_picard_max_iter |
int |
50 |
param |
- |
Maximum Picard iterations per sub-step (roering_implicit). |
- |
hillslope_implicit_slope_ratio_cap |
float |
0.99 |
param |
- |
Regularised slope-ratio cap r_max (<1) bounding D_eff near Sc (roering_implicit). |
- |
hillslope_implicit_solver_choice |
int |
0 |
param |
- |
Linear solver for roering_implicit: 0 = SimplicialLDLT, 1 = CG+IncompleteCholesky. |
LDLT is robust for moderate grids; CG+IC scales better on very large grids. |
hillslope_implicit_time_integrator |
int |
0 |
param |
- |
Time integrator for roering_implicit: 0 = backward Euler, 1 = TR-BDF2 (2nd order). |
TR-BDF2 is L-stable and time-accurate with embedded PI error control; use it for time-accurate transients rather than just the approach to steady state. |
hillslope_implicit_error_tolerance_metres |
float |
0 |
param |
- |
TR-BDF2 embedded-error tolerance (elevation units) for the PI step controller (0 = auto = a small fraction of the relief). Only used when time_integrator = 1. |
- |
hillslope_implicit_dt_init |
float |
0 |
param |
- |
Initial adaptive sub-step for roering_implicit (0 = auto = the LEM timestep). |
- |
hillslope_implicit_dt_min |
float |
0 |
param |
- |
Floor on the adaptive sub-step for roering_implicit (0 = auto). |
- |
hillslope_implicit_dt_max |
float |
0 |
param |
- |
Cap on the adaptive sub-step for roering_implicit (0 = the LEM timestep). |
- |
channel_mask_fname |
string |
- |
param |
- |
Optional raster (in read_path) whose cells > 0.5 are fixed-elevation channel pixels for the hillslope Dirichlet set, overriding the drainage-area threshold. |
Must lie on the model grid (rows, cols, cell size, origin and CRS), or be placed on it by input_raster_placement, like erodibility_fname. Empty (default) = derive channels from incision_threshold_specific_area. Useful for prescribed-channel / hillslope-strip runs. |
hold_channel_mask_fixed |
bool |
false |
param |
- |
Hold the channel_mask_fname pixels at fixed elevation through every step. |
Requires channel_mask_fname. The masked pixels join the open-edge boundary pixels as fixed-elevation cells, so uplift does not lift the channel network away from the hillslopes relaxing toward it. Use for hillslopes-only runs on a frozen network; leave false for coupled runs where the channels must incise. |
write_channel_mask_raster |
bool |
false |
switch |
- |
Write the hillslope Dirichlet channel mask (1 = channel). |
Output file: <write_fname>_channel_mask.tif for the final topography, plus <write_fname>model_iteration<N>_channel_mask.tif at every output frame when frequency_of_output_writing > 0 (the migrating network of an animation). The mask is the one the hillslope step would use: the channel_mask_fname raster when supplied, else the pixels whose D-infinity drainage area reaches incision_threshold_specific_area (or channel_mask_threshold_specific_area). Feed it back in as channel_mask_fname to freeze a fluvially-evolved network for a hillslopes-only run. |
write_erosion_rate_raster |
bool |
false |
switch |
- |
Write the per-pixel erosion rate (m/yr, positive = erosion, uplift backed out). |
Output file: <write_fname>model_iteration<N>_erosion_rate.tif at every output frame (needs frequency_of_output_writing > 0), plus <write_fname>_erosion_rate.tif for the final step. This is the field in which a transient pulse of incision is visible: knickpoints appear as a band of high erosion rate migrating up the channel network. Deposition appears as negative values. |
channel_mask_threshold_specific_area |
float |
0 |
param |
- |
A/dx threshold in metres when divide_area_by_dx=true; map area A in m^2 when false. Defines the written channel mask (0 = use incision_threshold_specific_area). |
Only affects write_channel_mask_raster; the model itself is unchanged. Lets a run erode fluvially everywhere (incision_threshold_specific_area: 0) while still writing a channel network defined at a positive threshold. The run header resolves the threshold into specific area, map area, and contributing pixels. |
enable_uplift |
bool |
true |
switch |
- |
Apply uniform tectonic uplift. |
- |
Process parameters
| Parameter |
Type |
Default |
Role |
Parent |
Description |
Guidance |
uplift_rate |
float |
1e-4 |
param |
- |
Tectonic uplift rate (m/yr). |
Applied uniformly to all valid pixels. Constant unless overridden by forcing_history_fname. |
baselevel_fall_rate |
float |
0 |
param |
- |
Rate at which base level falls (m/yr, positive = down). |
The fixed-elevation boundary pixels are lowered at this rate instead of being held at their pre-step elevation, so a wave of incision propagates up the channel network. 0 (default) = static base level. Constant unless overridden by forcing_history_fname. |
forcing_history_fname |
string |
- |
param |
- |
Optional CSV (in read_path) making uplift_rate, baselevel_fall_rate, erodibility and hillslope_diffusivity functions of model time. |
Columns: time_yr, uplift_rate, baselevel_fall_rate (the latter two optional, default 0; any column order), plus optional erodibility and hillslope_diffusivity, where an absent column or empty cell keeps the parameter-file value. Stepping K or D walks the channelization index; the applied K, D and CI are written to the stats CSV. Applied as a piecewise-constant step function of model time -- the row in force is the last one with time_yr <= t -- so a pulse has sharp on/off edges. Overrides the constant uplift_rate and baselevel_fall_rate parameters for the whole run. Use it to impose a pulse of incision: a window of rapid base-level fall that sends knickpoints up the network, which the hillslopes then respond to. The forcing actually applied at each step is recorded in the uplift_rate / baselevel_fall_rate columns of <write_fname>_model_elevation_stats.csv. |
erodibility |
float |
1e-3 |
param |
- |
Stream-power erodibility K. Must be > 0. |
Scales fluvial incision rate. Units: m^(1-m) yr^-1 with divide_area_by_dx: true (the default; specific area a = A/dx, so K is tied to m and to the cell size: K_specific = K_map * dx^m), or m^(1-2m) yr^-1 with divide_area_by_dx: false (map area). |
erodibility_fname |
string |
- |
param |
- |
Optional raster (in read_path) of ABSOLUTE erodibility K per pixel. |
Replaces the scalar erodibility in the fluvial step. Every DEM-valid pixel needs a finite K > 0 (nodata inside the domain is refused). The scalar erodibility stays the reference K: a forcing-history erodibility column scales the whole raster by K_forcing / erodibility. The raster is placed on the model grid by input_raster_placement; it is never resampled inside the LEM. |
erodibility_raster_m_exponent |
float |
-1 |
param |
erodibility_fname |
The m exponent the K raster was calibrated for (< 0 = not stated). |
K is tied to m: a stated m different from m_exponent is fatal; an unstated one gives a warning. |
erodibility_raster_n_exponent |
float |
-1 |
param |
erodibility_fname |
The n exponent the K raster was calibrated for (< 0 = not stated). |
A stated n different from n_exponent is fatal; an unstated one gives a warning. |
erodibility_raster_area_convention |
string |
unstated |
param |
erodibility_fname |
Area convention of the K raster: map_area, specific_area or unstated. |
map_area K (units m^(1-2m) yr^-1) is converted to the run's specific-area K by dx^m when divide_area_by_dx is on; specific_area K is tied to its calibration cell size. The conversion and its factor are printed. |
erodibility_raster_calibration_cell_size_metres |
float |
-1 |
param |
erodibility_fname |
Cell size (m) a specific_area K raster was calibrated at (< 0 = not stated). |
A different run cell size converts K by (dx_run/dx_cal)^m, with a note. |
write_erodibility_raster |
bool |
false |
param |
- |
Write the erodibility K that drove the model. |
Output: <write_fname>_erodibility.tif (the last step), and <write_fname>model_iteration<N>_erodibility.tif at every output frame; <write_fname>_steady_state_erodibility.tif in run_steady_state mode. With no erodibility_fname the raster is the uniform scalar K. |
m_exponent |
float |
0.45 |
param |
- |
Drainage area exponent m in stream power law. |
- |
n_exponent |
float |
1.0 |
param |
- |
Slope exponent n in stream power law. |
n=1 uses closed-form solver; n!=1 uses Newton-Raphson. |
hillslope_diffusivity |
float |
1e-3 |
param |
- |
Hillslope diffusivity kappa (m^2/yr). |
Used when enable_hillslope_transport is true. |
critical_hillslope_slope |
float |
0.8 |
param |
- |
Critical slope Sc (m/m) for nonlinear hillslope transport. |
- |
incision_threshold_specific_area |
float |
0 |
param |
- |
A/dx channel threshold in metres when divide_area_by_dx=true; map area A in m^2 when false. 0 = no threshold. |
With divide_area_by_dx true (the DEFAULT) the threshold is compared against specific catchment area a = A/dx, a length in metres; with it false, against map area A in m^2. Two consequences worth knowing before choosing a value: (1) under the default, threshold T selects cells with at least T/dx upstream pixels, so the same .param file carried from a 10 m DEM to a 1 m DEM asks for a ten times larger network in pixel terms; (2) a value picked as though it were m^2 is wrong by a factor of dx - on a 10 m grid '1000' means 100 pixels, not the 10 that 1000 m^2 would give. The run header prints the resolved threshold in all three forms. The specific-area convention follows Bonetti et al. (2020) and Litwin et al. (2022) and exists to remove grid dependence from the erosion law; only its documentation was ever wrong. Also defines channel pixels for hillslope coupling. |
drainage_area_moving_average_kernel_size_pixels |
int |
1 |
param |
- |
Odd-sized square moving-average kernel for drainage area used by D8 or D-infinity stream-power incision and channel thresholding; 1 disables smoothing. |
Must be a positive odd number. The filter is applied to drainage area before the threshold and incision calculation, following the convention used by lsdtt-advection-diffusion. |
hillslope_channel_coupling |
string |
auto |
param |
- |
Which channel/hillslope coupling to run: auto, coupled, or channels_as_boundaries. |
lsdtt3 contains BOTH standard couplings, and which one you get has until now been an unreported side effect of incision_threshold_specific_area. channels_as_boundaries makes channels FIXED (Dirichlet) nodes for the hillslope solve, so drainage density is an INPUT - the MuddPILE configuration, D8 routing. coupled gives no Dirichlet set: both processes act everywhere and valley spacing, hillslope length and drainage density EMERGE - the DonkModel configuration, which needs D-infinity because D8 on a diverging hillslope manufactures channel heads. These are different experiments, not different settings. 'auto' reproduces the historical inference exactly and only reports it, and is the default because parameter files across this project already depend on the implicit behaviour. NOTE roering_implicit cannot run the coupled regime: it needs a Dirichlet set, so the most robust hillslope solver is the one that cannot do the emergent-drainage-density experiment. |
divide_area_by_dx |
bool |
true |
param |
- |
Divide drainage area by cell size to get specific area a = A/dx. |
Applies to both fluvial incision and the hillslope coupling threshold, and changes the interpretation of incision_threshold_specific_area from map area in m^2 to specific area in metres. True is the Bonetti et al. (2020) / Litwin et al. (2022) convention (specific area, grid-independent); false is the Perron et al. (2008) total-area convention. The choice also changes the exponent in the landscape Peclet number, so it is not a free setting. |
slope_clamp |
float |
1e-5 |
param |
- |
Minimum slope used as Newton-Raphson fallback in stream power solver. |
- |
Analytical steady-state
| Parameter |
Type |
Default |
Role |
Parent |
Description |
Guidance |
run_steady_state |
bool |
false |
switch |
- |
Compute analytical steady-state topography instead of running a time-stepping LEM. |
Uses the flow algorithm selected by enable_d8_fluvial_erosion or enable_dinf_fluvial_erosion. Writes _steady_state_elevation.tif and returns. |
steady_state_mode |
string |
K |
param |
run_steady_state |
Steady-state solver mode: K or relief. |
K-mode: K (erodibility) is specified by the user. Relief-mode: target_relief is specified and K is back-calculated. |
target_relief |
float |
1000 |
param |
run_steady_state |
Target maximum relief (m) for relief-mode steady-state. |
The highest point in the output raster will be baselevel_elevation + target_relief. |
baselevel_elevation |
float |
0 |
param |
run_steady_state |
Elevation (m) assigned to outlet nodes in the steady-state solution. |
- |
steady_state_n_cycles |
int |
1 |
param |
run_steady_state |
Number of snapping cycles for steady-state computation. |
Each cycle recomputes the flow graph from the previous cycle's elevation, allowing drainage divides to migrate one pixel per cycle. Iterating (typically 5-20 cycles) smooths the sharp elevation breaks across divides that appear in a single-pass steady-state snap. The DEM is pit-filled between cycles. |
use_landscape_equilibration_cycle |
bool |
false |
param |
run_steady_state |
Route analytical steady-state through the landscape equilibration cycle module. |
Default false keeps legacy steady-state behavior unchanged. |
divide_merge_search_steps |
int |
5 |
param |
use_landscape_equilibration_cycle |
Downstream search depth used by divide diagnostics in equilibration-cycle runs. |
Must be > 0 when use_landscape_equilibration_cycle is true. |
divide_use_d8_diagonals |
bool |
true |
param |
use_landscape_equilibration_cycle |
Include diagonal neighbors in divide-step diagnostics (D8 adjacency). |
Only used by equilibration-cycle diagnostics outputs/convergence checks. |
steady_state_check_convergence |
bool |
false |
param |
use_landscape_equilibration_cycle |
Enable convergence-based early stopping in equilibration-cycle steady-state runs. |
Default false keeps current behavior (always runs steady_state_n_cycles). |
steady_state_tolerance_dz_over_relief |
float |
1e-3 |
param |
steady_state_check_convergence |
Convergence tolerance for max|dz|/relief between equilibration cycles. |
Used when steady_state_check_convergence is true and steady_state_tolerance_dz_metres is 0. |
steady_state_tolerance_dz_metres |
float |
0 |
param |
steady_state_check_convergence |
Absolute convergence tolerance for max|dz| (m) between equilibration cycles. |
If > 0 this overrides steady_state_tolerance_dz_over_relief. |
steady_state_tolerance_receiver_fraction |
float |
1e-3 |
param |
steady_state_check_convergence |
Convergence tolerance for fraction of pixels changing receiver each cycle. |
Set <= 0 to disable this convergence criterion. |
divide_gradient_target |
float |
0 |
param |
use_landscape_equilibration_cycle |
Optional divide-gradient acceptance target for equilibration diagnostics. |
Reporting-only threshold: when > 0, the final cycle reports whether divide gradient median <= this target; it does not change stopping. |
steady_state_convergence_patience |
int |
2 |
param |
steady_state_check_convergence |
Required number of consecutive converged cycles before early stopping. |
Only used when steady_state_check_convergence is true. |
Hillslope steady-state
| Parameter |
Type |
Default |
Role |
Parent |
Description |
Guidance |
run_hillslope_on_loaded_dem |
bool |
false |
switch |
- |
Solve hillslopes on the loaded DEM without re-snapping the fluvial field. |
Requires read_initial_dem: true, run_hillslope_steady_state: true and incision_threshold_specific_area > 0. Channels at or above the resolved threshold keep the elevations they arrived with and act as Dirichlet boundaries; only hillslope pixels are solved. Use this when the fluvial field is a TRANSIENT that must be preserved -- a step-change landscape carries a migrating knickpoint, and run_steady_state would snap the channels to a single ksn and erase it. Exits after writing <write_fname>_hillslope_on_loaded_dem. |
run_hillslope_steady_state |
bool |
false |
switch |
- |
Solve for hillslope steady-state elevations after fluvial steady-state. |
Solver is selected by hillslope_ss_model: linear, roering, or cidre. Requires run_steady_state: true and incision_threshold_specific_area > 0. Channel pixels at or above the resolved threshold become Dirichlet BCs. |
hillslope_ss_tolerance |
float |
1e-4 |
param |
run_hillslope_steady_state |
Convergence criterion for hillslope steady-state: max|delta_z| over hillslope pixels. |
- |
hillslope_ss_max_iterations |
int |
10000 |
param |
run_hillslope_steady_state |
Maximum SOR iterations for hillslope steady-state solver. |
- |
hillslope_ss_model |
string |
roering |
param |
run_hillslope_steady_state |
Hillslope steady-state solver: linear, roering, cidre, or critical_slope. |
linear: Red-Black SOR solving Dgrad^2z = -U (standard Laplacian diffusion). roering: Red-Black SOR solving Dgrad*[gradz/(1-(|gradz|/Sc)^2)] = -U (nonlinear). Both SOR solvers converge in O(N) iterations with auto-tuned omega. critical_slope: imposes Sc by upslope integration from the channels -- not an elliptic solve, so it never finds a divide position, it inherits one; only available with run_hillslope_on_loaded_dem. cidre: pseudo-transient Cidre (Carretier 2016) iterated until steady state. Rebuilds the D-inf flow graph each iteration (Picard update of routing directions). The nonlinear flag for cidre is taken from enable_nonlinear_hillslopes. At steady state the nonlinear Cidre and Roering solvers produce the same elevation field (Carretier et al. 2016 Sec3.3). |
hillslope_every_cycle |
bool |
true |
param |
run_hillslope_steady_state |
Solve the hillslopes on every equilibration cycle, not just the last one. |
Only used when use_landscape_equilibration_cycle and run_hillslope_steady_state are both true. Solving every cycle costs one extra solve per cycle but is the only way to show the divide is stable under re-routing; false solves once on the delivered surface. |
channel_hysteresis_factor |
float |
0.5 |
param |
run_hillslope_steady_state |
Hysteresis on the channel (Dirichlet) set between equilibration cycles. |
A pixel already flagged as channel stays channel until its drainage area falls below channel_hysteresis_factor * incision_threshold_specific_area. Stops the Dirichlet set flickering from cycle to cycle. 1.0 disables the hysteresis. |
hillslope_sor_omega |
float |
0 |
param |
run_hillslope_steady_state |
SOR relaxation factor omega for hillslope steady-state (0 = auto). |
Values in (1, 2) accelerate convergence. 0 = auto-estimate from grid size (capped at 1.95). Typical manual values: 1.5 (safe) to 1.9 (fast). Reduce toward 1.3 if the nonlinear solver diverges. |
Hillshade output (steady-state runs only)
| Parameter |
Type |
Default |
Role |
Parent |
Description |
Guidance |
write_hillshade_png |
bool |
false |
switch |
- |
Write a hillshade PNG of the final steady-state elevation. |
Computes a standard Horn (1981) hillshade and saves it as a PNG alongside the elevation output. If run_hillslope_steady_state is also true, a second hillshade of the combined fluvial+hillslope surface is written. PNG is always used regardless of write_output_format. |
hillshade_azimuth |
float |
315 |
param |
write_hillshade_png |
Sun azimuth for hillshade, degrees clockwise from grid north (grid up). |
315 = northwest (ESRI/QGIS default), relative to the raster grid. |
hillshade_altitude |
float |
45 |
param |
write_hillshade_png |
Sun altitude above the horizon for hillshade, degrees. |
45 is the standard default. |
hillshade_z_factor |
float |
1 |
param |
write_hillshade_png |
Vertical exaggeration factor for hillshade. |
Use values > 1 to emphasise relief on low-gradient landscapes. |
| Parameter |
Type |
Default |
Role |
Parent |
Description |
Guidance |
write_intermediate_hillshade_png |
bool |
false |
switch |
frequency_of_output_writing |
Write a hillshade PNG at each intermediate output checkpoint. |
The PNG is written to intermediate_hillshade_write_path, or write_path when that path is empty. |
write_intermediate_log10_dinf_drainage_area_png |
bool |
false |
switch |
frequency_of_output_writing |
Write a log10 D-infinity drainage-area PNG at each intermediate output checkpoint. |
The PNG uses an inverted grayscale mapping so larger drainage areas are darker, and is written to intermediate_drainage_area_write_path. |
write_intermediate_png_sidecars |
bool |
false |
switch |
- |
Keep PNG georeferencing sidecars (.wld/.pgw and .aux.xml) for intermediate diagnostics. |
False removes the sidecars after writing PNGs intended only for visual inspection. |
intermediate_hillshade_write_path |
string |
- |
io |
write_intermediate_hillshade_png |
Directory for intermediate hillshade PNGs. |
Empty uses write_path. |
intermediate_drainage_area_write_path |
string |
- |
io |
write_intermediate_log10_dinf_drainage_area_png |
Directory for intermediate D-infinity drainage-area PNGs. |
Empty uses write_path. |
Timestepping
| Parameter |
Type |
Default |
Role |
Parent |
Description |
Guidance |
timestep |
float |
100 |
param |
- |
Model timestep (yr). |
Stability depends on erodibility, resolution and slope. |
number_of_iterations |
int |
100 |
param |
- |
Number of timesteps to run. |
Ignored when stop_at_steady_state is true. |
snap_initial_surface_to_steady_state |
bool |
true |
switch |
- |
Before time-stepping, snap the initial surface to the analytical fluvial steady state (chi-based, K-mode). |
A near-flat start cannot reach steady state sooner than R/U, the time uplift needs to build the final relief R, so a run from noise spends at least that long just gaining height (0.8 Myr for 165 m at 0.2 mm/yr, and ~3 Myr in practice). The snap sets z = baselevel + (U/K)^(1/n) chi on the pit-filled initial surface, routed with the same flow method as the fluvial step (D-infinity when enable_dinf_fluvial_erosion, else D8), so time-stepping starts from the right relief and only has to equilibrate hillslopes and divides. Uses uplift_rate, erodibility, m_exponent, n_exponent, baselevel_elevation and divide_area_by_dx; with a forcing history the uplift rate at t = 0 is used. Skipped, with a message, when no fluvial process is enabled or the uplift rate is not positive. Set false to keep the initial surface as given -- REQUIRED for a transient experiment on a loaded DEM, whose topography this replaces. |
stop_at_steady_state |
bool |
false |
param |
- |
Stop when mean erosion rate is within 1% of uplift rate for 100 consecutive steps. |
After detection, runs 20x that step count more before stopping. |
Output
| Parameter |
Type |
Default |
Role |
Parent |
Description |
Guidance |
frequency_of_output_writing |
int |
0 |
param |
write_elevation_stats_csv |
Write an intermediate raster every N iterations. 0 = write final only. |
- |
write_output_format |
string |
cog |
io |
- |
Output raster format: cog, gtiff, same_as_input, png. |
png: 8-bit greyscale PNG for quick visualisation. Float32 elevation is normalised to 1-255 (nodata->0). A worldfile (.pgw) and GDAL PAM sidecar (.png.aux.xml) are written alongside for georeferencing. PNG cannot store float32 values or embed a CRS natively, so use cog/gtiff for analysis. |
write_elevation_stats_csv |
bool |
true |
switch |
- |
Write per-timestep elevation statistics to a CSV file. |
- |
write_snap_convergence_csv |
bool |
true |
switch |
- |
Write per-cycle snap convergence diagnostics for the landscape equilibration path. |
Only used when run_steady_state and use_landscape_equilibration_cycle are both true. |
write_divide_step_raster |
bool |
false |
switch |
- |
Write a divide-step raster from the final equilibration-cycle steady-state DEM. |
Only used when run_steady_state and use_landscape_equilibration_cycle are both true. |
Routing and threading
| Parameter |
Type |
Default |
Role |
Parent |
Description |
Guidance |
boundary_conditions |
string |
oooo |
param |
- |
Flow routing boundary conditions (north/east/south/west). |
o=open, n=no-flux, p=periodic, b=forced outlet. |
n_threads |
int |
0 |
io |
- |
Number of OpenMP threads. 0 = all available. |
- |