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.
Files changed (64) hide show
  1. Examples/Cross_Section_Thin.py +61 -0
  2. Examples/__init__.py +0 -0
  3. KIB_LAP/Betonbau/Bemessung_Polygon.py +667 -0
  4. KIB_LAP/Betonbau/Bemessung_Zust_II.py +648 -0
  5. KIB_LAP/Betonbau/Cross_Section_Kappa.py +925 -0
  6. KIB_LAP/Betonbau/Druckglied_KGV.py +179 -0
  7. KIB_LAP/Betonbau/Iterative_Design.py +723 -0
  8. KIB_LAP/Betonbau/Materialkennwerte_Beton.py +196 -0
  9. KIB_LAP/Betonbau/Querschnittsbreite.py +194 -0
  10. KIB_LAP/Betonbau/Querschnittsbreite_Kreis.py +63 -0
  11. KIB_LAP/Betonbau/__init__.py +2 -0
  12. KIB_LAP/Betonbau/beam_plate_T.py +921 -0
  13. KIB_LAP/Betonbau/beam_plate_T_reverse.py +915 -0
  14. KIB_LAP/Betonbau/beam_rectangular.py +635 -0
  15. KIB_LAP/Betonbau/beam_sub_section.py +9 -0
  16. KIB_LAP/Dynamik/Cross_Section_Properties.py +155 -0
  17. KIB_LAP/Dynamik/Deformation_Method.py +587 -0
  18. KIB_LAP/Dynamik/Duhamel_SDOF.py +221 -0
  19. KIB_LAP/Dynamik/FFT.py +87 -0
  20. KIB_LAP/Dynamik/Kontinuum_Eigenmodes.py +418 -0
  21. KIB_LAP/Dynamik/Kontinuum_Schwingung.py +757 -0
  22. KIB_LAP/Dynamik/Pendulum_Spring_Linearized.py +91 -0
  23. KIB_LAP/Dynamik/Pendulum_Spring_Problem.py +94 -0
  24. KIB_LAP/Dynamik/__init__.py +0 -0
  25. KIB_LAP/Examples/Cross_Section_Thin.py +61 -0
  26. KIB_LAP/Examples/Cross_Section_Thin_2.py +14 -0
  27. KIB_LAP/Examples/Plattentragwerke.py +39 -0
  28. KIB_LAP/Examples/Plattentragwerke_2.py +60 -0
  29. KIB_LAP/Examples/ShearDesign.py +28 -0
  30. KIB_LAP/Examples/__init__.py +0 -0
  31. KIB_LAP/Plattenbeulen/Plate_Design.py +276 -0
  32. KIB_LAP/Plattenbeulen/Ritz_Optimiert.py +658 -0
  33. KIB_LAP/Plattenbeulen/__init__.py +2 -0
  34. KIB_LAP/Plattenbeulen/dist/__init__.py +0 -0
  35. KIB_LAP/Plattenbeulen/plate_buckling.cpp +561 -0
  36. KIB_LAP/Plattenbeulen/plate_buckling_cpp.cp313-win_amd64.pyd +0 -0
  37. KIB_LAP/Plattenbeulen/plate_buckling_cpp.cpp +561 -0
  38. KIB_LAP/Plattenbeulen/setup.py +35 -0
  39. KIB_LAP/Plattentragwerke/Functions.cpp +326 -0
  40. KIB_LAP/Plattentragwerke/Functions.h +41 -0
  41. KIB_LAP/Plattentragwerke/NumInte.cpp +23 -0
  42. KIB_LAP/Plattentragwerke/NumericalIntegration.cpp +23 -0
  43. KIB_LAP/Plattentragwerke/PlateBendingKirchhoff.py +843 -0
  44. KIB_LAP/Plattentragwerke/__init__.py +1 -0
  45. KIB_LAP/Plattentragwerke/plate_bending.cpp +341 -0
  46. KIB_LAP/Plattentragwerke/plate_bending_cpp.cp313-win_amd64.pyd +0 -0
  47. KIB_LAP/Plattentragwerke/setup.py +39 -0
  48. KIB_LAP/Querschnittswerte/Querschnitt_Duenn.py +526 -0
  49. KIB_LAP/Querschnittswerte/__init__.py +1 -0
  50. KIB_LAP/STABRAUM/InputData.py +92 -0
  51. KIB_LAP/STABRAUM/Programm.py +1403 -0
  52. KIB_LAP/STABRAUM/Steifigkeitsmatrix.py +275 -0
  53. KIB_LAP/STABRAUM/__init__.py +3 -0
  54. KIB_LAP/Stahlbau/__init__.py +0 -0
  55. KIB_LAP/Verbundbau/Verbundtraeger_Bemessung.py +766 -0
  56. KIB_LAP/Verbundbau/__init__.py +0 -0
  57. KIB_LAP/__init__.py +4 -0
  58. KIB_LAP/main.py +2 -0
  59. KIB_LAP/plate_bending_cpp.cp313-win_amd64.pyd +0 -0
  60. KIB_LAP/plate_buckling_cpp.cp313-win_amd64.pyd +0 -0
  61. kib_lap-0.5.dist-info/METADATA +25 -0
  62. kib_lap-0.5.dist-info/RECORD +64 -0
  63. kib_lap-0.5.dist-info/WHEEL +5 -0
  64. 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