Skip to main content

Lythos LE

Limit equilibrium slope stability analysis in pure Python, with a browser front end.

Lythos LE computes the factor of safety of slopes and embankments with the method of slices, the same class of analysis as Rocscience Slide or GeoStudio SLOPE/W. It searches for the critical slip surface, reports every classical method on it, and draws the section in the browser.

  • No dependencies. The solver, the web server and the front end are standard library and vanilla JavaScript. python -m lythosle serve works on a bare Python 3.9+ install with nothing to pip install.
  • Eight methods, from Fellenius to Morgenstern-Price, all built on one slice formulation so the differences between them are the assumptions, not the code.
  • Validated against closed-form solutions, Taylor's stability numbers and the ACADS benchmark problem (see Validation).

the browser interface


Quick start

git clone https://github.com/hdaltuntas/lythosle
cd lythosle

python main.py                         # browser interface on http://127.0.0.1:8000
python main.py example                 # list the built-in examples
python main.py example homogeneous     # run one and print the report
python -m unittest discover -s tests   # run the test suite

Nothing needs installing. main.py takes everything the CLI does and starts the web interface when given nothing; HOST and PORT override the address, so a host that sets PORT gets a server bound to every interface. The same commands are available as python -m lythosle …, and pip install -e . adds a lythosle command.

What it does

Methods Ordinary (Fellenius), Bishop simplified, Janbu simplified and corrected, Corps of Engineers #1, Lowe-Karafiath, Spencer, Morgenstern-Price (half-sine, constant or trapezoidal interslice function)
Surfaces Circular (grid-and-tangent search with adaptive box and refinement), a single specified circle, a user-defined non-circular surface, and non-circular optimisation from the critical circle
Strength Effective stress (c', phi'), undrained (su, optionally increasing linearly with depth), impenetrable and no-strength materials
Groundwater Piezometric water table, per-material pore pressure ratio ru, separate saturated unit weights, ponded water on the slope
Loading Surface surcharges, pseudo-static seismic coefficients kh and kv, reinforcement (nails, anchors, geosynthetics), tension cracks with optional water pressure
Output Factor of safety per method, the critical surface, a full slice force table (CSV), the lambda-FS plot for Spencer/Morgenstern-Price, the search grid, JSON for everything

The three ways in

Browser

python -m lythosle serve --port 8000 --open

Build the geometry from a template or by typing coordinates, set up materials, groundwater and loading in the sidebar, then Run analysis (or Ctrl/Cmd + Enter). The section view shows the layers, the phreatic surface, the critical surface with its centre of rotation, the search grid coloured by factor of safety, the slices and the reinforcement. Results can be exported as SVG, CSV and JSON. The interface follows the system light/dark setting; the toggle in the header pins it.

?example=layered_water and ?theme=dark work as URL parameters.

The interface follows Claude's design language: the ivory and charcoal surfaces, the clay accent, sentence-case labels and a serif for the wordmark, headings and prose. Claude's own faces (Styrene, Tiempos, Copernicus) are licensed, so the stack asks for them first and falls back to Inter and Newsreader, which are bundled in lythosle/web/static/fonts/ — nothing is fetched from a CDN at runtime, and the page looks the same offline.

If you prefer FastAPI, uvicorn lythosle.web.app:app serves exactly the same API (pip install fastapi uvicorn first).

Command line

lythosle analyze model.json --method bishop --method spencer \
         --slices 60 --json result.json --csv slices.csv
lythosle example seismic --optimize
lythosle methods

analyze takes either a bare model file or a {"model": ..., "options": ...} file — which is exactly what the browser's Download button produces.

Python

from lythosle import SlopeModel, AnalysisOptions, analyze

model = SlopeModel.from_dict({
    "profile": [[0, 0], [10, 0], [30, 10], [50, 10]],
    "materials": [{"name": "fill", "unit_weight": 20, "cohesion": 3,
                   "friction_angle": 19.6}],
    "layers": [{"material": "fill"}],
})

result = analyze(model, AnalysisOptions.from_dict({
    "methods": ["bishop", "spencer"],
    "n_slices": 60,
    "search": {"nx": 16, "ny": 16, "n_tangent": 16, "refine_passes": 4},
}))

print(result.critical_fs)              # 0.985
print(result.results["spencer"].lam)   # interslice force ratio
print(result.text_report())

Lower level pieces are available too:

from lythosle import build_slices, circular_surface, solve_all

surface = circular_surface(model.canonical(), xc=20, yc=30, radius=28)
mass = build_slices(model.canonical(), surface, n_slices=50)
print({k: v.fs for k, v in solve_all(mass).items()})

Model format

Coordinates are [x, y] with y as elevation, in whatever consistent unit set you use (kN/m³ and kPa, or pcf and psf). The full reference is in docs/model-format.md; the short version:

{
  "name": "Layered slope",
  "units": "metric",
  "profile": [[0, 0], [18, 0], [48, 15], [75, 15]],
  "materials": [
    {"name": "Fill",  "unit_weight": 18, "sat_unit_weight": 19.5,
     "cohesion": 5, "friction_angle": 26, "color": "#C4A883"},
    {"name": "Clay",  "unit_weight": 19, "strength_model": "undrained",
     "su": 40, "su_gradient": 1.5, "su_datum": 0}
  ],
  "layers": [
    {"material": "Fill"},
    {"material": "Clay", "boundary": [[0, -4], [75, 7]]}
  ],
  "water_table": [[0, -2], [30, 3.5], [75, 9.5]],
  "seismic": {"kh": 0.15, "kv": 0},
  "surcharges": [{"x1": 50, "x2": 70, "pressure": 20}],
  "supports": [{"name": "Nail 1", "x1": 14, "y1": 1.5,
                "x2": 28, "y2": -0.2, "capacity": 40}],
  "tension_crack": {"enabled": true, "depth": 3, "water_fill": 1.0}
}

