API Reference

Package

VorLap public package interface.

AirfoilFFT

Holds multidimensional FFT data for unsteady aerodynamic forces and moments as a function of Reynolds number and angle of attack.

Attributes:
  • name (str) –

    Airfoil identifier name

  • Re (ndarray) –

    Reynolds number axis (1D)

  • AOA (ndarray) –

    Angle of attack axis in degrees (1D)

  • Thickness (float) –

    Relative airfoil thickness

  • CL_ST (ndarray) –

    Strouhal numbers for lift coefficient [Re × AOA × freq]

  • CD_ST (ndarray) –

    Strouhal numbers for drag coefficient

  • CM_ST (ndarray) –

    Strouhal numbers for moment coefficient

  • CF_ST (ndarray) –

    Strouhal numbers for total force coefficient magnitude

  • CL_Amp (ndarray) –

    FFT amplitudes of CL [Re × AOA × freq]

  • CD_Amp (ndarray) –

    FFT amplitudes of CD

  • CM_Amp (ndarray) –

    FFT amplitudes of CM

  • CF_Amp (ndarray) –

    FFT amplitudes of CF

  • CL_Pha (ndarray) –

    FFT phases of CL (radians)

  • CD_Pha (ndarray) –

    FFT phases of CD

  • CM_Pha (ndarray) –

    FFT phases of CM

  • CF_Pha (ndarray) –

    FFT phases of CF

  • _interpolators_cached (bool) –

    Whether interpolators are pre-computed

  • _cl_st_interps (List) –

    Pre-computed ST interpolators for CL

  • _cl_amp_interps (List) –

    Pre-computed amplitude interpolators for CL

  • _cl_pha_interps (List) –

    Pre-computed phase interpolators for CL

  • _cd_st_interps (List) –

    Pre-computed ST interpolators for CD

  • _cd_amp_interps (List) –

    Pre-computed amplitude interpolators for CD

  • _cd_pha_interps (List) –

    Pre-computed phase interpolators for CD

  • _cf_st_interps (List) –

    Pre-computed ST interpolators for CF

  • _cf_amp_interps (List) –

    Pre-computed amplitude interpolators for CF

  • _cf_pha_interps (List) –

    Pre-computed phase interpolators for CF

Notes
  • The frequency axis is implicit in the third dimension and must be consistent across all arrays.
  • All arrays must share shape [length(Re), length(AOA), length(freq)].
  • Phases are in radians, and FFT data assumes periodic unsteady oscillations (e.g., vortex shedding).

__init__(name: str, Re: np.ndarray, AOA: np.ndarray, Thickness: float, CL_ST: np.ndarray, CD_ST: np.ndarray, CM_ST: np.ndarray, CF_ST: np.ndarray, CL_Amp: np.ndarray, CD_Amp: np.ndarray, CM_Amp: np.ndarray, CF_Amp: np.ndarray, CL_Pha: np.ndarray, CD_Pha: np.ndarray, CM_Pha: np.ndarray, CF_Pha: np.ndarray)

Initialize AirfoilFFT with the provided data.

Component

Represents a single physical component in the full rotating structure. Each component includes a global transformation and local shape definition, segmented for per-section force calculations.

Attributes:
  • id (str) –

    Identifier name for the component

  • translation (ndarray) –

    Translation vector applied to the entire component

  • rotation (ndarray) –

    Euler angle rotation vector [deg] around X, Y, Z axes

  • pitch (ndarray) –

    Pitch angle for the segment [deg], vectorized to avoid mutability

  • shape_xyz (ndarray) –

    Nx3 matrix of local segment positions (untransformed)

  • shape_xyz_global (ndarray) –

    Nx3 matrix of global segment positions (transformed)

  • chord (ndarray) –

    Chord length per segment

  • twist (ndarray) –

    Twist angle per segment [deg]

  • thickness (ndarray) –

    Relative thickness per segment (scales airfoil height), fraction of chord

  • offset (ndarray) –

    Offset values per segment

  • airfoil_ids (List[str]) –

    Airfoil data identifier for each segment (defaults to "default" if missing)

  • chord_vector (ndarray) –

    Chord vector for each segment

  • normal_vector (ndarray) –

    Normal vector for each segment

__init__(id: str, translation: np.ndarray, rotation: np.ndarray, pitch: np.ndarray, shape_xyz: np.ndarray, shape_xyz_global: np.ndarray, chord: np.ndarray, twist: np.ndarray, thickness: np.ndarray, offset: np.ndarray, airfoil_ids: List[str], chord_vector: np.ndarray, normal_vector: np.ndarray)

Initialize Component with the provided data.

InflowTimeSeries

Time-varying inflow profile used for nonstationary force reconstruction.

Attributes:
  • time (ndarray) –

    Time stamps [s], strictly increasing.

  • inflow_speeds (ndarray) –

    Inflow speed magnitude [m/s] per time sample.

  • inflow_directions (ndarray) –

    Unit inflow direction vectors [ntime x 3].

VIV_Params

Encapsulates all top-level user-defined configuration inputs required for vortex-induced vibration analysis.

Attributes:
  • fluid_density (float) –

    Air density [kg/m³]

  • fluid_dynamicviscosity (float) –

    Dynamic viscosity of air [Pa·s]

  • rotation_axis (ndarray) –

    Axis of rotation as a 3-element vector

  • rotation_axis_offset (ndarray) –

    Origin of the rotation axis (used in torque calculations and visualization)

  • inflow_vec (ndarray) –

    Direction of inflow velocity (typically [1, 0, 0] for +X)

  • plot_cycle (List[str]) –

    List of hex colors used to differentiate components in visualization

  • azimuths (ndarray) –

    Azimuthal angles [deg] swept by the rotor or structure

  • inflow_speeds (ndarray) –

    Freestream inflow speeds [m/s]

  • output_time (ndarray) –

    Output time points [s]

  • freq_min (float) –

    Minimum frequency [Hz] to consider in overlap comparison

  • freq_max (float) –

    Maximum frequency [Hz] to consider in overlap comparison

  • airfoil_folder (str) –

    Path to the airfoil folder

  • n_harmonic (int) –

    Number of harmonics to check against

  • amplitude_coeff_cutoff (float) –

    Lower threshold on what amplitudes are of interest

  • n_freq_depth (int) –

    How deep to go in the Strouhaul number spectrum

  • output_azimuth_vinf (Tuple[float, float]) –

    Used to limit the case where the relatively expensive output signal reconstruction is done

