Skip to main content

axialfans

Spanwise-resolved analytical solver for multistage axial turbomachinery

PyPI version License: MIT

Quasi-1D pointwise solver for arbitrary sequences of rotating and stationary axial blade rows (rotors, stators, counter-rotating fans) using Newton-Raphson iteration on coupled thermodynamic equations at each radial station. Designed for preliminary turbomachinery design and uncertainty quantification.


Installation

pip install axialfans

Requirements: Python 3.9+, NumPy


Quick Start

from axialfans.fan_solver import MultistageFanSolver, State
import numpy as np

M = 25  # radial stations

solver = MultistageFanSolver(
    N=1, M=M,
    direction=[1],
    sigma=0.9,
    omega=1800,
    beta=45,
    rp=0.25, rm=0.18,
    eta=0.85,
    R=287.05, cp=1004.7, gamma=1.4
)

T0   = 288.15
P0   = 101325.0
rho0 = P0 / (287.05 * T0)

inlet = State(0, M, 0.18, 0.25, T0, P0, 50.0, rho0, 0)
solver.solve(inlet)

perf = solver.performance()
print(f"Pressure ratio:        {perf['PR']:.3f}")
print(f"Temperature ratio:     {perf['TR']:.3f}")
print(f"Isentropic efficiency: {perf['eta_isen']:.3f}")

Examples

See the examples/ directory:

Example Description
01_single_rotor.py Basic single-stage fan
02_rotor_stator.py Fan with straightening vanes
03_counter_rotating.py Swirl cancellation with opposite-spinning rotors
04_variable_area.py Converging/diverging ducts
05_multi_spool.py LP + stator + HP compressor (jet engine architecture)
06_monte_carlo_uq.py Uncertainty quantification with LHS

Key Concepts

State Object

All inlet conditions are passed as a State:

inlet = State(
    n=0,        # stage index (0 = inlet)
    M=25,       # radial stations
    rm=0.18,    # hub radius [m]
    rp=0.25,    # tip radius [m]
    T=288.15,   # temperature [K]
    P=101325,   # pressure [Pa]
    vax=50.0,   # axial velocity [m/s]
    rho=1.225,  # density [kg/m³]
    vtheta=0    # tangential velocity [m/s]
)

Spanwise Resolution

M radial stations are solved independently at each blade row. Spanwise variation arises from blade twist. Pass a 2D (N x M) beta array for full control, or np.linspace(beta_hub, beta_tip, M) for linear twist:

beta_row = np.linspace(65, 71, M)           # single twisted row
beta_matrix = np.array([row1, row2])        # N x M for multistage

Slip Factor

Supplied externally before calling solve(). The modified Stodola model developed in Wang (2026) is recommended for axial machines:

sigma = 1 - C / Z   # Z = blade count, C calibrated from NASA Rotor 37

Unlike Qiu, Wiesner, and classical Stodola — which were derived for centrifugal machines and degenerate toward σ ≈ 1 for low-twist axial geometries — this model explicitly encodes blade count as the primary slip mechanism, which is physically correct for axial blade rows. It applies consistently to both rotors and stators.

Direction Array

Configuration direction
Single rotor [1]
Rotor + stator [1, -1]
Counter-rotating pair [1, -1]
LP + stator + HP [1, -1, 1, -1, ...]

Stators have omega=0. Direction still alternates to correctly handle the velocity triangle frame at each interface.

Variable Area

Pass per-stage radii as arrays:

rp=[0.30, 0.25, 0.20]
rm=[0.20, 0.18, 0.15]

Tunable Solver Constants

import axialfans.fan_solver as solver_module

solver_module.MAX_ITER = 2000   # Newton-Raphson iteration limit
solver_module.TOL      = 1e-10  # convergence tolerance
solver_module.ALPHA    = 0.5    # line search step (reduce if NR diverges)

Performance

  • ~10,000 Monte Carlo evaluations in ~20 minutes on a standard workstation
  • Enables UQ studies that would be computationally prohibitive with RANS CFD
  • A single RANS CFD evaluation for an equivalent geometry takes hours on a cluster

Validation

Validated against NASA experimental data across two independent transonic rotors:

Test Case Configuration PR Error
NASA Rotor 37 Transonic single rotor, deterministic 2.0%
NASA Rotor 67 Transonic single rotor, uncertain geometry, 50,000-sample UQ 2.54%
NACA TR 729 Low-speed rotor-stator, regime of validity characterization —

The NACA TR 729 case identifies the solver's validity boundary: the inviscid compressible model breaks down at low rotor speed and high inlet axial velocity where viscous effects dominate.


Important Note

This solver is a preliminary design and research tool. Outputs must be independently verified before any engineering application. See LICENSE for full liability disclaimer.


Citation

If you use this software in your research, please cite:

@software{wang2026axialfans,
  title={axialfans: Spanwise-Resolved Analytical Solver for Multistage Axial Turbomachinery with Uncertainty Quantification},
  author={Wang, Sean H.},
  year={2026},
  url={https://github.com/sean-h-wang/axialfans},
  version={2.0.0}
}

@article{wang2026analytical,
  title={Spanwise-Resolved Analytical Solver for Multistage Axial Turbomachinery with Uncertainty Quantification},
  author={Wang, Sean H.},
  journal={AIAA Journal},
  year={2026},
  note={submitted}
}

License

MIT License — see LICENSE for details.


Contributing

Issues and pull requests welcome. For bug reports include Python version, NumPy version, and a minimal reproducible example.


Author

Sean H. Wang

Metadata

Release files for axialfans 2.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for axialfans 2.0.0
File Size Uploaded
axialfans-2.0.0.tar.gz 17.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for axialfans 2.0.0
File Interpreter ABI Platform
axialfans-2.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 31.1 kB

Release files / axialfans-2.0.0.tar.gz

Download URL axialfans-2.0.0.tar.gz
Size 17.7 kB
Tags Source
SHA-256 checksum
How to use checksums
7693619e1036c990ab5e0f96fd415a585e910fb75d6e69d6efa154071479fed1
BLAKE2b-256 checksum
How to use checksums
2ce832d08fb734af3231094f8462b30f9454db78cc84d55e6b4bb76f1ad32167
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.7

Release files / axialfans-2.0.0-py3-none-any.whl

Download URL axialfans-2.0.0-py3-none-any.whl
Size 13.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f98b15c76549a4936ef52e5fafac9c5962db9e451eee6d267217be1dc2c4e4da
BLAKE2b-256 checksum
How to use checksums
ba34b5433156d7a34362d11220cb923357c107104d0ffabc80b48029caf14556
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.7

Release history Release notifications | RSS feed

This release

2.0.0 This release

2 release files

1.0.2

2 release files

1.0.1

2 release files

1.0.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page