kib-lap 0.5__cp313-cp313-win_amd64.whl → 0.7.7__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 (44) hide show
  1. KIB_LAP/Betonbau/TEST_Rectangular.py +21 -0
  2. KIB_LAP/Betonbau/beam_rectangular.py +4 -0
  3. KIB_LAP/FACHWERKEBEN/Elements.py +209 -0
  4. KIB_LAP/FACHWERKEBEN/InputData.py +118 -0
  5. KIB_LAP/FACHWERKEBEN/Iteration.py +967 -0
  6. KIB_LAP/FACHWERKEBEN/Materials.py +30 -0
  7. KIB_LAP/FACHWERKEBEN/Plotting.py +681 -0
  8. KIB_LAP/FACHWERKEBEN/__init__.py +4 -0
  9. KIB_LAP/FACHWERKEBEN/main.py +27 -0
  10. KIB_LAP/Plattentragwerke/PlateBendingKirchhoff.py +36 -29
  11. KIB_LAP/STABRAUM/InputData.py +13 -2
  12. KIB_LAP/STABRAUM/Output_Data.py +61 -0
  13. KIB_LAP/STABRAUM/Plotting.py +1453 -0
  14. KIB_LAP/STABRAUM/Programm.py +518 -1026
  15. KIB_LAP/STABRAUM/Steifigkeitsmatrix.py +338 -117
  16. KIB_LAP/STABRAUM/main.py +58 -0
  17. KIB_LAP/STABRAUM/results.py +37 -0
  18. KIB_LAP/Scheibe/Assemble_Stiffness.py +246 -0
  19. KIB_LAP/Scheibe/Element_Stiffness.py +362 -0
  20. KIB_LAP/Scheibe/Meshing.py +365 -0
  21. KIB_LAP/Scheibe/Output.py +34 -0
  22. KIB_LAP/Scheibe/Plotting.py +722 -0
  23. KIB_LAP/Scheibe/Shell_Calculation.py +523 -0
  24. KIB_LAP/Scheibe/Testing_Mesh.py +25 -0
  25. KIB_LAP/Scheibe/__init__.py +14 -0
  26. KIB_LAP/Scheibe/main.py +33 -0
  27. KIB_LAP/StabEbenRitz/Biegedrillknicken.py +757 -0
  28. KIB_LAP/StabEbenRitz/Biegedrillknicken_Trigeometry.py +328 -0
  29. KIB_LAP/StabEbenRitz/Querschnittswerte.py +527 -0
  30. KIB_LAP/StabEbenRitz/Stabberechnung_Klasse.py +868 -0
  31. KIB_LAP/plate_bending_cpp.cp313-win_amd64.pyd +0 -0
  32. KIB_LAP/plate_buckling_cpp.cp313-win_amd64.pyd +0 -0
  33. {kib_lap-0.5.dist-info → kib_lap-0.7.7.dist-info}/METADATA +1 -1
  34. {kib_lap-0.5.dist-info → kib_lap-0.7.7.dist-info}/RECORD +37 -19
  35. Examples/Cross_Section_Thin.py +0 -61
  36. KIB_LAP/Betonbau/Bemessung_Zust_II.py +0 -648
  37. KIB_LAP/Betonbau/Iterative_Design.py +0 -723
  38. KIB_LAP/Plattentragwerke/NumInte.cpp +0 -23
  39. KIB_LAP/Plattentragwerke/NumericalIntegration.cpp +0 -23
  40. KIB_LAP/Plattentragwerke/plate_bending_cpp.cp313-win_amd64.pyd +0 -0
  41. KIB_LAP/main.py +0 -2
  42. {Examples → KIB_LAP/StabEbenRitz}/__init__.py +0 -0
  43. {kib_lap-0.5.dist-info → kib_lap-0.7.7.dist-info}/WHEEL +0 -0
  44. {kib_lap-0.5.dist-info → kib_lap-0.7.7.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,868 @@
1
+ import numpy as np
2
+ from tabulate import tabulate
3
+ import matplotlib
4
+ from scipy.linalg import eig
5
+
6
+ # matplotlib.use('Agg') # Setzt das Agg Backend, das keine Fenster öffnet
7
+ import matplotlib.pyplot as plt
8
+
9
+ import pandas as pd
10
+ from Querschnittswerte import CrossSectionThin
11
+ import sys
12
+
13
+ from Biegedrillknicken_Trigeometry import Biegedrillknicken
14
+
15
+
16
+ class StabRitz:
17
+ def __init__(
18
+ self,
19
+ l_x,
20
+ x0,
21
+ x1,
22
+ p,
23
+ x0F,
24
+ F,
25
+ E,
26
+ I,
27
+ reihen=5,
28
+ load_input="file",
29
+ Ansatz="Polynom",
30
+ Knoten="Querschnittseingabe/Knoten_2.csv",
31
+ Elemente="Querschnittseingabe/Elemente_2.csv",
32
+ _c_bett_z=0,
33
+ ):
34
+ """
35
+
36
+ Args:
37
+ l_x (_type_): Spannweite des Trägers \n
38
+ x0 (_type_): Lasteinleitungsbegin Linienlast \n
39
+ x1 (_type_): Lasteinleitungsende Linienlast \n
40
+ p (_type_): Linienlast in [MN/m] \n
41
+ x0F (_type_): Lasteinleitungsbegin Einzellast \n
42
+ F (_type_): Einzellast in [MN] \n
43
+ E (_type_): E-Modul in [MN/m**2] \n
44
+ I (_type_): Flächenträgheitsmoment in [m**4] \n
45
+ reihen (int, optional): Anzahl der zu berücksichtigenden Reihen. Entspricht der Größe der \n
46
+ Matrix. Defaultwert ist 5.
47
+ """
48
+ self.l_x = l_x
49
+ self.list_lx = np.linspace(1e-5, self.l_x, 1000)
50
+
51
+ if Ansatz == "Fourier":
52
+ self.reihen = reihen
53
+ else:
54
+ self.BC = pd.DataFrame(pd.read_csv("Federeingabe/Federeingabe.csv"))
55
+
56
+ self.c_bett_z = _c_bett_z
57
+
58
+ # Estimate the required precision
59
+ self.precision = 1e-2
60
+ for i in self.BC["xi[-]"]:
61
+ i_prec = round(i * 1000, 0)
62
+ i_mod = int(i_prec % 10)
63
+
64
+ if i_mod == 0:
65
+ self.precision = 0.5e-1
66
+ else:
67
+ self.precision = 0.5e-1
68
+
69
+ self.reihen = int(1 / self.precision)
70
+
71
+ self.K = np.zeros((self.reihen, self.reihen))
72
+ self.P = np.zeros(self.reihen)
73
+
74
+ self.x0 = x0
75
+ self.x1 = x1
76
+ self.p = p
77
+
78
+ self.x0F = x0F
79
+ self.F = F
80
+
81
+ self.load_input = load_input
82
+ # Einlesen der Querschnittswerte über Python-Klasse
83
+ self.Querschnitt = CrossSectionThin(210000, 0.30, Knoten, Elemente)
84
+ self.Querschnitt.read_node_input()
85
+ self.Querschnitt.CalculateElementStiffness()
86
+ self.Querschnitt.Calculate_GesMat()
87
+ self.Querschnitt.SolverTorsion()
88
+ self.Querschnitt.CalculateAyzw()
89
+ self.Querschnitt.Update_SMP()
90
+ self.Querschnitt.Calculate_IwIt()
91
+ self.Querschnitt.Calculate_WoWu()
92
+ self.Querschnitt.Calculate_ShearStress_Vz()
93
+ self.Querschnitt.Calculate_imryrzrw()
94
+ self.I = self.Querschnitt.I_yy
95
+ self.EI = self.Querschnitt.E * self.I
96
+
97
+ self.CrossSection = "Konstant"
98
+
99
+ self.Ansatz = Ansatz
100
+
101
+ def function_I(self, x):
102
+ if self.CrossSection == "Linear":
103
+ if x < self.l_x / 2:
104
+ return self.I + x / (self.l_x) * 0.5 * 0.01
105
+ else:
106
+ return self.I
107
+
108
+ def function(self, x, m):
109
+ return np.sin(m * np.pi * x / self.l_x)
110
+
111
+ def function_x(self, x, m):
112
+ return np.cos(m * np.pi * x / self.l_x) * m * np.pi / self.l_x
113
+
114
+ def function_xx(self, x, m):
115
+ return np.sin(m * np.pi * x / self.l_x) * (m * np.pi / self.l_x) ** 2 * (-1)
116
+
117
+ def function_xxx(self, x, m):
118
+ return np.sin(m * np.pi * x / self.l_x) * (m * np.pi / self.l_x) ** 3 * (-1)
119
+
120
+ def function_1_FE(self, x, le):
121
+ return 1 - 3 * x**2 / le**2 + 2 * x**3 / le**3
122
+
123
+ def function_1_FE_x(self, x, le):
124
+ return -6 * x / le**2 + 6 * x**2 / le**3
125
+
126
+ def function_1_FE_xx(self, x, le):
127
+ return -6 / le**2 + 12 * x / le**3
128
+
129
+ def function_1_FE_xxx(self, x, le):
130
+ return 12 / le**3
131
+
132
+ def function_2_FE(self, x, le):
133
+ return x - 2 * x**2 / le + x**3 / le**2
134
+
135
+ def function_2_FE_x(self, x, le):
136
+ return 1 - 4 * x / le + 3 * x**2 / le**2
137
+
138
+ def function_2_FE_xx(self, x, le):
139
+ return -4 / le + 6 * x / le**2
140
+
141
+ def function_2_FE_xxx(self, x, le):
142
+ return 6 / le**2
143
+
144
+ def function_3_FE(self, x, le):
145
+ return 3 * x**2 / le**2 - 2 * x**3 / le**3
146
+
147
+ def function_3_FE_x(self, x, le):
148
+ return 6 * x / le**2 - 6 * x**2 / le**3
149
+
150
+ def function_3_FE_xx(self, x, le):
151
+ return 6 / le**2 - 12 * x / le**3
152
+
153
+ def function_3_FE_xxx(self, x, le):
154
+ return -12 / le**3
155
+
156
+ def function_4_FE(self, x, le):
157
+ return -(x**2) / le + x**3 / le**2
158
+
159
+ def function_4_FE_x(self, x, le):
160
+ return -2 * x / le + 3 * x**2 / le**2
161
+
162
+ def function_4_FE_xx(self, x, le):
163
+ return -2 / le + 6 * x / le**2
164
+
165
+ def function_4_FE_xxx(self, x, le):
166
+ return 6 / le**2
167
+
168
+ def function_FE_load(self, x, le, q):
169
+ return (
170
+ q
171
+ * le**4
172
+ / (24 * self.EI)
173
+ * ((x / le) ** 2 - 2 * (x / le) ** 3 + (x / le) ** 4)
174
+ )
175
+
176
+ def Calculate_All(self):
177
+ self.SteMa()
178
+ self.Lasteingabe()
179
+ self.LoadMa()
180
+ self.BoundaryConditions()
181
+ self.Solver()
182
+ self.CalculateElementSolutions()
183
+ self.Verschiebungen(0.5)
184
+ self.Schnittkraefte()
185
+
186
+ def Calculate_All_II(self):
187
+ self.SteMa()
188
+ self.Lasteingabe()
189
+ self.LoadMa()
190
+ self.BoundaryConditions()
191
+ self.Solver()
192
+ self.CalculateElementSolutions()
193
+ self.Verschiebungen(0.5)
194
+ self.Schnittkraefte()
195
+ self.Stabknicken_Element_Mat()
196
+ self.CalculateDeflections_II_Order()
197
+
198
+ def CalculatePrintALL(self):
199
+ self.SteMa()
200
+ self.Lasteingabe()
201
+ self.LoadMa()
202
+ self.BoundaryConditions()
203
+ self.Solver()
204
+ self.CalculateElementSolutions()
205
+ self.Verschiebungen(0.5)
206
+ self.Schnittkraefte()
207
+ self.Verschiebungslinie()
208
+ self.Momentenlinie()
209
+ self.Querkraftlinie()
210
+
211
+ def CalculatePrint_All_II(self):
212
+ self.SteMa()
213
+ self.Lasteingabe()
214
+ self.LoadMa()
215
+ self.BoundaryConditions()
216
+ self.Solver()
217
+ self.CalculateElementSolutions()
218
+ self.Verschiebungen(0.5)
219
+ self.Schnittkraefte()
220
+ self.Stabknicken_Element_Mat()
221
+ self.CalculateDeflections_II_Order()
222
+ self.PlotDeflections_II_Order()
223
+
224
+ def SteMa(self):
225
+ if self.Ansatz == "Fourier":
226
+ for m in range(1, self.reihen + 1, 1):
227
+ for n in range(1, self.reihen + 1, 1):
228
+ self.K[m - 1][n - 1] = self.EI * np.trapz(
229
+ self.function_xx(self.list_lx, m)
230
+ * self.function_xx(self.list_lx, n),
231
+ self.list_lx,
232
+ )
233
+
234
+ self.K = np.where(self.K < 1e-9, 0, self.K)
235
+
236
+ elif self.Ansatz == "FE":
237
+ ne = self.reihen
238
+ le = self.l_x / ne
239
+
240
+ self.list_lxle = np.linspace(0, le, 1000)
241
+
242
+ self.K = np.zeros(((ne + 1) * 2, (ne + 1) * 2))
243
+ self.K_el = np.zeros((4, 4)) # Elementsteifigkeitsmatrix
244
+ self.K_el_bet = np.zeros((4, 4)) # Elementsteifigkeitsmatrix
245
+
246
+ self.K_el_store = np.zeros((ne, 4, 4))
247
+
248
+ # Start-Wert für die Index-Arrays
249
+ start_werte = np.arange(
250
+ 0, 2 * ne, 2
251
+ ) # Erstellt einen Array von Startwerten
252
+
253
+ # Erstelle den Index-Vektor
254
+ self.index_vector = np.array(
255
+ [np.arange(start, start + 4) for start in start_werte]
256
+ )
257
+
258
+ for i in range(0, ne, 1):
259
+ # Row = 0, Col = ...
260
+ self.K_el[0][0] = self.EI * np.trapz(
261
+ self.function_1_FE_xx(self.list_lxle, le)
262
+ * self.function_1_FE_xx(self.list_lxle, le),
263
+ self.list_lxle,
264
+ )
265
+
266
+ self.K_el[0][1] = self.EI * np.trapz(
267
+ self.function_1_FE_xx(self.list_lxle, le)
268
+ * self.function_2_FE_xx(self.list_lxle, le),
269
+ self.list_lxle,
270
+ )
271
+
272
+ self.K_el[0][2] = self.EI * np.trapz(
273
+ self.function_1_FE_xx(self.list_lxle, le)
274
+ * self.function_3_FE_xx(self.list_lxle, le),
275
+ self.list_lxle,
276
+ )
277
+
278
+ self.K_el[0][3] = self.EI * np.trapz(
279
+ self.function_1_FE_xx(self.list_lxle, le)
280
+ * self.function_4_FE_xx(self.list_lxle, le),
281
+ self.list_lxle,
282
+ )
283
+
284
+ # Row = 1, Col = ...
285
+
286
+ self.K_el[1][0] = self.EI * np.trapz(
287
+ self.function_2_FE_xx(self.list_lxle, le)
288
+ * self.function_1_FE_xx(self.list_lxle, le),
289
+ self.list_lxle,
290
+ )
291
+
292
+ self.K_el[1][1] = self.EI * np.trapz(
293
+ self.function_2_FE_xx(self.list_lxle, le)
294
+ * self.function_2_FE_xx(self.list_lxle, le),
295
+ self.list_lxle,
296
+ )
297
+
298
+ self.K_el[1][2] = self.EI * np.trapz(
299
+ self.function_2_FE_xx(self.list_lxle, le)
300
+ * self.function_3_FE_xx(self.list_lxle, le),
301
+ self.list_lxle,
302
+ )
303
+
304
+ self.K_el[1][3] = self.EI * np.trapz(
305
+ self.function_2_FE_xx(self.list_lxle, le)
306
+ * self.function_4_FE_xx(self.list_lxle, le),
307
+ self.list_lxle,
308
+ )
309
+
310
+ # Row = 2, Col = ...
311
+
312
+ self.K_el[2][0] = self.EI * np.trapz(
313
+ self.function_3_FE_xx(self.list_lxle, le)
314
+ * self.function_1_FE_xx(self.list_lxle, le),
315
+ self.list_lxle,
316
+ )
317
+
318
+ self.K_el[2][1] = self.EI * np.trapz(
319
+ self.function_3_FE_xx(self.list_lxle, le)
320
+ * self.function_2_FE_xx(self.list_lxle, le),
321
+ self.list_lxle,
322
+ )
323
+
324
+ self.K_el[2][2] = self.EI * np.trapz(
325
+ self.function_3_FE_xx(self.list_lxle, le)
326
+ * self.function_3_FE_xx(self.list_lxle, le),
327
+ self.list_lxle,
328
+ )
329
+
330
+ self.K_el[2][3] = self.EI * np.trapz(
331
+ self.function_3_FE_xx(self.list_lxle, le)
332
+ * self.function_4_FE_xx(self.list_lxle, le),
333
+ self.list_lxle,
334
+ )
335
+
336
+ # Row = 3, Col = ...
337
+
338
+ self.K_el[3][0] = self.EI * np.trapz(
339
+ self.function_4_FE_xx(self.list_lxle, le)
340
+ * self.function_1_FE_xx(self.list_lxle, le),
341
+ self.list_lxle,
342
+ )
343
+
344
+ self.K_el[3][1] = self.EI * np.trapz(
345
+ self.function_4_FE_xx(self.list_lxle, le)
346
+ * self.function_2_FE_xx(self.list_lxle, le),
347
+ self.list_lxle,
348
+ )
349
+
350
+ self.K_el[3][2] = self.EI * np.trapz(
351
+ self.function_4_FE_xx(self.list_lxle, le)
352
+ * self.function_3_FE_xx(self.list_lxle, le),
353
+ self.list_lxle,
354
+ )
355
+
356
+ self.K_el[3][3] = self.EI * np.trapz(
357
+ self.function_4_FE_xx(self.list_lxle, le)
358
+ * self.function_4_FE_xx(self.list_lxle, le),
359
+ self.list_lxle,
360
+ )
361
+ # Bettung
362
+
363
+ FE_funcs = [
364
+ self.function_1_FE,
365
+ self.function_2_FE,
366
+ self.function_3_FE,
367
+ self.function_4_FE,
368
+ ]
369
+
370
+ FE_funcs = [
371
+ self.function_1_FE,
372
+ self.function_2_FE,
373
+ self.function_3_FE,
374
+ self.function_4_FE,
375
+ ]
376
+
377
+ # 4) Integral über N_i * N_j
378
+ for a, Na in enumerate(FE_funcs):
379
+ for b, Nb in enumerate(FE_funcs):
380
+ self.K_el_bet[a, b] = self.c_bett_z * np.trapz(
381
+ Na(self.list_lxle, le) * Nb(self.list_lxle, le),
382
+ self.list_lxle,
383
+ )
384
+
385
+ # Steifigkeitsmatrix inklusive Bettung
386
+ self.K_el_store[i, :, :] = (
387
+ self.K_el + self.K_el_bet
388
+ ) # Speichert die 2D Arrays in das 3D Array ab
389
+
390
+ for n in range(0, ne, 1):
391
+ for row in range(0, 4, 1):
392
+ for col in range(0, 4, 1):
393
+ self.K[self.index_vector[n][row]][
394
+ self.index_vector[n][col]
395
+ ] += self.K_el_store[n][row][col]
396
+
397
+ def Lasteingabe(self):
398
+ self.Einzellasten = False
399
+ self.Linienlasten = False
400
+ if self.load_input == "console":
401
+ # Implementieren Sie hier die Konsoleneingabe
402
+ pass
403
+ else:
404
+ self.Einzellasten = pd.DataFrame(
405
+ pd.read_csv("Lasteingabe_Text/Einzellasten.csv")
406
+ )
407
+ self.Linienlasten = pd.DataFrame(
408
+ pd.read_csv("Lasteingabe_Text/Linienlasten.csv")
409
+ )
410
+
411
+ def LoadMa(self):
412
+ if self.Ansatz == "Fourier":
413
+ for m in range(1, self.reihen + 1, 1):
414
+ if self.Ansatz == "Fourier":
415
+ self.P[m - 1] = (
416
+ np.trapz(self.function(self.list_lx, m), self.list_lx) * self.p
417
+ )
418
+
419
+ elif self.Ansatz == "FE":
420
+ ne = self.reihen
421
+ self.P = np.zeros(2 * (ne + 1))
422
+ le = self.l_x / ne
423
+
424
+ # Element load-vector (Single Load from File)
425
+ for i in self.Einzellasten["x0F in [m]"]:
426
+ num_el = int(i / le + 1)
427
+ x_el = (i / le - num_el + 1) * le
428
+
429
+ load_index = self.index_vector[num_el - 1][0]
430
+
431
+ self.F = self.Einzellasten["F in [MN]"][0]
432
+
433
+ self.P[load_index + 0] += self.F * self.function_1_FE(x_el, le)
434
+ self.P[load_index + 1] += self.F * self.function_2_FE(x_el, le)
435
+ self.P[load_index + 2] += self.F * self.function_3_FE(x_el, le)
436
+ self.P[load_index + 3] += self.F * self.function_4_FE(x_el, le)
437
+
438
+ # Element load-vector (Constant line loads from File)
439
+ for i in range(0, len(self.Linienlasten["x0"]), 1):
440
+ num_el_0 = int(
441
+ self.Linienlasten["x0"][i] / le
442
+ ) # Anfangselement der Linienlast
443
+ x_el_0 = self.Linienlasten["x0"][
444
+ i
445
+ ] # Lokale Startposition im Anfangselement
446
+ num_el_1 = int(np.ceil(self.Linienlasten["x1"][i] / le))
447
+
448
+ x_el_1 = (
449
+ self.Linienlasten["x1"][i] - (num_el_1 - 1) * le
450
+ ) # Lokale Endposition im Endelement
451
+
452
+ # Check, if the load is smaller than the beam itself
453
+
454
+ if self.Linienlasten["x1"][i] <= self.l_x:
455
+ print("HERE 1")
456
+ else:
457
+ x_el_1 = le
458
+ num_el_1 = int(np.ceil(self.l_x / le))
459
+
460
+ q = self.Linienlasten["q"][i]
461
+
462
+ load_integration = np.zeros((num_el_1 - num_el_0, 10))
463
+ for j in range(num_el_0, num_el_1):
464
+ local_start = (
465
+ x_el_0 if j == num_el_0 else 0
466
+ ) # Start bei x_el_0 für das erste betroffene Element, sonst bei le*j
467
+ local_end = (
468
+ x_el_1 if j == num_el_1 - 1 else le
469
+ ) # Ende bei x_el_1 für das letzte betroffene Element, sonst bei le
470
+ idx = j - num_el_0 # Korrigierter Index für load_integration
471
+ load_integration[idx][:] = np.linspace(local_start, local_end, 10)
472
+
473
+ load_index = self.index_vector[j][0]
474
+ local_le = local_end - local_start
475
+
476
+ self.P[load_index + 0] += q * np.trapz(
477
+ self.function_1_FE(load_integration[idx][:], local_le),
478
+ load_integration[idx][:],
479
+ )
480
+
481
+ self.P[load_index + 1] += q * np.trapz(
482
+ self.function_2_FE(load_integration[idx][:], local_le),
483
+ load_integration[idx][:],
484
+ )
485
+ self.P[load_index + 2] += q * np.trapz(
486
+ self.function_3_FE(load_integration[idx][:], local_le),
487
+ load_integration[idx][:],
488
+ )
489
+
490
+ self.P[load_index + 3] += q * np.trapz(
491
+ self.function_4_FE(load_integration[idx][:], local_le),
492
+ load_integration[idx][:],
493
+ )
494
+
495
+ def BoundaryConditions(self):
496
+ self.BC = pd.DataFrame(pd.read_csv("Federeingabe/Federeingabe.csv"))
497
+
498
+ self.v = []
499
+ self.v_cp = []
500
+ self.phi = []
501
+ self.phi_cp = []
502
+
503
+ len_K = len(self.K)
504
+
505
+ for j in self.BC["No"]:
506
+ i = self.BC["xi[-]"][self.BC["No"] == j].iloc[0]
507
+ BC_LOC = self.BC["DOF"][self.BC["No"] == j].iloc[0]
508
+ cp = self.BC["cf in [MN/m]/[MNm/rad]"][self.BC["No"] == j].iloc[0]
509
+
510
+ if BC_LOC == "v":
511
+ self.v.append(
512
+ i * (len_K - 2)
513
+ ) # Element which displacement is constrained
514
+ self.v_cp.append(cp)
515
+ elif BC_LOC == "phi":
516
+ self.phi.append(i * (len_K - 2) + 1)
517
+ self.phi_cp.append(cp)
518
+ for i in self.v:
519
+ node = int(i)
520
+ self.K[node][node] += cp
521
+ for j in self.phi:
522
+ node = int(j)
523
+ self.K[node][node] += cp
524
+
525
+ def Solver(self):
526
+ if self.Ansatz == "Fourier":
527
+ self.x_reduced = np.linalg.solve(self.K, self.P)
528
+ self.x_disp_red = self.x_reduced[::2]
529
+ if self.Ansatz == "FE":
530
+ self.x_reduced = np.linalg.solve(self.K, self.P)
531
+ self.x_disp_red = self.x_reduced[::2]
532
+
533
+ def CalculateElementSolutions(self):
534
+ if self.Ansatz == "FE":
535
+ ne = self.reihen
536
+ self.x_disp_e = np.zeros((ne, 4))
537
+
538
+ for i in range(0, ne, 1):
539
+ for j in range(0, 4, 1):
540
+ self.x_disp_e[i][j] = self.x_reduced[j + i * 2]
541
+ else:
542
+ pass
543
+
544
+ def Verschiebungen(self, x_cal):
545
+ if self.Ansatz == "Fourier":
546
+ self.x_disp = 0
547
+ for m in range(1, self.reihen + 1, 1):
548
+ self.x_disp += self.x_reduced[m - 1] * self.function(x_cal, m)
549
+ return self.x_disp
550
+
551
+ elif self.Ansatz == "FE":
552
+ ne = self.reihen
553
+ le = self.l_x / ne
554
+ self.uz_el_store = np.zeros((ne, 2))
555
+ self.phi_el_store = np.zeros((ne, 2))
556
+ self.x_el_store = np.zeros((ne, 2))
557
+
558
+ for i in range(0, ne, 1):
559
+ self.uz_el_store[i] = self.x_disp_e[i][
560
+ ::2
561
+ ] # Elementweise Angabe der Knotenverschiebungen
562
+ self.phi_el_store[i] = self.x_disp_e[i][
563
+ 1::2
564
+ ] # Elementweise Angabe der Knotenverdrehungen
565
+
566
+ self.x_el_store[i][0] = i * le
567
+ self.x_el_store[i][1] = (i + 1) * le
568
+
569
+ def Schnittkraefte(self, x_cal=0.5):
570
+ """_summary_
571
+
572
+ Args:
573
+ x_cal (float, optional): Auswertepunkt bei einem Fourieransatz. \n
574
+ Defaultwert ist 0.5. Nicht notwendig, wenn die Berechnung \n
575
+ mit FE-Ansatzfunktionen durchgeführt wird. \n
576
+
577
+ Returns:
578
+ _type_: float-Value für Ansatz von Fourierreihen für die Annäherung an die Durchbiegung. \n
579
+ Kein Rückgabewert, wenn FE-Ansatz nach dem Ritzverfahren angewandt wird.
580
+ """
581
+ if self.Ansatz == "Fourier":
582
+ self.m_y = 0
583
+ for m in range(1, self.reihen, 1):
584
+ self.m_y += (
585
+ self.x_reduced[m - 1] * self.function_xx(x_cal, m) * self.EI * (-1)
586
+ )
587
+
588
+ return self.m_y
589
+ elif self.Ansatz == "FE":
590
+ ne = self.reihen
591
+ le = self.l_x / ne
592
+ self.m_el_store = np.zeros((ne, 2))
593
+ self.v_el_store = np.zeros((ne, 2))
594
+
595
+ for i in range(0, ne, 1):
596
+ self.inner_forces_el_store = np.matmul(
597
+ self.K_el_store[i], self.x_disp_e[i]
598
+ )
599
+
600
+ self.inner_forces_el_store[
601
+ 0
602
+ ] *= (
603
+ -1
604
+ ) # Linkes Schnittufer der Querkraft , Umgedrehtes Vorzeichen aus FE-Konvention
605
+ self.inner_forces_el_store[
606
+ 3
607
+ ] *= (
608
+ -1
609
+ ) # Rechtes Schnittufer , Umgedrehtes Vorzeichen aus FE-Konvention
610
+ self.m_el_store[i] = self.inner_forces_el_store[1::2]
611
+ self.v_el_store[i] = self.inner_forces_el_store[::2]
612
+
613
+ def Verschiebungslinie(self, interpolation=2):
614
+ """
615
+ Funktion zur Berechnung der Verschiebungen in den Elementen \n
616
+ Aus der vorherigen Verschiebungsfunktion sind für die \n
617
+ Polynomansätze die Verschiebungen an den Knoten bekannt. \n
618
+ Über die Verschiebungen und die Kenntnis über die Linienbelastungen \n
619
+ auf den Einzelelementen können die Elementschnittgrößen ermittelt werden \n
620
+ Dies erfolgt über die Rückrechnung aus den Ansatzfunktionen \n
621
+
622
+ """
623
+
624
+ if self.Ansatz == "Fourier":
625
+ self.v_list = np.zeros(len(self.list_lx))
626
+
627
+ for i in range(0, len(self.list_lx), 1):
628
+ self.v_list[i] = self.Verschiebungen(self.list_lx[i])
629
+ else:
630
+ ne = self.reihen
631
+ n_inter = interpolation
632
+ self.x_element_inter = np.zeros(
633
+ (ne, n_inter)
634
+ ) # Interpolierte Längenliste für die Elemente
635
+ self.uz_element_inter = np.zeros((ne, n_inter))
636
+
637
+ for i in range(0, ne, 1):
638
+ xA = self.x_el_store[i][0]
639
+ xB = self.x_el_store[i][1]
640
+ le = self.l_x / ne
641
+ dle = le / (n_inter - 1)
642
+
643
+ wA = self.uz_el_store[i][0]
644
+ PhiA = self.phi_el_store[i][0]
645
+ wB = self.uz_el_store[i][1]
646
+ PhiB = self.phi_el_store[i][1]
647
+
648
+ for j in range(0, n_inter, 1):
649
+ x_loc = j * dle
650
+
651
+ f_1 = self.function_1_FE(x_loc, le)
652
+ f_2 = self.function_2_FE(x_loc, le)
653
+ f_3 = self.function_3_FE(x_loc, le)
654
+ f_4 = self.function_4_FE(x_loc, le)
655
+
656
+ f_load = self.function_FE_load(
657
+ x_loc, le, 0
658
+ ) # Load function not implemented
659
+ # Steps: Calculate q(x_loc) for each element necessary
660
+
661
+ self.x_element_inter[i][j] = x_loc
662
+ self.uz_element_inter[i][j] = (
663
+ f_1 * wA + f_2 * PhiA + f_3 * wB + f_4 * PhiB + f_load
664
+ )
665
+
666
+ self.x_element_inter[i] += i * le
667
+
668
+ plt.plot(self.x_element_inter[i], self.uz_element_inter[i])
669
+
670
+ plt.show(block=False)
671
+ plt.pause(0.1)
672
+ plt.close()
673
+
674
+ def Momentenlinie(self, interpolation=2):
675
+ if self.Ansatz == "Fourier":
676
+ self.m = np.zeros(len(self.list_lx))
677
+ for i in range(0, len(self.list_lx), 1):
678
+ self.m[i] = self.Schnittkraefte(self.list_lx[i])
679
+ else:
680
+ ne = self.reihen
681
+ n_inter = interpolation
682
+ self.x_element_inter = np.zeros(
683
+ (ne, n_inter)
684
+ ) # Interpolierte Längenliste für die Elemente
685
+ self.m_element_inter = np.zeros((ne, n_inter))
686
+
687
+ for i in range(0, ne, 1):
688
+ xA = self.x_el_store[i][0]
689
+ xB = self.x_el_store[i][1]
690
+ le = self.l_x / ne
691
+ dle = le / (n_inter - 1)
692
+
693
+ wA = self.uz_el_store[i][0]
694
+ PhiA = self.phi_el_store[i][0]
695
+ wB = self.uz_el_store[i][1]
696
+ PhiB = self.phi_el_store[i][1]
697
+
698
+ for j in range(0, n_inter, 1):
699
+ x_loc = j * dle
700
+
701
+ f_1 = self.function_1_FE_xx(x_loc, le)
702
+ f_2 = self.function_2_FE_xx(x_loc, le)
703
+ f_3 = self.function_3_FE_xx(x_loc, le)
704
+ f_4 = self.function_4_FE_xx(x_loc, le)
705
+
706
+ self.x_element_inter[i][j] = x_loc
707
+ self.m_element_inter[i][j] = (
708
+ f_1 * wA + f_2 * PhiA + f_3 * wB + f_4 * PhiB
709
+ ) * (-self.EI)
710
+
711
+ self.x_element_inter[i] += i * le
712
+
713
+ plt.plot(self.x_element_inter[i], self.m_element_inter[i])
714
+
715
+ # print("Max Bending Moment ", self.m_element_inter.max())
716
+ # print("Min Bending Moment ", self.m_element_inter.min())
717
+ plt.show(block=False)
718
+ plt.pause(0.1)
719
+ plt.close()
720
+
721
+ def Querkraftlinie(self, interpolation=2):
722
+ if self.Ansatz == "Fourier":
723
+ self.m = np.zeros(len(self.list_lx))
724
+ for i in range(0, len(self.list_lx), 1):
725
+ self.m[i] = self.Schnittkraefte(self.list_lx[i])
726
+ else:
727
+ ne = self.reihen
728
+ n_inter = interpolation
729
+ self.x_element_inter = np.zeros(
730
+ (ne, n_inter)
731
+ ) # Interpolierte Längenliste für die Elemente
732
+ self.vz_element_inter = np.zeros((ne, n_inter))
733
+
734
+ for i in range(0, ne, 1):
735
+ xA = self.x_el_store[i][0]
736
+ xB = self.x_el_store[i][1]
737
+ le = self.l_x / ne
738
+ dle = le / (n_inter - 1)
739
+
740
+ wA = self.uz_el_store[i][0]
741
+ PhiA = self.phi_el_store[i][0]
742
+ wB = self.uz_el_store[i][1]
743
+ PhiB = self.phi_el_store[i][1]
744
+
745
+ for j in range(0, n_inter, 1):
746
+ x_loc = j * dle
747
+
748
+ f_1 = self.function_1_FE_xxx(x_loc, le)
749
+ f_2 = self.function_2_FE_xxx(x_loc, le)
750
+ f_3 = self.function_3_FE_xxx(x_loc, le)
751
+ f_4 = self.function_4_FE_xxx(x_loc, le)
752
+
753
+ self.x_element_inter[i][j] = x_loc
754
+ self.vz_element_inter[i][j] = (
755
+ f_1 * wA + f_2 * PhiA + f_3 * wB + f_4 * PhiB
756
+ ) * (-self.EI)
757
+
758
+ self.x_element_inter[i] += i * le
759
+
760
+ plt.plot(self.x_element_inter[i], self.vz_element_inter[i])
761
+
762
+ # print("Max Shear Force", self.vz_element_inter.max())
763
+ plt.show(block=False)
764
+ plt.pause(0.1)
765
+ plt.close()
766
+
767
+ def Stabknicken_Element_Mat(self):
768
+ # Definieren Sie l und S entsprechend Ihren spezifischen Anforderungen
769
+ self.S = -1 # Default value for the normal force to -1 MN (Compression)
770
+
771
+ ne = self.reihen
772
+ le = self.l_x / ne
773
+
774
+ self.Kg_II = np.zeros(((ne + 1) * 2, (ne + 1) * 2))
775
+
776
+ self.K_el_gII_store = np.zeros((ne, 4, 4))
777
+ for i in range(0, ne, 1):
778
+
779
+ # Definieren Sie die Matrix
780
+ K_G_II = (
781
+ self.S
782
+ / (30 * le)
783
+ * np.array(
784
+ [
785
+ [36, 3 * le, -36, 3 * le],
786
+ [3 * le, 4 * le**2, -3 * le, -(le**2)],
787
+ [-36, -3 * le, 36, -3 * le],
788
+ [3 * le, -(le**2), -3 * le, 4 * le**2],
789
+ ]
790
+ )
791
+ )
792
+
793
+ self.K_el_gII_store[i, :, :] = (
794
+ K_G_II # Speichert die 2D Arrays in das 3D Array ab
795
+ )
796
+
797
+ # Index-vectors are the same as for the calculation with TH.I.Order
798
+ for n in range(0, ne, 1):
799
+ for row in range(0, 4, 1):
800
+ for col in range(0, 4, 1):
801
+ self.Kg_II[self.index_vector[n][row]][
802
+ self.index_vector[n][col]
803
+ ] += self.K_el_gII_store[n][row][col]
804
+
805
+ def Stabknicken_Eigenwerte(self):
806
+ alpha_min = 0
807
+ alpha_max = 25
808
+ precision = 1e-3
809
+ initial_delta_alpha = 0.1
810
+ critical_alphas = []
811
+ self.det_list = []
812
+
813
+ for i in range(0, 2500, 1):
814
+ a_cr = 0.01 * i
815
+ det = np.linalg.det(self.K + a_cr * self.Kg_II)
816
+ self.det_list.append(det)
817
+ if (i > 0) and ((det < 0 and det_1 >= 0) or (det >= 0 and det_1 < 0)):
818
+ print("Eigenvalue ", a_cr)
819
+ det_1 = det
820
+
821
+ self.alpha_crit, eigenmodes = eig(self.K, -self.Kg_II)
822
+
823
+ # print(self.alpha_crit)
824
+
825
+ min_index = np.argmin(self.alpha_crit) # Index des kleinsten Eigenwertes
826
+
827
+ min_eigenmode = eigenmodes[:, min_index] # Zugehöriger Eigenvektor
828
+ self.min_eigenmode_every_second = min_eigenmode[
829
+ ::2
830
+ ] # Auswahl jedes zweiten Elements
831
+
832
+ self.alpha_crit = min(self.alpha_crit)
833
+ self.N_crit = self.alpha_crit * self.S
834
+
835
+ return critical_alphas
836
+
837
+ def PlotBucklingEigenmodes(self):
838
+ print("Min acrit ", self.alpha_crit)
839
+
840
+ plt.plot(self.min_eigenmode_every_second)
841
+ plt.gca().invert_yaxis() # 'gca' stands for 'get current axis'
842
+
843
+ plt.show(block=False)
844
+ plt.pause(3)
845
+ plt.close()
846
+
847
+ plt.plot(self.det_list)
848
+ plt.show(block=False)
849
+ plt.pause(3)
850
+ plt.close()
851
+
852
+ def CalculateDeflections_II_Order(self):
853
+ self.x_II = np.linalg.solve((self.K + self.Kg_II), self.P)
854
+ self.x_disp_II = self.x_II[::2]
855
+
856
+ def PlotDeflections_II_Order(self):
857
+ print("Max. Deflection First Order ", self.x_disp_red.max())
858
+ print("Max. Deflection Second Order ", self.x_disp_II.max())
859
+ print("Max. Moment First Order ", self.m_el_store.max())
860
+ plt.plot(self.x_disp_II, color="Red")
861
+ plt.plot(self.x_disp_red, color="Blue")
862
+ plt.show(block=False)
863
+ plt.pause(4)
864
+ plt.close()
865
+
866
+ def Biegedrillknicken_Aufruf(self):
867
+ self.BDK = Biegedrillknicken(self)
868
+ self.BDK.Calculate_All()