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,587 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
from scipy.linalg import eigh
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class DeformationMethod:
|
|
6
|
+
def __init__(
|
|
7
|
+
self,
|
|
8
|
+
num_input,
|
|
9
|
+
E_inp=1,
|
|
10
|
+
I_inp=1,
|
|
11
|
+
A_inp=1,
|
|
12
|
+
rho_inp=1,
|
|
13
|
+
l_inp=1,
|
|
14
|
+
static_inp="SPG",
|
|
15
|
+
l_inp_multi=[1, 1],
|
|
16
|
+
_num_integral = 1000
|
|
17
|
+
):
|
|
18
|
+
"""_summary_
|
|
19
|
+
|
|
20
|
+
Args:
|
|
21
|
+
num_input (_type_): _description_
|
|
22
|
+
E_inp (int, optional): _description_. Defaults to 1.
|
|
23
|
+
I_inp (int, optional): _description_. Defaults to 1.
|
|
24
|
+
A_inp (int, optional): _description_. Defaults to 1.
|
|
25
|
+
rho_inp (int, optional): _description_. Defaults to 1.
|
|
26
|
+
l_inp (int, optional): _description_. Defaults to 1.
|
|
27
|
+
static_inp (str, optional): _description_. Defaults to "SPG".
|
|
28
|
+
l_inp_multi (list, optional): _description_. Defaults to [1,1]. First Value: Multispan in [m] and Second value:
|
|
29
|
+
"""
|
|
30
|
+
self.statical_system = static_inp
|
|
31
|
+
self.input_discret = num_input
|
|
32
|
+
self.E = E_inp
|
|
33
|
+
self.I = I_inp
|
|
34
|
+
self.A = A_inp
|
|
35
|
+
self.l = l_inp
|
|
36
|
+
self.rho = rho_inp
|
|
37
|
+
|
|
38
|
+
self.l_2 = l_inp_multi[0]
|
|
39
|
+
|
|
40
|
+
self.absorber_node = []
|
|
41
|
+
self.absorber_mass = []
|
|
42
|
+
self.absorber_stiffness = []
|
|
43
|
+
|
|
44
|
+
self.num_integral = _num_integral # Check for the required accuracy:
|
|
45
|
+
self.f_s = 1 / 10000
|
|
46
|
+
|
|
47
|
+
# Length vector for numerical integration
|
|
48
|
+
|
|
49
|
+
self.length = [
|
|
50
|
+
self.l / self.num_integral * i for i in range(self.num_integral + 1)
|
|
51
|
+
]
|
|
52
|
+
|
|
53
|
+
self.length_2 = [
|
|
54
|
+
self.l_2 / self.num_integral * i for i in range(self.num_integral + 1)
|
|
55
|
+
]
|
|
56
|
+
|
|
57
|
+
def calculation_params_spg(self):
|
|
58
|
+
self.xi = [
|
|
59
|
+
(i + 1) / (self.input_discret + 1) for i in range(self.input_discret)
|
|
60
|
+
]
|
|
61
|
+
self.m_moment = np.zeros((self.num_integral, self.input_discret))
|
|
62
|
+
|
|
63
|
+
for col in range(self.input_discret):
|
|
64
|
+
for row in range(self.num_integral):
|
|
65
|
+
A_Bearing = 1 - self.xi[col]
|
|
66
|
+
B_Bearing = self.xi[col]
|
|
67
|
+
if row <= self.xi[col] * (self.num_integral):
|
|
68
|
+
self.m_moment[row][col] = (
|
|
69
|
+
A_Bearing * row / self.num_integral * self.l
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
else:
|
|
73
|
+
self.m_moment[row][col] = (
|
|
74
|
+
A_Bearing * row / self.num_integral * self.l
|
|
75
|
+
- (row / self.num_integral - self.xi[col]) * self.l
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
def calculation_params_ctb(self):
|
|
79
|
+
self.xi = [(i + 1) / self.input_discret for i in range(self.input_discret)]
|
|
80
|
+
self.m_moment = np.zeros((self.num_integral, self.input_discret))
|
|
81
|
+
|
|
82
|
+
for col in range(self.input_discret):
|
|
83
|
+
for row in range(self.num_integral):
|
|
84
|
+
A_Bearing = 1
|
|
85
|
+
M_Bearing = self.xi[col] * self.l * A_Bearing
|
|
86
|
+
if row <= int(self.xi[col] * self.num_integral):
|
|
87
|
+
self.m_moment[row][col] = (
|
|
88
|
+
M_Bearing - A_Bearing * row / self.num_integral * self.l
|
|
89
|
+
)
|
|
90
|
+
else:
|
|
91
|
+
self.m_moment[row][col] = 0
|
|
92
|
+
self.length = [
|
|
93
|
+
self.l / self.num_integral * i for i in range(self.num_integral + 1)
|
|
94
|
+
]
|
|
95
|
+
|
|
96
|
+
def calculation_params_two_span_girder(self):
|
|
97
|
+
## Calculating the M0-Moment-Curve for discrete single loads at each point
|
|
98
|
+
self.xi = [
|
|
99
|
+
(i + 1) / (self.input_discret + 1) for i in range(self.input_discret)
|
|
100
|
+
]
|
|
101
|
+
self.m_moment_0 = np.zeros((self.num_integral + 1, self.input_discret))
|
|
102
|
+
self.m_moment_1 = np.zeros(
|
|
103
|
+
self.num_integral + 1
|
|
104
|
+
) # valid, if the bearing of the two-span girder is in the middle of the bridge (Usually fullfilled)
|
|
105
|
+
self.m_moment = np.zeros((self.num_integral + 1, self.input_discret))
|
|
106
|
+
|
|
107
|
+
for col in range(self.input_discret):
|
|
108
|
+
for row in range(self.num_integral + 1):
|
|
109
|
+
A_Bearing = 1 - self.xi[col]
|
|
110
|
+
B_Bearing = self.xi[col]
|
|
111
|
+
if row <= self.xi[col] * self.num_integral:
|
|
112
|
+
self.m_moment_0[row][col] = (
|
|
113
|
+
A_Bearing * row / self.num_integral * self.l
|
|
114
|
+
)
|
|
115
|
+
else:
|
|
116
|
+
self.m_moment_0[row][col] = (
|
|
117
|
+
A_Bearing * row / self.num_integral * self.l
|
|
118
|
+
- (row / self.num_integral - self.xi[col]) * self.l
|
|
119
|
+
)
|
|
120
|
+
if col == 0:
|
|
121
|
+
if row <= (self.num_integral + 1) / 2:
|
|
122
|
+
self.m_moment_1[row] = -row / self.num_integral * self.l * 0.5
|
|
123
|
+
else:
|
|
124
|
+
self.m_moment_1[row] = (
|
|
125
|
+
-self.l / 4
|
|
126
|
+
+ (row - (self.num_integral) / 2)
|
|
127
|
+
/ self.num_integral
|
|
128
|
+
* self.l
|
|
129
|
+
* 0.5
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
self.m_moment_1[-1] = 0
|
|
133
|
+
self.length_0 = [
|
|
134
|
+
self.l / self.num_integral * i for i in range(self.num_integral)
|
|
135
|
+
]
|
|
136
|
+
|
|
137
|
+
## Calculation of the delta-coefficients
|
|
138
|
+
integral_11 = [
|
|
139
|
+
self.m_moment_1[i] * self.m_moment_1[i]
|
|
140
|
+
for i in range(0, len(self.m_moment_1), 1)
|
|
141
|
+
]
|
|
142
|
+
|
|
143
|
+
delta_11 = np.trapz(integral_11, self.length) * 1 / (self.E * self.I)
|
|
144
|
+
|
|
145
|
+
x1 = np.zeros(self.input_discret) # Statically indetermined
|
|
146
|
+
self.delta_10_mat = np.zeros(self.input_discret) # For testing purposes
|
|
147
|
+
|
|
148
|
+
for col in range(self.input_discret):
|
|
149
|
+
m_moment_inte = np.zeros(self.num_integral + 1)
|
|
150
|
+
for i in range(self.num_integral + 1):
|
|
151
|
+
m_moment_inte[i] = self.m_moment_0[i][col]
|
|
152
|
+
|
|
153
|
+
integrant_10 = m_moment_inte * self.m_moment_1
|
|
154
|
+
delta_10 = np.trapz(integrant_10, self.length) * 1 / (self.E * self.I)
|
|
155
|
+
|
|
156
|
+
self.delta_10_mat[col] = delta_10
|
|
157
|
+
x1[col] = -delta_10 / delta_11
|
|
158
|
+
|
|
159
|
+
for i in range(self.num_integral + 1):
|
|
160
|
+
self.m_moment[i][col] = (
|
|
161
|
+
self.m_moment_0[i][col] + x1[col] * self.m_moment_1[i]
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
def calculation_params_two_span_girder_SPG(self):
|
|
165
|
+
## Calculating the M0-Moment-Curve for discrete single loads at each point
|
|
166
|
+
self.xi = [
|
|
167
|
+
(i + 1) / (self.input_discret + 1) for i in range(self.input_discret)
|
|
168
|
+
]
|
|
169
|
+
self.m_moment_0_1 = np.zeros(
|
|
170
|
+
(self.num_integral + 1, self.input_discret)
|
|
171
|
+
) # First statically determined part system
|
|
172
|
+
self.m_moment_0_2 = np.zeros(
|
|
173
|
+
(self.num_integral + 1, self.input_discret)
|
|
174
|
+
) # Second statically determined part system
|
|
175
|
+
|
|
176
|
+
self.m_moment_1_1 = np.zeros(self.num_integral + 1)
|
|
177
|
+
self.m_moment_1_2 = np.zeros(self.num_integral + 1)
|
|
178
|
+
|
|
179
|
+
self.m_moment = np.zeros(((self.num_integral + 1) * 2, self.input_discret * 2))
|
|
180
|
+
|
|
181
|
+
# Calulating the moment-curves for the first span
|
|
182
|
+
|
|
183
|
+
for col in range(self.input_discret):
|
|
184
|
+
for row in range(self.num_integral + 1):
|
|
185
|
+
A_Bearing = 1 - self.xi[col]
|
|
186
|
+
B_Bearing = self.xi[col]
|
|
187
|
+
if row <= self.xi[col] * self.num_integral:
|
|
188
|
+
self.m_moment_0_1[row][col] = (
|
|
189
|
+
A_Bearing * row / self.num_integral * self.l
|
|
190
|
+
)
|
|
191
|
+
else:
|
|
192
|
+
self.m_moment_0_1[row][col] = (
|
|
193
|
+
A_Bearing * row / self.num_integral * self.l
|
|
194
|
+
- (row / self.num_integral - self.xi[col]) * self.l
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
if col == 0:
|
|
198
|
+
self.m_moment_1_1[row] = -row / self.num_integral * self.l * 1 / self.l
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
# Calculating the moment curves for the second span
|
|
202
|
+
|
|
203
|
+
# Calculating the moment-curves for the second span
|
|
204
|
+
for col in range(self.input_discret):
|
|
205
|
+
for row in range(self.num_integral + 1):
|
|
206
|
+
A_Bearing = 1 - self.xi[col]
|
|
207
|
+
B_Bearing = self.xi[col]
|
|
208
|
+
if row <= self.xi[col] * self.num_integral:
|
|
209
|
+
self.m_moment_0_2[row][col] = (
|
|
210
|
+
A_Bearing * row / self.num_integral * self.l_2
|
|
211
|
+
)
|
|
212
|
+
else:
|
|
213
|
+
self.m_moment_0_2[row][col] = (
|
|
214
|
+
A_Bearing * row / self.num_integral * self.l_2
|
|
215
|
+
- (row / self.num_integral - self.xi[col]) * self.l_2
|
|
216
|
+
)
|
|
217
|
+
|
|
218
|
+
if col == 0:
|
|
219
|
+
self.m_moment_1_2[row] = (
|
|
220
|
+
-1 + row / self.num_integral * self.l_2 * 1 / self.l_2
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
# Calculating the influence number for delta_11
|
|
225
|
+
|
|
226
|
+
integral_11_1 = [
|
|
227
|
+
self.m_moment_1_1[i] * self.m_moment_1_1[i]
|
|
228
|
+
for i in range(0, len(self.m_moment_1_1), 1)
|
|
229
|
+
]
|
|
230
|
+
|
|
231
|
+
delta_11_1 = np.trapz(integral_11_1, self.length) * 1 / (self.E * self.I)
|
|
232
|
+
|
|
233
|
+
integral_11_2 = [
|
|
234
|
+
self.m_moment_1_2[i] * self.m_moment_1_2[i]
|
|
235
|
+
for i in range(0, len(self.m_moment_1_2), 1)
|
|
236
|
+
]
|
|
237
|
+
|
|
238
|
+
delta_11_2 = np.trapz(integral_11_2, self.length_2) * 1 / (self.E * self.I)
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
# Calulating the influence number for delta_10 for the first span
|
|
242
|
+
|
|
243
|
+
x1 = np.zeros(self.input_discret) # Statically indetermined moment an the middle bearing
|
|
244
|
+
|
|
245
|
+
for col in range(self.input_discret):
|
|
246
|
+
m_moment_inte_1 = np.zeros(self.num_integral + 1)
|
|
247
|
+
m_moment_inte_2 = np.zeros(self.num_integral + 1)
|
|
248
|
+
for i in range(self.num_integral + 1):
|
|
249
|
+
m_moment_inte_1[i] = self.m_moment_0_1[i][col]
|
|
250
|
+
m_moment_inte_2[i] = self.m_moment_0_2[i][col]
|
|
251
|
+
|
|
252
|
+
integrant_10_1 = m_moment_inte_1 * self.m_moment_1_1
|
|
253
|
+
delta_10_1 = np.trapz(integrant_10_1, self.length) * 1 / (self.E * self.I)
|
|
254
|
+
|
|
255
|
+
# print("Statically determined moment")
|
|
256
|
+
# print(self.m_moment_0_1)
|
|
257
|
+
# print("Virtual Moment - 1")
|
|
258
|
+
# print(self.m_moment_1_1)
|
|
259
|
+
# print("Virtual Moment - 2")
|
|
260
|
+
# print(self.m_moment_1_2)
|
|
261
|
+
|
|
262
|
+
# print("delta 10 ")
|
|
263
|
+
|
|
264
|
+
# print(delta_10_1)
|
|
265
|
+
|
|
266
|
+
# print("delta 11")
|
|
267
|
+
|
|
268
|
+
# print(delta_11_1 + delta_11_2)
|
|
269
|
+
|
|
270
|
+
x1[col] = -(delta_10_1 / (delta_11_1 + delta_11_2))
|
|
271
|
+
|
|
272
|
+
# print(x1)
|
|
273
|
+
|
|
274
|
+
# Integration result for the first span
|
|
275
|
+
|
|
276
|
+
for i in range(self.num_integral + 1):
|
|
277
|
+
self.m_moment[i][col] = (
|
|
278
|
+
self.m_moment_0_1[i][col] + x1[col] * self.m_moment_1_1[i]
|
|
279
|
+
)
|
|
280
|
+
|
|
281
|
+
# Integration result for the second span
|
|
282
|
+
|
|
283
|
+
for i in range(self.num_integral + 1, (self.num_integral + 1) * 2):
|
|
284
|
+
self.m_moment[i][col] = (
|
|
285
|
+
0 + x1[col] * self.m_moment_1_2[int(i-(self.num_integral + 1))]
|
|
286
|
+
)
|
|
287
|
+
|
|
288
|
+
# Calculating the influence number for delta_10 for the second span
|
|
289
|
+
x1 = np.zeros(self.input_discret) # Statically indetermined moment an the middle bearing
|
|
290
|
+
|
|
291
|
+
for col in range(self.input_discret,self.input_discret*2):
|
|
292
|
+
m_moment_inte_1 = np.zeros(self.num_integral + 1)
|
|
293
|
+
m_moment_inte_2 = np.zeros(self.num_integral + 1)
|
|
294
|
+
for i in range(self.num_integral + 1):
|
|
295
|
+
m_moment_inte_2[i] = self.m_moment_0_2[i][int(col-self.input_discret)]
|
|
296
|
+
|
|
297
|
+
integrant_10_2 = m_moment_inte_2 * self.m_moment_1_2
|
|
298
|
+
delta_10_2 = np.trapz(integrant_10_2, self.length_2) * 1 / (self.E * self.I)
|
|
299
|
+
|
|
300
|
+
# print("Statically determined moment")
|
|
301
|
+
# print(self.m_moment_0_2)
|
|
302
|
+
# print("Virtual Moment - 1")
|
|
303
|
+
# print(self.m_moment_1_1)
|
|
304
|
+
# print("Virtual Moment - 2")
|
|
305
|
+
# print(self.m_moment_1_2)
|
|
306
|
+
|
|
307
|
+
# print("delta 10 ")
|
|
308
|
+
|
|
309
|
+
# print(delta_10_2)
|
|
310
|
+
|
|
311
|
+
# print("delta 11")
|
|
312
|
+
|
|
313
|
+
# print(delta_11_1 + delta_11_2)
|
|
314
|
+
|
|
315
|
+
x1[int(col-self.input_discret)] = -(delta_10_2 / (delta_11_1 + delta_11_2))
|
|
316
|
+
|
|
317
|
+
# print(x1)
|
|
318
|
+
|
|
319
|
+
# Integration result for the first span
|
|
320
|
+
|
|
321
|
+
for i in range(self.num_integral + 1):
|
|
322
|
+
self.m_moment[i][col] = (
|
|
323
|
+
x1[int(col-self.input_discret)] * self.m_moment_1_1[i]
|
|
324
|
+
)
|
|
325
|
+
|
|
326
|
+
# Integration result for the second span
|
|
327
|
+
|
|
328
|
+
for i in range(self.num_integral + 1, (self.num_integral+1) * 2):
|
|
329
|
+
self.m_moment[i][col] = (
|
|
330
|
+
self.m_moment_0_2[i-(self.num_integral + 1)][int(col-self.input_discret)] + x1[int(col-self.input_discret)] * self.m_moment_1_2[int(i-(self.num_integral + 1))]
|
|
331
|
+
)
|
|
332
|
+
|
|
333
|
+
def mass_matrix(self):
|
|
334
|
+
if (self.statical_system == "TSG_H"):
|
|
335
|
+
self.M_matrix = np.zeros(
|
|
336
|
+
(
|
|
337
|
+
self.input_discret*2 + len(self.absorber_node),
|
|
338
|
+
self.input_discret*2 + len(self.absorber_node),
|
|
339
|
+
)
|
|
340
|
+
)
|
|
341
|
+
|
|
342
|
+
m_i_1 = self.rho * self.l * self.A / (self.input_discret + 1)
|
|
343
|
+
m_i_2 = self.rho * self.l_2 * self.A / (self.input_discret + 1)
|
|
344
|
+
|
|
345
|
+
for row in range(self.input_discret):
|
|
346
|
+
self.M_matrix[row][row] = m_i_1
|
|
347
|
+
self.M_matrix[row+self.input_discret][row+self.input_discret] = m_i_2
|
|
348
|
+
|
|
349
|
+
for row in range(len(self.absorber_node)):
|
|
350
|
+
self.M_matrix[row + self.input_discret*2][
|
|
351
|
+
row + self.input_discret * 2
|
|
352
|
+
] = self.absorber_mass[row]
|
|
353
|
+
|
|
354
|
+
else:
|
|
355
|
+
self.M_matrix = np.zeros(
|
|
356
|
+
(
|
|
357
|
+
self.input_discret + len(self.absorber_node),
|
|
358
|
+
self.input_discret + len(self.absorber_node),
|
|
359
|
+
)
|
|
360
|
+
)
|
|
361
|
+
m_i = self.rho * self.l * self.A / (self.input_discret + 1)
|
|
362
|
+
|
|
363
|
+
for row in range(self.input_discret):
|
|
364
|
+
self.M_matrix[row][row] = m_i
|
|
365
|
+
|
|
366
|
+
for row in range(len(self.absorber_node)):
|
|
367
|
+
self.M_matrix[row + self.input_discret][
|
|
368
|
+
row + self.input_discret
|
|
369
|
+
] = self.absorber_mass[row]
|
|
370
|
+
|
|
371
|
+
def single_span_girder(self):
|
|
372
|
+
self.mass_matrix()
|
|
373
|
+
EI = self.E * self.I
|
|
374
|
+
self.calculation_params_spg()
|
|
375
|
+
integral = np.zeros(self.num_integral+1)
|
|
376
|
+
self.delta_i = np.zeros((self.input_discret, self.input_discret))
|
|
377
|
+
|
|
378
|
+
for row in range(self.input_discret):
|
|
379
|
+
for col in range(self.input_discret):
|
|
380
|
+
for i in range(self.m_moment.shape[0]):
|
|
381
|
+
integral[i] = self.m_moment[i][row] * self.m_moment[i][col]
|
|
382
|
+
self.delta_i[row][col] = (1 / EI) * np.trapz(integral, self.length)
|
|
383
|
+
|
|
384
|
+
self.K_matrix = np.linalg.inv(self.delta_i)
|
|
385
|
+
|
|
386
|
+
def cantilever_beam(self):
|
|
387
|
+
self.mass_matrix()
|
|
388
|
+
EI = self.E * self.I
|
|
389
|
+
self.calculation_params_ctb()
|
|
390
|
+
integral = np.zeros(self.num_integral+1)
|
|
391
|
+
self.delta_i = np.zeros((self.input_discret, self.input_discret))
|
|
392
|
+
|
|
393
|
+
for row in range(self.input_discret):
|
|
394
|
+
for col in range(self.input_discret):
|
|
395
|
+
for i in range(self.m_moment.shape[0]):
|
|
396
|
+
integral[i] = self.m_moment[i][row] * self.m_moment[i][col]
|
|
397
|
+
self.delta_i[row][col] = (1 / EI) * np.trapz(integral, self.length)
|
|
398
|
+
|
|
399
|
+
self.K_matrix = np.linalg.inv(self.delta_i)
|
|
400
|
+
|
|
401
|
+
def two_span_girder(self):
|
|
402
|
+
self.mass_matrix()
|
|
403
|
+
EI = self.E * self.I
|
|
404
|
+
self.calculation_params_two_span_girder()
|
|
405
|
+
|
|
406
|
+
integral = np.zeros(self.num_integral + 1)
|
|
407
|
+
self.delta_i = np.zeros((self.input_discret, self.input_discret))
|
|
408
|
+
|
|
409
|
+
for row in range(self.input_discret):
|
|
410
|
+
for col in range(self.input_discret):
|
|
411
|
+
for i in range(self.m_moment.shape[0]):
|
|
412
|
+
integral[i] = (
|
|
413
|
+
self.m_moment[i][row] * self.m_moment_0[i][col]
|
|
414
|
+
) # m_moment_0 ->
|
|
415
|
+
# Virtual moment at the statically determined system
|
|
416
|
+
# Virtual moment is equal to the moment_0
|
|
417
|
+
self.delta_i[row][col] = (1 / EI) * np.trapz(integral, self.length)
|
|
418
|
+
|
|
419
|
+
# Define your threshold for deflection values below which rows and columns are removed
|
|
420
|
+
|
|
421
|
+
threshold = 1e-15
|
|
422
|
+
|
|
423
|
+
# Calculate the absolute values of the matrices
|
|
424
|
+
abs_GSM = np.abs(self.delta_i)
|
|
425
|
+
abs_GMM = np.abs(self.M_matrix)
|
|
426
|
+
|
|
427
|
+
# Create masks to identify rows and columns with values above the threshold
|
|
428
|
+
rows_to_keep_GSM = np.any(abs_GSM >= threshold, axis=1)
|
|
429
|
+
cols_to_keep_GSM = np.any(abs_GSM >= threshold, axis=0)
|
|
430
|
+
|
|
431
|
+
# Perform row reduction based on the threshold for the global stiffness matrix
|
|
432
|
+
rrgsm = self.delta_i[rows_to_keep_GSM]
|
|
433
|
+
crgsm = rrgsm[:, cols_to_keep_GSM]
|
|
434
|
+
self.delta_i = crgsm
|
|
435
|
+
|
|
436
|
+
# Perform row reduction based on the threshold for the global mass matrix
|
|
437
|
+
rgmm = self.M_matrix[rows_to_keep_GSM]
|
|
438
|
+
crgmm = rgmm[:, cols_to_keep_GSM]
|
|
439
|
+
self.M_matrix = crgmm
|
|
440
|
+
|
|
441
|
+
self.K_matrix = np.linalg.inv(self.delta_i)
|
|
442
|
+
|
|
443
|
+
|
|
444
|
+
def two_span_girder_hinged(self):
|
|
445
|
+
print("Two span girder with a hinge")
|
|
446
|
+
self.mass_matrix()
|
|
447
|
+
EI = self.E * self.I
|
|
448
|
+
self.calculation_params_two_span_girder_SPG()
|
|
449
|
+
|
|
450
|
+
integral_1 = np.zeros(self.num_integral + 1)
|
|
451
|
+
integral_2 = np.zeros(self.num_integral + 1)
|
|
452
|
+
|
|
453
|
+
self.delta_i = np.zeros((self.input_discret * 2, self.input_discret * 2))
|
|
454
|
+
|
|
455
|
+
for row in range(self.input_discret*2): # Corresponds to the loading node (Single load 1)
|
|
456
|
+
for col in range(self.input_discret*2): # Corresponds to the reaction node (Node, where the deflection is calculated (Virtual Moment!))
|
|
457
|
+
for i in range(int(self.m_moment.shape[0]/2)):
|
|
458
|
+
if (col < self.input_discret):
|
|
459
|
+
# Case 1: The deformations are calculated for the first n = self.input_discrete masses in the span 1
|
|
460
|
+
# Therefore the integral in the second span is zero, because the moment curves are decoupled due to the hinge
|
|
461
|
+
# in the midspan
|
|
462
|
+
integral_1[i] = (
|
|
463
|
+
self.m_moment[i][row] * self.m_moment_0_1[i][col-self.input_discret]
|
|
464
|
+
)
|
|
465
|
+
integral_2[i] = (
|
|
466
|
+
self.m_moment[i+int(self.m_moment.shape[0]/2)][row] * 0
|
|
467
|
+
)
|
|
468
|
+
else:
|
|
469
|
+
# Case 2: The deformations are calculated for the second n = self.input_discrete masses in the span 2
|
|
470
|
+
# Therefore the integral in the first span is zero, because the moment curves are decoupled due to the hinge
|
|
471
|
+
# in the midspan.
|
|
472
|
+
integral_1[i] = (
|
|
473
|
+
self.m_moment[i][row] * 0
|
|
474
|
+
)
|
|
475
|
+
integral_2[i] = (
|
|
476
|
+
self.m_moment[i+int(self.m_moment.shape[0]/2)][row] *self.m_moment_0_2[i][col-self.input_discret]
|
|
477
|
+
)
|
|
478
|
+
|
|
479
|
+
# print(self.m_moment[i+int(self.m_moment.shape[0]/2)][row])
|
|
480
|
+
|
|
481
|
+
self.delta_i[row][col] = (1 / EI) * (np.trapz(integral_1, self.length) + np.trapz(integral_2, self.length_2) )
|
|
482
|
+
|
|
483
|
+
|
|
484
|
+
|
|
485
|
+
self.K_matrix = np.linalg.inv(self.delta_i)
|
|
486
|
+
|
|
487
|
+
def compute_eigenfrequencies(self):
|
|
488
|
+
try:
|
|
489
|
+
eigenvalues, eigenvectors = eigh(self.K_matrix, self.M_matrix, subset_by_index=(0, 20 - 1))
|
|
490
|
+
except:
|
|
491
|
+
eigenvalues, eigenvectors = eigh(self.K_matrix, self.M_matrix) # Eigenvalues with Number of DOFS below 20
|
|
492
|
+
|
|
493
|
+
num_eigenval = len(eigenvalues)
|
|
494
|
+
|
|
495
|
+
self.eigenfrequencies = np.sqrt(np.abs(eigenvalues))
|
|
496
|
+
|
|
497
|
+
normalized_modes = eigenvectors / np.abs(eigenvectors).max(axis=0)
|
|
498
|
+
|
|
499
|
+
self.eigenmodes_matrix_storage = normalized_modes
|
|
500
|
+
|
|
501
|
+
self.eigenmodes_matrix = normalized_modes
|
|
502
|
+
|
|
503
|
+
|
|
504
|
+
num_rows, num_columns = self.eigenmodes_matrix.shape
|
|
505
|
+
|
|
506
|
+
# Define the number of zeros to add at the beginning and end of each column
|
|
507
|
+
num_zeros = 1 # You want to add one zero at each end
|
|
508
|
+
|
|
509
|
+
# Create a new matrix with the desired structure
|
|
510
|
+
new_num_rows = num_rows + 2 * num_zeros # Calculate the new number of rows
|
|
511
|
+
new_matrix = np.zeros((new_num_rows, num_columns)) # Initialize a new matrix with zeros
|
|
512
|
+
|
|
513
|
+
# Copy the original matrix into the center of the new matrix
|
|
514
|
+
new_matrix[num_zeros:num_zeros + num_rows, :] = self.eigenmodes_matrix
|
|
515
|
+
|
|
516
|
+
self.eigenmodes_matrix = new_matrix
|
|
517
|
+
|
|
518
|
+
if self.statical_system == "TSG_H": # Adding a zero deflection point, because of the vertical bearing
|
|
519
|
+
|
|
520
|
+
new_num_rows = self.eigenmodes_matrix.shape[0] + 1 # Calculate the new number of rows
|
|
521
|
+
new_matrix = np.zeros((new_num_rows, num_columns)) # Initialize a new matrix with zeros
|
|
522
|
+
|
|
523
|
+
# Copy the first half of the original matrix between the first row and the middle row
|
|
524
|
+
for row in range(0, 1 + self.input_discret):
|
|
525
|
+
for col in range(num_eigenval):
|
|
526
|
+
new_matrix[row][col] = self.eigenmodes_matrix[row][col]
|
|
527
|
+
try:
|
|
528
|
+
for row in range(1 + self.input_discret, self.input_discret*2+3):
|
|
529
|
+
print(row)
|
|
530
|
+
for col in range(num_eigenval):
|
|
531
|
+
new_matrix[row+1][col] = self.eigenmodes_matrix[row][col]
|
|
532
|
+
except:
|
|
533
|
+
pass
|
|
534
|
+
|
|
535
|
+
for row in range(1 + self.input_discret, self.input_discret*2+2):
|
|
536
|
+
print(row)
|
|
537
|
+
for col in range(num_eigenval):
|
|
538
|
+
new_matrix[row+1][col] = self.eigenmodes_matrix[row][col]
|
|
539
|
+
|
|
540
|
+
|
|
541
|
+
self.eigenmodes_matrix = new_matrix
|
|
542
|
+
|
|
543
|
+
# Length-Vector for the whole structure
|
|
544
|
+
|
|
545
|
+
self.len_plotting = np.zeros(2*self.input_discret+3)
|
|
546
|
+
|
|
547
|
+
for i in range(0,self.input_discret+1,1):
|
|
548
|
+
self.len_plotting[i] = self.l / (self.input_discret+1) * i
|
|
549
|
+
|
|
550
|
+
self.len_plotting[self.input_discret+1] = self.l
|
|
551
|
+
|
|
552
|
+
for i in range(0,self.input_discret+1,1):
|
|
553
|
+
self.len_plotting[i+self.input_discret+2] = self.l + self.l_2 / (self.input_discret+1) * (i+1)
|
|
554
|
+
|
|
555
|
+
|
|
556
|
+
else:
|
|
557
|
+
# Length-Vector for the whole structure
|
|
558
|
+
self.len_plotting = np.zeros(self.input_discret+2)
|
|
559
|
+
|
|
560
|
+
for i in range(0, self.input_discret+1, 1):
|
|
561
|
+
self.len_plotting[i] = self.l / (self.input_discret+1) * i
|
|
562
|
+
|
|
563
|
+
self.len_plotting[self.input_discret+1] = self.l
|
|
564
|
+
|
|
565
|
+
|
|
566
|
+
return self.eigenfrequencies, self.eigenmodes_matrix
|
|
567
|
+
|
|
568
|
+
|
|
569
|
+
def modal_matrices(self):
|
|
570
|
+
self.M_trans = np.dot(np.transpose(self.eigenmodes_matrix_storage),np.dot(self.M_matrix,self.eigenmodes_matrix_storage))
|
|
571
|
+
self.K_trans = np.dot(np.transpose(self.eigenmodes_matrix_storage),np.dot(self.K_matrix,self.eigenmodes_matrix_storage))
|
|
572
|
+
|
|
573
|
+
|
|
574
|
+
def print_modes_matrix(self):
|
|
575
|
+
print("Circular eigenfrequencies")
|
|
576
|
+
print(self.eigenfrequencies)
|
|
577
|
+
|
|
578
|
+
print("Eigenfrequencies")
|
|
579
|
+
|
|
580
|
+
print(self.eigenfrequencies / (2 * np.pi))
|
|
581
|
+
|
|
582
|
+
print("Normalized eigenmodes")
|
|
583
|
+
|
|
584
|
+
for row in self.eigenmodes_matrix:
|
|
585
|
+
formatted_row = ["{:.4f}".format(item) for item in row]
|
|
586
|
+
print(" | ".join(formatted_row))
|
|
587
|
+
print("-" * (len(formatted_row) * 8)) # Print dashes for clarity
|