__init__(fluid_density: float = 1.225, fluid_dynamicviscosity: float = 1.81e-05, rotation_axis: np.ndarray = np.array([0.0, 0.0, 1.0]), rotation_axis_offset: np.ndarray = np.array([0.0, 0.0, 0.0]), inflow_vec: np.ndarray = np.array([1.0, 0.0, 0.0]), plot_cycle: Optional[List[str]] = None, azimuths: Optional[np.ndarray] = None, inflow_speeds: Optional[np.ndarray] = None, output_time: Optional[np.ndarray] = None, freq_min: float = 0.0, freq_max: float = float('inf'), airfoil_folder: Optional[str] = None, n_harmonic: int = 5, amplitude_coeff_cutoff: float = 0.01, n_freq_depth: int = 3, output_azimuth_vinf: Tuple[float, float] = (5.0, 2.0))

Initialize VIV_Params with the provided data.

calc_structure_vectors_andplot(components: List[Component], viv_params: VIV_Params, show_plot: bool = True, return_fig: bool = False, components_black: bool = False, save_path: Optional[str] = None) -> Optional[go.Figure]

Calculates structure vectors and creates a plot.

Parameters:
  • components (List[Component]) –

    List of structural components.

  • viv_params (VIV_Params) –

    Configuration parameters.

  • show_plot (bool, default: True ) –

    Whether to display the plot (default: True).

  • return_fig (bool, default: False ) –

    Whether to return the figure object (default: False).

  • components_black (bool, default: False ) –

    When True, draw component geometry in black instead of the default blue (default: False).

  • save_path (Optional[str], default: None ) –

    Optional file path for static image export via Kaleido. If None, no static image is written.

Returns:
  • Optional[Figure]

    Optional[go.Figure]: Plotly figure object if return_fig=True, otherwise None.

compute_thrust_torque_spectrum(components: List[Component], affts: Dict[str, AirfoilFFT], viv_params: VIV_Params, natfreqs: np.ndarray) -> Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray]

Compute force, moment, overlap metrics, and node-level reconstructed loads.

This variant uses the baseline per-field interpolation backend.

compute_thrust_torque_spectrum_optimized(components: List[Component], affts: Dict[str, AirfoilFFT], viv_params: VIV_Params, natfreqs: np.ndarray) -> Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray]

Compute force, moment, overlap metrics, and node-level reconstructed loads.

This variant uses the optimized vectorized interpolation backend.

compute_time_varying_force_history(components: List[Component], affts: Dict[str, AirfoilFFT], viv_params: VIV_Params, inflow_profile: Union[InflowTimeSeries, Dict[str, np.ndarray]], azimuth_deg: Optional[float] = None, smoothing_cycles: float = 0.25, n_freq_depth: Optional[int] = None) -> Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]

Baseline nonstationary force-history computation.

This variant uses per-sample interpolation and is primarily intended as a reference for the optimized implementation.

compute_time_varying_force_history_optimized(components: List[Component], affts: Dict[str, AirfoilFFT], viv_params: VIV_Params, inflow_profile: Union[InflowTimeSeries, Dict[str, np.ndarray]], azimuth_deg: Optional[float] = None, smoothing_cycles: float = 0.25, n_freq_depth: Optional[int] = None) -> Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]

Compute nonstationary node/global forces for time-varying inflow speed and direction.

Returns:
  • time( ndarray ) –

    Time vector [ntime].

  • total_global_force_vector( ndarray ) –

    Global force time series [ntime, 3].

  • total_global_moment_vector( ndarray ) –

    Global moment time series [ntime, 3].

  • global_force_vector_nodes( ndarray ) –

    Node-level force time series [ntime, 3, nnodes].

convert_qblade_to_vorlap_inputs(sim_path: str, default_airfoil_id: str = 'default', include_struts: bool = True, include_tower: bool = True, tower_airfoil_id: str = 'cylinder') -> Tuple[List[Component], VIV_Params, List[str]]

Convert a QBlade .sim setup into equivalent VorLap components and baseline parameters.

This supports the "existing LOADINGFILE path" workflow where VorLap reconstructs non-mean nodal loads and exports them for QBlade external-loading ingestion.

Returns:
  • components( List[Component] ) –

    VorLap components equivalent to QBlade blade/strut geometry.

  • viv_params( VIV_Params ) –

    Baseline parameters inferred from QBlade simulation/turbine files.

  • qblade_node_ids( List[str] ) –

    Per-node QBlade location IDs aligned with VorLap node ordering.

Parameters:
  • include_struts (bool, default: True ) –

    Include strut components when available in the blade definition.

  • include_tower (bool, default: True ) –

    Include a tower component inferred from .trb tower fields.

interpolate_fft_spectrum(afft: AirfoilFFT, Re_val: float, AOA_val: float, field: str, n_freq_depth: Optional[int] = None) -> Tuple[np.ndarray, np.ndarray, np.ndarray]

Interpolates the FFT amplitude and phase spectra for a given Reynolds number Re_val and angle of attack AOA_val using bilinear interpolation over the stored Re × AOA grid.

Parameters:
  • afft (AirfoilFFT) –

    AirfoilFFT struct containing FFT results.

  • Re_val (float) –

    Desired Reynolds number.

  • AOA_val (float) –

    Desired angle of attack (degrees).

  • field (str) –

    String ('CL', 'CD', 'CM', or 'CF') indicating which force coefficient to interpolate.

  • n_freq_depth (Optional[int], default: None ) –

    Optional number of frequencies to return. If None, returns all frequencies.

