kib-lap 0.5__cp313-cp313-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- Examples/Cross_Section_Thin.py +61 -0
- Examples/__init__.py +0 -0
- KIB_LAP/Betonbau/Bemessung_Polygon.py +667 -0
- KIB_LAP/Betonbau/Bemessung_Zust_II.py +648 -0
- KIB_LAP/Betonbau/Cross_Section_Kappa.py +925 -0
- KIB_LAP/Betonbau/Druckglied_KGV.py +179 -0
- KIB_LAP/Betonbau/Iterative_Design.py +723 -0
- KIB_LAP/Betonbau/Materialkennwerte_Beton.py +196 -0
- KIB_LAP/Betonbau/Querschnittsbreite.py +194 -0
- KIB_LAP/Betonbau/Querschnittsbreite_Kreis.py +63 -0
- KIB_LAP/Betonbau/__init__.py +2 -0
- KIB_LAP/Betonbau/beam_plate_T.py +921 -0
- KIB_LAP/Betonbau/beam_plate_T_reverse.py +915 -0
- KIB_LAP/Betonbau/beam_rectangular.py +635 -0
- KIB_LAP/Betonbau/beam_sub_section.py +9 -0
- KIB_LAP/Dynamik/Cross_Section_Properties.py +155 -0
- KIB_LAP/Dynamik/Deformation_Method.py +587 -0
- KIB_LAP/Dynamik/Duhamel_SDOF.py +221 -0
- KIB_LAP/Dynamik/FFT.py +87 -0
- KIB_LAP/Dynamik/Kontinuum_Eigenmodes.py +418 -0
- KIB_LAP/Dynamik/Kontinuum_Schwingung.py +757 -0
- KIB_LAP/Dynamik/Pendulum_Spring_Linearized.py +91 -0
- KIB_LAP/Dynamik/Pendulum_Spring_Problem.py +94 -0
- KIB_LAP/Dynamik/__init__.py +0 -0
- KIB_LAP/Examples/Cross_Section_Thin.py +61 -0
- KIB_LAP/Examples/Cross_Section_Thin_2.py +14 -0
- KIB_LAP/Examples/Plattentragwerke.py +39 -0
- KIB_LAP/Examples/Plattentragwerke_2.py +60 -0
- KIB_LAP/Examples/ShearDesign.py +28 -0
- KIB_LAP/Examples/__init__.py +0 -0
- KIB_LAP/Plattenbeulen/Plate_Design.py +276 -0
- KIB_LAP/Plattenbeulen/Ritz_Optimiert.py +658 -0
- KIB_LAP/Plattenbeulen/__init__.py +2 -0
- KIB_LAP/Plattenbeulen/dist/__init__.py +0 -0
- KIB_LAP/Plattenbeulen/plate_buckling.cpp +561 -0
- KIB_LAP/Plattenbeulen/plate_buckling_cpp.cp313-win_amd64.pyd +0 -0
- KIB_LAP/Plattenbeulen/plate_buckling_cpp.cpp +561 -0
- KIB_LAP/Plattenbeulen/setup.py +35 -0
- KIB_LAP/Plattentragwerke/Functions.cpp +326 -0
- KIB_LAP/Plattentragwerke/Functions.h +41 -0
- KIB_LAP/Plattentragwerke/NumInte.cpp +23 -0
- KIB_LAP/Plattentragwerke/NumericalIntegration.cpp +23 -0
- KIB_LAP/Plattentragwerke/PlateBendingKirchhoff.py +843 -0
- KIB_LAP/Plattentragwerke/__init__.py +1 -0
- KIB_LAP/Plattentragwerke/plate_bending.cpp +341 -0
- KIB_LAP/Plattentragwerke/plate_bending_cpp.cp313-win_amd64.pyd +0 -0
- KIB_LAP/Plattentragwerke/setup.py +39 -0
- KIB_LAP/Querschnittswerte/Querschnitt_Duenn.py +526 -0
- KIB_LAP/Querschnittswerte/__init__.py +1 -0
- KIB_LAP/STABRAUM/InputData.py +92 -0
- KIB_LAP/STABRAUM/Programm.py +1403 -0
- KIB_LAP/STABRAUM/Steifigkeitsmatrix.py +275 -0
- KIB_LAP/STABRAUM/__init__.py +3 -0
- KIB_LAP/Stahlbau/__init__.py +0 -0
- KIB_LAP/Verbundbau/Verbundtraeger_Bemessung.py +766 -0
- KIB_LAP/Verbundbau/__init__.py +0 -0
- KIB_LAP/__init__.py +4 -0
- KIB_LAP/main.py +2 -0
- KIB_LAP/plate_bending_cpp.cp313-win_amd64.pyd +0 -0
- KIB_LAP/plate_buckling_cpp.cp313-win_amd64.pyd +0 -0
- kib_lap-0.5.dist-info/METADATA +25 -0
- kib_lap-0.5.dist-info/RECORD +64 -0
- kib_lap-0.5.dist-info/WHEEL +5 -0
- kib_lap-0.5.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
import matplotlib.pyplot as plt
|
|
3
|
+
import pandas as pd
|
|
4
|
+
from Kontinuum_Schwingung import *
|
|
5
|
+
|
|
6
|
+
class DuhamelSolver:
|
|
7
|
+
def __init__(self, k, m, zeta, dt, duration, loading = "Pedestrian", parameters = [2,1.3,800,60], m2_imp = 0):
|
|
8
|
+
"""
|
|
9
|
+
loading = Pedestrian, Harmonic, Impulse
|
|
10
|
+
parameters = [Frequency in Hz,
|
|
11
|
+
Speed in [m/s],
|
|
12
|
+
First harmonic Loading in [N],
|
|
13
|
+
Length of the Bridge in [m]]
|
|
14
|
+
"""
|
|
15
|
+
self.k = k
|
|
16
|
+
self.m = m + m2_imp # mass of the system, including the impact mass
|
|
17
|
+
self.m2 = m2_imp # impact mass, if impact response is calculated
|
|
18
|
+
self.zeta = zeta
|
|
19
|
+
self.dt = dt
|
|
20
|
+
self.duration = duration
|
|
21
|
+
|
|
22
|
+
self.loading = loading
|
|
23
|
+
self.parameters = parameters
|
|
24
|
+
self.L = self.parameters[-1]
|
|
25
|
+
|
|
26
|
+
# Train passing
|
|
27
|
+
try:
|
|
28
|
+
Kraftdefinition=pd.read_csv('TrainPassing/Inputdatei_1.txt',delim_whitespace=True)
|
|
29
|
+
|
|
30
|
+
# # # % Koordinaten der Radsätze mit Bezug auf den ersten Radsatz [m]
|
|
31
|
+
self.x_k=Kraftdefinition.iloc[:, 0].to_list()
|
|
32
|
+
# # # % Achslasten in [N]
|
|
33
|
+
self.P_k=Kraftdefinition.iloc[:, 1].to_list()
|
|
34
|
+
except:
|
|
35
|
+
pass
|
|
36
|
+
|
|
37
|
+
def load_function(self, time_step):
|
|
38
|
+
|
|
39
|
+
if (self.loading == "Pedestrian"):
|
|
40
|
+
|
|
41
|
+
phi = 0
|
|
42
|
+
if (time_step < self.L / self.parameters[1]):
|
|
43
|
+
xp = self.parameters[1] * time_step
|
|
44
|
+
phi = np.sin(np.pi * xp / self.L)
|
|
45
|
+
else:
|
|
46
|
+
phi = 0
|
|
47
|
+
|
|
48
|
+
coeff_1 = 0.50
|
|
49
|
+
coeff_2 = 0.10
|
|
50
|
+
coeff_3 = 0.10
|
|
51
|
+
|
|
52
|
+
Fn = (1+ coeff_1 * np.sin(2 *np.pi * self.parameters[0]* time_step)
|
|
53
|
+
+ coeff_2 * np.sin(4 *np.pi * self.parameters[0]* time_step -np.pi/2 )
|
|
54
|
+
+coeff_3 * np.sin(6 *np.pi * self.parameters[0]* time_step -np.pi/2 )
|
|
55
|
+
) * self.parameters[2] * phi
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
return Fn
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
elif ( self.loading == "Harmonic"):
|
|
62
|
+
return np.sin(np.sqrt(self.k/self.m)* time_step) * 1000
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
elif (self.loading == "impact"):
|
|
66
|
+
return self.m2 * 9.81
|
|
67
|
+
|
|
68
|
+
elif (self.loading == "trainpassing"):
|
|
69
|
+
self.v_train = self.parameters[1]
|
|
70
|
+
time = np.arange(0, self.duration + self.dt, self.dt)
|
|
71
|
+
nt = len(time)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
P_k_array = np.array(self.P_k)
|
|
75
|
+
|
|
76
|
+
F_Mat = np.zeros((len(self.x_k))) # rows -> Index of the train load, cols = number of time steps
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
for j in range(len(self.x_k)):
|
|
80
|
+
if ((-self.x_k[j] + self.v_train * time_step > 0) and (-self.x_k[j] + self.v_train * time_step < self.L)):
|
|
81
|
+
xp = -self.x_k[j] + self.v_train * time_step # Condition, that the train needs to be on the bridge
|
|
82
|
+
phi = np.sin(np.pi * xp / self.L)
|
|
83
|
+
F_Mat[j] = self.P_k[j] * phi
|
|
84
|
+
else:
|
|
85
|
+
F_Mat[j] = 0
|
|
86
|
+
|
|
87
|
+
return F_Mat.sum(axis=0)
|
|
88
|
+
|
|
89
|
+
else:
|
|
90
|
+
if time_step < 3e-3:
|
|
91
|
+
return 1000
|
|
92
|
+
else:
|
|
93
|
+
return 0
|
|
94
|
+
|
|
95
|
+
def solve(self):
|
|
96
|
+
omega_0 = np.sqrt(self.k / self.m)
|
|
97
|
+
omega_d = omega_0 * np.sqrt(1 - self.zeta**2)
|
|
98
|
+
|
|
99
|
+
time = np.arange(0, self.duration + self.dt, self.dt)
|
|
100
|
+
self.time_output = time
|
|
101
|
+
u = np.zeros(len(time))
|
|
102
|
+
|
|
103
|
+
ACum_i = 0
|
|
104
|
+
BCum_i = 0
|
|
105
|
+
|
|
106
|
+
for i, t in enumerate(time):
|
|
107
|
+
if i > 0:
|
|
108
|
+
y_i = np.exp(self.zeta * omega_0 * time[i]) * self.load_function(time[i]) * np.cos(omega_d * time[i])
|
|
109
|
+
y_i_1 = np.exp(self.zeta * omega_0 * time[i-1]) * self.load_function(time[i-1]) * np.cos(omega_d * time[i-1])
|
|
110
|
+
area_i = 0.5 * self.dt * (y_i + y_i_1)
|
|
111
|
+
ACum_i += area_i
|
|
112
|
+
|
|
113
|
+
y_i = np.exp(self.zeta * omega_0 * time[i]) * self.load_function(time[i]) * np.sin(omega_d * time[i])
|
|
114
|
+
y_i_1 = np.exp(self.zeta * omega_0 * time[i-1]) * self.load_function(time[i-1]) * np.sin(omega_d * time[i-1])
|
|
115
|
+
area_i = 0.5 * self.dt * (y_i + y_i_1)
|
|
116
|
+
BCum_i += area_i
|
|
117
|
+
|
|
118
|
+
u[i] = (1 / (self.m * omega_d)) * (ACum_i) * np.exp(-self.zeta * omega_0 * time[i]) * np.sin(omega_d * time[i]) - (1 / (self.m * omega_d)) * (BCum_i) * np.exp(-self.zeta * omega_0 * time[i]) * np.cos(omega_d * time[i])
|
|
119
|
+
|
|
120
|
+
return time, u
|
|
121
|
+
|
|
122
|
+
def calculate_velocity_and_acceleration(self):
|
|
123
|
+
time, u = self.solve()
|
|
124
|
+
velocity = (np.roll(u, -1) - np.roll(u, 1)) / (2 * self.dt)
|
|
125
|
+
acceleration = (np.roll(u, -1) - 2 * u + np.roll(u, 1)) / (self.dt**2)
|
|
126
|
+
# Remove the erroneous first and last elements
|
|
127
|
+
velocity = velocity[1:-1]
|
|
128
|
+
acceleration = acceleration[1:-1]
|
|
129
|
+
time = time[1:-1]
|
|
130
|
+
return time, velocity, acceleration
|
|
131
|
+
|
|
132
|
+
def plot_solution(self):
|
|
133
|
+
time, self.u = self.solve()
|
|
134
|
+
self._time = time
|
|
135
|
+
self.time_v_a , self.vel, self.acc = self.calculate_velocity_and_acceleration()
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
fig,axes = plt.subplots(nrows = 3, ncols=1)
|
|
139
|
+
|
|
140
|
+
axes[0].plot(self._time,self.u, label = "Deflection")
|
|
141
|
+
axes[0].set_ylabel("Deflection in [m]")
|
|
142
|
+
axes[1].plot(self.time_v_a, self.vel, label = "Velocity")
|
|
143
|
+
axes[1].set_ylabel("Velocity in [m/s]")
|
|
144
|
+
axes[2].plot(self.time_v_a, self.acc, label = "Acceleration")
|
|
145
|
+
axes[2].set_ylabel("Acceleration in [m/s²]")
|
|
146
|
+
fig.suptitle("Vibrations with the Duhamel integral")
|
|
147
|
+
|
|
148
|
+
plt.xlabel('Time in [s]')
|
|
149
|
+
plt.tight_layout()
|
|
150
|
+
plt.grid(True)
|
|
151
|
+
plt.show(block = False)
|
|
152
|
+
plt.pause(10)
|
|
153
|
+
plt.close()
|
|
154
|
+
|
|
155
|
+
def plot_load_function(self):
|
|
156
|
+
self.time_modal_load = np.arange(0, self.duration + self.dt, self.dt)
|
|
157
|
+
self.load_values = np.array([self.load_function(t) for t in self.time_modal_load])
|
|
158
|
+
|
|
159
|
+
plt.figure()
|
|
160
|
+
plt.plot(self.time_modal_load ,self.load_values, label='Load Function')
|
|
161
|
+
plt.xlabel('Time in [s]')
|
|
162
|
+
plt.ylabel('Load in [N]')
|
|
163
|
+
plt.title('Load Function over Time')
|
|
164
|
+
plt.grid(True)
|
|
165
|
+
plt.legend()
|
|
166
|
+
plt.show()
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
# Impact = DuhamelSolver(1e6, 1000, 0.01, 0.001, 10, loading = "impact", parameters = [2,1.3,800,60], m2_imp = 100)
|
|
171
|
+
# Impact.plot_solution()
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
# u_stat = 100/1e6*9.81
|
|
175
|
+
|
|
176
|
+
# print("udyn", max(Impact.u))
|
|
177
|
+
# print("ustat", u_stat)
|
|
178
|
+
# print("faktor", max(Impact.u)/u_stat )
|
|
179
|
+
|
|
180
|
+
v_train = 300/3.6
|
|
181
|
+
l_up = 25
|
|
182
|
+
f_train = v_train / l_up
|
|
183
|
+
E = 2.1e11
|
|
184
|
+
I = 0.5
|
|
185
|
+
EI = E*I
|
|
186
|
+
l = 60
|
|
187
|
+
f = l**3/(48 * EI)
|
|
188
|
+
m = 0.5 * l * 5160
|
|
189
|
+
|
|
190
|
+
t_cal = 10
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
TrainPassing = DuhamelSolver(1/f, m , 0.0257, 0.001, t_cal, loading = "trainpassing", parameters = [f_train,v_train,0,l], m2_imp = 100)
|
|
194
|
+
TrainPassing.plot_solution()
|
|
195
|
+
|
|
196
|
+
# print("time for passing in [s]", (60+393.7) / v_train)
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
Schwingung = Balkenschwingungen(l, 1, 5063, 0.0257, E, I, t_cal,"Hinged-Hinged",None,l/2,300)
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
fig,axes = plt.subplots(nrows = 3, ncols=1)
|
|
204
|
+
|
|
205
|
+
axes[0].plot(TrainPassing._time,TrainPassing.u, label = "Deflection SDOF")
|
|
206
|
+
axes[0].plot(Schwingung.t,Schwingung.y, label = "Deflection continuum")
|
|
207
|
+
axes[0].set_ylabel("Deflection in [m]")
|
|
208
|
+
axes[1].plot(TrainPassing.time_v_a, TrainPassing.vel, label = "Velocity SDOF")
|
|
209
|
+
axes[1].plot(Schwingung.t,Schwingung.v, label = "Velocity continuum")
|
|
210
|
+
axes[1].set_ylabel("Velocity in [m/s]")
|
|
211
|
+
axes[2].plot(TrainPassing.time_v_a, TrainPassing.acc, label = "Acceleration SDOF")
|
|
212
|
+
axes[2].plot(Schwingung.t,Schwingung.a, label = "Acceleration continuum")
|
|
213
|
+
axes[2].set_ylabel("Acceleration in [m/s²]")
|
|
214
|
+
fig.suptitle("Vibrations with the Duhamel integral and continuum")
|
|
215
|
+
|
|
216
|
+
plt.xlabel('Time in [s]')
|
|
217
|
+
plt.tight_layout()
|
|
218
|
+
plt.grid(True)
|
|
219
|
+
plt.show(block = False)
|
|
220
|
+
plt.pause(10)
|
|
221
|
+
plt.close()
|
KIB_LAP/Dynamik/FFT.py
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
class FFTAnalyzer:
|
|
4
|
+
def __init__(self, t: np.ndarray, y: np.ndarray, window: str = None):
|
|
5
|
+
"""
|
|
6
|
+
Parameters
|
|
7
|
+
----------
|
|
8
|
+
t : np.ndarray
|
|
9
|
+
Time array (must be uniformly spaced).
|
|
10
|
+
y : np.ndarray
|
|
11
|
+
Signal array, same length as t.
|
|
12
|
+
window : str or None
|
|
13
|
+
If not None, must be one of np’s window functions, e.g. 'hann','hamming','blackman'.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
# sampling
|
|
17
|
+
dt = t[1] - t[0]
|
|
18
|
+
if not np.allclose(np.diff(t), dt, rtol=1e-5, atol=1e-8):
|
|
19
|
+
raise ValueError("t must be uniformly spaced")
|
|
20
|
+
self.fs = 1.0 / dt
|
|
21
|
+
self.N = len(t)
|
|
22
|
+
self._t = t
|
|
23
|
+
self._y = y
|
|
24
|
+
# window
|
|
25
|
+
if window is not None:
|
|
26
|
+
try:
|
|
27
|
+
win = getattr(np, window)(self.N)
|
|
28
|
+
except AttributeError:
|
|
29
|
+
raise ValueError(f"Unknown window '{window}'")
|
|
30
|
+
else:
|
|
31
|
+
win = np.ones(self.N)
|
|
32
|
+
self._y_win = y * win
|
|
33
|
+
|
|
34
|
+
# placeholders
|
|
35
|
+
self.freqs = None
|
|
36
|
+
self.amp = None
|
|
37
|
+
self.phase = None
|
|
38
|
+
self._computed = False
|
|
39
|
+
|
|
40
|
+
def compute(self):
|
|
41
|
+
"""Compute the one-sided FFT, filling freqs, amp, phase."""
|
|
42
|
+
# full FFT
|
|
43
|
+
Y = np.fft.rfft(self._y_win)
|
|
44
|
+
# frequencies
|
|
45
|
+
self.freqs = np.fft.rfftfreq(self.N, d=1/self.fs)
|
|
46
|
+
# amplitude correction (accounting for window & symmetry)
|
|
47
|
+
# multiply by 2/N (except DC and Nyquist if present)
|
|
48
|
+
A = np.abs(Y) * 2.0 / self.N
|
|
49
|
+
A[0] /= 2.0
|
|
50
|
+
if self.N % 2 == 0: # Nyquist freq at end
|
|
51
|
+
A[-1] /= 2.0
|
|
52
|
+
self.amp = A
|
|
53
|
+
# phase
|
|
54
|
+
self.phase = np.angle(Y)
|
|
55
|
+
self._computed = True
|
|
56
|
+
return self.freqs, self.amp, self.phase
|
|
57
|
+
|
|
58
|
+
def plot(self, ax=None, xlim=None):
|
|
59
|
+
"""
|
|
60
|
+
Quick plot of amplitude spectrum.
|
|
61
|
+
Returns (fig, ax).
|
|
62
|
+
|
|
63
|
+
Parameters
|
|
64
|
+
----------
|
|
65
|
+
ax : matplotlib.axes.Axes, optional
|
|
66
|
+
Axes to plot into. Wenn None, wird ein neues Figure/Axes‐Paar erzeugt.
|
|
67
|
+
xlim : tuple of float (xmin, xmax), optional
|
|
68
|
+
Frequenzbereich in Hz für die x‐Achse.
|
|
69
|
+
"""
|
|
70
|
+
import matplotlib.pyplot as plt
|
|
71
|
+
if not self._computed:
|
|
72
|
+
self.compute()
|
|
73
|
+
if ax is None:
|
|
74
|
+
fig, ax = plt.subplots()
|
|
75
|
+
else:
|
|
76
|
+
fig = ax.figure
|
|
77
|
+
|
|
78
|
+
ax.plot(self.freqs, self.amp)
|
|
79
|
+
ax.set_xlabel("Frequency [Hz]")
|
|
80
|
+
ax.set_ylabel("Amplitude")
|
|
81
|
+
ax.grid(True)
|
|
82
|
+
|
|
83
|
+
if xlim is not None:
|
|
84
|
+
ax.set_xlim(xlim)
|
|
85
|
+
|
|
86
|
+
return fig, ax
|
|
87
|
+
|