In [1]:
from IPython.display import display, Markdown as md, HTML as html, FileLink
import math
import time
import json
import zipfile

try:
    import pandas as pd
    import ipywidgets as widgets
    from ipywidgets import interact, interactive, interactive_output
    import numpy as np
    import matplotlib.pylab as plt
    import scipy
    from sklearn.preprocessing import minmax_scale
    import plotly.express as px
    from plotly.subplots import make_subplots
    import plotly.graph_objects as go
    import statsmodels.api as sm
    from matplotlib import pyplot
    from scipy.optimize import curve_fit

except Exception as e:
    !pip install pandas ipywidgets matplotlib plotly pandas-bokeh scipy scikit-learn statsmodels
    import pandas as pd
    import ipywidgets as widgets
    from ipywidgets import interact, interactive
    import numpy as np
    import matplotlib.pylab as plt
    import scipy
    from sklearn.preprocessing import minmax_scale
    import plotly.express as px
    from plotly.subplots import make_subplots
    import plotly.graph_objects as go
    import statsmodels.api as sm
    from matplotlib import pyplot
    from scipy.optimize import curve_fit
    
#pd.options.plotting.backend = "plotly"
In [2]:
display(md("# Wöhlerlinie"))
df = pd.read_csv('woehlerlinie.csv')

df["kN"] = df[["Prüflast"]].multiply(0.6, axis=1)
df["Gesamt Lastwechsel"] = df[["Lastwechsel", "Vorbelastung"]].sum(axis=1)

Wöhlerlinie¶

In [3]:
display(df.info())
display(df.head())
display(df.describe())
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 27 entries, 0 to 26
Data columns (total 9 columns):
 #   Column              Non-Null Count  Dtype  
---  ------              --------------  -----  
 0   Serie               27 non-null     int64  
 1   Prüfkörper          27 non-null     object 
 2   Prüflast            27 non-null     int64  
 3   Vorbelastung        27 non-null     int64  
 4   Lastwechsel         27 non-null     int64  
 5   Bemerkung           1 non-null      object 
 6   Gebrochen           27 non-null     int64  
 7   kN                  27 non-null     float64
 8   Gesamt Lastwechsel  27 non-null     int64  
dtypes: float64(1), int64(6), object(2)
memory usage: 2.0+ KB
None
Serie Prüfkörper Prüflast Vorbelastung Lastwechsel Bemerkung Gebrochen kN Gesamt Lastwechsel
0 1 Pk 1 125 0 3000000 NaN 0 75.0 3000000
1 1 Pk 14 125 0 3000000 NaN 0 75.0 3000000
2 1 Pk 19 125 0 3000000 NaN 0 75.0 3000000
3 1 Pk 4 150 0 718000 NaN 1 90.0 718000
4 1 Pk 5 150 0 3000000 NaN 0 90.0 3000000
Serie Prüflast Vorbelastung Lastwechsel Gebrochen kN Gesamt Lastwechsel
count 27.00000 27.000000 2.700000e+01 2.700000e+01 27.000000 27.000000 2.700000e+01
mean 2.00000 151.851852 3.620000e+05 1.306313e+06 0.703704 91.111111 1.668313e+06
std 0.83205 23.944975 9.533156e+05 1.985510e+06 0.465322 14.366985 2.354422e+06
min 1.00000 125.000000 0.000000e+00 1.000000e+00 0.000000 75.000000 4.830000e+03
25% 1.00000 125.000000 0.000000e+00 2.824700e+04 0.000000 75.000000 4.615000e+04
50% 2.00000 150.000000 0.000000e+00 1.712000e+05 1.000000 90.000000 3.422500e+05
75% 3.00000 175.000000 2.300000e+04 2.203000e+06 1.000000 105.000000 3.000000e+06
max 3.00000 200.000000 3.000000e+06 6.000000e+06 1.000000 120.000000 9.000000e+06
In [4]:
#df.set_index('Prüflast', inplace=True)
df.reset_index()
#df.groupby("Serie")["Lastwechsel"].plot()
fig, ax = pyplot.subplots()
df.plot.scatter(x="Lastwechsel", y="Prüflast",ax=ax)

#model = sm.formula.ols(formula='Prüflast ~ Lastwechsel', data=df)
#res = model.fit()
#df.assign(fit=res.fittedvalues).plot(x='Lastwechsel', y='Prüflast', ax=ax)
Out[4]:
<Axes: xlabel='Lastwechsel', ylabel='Prüflast'>
No description has been provided for this image
In [5]:
#df.set_index('Prüflast', inplace=True)
df.reset_index()