Returns:
  • freqs( ndarray ) –

    Vector of frequency values.

  • amp_out( ndarray ) –

    Vector of interpolated amplitudes at each frequency.

  • phase_out( ndarray ) –

    Vector of interpolated phases at each frequency.

Notes
  • The interpolation is performed independently at each frequency index in the spectrum.
  • Assumes consistent frequency axis across the full 3D data structure.
  • Returns values suitable for reconstructing time-domain or frequency-domain force estimates.

interpolate_fft_spectrum_batch(afft: AirfoilFFT, Re_vals: np.ndarray, AOA_vals: np.ndarray, field: str, n_freq_depth: Optional[int] = None) -> Tuple[np.ndarray, np.ndarray, np.ndarray]

Batch interpolation for multiple Re/AOA points simultaneously.

Parameters:
  • afft (AirfoilFFT) –

    AirfoilFFT struct containing FFT results with cached interpolators.

  • Re_vals (ndarray) –

    Array of Reynolds numbers.

  • AOA_vals (ndarray) –

    Array of angles of attack (degrees).

  • field (str) –

    Field string ('CL', 'CD', 'CM', 'CF') to interpolate.

  • n_freq_depth (Optional[int], default: None ) –

    Optional number of frequencies to return.

Returns:
  • ST_out( ndarray ) –

    Array of shape [n_points, n_freq]

  • amp_out( ndarray ) –

    Array of shape [n_points, n_freq]

  • phase_out( ndarray ) –

    Array of shape [n_points, n_freq]

interpolate_fft_spectrum_optimized(afft: AirfoilFFT, Re_val: float, AOA_val: float, fields: List[str], n_freq_depth: Optional[int] = None) -> Dict[str, Tuple[np.ndarray, np.ndarray, np.ndarray]]

Vectorized, fast bilinear + flat extrapolation for multiple fields at once. Matches your return structure: { 'CL': (ST, Amp, Pha), ... } with arrays length n_freq_depth.

load_airfoil_coords(afpath: str = '') -> np.ndarray

Loads an airfoil shape from a 2-column text file (x, z), normalized to unit chord length. If no file is specified, or if loading fails, returns a built-in 200-point Clark Y airfoil shape.

Parameters:
  • afpath (str, default: '' ) –

    Optional path to a text file with two columns: x and z coordinates.

Returns:
  • xy( ndarray ) –

    Nx2 matrix of normalized (x, y) coordinates representing the airfoil surface.

Notes
  • If loading from file, x-coordinates are normalized to span [0, 1].
  • The default fallback airfoil is a symmetric approximation of the Clark Y shape.
  • This airfoil is primarily used for visualization, not aerodynamic calculations.

load_airfoil_fft(path: str) -> AirfoilFFT

Loads a processed airfoil unsteady FFT dataset from an HDF5 file.

Parameters:
  • path (str) –

    Path to the HDF5 file containing the airfoil FFT data.

Returns:
  • AirfoilFFT

    AirfoilFFT object containing the loaded data.

Expected HDF5 File Format

The file must contain the following datasets: - Airfoilname :: String — Name of the airfoil (e.g., "NACA0012") - Re :: Vector{Float64} — Reynolds number values (assumed constant across all entries) - Thickness :: Vector{Float64} — Thickness ratio(s) used - AOA :: Vector{Float64} — Angle of attack values in degrees - CL_ST, CD_ST, CM_ST, CF_ST :: 3D Arrays [Re x AOA x freq] — Strouhal numbers for each force/moment - CL_Amp, CD_Amp, CM_Amp, CF_Amp :: 3D Arrays [Re x AOA x freq] — FFT amplitudes for lift, drag, moment, and combined force - CL_Pha, CD_Pha, CM_Pha, CF_Pha :: 3D Arrays [Re x AOA x freq] — FFT phases in radians for each quantity

Assumptions
  • All arrays must share dimensions [Re, AOA, NFreq], where the frequency dimension is sorted by the amplitude
  • Phase data is in radians.
  • Struhaul data represents unsteady aerodynamics due to vortex shedding.
  • No ragged or missing data is allowed.

load_components_from_csv(dir_path: str) -> List[Component]

Loads all component geometry and metadata from CSV files in the given directory.

Parameters:
  • dir_path (str) –

    Path to a directory containing CSV files. Each file must follow a two-header format.

Returns:
  • List[Component]

    List of parsed Component objects containing all geometry and configuration data.

Expected CSV Format
  1. First data row contains: id, translation_x, translation_y, translation_z, rotation_x, rotation_y, rotation_z
  2. Second header row: column names for vectors — must include x, y, z, chord, twist, thickness, and optional airfoil_id
  3. Remaining rows: vector data for each blade segment or shape point
Notes
  • If airfoil_id is missing, "default" will be used for all segments in that component
  • All transformations are centered at the origin and adjusted by top-level translation/rotation
  • All components are assumed to have the span oriented in the z-direction

load_inflow_time_series(path: str) -> InflowTimeSeries

Load a time-varying inflow profile from CSV.

Required columns
  • time
  • inflow_speed
Direction column options

1) inflow_direction_deg (degrees CCW from +X in the global XY plane), or 2) inflow_dir_x, inflow_dir_y, and optional inflow_dir_z.

Parameters:
  • path (str) –

    CSV file path.

Returns:
  • InflowTimeSeries

    InflowTimeSeries with validated and normalized direction vectors.

load_qblade_blade_definition(bld_path: str) -> Dict[str, object]

Load blade and strut geometry tables from a QBlade .bld definition file.

Returns:
  • Dict[str, object]

    Dictionary with fields: - num_blades - blade_rows (list of dicts) - strut_rows (list of dicts)

load_qblade_simulation_definition(sim_path: str) -> Dict[str, object]

Load key fields from a QBlade .sim file.

Returns a dictionary with parsed and path-resolved entries used by VorLap.

load_qblade_turbine_definition(trb_path: str) -> Dict[str, object]

Load key fields from a QBlade .trb turbine definition file.

