Source code for vane.campbell.builder

"""Assembly of Campbell-diagram data from tracked modes.

A Campbell diagram plots modal natural frequency (and damping) against an operating
parameter — rotor speed or wind speed — with one curve per tracked mode. This
module pairs the mode tracks from :func:`vane.modal.identify_modes` with the
operating-parameter value of each operating point, producing a structure ready for
plotting or resonance analysis.
"""

from __future__ import annotations

from dataclasses import dataclass
from typing import TYPE_CHECKING

import numpy as np

from vane.modal.identifier import identify_modes

if TYPE_CHECKING:
    from collections.abc import Sequence

    import numpy.typing as npt

    from vane.modal.eigensolver import ModalSolution
    from vane.modal.identifier import IdentificationResult, ModeTrack

__all__ = ["CampbellDiagram", "build_campbell", "campbell_from_solutions"]


[docs] @dataclass class CampbellDiagram: """Campbell-diagram data: tracked modes against an operating parameter. Parameters ---------- parameter_values : npt.NDArray[np.float64] Operating-parameter value (e.g. rotor speed in rev/min) at each operating point, indexed by operating-point number, shape ``(n_operating_points,)``. parameter_name : str Name of the operating parameter (e.g. ``"rotor_speed_rpm"``). tracks : list[ModeTrack] The tracked modes, ordered by first natural frequency. n_operating_points : int Number of operating points. """ parameter_values: npt.NDArray[np.float64] parameter_name: str tracks: list[ModeTrack] n_operating_points: int
[docs] def track_curve( self, track: ModeTrack ) -> tuple[ npt.NDArray[np.float64], npt.NDArray[np.float64], npt.NDArray[np.float64] ]: """Return the operating-parameter, frequency, and damping arrays of a track. Parameters ---------- track : ModeTrack A track belonging to this diagram. Returns ------- tuple of npt.NDArray[np.float64] ``(parameter_values, natural_frequencies_hz, damping_ratios)`` along the track, each of length equal to the track's span. """ x = self.parameter_values[track.operating_points] return ( x, np.asarray(track.natural_frequencies_hz, dtype=np.float64), np.asarray(track.damping_ratios, dtype=np.float64), )
[docs] def build_campbell( result: IdentificationResult, parameter_values: Sequence[float], *, parameter_name: str = "rotor_speed_rpm", ) -> CampbellDiagram: """Build a Campbell diagram from identified mode tracks. Parameters ---------- result : IdentificationResult The cross-operating-point mode tracks. parameter_values : Sequence[float] Operating-parameter value at each operating point, in operating-point order; its length must equal ``result.n_operating_points``. parameter_name : str, optional Name of the operating parameter (default ``"rotor_speed_rpm"``). Returns ------- CampbellDiagram The assembled diagram. Raises ------ ValueError If ``parameter_values`` length does not match the number of operating points. """ if len(parameter_values) != result.n_operating_points: msg = ( f"parameter_values has {len(parameter_values)} entries but there are " f"{result.n_operating_points} operating points" ) raise ValueError(msg) return CampbellDiagram( parameter_values=np.asarray(parameter_values, dtype=np.float64), parameter_name=parameter_name, tracks=result.tracks, n_operating_points=result.n_operating_points, )
[docs] def campbell_from_solutions( solutions: Sequence[ModalSolution], parameter_values: Sequence[float], *, parameter_name: str = "rotor_speed_rpm", frequency_weight: float = 0.5, mac_threshold: float = 0.5, ) -> CampbellDiagram: """Identify mode tracks from solutions and build a Campbell diagram. Parameters ---------- solutions : Sequence[ModalSolution] Modal solutions, one per operating point, in operating-point order. parameter_values : Sequence[float] Operating-parameter value at each operating point. parameter_name : str, optional Name of the operating parameter. frequency_weight, mac_threshold : float, optional Passed through to :func:`vane.modal.identify_modes`. Returns ------- CampbellDiagram The assembled diagram. """ result = identify_modes( solutions, frequency_weight=frequency_weight, mac_threshold=mac_threshold ) return build_campbell(result, parameter_values, parameter_name=parameter_name)