Skip to content

Hardening Soil models

numgeo-ACT supports both Hardening-Soil-MN and its Hardening-Soil-MN-Bricks small-strain extension. Both models can be calibrated against any combination of the laboratory tests supported by ACT.

Model classes

from ACT.models import hardening_soil, hardening_soil_bricks

model = hardening_soil()
# or:
model = hardening_soil_bricks()

Units and angles

Enter phi and psi in degrees. Enter E50, Eoed, Eur, c, pref, Eiref, Hpp and Bricks G0 in kPa, consistent with ACT's experimental sheets. gamma_07 is a strain fraction; m, nu_ur, K0nc, Rf and alpha are dimensionless.

The base-model parameter order is:

ACT name numgeo parameter Principal calibration data
E50 \(E_{50}^{ref}\) Primary drained triaxial loading
Eoed \(E_{oed}^{ref}\) Primary oedometric loading
Eur \(E_{ur}^{ref}\) Unloading and reloading branches
m \(m\) Tests at different stress levels
c \(c_{eff}\) Failure states
phi \(\varphi\) Failure states
psi \(\psi\) Drained volumetric response
nu_ur \(\nu_{ur}\) Unloading/reloading response
pref \(p_{ref}\) User-selected reference pressure
K0nc \(K_0^{nc}\) Normally consolidated oedometric response
Rf \(R_f\) Triaxial hyperbola/failure approach
Eiref \(E_i^{ref}\) Initial triaxial tangent
alpha \(\alpha\) Cap shape; zero requests numgeo determination
Hpp \(H_{pp}\) Cap hardening; zero requests numgeo determination

hardening_soil_bricks adds gamma_07 (\(\gamma_{0.7}\)) and G0 (\(G_0^{ref}\)), in that order. The implementation rejects \(G_0^{ref}<G_{ur}^{ref}\), where \(G_{ur}^{ref}=E_{ur}^{ref}/[2(1+\nu_{ur})]\), and requires a positive \(\gamma_{0.7}\) whenever the small-strain extension is active.

Calibration example

from ACT import globals
from ACT.models import hardening_soil_bricks

model = hardening_soil_bricks()
model.set(
    E50=30_000.0, Eoed=30_000.0, Eur=90_000.0,
    m=0.55, c=0.0, phi=42.0, psi=12.0, nu_ur=0.2,
    pref=100.0, K0nc=0.4, Rf=0.9, Eiref=54_545.0,
    alpha=0.0, Hpp=0.0, gamma_07=1.0e-4, G0=150_000.0,
)

globals.setup(
    Model=model,
    Free_parameter=["E50", "Eoed", "Eur", "m", "phi", "psi", "G0", "gamma_07"],
    oedometer=oedometer_tests,
    triaxCD=triaxial_tests,
    DSS=dss_tests,
    path=working_directory,
)

Set parameter-specific search intervals before starting the optimiser:

model.set_bounds(E50=(10_000.0, 100_000.0), phi=(30.0, 48.0))

Optional initial estimates

The method below applies common Hardening Soil engineering estimates:

estimated = model.apply_correlations(
    stiffness=True,   # Eoed=E50, Eur=3 E50, Ei=2 E50/(2-Rf)
    jaky=True,        # K0nc=1-sin(phi)
    dilatancy=True,   # psi=max(phi-30 degrees, 0)
)

These relationships are intended to initialise a calibration or to fill gaps when measurements are unavailable. They are not universal soil laws. In particular, use unloading/reloading data for \(E_{ur}^{ref}\), tests at several stress levels for \(m\), and small-strain cyclic or wave-velocity data for \(G_0^{ref}\) and \(\gamma_{0.7}\) whenever those observations exist. Calling apply_correlations is explicit; ACT does not alter parameters automatically.

The \(E_i^{ref}\) relationship is the approximation documented for numgeo's HS-MN implementation. The stiffness ratios and \(\psi\approx\varphi-30^\circ\) rule are the conventional Hardening Soil defaults, while \(K_0^{nc}=1-\sin\varphi\) is Jaky's normally consolidated estimate.

Cross-parameter constraints

The reference stiffnesses of the Hardening Soil model are not independent. An unloading/reloading modulus below the primary-loading modulus, or an initial tangent modulus below the secant modulus, is physically inconsistent, yet an optimiser with independent bounds on E50, Eoed, Eur and Eiref will use such combinations if they reduce the objective (for example fitting the oedometer with a low Eur). Both Hardening Soil classes therefore enforce the following ratio limits during a calibration; a candidate that violates one of them receives the failure penalty and is never accepted as result:

Ratio Default range Background
\(E_{ur}^{ref}/E_{50}^{ref}\) \(\geq 2\) conventional range \(2\)\(4\) (default estimate \(3\))
\(E_{oed}^{ref}/E_{50}^{ref}\) \(0.5\)\(2\) conventional estimate \(E_{oed}^{ref}\approx E_{50}^{ref}\)
\(E_i^{ref}/E_{50}^{ref}\) \(\geq 1\) follows from the hyperbola, \(E_i = 2E_{50}/(2-R_f)\)

The limits are evaluated on the complete parameter vector, so they also apply when only one of the two parameters of a ratio is free. Adjust or disable them per soil before calling the optimiser:

model.set_stiffness_ratio_limits(
    Eur_E50=(3.0, 6.0),   # (minimum, maximum); None on one side removes that limit
    Eoed_E50=(0.7, 1.5),
    Eiref_E50=None,       # remove the constraint entirely
)

model.stiffness_ratio_violations(values) lists the violated limits of a complete parameter vector (in parameter_names order); an empty list means the vector is admissible. The active limits are written to the calibration log. ACT warns at the start of a calibration if the initial parameter vector itself violates a limit, because its objective is then the penalty. With independent bounds on the four stiffnesses a large part of the search box violates the ratios; CMAES and SMAC therefore check the constraints before proposing a point and redraw violating candidates, while DEEM evaluates the constraints before starting numgeo, so a violating particle costs no simulation time.

The remaining single-parameter requirements (positive stiffnesses and reference pressure, \(0<\varphi<90^\circ\), \(0\leq\nu_{ur}<0.5\), \(0<R_f\leq 1\), \(m,c,\alpha,H_{pp}\geq 0\), \(K_0^{nc}>0\) and, for the Bricks model, \(G_0^{ref}\geq G_{ur}^{ref}\)) are checked in the same way.

Automatic cap parameters

Setting alpha=0 and/or Hpp=0 delegates determination of the corresponding cap parameter to numgeo. This is different from making the parameter free in ACT: include a parameter in Free_parameter only when ACT itself should optimise it.