lookup_fft_spectrum_nearest(afft, Re_val: float, AOA_val: float, fields: List[str], n_freq_depth: Optional[int] = None) -> Dict[str, Tuple[np.ndarray, np.ndarray, np.ndarray]]

Nearest-neighbor lookup (no interpolation). Matches your return structure: { 'CL': (ST, Amp, Pha), ... }.

reconstruct_nonstationary_signal(freqs: np.ndarray, amps: np.ndarray, phases: np.ndarray, tvec: np.ndarray, smoothing_cycles: float = 0.0) -> np.ndarray

Reconstruct a nonstationary harmonic signal with phase continuity.

This is an oscillator-bank reconstruction where instantaneous phase is integrated from frequency (dphi/dt = 2*pi*f(t)) to avoid discontinuities when inflow conditions vary in time. The provided phase is used as the initial phase for each harmonic; subsequent phase evolution comes from frequency integration.

Parameters:
  • freqs (ndarray) –

    Instantaneous frequencies [ntime, nfreq] in Hz.

  • amps (ndarray) –

    Instantaneous peak amplitudes [ntime, nfreq].

  • phases (ndarray) –

    Instantaneous phase offsets [ntime, nfreq] in rad.

  • tvec (ndarray) –

    Time vector [ntime] in seconds.

  • smoothing_cycles (float, default: 0.0 ) –

    Optional smoothing strength in oscillation cycles for frequency/amplitude trajectories (0 disables smoothing).

Returns:
  • ndarray

    Reconstructed signal [ntime].

reconstruct_signal(freqs: np.ndarray, amps: np.ndarray, phases: np.ndarray, tvec: np.ndarray) -> np.ndarray

Reconstruct a time-domain signal from frequency, peak amplitude, and phase (radians).

Assumptions / conventions (matching the Julia version): - DC term(s): entries where freqs == 0 carry the mean value in amps; all such entries are summed. - For f > 0, amps are peak amplitudes (not RMS) and phases follow a cosine convention: cos(ωt + φ). - Negative frequencies, if present, are ignored (assumed redundant w.r.t. positive freqs + phases).

Parameters:
  • freqs (ndarray) –

    Array of frequencies [Hz].

  • amps (ndarray) –

    Array of peak amplitudes corresponding to each frequency.

  • phases (ndarray) –

    Array of phase offsets [rad] corresponding to each frequency.

  • tvec (ndarray) –

    Time vector [s] (must have at least 2 samples).

Returns:
  • ndarray

    np.ndarray: Reconstructed time-domain signal (float64), shape (len(tvec),).

resample_airfoil(xy: np.ndarray, npoints: int = 200) -> np.ndarray

Resamples the given airfoil shape by: 1. Identifying leading (min x) and trailing (max x) edges. 2. Splitting into upper and lower surfaces. 3. Interpolating both surfaces using npoints uniformly spaced x-values. 4. Recombining to produce a smooth resampled airfoil shape.

Parameters:
  • xy (ndarray) –

    Nx2 matrix of (x, y) airfoil coordinates, not assumed to start at TE or LE.

  • npoints (int, default: 200 ) –

    Number of points used in interpolation (default: 200).

Returns:
  • xy_resampled( ndarray ) –

    Resampled and recombined airfoil shape.

rotate_vector(vec: np.ndarray, axis: np.ndarray, angle_deg: float) -> np.ndarray

Rotates a 3D vector vec around a given axis by angle_deg degrees using Rodrigues' rotation formula.

Parameters:
  • vec (ndarray) –

    Vector to rotate (length-3, any direction).

  • axis (ndarray) –

    Rotation axis (length-3, not required to be normalized).

  • angle_deg (float) –

    Rotation angle in degrees (positive is right-hand rule about the axis).

Returns:
  • ndarray

    Rotated 3D vector (length-3).

rotationMatrix(euler: np.ndarray) -> np.ndarray

Computes a 3×3 rotation matrix from Euler angles using the ZYX convention (yaw–pitch–roll), where: - Z: yaw (heading) - Y: pitch (elevation) - X: roll (bank)

The angles are provided in degrees and applied in Z–Y–X order (extrinsic frame), meaning: 1. Rotate about global Z axis (yaw) 2. Then about the global Y axis (pitch) 3. Then about the global X axis (roll)

Parameters:
  • euler (ndarray) –

    Euler angles [roll, pitch, yaw] in degrees.

Returns:
  • R_global( ndarray ) –

    A 3×3 rotation matrix for transforming a local vector into the global frame.

Example
euler = np.array([30.0, 15.0, 60.0])  # roll, pitch, yaw in degrees
R = rotationMatrix(euler)
v_local = np.array([1.0, 0.0, 0.0])
v_global = R @ v_local

write_components_to_csv(dir_path: str, components: List[Component]) -> List[str]

Write VorLap components to per-component CSV files compatible with load_components_from_csv.

Parameters:
  • dir_path (str) –

    Output directory for component CSV files.

  • components (List[Component]) –

    Components to write.

Returns:
  • List[str]

    List of absolute file paths written.

write_force_time_series(filename: str, output_time: np.ndarray, global_force_vector_nodes: np.ndarray) -> None

Writes force time series data to a CSV file.

Parameters:
  • filename (str) –

    Path to the output CSV file.

  • output_time (ndarray) –

    Vector of time points.

  • global_force_vector_nodes (ndarray) –

    Array of force vectors for each node at each time point.

Returns:
  • None

    None

write_qblade_loading_file(filename: str, time: np.ndarray, global_force_vector_nodes: np.ndarray, node_ids: List[str], local: bool = False, node_torque_vector_nodes: Optional[np.ndarray] = None) -> None

Write a QBlade external loading file compatible with LOADINGFILE.

File format per node block

NODE_ID [LOCAL] t Fx Fy Fz Mx My Mz ...

QBlade linearly interpolates between time rows during simulation.

vorlap.computations

Utility functions for the VorLap package.

compute_thrust_torque_spectrum(components: List[Component], affts: Dict[str, AirfoilFFT], viv_params: VIV_Params, natfreqs: np.ndarray) -> Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray]

