Uncertainty quantification (Phase 5)

The op3.uq package implements three orthogonal UQ tools:

Soil parameter propagation

class op3.uq.propagation.SoilPrior(depth_m: float, G_mean_Pa: float, G_cov: float = 0.3, soil_type: str = 'sand', su_or_phi_mean: float = 35.0, su_or_phi_cov: float = 0.1)[source]

Bases: object

Probabilistic specification for one soil layer. The prior is parameterised by mean and coefficient of variation (COV = std / mean) for each fluctuating quantity. Lognormal sampling is used so that all draws stay strictly positive.

G_cov: float = 0.3
G_mean_Pa: float
depth_m: float
sample(rng: Generator) SoilState[source]
soil_type: str = 'sand'
su_or_phi_cov: float = 0.1
su_or_phi_mean: float = 35.0
op3.uq.propagation.propagate_pisa_mc(*, diameter_m: float, embed_length_m: float, soil_priors: list[SoilPrior], n_samples: int = 500, seed: int = 42, correlated: bool = True) ndarray[source]

Run an MC sweep through pisa_pile_stiffness_6x6 and return an (n_samples, 6, 6) array of K matrices.

Parameters:

correlated – If True (default), all layers share the same realisation of the underlying standard normal so that “soft” draws have all layers softer simultaneously (perfectly correlated). If False, each layer is sampled independently. The published practice for site-specific design is to assume strong correlation.

op3.uq.propagation.summarise_samples(samples: ndarray) dict[source]

Reduce an (n, 6, 6) sample array to per-DOF summary statistics on the diagonal terms.

Returns:

Keys: ‘Kxx’, ‘Kyy’, ‘Kzz’, ‘Krxrx’, ‘Kryry’, ‘Krzrz’ Each value is a sub-dict with mean, std, p05, p50, p95.

Return type:

dict

Polynomial Chaos Expansion

class op3.uq.pce.HermitePCE(coeffs: 'np.ndarray', order: 'int', n_dim: 'int')[source]

Bases: object

coeffs: ndarray
evaluate(xi: float | ndarray, xi2: float | ndarray | None = None) ndarray[source]
n_dim: int
order: int
op3.uq.pce.build_pce_1d(f: Callable[[float], float], order: int = 4, n_quad: int | None = None) HermitePCE[source]

Pseudo-spectral 1D Hermite PCE built on Gauss-Hermite quadrature. The input is the standard normal coordinate xi ~ N(0, 1); callers are responsible for mapping back to the physical parameter space.

op3.uq.pce.build_pce_2d(f: Callable[[float, float], float], order: int = 3, n_quad: int | None = None) HermitePCE[source]

Bayesian calibration

class op3.uq.bayesian.BayesianPosterior(grid: 'np.ndarray', prior: 'np.ndarray', likelihood: 'np.ndarray', posterior: 'np.ndarray', mean: 'float', std: 'float', p05: 'float', p50: 'float', p95: 'float')[source]

Bases: object

grid: ndarray
likelihood: ndarray
mean: float
p05: float
p50: float
p95: float
posterior: ndarray
prior: ndarray
std: float
op3.uq.bayesian.normal_likelihood(measured: float, sigma: float) Callable[[float], float][source]

Return L(predicted) = N(measured | predicted, sigma^2) callable.

op3.uq.bayesian.grid_bayesian_calibration(*, forward_model: Callable[[float], float], likelihood_fn: Callable[[float], float], grid: ndarray, prior: ndarray | None = None) BayesianPosterior[source]

1D grid Bayesian calibration.

Parameters:
  • forward_model – Map from the calibration parameter (e.g. EI scale factor) to the predicted observable (e.g. f1 in Hz).

  • likelihood_fn – Maps a predicted value to its likelihood under the measurement noise model. Use normal_likelihood(measured, sigma).

  • grid – Discretisation of the parameter axis.

  • prior – Prior PDF over the same grid (un-normalised is fine). If None, a uniform prior is used.

Example: NREL 5 MW OC3 EI calibration

The Op3 Bayesian calibration of the NREL 5 MW OC3 monopile tower EI scale factor against the published Jonkman & Musial (2010) reference frequency yields:

posterior mean   = 1.014
posterior std    = 0.076
5%-95% interval  = [0.888, 1.145]

Translation: the published OC3 tower stiffness is consistent with the Op3 model to within ±1.4% mean and a 13% credible interval.

Reference: tests/test_uq.py::test_5_3_4_op3_calibration_demo.