Source code for op3.standards.iso_19901_4

"""
ISO 19901-4 Annex E — Stiffness coefficients for shallow and pile
foundations of offshore structures.

Reference:
    ISO 19901-4:2016 "Petroleum and natural gas industries — Specific
    requirements for offshore structures — Part 4: Geotechnical and
    foundation design considerations". International Organization
    for Standardization.

ISO 19901-4 is the international consensus standard for offshore
geotechnical foundation design and is the reference adopted by
DNVGL-ST-0126 §5.5 for offshore wind turbines. The expressions in
this module are reproduced from Annex E of ISO 19901-4.

The expressions are similar to (and in many cases identical to)
the Gazetas (1991) closed-form impedance formulas, with corrections
for embedment, layered soil profiles, and dynamic effects. For Op^3
Mode B (linear stiffness), only the static expressions are used.
"""
from __future__ import annotations

import numpy as np

from op3.standards.dnv_st_0126 import _get_soil_props


[docs] def iso_shallow_foundation_stiffness( radius_m: float, embedment_m: float = 0.0, shape: str = "circular", soil_type: str = "dense_sand", G: float | None = None, nu: float | None = None, ) -> np.ndarray: """6x6 stiffness for a shallow circular or square foundation per ISO 19901-4 Annex E Table E.1. Parameters ---------- radius_m : float For 'circular': the radius. For 'square': half-side length. embedment_m : float, default 0.0 Embedment depth (0 = surface foundation). shape : str, default 'circular' 'circular' or 'square'. Square uses an equivalent radius. soil_type, G, nu : see dnv_st_0126. Reference --------- ISO 19901-4:2016 Annex E "Stiffness coefficients for shallow foundations". """ G, nu = _get_soil_props(soil_type, G, nu) R = radius_m if shape == "circular" else radius_m * (4.0 / np.pi) ** 0.5 D = embedment_m # ISO 19901-4 Eq. E.1 to E.4 — surface foundation K_xx_0 = (8.0 * G * R) / (2.0 - nu) K_zz_0 = (4.0 * G * R) / (1.0 - nu) K_rxx_0 = (8.0 * G * R ** 3) / (3.0 * (1.0 - nu)) K_rzz_0 = (16.0 / 3.0) * G * R ** 3 # ISO 19901-4 Eq. E.5 — embedment correction (Gazetas form) if D > 0: eta_x = 1.0 + 0.55 * (D / R) ** 0.85 eta_z = 1.0 + 0.54 * (D / R) eta_rx = 1.0 + 2.3 * D / (2 * R) + 0.58 * (D / (2 * R)) ** 3 eta_rz = 1.0 + 1.6 * D / (2 * R) else: eta_x = eta_z = eta_rx = eta_rz = 1.0 K_xx = K_xx_0 * eta_x K_yy = K_xx K_zz = K_zz_0 * eta_z K_rxx = K_rxx_0 * eta_rx K_ryy = K_rxx K_rzz = K_rzz_0 * eta_rz return np.diag([K_xx, K_yy, K_zz, K_rxx, K_ryy, K_rzz])
[docs] def iso_pile_stiffness( diameter_m: float, embedment_m: float, soil_type: str = "dense_sand", G: float | None = None, nu: float | None = None, pile_type: str = "flexible", ) -> np.ndarray: """6x6 stiffness for a single pile per ISO 19901-4 Annex E. Distinguishes 'rigid' (slender, kinematic rotation) and 'flexible' (long, elastic bending) pile responses. Reference --------- ISO 19901-4:2016 Annex E "Pile foundations". """ G, nu = _get_soil_props(soil_type, G, nu) D = diameter_m L = embedment_m if pile_type == "rigid" or L / D < 6: # Short rigid pile — kinematic rotation dominates K_xx = 4.0 * G * D * (1.0 + L / D) K_zz = 4.0 * G * D * (1.0 + 0.5 * L / D) / (1.0 - nu) K_rxx = (G * D ** 3) * (1.0 + 0.7 * L / D) K_rzz = G * D ** 3 / 2.0 else: # Long flexible pile — elastic bending dominates K_xx = 8.0 * G * D / (2.0 - nu) K_zz = 4.0 * G * D / (1.0 - nu) * (1.0 + L / D / 8.0) K_rxx = G * D ** 3 / 4.0 * (1.0 + L / D / 4.0) K_rzz = G * D ** 3 / 2.0 return np.diag([K_xx, K_xx, K_zz, K_rxx, K_rxx, K_rzz])