pyflange.stats

Probability distributions and random samplers for probabilistic flange analyses.

This module contains tools for the probabilistic analysis of flanged connections. In particular, two categories of tools are provided:

  • Probability distributions for some flange properties.
  • Samplers: random realization generators for flange properties.

The provided probability distributions are:

  • gap_height_distribution (IEC 61400-6 AMD1)
  • gap_height_distribution_ED2 and gap_angle_distribution_ED2 (IEC 61400-6 ED2)

The samplers are just Python generator functions that yield random values. Samplers can be used in a loop or to generate random values via the python next function. The following general-purpose samplers are available:

  • sampler
  • norm_sampler
  • lognorm_sampler
  • weibull_sampler
  • beta_sampler
  • product_sampler
  • clayton_copula_sampler
  • clayton_gap_sampler
  • fatigue_case_sampler

The following samplers are instead specific to IEC 61400-6:2020:

  • standard_gap_sampler
  • standard_gap_sampler_ED2
  • standard_PolynomialLFlangeSegment_sampler
  • standard_markov_matrix_sampler
  • standard_bolt_fatigue_curve_sampler

An example of how to use the above generators to perform a Montecarlo simulation, is given in this example.

The following references are used through this documentation:

  • [1] IEC 61400-6 AMD1 Background document
  • [2] IEC 61400-6:2020
  • [3] IEC 61400-6 ED2 (draft)

beta_sampler(a, b, x0=0, x1=1)

Sampler based on a Beta distribution.

Parameters:
  • a (float) –

    Shape parameter alpha.

  • b (float) –

    Shape parameter beta.

  • x0 (float, default: 0 ) –

    Lower bound of the variable definition interval. If omitted, it defaults to 0.

  • x1 (float, default: 1 ) –

    Upper bound of the variable definition interval. If omitted, it defaults to 1.

Returns:
  • Generator –

    A Beta distribution sampler with given shape parameters and definition interval boundaries.

Example

The following example creates a Beta distribution sampler and generates three realizations.

samp = beta_sampler(2, 5)  # Beta sampler with  
                           # alpha=2, beta=5, defined in [0,1].

val1 = next(samp)   # A random value from the Beta distribution
val2 = next(samp)   # Another random value from the Beta distribution
val3 = next(samp)   # Yet another random value from the Beta distribution

clayton_copula_sampler(theta, marginal_dist1, marginal_dist2)

Sampler of two random variables joined by a Clayton copula.

The copula realizations are generated with the conditional inverse method: given two independent uniform variables u and w, the second copula variable is

$$v = \left(u^{-\theta} \left(w^{-\theta/(1+\theta)} - 1\right) + 1\right)^{-1/\theta}$$

and the two variables are then mapped to the marginal distributions via their inverse cumulative distribution functions. The Kendall's rank correlation of the two variables is $\tau = \theta / (\theta + 2)$.

Parameters:
  • theta (float) –

    Clayton copula parameter. Must be positive.

  • marginal_dist1 (rv_frozen) –

    Marginal distribution of the first variable.

  • marginal_dist2 (rv_frozen) –

    Marginal distribution of the second variable.

Yields:
  • –

    numpy.ndarray: An array [x1, x2] containing a joint realization of the two variables.

Raises:
  • ValueError –

    If theta is not positive.

Example
from scipy.stats import norm, lognorm
samp = clayton_copula_sampler(2.0, norm(10, 1), lognorm(0.5))
x1, x2 = next(samp)

clayton_gap_sampler(theta, height_marginal_dist, angle_marginal_dist, shape_factor_sampler)

Sampler that generates random flange gaps with correlated height and angle.

The gap height and gap angle are generated as two variables joined by a Clayton copula (see clayton_copula_sampler), while the gap shape factor is generated independently.

Parameters:
  • theta (float) –

    Clayton copula parameter. Must be positive.

  • height_marginal_dist (rv_frozen) –

    Marginal distribution of the gap height, in meters.

  • angle_marginal_dist (rv_frozen) –

    Marginal distribution of the gap angle, in radians.

  • shape_factor_sampler (Generator) –

    A sampler for the gap shape factor.

Yields:
  • –

    pyflange.flangesegments.Gap: A random gap.

fatigue_case_sampler(fseg_samp, markov_matrix_samp, fatigue_curve_samp, allowable_damage_samp, SMF=1.0)

Sampler that generates random fatigue cases.

Parameters:
  • fseg_samp (Generator) –

    A pyflange.flangesegments.FlangeSegment sampler, such as standard_PolynomialLFlangeSegment_sampler.

  • markov_matrix_samp (Generator) –

    A pyflange.fatigue.MarkovMatrix sampler.

  • fatigue_curve_samp (Generator) –

    A pyflange.fatigue.BoltFatigueCurve sampler.

  • allowable_damage_samp (Generator) –

    A float sampler that generates random allowable damages.

  • SMF (float | Generator, default: 1.0 ) –

    Stress Multiplication Factor. If it is a sampler, a new SMF will be generated for every next fatigue case. If it is a float, it will be applied to every next fatigue case. If omitted, it defaults to 1.0.

Yields:
  • –

    pyflange.fatigue.BoltFatigueAnalysis: A random BoltFatigueAnalysis object.

gap_angle_distribution_ED2(flange_diameter, flange_flatness_tolerance)

Evaluates the gap angle probability distribution according to ref. [3].

The gap angle is modeled as a Beta random variable defined over the interval [0, pi], whose parameters depend on the flange diameter and flatness tolerance.

Parameters:
  • flange_diameter (float) –

    The outer diameter of the flange, in meters.

  • flange_flatness_tolerance (float) –

    The flatness tolerance, in mm/mm (non-dimensional).

Returns:
  • –

    scipy.stats.rv_frozen: A frozen SciPy Beta distribution (scipy.stats.beta) representing the gap angle, in radians.

gap_height_distribution(flange_diameter, flange_flatness_tolerance, gap_length)

Evaluates the gap height probability distribution according to ref. [1].

The gap height is modeled as a log-normal random variable, whose mean value and coefficient of variation depend on the flange diameter, the flatness tolerance and the gap length.

Parameters:
  • flange_diameter (float) –

    The outer diameter of the flange, expressed in meters.

  • flange_flatness_tolerance (float) –

    The flatness tolerance, as defined in ref. [1], expressed in mm/mm (non-dimensional).

  • gap_length (float) –

    The length of the gap, expressed in meters and measured at the outer edge of the flange.

Returns:
  • –

    scipy.stats.rv_frozen: A frozen SciPy log-normal distribution (scipy.stats.lognorm) representing the gap height stochastic variable, expressed in meters.

Example

The following example creates a gap distribution and then calculates the 95% quantile of the gap height.

from pyflange.stats import gap_height_distribution

D = 7.50      # Flange diameter in meters
u = 0.0014    # Flatness tolerance (non-dimensional)
L = 1.22      # Gap length
gap_dist = gap_height_distribution(D, u, L)     # a lognorm distribution object

u95 = gap_dist.ppf(0.95)    # PPF is the inverse of CDF. See scipy.stats.lognorm documentation.

gap_height_distribution_ED2(flange_diameter, flange_flatness_tolerance, gap_length)

Evaluates the gap height probability distribution according to ref. [3].

The gap height is modeled as a Weibull random variable, whose shape and scale parameters depend on the flange diameter, the flatness tolerance and the gap angle.

Parameters:
  • flange_diameter (float) –

    The outer diameter of the flange, in meters.

  • flange_flatness_tolerance (float) –

    The flatness tolerance, in mm/mm (non-dimensional).

  • gap_length (float) –

    The length of the gap, in meters, measured at the outer edge of the flange.

Returns:
  • –

    scipy.stats.rv_frozen: A frozen SciPy Weibull distribution (scipy.stats.weibull_min) representing the gap height, in meters.

Example
from math import pi
from pyflange.stats import gap_height_distribution_ED2

D = 7.50                         # Flange diameter in meters
u = 0.0014                       # Flatness tolerance (1.4 mm/m)
L = pi/6 * D/2                   # Length of a 30 deg gap
dist = gap_height_distribution_ED2(D, u, L)
u95 = dist.ppf(0.95)             # 95% quantile of the gap height

lognorm_sampler(mean, cv)

Sampler based on a Log-Normal distribution.

Parameters:
  • mean (float) –

    Mean value of the log-normal distribution.

  • cv (float) –

    Coefficient of variation of the log-normal distribution.

Returns:
  • Generator –

    A log-normal distribution sampler with given mean value and coefficient of variation.

Example

The following example creates a Log-Normal distribution sampler and generates three realizations.

samp = lognorm_sampler(12.0, 0.25)  # log-normal sampler with
                                    # mean value 12.0 and CoV = 0.25.

val1 = next(samp)   # A random value from the log-normal distribution
val2 = next(samp)   # Another random value from the log-normal distribution
val3 = next(samp)   # Yet another random value from the log-normal distribution

norm_sampler(mean, cv)

Sampler based on a Normal distribution.

Parameters:
  • mean (float) –

    Mean value of the normal distribution.

  • cv (float) –

    Coefficient of variation of the normal distribution.

Returns:
  • Generator –

    A normal distribution sampler with given mean value and coefficient of variation.

Example

The following example creates a Normal distribution sampler and generates three realizations.

samp = norm_sampler(12.0, 0.25)   # normal sampler with mean 12.0
                                  # and CoV = 0.25.

val1 = next(samp)   # A random value from the normal distribution
val2 = next(samp)   # Another random value from the normal distribution
val3 = next(samp)   # Yet another random value from the normal distribution

product_sampler(dist1, dist2)

Sampler of the product of two independent random variables.

Parameters:
  • dist1 (rv_frozen) –

    Distribution of the first factor.

  • dist2 (rv_frozen) –

    Distribution of the second factor.

Yields:
  • float –

    The product of a realization of dist1 and a realization of dist2.

Example
from scipy.stats import norm, lognorm
samp = product_sampler(norm(1.0, 0.1), lognorm(0.1))
value = next(samp)

sampler(random_variable)

Generic distribution-based sampler.

Parameters:
  • random_variable (rv_continuous) –

    Any SciPy continuous random variable.

Yields:
  • float –

    A random realization of the passed random variable, at every next call.

Example

The following example creates a Normal distribution sampler and generates three realizations.

from scipy.stats import norm
ndist = norm(12.0, 2.0) # normal distribution with mean value 12 and standard deviation 2.

samp = sampler(ndist)   # sampler based on the ndist distribution

val1 = next(samp)       # A random value from ndist distribution
val2 = next(samp)       # Another random value from ndist distribution
val3 = next(samp)       # Yet another random value from ndist distribution

standard_PolynomialLFlangeSegment_sampler(a, b, s, t, R, central_angle, Zg, bolt, Do, washer, nut, preload_sampler, ppl_sampler, dft_sampler, gap_sampler, tilt_sampler=lognorm_sampler(0.1 * deg, 0.5), E=210000000000.0, G=80770000000.0, s_ratio=1.0, r=0.01, k_shell='interp', settlement_factor=1.0, segment_class=None)

A sampler that yields random pyflange PolynomialLFlangeSegment objects.

For each realization, a random gap and a random flange tilt are drawn, and the bolt preload is sampled and averaged over the bolts affected by the gap (half of the bolts subtended by the gap angle, at least one), to account for the larger preload scatter at small gap angles. The returned segment already includes the effect of the sampled preload losses (settlement and plastic), so its PPL and DFT attributes are zero.

Parameters:
  • a (float) –

    Distance between inner face of the flange and center of the bolt hole.

  • b (float) –

    Distance between center of the bolt hole and center-line of the shell.

  • s (float) –

    Shell thickness.

  • t (float) –

    Flange thickness.

  • R (float) –

    Shell outer curvature radius.

  • central_angle (float) –

    Angle subtended by the flange segment.

  • Zg (float) –

    Load applied to the flange segment shell at rest (normally dead weight of tower + RNA, divided by the number of bolts). Negative if compression.

  • bolt (Bolt) –

    Bolt object representing the flange segment bolt.

  • Do (float) –

    Bolt hole diameter.

  • washer (Washer) –

    Bolt washer.

  • nut (Nut) –

    Bolt nut.

  • preload_sampler (Generator) –

    Random preload sampler.

  • ppl_sampler (Generator) –

    Sampler of the percentage of pretension losses due to plastic deformation (non-dimensional, e.g. 0.03 for 3%).

  • dft_sampler (Generator) –

    Dry film thickness sampler.

  • gap_sampler (Generator) –

    Sampler of pyflange.flangesegments.Gap objects, such as standard_gap_sampler.

  • tilt_sampler (Generator, default: lognorm_sampler(0.1 * deg, 0.5) ) –

    Random tilt angle sampler. Sampled angles are reduced to the interval [0, pi]. Defaults to lognorm_sampler(0.1*deg, 0.50).

  • E (float, default: 210000000000.0 ) –

    Young modulus of the flange. Defaults to 210e9.

  • G (float, default: 80770000000.0 ) –

    Shear modulus of the flange. Defaults to 80.77e9.

  • s_ratio (float, default: 1.0 ) –

    Ratio of bottom shell thickness over s. Defaults to 1.0.

  • r (float, default: 0.01 ) –

    Rounding between flange and shell. Defaults to 0.01.

  • k_shell (str | float | None, default: 'interp' ) –

    Custom shell stiffness. If 'interp' (default), the stiffness is interpolated from the tabulated FEA results, as a function of the gap angle (see pyflange.flangesegments.shell_stiffness). If a number, it's used as the stiffness. If None, a simplified formula is used.

  • settlement_factor (float, default: 1.0 ) –

    Factor reducing the amount of bolt settlement, to be taken as 1.0 for torque tightening and 0.5 for tension tightening. If omitted, it defaults to 1.0.

  • segment_class (type, default: None ) –

    The class of the generated flange segments: PolynomialLFlangeSegment or one of its subclasses, such as PolynomialLFlangeSegmentED2. If omitted, it defaults to PolynomialLFlangeSegment.

Yields:
  • –

    pyflange.flangesegments.PolynomialLFlangeSegment: A random L-Flange segment object.

Example

The following example creates a L-Flange segment sampler and generates three random flange segments.

from math import pi
from metrum.units import mm, um, kN

import pyflange.stats as stats
from pyflange.bolts import StandardMetricBolt, RoundNut
N_BOLTS = 156

fseg_samp = standard_PolynomialLFlangeSegment_sampler (
        a = 150*mm,        # distance between inner face of the flange and center of the bolt hole
        b = 122*mm,        # distance between center of the bolt hole and center-line of the shell
        s =  54*mm,        # shell thickness
        t = 172*mm,        # flange thickness
        R = 4000*mm,       # shell outer curvature radius
        central_angle = 2*pi / N_BOLTS,  # angle subtended by the flange segment

        Zg = -18044*kN / N_BOLTS,      # load applied to the flange segment shell at rest

        # Bolt object representing the flange segment bolt
        bolt = StandardMetricBolt("M80", "10.9", shank_length=160*mm,
                shank_diameter_ratio=76.1/80, stud=True),

        Do = 86*mm,               # Bolt hole diameter
        washer = None,            # Bolt washer
        nut = RoundNut("M80"),    # Bolt nut

        # bolt preload random sampler and preload losses parameters
        preload_sampler = stats.norm_sampler(2932.24*kN, 0.03), 
        ppl_sampler = stats.norm_sampler(0.03, 1/3),
        dft_sampler = stats.norm_sampler(250*um, 0.12),

        # gap object random sampler
        gap_sampler = stats.standard_gap_sampler(
                    flange_diameter = 8000*mm,
                    flange_flatness_tolerance = 0.0014,   # 1.4 mm/m
                    gap_angle_sampler = stats.lognorm_sampler(100*deg, 1.0),
                    gap_shape_factor_sampler = stats.norm_sampler(1.0, 0.15)
                ),

        s_ratio = 1.0,              # Ratio of bottom shell thickness over s.
        settlement_factor = 0.50    # Settlement reduction for tension tightening.
    )

fseg1 = next(fseg_samp)     # A random L-Flange segment object
fseg2 = next(fseg_samp)     # Another random L-Flange segment object
fseg3 = next(fseg_samp)     # Yet another random L-Flange segment object

standard_bolt_fatigue_curve_sampler(bolt_nominal_diameter, mean_stress_factor=1.0, stress_factor_CoV=0.1, DS_ref_mean=62 * MPa)

Sampler that generates random bolt S-N curves, according to ref. [2].

The reference stress range of each curve is the product of DS_ref_mean and a normally distributed random coefficient. The curves have no material safety factor (gamma_M = 1.0).

Parameters:
  • bolt_nominal_diameter (float) –

    The nominal diameter of the bolt, in meters.

  • mean_stress_factor (float, default: 1.0 ) –

    The mean value of the fatigue class coefficient, assumed normally distributed. Defaults to 1.

  • stress_factor_CoV (float, default: 0.1 ) –

    The coefficient of variation of the fatigue class coefficient, assumed normally distributed. Defaults to 0.10.

  • DS_ref_mean (float, default: 62 * MPa ) –

    The mean value of the fatigue curve reference stress range. If unknown it could be calculated as 1.24 times the fatigue class. If omitted, it defaults to 62 MPa.

Yields:
  • –

    pyflange.fatigue.BoltFatigueCurve: A random bolt fatigue curve object.

standard_gap_sampler(flange_diameter, flange_flatness_tolerance, gap_angle_sampler=lognorm_sampler(100 * deg, 1.0), gap_shape_factor_sampler=norm_sampler(1.0, 0.15), gap_height_cap=2.0)

Sampler that generates random flange gaps according to ref. [1].

For each realization, a gap angle is drawn from gap_angle_sampler, the gap height is then drawn from the distribution returned by gap_height_distribution for that angle, and the gap shape factor is drawn from gap_shape_factor_sampler. Realizations are discarded and redrawn when the gap angle is not between 0 and 180 degrees, or when the gap height exceeds gap_height_cap times the 95th percentile of its distribution.

Parameters:
  • flange_diameter (float) –

    The outer diameter of the flange, in meters.

  • flange_flatness_tolerance (float) –

    The flatness tolerance in mm/mm.

  • gap_angle_sampler (Generator, default: lognorm_sampler(100 * deg, 1.0) ) –

    A sampler for the gap angle, in radians. Defaults to a log-normal sampler with mean 100 deg and CoV = 1.0.

  • gap_shape_factor_sampler (Generator, default: norm_sampler(1.0, 0.15) ) –

    A sampler for the gap shape factor. Defaults to a normal sampler with mean 1.0 and CoV = 0.15.

  • gap_height_cap (float, default: 2.0 ) –

    The generated gap height will be capped at gap_height_cap * p95, where p95 is the 95th percentile of the gap height distribution. If omitted, it defaults to 2.0.

Yields:
  • –

    pyflange.flangesegments.Gap: A random gap, with random height, angle and shape factor.

Example

The following example creates a standard gap sampler and generates three realizations.

# Gap sampler for a 7.5 m flange with flatness tolerance 1.4 mm/m
samp = standard_gap_sampler(7.5, 0.0014)

gap1 = next(samp)  # A random gap
gap2 = next(samp)  # Another random gap
gap3 = next(samp)  # Yet another random gap

print(gap1.height, gap1.angle, gap1.shape_factor)

standard_gap_sampler_ED2(flange_diameter, flange_flatness_tolerance)

Sampler that generates random flange gaps according to ref. [3].

For each realization, a gap angle is drawn from the distribution returned by gap_angle_distribution_ED2 and the gap height is then drawn from the distribution returned by gap_height_distribution_ED2 for that angle. The gap shape factor is always 1.0.

Parameters:
  • flange_diameter (float) –

    The outer diameter of the flange, in meters.

  • flange_flatness_tolerance (float) –

    The flatness tolerance in mm/mm.

Yields:
  • –

    pyflange.flangesegments.Gap: A random gap, with random height and angle.

Example
# ED2 gap sampler for a 7.5 m flange with flatness tolerance 1.4 mm/m
samp = standard_gap_sampler_ED2(7.5, 0.0014)
gap = next(samp)

standard_markov_matrix_sampler(markov_matrix, mean_range_coeff=1.0, range_CoV=0.12)

Sampler that generates a random Markov matrix according to ref [2].

Each realization has the same cycles, means and duration as the design Markov matrix, while its ranges are scaled by a single log-normally distributed coefficient.

Parameters:
  • markov_matrix (MarkovMatrix) –

    The deterministic design Markov matrix.

  • mean_range_coeff (float, default: 1.0 ) –

    The mean value of the coefficient multiplying the load ranges of markov_matrix, assumed log-normally distributed. Defaults to 1.0.

  • range_CoV (float, default: 0.12 ) –

    The coefficient of variation of the coefficient multiplying the load ranges. Defaults to 0.12.

Yields:
  • –

    pyflange.fatigue.MarkovMatrix: A random Markov matrix.

weibull_sampler(shape, scale=1.0)

Sampler based on a Weibull distribution.

Parameters:
  • shape (float) –

    Shape parameter of the Weibull distribution.

  • scale (float, default: 1.0 ) –

    Scale parameter of the Weibull distribution. Defaults to 1.0.

Returns:
  • Generator –

    A Weibull distribution sampler with given scale and shape parameters.

Example

The following example creates a Weibull distribution sampler and generates three realizations.

samp = weibull_sampler(1.5, 2)  # Weibull sampler with  
                                # shape 1.5 and scale 2.0

val1 = next(samp)   # A random value from the Weibull distribution
val2 = next(samp)   # Another random value from the Weibull distribution
val3 = next(samp)   # Yet another random value from the Weibull distribution