# loc[(df["Prüflast"] != 175)]
_exp = df.groupby("Prüflast")["Gesamt Lastwechsel"].mean().reset_index()
print(_exp)
fig, ax = pyplot.subplots()
_exp.plot.scatter(x="Gesamt Lastwechsel", y="Prüflast",ax=ax)

x = _exp["Gesamt Lastwechsel"].to_numpy()
y = _exp["Prüflast"].to_numpy()

fit = np.polyfit(x, np.log(y), 1)

#plt. plot (x, p(x), color="purple")

print("log(y) =", fit[1], fit[0], "x")
#print("y =", np.exp(fit[1] + fit[0] * 10000000))

print("x =", (np.log(100) - fit[1]) / fit[0])

#def func(x, a, b, c):
#    return a * np.exp(-b * x) + c
#popt, pcov = curve_fit(func, x, y)
#print(popt)
#plt.plot(x, func(x, *popt), 'r-', label='fit: a=%5.3f, b=%5.3f, c=%5.3f' % tuple(popt))

def monoExp(x, m, t, b):
    return m * np.exp(-t * x) + b
# perform the fit
p0 = ( fit[1], -fit[0], 50) # start with values near those we expect
params, cv = scipy.optimize.curve_fit(monoExp, x, y, p0)
m, t, b = params
sampleRate = 20_000 # Hz
tauSec = (1 / t) / sampleRate

# determine quality of the fit
squaredDiffs = np.square(y - monoExp(x, m, t, b))
squaredDiffsFromMean = np.square(y - np.mean(y))
rSquared = 1 - np.sum(squaredDiffs) / np.sum(squaredDiffsFromMean)
print(f"R² = {rSquared}")

# plot the results
plt.plot(x, monoExp(x, m, t, b), '--', label="fitted")

# inspect the parameters
print(f"Y = {m} * e^(-{t} * x) + {b}")
print(f"Tau = {tauSec * 1e6} µs")

#for i in [3000000,10000000,20000000]:
#    print(monoExp(i, m, t, b))

#def _exp_func(y):
#    return (np.log(y) - fit[1]) / fit[0]
def _exp_func(x):
    return np.exp(fit[1]) * np.exp(fit[0] * x)
#print(_exp_func(6625238))
plt. plot (x, _exp_func(x), color="purple")

x = df["Gesamt Lastwechsel"].to_numpy()
y = df["Prüflast"].to_numpy()

fit = np.polyfit(x, np.log(y), 1)
print("log(y) =", fit[1], fit[0], "x")
#print("y =", np.exp(fit[1] + fit[0] * 10000000))

print("x =", (np.log(100) - fit[1]) / fit[0])

#model = sm.formula.ols(formula='Prüflast ~ Lastwechsel', data=df)
#res = model.fit()
#df.assign(fit=res.fittedvalues).plot(x='Lastwechsel', y='Prüflast', ax=ax)
   Prüflast  Gesamt Lastwechsel
0       125        4.286822e+06
1       150        6.858833e+05
2       175        3.977914e+04
3       200        5.823000e+03
log(y) = 5.1853843533743715 -8.757634212738333e-08 x
x = 6625238.657973803
R² = 0.9229652299165378
Y = 64.92298636146543 * e^(-1.5016737334552002e-06 * x) + 125.30034798807925
Tau = 33296180.712274313 µs
log(y) = 5.092285574940918 -4.864156719896677e-08 x
x = 10014385.164859032
No description has been provided for this image
In [6]:
import plotly.express as px
#fig, ax = pyplot.subplots()

fig = px.scatter(df, x="Lastwechsel", y="Prüflast", trendline="ols", trendline_options=dict(log_x=True), trendline_color_override="green")
#ax.fill_between(x, y1, 1)
fig.show()
01M2M3M4M5M6M120130140150160170180190200
LastwechselPrüflast
plotly-logomark
In [7]:
_df = df.sort_values(by=["Lastwechsel"])
x = _df["Lastwechsel"].to_numpy()
y = _df["Prüflast"].to_numpy()
z = np. polyfit (x, y, 1)
p = np. poly1d (z)
print(z)
print(p)
fig, ax = pyplot.subplots()

ax.fill_between(x, p(x), 100, where=(p(x)>100), color="green", interpolate=True)#, alpha=0.3)
ax.fill_between(x, p(x), 130, where=(p(x)>130), color="yellow", interpolate=True)#, alpha=0.3)
ax.fill_between(x, p(x), 155, where=(p(x)>155), color="red", interpolate=True)#, alpha=0.3)

plt.scatter (x,y, color="purple")
#calculate equation for trendline
#add trendline to plot
plt. plot (x, p(x), color="purple")