Compute force, moment, overlap metrics, and node-level reconstructed loads.

This variant uses the baseline per-field interpolation backend.

compute_thrust_torque_spectrum_optimized(components: List[Component], affts: Dict[str, AirfoilFFT], viv_params: VIV_Params, natfreqs: np.ndarray) -> Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray]

Compute force, moment, overlap metrics, and node-level reconstructed loads.

This variant uses the optimized vectorized interpolation backend.

compute_time_varying_force_history(components: List[Component], affts: Dict[str, AirfoilFFT], viv_params: VIV_Params, inflow_profile: Union[InflowTimeSeries, Dict[str, np.ndarray]], azimuth_deg: Optional[float] = None, smoothing_cycles: float = 0.25, n_freq_depth: Optional[int] = None) -> Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]

Baseline nonstationary force-history computation.

This variant uses per-sample interpolation and is primarily intended as a reference for the optimized implementation.

compute_time_varying_force_history_optimized(components: List[Component], affts: Dict[str, AirfoilFFT], viv_params: VIV_Params, inflow_profile: Union[InflowTimeSeries, Dict[str, np.ndarray]], azimuth_deg: Optional[float] = None, smoothing_cycles: float = 0.25, n_freq_depth: Optional[int] = None) -> Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]

Compute nonstationary node/global forces for time-varying inflow speed and direction.

Returns:
  • time( ndarray ) –

    Time vector [ntime].

  • total_global_force_vector( ndarray ) –

    Global force time series [ntime, 3].

  • total_global_moment_vector( ndarray ) –

    Global moment time series [ntime, 3].

  • global_force_vector_nodes( ndarray ) –

    Node-level force time series [ntime, 3, nnodes].

interpolate_fft_spectrum(afft, Re_val, AOA_val, field, n_freq_depth=None)

This is a wrapper function to avoid circular imports. The actual implementation is in fileio.py.

reconstruct_nonstationary_signal(freqs: np.ndarray, amps: np.ndarray, phases: np.ndarray, tvec: np.ndarray, smoothing_cycles: float = 0.0) -> np.ndarray

Reconstruct a nonstationary harmonic signal with phase continuity.

This is an oscillator-bank reconstruction where instantaneous phase is integrated from frequency (dphi/dt = 2*pi*f(t)) to avoid discontinuities when inflow conditions vary in time. The provided phase is used as the initial phase for each harmonic; subsequent phase evolution comes from frequency integration.

Parameters:
  • freqs (ndarray) –

    Instantaneous frequencies [ntime, nfreq] in Hz.

  • amps (ndarray) –

    Instantaneous peak amplitudes [ntime, nfreq].

  • phases (ndarray) –

    Instantaneous phase offsets [ntime, nfreq] in rad.

  • tvec (ndarray) –

    Time vector [ntime] in seconds.

  • smoothing_cycles (float, default: 0.0 ) –

    Optional smoothing strength in oscillation cycles for frequency/amplitude trajectories (0 disables smoothing).

Returns:
  • ndarray

    Reconstructed signal [ntime].

reconstruct_signal(freqs: np.ndarray, amps: np.ndarray, phases: np.ndarray, tvec: np.ndarray) -> np.ndarray

Reconstruct a time-domain signal from frequency, peak amplitude, and phase (radians).

Assumptions / conventions (matching the Julia version): - DC term(s): entries where freqs == 0 carry the mean value in amps; all such entries are summed. - For f > 0, amps are peak amplitudes (not RMS) and phases follow a cosine convention: cos(ωt + φ). - Negative frequencies, if present, are ignored (assumed redundant w.r.t. positive freqs + phases).

Parameters:
  • freqs (ndarray) –

    Array of frequencies [Hz].

  • amps (ndarray) –

    Array of peak amplitudes corresponding to each frequency.

  • phases (ndarray) –

    Array of phase offsets [rad] corresponding to each frequency.

  • tvec (ndarray) –

    Time vector [s] (must have at least 2 samples).

Returns:
  • ndarray

    np.ndarray: Reconstructed time-domain signal (float64), shape (len(tvec),).

rotate_vector(vec: np.ndarray, axis: np.ndarray, angle_deg: float) -> np.ndarray

Rotates a 3D vector vec around a given axis by angle_deg degrees using Rodrigues' rotation formula.

Parameters:
  • vec (ndarray) –

    Vector to rotate (length-3, any direction).

  • axis (ndarray) –

    Rotation axis (length-3, not required to be normalized).

  • angle_deg (float) –

    Rotation angle in degrees (positive is right-hand rule about the axis).

Returns:
  • ndarray

    Rotated 3D vector (length-3).

rotationMatrix(euler: np.ndarray) -> np.ndarray

Computes a 3×3 rotation matrix from Euler angles using the ZYX convention (yaw–pitch–roll), where: - Z: yaw (heading) - Y: pitch (elevation) - X: roll (bank)

The angles are provided in degrees and applied in Z–Y–X order (extrinsic frame), meaning: 1. Rotate about global Z axis (yaw) 2. Then about the global Y axis (pitch) 3. Then about the global X axis (roll)

Parameters:
  • euler (ndarray) –

    Euler angles [roll, pitch, yaw] in degrees.

Returns:
  • R_global( ndarray ) –

    A 3×3 rotation matrix for transforming a local vector into the global frame.

Example
euler = np.array([30.0, 15.0, 60.0])  # roll, pitch, yaw in degrees
R = rotationMatrix(euler)
v_local = np.array([1.0, 0.0, 0.0])
v_global = R @ v_local

vorlap.interpolation

interpolate_fft_spectrum(afft: AirfoilFFT, Re_val: float, AOA_val: float, field: str, n_freq_depth: Optional[int] = None) -> Tuple[np.ndarray, np.ndarray, np.ndarray]

Interpolates the FFT amplitude and phase spectra for a given Reynolds number Re_val and angle of attack AOA_val using bilinear interpolation over the stored Re × AOA grid.

