5.1. SDOF-to-MDOF Calibration
- openquake.vmtk.calibration.calibrate_model(nst, sdof_capacity, is_sos=False, is_frame=False, storey_heights=None, verbose=False)[source]
Calibrate MDOF storey force-drift backbones from an SDOF spectral capacity curve.
- Parameters:
nst (int) – Number of storeys.
sdof_capacity (array-like) – SDOF capacity array [Sd (m), Sa (g)], shape (n_points, 2).
is_sos (bool, optional) – True for soft-storey buildings. Softens the ground-floor stiffness used to derive the mode shape. Default False.
is_frame (bool, optional) – True for moment/braced-frame buildings (nst <= 12), which use a power-law mode shape instead of the eigenvalue-derived one. Ignored when is_sos is True: soft-storey buildings always use the eigenvalue-derived shape, so the ground-floor softening is never bypassed. Default False.
storey_heights (list of float, optional) – Not used by the calibration; carried through to metadata for callers that need it. Default None.
verbose (bool, optional) – Print a one-line summary if True. Default False.
- Returns:
floor_masses (list of float) – MDOF floor masses.
storey_drifts (numpy.ndarray) – Inter-storey drift capacities (m), shape (nst, n_points).
storey_forces (numpy.ndarray) – Storey shear-force capacities (g x mass units), shape (nst, n_points).
phi (numpy.ndarray) – First mode shape (roof-normalised).
metadata (dict) – gamma_real, is_sos, is_frame, storey_heights.
- Raises:
ValueError – If nst, sdof_capacity, or storey_heights is malformed (see above).
TypeError – If is_sos, is_frame, or storey_heights has the wrong type.
Theoretical Background
The SDOF-to-MDOF calibration maps a single-degree-of-freedom (SDOF) spectral capacity curve to storey-level force-deformation relationships for a stick-and-mass MDOF model (Xu et al., 2016; Lu et al., 2020).
First-mode shape
The normalised first-mode shape \(\phi_1\) (roof value 1.0) is obtained in one of two ways:
Frame buildings (
is_frame=True, \(n \le 12\) storeys, not soft-storey): an assumed power law,\[\phi_1^{(i)} = \left(\frac{i}{n}\right)^{0.6}, \quad i = 1, \ldots, n\]Everything else (including all soft-storey buildings, regardless of
is_frame): the first eigenvector of a uniform tri-diagonal lateral stiffness matrix (unit diagonal terms of 2, roof term of 1), solved against a diagonal mass matrix with a reduced roof mass factor of 0.75. For soft-storey systems (is_sos=True) the ground-floor stiffness term is softened to 1.20 instead of 2, so the soft-storey mode-shape softening is never bypassed byis_frame.
Unit effective modal mass
Floor masses are scaled so that the assumed mode shape carries unit effective modal mass, consistent with the unit-mass SDOF capacity curve:
with the modal participation factor given by
Storey force and drift distribution
The storey shear force at storey \(i\) is the SDOF spectral acceleration distributed over the modal mass tributary to storeys \(i\) through the roof:
The first-storey drift follows directly from the SDOF spectral displacement, \(\delta_1 = S_d \cdot \Gamma_1 \cdot \phi_1^{(1)}\); every other storey drift is scaled by the mode-shape increment relative to the first storey:
No iterative period-matching or OpenSees verification step is performed — the calibration is a single closed-form pass driven entirely by the assumed mode shape.
Example
import numpy as np
from openquake.vmtk.calibration import calibrate_model
sdof_capacity = np.array([
[0.000, 0.00],
[0.020, 0.18],
[0.080, 0.22],
[0.150, 0.10],
])
floor_masses, storey_drifts, storey_forces, phi, metadata = calibrate_model(
nst=4,
sdof_capacity=sdof_capacity,
storey_heights=[3.0, 3.0, 3.0, 3.0],
)
print(f"Floor masses: {floor_masses}")