print("Wert fuer Prueflast100:", (100-z[1])/z[0])
[-7.79554891e-06  1.62035279e+02]
 
-7.796e-06 x + 162
Wert fuer Prueflast100: 7957781.993149513
No description has been provided for this image
In [8]:
import statsmodels.api as sm

fig, ax = pyplot.subplots()

#fig = sm.graphics.abline_plot(model_results=results, color='red')
#fig.axes[0].set(ylim=(-1,0), xlim=(1,2))

_df = df.sort_values(by=["Lastwechsel"])
x = _df["Lastwechsel"].to_numpy()
y = _df["kN"].to_numpy()

A = np.vstack([np.log(x), np.ones(len(x))]).T
m, c = np.linalg.lstsq(A, y, rcond=None)[0]

def p(x):
    return m * np.log(x) + c
    
_ = plt.plot(x, y, 'o', label='Meßwerte', markersize=10)
_ = plt.plot(x, p(x), 'r', label='Wöhlerlinie')
_ = plt.legend()

#ax.fill_between(x, p(x), 100 * 0.6, where=(p(x)>110*0.6), color="green", interpolate=True)#, alpha=0.3)
#ax.fill_between(x, p(x), 130 * 0.6, where=(p(x)>130*0.6), color="yellow", interpolate=True)#, alpha=0.3)
#ax.fill_between(x, p(x), 155 * 0.6, where=(p(x)>155*0.6), color="red", interpolate=True)#, alpha=0.3)

ax.set_xlabel("Lastzyklen in Mio.")
ax.set_ylabel("Last in kN")
#plt.scatter (x,y, color="purple")
#calculate equation for trendline
#add trendline to plot
#plt. plot (x, p(x), color="purple")
print(m, c)
def p_rev(y):
    return math.exp((y-c)/m)
#print(p(703474306382))
print("y = 60 :", "%.0f" % p_rev(60))

print(703474306382 / 20 / 19 / 365)
-2.0258903908369246 115.26486604656881
y = 60 : 703474306382
5071912.807368421
No description has been provided for this image
In [9]:
_df["Berechnete Lastwechsel"] = _df["kN"].apply(p_rev)
_df["Berechnete Lastwechsel"] = _df["Berechnete Lastwechsel"].map('{:.0f}'.format)
_df2 = _df.sort_values(by=["Serie", "Prüflast"])
_df2.to_csv('woehlerlinie_berechnete_lw.csv', index=False)
_df2
Out[9]:
Serie Prüfkörper Prüflast Vorbelastung Lastwechsel Bemerkung Gebrochen kN Gesamt Lastwechsel Berechnete Lastwechsel
2 1 Pk 19 125 0 3000000 NaN 0 75.0 3000000 428219033
1 1 Pk 14 125 0 3000000 NaN 0 75.0 3000000 428219033
0 1 Pk 1 125 0 3000000 NaN 0 75.0 3000000 428219033
5 1 Pk 9 150 0 342250 NaN 1 90.0 342250 260666
3 1 Pk 4 150 0 718000 NaN 1 90.0 718000 260666
4 1 Pk 5 150 0 3000000 NaN 0 90.0 3000000 260666
6 1 Pk 8 175 0 31340 NaN 1 105.0 31340 159
8 1 Pk 7 200 0 4830 NaN 1 120.0 4830 0
7 1 Pk 6 200 0 6816 NaN 1 120.0 6816 0
9 2 Pk 18 125 0 1406000 NaN 1 75.0 1406000 428219033
10 2 Pk 2 125 0 6000000 NaN 0 75.0 6000000 428219033
11 2 Pk 11 125 0 6000000 NaN 0 75.0 6000000 428219033
13 2 Pk 17 150 0 107600 NaN 1 90.0 107600 260666
12 2 Pk 12 150 0 114700 NaN 1 90.0 114700 260666
14 2 Pk 15 150 0 171200 NaN 1 90.0 171200 260666
16 2 Pk 13 175 0 11220 NaN 1 105.0 11220 159
15 2 Pk 10 175 0 26230 NaN 1 105.0 26230 159
17 2 Pk 16 175 0 30264 NaN 1 105.0 30264 159
18 3 Pk 1 125 3000000 1 * Nach dem FTW wurde an der Spannklemme einen ... 0 75.0 3000001 428219033
20 3 Pk 19 125 3000000 1175400 NaN 1 75.0 4175400 428219033
19 3 Pk 14 125 3000000 6000000 NaN 0 75.0 9000000 428219033
22 3 Pk 21 150 235000 72900 NaN 1 90.0 307900 260666
21 3 Pk 20 150 235000 281800 NaN 1 90.0 516800 260666
23 3 Pk 22 150 235000 659500 NaN 1 90.0 894500 260666
26 3 Pk 3 175 23000 20800 NaN 1 105.0 43800 159
24 3 Pk 23 175 23000 25500 NaN 1 105.0 48500 159
25 3 Pk 24 175 23000 64100 NaN 1 105.0 87100 159
In [10]:
import statsmodels.api as sm



