Skip to main content

cufsm-rs-py

CUFSM, the finite strip method for the elastic buckling of thin-walled sections, in Python.

pip install cufsm-rs-py            # the engine (needs only NumPy)
pip install "cufsm-rs-py[plot]"    # plus matplotlib, for cufsm_rs.plot
import cufsm_rs

CUFSM is by B.W. Schafer and co-workers at Johns Hopkins University (www.ce.jhu.edu/cufsm). This package is an independent port, not affiliated with or endorsed by the CUFSM authors.

Why this exists

cufsm-rs is a Rust port of CUFSM, written so CUFSM could run in the browser, compiled to WebAssembly, in CivilKit Buckling. These bindings make the same engine available in Python, so a script and the web app give the same numbers. The results are checked against CUFSM's own MATLAB code run under Octave (see Tests).

Units

The package is unit-agnostic, as CUFSM is: use any consistent set, for example N, mm and MPa (moments in N mm) or kip, in and ksi. Results come back in the same set.

A load factor is a multiplier on the model's reference stresses: the section buckles when the reference stresses are multiplied by it. Set the reference stresses from the squash load (stress(model, P=Py)) and a load factor reads directly as Pcr / Py. Positive stress is compression.

Quickstart

import numpy as np
import cufsm_rs as fsm

# CUFSM's tutorial C: 9 x 5 x 1 in, t = 0.1 in (inches and ksi)
xz = [(5, 1), (5, 0), (2.5, 0), (0, 0), (0, 3), (0, 6), (0, 9), (2.5, 9), (5, 9), (5, 8)]
m = fsm.Model(
    prop=[[100, 29500, 29500, 0.3, 0.3, 11346.15]],
    node=[[i + 1, x, z, 1, 1, 1, 1, 0] for i, (x, z) in enumerate(xz)],
    elem=[[i + 1, i + 1, i + 2, 0.1, 100] for i in range(9)],
)

p = fsm.section_properties(m)          # p.A, p.Ixx, p.J, p.Cw, p.xs, ... (also p["Ixx"])
y = fsm.first_yield(m, fy=50)          # y.Py = 105, y.Mxx = 324.64 (element faces, as CUFSM)

mc = fsm.stress(m, P=y.Py)             # a new Model with the reference stresses set
sig = fsm.signature(mc, np.logspace(0, 3, 80))
sig                                    # StripResult(signature, bc=S-S, 80 lengths 1 to 1000, neigs=1, 2 minima)
sig.minima                             # [[7.27, 0.353], [43.9, 0.544]]: [half-wavelength, load factor]
sig.classify_minima()                  # [G, D, L, O] percent of each minimum's mode: L 98%, D 94%

r = fsm.strip(mc, [7.27, 43.9], neigs=3)   # any lengths, several modes
r.load_factors                             # (2, 3)
shape = r.mode_shape(0)                    # the lowest mode at the first length
shape.u, shape.v, shape.w, shape.theta     # each (terms, nodes)
shape.dofs                                 # the raw vector, CUFSM's DOF order
shape.at()                                 # displacements summed over terms at mid-length

dist = fsm.strip(mc, [43.9], spaces="D", neigs=1)                  # pure distortional (cFSM)
cc = fsm.strip(mc, [100.0, 200.0], m_all=10, bc="C-C", neigs=2)    # general end conditions
cc.classify()                                                       # (2, 2, 4): G, D, L, O percent

