Skip to content

pyflange.fatigue

Fatigue calculation and S-N curve tools for flanged connections.

This module provides data structures, fatigue (Wöhler) curve representations, and analysis classes to evaluate structural fatigue damage and fatigue life for large bolted flanges.

Key components provided by this module:

  • MarkovMatrix: Encapsulates a discrete cyclic load or stress history (load ranges, mean values, cycle counts, and duration) obtained from rainflow counting or design load spectra.
  • FatigueCurve: Abstract base class defining the S-N curve interface and Palmgren-Miner linear cumulative damage accumulation \(D = \sum_{i} n_i / N(\Delta S_i)\).
  • SingleSlopeFatigueCurve: Represents a Wöhler curve with a single logarithmic slope exponent \(m\), defined by the power law \(N \cdot \Delta S^m = a\).
  • MultiSlopeFatigueCurve: Represents a composite multi-slope S-N curve constructed as the upper envelope of multiple single-slope curve segments.
  • DoubleSlopeFatigueCurve: Represents a bilinear S-N curve with two slopes (\(m_1, m_2\)) intersecting at a transition knee point \((\Delta S_{12}, N_{12})\).
  • BoltFatigueCurve: Specialized bilinear S-N curve for threaded bolts conforming to IEC 61400-6 AMD1, incorporating nominal diameter size-effect corrections and a material partial safety factor \(\gamma_M\).
  • BoltFatigueAnalysis: End-to-end fatigue analysis pipeline that evaluates bolt stress spectra from flange bending moment histories, calculates total cumulative damage, and predicts bolt fatigue life.
Units

All parameters must be supplied in a consistent system of units. When using SI units:

  • Distances and diameters: meters (m)
  • Forces: newtons (N)
  • Bending moments: newton-meters (N·m)
  • Stresses and pressures: pascals (Pa)
  • Duration and fatigue life: consistent time units (e.g., seconds or years)
References

The reference numbers are the same in all the PyFlange modules (see the references page). This module cites:

  • [1] Seidel, M.: IEC 61400-6 AMD1 Background document. Fatigue design for ring flange connections in wind turbine support structures. Rev00, Siemens Gamesa, 2024. Section 3 explains the selection of the bolt S-N curve.
  • [2] IEC 61400-6:2020+AMD1:2025 CSV. Wind energy generation systems - Part 6: Tower and foundation design requirements. Consolidated version,
  • The bolt damage calculation is given in section 6.7.5.4.
  • [5] Seidel, M.: IEC 61400-6 AMD1 & ED2 Background document. Rev01, draft 2026-08-04, Siemens Gamesa. Section 3 explains the selection of the bolt S-N curve.

Classes:

MarkovMatrix dataclass

MarkovMatrix(range, mean, cycles, duration=1.0)

A Markov matrix representation of a cyclic load history.

Encapsulates a discrete load or stress spectrum resulting from cycle counting (e.g., rainflow counting). The load history is characterized by arrays of cycle ranges, mean values, and associated cycle counts, along with an overall duration.

The physical quantity represented can be stress (Pa), force (N), bending moment (N·m), etc., provided that consistent units are maintained throughout downstream calculations.

Attributes:

  • range (ndarray) –

    Array of cycle load or stress ranges (\(\Delta S\) or \(\Delta L\)).

  • mean (ndarray) –

    Array of mean load or stress values (\(S_m\) or \(L_m\)).

  • cycles (ndarray) –

    Array containing the number of applied cycles (\(n\)) for each (range, mean) bin.

  • duration (float) –

    Time duration represented by the load history (e.g., in seconds or years). Defaults to 1.0.

FatigueCurve

Abstract base class for Wöhler (S-N) fatigue strength curves.

This class provides the interface for evaluating fatigue endurance (number of cycles to failure \(N\) as a function of stress range \(\Delta S\), and vice versa), as well as calculating fatigue damage and cumulative damage using the Palmgren-Miner linear cumulative damage hypothesis:

\[D = \sum_{i} \frac{n_i}{N(\Delta S_i)}\]

This class should not be instantiated directly; use one of its concrete subclasses such as SingleSlopeFatigueCurve, DoubleSlopeFatigueCurve, or BoltFatigueCurve.