Parameters:
  • afft (AirfoilFFT) –

    AirfoilFFT struct containing FFT results.

  • Re_val (float) –

    Desired Reynolds number.

  • AOA_val (float) –

    Desired angle of attack (degrees).

  • field (str) –

    String ('CL', 'CD', 'CM', or 'CF') indicating which force coefficient to interpolate.

  • n_freq_depth (Optional[int], default: None ) –

    Optional number of frequencies to return. If None, returns all frequencies.

Returns:
  • freqs( ndarray ) –

    Vector of frequency values.

  • amp_out( ndarray ) –

    Vector of interpolated amplitudes at each frequency.

  • phase_out( ndarray ) –

    Vector of interpolated phases at each frequency.

Notes
  • The interpolation is performed independently at each frequency index in the spectrum.
  • Assumes consistent frequency axis across the full 3D data structure.
  • Returns values suitable for reconstructing time-domain or frequency-domain force estimates.

interpolate_fft_spectrum_batch(afft: AirfoilFFT, Re_vals: np.ndarray, AOA_vals: np.ndarray, field: str, n_freq_depth: Optional[int] = None) -> Tuple[np.ndarray, np.ndarray, np.ndarray]

Batch interpolation for multiple Re/AOA points simultaneously.

Parameters:
  • afft (AirfoilFFT) –

    AirfoilFFT struct containing FFT results with cached interpolators.

  • Re_vals (ndarray) –

    Array of Reynolds numbers.

  • AOA_vals (ndarray) –

    Array of angles of attack (degrees).

  • field (str) –

    Field string ('CL', 'CD', 'CM', 'CF') to interpolate.

  • n_freq_depth (Optional[int], default: None ) –

    Optional number of frequencies to return.

Returns:
  • ST_out( ndarray ) –

    Array of shape [n_points, n_freq]

  • amp_out( ndarray ) –

    Array of shape [n_points, n_freq]

  • phase_out( ndarray ) –

    Array of shape [n_points, n_freq]

interpolate_fft_spectrum_optimized(afft: AirfoilFFT, Re_val: float, AOA_val: float, fields: List[str], n_freq_depth: Optional[int] = None) -> Dict[str, Tuple[np.ndarray, np.ndarray, np.ndarray]]

Vectorized, fast bilinear + flat extrapolation for multiple fields at once. Matches your return structure: { 'CL': (ST, Amp, Pha), ... } with arrays length n_freq_depth.

lookup_fft_spectrum_nearest(afft, Re_val: float, AOA_val: float, fields: List[str], n_freq_depth: Optional[int] = None) -> Dict[str, Tuple[np.ndarray, np.ndarray, np.ndarray]]

Nearest-neighbor lookup (no interpolation). Matches your return structure: { 'CL': (ST, Amp, Pha), ... }.

resample_airfoil(xy: np.ndarray, npoints: int = 200) -> np.ndarray

Resamples the given airfoil shape by: 1. Identifying leading (min x) and trailing (max x) edges. 2. Splitting into upper and lower surfaces. 3. Interpolating both surfaces using npoints uniformly spaced x-values. 4. Recombining to produce a smooth resampled airfoil shape.

Parameters:
  • xy (ndarray) –

    Nx2 matrix of (x, y) airfoil coordinates, not assumed to start at TE or LE.

  • npoints (int, default: 200 ) –

    Number of points used in interpolation (default: 200).

Returns:
  • xy_resampled( ndarray ) –

    Resampled and recombined airfoil shape.

vorlap.fileio

File input/output operations for the VorLap package.

convert_qblade_to_vorlap_inputs(sim_path: str, default_airfoil_id: str = 'default', include_struts: bool = True, include_tower: bool = True, tower_airfoil_id: str = 'cylinder') -> Tuple[List[Component], VIV_Params, List[str]]

Convert a QBlade .sim setup into equivalent VorLap components and baseline parameters.

This supports the "existing LOADINGFILE path" workflow where VorLap reconstructs non-mean nodal loads and exports them for QBlade external-loading ingestion.

Returns:
  • components( List[Component] ) –

    VorLap components equivalent to QBlade blade/strut geometry.

  • viv_params( VIV_Params ) –

    Baseline parameters inferred from QBlade simulation/turbine files.

  • qblade_node_ids( List[str] ) –

    Per-node QBlade location IDs aligned with VorLap node ordering.

Parameters:
  • include_struts (bool, default: True ) –

    Include strut components when available in the blade definition.

  • include_tower (bool, default: True ) –

    Include a tower component inferred from .trb tower fields.

load_airfoil_coords(afpath: str = '') -> np.ndarray

Loads an airfoil shape from a 2-column text file (x, z), normalized to unit chord length. If no file is specified, or if loading fails, returns a built-in 200-point Clark Y airfoil shape.

Parameters:
  • afpath (str, default: '' ) –

    Optional path to a text file with two columns: x and z coordinates.

Returns:
  • xy( ndarray ) –

    Nx2 matrix of normalized (x, y) coordinates representing the airfoil surface.

Notes
  • If loading from file, x-coordinates are normalized to span [0, 1].
  • The default fallback airfoil is a symmetric approximation of the Clark Y shape.
  • This airfoil is primarily used for visualization, not aerodynamic calculations.

load_airfoil_fft(path: str) -> AirfoilFFT

Loads a processed airfoil unsteady FFT dataset from an HDF5 file.

Parameters:
  • path (str) –

    Path to the HDF5 file containing the airfoil FFT data.

Returns:
  • AirfoilFFT

    AirfoilFFT object containing the loaded data.

Expected HDF5 File Format

The file must contain the following datasets: - Airfoilname :: String — Name of the airfoil (e.g., "NACA0012") - Re :: Vector{Float64} — Reynolds number values (assumed constant across all entries) - Thickness :: Vector{Float64} — Thickness ratio(s) used - AOA :: Vector{Float64} — Angle of attack values in degrees - CL_ST, CD_ST, CM_ST, CF_ST :: 3D Arrays [Re x AOA x freq] — Strouhal numbers for each force/moment - CL_Amp, CD_Amp, CM_Amp, CF_Amp :: 3D Arrays [Re x AOA x freq] — FFT amplitudes for lift, drag, moment, and combined force - CL_Pha, CD_Pha, CM_Pha, CF_Pha :: 3D Arrays [Re x AOA x freq] — FFT phases in radians for each quantity

