Parametric Studies

Vary the inputs and watch the answer move. XSLOPE groups three closely related studies under one Parametric umbrella — one Studio button, one API family, one parameter grammar:

  • Sensitivity — sweep one or more parameters and see how the factor of safety responds. The results feed a family of plots: a tornado, scaled-sensitivity bars, a spider plot, and — when the model carries standard deviations — a variance-contribution Pareto and a Monte Carlo rank-correlation chart.
  • Design — sweep one parameter across an explicit range and find the value at which FS meets a target (FS = 1.5, say).
  • Back-Analysis — the same single-parameter sweep framed as a failure investigation: a slide has occurred, so FS = 1.0 is known, and the study back-calculates the parameter value consistent with the observed failure.

This is the geotechnical staple — Duncan & Wright present exactly these charts (FS vs parameter, and tornado diagrams comparing several parameters at their low/high bounds) — and half of slope-stability judgment is knowing which parameter matters on a given slope.

Sensitivity is deliberately distinct from reliability analysis: the Taylor-series method perturbs parameters by ±σ to estimate the distribution of FS, which requires the parameters to be independent. A sensitivity sweep asserts nothing statistical — it simply evaluates the model across a range — which also makes it the right tool for correlated fit coefficients (the power-curve A and b, for example) that the reliability method must not treat as independent. The Hoek-Brown inputs are in the same category: hb_sci, hb_gsi, hb_mi and hb_d are all sweepable here, but they carry no standard-deviation columns and reliability rejects them, because \(m_b\), \(s\) and \(a\) are all derived from GSI, \(m_i\) and \(D\) — perturbing them independently would be meaningless.

Sweeps are configured entirely through the API — sensitivity describes an analysis you run, not a property of the model, so nothing is added to the Excel input template. The same engine drives the point-and-click Parametric study dialog in Studio and the recipes in the /xslope Claude Code skill, so a study set up one way reads the same the others.

Analysis modes: LEM, FEM, seepage

Every sweep runs through one of three engine mode= values: 'lem' (limit equilibrium, output FS — the default), 'fem' (a full finite-element SSRM solve per point, output FS), or 'seep' (a rebuilt-and-solved seepage problem per point, output the total discharge q). mode='fem' and mode='seep' both need a mesh in slope_data['mesh']. Not every function in the family takes a mode= argument — the two plots that reuse the reliability machinery directly are LEM-only:

Function lem fem seep
sensitivity() yes yes yes
tornado() yes yes yes
design() yes yes yes
back_analysis() yes yes yes
scaled_sensitivity() yes yes yes
variance_contribution() yes
mc_rank_correlation() yes

variance_contribution() and mc_rank_correlation() reuse the LEM Taylor-series and Monte Carlo reliability machinery directly (xslope.advanced.reliability and reliability_mc), which is a limit-equilibrium path only — see Monte Carlo in xslope for why. They take no mode= argument at all rather than accepting one they cannot honor.

Addressing a parameter

A sweep needs an unambiguous name for the thing being varied. Parameter references are strings of the form "kind:name:field":

kind name fields example
mat material name strength fields valid for the material's option (c, phi for mc; c, cp for cp), plus gamma, gamma_sat, ru, d, psi "mat:Clay:c"
reinforce line label t_max, t_res, lp1, lp2, tend1, tend2, spacing "reinforce:Row 2:t_max"
piles pile label H, theta, D, S, V_cap, M_cap "piles:Pile 1:H"
global k_seismic, tcrack_depth, tcrack_water "global:k_seismic"
seep material name k1, k2, alpha, kr0, h0 "seep:Sand:k1"
geom piezo:dy — shift the piezometric line vertically (the value is a delta) "geom:piezo:dy"

Every reference is validated against the loaded model before anything runs: an unknown kind, an unmatched name, or a field the material's strength option does not use raises immediately, naming what was given and what exists. Names resolve case-insensitively; duplicated names are an error rather than a guess. Sweeping c on a cp material is rejected for the same reason the reliability module rejects it — the model would not read the value, and the sweep would silently report zero sensitivity.

Note that gamma and gamma_sat are the same soil weighed two ways, so sweeping gamma moves gamma_sat by the same absolute delta (the same coupling the reliability module applies); gamma_sat remains separately addressable when that is what you mean.

Discovering and specifying parameters

Rather than hand-write every reference, list_params(slope_data) enumerates every sweepable parameter in the loaded model — each material's option-aware strength and general fields, plus the global k_seismic — as plain dicts. It is the menu a GUI parameter-picker (or an assistant driving the API) chooses from, so a reference is never guessed:

from xslope.sensitivity import list_params

for p in list_params(slope_data):
    print(p['ref'], p['value'], p['sigma'])
    # mat:Soil:c        3.0   1.8
    # mat:Soil:phi      19.6  2.744
    # mat:Soil:gamma    20.0  1.2
    # global:k_seismic  0.0   None

Each entry carries ref (the canonical string), kind, name, index (the 1-based material index), field, value (the current value, or None if unset), sigma (the reliability standard deviation — sigma_c, sigma_phi, … — if the model carries a non-zero one, so a picker can offer a one-click ±σ range), and a short label. Blank or zero-valued fields are still listed, so a design study can target them with explicit bounds.

Anywhere a "kind:name:field" string is accepted, the entry points also accept the equivalent dict or tuple — often what a GUI or an assistant naturally produces. All forms resolve to the same setter and validate identically:

design(slope_data, {"material": "Soil", "property": "c"}, low=6, high=18)  # dict, by name
design(slope_data, {"material": 1, "property": "phi"}, low=15, high=25)     # 1-based index
design(slope_data, {"global": "k_seismic"}, low=0.0, high=0.3)             # a global
design(slope_data, ("mat", "Soil", "c"), low=6, high=18)                    # tuple form

The dict accepts ref (passed straight through), material/name and property/field, or a global key; a material may be named or given by 1-based index.