for i in range(1,4):

    fig, ax = pyplot.subplots()
    
    #fig = sm.graphics.abline_plot(model_results=results, color='red')
    #fig.axes[0].set(ylim=(-1,0), xlim=(1,2))
    
    _df = df.loc[(df["Serie"] == i)].sort_values(by=["Lastwechsel"])
    x = _df["Lastwechsel"].to_numpy()
    y = _df["Prüflast"].to_numpy()
    
    #X = sm.add_constant(x)
    #model = sm.OLS(y,X)
    #results = model.fit()
    #print(results.summary())
    
    A = np.vstack([np.log(x), np.ones(len(x))]).T
    m, c = np.linalg.lstsq(A, y, rcond=None)[0]
    
    def p(x):
        return m*np.log(x) + c   
        
    _ = plt.plot(x, y, 'o', label='Original data', markersize=10)
    _ = plt.plot(x, p(x), 'r', label='Fitted line')
    _ = plt.legend()

    ax.fill_between(x, p(x), 100, where=(p(x)>100), color="green", interpolate=True)#, alpha=0.3)
    ax.fill_between(x, p(x), 130, where=(p(x)>130), color="yellow", interpolate=True)#, alpha=0.3)
    ax.fill_between(x, p(x), 155, where=(p(x)>155), color="red", interpolate=True)#, alpha=0.3)

    ax.set_xlabel("Lastzyklen in Mio.")
    ax.set_ylabel("Last in %")
#plt.scatter (x,y, color="purple")
#calculate equation for trendline
#add trendline to plot
#plt. plot (x, p(x), color="purple")
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
In [11]:
S_M = 0
sum_kN = 0

for index, row in df.iterrows(): #loc[(df["Serie"] == 1)].iterrows():
    #sum_kN += row['kN']
    #if row['Gesamt Lastwechsel'] < 3000000:
    #    S_M += row['kN'] / row['Gesamt Lastwechsel']
    #print(S_M, row['kN'], row['Gesamt Lastwechsel'],row['Lastwechsel'], 3000000)
    
    #sum_kN += row['Lastwechsel']
    #S_M += row['Lastwechsel'] / row['kN']
    #print(S_M, row['Lastwechsel'], row['kN'])

    # Berechnung für N_OM
    sum_kN += row['Gesamt Lastwechsel']
    S_M += row['Gesamt Lastwechsel'] / row['kN']
    print(sum_kN, S_M, row['Lastwechsel'],row['Vorbelastung'], row['kN'])

    #sum_kN += float(row['Gesamt Lastwechsel'])
    #if row['Gesamt Lastwechsel'] < 3000000:
    #    S_M += float(row['Gesamt Lastwechsel'] / 3000000.0)
    #print(S_M, row['kN'], row['Gesamt Lastwechsel'],row['Lastwechsel'], 3000000)
    
    #sum_kN += 3000000.0
    #S_M += float(3000000.0 / row['Gesamt Lastwechsel'])
    #print(S_M, row['kN'], row['Gesamt Lastwechsel'],row['Lastwechsel'], 3000000)

N_M = float(sum_kN / S_M)
print(sum_kN, S_M, N_M)
3000000 40000.0 3000000 0 75.0
6000000 80000.0 3000000 0 75.0
9000000 120000.0 3000000 0 75.0
9718000 127977.77777777778 718000 0 90.0
12718000 161311.11111111112 3000000 0 90.0
13060250 165113.8888888889 342250 0 90.0
13091590 165412.3650793651 31340 0 105.0
13098406 165469.16507936508 6816 0 120.0
13103236 165509.41507936508 4830 0 120.0
14509236 184256.08174603173 1406000 0 75.0
20509236 264256.08174603176 6000000 0 75.0
26509236 344256.08174603176 6000000 0 75.0
26623936 345530.5261904762 114700 0 90.0
26731536 346726.08174603176 107600 0 90.0
26902736 348628.303968254 171200 0 90.0
26928966 348878.11349206354 26230 0 105.0
26940186 348984.9706349207 11220 0 105.0
26970450 349273.19920634927 30264 0 105.0
29970451 389273.21253968263 1 3000000 75.0
38970451 509273.21253968263 6000000 3000000 75.0
43145851 564945.2125396826 1175400 3000000 75.0
43662651 570687.4347619049 281800 235000 90.0
43970551 574108.545873016 72900 235000 90.0
44865051 584047.4347619049 659500 235000 90.0
44913551 584509.3395238096 25500 23000 105.0
45000651 585338.8633333334 64100 23000 105.0
45044451 585756.0061904762 20800 23000 105.0
45044451 585756.0061904762 76.89968267325361