Assumptions
  • All arrays must share dimensions [Re, AOA, NFreq], where the frequency dimension is sorted by the amplitude
  • Phase data is in radians.
  • Struhaul data represents unsteady aerodynamics due to vortex shedding.
  • No ragged or missing data is allowed.

load_components_from_csv(dir_path: str) -> List[Component]

Loads all component geometry and metadata from CSV files in the given directory.

Parameters:
  • dir_path (str) –

    Path to a directory containing CSV files. Each file must follow a two-header format.

Returns:
  • List[Component]

    List of parsed Component objects containing all geometry and configuration data.

Expected CSV Format
  1. First data row contains: id, translation_x, translation_y, translation_z, rotation_x, rotation_y, rotation_z
  2. Second header row: column names for vectors — must include x, y, z, chord, twist, thickness, and optional airfoil_id
  3. Remaining rows: vector data for each blade segment or shape point
Notes
  • If airfoil_id is missing, "default" will be used for all segments in that component
  • All transformations are centered at the origin and adjusted by top-level translation/rotation
  • All components are assumed to have the span oriented in the z-direction

load_inflow_time_series(path: str) -> InflowTimeSeries

Load a time-varying inflow profile from CSV.

Required columns
  • time
  • inflow_speed
Direction column options

1) inflow_direction_deg (degrees CCW from +X in the global XY plane), or 2) inflow_dir_x, inflow_dir_y, and optional inflow_dir_z.

Parameters:
  • path (str) –

    CSV file path.

Returns:
  • InflowTimeSeries

    InflowTimeSeries with validated and normalized direction vectors.

load_qblade_blade_definition(bld_path: str) -> Dict[str, object]

Load blade and strut geometry tables from a QBlade .bld definition file.

Returns:
  • Dict[str, object]

    Dictionary with fields: - num_blades - blade_rows (list of dicts) - strut_rows (list of dicts)

load_qblade_simulation_definition(sim_path: str) -> Dict[str, object]

Load key fields from a QBlade .sim file.

Returns a dictionary with parsed and path-resolved entries used by VorLap.

load_qblade_turbine_definition(trb_path: str) -> Dict[str, object]

Load key fields from a QBlade .trb turbine definition file.

write_components_to_csv(dir_path: str, components: List[Component]) -> List[str]

Write VorLap components to per-component CSV files compatible with load_components_from_csv.

Parameters:
  • dir_path (str) –

    Output directory for component CSV files.

  • components (List[Component]) –

    Components to write.

Returns:
  • List[str]

    List of absolute file paths written.

write_force_time_series(filename: str, output_time: np.ndarray, global_force_vector_nodes: np.ndarray) -> None

Writes force time series data to a CSV file.

Parameters:
  • filename (str) –

    Path to the output CSV file.

  • output_time (ndarray) –

    Vector of time points.

  • global_force_vector_nodes (ndarray) –

    Array of force vectors for each node at each time point.

Returns:
  • None

    None

write_qblade_loading_file(filename: str, time: np.ndarray, global_force_vector_nodes: np.ndarray, node_ids: List[str], local: bool = False, node_torque_vector_nodes: Optional[np.ndarray] = None) -> None

Write a QBlade external loading file compatible with LOADINGFILE.

File format per node block

NODE_ID [LOCAL] t Fx Fy Fz Mx My Mz ...

QBlade linearly interpolates between time rows during simulation.

vorlap.structs

Data structures for the VorLap package.

AirfoilFFT

Holds multidimensional FFT data for unsteady aerodynamic forces and moments as a function of Reynolds number and angle of attack.

Attributes:
  • name (str) –

    Airfoil identifier name

  • Re (ndarray) –

    Reynolds number axis (1D)

  • AOA (ndarray) –

    Angle of attack axis in degrees (1D)

  • Thickness (float) –

    Relative airfoil thickness

  • CL_ST (ndarray) –

    Strouhal numbers for lift coefficient [Re × AOA × freq]

  • CD_ST (ndarray) –

    Strouhal numbers for drag coefficient

  • CM_ST (ndarray) –

    Strouhal numbers for moment coefficient

  • CF_ST (ndarray) –

    Strouhal numbers for total force coefficient magnitude

  • CL_Amp (ndarray) –

    FFT amplitudes of CL [Re × AOA × freq]

  • CD_Amp (ndarray) –

    FFT amplitudes of CD

  • CM_Amp (ndarray) –

    FFT amplitudes of CM

  • CF_Amp (ndarray) –

    FFT amplitudes of CF

  • CL_Pha (ndarray) –

    FFT phases of CL (radians)

  • CD_Pha (ndarray) –

    FFT phases of CD

  • CM_Pha (ndarray) –

    FFT phases of CM

  • CF_Pha (ndarray) –

    FFT phases of CF

  • _interpolators_cached (bool) –

    Whether interpolators are pre-computed

  • _cl_st_interps (List) –

    Pre-computed ST interpolators for CL

  • _cl_amp_interps (List) –

    Pre-computed amplitude interpolators for CL

  • _cl_pha_interps (List) –

    Pre-computed phase interpolators for CL

  • _cd_st_interps (List) –

    Pre-computed ST interpolators for CD

  • _cd_amp_interps (List) –

    Pre-computed amplitude interpolators for CD

  • _cd_pha_interps (List) –

    Pre-computed phase interpolators for CD

  • _cf_st_interps (List) –

    Pre-computed ST interpolators for CF

  • _cf_amp_interps (List) –

    Pre-computed amplitude interpolators for CF

  • _cf_pha_interps (List) –

    Pre-computed phase interpolators for CF