lipped_c, lipped_z, plain_c (outside dimensions and inside radius, default steel in MPa) and template (CUFSM's templatecalc) build models for you:

lc = fsm.lipped_c(200, 76, 15, 1.9, ri=3)    # mm; 37 nodes

The notebook examples/quickstart.ipynb walks through all of this, with plots.

Models

Models use CUFSM's arrays, in CUFSM's column order and with its 1-based node and material numbers. x and z are the cross-section coordinates; y runs along the member.

array columns
prop [mat#, Ex, Ey, vx, vy, G]
node [node#, x, z, xdof, zdof, ydof, qdof, stress] (1 = free, 0 = fixed)
elem [elem#, nodei, nodej, t, mat#] (mat# optional)
constraints [node#e, dofe, coeff, node#k, dofk]
springs [#, nodei, nodej, ku, kv, kw, kq, local, discrete, ys] (nodej 0 = ground)

Model.from_dicts(...) builds the same arrays from lists of dicts with 0-based indices. The arrays are NumPy and editable in place.

Results

strip() and signature() both return a StripResult:

attribute
lengths (nlengths,) half-wavelengths (signature, S-S) or member lengths
load_factors (nlengths, neigs), smallest first, NaN where fewer were found
curve the lowest load factor at each length
modes (nlengths, neigs, ndof) raw mode vectors, CUFSM's DOF order
m_terms the longitudinal terms at each length
minima (n, 2) [length, load factor] at each local minimum (signature only; empty for strip)
kind, bc, model "signature" or "strip", the end conditions, the analysed model

Methods: mode_shape(i_length, k_mode=0), classify(), classify_minima().

Mode shapes. mode_shape returns a ModeShape with u (along x), v (along y, the member), w (along z) and theta (rotation, anticlockwise with x right and z up), each of shape (nterms, nnodes), and the raw vector as dofs. The raw vector is CUFSM's order: for each longitudinal term in turn, a block of 4 * nnodes entries, first u and v interleaved for every node (u1 v1 u2 v2 ...), then w and theta interleaved (w1 theta1 w2 theta2 ...). Modes are scaled so their largest entry is +1. shape.at(y) sums the terms with the end conditions' longitudinal shape functions at y along the member.

Plotting

pip install "cufsm-rs-py[plot]", then:

from cufsm_rs.plot import plot_section, plot_signature, plot_mode

plot_section(mc, node_numbers=True)     # elements to thickness, nodes, stress bands
plot_signature(sig, classify=True)      # log-x curve, minima labelled with G/D/L/O
plot_mode(sig, i_length=20)             # deformed over undeformed cross-section

Each takes an optional ax and returns the matplotlib Axes. plot_mode scales the mode so its largest in-plane displacement is 10% of the section size, whatever the units (scale= to override). import cufsm_rs never imports matplotlib.

Jupyter

Model, SectionProperties, YieldActions and StripResult render as small HTML tables in a notebook (big models are truncated). There is nothing extra to install.

Errors and threads

Invalid input raises ValueError, and the message names the bad row. A model with a mechanism raises cufsm_rs.MechanismError, a subclass of ValueError. The long solves (strip, signature, classify) release the GIL, and cufsm-rs spreads the lengths across threads.

Install from source

You need Rust (1.75 or later) and Python 3.9 or later. The Rust engine comes from crates.io (cufsm-rs = "0.4.1").

python3 -m venv .venv && source .venv/bin/activate
pip install maturin
maturin develop --release --extras dev
pytest -q

The build is abi3, so one wheel covers CPython 3.9 and later.

Tests

tests/test_oracle.py compares against CUFSM's own MATLAB run under Octave, the same oracle fixture the cufsm-rs parity tests use: properties, stresgen stresses, centreline and face first yield, bimoment stress, stress_to_action, load factors, mode MAC, cFSM classification and restricted load factors, at the Rust tolerances. The fixture ships with the cufsm-rs source (tests/fixtures/cufsm_octave.json). It is looked for at ../cufsm-rs/tests/fixtures/ next to this checkout; set CUFSM_ORACLE to its path otherwise. Without it those tests skip and say so. The other tests cover the API, mode shapes, plotting (Agg backend) and the HTML reprs.

Citation

If you publish results, cite CUFSM as its authors ask:

  • Schafer, B.W., Ádány, S., Li, Z., Jin, S. CUFSM v5.66. DOI 10.5281/zenodo.17771486.
  • For general end conditions: Schafer, B.W., Li, Z. "Buckling analysis of cold-formed steel members with general boundary conditions using CUFSM: conventional and constrained finite strip methods." 20th International Specialty Conference on Cold-Formed Steel Structures, 2010, pp. 17-32.
  • CUFSM itself (MATLAB), by B.W. Schafer and co-workers.
  • pyCUFSM by ClearCalcs, a pure-Python port of CUFSM and prior work in this space that this project gratefully acknowledges.
  • cufsm-rs, the Rust engine behind this package.

License

MIT, see LICENSE. CUFSM is MIT-licensed, and its copyright notice is kept there.

Metadata

Release files for cufsm-rs-py 0.1.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 cufsm-rs-py 0.1.0
File Size Uploaded
cufsm_rs_py-0.1.0.tar.gz 39.7 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for cufsm-rs-py 0.1.0
File
cufsm_rs_py-0.1.0-cp39-abi3-win_amd64.whl CPython 3.9 abi3 Windows x86-64 Details
cufsm_rs_py-0.1.0-cp39-abi3-musllinux_1_2_x86_64.whl CPython 3.9 abi3 Linux musl 1.2+ x86-64 Details
cufsm_rs_py-0.1.0-cp39-abi3-musllinux_1_2_aarch64.whl CPython 3.9 abi3 Linux musl 1.2+ ARM64 Details
cufsm_rs_py-0.1.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.9 abi3 Linux glibc 2.17+ x86-64 Details
cufsm_rs_py-0.1.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl CPython 3.9 abi3 Linux glibc 2.17+ ARM64 Details
cufsm_rs_py-0.1.0-cp39-abi3-macosx_11_0_arm64.whl CPython 3.9 abi3 macOS 11.0+ ARM64 Details
cufsm_rs_py-0.1.0-cp39-abi3-macosx_10_12_x86_64.whl CPython 3.9 abi3 macOS 10.12+ x86-64 Details

Total release size: 3.5 MB

Release files / cufsm_rs_py-0.1.0.tar.gz

Download URL cufsm_rs_py-0.1.0.tar.gz
Size 39.7 kB
Tags Source
SHA-256 checksum
How to use checksums
a00ba2a125875ef30a463898347d29166e3f59cc5c49b76bacbbe15685990988
BLAKE2b-256 checksum
How to use checksums
cf317b2d61de1629fde156bcb864072a92a431a2cd325b7bb80245da1bcd4e17
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 1, 2026.

Transparency log

Release files / cufsm_rs_py-0.1.0-cp39-abi3-win_amd64.whl

Download URL cufsm_rs_py-0.1.0-cp39-abi3-win_amd64.whl
Size 345.2 kB
Tags CPython 3.9 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
e3085c93ec9308a2bfbd00977ff3b18cd8d92180505a373850b31821dcb743f9
BLAKE2b-256 checksum
How to use checksums
0db35ea5bf495f76f74c6c89f126b1261c865a0d8c235aa442acc30bd785d5a9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 1, 2026.

Transparency log

Release files / cufsm_rs_py-0.1.0-cp39-abi3-musllinux_1_2_x86_64.whl

Download URL cufsm_rs_py-0.1.0-cp39-abi3-musllinux_1_2_x86_64.whl
Size 683.2 kB
Tags CPython 3.9 Linux musl 1.2+ x86-64 abi3
SHA-256 checksum
How to use checksums
5da9011ba9c08a26a297e94c5e8e1f0685702de6171f5b94cd4ca91d6e0807fa
BLAKE2b-256 checksum
How to use checksums
66046de384ba67738e0cd6291fa23963c6256ea91a435b13481851b54a4b1eea
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 1, 2026.

Transparency log

Release files / cufsm_rs_py-0.1.0-cp39-abi3-musllinux_1_2_aarch64.whl

Download URL cufsm_rs_py-0.1.0-cp39-abi3-musllinux_1_2_aarch64.whl
Size 627.6 kB
Tags CPython 3.9 Linux musl 1.2+ ARM64 abi3
SHA-256 checksum
How to use checksums
043a18a376ae829468216ecd2bc0223fc448ee606397cf4d48350995957680b8
BLAKE2b-256 checksum
How to use checksums
7471b2283145bd57de5056da8fa59c6dea2d528d4c44f13efe25cbce3f03c439
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 1, 2026.

Transparency log

Release files / cufsm_rs_py-0.1.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL cufsm_rs_py-0.1.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 470.9 kB
Tags CPython 3.9 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
5ef9bbe06103e828c0d2836aeb57fd29392e7f85cb38c92226c8278466af7752
BLAKE2b-256 checksum
How to use checksums
3768b68bb457f40046b86b8fb95acdc5909a8deb888e233292ad0860f113f41e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 1, 2026.

Transparency log

Release files / cufsm_rs_py-0.1.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL cufsm_rs_py-0.1.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 451.3 kB
Tags CPython 3.9 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
78590627d864229a1feddf3acd218e452c0310670c4a7612035c9919ac0d6596
BLAKE2b-256 checksum
How to use checksums
ac5b1eefc950b96680b41caa48f338aa1ab931de7cfbbf4464385c72f138d72f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 1, 2026.

Transparency log

Release files / cufsm_rs_py-0.1.0-cp39-abi3-macosx_11_0_arm64.whl

Download URL cufsm_rs_py-0.1.0-cp39-abi3-macosx_11_0_arm64.whl
Size 415.0 kB
Tags CPython 3.9 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
618dea0604c8da81783172fc7d725037e55b13fd69bc8cfa4595cf05cf2c84b2
BLAKE2b-256 checksum
How to use checksums
60fdf8238e80afc3c6c91cd87d069a26838b12d9196e25d10e5ecf552116a35b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 1, 2026.

Transparency log

Release files / cufsm_rs_py-0.1.0-cp39-abi3-macosx_10_12_x86_64.whl

Download URL cufsm_rs_py-0.1.0-cp39-abi3-macosx_10_12_x86_64.whl
Size 425.5 kB
Tags CPython 3.9 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
a4fd53c35aa75bba7b8a0a7ad4f6a43414d0ebdbc5e7b9965dd9280e120abd76
BLAKE2b-256 checksum
How to use checksums
d18e9a8115bd67da56e2107a6b3b63b2dd286c3ae3ecadfae340dda7521d6b48
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 1, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

8 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