0 75.0 3000000 3000000 3000000 0 75.0 3000000 3000000 3000000 0 75.0 3000000 3000000 3000000 0.0001253481894150418 90.0 718000 718000 3000000 0.0001253481894150418 90.0 3000000 3000000 3000000 0.0003883138577861155 90.0 342250 342250 3000000 0.00373866484693736 105.0 31340 31340 3000000 0.021344298649754262 120.0 6816 6816 3000000 0.04618901914664867 120.0 4830 4830 3000000 840.0 0.04618901914664867 18186.140678437587

In [12]:
display(md("# Test Miner Original"))

d = {'oai': [200,160,120,80,40], 'ni': [10,90,1000,9000,10000], 'Ni': [31250,95367,401878,1000000,1000000]}

_df = pd.DataFrame(data=d)

S_M = 0
sum_kN = 0

for index, row in _df.iterrows():
    #sum_kN += row['kN']
    #S_M += row['kN'] / row['Gesamt Lastwechsel']
    #print(S_M, row['kN'], row['Gesamt Lastwechsel'])
    
    #sum_kN += row['Lastwechsel']
    #S_M += row['Lastwechsel'] / row['kN']
    #print(S_M, row['Lastwechsel'], row['kN'])
    
    #sum_kN += row['Gesamt Lastwechsel']
    #S_M += row['Gesamt Lastwechsel'] / row['kN']
    #print(sum_kN, S_M, row['Lastwechsel'],row['Vorbelastung'], row['kN'])

    # Gesamtlebensdauer N_OM
    sum_kN += float(row['ni'])
    if row['Ni'] < 1000000:
        S_M += float(row['ni'] / row['Ni'])
    print(S_M, row['oai'], row['ni'],row['Ni'], 1000000)
    
    #sum_kN += 3000000.0
    #S_M += float(3000000.0 / row['Gesamt Lastwechsel'])
    #print(S_M, row['kN'], row['Gesamt Lastwechsel'],row['Lastwechsel'], 3000000)

N_M = float(sum_kN / S_M)
print(sum_kN, S_M, N_M)

Test Miner Original¶

0.00032 200 10 31250 1000000
0.0012637226713643084 160 90 95367 1000000
0.0037520400214058635 120 1000 401878 1000000
0.0037520400214058635 80 9000 1000000 1000000
0.0037520400214058635 40 10000 1000000 1000000
20100.0 0.0037520400214058635 5357085.714791674
In [13]:
S_M = 0
sum_kN = 0

for index, row in _df2.iterrows():
    #sum_kN += row['kN']
    #if row['Gesamt Lastwechsel'] < 3000000:
    #    S_M += row['kN'] / row['Gesamt Lastwechsel']
    #print(S_M, row['kN'], row['Gesamt Lastwechsel'],row['Lastwechsel'], 3000000)
    
    #sum_kN += row['Lastwechsel']
    #S_M += row['Lastwechsel'] / row['kN']
    #print(S_M, row['Lastwechsel'], row['kN'])

    # Berechnung für N_OM
    sum_kN += int(row['Berechnete Lastwechsel'])
    if row['Gebrochen']:
        S_M += int(row['Berechnete Lastwechsel']) / row['Gesamt Lastwechsel']
    
    #print(sum_kN, S_M, row['Gesamt Lastwechsel'], row['Berechnete Lastwechsel'])

    #sum_kN += float(row['Gesamt Lastwechsel'])
    #if row['Gesamt Lastwechsel'] < 3000000:
    #    S_M += float(row['Gesamt Lastwechsel'] / 3000000.0)
    #print(S_M, row['kN'], row['Gesamt Lastwechsel'],row['Lastwechsel'], 3000000)
    
    #sum_kN += 3000000.0
    #S_M += float(3000000.0 / row['Gesamt Lastwechsel'])
    #print(S_M, row['kN'], row['Gesamt Lastwechsel'],row['Lastwechsel'], 3000000)

N_M = float(sum_kN / S_M)
print(sum_kN, S_M, N_M)
3856318404 416.14713268646807 9266718.670161815
In [ ]: