Release notes

Contents

Release notes#

Version 2.3.0#

The following enhancements and bug fixes were implemented for this release:

Enhancements#

Fully Coupled Oil Film–Pad Thermal Model for Tilting-Pad Bearings#

Implemented a fully coupled thermal model for the TiltingPad class, introducing pad conduction solvers and film-pad coupling iteration. The previous model treated the pad as adiabatic — no heat was exchanged between the oil film and the pad body. The new formulation resolves the temperature field across the pad cross-section and iteratively couples it with the Reynolds and energy equations (#1278).

BearingResults Pattern for Bearing Post-Processing#

Introduced a standardized post-processing layer for TiltingPad, ThrustPad, PlainJournal, and SqueezeFilmDamper in ross/bearings/. The new abstract base class BearingResults centralizes the result visualization and console output interface (show_results(), show_coefficients_comparison(), show_execution_time(), plot_*()), eliminating method duplication across bearing types (#1303).

Clearance Analysis#

Added run_clearance_analysis() to the Rotor class. Users can now sweep bearing clearances, inspect bearing vibration magnitudes, and visualize the relationship between response amplitudes and clearance limits in a bar chart. The result object behaves both as a mapping-like interface and as a plot-ready result container (#1285).

Rotor ID Summary#

Added a rotor identification summary method that surfaces key rotor descriptors for reporting and traceability (#1280).

Architecture Overview Documentation#

Added an Architecture Overview page (docs/getting_started/architecture.md) with interactive d2-generated SVG diagrams covering the full ROSS workflow: element definition, rotor assembly, run_*() analyses, and results visualization. All 13 diagrams are interlinked, allowing navigation from the overview down to detailed element and analysis views (#1275).

Line Shape Option for Magnitude Plots#

Exposed Plotly’s line_shape interpolation option on FrequencyResponseResults.plot_magnitude, ForcedResponseResults.plot_magnitude, and their stochastic counterparts, allowing users to smooth magnitude plots on demand. Default behavior (linear) is unchanged (#1271).

Use BearingElement for Dummy Bearings in run_static()#

run_static() previously instantiated dummy bearings using the original bearing’s class, which failed for subclasses (such as rossxl.MaxBrg) whose constructors require extra parameters. The dummy bearings now use BearingElement directly, since they only need to provide linear spring supports (#1273).

ruff format --check in CI#

Extended the CI workflow to run ruff format --check alongside ruff check, ensuring that all code merged into the repository is both lint-compliant and formatted consistently (#1277).

New Tutorials#

Added several tutorials to make ROSS easier to learn:

  • Bearing classes tutorial — covers the use of all available bearing classes and their result visualization methods, highlighting similarities and differences across types (#1286).

  • Seal models tutorial — examples for LabyrinthSeal, HolePatternSeal, and HybridSeal, replacing the previous Hybrid Seal Analysis tutorial (#1284).

  • Faults tutorial — practical examples of misalignment, rubbing, crack, and related fault analyses (#1288).

  • Tutorials on ReadTheDocs — added tutorial_bearings_part_13 and reorganized the tutorial ordering on ReadTheDocs (#1299).

  • General documentation updates (#1269).

Bug Fixes#

Fix run_level1() Cross-Coupling Element Instantiation#

run_level1() previously created the cross-coupling element via bearings[0].__class__(...), which assumed all bearing subclasses shared the BearingElement constructor signature. The cross-coupling element is now instantiated as a BearingElement directly, consistent with the fix applied to run_static() (#1302).

Fix Sporadic NaN in _init_orbit#

test_kappa_rotor3 was failing intermittently because la.eigvals could return slightly negative values for a symmetric positive semi-definite matrix due to floating-point rounding, producing NaN after sqrt. Eigenvalues are now clipped to zero before the square root (#1295).

Fix Mode Shape Discontinuity in Plots#

Addressed discontinuities in the Shape and Orbit classes that produced incorrect plot_2d() visualizations. Updated the _calculate() method in Shape, corrected plot_2d() for the x, y, and major orientations, and updated the Rotor._index() sort so that only w_d > 0 modes are at the top of the index (#1289).

Fix Dynamic Coefficient Method for Plain Journal Bearings#

Corrected the perturbation method used to compute the dynamic coefficients of plain journal bearings in the PlainJournal class (#1287).

Fix GearElementTVMS Initialization from Geometry#

Fixed GearElementTVMS.from_geometry so that all geometric parameters are correctly propagated, resolving inconsistencies in gear element representation and downstream calculations (#1274, #1274).

Contributors#

This release includes contributions from: @gsabinoo, @ViniciusTxc3, @jguarato, @fernandarossi, @mariac-souza, @kiracofe8, @raphaeltimbo

Version 2.2.0#

The following enhancements and bug fixes were implemented for this release:

Enhancements#

LLM/Agent-Oriented Documentation#

Added comprehensive documentation and cookbook recipes for LLM and AI agent integration:

  • Restructured CLAUDE.md with a quick-reference table for all run_* methods, units conventions, example rotors, and cookbook pointers

  • Added 12 focused cookbook recipe files in docs/cookbook/ covering modal analysis, Campbell diagram, critical speed, static analysis, unbalance response, frequency response, time response, UCS & Level 1, faults, bearings advanced, building rotors, and gotchas

  • Added docs/cookbook/README.md as an index for all recipes

  • Expanded AGENTS.md with a quick-start card for agent onboarding

Bug Fixes#

Fix seal_leakage for list/array inputs#

Fixed seal_leakage handling in bearing seal elements to correctly detect whether the value is a collection (list or NumPy array) or a single scalar (float/int). Previously, passing a list of leakage values would cause incorrect behavior (#1270).

Removals#

Remove MCP Server Package#

Removed the ross/mcp/ package, including the MCP server, __main__ module, and __init__. Also removed the mcp optional dependency, the ross-mcp entry point from pyproject.toml, and all MCP-related references from documentation and tutorials.

Contributors#

This release includes contributions from: @raphaeltimbo, @ViniciusTxc3

Version 2.1.0#

The following enhancements and bug fixes were implemented for this release:

Enhancements#

Harmonic Balance Method#

Added run_harmonic_balance() method to the Rotor class for computing steady-state periodic responses under harmonic excitation using the Harmonic Balance Method (HBM). Features include:

  • Multi-harmonic expansion for nonlinear and parametric excitation

  • Support for crack-induced stiffness variation

  • HarmonicBalanceResults class with plot_dfft(), plot_deflected_shape(), and probe response methods

  • Tutorial with worked examples

import ross as rs
import numpy as np

rotor = rs.rotor_example()
speed = 300
dt = 1e-4
t = np.arange(0, 5, dt)

node = [3]
unb_mag = [0.001]
unb_phase = [0]

F = rotor.unbalance_force_over_time(
    node=node, magnitude=unb_mag, phase=unb_phase, omega=speed, t=t
)

hb_results = rotor.run_harmonic_balance(
    speed=speed,
    F=F.T,
    dt=dt,
    num_harmonics=5,
)

Squeeze Film Damper#

Added SqueezeFilmDamper class as a subclass of BearingElement for modeling squeeze film dampers (SFDs). Supports:

  • Short and long bearing approximations

  • End seal and groove configurations

  • Frequency-dependent stiffness and damping coefficients

  • Integration with existing rotor assembly workflow

Hybrid Seal#

Added HybridSeal class for modeling hybrid seals that combine labyrinth and hole-pattern seal stages in series configuration. Features:

  • Coupled solution of labyrinth and hole-pattern stages

  • Convergence criterion based on seal leakage matching

  • Pressure distribution plotting across both stages

  • Dynamic coefficients (mass, stiffness, damping) for the combined seal

Enhanced Magnetic Bearing with General Controllers#

Upgraded MagneticBearingElement from a fixed PID controller to a generalized control system approach using the control library. Enhancements include:

  • Support for arbitrary transfer function controllers (not limited to PID)

  • Coordinate transformations with bearing sensor rotation

  • Scaled AMB equivalent gains with k_amp and k_sense

  • Updated AMB sensitivity analysis (run_amb_sensitivity) with corrected sensor rotation handling

  • New tutorial (tutorial_part_5) with auxiliary methods for defining and evaluating transfer functions

GearElement with Time-Varying Mesh Stiffness (TVMS)#

Extended gear modeling with time-varying mesh stiffness capabilities:

  • GearElementTVMS and Mesh classes for computing stiffness as a function of angular position

  • Spur gear geometry computation (involute curves, transition curves, contact ratio)

  • Square profile approximation for variable stiffness

  • Support for user-defined constant stiffness or geometry-based TVMS

  • Integration with run_time_response() for variable stiffness simulations

Post-Processing Methods for THD Bearings#

Added comprehensive post-processing and visualization methods across THD bearing classes (TiltingPad, ThrustPad, PlainJournal):

  • show_results() — formatted display of field quantities at all speeds

  • show_coefficients_comparison() — tabular comparison of dynamic coefficients

  • plot_results() — field visualization (pressure, temperature, film thickness)

  • Optimization convergence tracking with residual history plots

  • Per-pad convergence visualization for tilting pad bearings

  • Viridis colorscale standardization across all THD visualizations

TiltingPad Performance Optimization#

Significant performance improvements to the TiltingPad class:

  • Numba JIT compilation for performance-critical numerical routines

  • Sparse matrix solvers for Reynolds equation

  • Vectorized operations replacing explicit loops

  • Fixed determine_eccentricity to require load inputs and clarified docstring

JSON Save/Load Support#

Added JSON as an alternative serialization format alongside TOML:

  • Rotor.save() and Rotor.load() now support both .toml and .json file extensions

  • Format-aware I/O helpers (load_data, dump_data) detect format from the file extension

  • JSON format enables easier integration with web applications and AI tools

Rotor File Version Traceability#

Added version tracking to saved rotor files:

  • Rotor.save() now includes ross_version as a top-level key

  • Rotor.load() compares saved version against current version and emits a warning if they differ

  • Helps diagnose compatibility issues when loading files saved with different ROSS versions

Bearing/Seal Skip-Computation on Load#

Improved loading of rotors with complex bearing and seal elements:

  • Override read_toml_data in BearingElement so saved coefficients are passed through to __init__

  • Subclass constructors (THD bearings, seals) skip expensive recomputation when pre-computed coefficients are available

  • Significantly faster Rotor.load() for models with THD bearings or seals

Hover Information for Bearings and Seals#

Added interactive hover information to bearing and seal elements in rotor plots, showing element details on mouse hover — matching the existing shaft element hover functionality.

Bug Fixes#

Fix add_nodes for conical shaft elements#

Fixed incorrect behavior in Rotor.add_nodes when applied to conical (tapered) shaft elements. The method now correctly interpolates diameters and lengths when splitting tapered elements.

Fix transfer matrix for zero-speed FRF#

Corrected the transfer matrix formulation used in frequency response function (FRF) calculations at zero rotation speed, resolving significant discrepancies between numerical and experimental results.

Fix plot_rotor for coupling element#

Fixed an issue that occurred during rotor plotting when a coupling element was combined with bearings.

Fix units in format_table of bearings#

Corrected coefficient units displayed in the .format_table() method of BearingElement subclasses.

Fix TiltingPad class example#

Corrected the example in the TiltingPad class for using the determine_eccentricity equilibrium type, which now requires explicit load inputs.

Fix warning message formatting in TiltingPad#

Fixed formatting of warning messages during TiltingPad initialization.

Fix typos and documentation clarity#

Fixed numerous typos and improved clarity across documentation files, Jupyter notebooks, and Python docstrings.

Documentation and Tutorials#

  • Added hybrid seal tutorial

  • Updated AMB sensitivity analysis tutorial (tutorial_part_5) with transfer function methods

  • Added harmonic balance tutorial with worked examples

  • Updated multi-rotor and gear element tutorials

  • Fixed tutorial print output for ShaftElement

  • Updated README links

Contributors#

This release includes contributions from: @raphaeltimbo, @jguarato, @gsabinoo, @murilloabs, @luisotaviomc2002, @ArthurIasbeck, @Raimundovpn, @ViniciusTxc3, @tches-co

Version 2.0.0#

The following enhancements and bug fixes were implemented for this release:

Enhancements#

Model Reduction#

Added comprehensive model reduction functionality to reduce the size of rotor models while preserving dynamic behavior. Two methods are available:

  • Guyan reduction: Reduces model to specified degrees of freedom (DOFs)

  • Pseudo-modal reduction: Uses modal transformation with specified number of modes

The ModelReduction class provides methods to reduce matrices and vectors, and revert reduced vectors back to the full model.

import ross as rs

 compressor = rs.compressor_example()

 dt = 1e-4
 t = np.arange(0, 10, dt)
 speed = 600

 node = [29]
 unb_mag = [0.003]
 unb_phase = [0]

 probe_nodes = [30]

 # Unbalance force
 F = compressor.unbalance_force_over_time(
     node=node, magnitude=unb_mag, phase=unb_phase, omega=speed, t=t
 )

 response = compressor.run_time_response(
     speed,
     F.T,
     t,
     method="newmark",
     model_reduction={
         "method": "guyan",
         "include_nodes": probe_nodes, # Make sure to include output nodes
         "dof_mapping": ["x", "y"],
     },
 )

Thermo-Hydro-Dynamic Tilting-Pad Bearings#

Added two new bearing classes with full THD (Thermo-Hydro-Dynamic) analysis:

TiltingPad: Tilting-pad journal bearing with individual pad analysis, pivot mechanics, and thermal effects. Uses Reynolds equation and energy equation with finite difference methods, Lund’s perturbation method for dynamic coefficients.

ThrustPad: Tilting-pad thrust bearing with similar THD capabilities for axial applications.

Both classes support multiple lubricant types, turbulence modeling, and provide accurate dynamic coefficients for stability analysis.

HolePatternSeal (Annular Seals)#

Added HolePatternSeal class for modeling annular seals with holepattern. Uses bulk flow theory with:

  • 1D compressible flow through annular clearance

  • Perturbation analysis for dynamic coefficients

  • Mass, stiffness, and damping matrices

  • Leakage prediction

  • Temperature-dependent viscosity using Sutherland’s law

Previously named “honeycomb seal”, this is a comprehensive implementation for pocket damper seals in turbomachinery.

LabyrinthSeal Enhancements#

Significant improvements to the LabyrinthSeal class:

  • Integration with ccp for gas properties

  • Support for custom gas mixtures via composition dictionary

  • Improved numerical methods for pressure distribution

  • Enhanced velocity field calculations with swirl effects

  • Up to 10x performance improvement through code optimization

MultiRotor Class#

Added MultiRotor class for analyzing systems with multiple interconnected rotors, such as geared systems. Supports:

  • Multiple rotors connected via coupling or gear elements

  • Coordinated modal analysis across all rotors

  • Campbell diagram for multi-rotor systems

  • Frequency response analysis

  • Proper handling of coupled dynamics

GearElement and Mesh Stiffness#

New methodology for gear mesh coupling:

  • GearElement class for connecting rotors via gear mesh

  • Mesh stiffness calculation based on gear geometry

  • Contact ratio computation

  • Support for multi-rotor analysis with gears

Flexible Crack Models#

Added flexible crack model implementation (breathing and open crack models) for shaft crack analysis. Enables:

  • Time-varying stiffness due to crack opening/closing

  • Breathing crack behavior

  • Open crack model for continuous stiffness reduction

Gravitational Force#

Added gravitational_force() method to apply gravitational loads on the rotor system, useful for static deflection analysis and considering gravity in dynamic simulations.

Free-Free Analysis#

Added free-free boundary condition option in run_freq_response() for analyzing rotors without supports, useful for:

  • Component mode synthesis

  • Free-free modal analysis

  • Validation against experimental modal testing

Torsional Model Conversion#

Added convert_6dof_to_torsional() function to convert a 6-DoF rotor model to a torsional-only model, enabling:

  • Simplified torsional analysis

  • Faster computation for torsional-dominated problems

  • Separate lateral and torsional analysis

Orbit Animation#

Added animation capability to orbit plots with animation=True parameter. Visualizes:

  • Dynamic motion of the rotor orbit

  • Time-evolution of displacements

  • Easier identification of motion patterns

AMB Sensitivity Analysis#

Added run_amb_sensitivity() method for computing Active Magnetic Bearing (AMB) sensitivities according to ISO 14839-3 standard. This enables:

  • Open-loop, closed-loop, and sensitivity transfer functions calculation

  • Compliance with API STANDARD 617 stability assessment requirements

  • Chirp disturbance signal injection for frequency response analysis

  • Multiple AMB analysis with configurable sensor positions

  • Time-domain and frequency-domain visualization

The method returns a SensitivityResults object with attributes for magnitude, phase, and maximum sensitivities, plus plotting methods for both frequency-domain (plot()) and time-domain (plot_run_time_results()) visualization.

rotor_amb = rs.rotor_amb_example()

sensitivity_results = rotor_amb.run_amb_sensitivity(
    speed=0,
    t_max=5,
    dt=1e-4,
    disturbance_amplitude=10e-6,
    disturbance_min_frequency=0.01,
    disturbance_max_frequency=150,
    amb_tags=["Magnetic Bearing 0", "Magnetic Bearing 1"],
)

# Access maximum sensitivity for a specific bearing
max_sens = sensitivity_results.max_abs_sensitivities["Magnetic Bearing 0"]["x"]

# Plot frequency response
fig = sensitivity_results.plot()

ROSS GPT Integration#

Integrated ROSS GPT assistant into documentation for interactive help and guidance on using the library.

Performance Improvements#

Significant performance optimizations across multiple modules:

HolePatternSeal Optimization#

Optimized HolePatternSeal for 1.6x faster computation through:

  • Caching of repeated calculations

  • Vectorized operations

  • Reduced function call overhead

LabyrinthSeal Optimization#

Optimized LabyrinthSeal for up to 10x faster performance:

  • Smart multiprocessing thresholds

  • Matrix creation optimization

  • Reduced memory allocations

  • Efficient array operations

THD Bearing Optimization#

Optimized PlainJournal (THD Cylindrical) bearing calculations using:

  • Numba JIT compilation for performance-critical sections

  • Reduced redundant computations

  • Improved numerical integration

General Optimizations#

  • Applied lru_cache to frequently-called methods across rotor assembly

  • Optimized matrix building operations

  • Reduced computation time in modal and response analyses

  • Pre-computed base matrices in Rotor.__init__ for faster repeated calculations

API Changes#

Remove 4-DoF Model (Breaking Change)#

Removed support for the 4-DoF model. All analyses now use the 6-DoF model only (lateral, axial, and torsional). This change:

  • Simplifies the codebase

  • Ensures consistent behavior across all elements

  • Improves maintainability

  • Affects: ShaftElement, DiskElement, BearingElement, PointMass

Migration: Update any code that explicitly used n_dof=4 to work with the 6-DoF model.

Folder Restructuring#

Renamed the fluid_flow folder to bearing for better organization and clarity. All bearing-related classes are now in the ross.bearing module.

Migration: Update imports from ross.fluid_flow to ross.bearing.

Build System Update#

Migrated from setup.py to pyproject.toml for modern Python packaging standards. This improves:

  • Dependency management

  • Build reproducibility

  • PEP 517 compliance

CylindricalBearing Updates#

Enhanced CylindricalBearing class with:

  • Improved parameter handling

  • Better documentation with “when to use” guidance

  • Support for frequency-dependent coefficients

  • Oil flow properties calculation

Format Table Methods#

Added format_table() methods to results classes for displaying:

  • Modal analysis results in formatted tables

  • Bearing coefficients comparison

  • Critical speeds with detailed information

Check Units Decorator#

Added @check_units decorator to run_* methods for automatic unit validation and conversion, improving:

  • Type safety with pint quantities

  • Clear error messages for unit mismatches

  • Consistent unit handling across methods

Pressure Distribution Plot#

Added pressure distribution plotting capability for THD bearings to visualize:

  • 2D pressure field across bearing surface

  • Pressure contours

  • Location of maximum pressure

Documentation and Tutorials#

Documentation Build Updates#

Updated documentation dependencies to latest versions:

  • Sphinx 7.2.6 → 8.2.3

  • myst-nb 1.1.0 → 1.3.0

  • Updated ReadTheDocs Python version to 3.13

Enhanced API documentation with comprehensive theoretical foundations for bearing and seal classes, explaining the numerical methods used.

Tutorial Enhancements#

Expanded tutorials with new examples:

  • Friswell book examples added to tutorial

  • MultiRotor usage examples

  • CouplingElement demonstration

  • Torsional analysis guide

  • GearElement examples

  • New user guide examples (User Guide 30)

Bug Fixes#

Fix integrate_system for Variable Speed#

Fixed NameError in integrate_system() when using variable speed with frequency-dependent bearing coefficients. The bug caused failures in time response analysis with bearings that have speed-dependent properties.

Fix Lund Perturbation Method#

Corrected formulation in Lund’s perturbation method for calculating dynamic coefficients in cylindrical bearings, ensuring accurate cross-coupled stiffness and damping terms.

Fix UCS with Rotor Supports#

Fixed bugs in run_ucs() (Unbalance Constant Speed) analysis when rotor has support elements, including:

  • Correct equivalent stiffness calculation

  • Proper DOF handling with supports

  • Pseudo-modal reduction compatibility

Fix Modal Loading#

Fixed error when loading ModalResults from saved files with NumPy version >= 2.0, ensuring backward compatibility.

Fix MultiRotor Plots#

Fixed plotting issues for MultiRotor systems, including:

  • Bearing element visualization

  • Proper scaling and positioning

  • Shape updates and reordering

Fix Campbell for Torsional Modes#

Corrected Campbell diagram to properly classify and display torsional modes, preventing misidentification of mode types.

Fix Critical Speed Tracking#

Improved critical speed identification in Campbell diagrams using MAC (Modal Assurance Criterion) to properly track modes across speed range.

Fix Coupling Element Save/Load#

Fixed save() and load() methods for CouplingElement to correctly persist and restore coupling properties.

Fix Misalignment Parameter#

Corrected the sign of the fib variable relationship in flexible coupling misalignment calculations.

Fix Crack Test Precision#

Fixed numerical precision issues in crack test assertions to handle floating-point comparison properly.

Fix plot_deflected_shape Units#

Fixed unit handling in plot_deflected_shape() to properly accept speed as pint Quantity.

Fix Plotly Rendering#

Fixed plotly rendering issues and dropped deprecated heatmapgl traces for compatibility with plotly v6.0.0.

Fix Mode Shape Updates#

Fixed update_mode_3d issue and adapted mode shape plotting methods to work correctly with MultiRotor systems.

Testing and Compatibility#

Python 3.12 and 3.13 Support#

Updated test suite and codebase for compatibility with Python 3.12 and 3.13:

  • Removed Python 3.9 testing (minimum version now 3.10)

  • Added Python 3.12 to CI pipeline

  • Fixed deprecation warnings

  • Updated dependencies for new Python versions

Contributors#

This release includes contributions from: @raphaeltimbo, @jguarato, @gsabinoo, @ViniciusTxc3, @murilloabs, @Raimundovpn, @gNicchetti, @Emanuela-Carneiro, @vitorp0604, @stanley-washington, @CisneirosRaphael

Version 1.6.0#

The following enhancements and bug fixes were implemented for this release:

Enhancements#

Fix plot torsional and axial modes#

Corrections related to the plotting of mode shapes and includes new methods to handle the plotting of torsional and axial modes in the 6-DoF model.

The plot_with_mode_shape method was not functioning due to changes in the frequency_units parameter in the ModalResults class from previous PRs. To resolve this, corrections were made to manage speed_units separately from frequency_units.

Additionally, new methods were added to the Shape class, including _plot_torsional and _plot_axial, which are now integrated into the plot_mode_2d and plot_mode_3d methods of ModalResults. For 3D plots, an optional animation feature was added, which can be activated by passing animation=True as an argument.

Added CouplingElement#

Added a CouplingElement class that creates a coupling element from input data of inertia and mass from the left station and right station, and also translational and rotational stiffness and damping values. The matrices will be defined considering the same local coordinate vector of the ShaftElement.

API changes#

Change the X Axis (Rotor Speed) in Campbell Diagram#

Now, it’s possible change the x axis (rotor speed) with variable speed_units in plot().

import ross as rs
import numpy as np

Q_ = rs.Q_
rotor = rs.rotor_example()
speed = np.linspace(0, 400, 101)
camp = rotor.run_campbell(speed)
fig = camp.plot(
        harmonics=[1, 2],
        damping_parameter="damping_ratio",
        frequency_range=Q_((2000, 10000), "RPM"),
        damping_range=(-0.1, 100),
        frequency_units="Hz",
        speed_units="RPM",
        )

This PR resolves issue #1087.

Bug fixes#

Version 1.5.0#

The following enhancements and bug fixes were implemented for this release:

Enhancements#

Dev sync ucs map#

For the UCS, the eigenvalues for the synchronous case are now computed directly, eliminating the need to iterate the rotor speed.

Improve numerical integrator#

Newmark method has been added as an option for the numerical integrator used in the .run_time_response() method. Also, the following modifications have been made:

  • Moved the integrate_system() function from utils.py to be a method of the rotor in rotor_assembly.py.

  • Added a new ignore argument for constructing the rotor’s $C$ and $K$ matrices. This argument is a list of elements to be disregarded when constructing these matrices.

  • Provided additional information to the add_to_RHS() function. It is now possible to access, at each time step, the step (required), and optionally, time_step, disp_resp, velc_resp, and accl_resp. For example:

# If you only need to access the step number:
def other_forces(step, **current_state):
    ...

# If you need to access the time step value:
def other_forces(step, time_step=None, **curr_state):
    ...

# If you need to access some response at the current step:
def other_forces(step, velc_resp=None, disp_resp=None, **extra_info):
    ...

# Run time integration:
response = rotor.run_time_response(speed, F, t, method="newmark", add_to_RHS=other_forces)
  • Enabled the possibility to pass any matrices ($M, C, K, G, K_{sdt}$) as arguments to the function, allowing them to replace the rotor matrices constructed in the code. For example:

# Create new matrices (be careful with the size of the arrays):
M = np.array([...])
C = np.array([...])
K = np.array([...])
G = np.array([...])
Ksdt = np.array([...])

# Run time integration:
response = rotor.run_time_response(speed, F, t, method="newmark", M=M, C=C, K=K, G=G, Ksdt=Ksdt)
  • Created unit tests (_test_transientnewmark.py) to cover the run_time_response(method="newmark").

Improve Campbell diagram for 6 dof model#

Improved Shape class by adding a new function to classify mode shapes into “Lateral,” “Axial,” or “Torsional.” With the new attribute mode_type, it is now possible to identify the mode shape in the Campbell diagram for the 6 dof model, leading to the creation of two new labels: “Axial” and “Torsional.”

Additionally, an issue was observed in the eigen solver results for certain 6 dof model cases. The sigma argument in las.eigs() function was previously set to 0, which resulted in poor accuracy. By adjusting sigma to a value slightly greater than 0, the accuracy of the results has improved. However, it is not yet clear whether the value now assumed for sigma presents good results for other cases. For more details about this parameter, refer to the solver documentation here.

The values in the hover info of critical speeds were fixed, and I suggested changing the x-axis of the Campbell diagram to “Rotor Speed”.

Some comparison of results are shown below:

Rotor model from tutorial#

6_dof_without tutorial_3_zoom

LMEst 2 disk rotor#

4_dof 6_dof_with 6_dof_without

Gp68#

4_dof 6_dof_with 6_dof_without

API changes#

Change defects to faults#

We have renamed the ‘defects’ module to ‘faults’.

Bug fixes#

Fix copying a bearing and setting node#

Fixed a bug when the user tried to copy a bearing and then set it to a different node.

A common requirement is to run an expensive bearing calculation and then copy this bearing and just set a different node where it will be located in the rotor:

import ross as rs
from copy import copy

bearing_de = rs.SpecialBearing(n=0, ...)
bearing_nde = copy(bearing_de)
bearing_nde.n = 20

The above code would give an error, since in the rotor assembly we have code which relies on bearings having n_l and n_d attributes (although this only makes sense for shaft elements).

This code removes the attribute from bearing initialization and sets it at rotor initialization. This way it is possible to modify the attribute before creating the rotor.

Fix y label for frequency response plots#

Fixed the y label for the frequency response plots, showing ‘magnitude’ instead of displacement, velocity or acceleration.

Fix use of Kst matrix#

Corrected the stiffness matrix Kst resulting from the transient motion. This matrix should be multiplied by the acceleration, rather than the rotor speed as was previously done.

Fix disk K matrix#

The K matrix for the disk elements should be zero. In the 6 dof model, there was confusion between the K matrix and the Kdt matrix of disk elements. This PR resolves this misunderstanding. Additionally, it proposes the incorporation of the Kdt matrix into the rotor Ksdt matrix, which represents the stiffness matrix related to transient motion of the shaft and discs (formerly Kst).

Fix 6 dof matrices#

  • the signs of K and M matrices of the shaft elements;

  • the consideration of shear effect on M matrix of the shaft elements;

Fix run_ucs for 6 dof model#

Closes issues #1034 and #772

Fixed the run_ucs() method to not show the axial and torsional modes in the 6 dof model results. A new function has been added to utils.py to convert a 6 dof rotor model to a 4 dof model to support this update.

Comparisons of old UCS maps are presented below with those obtained after modification:

rotor.run_ucs(stiffness_range=(6, 11), num=20, num_modes=16)
ucs2_4dof ucs2_6dof ucs2_6dof_mod
rotor.run_ucs(stiffness_range=(6, 11), num=20, num_modes=24)
ucs_4dof ucs_6dof ucs_6dof_mod

Version 1.4.0#

The following enhancements and bug fixes were implemented for this release:

Fix the y label for the frequency response plots, showing ‘magnitude’ instead of displacement, velocity or acceleration.

Documentation improvements in the tutorials and class/functions missing from the API reference.

Version 1.3.0#

The following enhancements and bug fixes were implemented for this release:

Enhancements#

Python 3.10 support#

This release adds Python 3.10 support.

Version 1.2.0#

The following enhancements and bug fixes were implemented for this release:

Enhancements#

Added Shape and Orbit classes#

We have added a Shape and an Orbit class to the results module. These classes are now responsible for calculating the mode shapes in the ModalResults class and also the deflected shapes in the ForcedResponseResults class. This simplifies the code since it avoids the repetition of code between these two classes. It also selects a single method for calculation of the major/minor axes and precession (forward or backward). Before, in the ModalResults, we were doing this using the method described by Friswell with the eigenvalues of the H matrix, and in the ForcedResponseResults we were using a calculation based on forward and backward vectors. The current code in the Orbit uses the method described by Friswell.

Bug fixes#

Fix ucs map#

Fix calculation of bearing stiffness for plotting

Since we have removed the Coefficient class we no longer calculate the bearing coefficient with bearing.kxx.interpolated. Now we use bearing.kxx_interpolated.

Fix number of modes

It was only possible to plot 4 modes. Now we can change the num_modes which is the number of calculated modes, and we will have that value divided by 4 being plotted. Value is divided by 4 because for each pair of eigenvalues calculated we have one wn, and we show only the forward mode in the plots, therefore we have num_modes / 2 / 2.

Fix stiffness expression for tapered element#

In the stiffness expression described on appendix A of the Genta and Gugliotta paper, when substituting chi = 12EI/(phiGA*L**2) in the constant that multiplies the second matrix, we had canceled the A here with the Aj from the equation, but they are actually not the same area. The area Aj in the equation refers to the area in the element’s left side, while the area in the chi calculation refers to the area in the middle of the element. Therefore, we were having an error in this formula by a factor of Aj / A.

Version 1.1.0#

The following enhancements and bug fixes were implemented for this release:

Enhancements#

Removed python 3.6 support#

Since we are now using pint 0.18 which requires python 3.7+, we can no longer support python 3.6.

Add damping parameter and filtering to campbell#

Three additional arguments have been added to the Campbell plot:

  • damping_parameter: choose between log_dec or damping_ratio;

  • frequency_range: filter out modes that are out of this frequency range;

  • damping_range: filter out modes that are out of this damping range;

Improve bearing save method#

Save and load methods for bearings have been modified in order to have additional info in the save file, such as attributes used in bearing initialization.

API changes#

Change pkpk parameter used in plot#

The peak to peak parameter (pkpk) has been changed from prefix to constant, which simplifies it use. To use peak to peak use ‘<unit> pkpk’ (e.g. ‘m pkpk’)

Remove coefficient class#

Remove the auxiliary _Coefficient class in favor of a more simple data processing within the BearingElement class. The _Coefficient class was used to process the coefficient data, creating the interpolation functions and also providing plots (e.g. bearing.kxx.plot()). This was making the code more complicated since we basically had to reproduce the methods of an iterable object in this class. The discoverability of the plot function was also improved, since it is more natural for the user to search for a plot function within the bearing element and not as an attribute of each coefficient (bearing.plot('kxx') instead of bearing.kxx.plot() is now used). Another improvement regarding the plot is that the user can now pass multiple coefficients to plot with. Before the user would have to do something like:

fig = bearing.kxx.plot()
fig = bearing.kyy.plot(fig=fig)
fig = bearing.kxy.plot(fig=fig)
fig = bearing.kyx.plot(fig=fig)

Now we can do:

bearing.plot(coefficients=['kxx', 'kyy', 'kxy', 'kyx'])

Bug fixes#

Correct an error in the damping coefficient of the Magnetic Bearings Element#

A small error in the magnetic bearing calculation has been corrected. See #816.

Fix error in static analysis for bearings with high stiffness#

This adds an auxiliary rotor with 0 stiffness in the bearing location to fix calculations, otherwise, a rotor with a bearing with high stiffness would have 0 reaction force at the bearing location.

Fix error in static analysis for bearings and disks added to the same node#

For rotors with a bearing and a disk added to the same node the static analysis would fail. See #845 for more details.

Add check units to run modal#

Run modal was not working with units. Now we can use rotor.run_modal(speed=Q_(1000, “RPM”).

Version 1.0.0#

The following enhancements and bug fixes were implemented for this release:

Enhancements#

Add loop to calculate frequency-dependent coefficients in from_fluid_flow()#

Users will be able to input as many frequency values as needed and from_fluid_flow() will run a loop calculating a set of coefficients for each given frequency. Now, omega argument must be a list of frequencies. It also changes the main function used to calculate the coefficients. calculate_stiffness_and_damping_coefficients() is now used to do it numerically.

Extract fluid flow#

The .from_fluid_flow method has been extracted from the BearingElement to a class called BearingFluidFlow. This is more in line with how we have all the Bearing classes, and makes it easier for the user to find it.

Add minor and major axes to response plots#

We can now select the major and minor axis when plotting responses:

   # plot response for major or minor axis:
   >>> probe_node = 3
   >>> probe_angle = "major"   # for major axis
   >>> # probe_angle = "minor" # for minor axis
   >>> probe_tag = "my_probe"  # optional
   >>> fig = response.plot(probe=[(probe_node, probe_angle, probe_tag)])

Calculate velocity and acceleration responses

The method run_freq_response() now returns, not only the displacement results, but also the velocity and acceleration. The data is then input to FrequencyResponseResults and ForcedResponseResults classes.

The user is able to choose the response by changing the amplitude_units argument.
  • Inputing ‘[length]/[force]’, it displays the displacement;

  • Inputing ‘[speed]/[force]’, it displays the velocity;

  • Inputing ‘[acceleration]/[force]’, it displays the acceleration.

Add units to stochastic ross module#

Units use is now possible in the stochastic module.

Crack, rubbing and misalignment simulation#

It is now possible to run simulations for some defects such as cracks, rubbing and misalignment.

API changes#

Change methods to run_#

The plot_level1 and plot_ucs methods were refactored so that they behave as other run methods. Now we use the run* prefix to call them and they will return Results objects.

ucs = rotor.run_ucs(...)
ucs.plot(...)

Bug fixes#

Fix GlobalIndex with non integer values#

PointMass and BearingElements with n_link argument were getting non integer values. Matrices would not be built, once these values are used as reference to array indexes (which must be integers).

Version 0.4.0#

The following enhancements and bug fixes were implemented for this release:

Enhancements#

Class MagneticBearingElement was created#

This class creates a magnetic bearing element. The element can be created by:

  • defining directly the stifness and damping coefficients with the method **init**;

  • defining the magnetic parameters g0, i0, ag, nw, alpha and the proportional and derivative gains of a PID controller kp_pid, kd_pid with the method param_to_coef.

The reference for the equations is: Book: Magnetic Bearings. Theory, Design, and Application to Rotating Machinery Authors: Gerhard Schweitzer and Eric H. Maslen Page: 84-95 (magnetic parameters) and 354 (PID gains)

Stochastic Ross module#

The files follow the hierarchy of ROSS: different files to build the elements and a main file to build the rotors.

The main difference between these new files and the element files from ROSS is that the stochastic elements files build a list of elements instead of a single one.

The analysis will also follow the ROSS structure, but it’s not added yet.

6dof assembly#

Generalization of the assembly and evaluation codes of ROSS for a generic “N” DoF sized formulation. This is intended to enable the 6 DoF implementation to be executed appropriately, and is made in a generalized fashion by default.

Add scale_factor argument to DiskElement class#

Argument to scale the disk patch. Used to increase (scale_factor > 1.0) or reduce (scale_factor < 1.0) the size of disk patches when plotting the rotor.

Add units to the DiskElement, BearingElement and PointMass classes#

Arguments for these classes can be passed as pint.Quantity now.

Replacing plotting libraries#

We have replaced Matplotlib and Bokeh plotting libraries with Plotly.

Add methods to plot the deflected shape

Move “sparse” argument to run_modal()#

The eigenvalue / eigenvector solver is chosen when running the run_modal() method, and is no longer a parameter from the rotor model

Set default values to log_dec color scale#

The color scale to represent the log_dec values ranges between 0 and 1, independently of the log_dec values calculated. It can be manually modified by insert 2 simple kwargs: coloraxis_cmin and coloraxis_cmax. It will change respectively the minimum and maximum values for the color scale. Also adds exponentformat = “none” to X and Y axis for better visualization of values

Example with default options:

>>> speed_range = np.linspace(0, 3000, 51)
>>> campbell = rotor.run_campbell(speed_range)
>>> campbell.plot(harmonics=[0.5, 1])
image

Example changing the max value for the scale:

>>> speed_range = np.linspace(0, 3000, 51)
>>> campbell = rotor.run_campbell(speed_range)
>>> campbell.plot(harmonics=[0.5, 1], coloraxis_cmax=2.0)
image

Replace interp1d by line_shape from Plotly#

It removes the need of creating sub arrays from interpolation to smooth some results in StaticResults.

Add probe argument to ForcedResponseResults#

Replace dof by probeargument probe is a list of tuples. Each tuple refers to a probe, which must include the node and the orientation.

The orientation units is set by probe_units argument. in plot() method, data.showlegend is turn off to avoid repetitive legend marks on graphs

Change .use_material() to .load_material()#

We have change most methods to use the word ‘save’ and ‘load’ instead of ‘get’, ‘use’ etc.

Move “sparse” argument to run_modal()#

The eigenvalue / eigenvector solver is chosen when running the run_modal() method, and is no longer a parameter from the rotor model

Bug fixes#

Fix issue with check_units#

Related to Issue #511

Add a condition to verify if the argument value is None. It allows the user to pass “None” args without getting an error with the code trying to assign a unit to a None value.

Fix missing parameters in ST_ShaftElement#

  • The parameters axial_force and torque were missing from the ST_ShaftElement.__init__().

Fix missing y_pos and y_pos_sup in df_seals#

Related to Issue #571.

Seals can be displayed in different colors than bearings

image

Fix ValueError when inputting an integer to disk properties#

Related to Issue #593.

Version 0.3.0#

The following enhancements and bug fixes were implemented for this release:

Enhancements#

Remove ShaftElement and replace with the ShaftTaperedElement#

Now we only have one class for the shaft element which is capable of handling cylindrical and tapered elements.

Allow user choose material in “Rotor.from_section()”#

As requested in Issue #401, the user will be able to define a material when using .from_section() classmethod. In addition, more modifications have been done regarding the new ShaftElement API. Now, the user has the option to instantiate tapered sections.

CoAxialRotor class#

A class is now available for modeling coaxial rotors.

Bug fixes#

Fix bearing position bug#

Fix bug mentioned in Issue #276

Sorting the bearing_seal_elements make it to cycle correctly while assuming y_pos values to them.

Version 0.2.0 (beta release)#

The following enhancements and bug fixes were implemented for this release:

Enhancements#

Improvements for plotting results#

This PR make some modifications in results.py

  • Add show(camp) to show campbell bokeh plotting

  • Add command to align ColorBar axis for better appearance

  • Add figure dimensions for campbell bokeh plotting

  • increases the font size of all axis labels

Some bokeh figures have the attribute sizing_mode="stretch_both. This command line is used so that the plotting of the graphics is always the maximum size of the browser. However, this creates a bug in jupyter notebook, and the graphs does not appears. So it should be replaced by width and height command lines

  • adds an interpolation function to highlight to the user the intersection between the critical frequency curves and the speed line

Index method#

Adds .dof_local_index() and .dof_global_index() methods to the elements. These methods will return namedtuples with the index for each coordinate based on the following convention:

image

As an example:

>>> import ross as rs
>>> from ross.materials import steel

>>> le = 0.25
>>> i_d = 0
>>> o_d = 0.05
>>> sh_el = rs.ShaftElement(le, i_d, o_d, steel, n=2)
>>> sh_el.dof_local_coordinates()
LocalIndex(x0=0, y0=1, alpha0=2, beta0=3, x1=4, y1=5, alpha1=6, beta1=7)
>>> sh_el.dof_global_coordinates()
GlobalIndex(x0=8, y0=9, alpha0=10, beta0=11, x1=12, y1=13, alpha1=14, beta1=15)

With this we can change the following code:

for elm in self.shaft_elements:
    n1, n2 = self._dofs(elm)
    M0[n1:n2, n1:n2] += elm.M()
for elm in self.disk_elements:
    n1, n2 = self._dofs(elm)
    M0[n1:n2, n1:n2] += elm.M()

To:

for elm in self.elements:
    dofs = elm.dof_global_index()
    n0 = dofs[0]
    n1 = dofs[-1] + 1  # +1 to include this dof in the slice
    M0[n0:n1, n0:n1] += elm.M()

interactions with rotor plotting#

When plotting a rotor, the user will be able to check some parameters of the elements in the output image itself, just by moving the cursor over the desired element, for example:

By moving the cursor over a shaft element the user will see this:

shaft

And, by moving the cursor over a disk element the user will see this:

disk

I didn’t add the same functionality to bearing elements because the coefficients may vary with rotor speed, and this may cause a misunderstanding to the user.

Move time response plotting to results#

  • Removes the code related to plotting from this file. It was transfered to results.py

  • Replaces the method name from plot_time_response to run_time_response.

  • Fix ForcedResponseResults docstring

Add tapered shaft element#

  • Add new element: tapered shaft element

  • Add class ShaftTaperedElement

  • This class have, basically, the same inputs than “ShaftElement”. The difference relies on entering the diameters of each side of the element (left and right).

  • Patches methods were adapted to draw the conical shape of the element.

The matrices generated for this element follow the reference below.

Genta, G., and Gugliotta, A. (1988). A conical element for finite element rotor dynamics, Journal of Sound and Vibration 120,175-182.

Improving plot rotor#

This PR modifies the plotting size of disks, bearings and seals. The size, previously based on shaft length, is now calculated based on the shaft diameter.

Add Check slenderness ratio method#

Adds a method that will return the colored rotor plot if the condition to the mininum slenderness ratio is not met.

Now using .plot.rotor() won’t display the colored rotor anymore. Instead, the user will call .check_slenderness_ratio() to check this attribute.

Make Free-Body Diagram more readable#

Pull Request to fix Issue #243

  • Slightly increases the size of the figures

  • Arrows have a fixed length now (as shown in this figure below);

  • Arrows now have different colors to distinguish forces (from shaft, disks or bearings/seals);

  • Labels were rotated 90º;

  • Text font size reduced to “9pt”;

  • Y axis is hidden. The force values are only displayed only next to the arrows, without size ratio.

Replace bearing plot style / remove element length dependency from glyphs#

  • Bearing representation changes from a simple square to a spring-damper set.

  • Fix bug glyphs were plotted on the minimum outer diameters of a shaft node.

  • Removes length attribute from patch() and bokeh_patch() of BearingElement and DiskElement classes.

Bokeh plot

bokeh_plot(2)

Matplotlib plot

Figure_1

Add API_report#

Work in Progress

This PR adds some plotting styles following the API reference:

  • Separation Margin

  • Amplification Factor

  • Table of API parameters

It follows the Issue #195

Add new “Tag” attribute to elements#

Disk, bearing and seal elements now get an attribute called “Tag”. This allows the user to name the elements to help refer to the actual equipment (impellers, blades, labyrinth seal…)

If the user do not input a tag, it’s named after:

  • Disk 1, 2, 3…

  • Bearing 1, 2, 3…

  • Seal 1, 2, 3…

As bearings and seals are input in the same list of objects, this situation below may happens:

def rotor_example():
    i_d = 0
    o_d = 0.05
    n = 6
    L = [0.25 for _ in range(n)]

    shaft_elem = [
        ShaftElement(
            l, i_d, o_d, steel, shear_effects=True, rotary_inertia=True, gyroscopic=True
        )
        for l in L
    ]

    disk0 = DiskElement.from_geometry(
        n=1, material=steel, width=0.07, i_d=0.05, o_d=0.28
    )
    disk1 = DiskElement.from_geometry(
        n=3, material=steel, width=0.07, i_d=0.05, o_d=0.28, tag="disk_test"
    )
    disk2 = DiskElement.from_geometry(
        n=5, material=steel, width=0.07, i_d=0.05, o_d=0.28, tag="disk_test2"
    )

    stfx = 1e8
    stfy = 1e8
    bearing0 = BearingElement(0, kxx=stfx, kyy=stfy, cxx=1000, tag="brg")
    bearing1 = BearingElement(6, kxx=stfx, kyy=stfy, cxx=1000)
    seal0 = SealElement(2, kxx=1e2, kyy=1e2, cxx=500, cyy=500, tag="seal")
    seal1 = SealElement(4, kxx=1e2, kyy=1e2, cxx=500, cyy=500)

    return Rotor(shaft_elem, [disk0, disk1, disk2], [bearing0, seal0, seal1, bearing1])

>>> rotor = rotor_example()
>>> rotor.df_bearings["tag"]
0    brg
1    seal
2    Seal 2
3    Bearing 3
Name: tag, dtype: object

The counting for bearings and seals is not independent. I don’t see it as big deal, but I’m open to suggestions.

Add separated DataFrame to seals#

This splits bearings from seals in two different dataframes:

  • df_bearings for bearings

  • df_seals for seals

It aims to better organize the elements and to avoid code interpretation problems such as in static analysis:

This is the free-body diagram of an example while seals and bearings are merged in same dataframe. The code interprets seals like bearings and calculate reaction forces where both seals are placed:

antigo

And now, spliting bearings and seals:

novo

Also, fix a bug when modeling too flexible bearings, displacement were getting larger than acceptable. It uses auxiliary bearings with high stiffness, considering almost zero displacement in bearing nodes.

Split StaticResults plot method#

This commit splits the plot method in four:

  • plot_deformation()

  • plot free_body_diagram()

  • plot_shearing_force()

  • plot_bending_moment() This is related to Issue #303.

Add BallBearing and RollerBearing Element#

This PR adds two new classes:

  • BallBearingElement

  • RollerBearingElement

These classes create a bearing element for ball and roller bearings models. They are instantiated based os some geometric and constructive parameters like: number of rotating elements, size (diameter for ballbearing; length for rollerbearing) of the rotating elements, contact angle, and static loading force.

The direct stiffness coefficients are calculated using these parameters.

I also left an opened option to instantiate the direct damping coefficients. But if it’s set as None, they are calculated based on the stiffness coefficient as the literature suggests. However the cross-coupling coefficients are set to zero, and the coefficients are not dependent on speed.

def __init__(
    self,
    n,
    n_balls,
    d_balls,
    fs,
    alpha,
    cxx=None,
    cyy=None,
    tag=None,
):

    Kb = 13.0e6
    kyy = (
        Kb * n_balls ** (2./3) * d_balls ** (1./3) *
        fs ** (1./3) * (np.cos(alpha)) ** (5./3)
    )

    nb = [8, 12, 16]
    ratio = [0.46, 0.64, 0.73]
    dict_ratio = dict(zip(nb, ratio))

    if n_balls in dict_ratio.keys():
        kxx = dict_ratio[n_balls] * kyy
    else:
        f = interpolate.interp1d(nb, ratio, kind="quadratic")
        kxx = f(n_balls)

    if cxx is None:
        cxx = 1.25e-5 * kxx
    if cyy is None:
        cyy = 1.25e-5 * kyy

    super().__init__(
        n=n,
        w=None,
        kxx=kxx,
        kxy=0.0,
        kyx=0.0,
        kyy=kyy,
        cxx=cxx,
        cxy=0.0,
        cyx=0.0,
        cyy=cyy,
        tag=tag,
    )

Add condition to ShaftTaperedElement instantiation#

  • Add a condition if the user do not attribute any value to inner and outer diameters on the right side, the values are automatically set to be equal the left side.

  • Also, move the “material” input to the first position, so the geometric parameters can be grouped together.

  • Adapt the examples in docstring.

  • Moves the inputs from ShaftTaperedElement to match the new position set.

    class ShaftTaperedElement(Element):
      def __init__(
          self,
          material,
          L,
          i_d_l,
          o_d_l,
          i_d_r=None,
          o_d_r=None,
          n=None,
          axial_force=0,
          torque=0,
          shear_effects=True,
          rotary_inertia=True,
          gyroscopic=True,
          shear_method_calc="cowper",
          tag=None,
      ):
    
          if i_d_r is None:
              i_d_r = i_d_l
          if o_d_r is None:
              o_d_r = o_d_l
    

Patches for PointMass element#

As required by issue #310

Add __repr__, __eq__, and example() to point mass element#

This commit adds the following methods to PointMass class:

  • repr - representative method;

  • eq - comparison method;

  • point_mass_example() - to run some doctests.

Improvements to Static Analysis Documentation#

  • Related to Issue #327

  • Remove force_data dictionary

  • Get the items and transform them in Rotor attributes

    • shaft_weight - Shaft total weight

    • disk_forces - Weight forces of each disk

    • bearing_reaction_forces - The static reaction forces on each bearing

General Modifications in CampbellResults#

This is related to Issues #326 and #328.

  • Introduce a condition to add the hover tool only if an harmonic crosses a critical speed curve.

  • Remove some unused imports.

  • In _plot_bokeh:

    • Change colormap from viridis to Red-Blue

    • Add different colors to harmonics lines

    • Make glyphs on legend with same color

  • In _plot_matplotlib:

    • Add different colors to harmonics lines

  • For both methods: Restructure code to increase efficiency (reduce plotting time): I could the plot time in an half by rearranging some routines.

import ross as rs
rotor = rs.rotor_example()
camp = rotor.run_campbell(np.linspace(0, 1000, 10)).plot([0.25, 0.5, 1, 2])
show(camp)

I’ve measured the time just to run the .plot(). It was taking 2.5s for the rotor_example(). Rearranging the code, it has been reduced to 1.2s for this same example.

Add summary table to plot rotor information#

Related to Issue #327.

It’s a first idea from what the summary will become. The class get the values stored in dataframes and turns them into a bokeh widget in table format.

We still can build other tables to make it more complete and useful to manipulate data.

Improvements to SummaryResults#

Related to Issue #327 Follows the PR #338

  • Add new attribute “tag” to name the rotor;

  • Add CG and Moment of Inertia parameters;

  • Add new attributes to .summary() method;

  • Add a system of Tabs that allows the user to alternate between tables;

  • Tables are separeted in:

    • Rotor summary

    • Shaft summary

    • Disk summary

Add Stability Level 1 analysis#

  • This analysis consider a anticipated cross coupling QA based on conditions at the normal operating point and the cross-coupling required to produce a zero log decrement, Q0.

  • Add attribute “rotor_type”

    • This attribute is necessary to distinguish overhung and between bearings rotors.

    • The unbalance forces and the respective nodes where they are introduced depend on this information.

  • Improve unbalance force method.

    • With this improvement, the unbalance forces are calculated according to the rotor_type and considers the disks and shaft weight (if overhung).

  • Change mode_shape to find nodes according to rotor_type

    • The method .mode_shapes() was capturing the maximum points from the rotor’s mode shapes without checking if it was overhung or between bearings.

    • For rotors where the disk is cantilevered beyond the bearings, unbalance shall be added at the disk. So, the method now checks the rotor_type to define the nodes correctly.

  • Add machine_type and disk_nodes attribute

    • Machine_type will be useful to help the code to distinguish between compressors, turbines, etc. Because each machine type has their own conditions to be calculated.

    • Disk_nodes is useful to collect the disk of interest. if we are working with a overhung rotor, disk_nodes will collect the disk which are overhung only, for example.

This Level 1 analysis does not have the screening criteria yet. The next step is to implement the Level 2 analysis. Once I get to work on it, I’ll add the screening criteria. I still need to organize some ideas for the next step.

Add Bearing Summary Table#

  • add a summary table for bearing elements: for now it displays only where it’s placed and the reaction forces.

  • fix bug: when setting and disk or bearing element in the last node, the code would fail

  • other minor changes

Improvements to api_report.py - Add test_api_report.py#

  • Add Stability level 1 screening criteria;

  • Modifies the code to storage the cross-coupling range for each rotor stage (or impeller). This is useful to distinguish the cross-coupling evaluation for different rotor_types (between bearings, overhung…);

  • Add .summary() method;

  • Add summary for stability level 1

Add stability analysis level 2#

For the level 2 stability analysis additional sources that contribute to the rotor stability shall be considered. These sources shall replace the cross-coupling Qa, calculated in the stability analysis level 1

Visual improvements to graphs#

The labels, ticks and titles font size from bokeh figure were small when putting it presentations. So I’ve increased the font size of all graphs.

  • Add new tab to the .summary() with stability level 2 data;

  • Change stability level 2 labels for better user understanding when using .summary(). The labels include explicitly all the components considered in a certain analysis (Shaft + Bearing + Disk + Seal…);

  • Increases labels, titiles and tick font sizes (results.py and api_report.py);

  • Add mcs speed to evaluate mode shapes (api_report.py);

  • Fix .unbalance_response() plot size to match results.py file;

  • In .stability_level_1() remove condition from returning and add it as attribute;

  • .run_modal().plot_mode() add legend informing the whirl direction.

Add method to plot orbit#

  • Add .run_orbit_response() method to rotor_assembly.py.

    • .run_orbit_response() calculates the orbit for a rotor’s given node, speed and forces.

  • Add class OrbitResponseResults to results.py.

    • Class used to store results and provide plots for orbit response.

Example using this new method:

>>> rotor = rotor_example()
>>> speed = 500.0                                           # pick a rotor speed
>>> size = 10000                                            # time array's size
>>> node = 3                                                # node of interest
>>> t = np.linspace(0, 10, size)                            # create time array
>>> F = np.zeros((size, rotor.ndof))                        # create force vectors
>>> F[:, 4 * node] = 10 * np.cos(2 * t)                     # introduce a periodic force in a single dof
>>> F[:, 4 * node + 1] = 10 * np.sin(2 * t)                 # introduce a periodic force in a single dof
>>> response = rotor.run_orbit_response(speed, F, t, node)  # run orbit response
>>> show(response.plot())                                   # plot orbit response

3D plots for orbit response#

Related to PR #385.

API changes#

Bug fixes#

Fix Campbell’s strange behavior for precession


Fix equality for bearing element#

Fixes the equality for bearing element, allowing the comparison with objects from different types, e.g. bearing == 1 will return False, before an AttributeError was raised since int doesn’t have .dict. This also removes pytest as a dependence for the user.

Add import to Axes3d#

The import has been added to the results module because the mode shape plot needs this to work. Although it looks like the import is not being used (this is highlighted by linters), matplotlib, for some strange reason, actually needs this to use the projection=’3d’. A doctest has been added to the mode shape plot for the tests to fail if this import is removed.

Fix bearing type definition and add new test#

Fix the bearing type definition and also add a new test that checks if a second analytical way to calculate the pressure matrix matches the numerical way. Close #175

Improvements for plotting results#

This PR make some modifications in results.py

  • Add show(camp) to show campbell bokeh plotting

  • Add command to align ColorBar axis for better appearance

  • Add figure dimensions for campbell bokeh plotting

  • increases the font size of all axis labels

Some bokeh figures have the attribute sizing_mode="stretch_both. This command line is used so that the plotting of the graphics is always the maximum size of the browser. However, this creates a bug in jupyter notebook, and the graphs does not appears. So it should be replaced by width and height command lines

  • adds an interpolation function to highlight to the user the intersection between the critical frequency curves and the speed line

Fix bug - plotting unbalance response#

Unbalance response was not plotting when calling it using matplotlib

Make Free-Body Diagram more readable#

Pull Request to fix Issue #243

  • Slightly increases the size of the figures

  • Arrows have a fixed length now (as shown in this figure below);

  • Arrows now have different colors to distinguish forces (from shaft, disks or bearings/seals);

  • Labels were rotated 90º;

  • Text font size reduced to “9pt”;

  • Y axis is hidden. The force values are only displayed only next to the arrows, without size ratio.

Fix inconsistencies in the mass and gyroscopic matrices; New tests for shaft tapered element


I found some problems in shaft tapered element matrices. Fow now I’ve fixed the issues on mass and gyroscopic matrices. Besides this PR modifies the tests for this class, adding tests to compare two cylindrical elements built from ShaftElement and ShaftTaperedElement classes. However, tests for stiffness matrices are skipped.

Fix typo in __repr__#

It follows the Issue #255.

Fix inconsistencies in the stiffness matrix#

  • Fix some typos in geometry coefficients;

  • Fix stiffness matrix formula for shaft tapered elements;

  • Fix docstrings for M(), K(), G() in ShaftTaperedElement;

  • Add better docstrings to ShaftTaperedElement.

Fix tests to match the changes done in shaft_element.py:

  • Fix stiffness matrix test;

  • Fix element attribute tests ;

  • Fix comparation tests.

Fixing doctests#

Well, since I have forgotten to add the .py extention on api_report file, the CI’s were not running the tests on it. And now that I did it, the building is failing due some tests.

This PR tries to fix this problem on api_report.py and in results.py (with new docstrings on ModeShapeResults)

The last PR (#272) was a failure actually.

Adapt convergence analysis to ShaftTaperedElement#

Now the convergence analysis uses the class ShaftTaperedElement to generate shaft elements since it’s more generic. This should solve issue #280.

Add separated DataFrame to seals#

This splits bearings from seals in two different dataframes:

  • df_bearings for bearings

  • df_seals for seals

It aims to better organize the elements and to avoid code interpretation problems such as in static analysis:

This is the free-body diagram of an example while seals and bearings are merged in same dataframe. The code interprets seals like bearings and calculate reaction forces where both seals are placed:

antigo

And now, spliting bearings and seals:

novo

Also, fix a bug when modeling too flexible bearings, displacement were getting larger than acceptable. It uses auxiliary bearings with high stiffness, considering almost zero displacement in bearing nodes.

Fix warning when changing number of nodes to be plotted#

Related to Issue #295

Remove unit conversion factor#

Remove a conversion factor (meters to milimeters) from the plot_deformation() ColumnDataSource. So the x and y axis units get to be the same.

Related to Issue #312

Improvements to Static Analysis Documentation#

  • Related to Issue #327

  • Remove force_data dictionary

  • Get the items and transform them in Rotor attributes

    • shaft_weight - Shaft total weight

    • disk_forces - Weight forces of each disk

    • bearing_reaction_forces - The static reaction forces on each bearing

Fix bearings not connecting to tapered elements#

Related to Issue #332

Fix bug when plotting bearings#

  • Fix bug when plotting bearing elements in a given node with more than 1 shaft element on it. The bearing would not get correct starting point.

  • Fix bug when using scale_factor with point mass. The auxiliar bearing would disattach from the first bearing.

Fix bug in .run_freq_response()#

Fix a bug that happens when calling .run_freq_response() with default arguments, i.e:

>>> rotor = rotor_example()
>>> response = rotor.run_freq_response()
Traceback (most recent call last):

  File "<ipython-input-3-292fe59ccc9e>", line 1, in <module>
    response = rotor.run_freq_response()

AttributeError: 'NoneType' object has no attribute 'imag'

Since running .run_modal() is required to create the attribute evalues, we need to call this function (run_modal()) before creating a default speed_range based on the evalues.

This should fix it.

Version 0.1.0 (alpha release)#

For the alpha release, the main classes have been created and the more important analyses have been implemented.

The following gives a list of enhancements, api changes and bug fixes that were implemented for this release:

Enhancements#

Implementation of the Material class#

A class has been implemented to represent any material that can be used when creating an element for the analysis.

Create ShaftElement, DiskElement and BearingSealElement#

The main classes used to create shaft elements, disk elements and bearings/seals elements have been implemented.

Add rotor assembly and results#

A Rotor class has been implemented to represent the rotor. A rotor object assembles the global matrices and provides methods to run the same analysis on the rotor. Results implemented are modal analysis, Campbell, frequency response and unbalance response.

Add static analysis method#

A method to calculate the static displacement of a rotor due to disks’ weight has been added.

New rotor save format#

A new format for saving rotors was implemented. It is based on the toml format.

Add convergence analysis#

Add convergence analysis as a method to the class Rotor.

Analytical fluid flow, short bearings#

Add analytical fluid flow routines for short bearings.

Add new diagram to static method#

Add a new plot to the static method - shearing force and changes the name of some graphs to make it more readable.

Add methods to allow inputs from a table in bearing element#

Two methods were added to bearing element. The first one allows instantiating a bearing object from a table (excel format). The second one converts from table to dictionary, that can be saved as a toml file.

Interpolation for static analysis and Bending moment diagram#

An interpolation method has been added to give a more smooth curve on plots generated by the static analysis.

Add bokeh plot to ForcedResponse() class#

Implements plotting using bokeh to generate magnitude and phase plot to ForcedResponse class.

Add bokeh plot to “plot_level1” and “plot_ucs”#

Add bokeh plotting as alternative to matplotlib to plot graphs.

Benchmark implementation and some changes in imports#

Add Benchmark folder to ross(__init__) folder. To run the benchmarks you only need to: * run run_benchmarks.py, the outputs will be saved into the version folder of benchmarking, which is placed inside Snakeviz_inputs folder. To visualize the results we recommend you to use snakeviz, you can easily install it with pip. * As an example, to run snakeviz on Convergence benchmarks, you only need to run(within the directory of saved Benchmarks) snakeviz Convergence.prof. Those changes are some import optimization and turning static() method into run_static() method.

Added user guide on how to use ROSS#

A tutorial has been added to the documentation. This is available as a jupyter notebook and is also rendered in the ../tutorials/tutorial_part_1 documentation page.

Jupyter examples#

Implementation of the following examples, taken from Friswell:
  • 5.9.1

  • 5.9.2

  • 5.9.4

  • 5.9.5

  • 5.9.6

  • 5.9.9

  • 5.9.10

Adds a binder badge#

Binder is available to test the library in a cloud virtual environment.

API changes#

Add run_modal method#

The modal analysis changed from .run() to .run_modal().

Change methods’ names#

This is mostly to add run_ to some Rotor methods, like:
  • campbell;

  • forced_response;

  • mode_shape;

  • static

Also, change the value to evaluate the slenderness ratio (SR) to 1.6. Since our convergence analysis have shown good results even for SR < 30, it was decided to change it to 1.6, which is equivalent to a length / diameter ratio of 0.5.

Remove show() from convergence and static#

Removes bokeh show() from the convergence and static analysis. Automatically showing the plots is not expected when running tests or scripts. With this modification, the figure is returned and the user can plot that if wanted. As an example:

static_analysis = rotor.run_static()
show(static_analysis)

Bug fixes#

Added interpolate to rotor_assembly.py#

The function interp1d was used but the interpolate function was not being imported.

Fix eccentricity ratio function#

The eccentricity ratio function was being calculated wrongly, using the sommerfeld number instead of the modified one, as it was supposed to use.

Improving plot_rotor#

There was an error that shaft elements were plotting with 2 times their respective radius. I enlarged the plot window size and distributed the axis size so that the rotor is presented with the correct proportions in relation to its dimensions. Also, adds the slenderness ratio parameter (equation: G * A * L ** 2 / E * I ) to each shaft element. It calculates the ratio using some global distance measures, rather than basing it upon individual element dimensions. The user is returned an warning message if it’s lower than a certain value, which could affect the convergence analysis.