Methods:

  • N –

    Calculates the number of cycles to failure for a given stress range.

  • DS –

    Calculates the allowable stress range for a given number of cycles.

  • damage –

    Calculates fatigue damage according to the Palmgren-Miner rule.

  • cumulated_damage –

    Calculates cumulative fatigue damage according to Miner's sum.

N

N(DS)

Calculates the number of cycles to failure for a given stress range.

Parameters:

  • DS (float | ndarray) –

    Applied stress range(s) \(\Delta S\).

Returns:

  • float | ndarray –

    Number of cycles to fatigue failure \(N(\Delta S)\).

DS

DS(N)

Calculates the allowable stress range for a given number of cycles.

Parameters:

  • N (float | ndarray) –

    Number of cycles to failure \(N\).

Returns:

  • float | ndarray –

    Allowable stress range(s) \(\Delta S(N)\) producing fatigue failure at \(N\) cycles.

damage

damage(n, DS)

Calculates fatigue damage according to the Palmgren-Miner rule.

Computes the elementary fatigue damage ratio:

\[D = \frac{n}{N(\Delta S)}\]

Parameters:

  • n (float | ndarray) –

    Number of applied load cycles.

  • DS (float | ndarray) –

    Applied stress range(s) \(\Delta S\).

Returns:

  • float | ndarray –

    The resulting fatigue damage ratio(s).

cumulated_damage

cumulated_damage(markov_matrix)

Calculates cumulative fatigue damage according to Miner's sum.

Evaluates the total cumulative damage over all bins in the load spectrum:

\[D_{\text{total}} = \sum_{i} \frac{n_i}{N(\Delta S_i)}\]

Bins producing NaN damage values (e.g., zero stress or invalid evaluations) are ignored in the summation via numpy.nansum.

Parameters:

  • markov_matrix (MarkovMatrix) –

    Load history represented as a Markov matrix containing arrays of cycle counts and stress ranges.

Returns:

  • float –

    Total cumulative fatigue damage index \(D_{\text{total}}\).

SingleSlopeFatigueCurve dataclass

SingleSlopeFatigueCurve(m, DS_ref, N_ref)

Bases: FatigueCurve

Wöhler (S-N) fatigue curve with a single logarithmic slope.

Represents a linear S-N relationship in log-log space governed by the power-law equation:

\[N \cdot \Delta S^m = a = \Delta S_{\text{ref}}^m \cdot N_{\text{ref}}\]

where \(m\) is the inverse slope exponent, \(\Delta S_{\text{ref}}\) is a reference stress range, and \(N_{\text{ref}}\) is the corresponding cycle count at failure.

Attributes:

  • m (float) –

    Negative inverse slope of the S-N curve in log-log coordinates (\(-\frac{\mathrm{d}\log N}{\mathrm{d}\log \Delta S}\)).

  • DS_ref (float) –

    Reference stress range \(\Delta S_{\text{ref}}\) (e.g., in Pa).

  • N_ref (float) –

    Reference number of cycles to failure \(N_{\text{ref}}\) at stress range DS_ref.

Methods:

  • N –

    Calculates the number of cycles to failure for given stress range(s).

  • DS –

    Calculates the allowable stress range for given cycle count(s).

a cached property

a

float: Curve capacity constant \(a = \Delta S_{\text{ref}}^m \cdot N_{\text{ref}}\).

N

N(DS)

Calculates the number of cycles to failure for given stress range(s).

Evaluates:

\[N = \frac{a}{\Delta S^m}\]

Parameters:

  • DS (float | ndarray) –

    Applied stress range(s) \(\Delta S\).

Returns:

  • float | ndarray –

    Number of cycles to failure \(N\). A zero stress range in an array returns inf (infinite endurance).

DS

DS(N)

Calculates the allowable stress range for given cycle count(s).

Evaluates:

\[\Delta S = \left(\frac{a}{N}\right)^{1/m}\]

Parameters:

  • N (float | ndarray) –

    Number of cycles to failure \(N\).

Returns:

  • float | ndarray –

    Allowable stress range(s) \(\Delta S\).

MultiSlopeFatigueCurve

MultiSlopeFatigueCurve(*fatigue_curves)

Bases: FatigueCurve

Multi-slope composite Wöhler (S-N) fatigue curve.

Represents an S-N curve formed by combining multiple SingleSlopeFatigueCurve segments. For any given stress range or cycle count, the effective capacity is evaluated as the upper envelope (maximum endurance / maximum allowable stress range) among all constituent curve segments.

Attributes:

Initializes the MultiSlopeFatigueCurve.

Parameters:

  • *fatigue_curves (SingleSlopeFatigueCurve, default: () ) –

    One or more single-slope fatigue curve segments composing the multi-slope curve.

Methods:

  • N –

    Calculates the maximum number of cycles to failure among all curve segments.

  • DS –

    Calculates the maximum allowable stress range among all curve segments.

N

N(DS)

Calculates the maximum number of cycles to failure among all curve segments.

Evaluates:

\[N(\Delta S) = \max_{i} N_i(\Delta S)\]

Parameters:

  • DS (float | ndarray) –

    Applied stress range(s) \(\Delta S\).

Returns:

  • float | ndarray –

    Maximum number of cycles to failure across all component curves.

DS

DS(N)

Calculates the maximum allowable stress range among all curve segments.

Evaluates:

\[\Delta S(N) = \max_{i} \Delta S_i(N)\]

Parameters:

  • N (float | ndarray) –

    Number of cycles \(N\).

Returns:

  • float | ndarray –

    Maximum allowable stress range across all component curves.

DoubleSlopeFatigueCurve

DoubleSlopeFatigueCurve(m1, m2, DS12, N12)

Bases: MultiSlopeFatigueCurve

Bilinear (double-slope) Wöhler (S-N) fatigue curve.

Implements a two-slope S-N curve commonly used in structural design standards (e.g., Eurocode 3, DNV, IEC standards). The curve transitions from slope \(m_1\) in the lower-cycle / higher-stress regime (\(N \le N_{12}\)) to slope \(m_2\) in the higher-cycle / lower-stress regime (\(N > N_{12}\)) at an intersection knee point \((\Delta S_{12}, N_{12})\).

Parameters:

  • m1 (float) –

    Logarithmic slope exponent for the lower-cycle regime (\(N \le N_{12}\)).

  • m2 (float) –

    Logarithmic slope exponent for the higher-cycle regime (\(N > N_{12}\)).

  • DS12 (float) –

    Stress range \(\Delta S_{12}\) at the knee point where the two slopes meet.

  • N12 (float) –

    Number of cycles \(N_{12}\) at the knee point where the two slopes meet.

Initializes the DoubleSlopeFatigueCurve (see the class documentation).

BoltFatigueCurve

BoltFatigueCurve(diameter, DS_ref=50000000.0, gamma_M=1.1)

Bases: DoubleSlopeFatigueCurve

Bolt fatigue S-N curve according to IEC 61400-6 AMD1.

Constructs a design bilinear S-N curve for threaded bolts with logarithmic slopes \(m_1 = 3\) (for \(N \le 2 \times 10^6\)) and \(m_2 = 5\) (for \(N > 2 \times 10^6\)), with a knee point located at \(N_{12} = 2 \times 10^6\) cycles (ref. [2], section 6.7.5.4).

The characteristic reference stress range \(\Delta \sigma_c\) at 2 million cycles is adjusted for bolt size effects with the factor \(k_s\) of ref. [2], eq. (44):

  • For \(d \le 30\text{ mm}\): \(\Delta \sigma_c = \Delta S_{\text{ref}}\)
  • For \(30\text{ mm} < d \le 72\text{ mm}\): \(\Delta \sigma_c = \Delta S_{\text{ref}} \cdot \left(\frac{0.030}{d}\right)^{0.1}\)
  • For \(d > 72\text{ mm}\): \(\Delta \sigma_c = \Delta S_{\text{ref}} \cdot \left(\frac{0.030}{d}\right)^{0.1} \cdot \left(\frac{0.072}{d}\right)^{0.25}\)

The knee point stress range for the design curve is obtained by dividing the characteristic strength by the material partial safety factor:

\[\Delta S_{12} = \frac{\Delta \sigma_c}{\gamma_M}\]

The curve has no endurance limit. With the default parameters (detail category 50, \(\gamma_M = 1.1\)) it is the design curve of ref. [2], section 6.7.5.4. In Monte Carlo simulations, random curves are generated with \(\gamma_M = 1.0\) and a random \(\Delta S_{\text{ref}}\) (see pyflange.stats.standard_bolt_fatigue_curve_sampler).

Parameters:

  • diameter (float) –

    Nominal bolt diameter \(d\) in meters.

  • DS_ref (float, default: 50000000.0 ) –

    Reference characteristic stress range \(\Delta S_{\text{ref}}\) at \(2 \times 10^6\) cycles before size and material factor corrections (in Pa). Defaults to 50 MPa (50e6 Pa), i.e. detail category 50 of ref. [2].

  • gamma_M (float, default: 1.1 ) –

    Material partial safety factor \(\gamma_M\) for fatigue design. Defaults to 1.1 (ref. [2], section 6.7.5.4).

Attributes:

  • diameter (float) –

    The nominal bolt diameter passed to the constructor.

  • DS_ref (float) –

    The reference stress range passed to the constructor.

  • gamma_M (float) –

    The material safety factor passed to the constructor.

Example
import numpy as np
from pyflange.fatigue import BoltFatigueCurve, MarkovMatrix

curve = BoltFatigueCurve(0.080)       # M80 bolt, default fatigue class
N = curve.N(40e6)                     # cycles to failure at a 40 MPa range

mkvm = MarkovMatrix(range=np.array([20e6, 40e6]),
                    mean=np.array([300e6, 300e6]),
                    cycles=np.array([1e6, 1e4]),
                    duration=20)      # e.g. 20 years
D = curve.cumulated_damage(mkvm)      # Miner's sum

Initializes the BoltFatigueCurve (see the class documentation).

BoltFatigueAnalysis dataclass

BoltFatigueAnalysis(fseg, flange_mkvm, custom_fatigue_curve=None, allowable_damage=1.0, SMF=1.0)

Fatigue analysis pipeline for a flange bolt.

Evaluates the cyclic stress history, total cumulative fatigue damage, and expected fatigue life for a bolt in a flanged connection under external bending moment histories.

The analysis transforms the flange shell moment Markov matrix into a bolt stress Markov matrix using the segment's non-linear transfer functions, accounting for axial force, bolt bending, bolt diameter effects, and dynamic stress multiplication. The bolt stress range is the axial stress range plus the bending stress range reduced by the factor \(\kappa_b\) (ref. [2], eqs. (42) and (43)), and the damage is evaluated with Miner's rule (ref. [2], section 6.7.5.4).

Attributes:

  • fseg (FlangeSegment) –

    The flange segment model containing geometry, bolt properties, preloads, and transfer functions.

  • flange_mkvm (MarkovMatrix) –

    The Markov matrix representing the external bending moment load history acting on the flange connection.

  • custom_fatigue_curve (FatigueCurve | None) –

    Optional custom S-N curve for the bolt. If None, an IEC 61400-6 AMD1 compliant BoltFatigueCurve is automatically constructed from the bolt nominal diameter. Defaults to None.

  • allowable_damage (float) –

    Maximum allowable cumulative fatigue damage limit \(D_{\text{allow}}\). Defaults to 1.0 (ref. [2], section 6.7.5.4).

  • SMF (float) –

    Stress Multiplication Factor applied to the bolt stress ranges to account for the model uncertainty of the analytical model (ref. [5], section 6.5). Defaults to 1.0.

Example
import numpy as np
from pyflange.fatigue import MarkovMatrix, BoltFatigueAnalysis

# fseg is a flange segment, e.g. a PolynomialLFlangeSegment
mkvm = MarkovMatrix(range=np.array([20e6, 40e6]),     # N·m
                    mean=np.array([30e6, 30e6]),      # N·m
                    cycles=np.array([1e7, 1e5]),
                    duration=25)                      # years
analysis = BoltFatigueAnalysis(fseg, mkvm)
print(analysis.damage, analysis.fatigue_life)

fatigue_curve cached property

fatigue_curve

FatigueCurve: The S-N fatigue curve used for bolt damage evaluation.

bolt_mkvm cached property

bolt_mkvm

MarkovMatrix: The bolt stress Markov matrix including axial and bending stresses.

The bending stresses are reduced by the factor \(\kappa_b = 0.5 + 0.5 \cdot \log(d/36) / \log(150/36) \ge 0.5\), with \(d\) the bolt nominal diameter in mm (ref. [2], eq. (43)). The stress ranges are multiplied by SMF.

damage cached property

damage

float: Total cumulative fatigue damage \(D = \sum \frac{n_i}{N(\Delta S_i)}\).

fatigue_life cached property

fatigue_life

float: Predicted fatigue life in the same time units as flange_mkvm.duration.