Tutorial - Bearings in ROSS#

This tutorial provides a comprehensive guide to all bearing element classes available in ROSS.

Bearings are passive or active elements that provide stiffness and damping support to a rotating shaft. In a finite-element rotor model, each bearing element connects a rotor node to ground (or to another node) and contributes to the global stiffness and damping matrices through a set of dynamic coefficients.

ROSS organises its bearing classes into three groups:

Group

Classes

Description

General / parametric

BearingElement, BallBearingElement, RollerBearingElement, CylindricalBearing

Coefficients supplied directly or computed from a simple analytical model

Thermo-Hydro-Dynamic (THD)

PlainJournal, TiltingPad, ThrustPad, SqueezeFilmDamper

Coefficients computed from numerical or analytical solution of the Reynolds equation, with optional thermal coupling

Active Magnetic Bearings (AMB)

MagneticBearingElement

Coefficients derived from electromagnetic parameters and a closed-loop PID or custom transfer-function controller

All bearing classes inherit from BearingElement and can be inserted directly into a rs.Rotor assembly.

The tutorial is split into three dedicated notebooks:

Section 1: General Bearing Classes#

The classes in this section receive stiffness and damping coefficients directly as input parameters (or compute them from a few geometric parameters). They are fast, require no iterative solver, and are suitable for preliminary design, and sensitivity studies.

All classes return the standard 8-coefficient set (\(k_{xx}\), \(k_{xy}\), \(k_{yx}\), \(k_{yy}\), \(c_{xx}\), \(c_{xy}\), \(c_{yx}\), \(c_{yy}\)) that is assembled into the global matrices by the Rotor class.

1.1: BearingElement#

The base bearing class. Coefficients can be constant values or speed-dependent arrays; when speed-dependent, ROSS interpolates between the supplied points at the operating speed.

Constant coefficients:

import ross as rs
import numpy as np

stfx = 1e6
stfy = 0.8e6
bearing1 = rs.BearingElement(n=0, kxx=stfx, kyy=stfy, cxx=1e3)
print(bearing1)
print(f"Kxx: {bearing1.kxx}")
BearingElement(n=0, n_link=None,
 kxx=[1000000.0], kxy=[0],
 kyx=[0], kyy=[800000.0],
 kzz=[0], cxx=[1000.0],
 cxy=[0], cyx=[0],
 cyy=[1000.0], czz=[0],
 mxx=[0], mxy=[0],
 myx=[0], myy=[0],
 mzz=[0],
 frequency=None, tag=None)
Kxx: [1000000.0]
/home/gsabino/Documents/dev/rosstest/fernandarossi/venvross/lib/python3.13/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html
  from .autonotebook import tqdm as notebook_tqdm

Speed-dependent coefficients — pass arrays of equal length for the coefficients and the corresponding frequency values:

bearing2 = rs.BearingElement(
    n=0,
    kxx=np.array([0.5e6, 1.0e6, 2.5e6]),
    kyy=np.array([1.5e6, 2.0e6, 3.5e6]),
    cxx=np.array([0.5e3, 1.0e3, 1.5e3]),
    frequency=np.array([0, 1000, 2000]),
)
print(bearing2)
print(f"Kxx: {bearing2.kxx}")
BearingElement(n=0, n_link=None,
 kxx=[ 500000. 1000000. 2500000.], kxy=[0, 0, 0],
 kyx=[0, 0, 0], kyy=[1500000. 2000000. 3500000.],
 kzz=[0, 0, 0], cxx=[ 500. 1000. 1500.],
 cxy=[0, 0, 0], cyx=[0, 0, 0],
 cyy=[ 500. 1000. 1500.], czz=[0, 0, 0],
 mxx=[0, 0, 0], mxy=[0, 0, 0],
 myx=[0, 0, 0], myy=[0, 0, 0],
 mzz=[0, 0, 0],
 frequency=[   0. 1000. 2000.], tag=None)
Kxx: [ 500000. 1000000. 2500000.]

Bearings in series — use n_link to chain two elements (useful to represent a bearing mounted on a flexible support structure):

bearing3 = rs.BearingElement(
    n=0, kxx=1e6, kyy=0.8e6, cxx=1e3, n_link=1, tag="journal_bearing"
)
bearing4 = rs.BearingElement(n=1, kxx=1e7, kyy=1e9, cxx=10, tag="support")
print(bearing3)
print(bearing4)
BearingElement(n=0, n_link=1,
 kxx=[1000000.0], kxy=[0],
 kyx=[0], kyy=[800000.0],
 kzz=[0], cxx=[1000.0],
 cxy=[0], cyx=[0],
 cyy=[1000.0], czz=[0],
 mxx=[0], mxy=[0],
 myx=[0], myy=[0],
 mzz=[0],
 frequency=None, tag='journal_bearing')