Notes
  • The frequency axis is implicit in the third dimension and must be consistent across all arrays.
  • All arrays must share shape [length(Re), length(AOA), length(freq)].
  • Phases are in radians, and FFT data assumes periodic unsteady oscillations (e.g., vortex shedding).

__init__(name: str, Re: np.ndarray, AOA: np.ndarray, Thickness: float, CL_ST: np.ndarray, CD_ST: np.ndarray, CM_ST: np.ndarray, CF_ST: np.ndarray, CL_Amp: np.ndarray, CD_Amp: np.ndarray, CM_Amp: np.ndarray, CF_Amp: np.ndarray, CL_Pha: np.ndarray, CD_Pha: np.ndarray, CM_Pha: np.ndarray, CF_Pha: np.ndarray)

Initialize AirfoilFFT with the provided data.

Component

Represents a single physical component in the full rotating structure. Each component includes a global transformation and local shape definition, segmented for per-section force calculations.

Attributes:
  • id (str) –

    Identifier name for the component

  • translation (ndarray) –

    Translation vector applied to the entire component

  • rotation (ndarray) –

    Euler angle rotation vector [deg] around X, Y, Z axes

  • pitch (ndarray) –

    Pitch angle for the segment [deg], vectorized to avoid mutability

  • shape_xyz (ndarray) –

    Nx3 matrix of local segment positions (untransformed)

  • shape_xyz_global (ndarray) –

    Nx3 matrix of global segment positions (transformed)

  • chord (ndarray) –

    Chord length per segment

  • twist (ndarray) –

    Twist angle per segment [deg]

  • thickness (ndarray) –

    Relative thickness per segment (scales airfoil height), fraction of chord

  • offset (ndarray) –

    Offset values per segment

  • airfoil_ids (List[str]) –

    Airfoil data identifier for each segment (defaults to "default" if missing)

  • chord_vector (ndarray) –

    Chord vector for each segment

  • normal_vector (ndarray) –

    Normal vector for each segment

__init__(id: str, translation: np.ndarray, rotation: np.ndarray, pitch: np.ndarray, shape_xyz: np.ndarray, shape_xyz_global: np.ndarray, chord: np.ndarray, twist: np.ndarray, thickness: np.ndarray, offset: np.ndarray, airfoil_ids: List[str], chord_vector: np.ndarray, normal_vector: np.ndarray)

Initialize Component with the provided data.

InflowTimeSeries

Time-varying inflow profile used for nonstationary force reconstruction.

Attributes:
  • time (ndarray) –

    Time stamps [s], strictly increasing.

  • inflow_speeds (ndarray) –

    Inflow speed magnitude [m/s] per time sample.

  • inflow_directions (ndarray) –

    Unit inflow direction vectors [ntime x 3].

VIV_Params

Encapsulates all top-level user-defined configuration inputs required for vortex-induced vibration analysis.

Attributes:
  • fluid_density (float) –

    Air density [kg/m³]

  • fluid_dynamicviscosity (float) –

    Dynamic viscosity of air [Pa·s]

  • rotation_axis (ndarray) –

    Axis of rotation as a 3-element vector

  • rotation_axis_offset (ndarray) –

    Origin of the rotation axis (used in torque calculations and visualization)

  • inflow_vec (ndarray) –

    Direction of inflow velocity (typically [1, 0, 0] for +X)

  • plot_cycle (List[str]) –

    List of hex colors used to differentiate components in visualization

  • azimuths (ndarray) –

    Azimuthal angles [deg] swept by the rotor or structure

  • inflow_speeds (ndarray) –

    Freestream inflow speeds [m/s]

  • output_time (ndarray) –

    Output time points [s]

  • freq_min (float) –

    Minimum frequency [Hz] to consider in overlap comparison

  • freq_max (float) –

    Maximum frequency [Hz] to consider in overlap comparison

  • airfoil_folder (str) –

    Path to the airfoil folder

  • n_harmonic (int) –

    Number of harmonics to check against

  • amplitude_coeff_cutoff (float) –

    Lower threshold on what amplitudes are of interest

  • n_freq_depth (int) –

    How deep to go in the Strouhaul number spectrum

  • output_azimuth_vinf (Tuple[float, float]) –

    Used to limit the case where the relatively expensive output signal reconstruction is done

__init__(fluid_density: float = 1.225, fluid_dynamicviscosity: float = 1.81e-05, rotation_axis: np.ndarray = np.array([0.0, 0.0, 1.0]), rotation_axis_offset: np.ndarray = np.array([0.0, 0.0, 0.0]), inflow_vec: np.ndarray = np.array([1.0, 0.0, 0.0]), plot_cycle: Optional[List[str]] = None, azimuths: Optional[np.ndarray] = None, inflow_speeds: Optional[np.ndarray] = None, output_time: Optional[np.ndarray] = None, freq_min: float = 0.0, freq_max: float = float('inf'), airfoil_folder: Optional[str] = None, n_harmonic: int = 5, amplitude_coeff_cutoff: float = 0.01, n_freq_depth: int = 3, output_azimuth_vinf: Tuple[float, float] = (5.0, 2.0))

Initialize VIV_Params with the provided data.

vorlap.graphics

calc_structure_vectors_andplot(components: List[Component], viv_params: VIV_Params, show_plot: bool = True, return_fig: bool = False, components_black: bool = False, save_path: Optional[str] = None) -> Optional[go.Figure]

Calculates structure vectors and creates a plot.

Parameters:
  • components (List[Component]) –

    List of structural components.

  • viv_params (VIV_Params) –

    Configuration parameters.

  • show_plot (bool, default: True ) –

    Whether to display the plot (default: True).

  • return_fig (bool, default: False ) –

    Whether to return the figure object (default: False).

  • components_black (bool, default: False ) –

    When True, draw component geometry in black instead of the default blue (default: False).

  • save_path (Optional[str], default: None ) –

    Optional file path for static image export via Kaleido. If None, no static image is written.

Returns:
  • Optional[Figure]

    Optional[go.Figure]: Plotly figure object if return_fig=True, otherwise None.