Amplitude-aware roll-period GM correction and reporting for ship stability workflows
Project description
rt4-roll-period
Amplitude-aware roll-period GM correction and reporting for ship stability workflows. The package corrects the systematic amplitude bias of the standard small-angle approximation (which under-estimates GM for finite-amplitude rolls in the linear-GZ regime) and selects the richest available method from vessel GZ tables, validated wall-sided correction, or a linear-GZ fallback.
Publication Status
This repository is being prepared as an open technical reference implementation. It is not class-approved software, a loading computer, a substitute for a statutory stability booklet, or a replacement for professional naval architecture review.
The Problem
During a ship inclining experiment, the standard formula:
GM = (C * B / T_obs)^2
implicitly assumes the roll period is independent of amplitude, which is only true in the small-angle limit. The observed period T_obs is longer than the small-amplitude natural period T0 (finite-amplitude pendulum effect), so plugging T_obs into the formula systematically under-estimates GM in the linear-GZ regime. At 20-degree amplitude this is ~1.54%; the practitioner reads a GM smaller than the ship actually has, which is conservative on stability margin but pessimistic on permitted loading. Wall-sided hull effects can shift the bias in the opposite direction; both corrections are exposed by the library.
The Solution
The exact formula (classical Bernoulli/Euler mechanics, 1749):
T = T0 * (2/pi) * K(sin^2(phi_max/2))
where K(m) is the complete elliptic integral of the first kind. This corrects the amplitude dependence exactly for the linear GZ model.
Result: RT4 mean GM error = 0.000 mm vs small-angle's 20.72 mm at 20-degree amplitude.
Install
pip install rt4-roll-period
Quick Start
from rt4_roll_period import (
roll_period_exact,
recover_gm_rt4,
recover_gm_wall_sided,
gm_correction_factor,
load_gz_table_csv,
assess_gz_table_quality,
build_roll_period_report,
roll_period_gz_table_ratio,
)
# Exact roll period at 20-degree amplitude
T0 = 15.0 # small-angle period (seconds)
T_exact = roll_period_exact(phi_max_deg=20.0, T0=T0)
# T_exact = 15.117... (longer than T0 due to nonlinearity)
# Recover corrected GM from observed roll period
GM_corrected = recover_gm_rt4(
T_obs=14.8, # observed period (s)
phi_max_deg=18.0, # observed max roll amplitude (deg)
C=0.797, # vessel C-factor
B=28.0, # beam (m)
)
# Amplitude correction factor: GM_small_angle / GM_true
factor = gm_correction_factor(phi_max_deg=20.0)
# factor = 0.9847... (small-angle estimate is ~1.54% smaller than true GM)
# Recover true GM by dividing the small-angle estimate by this factor.
# Wall-sided correction when BM is known and the case is inside
# the validated envelope: phi <= 30 deg, BM/GM <= 4
GM_wall = recover_gm_wall_sided(
T_obs=14.8,
phi_max_deg=18.0,
C=0.797,
B=28.0,
BM=3.0,
)
# Vessel-specific GZ curve workflow from a CSV table:
# angle_deg,GZ_m
angle_deg, gz_m = load_gz_table_csv("stability_curve.csv")
quality = assess_gz_table_quality(angle_deg, gz_m, phi_max_deg=20.0)
ratio = roll_period_gz_table_ratio(angle_deg, gz_m, phi_max_deg=20.0)
# ratio is T/T0 for the supplied righting-arm curve
# Practitioner workflow: selects arbitrary-GZ, wall-sided, or linear fallback
report = build_roll_period_report(
T_obs=14.8,
phi_max_deg=18.0,
C=0.797,
B=28.0,
gz_csv_path="stability_curve.csv",
)
API Reference
Core Functions
| Function | Description |
|---|---|
roll_period_exact(phi_max_deg, T0) |
Exact period via K(m) elliptic integral |
roll_period_small_angle(T0) |
Small-angle period (returns T0, for comparison) |
gm_correction_factor(phi_max_deg) |
Multiplicative factor: GM_small_angle / GM_true; recover linear-GZ truth with GM_true = GM_small_angle / factor |
recover_gm_rt4(T_obs, phi_max_deg, C, B) |
Recover corrected GM from observed period and amplitude |
wall_sided_shape_factor(phi_max_deg, bm_gm) |
Interpolated T_wall / T_linear_K factor for validated wall-sided range |
wall_sided_period_ratio(phi_max_deg, bm_gm) |
Interpolated wall-sided T/T0 ratio |
wall_sided_gm_correction_factor(phi_max_deg, bm_gm) |
Wall-sided factor GM_small_angle / GM_true for the validated envelope |
recover_gm_wall_sided(T_obs, phi_max_deg, C, B, BM) |
Recover GM with validated wall-sided interpolation and root solving |
recover_gm_small_angle(T_obs, C, B) |
Recover GM without correction (baseline) |
Vessel Helpers
| Function | Description |
|---|---|
T0_from_vessel(GM, B, k_factor) |
Compute small-angle period from vessel parameters |
C_from_k_factor(k_factor) |
Compute Schofield C-factor from gyration radius ratio |
C_LOOKUP |
Dict of empirical C-factors by vessel type |
GZ Models
| Function | Description |
|---|---|
gz_linear(phi_deg, GM) |
Linear GZ = GM * sin(phi) |
gz_wall_sided(phi_deg, GM, BM) |
Wall-sided GZ = sin(phi) * (GM + BM/2 * tan^2(phi)) |
roll_period_gz_numerical(gz_func, phi_max_deg, T0_ref, GM) |
Numerical period for arbitrary GZ curve |
load_gz_table_csv(path) |
Load and validate angle_deg,GZ_m CSV data |
gz_table_interpolator(angle_deg, gz_m) |
PCHIP interpolation for a validated GZ table |
gz_table_gm(angle_deg, gz_m) |
Estimate initial GM from a low-angle GZ slope fit |
assess_gz_table_quality(angle_deg, gz_m, phi_max_deg=None) |
Return table-quality flags and report warnings |
build_roll_period_report(T_obs, phi_max_deg, C, B, ...) |
Select the best correction workflow and return report-ready results |
roll_period_gz_table_ratio(angle_deg, gz_m, phi_max_deg) |
Compute arbitrary-GZ T/T0 from table data |
roll_period_gz_table(angle_deg, gz_m, phi_max_deg, T0_ref) |
Compute arbitrary-GZ absolute period from table data |
Analysis Tables
| Function | Description |
|---|---|
period_vs_amplitude_table(T0, angles) |
Table of exact vs small-angle periods |
gm_overestimate_table(angles) |
Table of GM amplitude bias by amplitude (despite the historical name, returns the magnitude by which the small-angle method under-estimates true GM in the linear-GZ regime) |
Limitations
The K(m) formula is exact for the linear GZ model (GZ = GM * sin(phi), pure pendulum). For the wall-sided hull model (GZ = sin(phi) * (GM + BM/2 * tan^2(phi))), the linear K(m) correction is not exact and can be materially wrong at high BM/GM ratios and large amplitudes.
The wall-sided interpolation functions are validated for the primary product envelope:
0 <= phi_max_deg <= 30
0 <= BM/GM <= 4
Inside that envelope, numerical validation found wall-sided GM recovery max error below 0.1% on midpoint test cases. Outside that envelope, use direct numerical integration or an actual vessel GZ curve workflow rather than extrapolating the interpolation table.
For full generality with arbitrary GZ curves, use roll_period_gz_table_ratio() for angle_deg,GZ_m tables or roll_period_gz_numerical() for custom callables. The table API estimates the initial GM from a low-angle slope fit, so sparse or digitized curves should carry uncertainty labels.
Sensitivity checks support 5-degree table spacing as a practical minimum and 2.5-degree spacing as preferred for highly curved GZ curves or near-limit amplitudes. Use assess_gz_table_quality() to surface warnings for coarse spacing, sparse low-angle data, near-vanishing-stability amplitudes, and digitized-curve uncertainty.
Mathematical Background
The roll equation of motion for a ship with linear restoring moment:
I * phi'' + W * GM * sin(phi) = 0
has the exact period solution involving the complete elliptic integral of the first kind K(m):
T = 4 * sqrt(I / (W * GM)) * K(sin^2(phi_max / 2))
= T0 * (2/pi) * K(sin^2(phi_max / 2))
where T0 = 2pisqrt(I/(W*GM)) is the small-angle period. This result is due to Bernoulli (1749) and is classical mechanics, not novel research.
The key insight for inclining experiments: when T_obs is measured at finite amplitude phi_max, T_obs > T0 (the finite-amplitude period is always longer than the small-amplitude limit). Plugging T_obs into the small-angle formula GM = (C*B/T)^2 therefore over-states the period that "should" appear in the formula and under-states GM. The exact correction is:
GM_true = GM_small_angle * [2 * K(sin^2(phi_max / 2)) / pi]^2
= GM_small_angle / gm_correction_factor(phi_max)
gm_correction_factor returns [pi / (2*K(m))]^2 <= 1, i.e. the ratio GM_small_angle / GM_true. Divide the small-angle estimate by this factor (or multiply by [2K/pi]^2) to recover the true GM.
Citation
Paper forthcoming. For now:
@software{rt4_roll_period,
title = {rt4-roll-period: Amplitude-Aware Roll-Period GM Correction and Reporting},
author = {R4RPI},
year = {2026},
version = {1.1.2},
url = {https://github.com/resonant4/rt4-roll-period},
license = {MIT}
}
License
MIT. See LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file rt4_roll_period-1.1.2.tar.gz.
File metadata
- Download URL: rt4_roll_period-1.1.2.tar.gz
- Upload date:
- Size: 36.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6c59740e8583c2e4572a0941038c6ac2dcd57c95d37da280295ff0c795d34ff0
|
|
| MD5 |
2c777507c841fe320351ecf3cb04e37d
|
|
| BLAKE2b-256 |
c922ed28e6cfbc999b712122b38dd215caed1619d790cfaf5ca3b259e32b140f
|
Provenance
The following attestation bundles were made for rt4_roll_period-1.1.2.tar.gz:
Publisher:
publish-pypi.yml on resonant4/rt4-roll-period
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
rt4_roll_period-1.1.2.tar.gz -
Subject digest:
6c59740e8583c2e4572a0941038c6ac2dcd57c95d37da280295ff0c795d34ff0 - Sigstore transparency entry: 1436101665
- Sigstore integration time:
-
Permalink:
resonant4/rt4-roll-period@4cdb2cf1090466f2ec2bbfe6d6600ddcba6135d9 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/resonant4
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@4cdb2cf1090466f2ec2bbfe6d6600ddcba6135d9 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file rt4_roll_period-1.1.2-py3-none-any.whl.
File metadata
- Download URL: rt4_roll_period-1.1.2-py3-none-any.whl
- Upload date:
- Size: 18.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bfc88eb6b67aa26f782f0917cbee1180fe967e75e6703c59ab6dc1ef248dfb8d
|
|
| MD5 |
3779e46a1ff3a25b2e3bd3e8bbe1a0b4
|
|
| BLAKE2b-256 |
e8546d9382dd8c522aa0d3fd4460b7c535a5f4405b5356d06ed71bff39b924f4
|
Provenance
The following attestation bundles were made for rt4_roll_period-1.1.2-py3-none-any.whl:
Publisher:
publish-pypi.yml on resonant4/rt4-roll-period
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
rt4_roll_period-1.1.2-py3-none-any.whl -
Subject digest:
bfc88eb6b67aa26f782f0917cbee1180fe967e75e6703c59ab6dc1ef248dfb8d - Sigstore transparency entry: 1436101669
- Sigstore integration time:
-
Permalink:
resonant4/rt4-roll-period@4cdb2cf1090466f2ec2bbfe6d6600ddcba6135d9 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/resonant4
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@4cdb2cf1090466f2ec2bbfe6d6600ddcba6135d9 -
Trigger Event:
workflow_dispatch
-
Statement type: