The meanstress module
Meanstress transformation
Meanstress transformation is used to take the influence of the meanstress of a load hysteresis into account. The fatigue of a cyclically loaded component is not only influenced by the amplitude but also by the mean stress. The usual way to take this into account is to compute a substitute amplitude that has the same fatigue result for the known mean stress. The mean stress sensitivity is usually defined by a haigh diagram, depending on the R-value regime.
In pyLife we have the class HaighDiagram
that lets you define an arbitrary haigh diagram, i.e. a mean stress sensitivity
for each interval of R. There are also convenience functions
fkm_goodman and
five_segment that lets you
define the more common haigh diagrams more easily.
FKM Goodman
Five Segment Correction
- class pylife.strength.meanstress.HaighDiagram(pandas_obj)[source]
Model for a Haigh diagram in order to perform meanstress transformations.
A Haigh diagram a set of meanstress sensitivity slopes $M$ that is changing with the R-values. The values of the
`pd.Seriesrepresents that slopes $M$ and the pd.IntervalIndex represents the R-ranges.- classmethod five_segment(five_segment_haigh_diagram)[source]
Create a five segment slope Haigh diagram.
- Parameters:
five_segment_haigh_diagram (
pandas.Seriesorpandas.DataFrame) – The five segment meanstress slope data.
Notes
five_segment_hagih_diagramhas to provide the following keys:M0: the mean stress sensitivity betweenR==-infandR==0M1: the mean stress sensitivity betweenR==0andR==R12M2: the mean stress sensitivity betwennR==R12andR==R23M3: the mean stress sensitivity betweenR==R23andR==1M4: the mean stress sensitivity beyondR==1R12: R-value betweenM1andM2R23: R-value betweenM2andM3
Examples
>>> haigh = HaighDiagram.five_segment( ... pd.Series( ... {"M0": 0.5, "M1": 0.25, "M2": 0.125, "M3": 1.0, "M4": -2.0, "R12": 0.2, "R23": 0.8} ... ) ... ) >>> haigh.to_pandas() R (1.0, inf] -2.000 (-inf, 0.0] 0.500 (0.0, 0.2] 0.250 (0.2, 0.8] 0.125 (0.8, 1.0] 1.000 dtype: float64
>>> collective = pd.DataFrame( ... { ... "range": [600.0, 300.0, 500.0], ... "mean": [400.0, -150.0, 0.0], ... "cycles": [1.0, 10.0, 100.0], ... } ... ) >>> haigh.transform(collective, 0.0) range mean cycles 0 640.000000 320.000000 1.0 1 100.000000 50.000000 10.0 2 333.333333 166.666667 100.0
- classmethod fkm_goodman(haigh_fkm_goodman)[source]
Create a Haigh diagram according to FKM Goodman.
- Parameters:
haigh_fkm_goodman (pd.Series or pd.DataFrame) – a series containing one or a dataframe containing multiple values for M and optionally M2.
Notes
The Haigh diagram according to FKM Goodman comes with the slope
Mwhich is valid betweenR==-infandR==0. BeyondR==0the slope isM2` if ``M2is given orM/3if not.Examples
A FKM Goodman diagram with default
M2>>> HaighDiagram.fkm_goodman(pd.Series({"M": 0.5})).to_pandas() R (1.0, inf] 0.000000 (-inf, 0.0] 0.500000 (0.0, 1.0] 0.166667 dtype: float64
A FKM Goodman diagram with manual
M2>>> HaighDiagram.fkm_goodman(pd.Series({"M": 0.5, "M2": 0.2})).to_pandas() R (1.0, inf] 0.0 (-inf, 0.0] 0.5 (0.0, 1.0] 0.2 dtype: float64
>>> collective = pd.DataFrame( ... { ... "range": [600.0, 300.0, 500.0], ... "mean": [100.0, 50.0, 80.0], ... "cycles": [1.0, 10.0, 100.0], ... } ... ) >>> HaighDiagram.fkm_goodman(pd.Series({"M": 0.5})).transform(collective, -1.0) range mean cycles 0 700.0 0.0 1.0 1 350.0 0.0 10.0 2 580.0 0.0 100.0
- classmethod from_dict(segments_dict)[source]
Create a Haigh diagram from a dict.
- Parameters:
segments_dict (dict) – dict resolving the R-value intervals to the meanstress slope
Example
>>> HaighDiagram.from_dict({ ... (1.0, np.inf): 0.0, ... (-np.inf, 0.0): 0.5, ... (0.0, 1.0): 0.167 ... }).to_pandas() R (1.0, inf] 0.000 (-inf, 0.0] 0.500 (0.0, 1.0] 0.167 dtype: float64
sets up a FKM Goodman like Haigh diagram.
- transform(collective, R_goal)[source]
Transform a load collective to defined R-value.
- Parameters:
collective (pd.DataFrame) – The load collective data to transform containing either range and mean or from and to columns to describe the load cycles. All other columns e.g. cycles are copied to the result.
R_goal (float) – The target R-value for the transformation.
- Returns:
DataFrame with columns: - ‘range’: transformed amplitude range - ‘mean’: transformed mean value - ‘cycles’: copied unchanged from the input if present
- Return type:
pd.DataFrame
Examples
>>> collective = pd.DataFrame( ... { ... "from": [300.0, -150.0, -250.0], ... "to": [-300.0, 150.0, 250.0], ... "cycles": [1.0, 10.0, 100.0], ... } ... ) >>> HaighDiagram.from_dict({(-np.inf, np.inf): 0.5}).transform(collective, 0.0) range mean cycles 0 400.000000 200.000000 1.0 1 200.000000 100.000000 10.0 2 333.333333 166.666667 100.0
>>> collective = pd.DataFrame( ... { ... "range": [600.0, 300.0, 500.0], ... "mean": [100.0, 50.0, 80.0], ... "cycles": [1.0, 10.0, 100.0], ... } ... ) >>> HaighDiagram.from_dict({(-np.inf, np.inf): 0.5}).transform(collective, -1.0) range mean cycles 0 700.0 0.0 1.0 1 350.0 0.0 10.0 2 580.0 0.0 100.0
- class pylife.strength.meanstress.MeanstressTransformCollective(pandas_obj)[source]
Meanstress transformer class for a load collective.
- five_segment(five_segment, R_goal)[source]
Perform a Five segment transformation on a load collective
- Parameters:
five_segment (pd.Series or pd.DataFrame) – The meanstress sensitivities and R transition values (see
HaighDiagram.five_segment())R_goal (float) – The R-value to transform to
- Returns:
transformed_collective – The transformed load collective. After the meanstress transformation, the resulting
(range, mean)interval bins may no longer be continuous.- Return type:
Examples
>>> collective = pd.DataFrame( ... { ... "range": [600.0, 300.0, 500.0], ... "mean": [400.0, -150.0, 0.0], ... "cycles": [1.0, 10.0, 100.0], ... } ... ) >>> haigh = pd.Series( ... {"M0": 0.5, "M1": 0.25, "M2": 0.125, "M3": 1.0, "M4": -2.0, "R12": 0.2, "R23": 0.8} ... ) >>> transformed = collective.meanstress_transform.five_segment(haigh, 0.0) >>> transformed.amplitude 0 320.000000 1 50.000000 2 166.666667 Name: amplitude, dtype: float64
>>> transformed.meanstress 0 320.000000 1 50.000000 2 166.666667 Name: meanstress, dtype: float64
- fkm_goodman(goodman, R_goal)[source]
Perform a FKM Goodman transformation on a load collective
- Parameters:
goodman (pd.Series or pd.DataFrame) – The meanstress sensitivity data needs M and optionally M2
R_goal (float) – The R-value to transform to
- Returns:
transformed_collective – The transformed load collective
- Return type:
Examples
>>> collective = pd.DataFrame( ... { ... "from": [300.0, -150.0, -250.0], ... "to": [-300.0, 150.0, 250.0], ... "cycles": [1.0, 10.0, 100.0], ... } ... ) >>> collective.meanstress_transform.fkm_goodman(pd.Series({"M": 0.5}), 0.0).amplitude 0 200.000000 1 100.000000 2 166.666667 Name: amplitude, dtype: float64
- class pylife.strength.meanstress.MeanstressTransformMatrix(pandas_obj)[source]
Meanstress transformer class for a load histogram.
- five_segment(five_segment, R_goal)[source]
Perform a Five segment transformation on a load histogram
- Parameters:
five_segment (pd.Series or pd.DataFrame) – The meanstress sensitivities and R transition values (see
HaighDiagram.five_segment())R_goal (float) – The R-value to transform to
- Returns:
transformed_histogram – The transformed load histogram. After the meanstress transformation, the resulting
(range, mean)interval bins may no longer be continuous.- Return type:
Notes
If continuous bins are required afterwards, e.g. for visualization, the transformed histogram can optionally be rebinned. Be aware that such a rebinning is a post-processing step for presentation purposes and may reduce the accuracy of the transformed histogram.
Examples
>>> histogram = pd.Series( ... [10, 90, 900, 9000, 90000, 900000], ... index=pd.MultiIndex.from_arrays( ... [ ... pd.IntervalIndex.from_arrays( ... [650, 550, 450, 350, 250, 150], [750, 650, 550, 450, 350, 250] ... ), ... pd.IntervalIndex.from_arrays([0, 0, 0, 0 ,0, 0], [0, 0, 0, 0, 0, 0]), ... ], ... names=["range", "mean"], ... ), ... name="cycles" ... ) >>> five_segments = pd.Series( ... { ... "M0": 0.5, ... "M1": 0.2, ... "M2": 0.1, ... "M3": 1.0, ... "M4": 2.0, ... "R12": 0.2, ... "R23": 0.8, ... } ... ) >>> transformed = histogram.meanstress_transform.five_segment(five_segments, 0) >>> transformed.amplitude range mean (433.3333333333333, 500.0] (216.66666666666666, 250.0] 233.333333 (366.6666666666667, 433.3333333333333] (183.33333333333334, 216.66666666666666] 200.000000 (300.0, 366.6666666666667] (150.0, 183.33333333333334] 166.666667 (233.33333333333334, 300.0] (116.66666666666667, 150.0] 133.333333 (166.66666666666669, 233.33333333333334] (83.33333333333334, 116.66666666666667] 100.000000 (100.0, 166.66666666666669] (50.0, 83.33333333333334] 66.666667 Name: amplitude, dtype: float64
- fkm_goodman(goodman, R_goal)[source]
Perform a FKM Goodman transformation on a load histogram
- Parameters:
goodman (pd.Series or pd.DataFrame) – The meanstress sensitivity data needs M and optionally M2.
R_goal (float) – The R-value to transform to
- Returns:
transformed_histogram – The transformed load histogram. After the meanstress transformation, the resulting
(range, mean)interval bins may no longer be continuous.- Return type:
Notes
If continuous bins are required afterwards, e.g. for visualization, the transformed histogram can optionally be rebinned. Be aware that such a rebinning is a post-processing step for presentation purposes and may reduce the accuracy of the transformed histogram.
Examples
>>> histogram = pd.Series( ... [10, 90, 900, 9000, 90000, 900000], ... index=pd.MultiIndex.from_arrays( ... [ ... pd.IntervalIndex.from_arrays( ... [650, 550, 450, 350, 250, 150], [750, 650, 550, 450, 350, 250] ... ), ... pd.IntervalIndex.from_arrays([0, 0, 0, 0 ,0, 0], [0, 0, 0, 0, 0, 0]), ... ], ... names=["range", "mean"], ... ), ... name="cycles" ... ) >>> transformed = histogram.meanstress_transform.fkm_goodman(pd.Series({"M": 0.0}), 0) >>> transformed.amplitude range mean (650.0, 750.0] (325.0, 375.0] 350.0 (550.0, 650.0] (275.0, 325.0] 300.0 (450.0, 550.0] (225.0, 275.0] 250.0 (350.0, 450.0] (175.0, 225.0] 200.0 (250.0, 350.0] (125.0, 175.0] 150.0 (150.0, 250.0] (75.0, 125.0] 100.0 Name: amplitude, dtype: float64
- pylife.strength.meanstress.experimental_mean_stress_sensitivity(sn_curve_R0, sn_curve_Rn1, N_c=inf)[source]
Estimate the mean stress sensitivity from two FiniteLifeCurve objects for the same amount of cycles N_c.
The formula for calculation is taken from: “Betriebsfestigkeit”, Haibach, 3. Auflage 2006
Formula (2.1-24):
\[M_{\sigma} = {S_a}^{R=-1}(N_c) / {S_a}^{R=0}(N_c) - 1\]Alternatively the mean stress sensitivity is calculated based on both SD values (if N_c is not given).
- Parameters:
sn_curve_R0 (pylife.strength.sn_curve.FiniteLifeCurve) – Instance of FiniteLifeCurve for R == 0
sn_curve_Rn1 (pylife.strength.sn_curve.FiniteLifeCurve) – Instance of FiniteLifeCurve for R == -1
N_c (float, (default=np.inf)) – Amount of cycles where the amplitudes should be compared. If N_c is higher than a fatigue transition point (ND) for the SN-Curves, SD is taken. If N_c is None, SD values are taken as stress amplitudes instead.
- Returns:
Mean stress sensitivity M_sigma
- Return type:
- Raises:
ValueError – if the resulting M_sigma doesn’t lie in the range from 0 to 1 a ValueError is raised, as this value would suggest higher strength with additional loads.
- pylife.strength.meanstress.five_segment_correction(amplitude, meanstress, M0, M1, M2, M3, M4, R12, R23, R_goal)[source]
- Performs a mean stress transformation to R_goal according to the
Five Segment Mean Stress Correction
- Parameters:
Sa – the stress amplitude
Sm – the mean stress
Rgoal – the R-value to transform to
M – the mean stress sensitivity between R=-inf and R=0
M1 – the mean stress sensitivity between R=0 and R=R12
M2 – the mean stress sensitivity betwenn R=R12 and R=R23
M3 – the mean stress sensitivity between R=R23 and R=1
M4 – the mean stress sensitivity beyond R=1
R12 – R-value between M1 and M2
R23 – R-value between M2 and M3
- Returns:
the transformed stress range