BearingElement(n=1, n_link=None,
 kxx=[10000000.0], kxy=[0],
 kyx=[0], kyy=[1000000000.0],
 kzz=[0], cxx=[10],
 cxy=[0], cyx=[0],
 cyy=[10], czz=[0],
 mxx=[0], mxy=[0],
 myx=[0], myy=[0],
 mzz=[0],
 frequency=None, tag='support')

1.2: BallBearingElement#

Computes direct stiffness coefficients from the geometric and loading parameters of a ball bearing, based on the theory from Friswell et al. (2010). Cross-coupling is not modelled. Damping defaults to \(1.25 \times 10^{-5} \cdot k_{xx}\) if not provided.

ballbearing = rs.BallBearingElement(
    n=0,
    n_balls=8,  # Number of balls
    d_balls=0.03,  # Ball diameter [m]
    fs=500.0,  # Static radial load [N]
    alpha=np.pi / 6,  # Contact angle [rad]
    tag="ball_bearing",
)
ballbearing
BallBearingElement(n=0, n_link=None,
 kxx=[np.float64(46416883.847697675)], kxy=[0.0],
 kyx=[0.0], kyy=[np.float64(100906269.23412538)],
 kzz=[0], cxx=[np.float64(580.211048096221)],
 cxy=[0.0], cyx=[0.0],
 cyy=[np.float64(1261.3283654265672)], czz=[0],
 mxx=[0], mxy=[0],
 myx=[0], myy=[0],
 mzz=[0],
 frequency=None, tag='ball_bearing')

1.3: RollerBearingElement#

Same philosophy as BallBearingElement but for cylindrical roller bearings. The stiffness formulation accounts for the line contact between roller and raceway.

rollerbearing = rs.RollerBearingElement(
    n=0,
    n_rollers=8,  # Number of rollers
    l_rollers=0.03,  # Roller length [m]
    fs=500.0,  # Static radial load [N]
    alpha=np.pi / 6,  # Contact angle [rad]
    tag="roller_bearing",
)
rollerbearing
RollerBearingElement(n=0, n_link=None,
 kxx=[np.float64(272821927.4006065)], kxy=[0.0],
 kyx=[0.0], kyy=[np.float64(556779443.6747072)],
 kzz=[0], cxx=[np.float64(3410.2740925075814)],
 cxy=[0.0], cyx=[0.0],
 cyy=[np.float64(6959.74304593384)], czz=[0],
 mxx=[0], mxy=[0],
 myx=[0], myy=[0],
 mzz=[0],
 frequency=None, tag='roller_bearing')

1.4: CylindricalBearing#

A simplified analytical model for plain cylindrical (journal) bearings, based on the short-bearing assumption (L/D ≪ 1) from Friswell et al. (2010). Suitable for quick calculations and preliminary design when computational speed is critical.

When to prefer PlainJournal instead: when thermal effects, multi-pad configurations, turbulence models, or oil starvation conditions are relevant.

from ross import CylindricalBearing
from ross.units import Q_

cylindrical = CylindricalBearing(
    n=0,
    speed=Q_([1500, 2000], "RPM"),
    weight=525,
    bearing_length=Q_(30, "mm"),
    journal_diameter=Q_(100, "mm"),
    radial_clearance=Q_(0.1, "mm"),
    oil_viscosity=0.1,
)

To access a coefficient array for all speeds:

cylindrical.kxx
array([12807959.57740873, 13005276.62769462])

To display a concise summary of inputs and outputs:

cylindrical._hover_info()
([0],
 'Cylindrical Bearing at Node: 0<br>Length: 0.0300 m<br>Journal Diameter: 0.1000 m<br>Radial Clearance: 1.0000e-04 m<br>Oil Viscosity: 0.1000 Pa·s<br>Load: 525.00 N<br>Speed: 1500.00 ... 2000.00 RPM<br>Eccentricity: 0.2663 ... 0.2126<br>Attitude Angle: 0.1989 ... 0.1617 rad<br>Sommerfeld: 3.571e+00 ... 4.762e+00<br>Kxx: 1.281e+07 ... 1.301e+07 N/m<br>Kyy: 8.815e+06 ... 8.021e+06 N/m<br>Cxx: 2.329e+05 ... 2.249e+05 N·s/m<br>Cyy: 2.949e+05 ... 2.620e+05 N·s/m<br>')