Tutorial about Seals: Labyrinth, Hole-pattern, and Hybrid#
This tutorial explains how to use three seal models in ROSS (ross/seals/):
LabyrinthSeal— multi-tooth compressible throttling seal.HolePatternSeal— bulk-flow model for annular seals with hole / honeycomb–type cells (pocket damper seals).HybridSeal— combined hole-pattern + labyrinth with iterative mass-flow matching at the interface.
ROSS units are SI internally. Use ross.units.Q_ for convenient input (for example RPM → rad/s).
1. Labyrinth seal (LabyrinthSeal)#
A labyrinth restricts leakage through a series of throttlings (teeth). ROSS solves compressible flow along the seal, estimates mass flow (including choke where relevant), swirl in cavities, and perturbed equations for stiffness and damping (and optional fluid-related mass terms) versus whirl speed.
Typical inputs: shaft radius, radial clearance, number of teeth, pitch and tooth geometry, seal type ("rotor", "stator", or "inter"), pressures, temperature, shaft frequency(ies), preswirl, and gas data.
# Make sure the default renderer is set to 'notebook' for inline plots in Jupyter
import plotly.io as pio
pio.renderers.default = "notebook"
from ross.seals.labyrinth_seal import LabyrinthSeal
from ross.units import Q_
seal = LabyrinthSeal(
n=0,
shaft_radius=Q_(72.5, "mm"),
radial_clearance=Q_(0.3, "mm"),
n_teeth=16,
pitch=Q_(3.175, "mm"),
tooth_height=Q_(3.175, "mm"),
tooth_width=Q_(0.1524, "mm"),
seal_type="inter",
inlet_pressure=308_000.0,
outlet_pressure=94_300.0,
inlet_temperature=283.15,
frequency=Q_([5000, 8000, 11000], "RPM"),
preswirl=0.98,
gas_composition={"Nitrogen": 0.79, "Oxygen": 0.21},
)
seal
c:\Users\vinic\OneDrive\Desktop\Digital_Twin\Github\ross\venv\Lib\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
LabyrinthSeal(n=0, n_link=None,
kxx=[-1.94449649e+04 -3.15819258e+09 2.80261312e+15], kxy=[ 1.65479279e+04 -7.83714166e+09 9.36204948e+15],
kyx=[-1.65479279e+04 7.83714166e+09 -9.36204948e+15], kyy=[-1.94449649e+04 -3.15819258e+09 2.80261312e+15],
kzz=[0, 0, 0], cxx=[ 1.46954145e+01 -1.03899648e+07 7.99109118e+12],
cxy=[ 3.54252215e+01 2.60730549e+06 -2.55043342e+12], cyx=[-3.54252215e+01 -2.60730549e+06 2.55043342e+12],
cyy=[ 1.46954145e+01 -1.03899648e+07 7.99109118e+12], 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=[ 523.5987756 837.75804096 1151.91730632], tag=None)
Access: Coefficients are stored as lists aligned with frequency (for example seal.kxx, seal.kxy, …; seal.cxx, …). Leakage: seal.seal_leakage.
Without gas_composition, you must supply molar, gamma, tz (two temperatures [K]), and muz (two dynamic viscosities [Pa·s]).
2. Hole-pattern seal (HolePatternSeal)#
Hole-pattern (including honeycomb stator) seals are represented by a one-dimensional bulk-flow model along the seal length: base compressible flow, perturbation for dynamic coefficients, integrated direct and cross stiffness, damping, and apparent mass terms.
Geometrically the model uses a representative cell (cell_length, cell_width, cell_depth) and roughness (dimensionless E/D), not a full CAD mesh.
from ross.seals.holepattern_seal import HolePatternSeal
from ross.units import Q_
# Geometry derived from honeycomb_data.pdf (see table above)
DRUM_OD_M = 196.5e-3
shaft_radius = DRUM_OD_M / 2
length_honeycomb = 84.9e-3
diametral_clearance = 0.36e-3
radial_clearance = diametral_clearance / 2
holepattern = HolePatternSeal(
n=0,
shaft_radius=shaft_radius,
radial_clearance=radial_clearance,
length=length_honeycomb,
roughness=1.0e-4,
cell_length=length_honeycomb / 37,
cell_width=2.1e-3,
cell_depth=2.8e-3,
inlet_pressure=1_830_000.0,
outlet_pressure=823_500.0,
inlet_temperature=300.0,
frequency=Q_([5000], "RPM"),
gas_composition={
"Nitrogen": 0.7812,
"Oxygen": 0.2096,
"Argon": 0.0092,
},
preswirl=1.0,
entr_coef=0.1,
exit_coef=0.5,
nz=40,
)
holepattern
HolePatternSeal(n=0, n_link=None,
kxx=[5760043.48572718], kxy=[1377442.42449097],
kyx=[-1377442.42449097], kyy=[5760043.48572718],
kzz=[0], cxx=[2470.55767601],
cxy=[-477.40987914], cyx=[477.40987914],
cyy=[2470.55767601], czz=[0],
mxx=[-0.4221625], mxy=[0.11170356],
myx=[-0.11170356], myy=[-0.4221625],
mzz=[0],
frequency=[523.5987756], tag=None)
3. Hybrid seal (HybridSeal)#
HybridSeal stacks the two models in series along the pressure path:
HolePatternSealfrom globalinlet_pressuredown to an unknown interface pressureLabyrinthSealfrom that interface to globaloutlet_pressure
ROSS finds the interface pressure by bisection so that the mass flow leaving the hole-pattern stage matches the mass flow leaving the labyrinth (leakage continuity). The resulting rotordynamic coefficients are added (series force contribution from both components), consistent with the implementation in hybrid_seal.py.
3.1 Concept#
After solving for the interface pressure, the hybrid element exposes:
hybrid.interface_pressure— converged junction pressure [Pa]hybrid.n_iterations— bisection stepshybrid.hole_patternandhybrid.laby— underlyingHolePatternSealandLabyrinthSealinstanceshybrid.seal_leakage— aligned leakagehybrid.summary_results()— tabular summary (PrettyTable)hybrid.plot_convergence()— Plotly figure for convergence / pressure / leakage histories
Iterative Pressure Matching#
The model uses a bisection method to find the interface pressure (\(P_{int}\)) between the two seal stages that satisfies mass conservation:
where:
\(P_{in}\) is the inlet pressure (upstream of hole-pattern seal)
\(P_{out}\) is the outlet pressure (downstream of labyrinth seal)
\(\dot{m}\) represents the mass flow rate (leakage)
from ross.seals.hybrid_seal import HybridSeal
from ross.units import Q_
gas_composition = {
"Nitrogen": 0.7812,
"Oxygen": 0.2096,
"Argon": 0.0092,
}
hole_pattern_parameters = {
"radial_clearance": 0.0003,
"length": 0.04,
"roughness": 0.0001,
"cell_length": 0.003,
"cell_width": 0.003,
"cell_depth": 0.002,
"preswirl": 0.8,
"entr_coef": 0.5,
"exit_coef": 1.0,
}
labyrinth_parameters = {
"radial_clearance": Q_(0.25, "mm"),
"n_teeth": 10,
"pitch": Q_(3, "mm"),
"tooth_height": Q_(3, "mm"),
"tooth_width": Q_(0.15, "mm"),
"seal_type": "inter",
"preswirl": 0.9,
"tz": [300.0, 299.5],
"muz": [1.85e-05, 1.84e-05],
}
hybrid = HybridSeal(
n=0,
shaft_radius=Q_(25, "mm"),
inlet_pressure=500_000.0,
outlet_pressure=100_000.0,
inlet_temperature=300.0,
frequency=Q_([2000, 3000, 5000], "RPM"),
gas_composition=gas_composition,
hole_pattern_parameters=hole_pattern_parameters,
labyrinth_parameters=labyrinth_parameters,
)
hybrid.format_table(frequency_units="RPM")
| Frequency [RPM] | kxx [N/m] | kyy [N/m] | kxy [N/m] | kyx [N/m] | kzz [N/m] | cxx [N*s/m] | cyy [N*s/m] | cxy [N*s/m] | cyx [N*s/m] | czz [N*s/m] |
|---|---|---|---|---|---|---|---|---|---|---|
| 2000.0 | 203520.12407 | 203520.12407 | 11480.74088 | -11480.74088 | 0.0 | 63.12131 | 63.12131 | -3.01923 | 3.01923 | 0.0 |
| 2750.0 | -604549639.96381 | -604549639.96381 | -3443320335.47969 | 3443320335.47969 | 0.0 | -6550598.04353 | -6550598.04353 | 1238528.75563 | -1238528.75563 | 0.0 |
| 3500.0 | 2416438849.994 | 2416438849.994 | 13765193232.82072 | -13765193232.82072 | 0.0 | 26175602.67469 | 26175602.67469 | -4950493.21321 | 4950493.21321 | 0.0 |
| 4250.0 | 9063168989.99748 | 9063168989.99748 | 51625552185.64214 | -51625552185.64214 | 0.0 | 98178665.27597 | 98178665.27597 | -18567068.92576 | 18567068.92576 | 0.0 |
| 5000.0 | 19335640780.04664 | 19335640780.04664 | 110137756522.98457 | -110137756522.98457 | 0.0 | 209458589.76032 | 209458589.76032 | -39611198.38201 | 39611198.38201 | 0.0 |
4. Plots and Results#
4.1. Coefficient vs frequency plots#
LabyrinthSeal, HolePatternSeal, and HybridSeal inherit SealElement → BearingElement.plot(). Pass stiffness names (kxx, kxy, …) or damping names (cxx, …) in one call (they cannot be mixed). The method interpolates between the discrete frequency samples and returns a Plotly figure. The same call works on holepattern or hybrid once those objects exist (use a denser frequency list if you need a smoother curve).
fig_k = seal.plot(
coefficients=["kxx", "kyy", "kxy", "kyx"],
frequency_units="RPM",
)
fig_k.update_layout(title="Labyrinth seal — stiffness vs whirl speed")
fig_k.show()
fig_c = seal.plot(
coefficients=["cxx", "cyy", "cxy", "cyx"],
frequency_units="RPM",
)
fig_c.update_layout(title="Labyrinth seal — damping vs whirl speed")
fig_c.show()
4.2. plot_pressure_distribution() — axial pressure profile#
Both LabyrinthSeal and HolePatternSeal implement plot_pressure_distribution(pressure_units="MPa", length_units="m", ...), returning a Plotly line plot of pressure vs axial position along the solved 1D domain.
LabyrinthSeal: pressure at cavity centres / stages — typically a step-like decay from inlet to outlet.HolePatternSeal: continuous profile along the discretisednzstations — smoother axial pressure drop with frictional and loss behaviour embedded in the base flow.
fig_p = seal.plot_pressure_distribution(pressure_units="MPa", length_units="mm")
fig_p.show()
4.2. HybridSeal—only: convergence diagnostic plots and table#
Method / attribute |
Purpose |
|---|---|
|
|
|
Three stacked subplots: (1) relative leakage error vs iteration — log-scaled (y), should trend downward; (2) mass-flow rates — hole-pattern vs labyrinth leakages converging to the same value; (3) interface pressure vs iteration — settling to the bisection root |
|
Raw lists for custom plots |
# After building hybrid (Section 4)
table = hybrid.summary_results()
print(table) # ASCII table: Parameter | Value
fig_conv = hybrid.plot_convergence()
fig_conv.show()
+-------------------------+--------------+
| Parameter | Value |
+-------------------------+--------------+
| Number of Iterations | 21 |
| Final Convergence | 1.017087e-07 |
| Interface Pressure (Pa) | 219426.92 |
| Seal Leakage (kg/s) | 3.488871e-02 |
+-------------------------+--------------+
5. Practical tips#
Gas model: Prefer
gas_compositionfor real mixtures so thatccpcan derivemolar,gamma, and Sutherland coefficients forHolePatternSeal(and labyrinth when applicable).Performance:
HolePatternSealand nested solves inHybridSealcan be heavy; reducenzwhile prototyping, then refine.Validation: Compare trends (leakage vs. pressure drop, stiffness order of magnitude) with vendor curves or test data where available.
Tests as reference:
ross/tests/test_labyrinth.py,test_holepattern.py, andtest_hybrid_seal.pycontain regression values and parameter sets that always run in CI.