pyserep.frf
pyserep.frf — FRF computation (direct and modal).
- class pyserep.frf.FRFResult(freqs_hz: ~numpy.ndarray, H_rom: ~typing.Dict[str, ~numpy.ndarray], H_ref: ~typing.Dict[str, ~numpy.ndarray], band_masks: ~typing.Dict[str, ~numpy.ndarray], method: str = 'direct', errors: ~typing.Dict[str, ~typing.Dict] = <factory>)[source]
Bases:
objectContainer for FRF results from both ROM and reference models.
- freqs_hz
Evaluation frequencies (Hz). May be non-uniform if selective bands are used.
- Type:
np.ndarray
- errors
Per-pair error metrics computed at construction time. Each entry is
{"max_pct": float, "rms_pct": float}.- Type:
- pyserep.frf.compute_frf_direct(Ka: ndarray, Ma: ndarray, force_dof_indices: List[int], output_dof_indices: List[int], freq_eval: ndarray | List[float], zeta: float = 0.001, Ca: ndarray | None = None, damping_type: str = 'modal', eta: float = 0.0, verbose: bool = True) Tuple[ndarray, Dict[str, ndarray]][source]
Compute FRF of the SEREP ROM using direct impedance inversion.
At each frequency ω, solve: Z(ω) H_col = I_{force_col}
where Z(ω) = Kₐ - ω²Mₐ + jωCₐ (or Kₐ(1+jη) - ω²Mₐ for hysteretic).
- Parameters:
Ka (np.ndarray, shape (m, m)) – Reduced stiffness matrix from SEREP.
Ma (np.ndarray, shape (m, m)) – Reduced mass matrix from SEREP.
force_dof_indices (list of int) – Indices of force (input) DOFs within the master DOF set (0-based, 0..m-1).
output_dof_indices (list of int) – Indices of response (output) DOFs within the master DOF set. Must be the same length as force_dof_indices.
freq_eval (array-like) – Evaluation frequencies in Hz.
zeta (float) – Uniform modal damping ratio (used only for
damping_type="modal"anddamping_type="rayleigh").Ca (np.ndarray, shape (m, m), optional) – User-supplied damping matrix. Overrides zeta and damping_type.
damping_type (str) – One of: *
"modal"— Ca built from modal damping ratios *"rayleigh"— Ca = α Ma + β Ka *"hysteretic"— structural damping: Ka(1+jη)−ω²Ma *"none"— undampedeta (float) – Structural damping loss factor (only for
damping_type="hysteretic").verbose (bool)
- Returns:
freq_eval (np.ndarray) – Evaluation frequencies in Hz.
H (dict) – FRF arrays keyed by
"f{fi}_o{oi}". Values are complex arrays of shape (n_freq,).
Notes
This function uses LU factorisation reuse (
scipy.linalg.lu_factor) only when the frequency loop is over simple viscous damping. For hysteretic or arbitrary Ca the system matrix changes with every ω so each step requires a fresh solve; but the (m × m) system is small, making direct LU fast regardless.Examples
>>> freqs, H = compute_frf_direct(Ka, Ma, [5], [5], np.arange(1, 501)) >>> H["f5_o5"].shape (500,)
- pyserep.frf.compute_frf_direct_fullmodel(K: csc_matrix, M: csc_matrix, master_dofs: ndarray, force_dof_global: List[int], output_dof_global: List[int], freq_eval: ndarray | List[float], zeta: float = 0.001, verbose: bool = True) Tuple[ndarray, Dict[str, ndarray]][source]
Compute reference FRF directly from the full-order physical matrices.
This is the true ground truth — no modal truncation, no approximation. Uses sparse LU factorisation at each frequency step.
WARNING: This function is computationally expensive for large systems (N > 10,000 DOFs × many frequencies). For large models, the modal reference (
compute_frf_modal_reference()) with all elastic modes is a practical alternative.- Parameters:
K (scipy.sparse.csc_matrix) – Full stiffness matrix.
M (scipy.sparse.csc_matrix) – Full mass matrix.
master_dofs (np.ndarray of int) – Global DOF indices corresponding to the ROM master DOFs. Used to determine the force/output DOF local indices.
force_dof_global (list of int) – Force DOF global indices (into the N-DOF full model).
output_dof_global (list of int) – Response DOF global indices.
freq_eval (array-like) – Evaluation frequencies in Hz.
zeta (float) – Uniform modal damping ratio (Rayleigh-type applied to full model).
verbose (bool)
- Returns:
freq_eval (np.ndarray)
H_ref (dict)
- pyserep.frf.compute_frf_modal(phi: ndarray, freqs_hz: ndarray, mode_indices: ndarray, force_dofs: List[int], output_dofs: List[int], band_set: FrequencyBandSet, zeta: float = 0.001, per_mode_zeta: ndarray | None = None, verbose: bool = True) Tuple[ndarray, Dict[str, ndarray]][source]
Compute FRF via modal superposition, evaluated only within band regions.
- Parameters:
phi (np.ndarray, shape (N, n_modes)) – Full modal matrix (mass-normalised).
freqs_hz (np.ndarray, shape (n_modes,)) – Natural frequencies in Hz.
mode_indices (np.ndarray of int) – Indices of modes to include in the superposition.
band_set (FrequencyBandSet) – Defines the frequency evaluation grid.
zeta (float) – Uniform damping ratio (used when
per_mode_zetais None).per_mode_zeta (np.ndarray, optional) – Per-mode damping ratios, shape (n_modes,). Overrides zeta.
verbose (bool)
- Returns:
freq_eval (np.ndarray) – Evaluation frequencies (Hz).
H (dict) – FRF arrays keyed by
"f{fi}_o{oi}".
- pyserep.frf.compute_frf_modal_reference(phi: ndarray, freqs_hz: ndarray, rb_hz: float, force_dofs: List[int], output_dofs: List[int], band_set: FrequencyBandSet, zeta: float = 0.001, verbose: bool = True) Dict[str, ndarray][source]
Compute reference FRF using ALL elastic modes of the full model.
This is used as the ground truth for FRF accuracy assessment.
- pyserep.frf.compute_frf_pair_direct(Ka: ndarray, Ma: ndarray, phi: ndarray, freqs_hz_all: ndarray, selected_modes: ndarray, master_dofs: ndarray, force_dofs: List[int], output_dofs: List[int], band_set: FrequencyBandSet, zeta: float = 0.001, damping_type: str = 'modal', rb_hz: float = 1.0, verbose: bool = True) FRFResult[source]
Compute both ROM (direct) and reference (modal, all elastic modes) FRFs.
The reference uses all elastic modes via modal superposition — this is sufficiently accurate for large models where the direct full-model solve would be prohibitively expensive.
- Parameters:
Ka (np.ndarray, shape (m, m)) – Reduced matrices from SEREP.
Ma (np.ndarray, shape (m, m)) – Reduced matrices from SEREP.
phi (np.ndarray, shape (N, n_modes)) – Full modal matrix.
freqs_hz_all (np.ndarray) – All full-model natural frequencies.
selected_modes (np.ndarray of int)
master_dofs (np.ndarray of int)
band_set (FrequencyBandSet)
zeta (see
compute_frf_direct())damping_type (see
compute_frf_direct())rb_hz (see
compute_frf_direct())verbose (bool)
- Return type: