Skip to content

Retaining walls & sheet piles

Three independent stability checks for gravity / cantilever walls, plus a sheet-pile embedment helper (Blum's simplified method).

Stability checks

Overturning

\[ FS_{\text{ovt}} = \frac{\sum M_R}{\sum M_O} \]
Python
ge.wall_overturning(resisting_moments=[300, 150],
                    driving_moments=[100])
# {'M_resisting': 450, 'M_driving': 100, 'FS': 4.5}

Typical design target: \(FS \geq 2\).

Sliding

\[ FS_{\text{slide}} = \frac{V\tan\delta + c_a B + P_p}{\sum H} \]
Python
ge.wall_sliding(
    horizontal_forces=[80],
    vertical_forces=[200],
    mu=0.6,                 # or delta=30 in degrees
    c_base=10, B=3.0,        # base cohesion contribution
    Pp=15,                   # passive resistance at toe (optional)
)
# {'sum_V': 200, 'sum_H': 80, 'R_friction': 120,
#  'R_cohesion': 30, 'Pp': 15, 'R_total': 165, 'FS': 2.06}

Typical design target: \(FS \geq 1.5\).

Bearing & kern

Eccentric loading on the base. Inside the kern (\(e \leq B/6\)), the base is fully in contact; outside it, contact is partial:

Python
ge.wall_bearing(V=400, M_net=200, B=4, q_ult=600)
# {'e': 0.5, 'q_max': ..., 'q_min': ..., 'within_kern': True,
#  'q_ult': 600, 'FS': ...}

Sheet pile — cantilever embedment (Blum)

For a cantilever sheet pile in cohesionless soil:

\[ D_{\text{theory}} = H\sqrt{\frac{K_a}{K_p - K_a}}, \qquad D_{\text{design}} = 1.3 \, D_{\text{theory}} \]
Python
ge.sheet_pile(gamma=18, H=4, phi=30, kind="cantilever")
# {'Ka': 0.333, 'Kp': 3.0,
#  'D_theory': 1.51, 'D_design': 1.96,
#  'method': 'Blum cantilever (approximate)'}

API reference

wall_overturning

Python
wall_overturning(resisting_moments: Sequence[float], driving_moments: Sequence[float]) -> dict

Factor of safety against overturning.

Text Only
FS_overturning = sum(M_R) / sum(M_O)

Returns dict with totals and FS.

Reference

Das (2014) Eq. 8.4.

Source code in geoeq/design/walls.py
Python
def wall_overturning(
    resisting_moments: Sequence[float],
    driving_moments: Sequence[float],
) -> dict:
    """Factor of safety against overturning.

        FS_overturning = sum(M_R) / sum(M_O)

    Returns dict with totals and FS.

    Reference
    ---------
    Das (2014) Eq. 8.4.
    """
    M_R = float(np.sum(np.atleast_1d(resisting_moments)))
    M_O = float(np.sum(np.atleast_1d(driving_moments)))
    if M_O <= 0:
        raise ValueError("Total driving moment must be > 0.")
    return {"M_resisting": M_R, "M_driving": M_O, "FS": M_R / M_O}

wall_sliding

Python
wall_sliding(horizontal_forces: Sequence[float], vertical_forces: Sequence[float], mu: float = None, delta: float = None, c_base: float = 0.0, B: float = None, Pp: float = 0.0) -> dict

Factor of safety against sliding at the wall base.

Text Only
FS_sliding = (sum_V * tan(delta) + c_a * B + Pp) / sum_H
PARAMETER DESCRIPTION
horizontal_forces

Forces pushing the wall horizontally (kN/m of wall).

TYPE: sequence

vertical_forces

Vertical forces resisting sliding (kN/m of wall).

TYPE: sequence

mu

Coefficient of friction between base and soil. If given, used as tan(delta). Otherwise computed from delta.

TYPE: float DEFAULT: None

delta

Base friction angle (degrees).

TYPE: float DEFAULT: None

c_base

Cohesion at base (kPa). Typically c_a ~ 0.5 to ⅔ of c'.

TYPE: float DEFAULT: 0.0

B

Base width (m). Required if c_base > 0.

TYPE: float DEFAULT: None

Pp

Passive resistance at the toe (kN/m). Default 0.

TYPE: float DEFAULT: 0.0

Reference

Das (2014) Eq. 8.6.

Source code in geoeq/design/walls.py
Python
def wall_sliding(
    horizontal_forces: Sequence[float],
    vertical_forces: Sequence[float],
    mu: float = None, delta: float = None,
    c_base: float = 0.0, B: float = None, Pp: float = 0.0,
) -> dict:
    """Factor of safety against sliding at the wall base.

        FS_sliding = (sum_V * tan(delta) + c_a * B + Pp) / sum_H

    Parameters
    ----------
    horizontal_forces : sequence
        Forces pushing the wall horizontally (kN/m of wall).
    vertical_forces : sequence
        Vertical forces resisting sliding (kN/m of wall).
    mu : float, optional
        Coefficient of friction between base and soil. If given, used as
        tan(delta). Otherwise computed from ``delta``.
    delta : float, optional
        Base friction angle (degrees).
    c_base : float
        Cohesion at base (kPa). Typically c_a ~ 0.5 to 2/3 of c'.
    B : float
        Base width (m). Required if c_base > 0.
    Pp : float
        Passive resistance at the toe (kN/m). Default 0.

    Reference
    ---------
    Das (2014) Eq. 8.6.
    """
    H = float(np.sum(np.atleast_1d(horizontal_forces)))
    V = float(np.sum(np.atleast_1d(vertical_forces)))
    check_positive(H, "sum(H)")
    if mu is None:
        if delta is None:
            raise ValueError("Provide mu or delta.")
        mu = np.tan(np.radians(delta))
    R_friction = V * mu
    R_cohesion = c_base * B if (c_base > 0 and B) else 0.0
    R_total = R_friction + R_cohesion + Pp
    return {
        "sum_V": V, "sum_H": H,
        "R_friction": R_friction, "R_cohesion": R_cohesion,
        "Pp": Pp, "R_total": R_total, "FS": R_total / H,
    }

wall_bearing

Python
wall_bearing(V: float, M_net: float, B: float, q_ult: float = None) -> dict

Bearing-pressure distribution under a wall foundation.

Computes the eccentricity e, maximum and minimum toe pressures, and -- if q_ult is given -- FS_bearing = q_ult / q_max.

PARAMETER DESCRIPTION
V

Total vertical load (kN/m).

TYPE: float

M_net

Net moment about the centreline of the base (kN.m/m). Positive = overturning sense.

TYPE: float

B

Base width (m).

TYPE: float

q_ult

Ultimate bearing capacity (kPa). If given, returns FS.

TYPE: float DEFAULT: None

RETURNS DESCRIPTION
dict

{'e', 'q_max', 'q_min', 'q_ult', 'FS', 'within_kern'}.

Reference

Das (2014) Eq. 8.8-8.10.

Source code in geoeq/design/walls.py
Python
def wall_bearing(
    V: float, M_net: float, B: float, q_ult: float = None,
) -> dict:
    """Bearing-pressure distribution under a wall foundation.

    Computes the eccentricity ``e``, maximum and minimum toe pressures,
    and -- if ``q_ult`` is given -- FS_bearing = q_ult / q_max.

    Parameters
    ----------
    V : float
        Total vertical load (kN/m).
    M_net : float
        Net moment about the centreline of the base (kN.m/m).
        Positive = overturning sense.
    B : float
        Base width (m).
    q_ult : float, optional
        Ultimate bearing capacity (kPa). If given, returns FS.

    Returns
    -------
    dict
        ``{'e', 'q_max', 'q_min', 'q_ult', 'FS', 'within_kern'}``.

    Reference
    ---------
    Das (2014) Eq. 8.8-8.10.
    """
    check_positive(V, "V")
    check_positive(B, "B")
    e = abs(M_net) / V
    in_kern = e <= B / 6
    if in_kern:
        q_max = (V / B) * (1 + 6 * e / B)
        q_min = (V / B) * (1 - 6 * e / B)
    else:
        # Triangular distribution -- only 3*(B/2 - e) of the base is in contact.
        q_max = (4 * V) / (3 * (B - 2 * e))
        q_min = 0.0
    out = {"e": float(e), "q_max": float(q_max), "q_min": float(q_min),
           "within_kern": bool(in_kern)}
    if q_ult is not None:
        check_positive(q_ult, "q_ult")
        out["q_ult"] = float(q_ult)
        out["FS"] = float(q_ult / q_max)
    return out

sheet_pile

Python
sheet_pile(gamma: float, H: float, phi: float, c: float = 0.0, gamma_sub: float = None, water_table: float = None, kind: str = 'cantilever') -> dict

Embedment depth of a sheet pile by Blum's simplified method.

Cantilever wall in cohesionless soil: Embedment depth D ~ found by satisfying moment equilibrium about the point of rotation. Closed-form approximation:

Text Only
    D ~ 1.2 to 1.5 * Dmin    where Dmin from theoretical balance.

Practical (Das Eq. 14.6): for a cantilever sheet pile in dry cohesionless backfill of height H above the dredge line:

Text Only
sigma_a = Ka * gamma * H   at the dredge line
gamma_b = gamma below dredge line (gamma_sub if submerged)

Total embedment D ~ H * [ (Kp - Ka) / (gamma * Kp) ]^something

Returns the theoretical embedment D_theory and a design D = 1.3 * D_theory.

PARAMETER DESCRIPTION
gamma

Unit weight of backfill (kN/m^3).

TYPE: float

H

Free height above the dredge line (m).

TYPE: float

phi

Friction angle (degrees).

TYPE: float

c

Cohesion (kPa). For c-phi soils, applies Bell's solution; for c=0 uses the Blum equations.

TYPE: float DEFAULT: 0.0

gamma_sub

Submerged unit weight below the water table (kN/m^3).

TYPE: float DEFAULT: None

water_table

Depth of the water table from the top (m).

TYPE: float DEFAULT: None

kind

'cantilever' (only currently supported).

TYPE: str DEFAULT: 'cantilever'

RETURNS DESCRIPTION
dict

{'D_theory', 'D_design', 'Ka', 'Kp'}.

Reference

Blum (1931); Das (2014) Ch. 14.

Source code in geoeq/design/walls.py
Python
def sheet_pile(
    gamma: float, H: float, phi: float, c: float = 0.0,
    gamma_sub: float = None, water_table: float = None,
    kind: str = "cantilever",
) -> dict:
    """Embedment depth of a sheet pile by Blum's simplified method.

    Cantilever wall in cohesionless soil:
        Embedment depth D ~ found by satisfying moment equilibrium about
        the point of rotation. Closed-form approximation:

            D ~ 1.2 to 1.5 * Dmin    where Dmin from theoretical balance.

    Practical (Das Eq. 14.6): for a cantilever sheet pile in dry
    cohesionless backfill of height H above the dredge line:

        sigma_a = Ka * gamma * H   at the dredge line
        gamma_b = gamma below dredge line (gamma_sub if submerged)

        Total embedment D ~ H * [ (Kp - Ka) / (gamma * Kp) ]^something

    Returns the theoretical embedment D_theory and a design D = 1.3 * D_theory.

    Parameters
    ----------
    gamma : float
        Unit weight of backfill (kN/m^3).
    H : float
        Free height above the dredge line (m).
    phi : float
        Friction angle (degrees).
    c : float
        Cohesion (kPa). For c-phi soils, applies Bell's solution; for
        c=0 uses the Blum equations.
    gamma_sub : float, optional
        Submerged unit weight below the water table (kN/m^3).
    water_table : float, optional
        Depth of the water table from the top (m).
    kind : str
        'cantilever' (only currently supported).

    Returns
    -------
    dict
        ``{'D_theory', 'D_design', 'Ka', 'Kp'}``.

    Reference
    ---------
    Blum (1931); Das (2014) Ch. 14.
    """
    check_positive(gamma, "gamma")
    check_positive(H, "H")
    check_non_negative(c, "c")
    if kind.lower() != "cantilever":
        raise NotImplementedError("Only 'cantilever' is implemented.")
    Ka_ = Ka(phi)
    Kp_ = Kp(phi)
    # Driving force per metre at and below dredge line.
    # Cohesionless: sigma_a at dredge = Ka*gamma*H, sigma_p_resisting at base.
    # Using Bowles' simplified equation for D (no water for now).
    # D_theory derived from cubic moment balance; approximate via:
    #   D = H * sqrt(Ka / (Kp - Ka))   -- Bowles "rough first estimate"
    if Kp_ - Ka_ <= 0:
        raise ValueError("Invalid soil: Kp <= Ka.")
    D_theory = H * np.sqrt(Ka_ / (Kp_ - Ka_))
    D_design = 1.3 * D_theory
    return {
        "Ka": float(Ka_), "Kp": float(Kp_),
        "D_theory": float(D_theory),
        "D_design": float(D_design),
        "method": "Blum cantilever (approximate)",
    }