Layers are listed from the top down. The first one starts at the ground surface; each one below it carries the boundary that forms its top. Boundaries and the water table are extended horizontally beyond their end points.

The slope may be drawn facing either way: the solver mirrors the model internally so the crest is on the right, and mirrors every result back. Set "direction": "left" | "right" in the options to analyse a chosen face of a two-sided embankment.

Formulation

Every method is built on the same slice equations, so the only differences are which equilibrium conditions are satisfied and what is assumed about the interslice forces X = lambda * f(x) * E:

Method Moment Force Interslice shear
Ordinary / Fellenius yes no ignored entirely
Bishop simplified yes no X = 0
Janbu simplified / corrected no yes X = 0 (corrected applies Janbu's f0)
Corps of Engineers #1 no yes parallel to the entry-exit chord
Lowe-Karafiath no yes average of ground and base inclination
Spencer yes yes constant inclination, solved for
Morgenstern-Price yes yes f(x) shape, lambda solved for

The base normal force comes from vertical equilibrium of each slice,

N = [ W (1 + kv) + (X_right - X_left) - (c l - u l tan phi) sin(alpha) / F ] / m_alpha
m_alpha = cos(alpha) + sin(alpha) tan(phi) / F

and the factor of safety from moment equilibrium about the centre of rotation or from horizontal force equilibrium of the whole mass. Spencer and Morgenstern-Price iterate on lambda until the two agree — the crossing point you can see on the lambda-FS plot in the interface.

The sign conventions, the treatment of pore pressure, seismic loads, reinforcement, tension cracks, and the search algorithms are documented in docs/theory.md. Read it before trusting a number.

Validation

tests/test_methods.py checks the solver against results that do not come from this code:

Check Reference Result
Circular arc in phi = 0 soil direct integration of c L R / M within 0.002 of the closed form; identical across Ordinary, Bishop, Spencer and Morgenstern-Price, as theory requires
Long planar surface infinite slope, FS = tan(phi')/tan(beta) within 1% for Bishop, Janbu, Spencer and Morgenstern-Price
Toe circles, phi = 0, beta = 53-75 deg Taylor (1937) stability numbers within 1.5%
ACADS problem 1(a) published FS = 1.00 Bishop 0.985, Spencer 0.984
Mirrored geometry the same slope drawn facing the other way identical FS and lambda
Slice refinement 20 to 200 slices converges monotonically, < 0.002 change past 100 slices

Method relationships are asserted as well: Ordinary is the most conservative, Bishop sits within 2% of Spencer for circular surfaces, and Morgenstern-Price needs a larger lambda than Spencer because the half-sine function averages less than one.

Limitations

Worth knowing before you use a number in anger:

  • Two-dimensional analysis only, per unit width out of plane.
  • The slice weight uses the mid-ordinate of each slice, so strongly curved boundaries need more slices (the default 50 is enough for typical sections).
  • Moment-only methods (Ordinary, Bishop) on a non-circular surface depend on the choice of moment axis. The result is reported with a warning; use Spencer or Morgenstern-Price for non-circular surfaces.
  • Spencer and Morgenstern-Price have no solution when Fm and Ff never intersect, which happens when reinforcement is large enough to satisfy force equilibrium by itself. Lythos LE reports this as "no solution" with both values rather than inventing a number.
  • Reinforcement is applied as a known force at the intersection with the slip surface. Pull-out capacity along the anchored length is not calculated for you — put the design force in.
  • Negative effective normal forces are clipped to zero (the usual practice), and surfaces with a very small m_alpha are flagged as poorly conditioned.
  • Probabilistic analysis, rapid drawdown, anisotropic strength and 3D effects are not implemented.

Project layout

main.py          run the interface, or anything the CLI does
lythosle/
  geometry.py    polylines, intersections, polygon helpers
  materials.py   strength models
  model.py       geometry, stratigraphy, groundwater, loading, mirroring
  slices.py      slip surfaces and the slicing of the sliding mass
  methods.py     the eight limit equilibrium solvers
  search.py      grid-and-tangent search and non-circular optimisation
  analysis.py    the driver, reporting and drawing data
  examples.py    six worked examples
  cli.py         command line interface
  web/           API, standard library server, optional FastAPI app, front end
tests/           70 tests, ~60 s
docs/            theory, model format, exported example models

Licence

MIT.

Release files for lythosle 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for lythosle 0.1.0
File Size Uploaded
lythosle-0.1.0.tar.gz 813.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for lythosle 0.1.0
File Interpreter ABI Platform
lythosle-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 1.6 MB

Release files / lythosle-0.1.0.tar.gz

Download URL lythosle-0.1.0.tar.gz
Size 813.8 kB
Tags Source
SHA-256 checksum
How to use checksums
4140a394d1d380525967309b9afb8f7ff51a8b3a0cafb6e845e11cb388992ca6
BLAKE2b-256 checksum
How to use checksums
1196d12f4b86d37a85438086789b3ab6905a3648bb6187cd29d4c248f343d32d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.4

Release files / lythosle-0.1.0-py3-none-any.whl

Download URL lythosle-0.1.0-py3-none-any.whl
Size 795.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8fc475af585cfa8a6459ce262b87371105dca823815be4137697e6e8a25d871b
BLAKE2b-256 checksum
How to use checksums
d55018c5382e88544f9657f73eaa55554d50c4445cea6140e21c437184535b06
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.4

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page