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,658 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
from scipy.linalg import eig
|
|
3
|
+
try:
|
|
4
|
+
import plate_buckling_cpp # Import des kompilierten C++-Moduls
|
|
5
|
+
except:
|
|
6
|
+
from KIB_LAP.Plattenbeulen import plate_buckling_cpp
|
|
7
|
+
|
|
8
|
+
class PlateBucklingRitz:
|
|
9
|
+
def __init__(
|
|
10
|
+
self,
|
|
11
|
+
a,
|
|
12
|
+
b,
|
|
13
|
+
t,
|
|
14
|
+
E,
|
|
15
|
+
nu,
|
|
16
|
+
Nx_params,
|
|
17
|
+
Ny_params,
|
|
18
|
+
Nxy,
|
|
19
|
+
m_terms,
|
|
20
|
+
n_terms,
|
|
21
|
+
x_s_positions,
|
|
22
|
+
I_s_values,
|
|
23
|
+
A_s_values,
|
|
24
|
+
y_s_positions,
|
|
25
|
+
I_t_values,
|
|
26
|
+
A_t_values
|
|
27
|
+
):
|
|
28
|
+
# Initialisierung der Parameter
|
|
29
|
+
self.a = a
|
|
30
|
+
self.b = b
|
|
31
|
+
self.t = t
|
|
32
|
+
self.E = E
|
|
33
|
+
self.nu = nu
|
|
34
|
+
self.Nx0, self.Nx1 = Nx_params
|
|
35
|
+
self.Ny0, self.Ny1 = Ny_params
|
|
36
|
+
self.Nxy = Nxy
|
|
37
|
+
self.m_terms = m_terms
|
|
38
|
+
self.n_terms = n_terms
|
|
39
|
+
self.x_s_positions = x_s_positions
|
|
40
|
+
self.I_s_values = I_s_values
|
|
41
|
+
self.A_s_values = A_s_values
|
|
42
|
+
self.y_s_positions = y_s_positions
|
|
43
|
+
self.I_t_values = I_t_values
|
|
44
|
+
self.A_t_values = A_t_values
|
|
45
|
+
|
|
46
|
+
self.num_terms = len(self.m_terms) * len(self.n_terms)
|
|
47
|
+
|
|
48
|
+
def assemble_matrices(self):
|
|
49
|
+
num_terms = self.num_terms
|
|
50
|
+
index_map = {}
|
|
51
|
+
idx = 0
|
|
52
|
+
m_list = []
|
|
53
|
+
n_list = []
|
|
54
|
+
for m_i in self.m_terms:
|
|
55
|
+
for n_i in self.n_terms:
|
|
56
|
+
index_map[(m_i, n_i)] = idx
|
|
57
|
+
m_list.append(m_i)
|
|
58
|
+
n_list.append(n_i)
|
|
59
|
+
idx += 1
|
|
60
|
+
|
|
61
|
+
self.index_map = index_map # Speichern für spätere Verwendung
|
|
62
|
+
self.m_list = m_list
|
|
63
|
+
self.n_list = n_list
|
|
64
|
+
|
|
65
|
+
# Nach der Erstellung von m_list und n_list in assemble_matrices()
|
|
66
|
+
self.stiffener_indices_m1 = []
|
|
67
|
+
for idx, (m_i, n_i) in enumerate(zip(self.m_list, self.n_list)):
|
|
68
|
+
if m_i == 1:
|
|
69
|
+
# Überprüfen, ob dieser Term einen Beitrag von den Längssteifen hat
|
|
70
|
+
# Angenommen, die Längssteifen beeinflussen alle DOFs, dies muss ggf. angepasst werden
|
|
71
|
+
self.stiffener_indices_m1.append(idx)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
m_array = np.array(m_list, dtype=np.int32)
|
|
75
|
+
n_array = np.array(n_list, dtype=np.int32)
|
|
76
|
+
|
|
77
|
+
K_flat = np.zeros(num_terms * num_terms)
|
|
78
|
+
G_flat = np.zeros(num_terms * num_terms)
|
|
79
|
+
|
|
80
|
+
x_s_array = np.array(self.x_s_positions, dtype=np.float64)
|
|
81
|
+
I_s_array = np.array(self.I_s_values, dtype=np.float64)
|
|
82
|
+
A_s_array = np.array(self.A_s_values, dtype=np.float64)
|
|
83
|
+
|
|
84
|
+
y_s_array = np.array(self.y_s_positions, dtype=np.float64)
|
|
85
|
+
I_t_array = np.array(self.I_t_values, dtype=np.float64)
|
|
86
|
+
A_t_array = np.array(self.A_t_values, dtype=np.float64)
|
|
87
|
+
|
|
88
|
+
# Aufruf der angepassten C++-Funktion zur Assemblierung
|
|
89
|
+
plate_buckling_cpp.assemble_matrices_with_stiffeners_cpp(
|
|
90
|
+
m_array,
|
|
91
|
+
n_array,
|
|
92
|
+
self.a,
|
|
93
|
+
self.b,
|
|
94
|
+
self.Nx0,
|
|
95
|
+
self.Nx1,
|
|
96
|
+
self.Ny0,
|
|
97
|
+
self.Ny1,
|
|
98
|
+
self.Nxy,
|
|
99
|
+
self.E,
|
|
100
|
+
self.t,
|
|
101
|
+
self.nu,
|
|
102
|
+
x_s_array,
|
|
103
|
+
I_s_array,
|
|
104
|
+
A_s_array,
|
|
105
|
+
y_s_array,
|
|
106
|
+
I_t_array,
|
|
107
|
+
A_t_array,
|
|
108
|
+
K_flat,
|
|
109
|
+
G_flat,
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
K = K_flat.reshape((num_terms, num_terms))
|
|
113
|
+
G = G_flat.reshape((num_terms, num_terms))
|
|
114
|
+
|
|
115
|
+
self.K = K
|
|
116
|
+
self.G = G
|
|
117
|
+
|
|
118
|
+
def solve_eigenvalue_problem(self):
|
|
119
|
+
"""
|
|
120
|
+
Löse das Eigenwertproblem und bestimme die kritischen Beullasten.
|
|
121
|
+
"""
|
|
122
|
+
self.assemble_matrices()
|
|
123
|
+
eigenvalues, eigenvectors = eig(self.K, self.G)
|
|
124
|
+
|
|
125
|
+
# Filtern der positiven Eigenwerte
|
|
126
|
+
positive_idx = np.where(eigenvalues > 1e-8)[0]
|
|
127
|
+
eigenvalues_positive = np.real(eigenvalues[positive_idx])
|
|
128
|
+
eigenvectors_positive = np.real(eigenvectors[:, positive_idx])
|
|
129
|
+
|
|
130
|
+
if len(eigenvalues_positive) == 0:
|
|
131
|
+
raise ValueError(
|
|
132
|
+
"Keine positiven Eigenwerte gefunden. Überprüfen Sie die Eingangsparameter."
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
# Sortieren der Eigenwerte und zugehörigen Eigenvektoren
|
|
136
|
+
sorted_idx = eigenvalues_positive.argsort()
|
|
137
|
+
eigenvalues_positive = eigenvalues_positive[sorted_idx]
|
|
138
|
+
eigenvectors_positive = eigenvectors_positive[:, sorted_idx]
|
|
139
|
+
|
|
140
|
+
self.eigenvalues = eigenvalues_positive
|
|
141
|
+
self.eigenvectors = eigenvectors_positive
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
# Analyse der Eigenvektoren, um die Modi mit m=1 zu identifizieren
|
|
145
|
+
m_array = np.array(self.m_list)
|
|
146
|
+
m_equals_one = (m_array == 1)
|
|
147
|
+
fraction_m1_list = []
|
|
148
|
+
for k in range(len(self.eigenvalues)):
|
|
149
|
+
eigenvector = self.eigenvectors[:, k]
|
|
150
|
+
total_contribution = np.sum(eigenvector**2)
|
|
151
|
+
contribution_m1 = np.sum(eigenvector[m_equals_one]**2)
|
|
152
|
+
fraction_m1 = contribution_m1 / total_contribution
|
|
153
|
+
fraction_m1_list.append(fraction_m1)
|
|
154
|
+
|
|
155
|
+
self.fraction_m1_array = np.array(fraction_m1_list)
|
|
156
|
+
|
|
157
|
+
return self.eigenvalues, self.eigenvectors
|
|
158
|
+
|
|
159
|
+
def get_mode_along_transverse_stiffener(self, y_s, eigenvector=None, num_points=100):
|
|
160
|
+
"""
|
|
161
|
+
Berechnet den Verlauf der Beulform entlang einer Quersteife bei Position y_s.
|
|
162
|
+
|
|
163
|
+
Parameters:
|
|
164
|
+
y_s (float): Position der Quersteife in y-Richtung
|
|
165
|
+
eigenvector (ndarray): Eigenvektor, der die Beulform definiert (Standard: erster Eigenvektor)
|
|
166
|
+
num_points (int): Anzahl der Punkte in x-Richtung für die Darstellung
|
|
167
|
+
|
|
168
|
+
Returns:
|
|
169
|
+
x (ndarray): Array der x-Koordinaten
|
|
170
|
+
W (ndarray): Verformungen W(x, y_s) entlang der Quersteife
|
|
171
|
+
"""
|
|
172
|
+
if eigenvector is None:
|
|
173
|
+
eigenvector = self.eigenvectors[:, 0] # Standardmäßig erste Beulform
|
|
174
|
+
|
|
175
|
+
x = np.linspace(0, self.a, num_points)
|
|
176
|
+
W = np.zeros_like(x)
|
|
177
|
+
|
|
178
|
+
idx = 0
|
|
179
|
+
for m_i in self.m_terms:
|
|
180
|
+
sin_m = np.sin(m_i * np.pi * x / self.a)
|
|
181
|
+
for n_i in self.n_terms:
|
|
182
|
+
sin_n = np.sin(n_i * np.pi * y_s / self.b)
|
|
183
|
+
W += eigenvector[idx] * sin_m * sin_n
|
|
184
|
+
idx += 1
|
|
185
|
+
|
|
186
|
+
return x, W
|
|
187
|
+
|
|
188
|
+
def plot_modes_along_transverse_stiffeners(self, modes=None, num_modes=1, num_points=100):
|
|
189
|
+
"""
|
|
190
|
+
Plottet den Verlauf der Beulform entlang aller Quersteifen für die angegebenen Moden.
|
|
191
|
+
|
|
192
|
+
Parameters:
|
|
193
|
+
modes (list of int): Liste der zu plottenden Modenindizes. Wenn None, werden die ersten `num_modes` Moden geplottet.
|
|
194
|
+
num_modes (int): Anzahl der zu plottenden Moden, wenn `modes` None ist.
|
|
195
|
+
num_points (int): Anzahl der Punkte in x-Richtung für die Darstellung.
|
|
196
|
+
"""
|
|
197
|
+
import matplotlib.pyplot as plt
|
|
198
|
+
|
|
199
|
+
if not hasattr(self, 'eigenvalues'):
|
|
200
|
+
self.solve_eigenvalue_problem()
|
|
201
|
+
|
|
202
|
+
if modes is None:
|
|
203
|
+
modes = list(range(num_modes))
|
|
204
|
+
|
|
205
|
+
num_plots = len(modes)
|
|
206
|
+
# Bestimmen der Anzahl der Zeilen und Spalten für die Subplots
|
|
207
|
+
num_cols = 2 # Sie können dies nach Bedarf anpassen
|
|
208
|
+
num_rows = (num_plots + num_cols - 1) // num_cols
|
|
209
|
+
|
|
210
|
+
fig, axs = plt.subplots(num_rows, num_cols, figsize=(8 * num_cols, 6 * num_rows))
|
|
211
|
+
axs = axs.flatten()
|
|
212
|
+
|
|
213
|
+
for i, mode_idx in enumerate(modes):
|
|
214
|
+
eigenvector = self.eigenvectors[:, mode_idx]
|
|
215
|
+
ax = axs[i]
|
|
216
|
+
for y_s in self.y_s_positions:
|
|
217
|
+
x, W = self.get_mode_along_transverse_stiffener(y_s, eigenvector, num_points)
|
|
218
|
+
ax.plot(x, W, label=f'y = {y_s:.2f} m')
|
|
219
|
+
ax.set_xlabel('x (m)')
|
|
220
|
+
ax.set_ylabel('Verformung $W(x, y_s)$')
|
|
221
|
+
ax.set_title(f'Modus {mode_idx}: Verlauf entlang Quersteifen')
|
|
222
|
+
ax.legend()
|
|
223
|
+
ax.grid(True)
|
|
224
|
+
|
|
225
|
+
# Verstecken von nicht genutzten Subplots
|
|
226
|
+
for j in range(i + 1, len(axs)):
|
|
227
|
+
fig.delaxes(axs[j])
|
|
228
|
+
|
|
229
|
+
plt.tight_layout()
|
|
230
|
+
plt.show()
|
|
231
|
+
|
|
232
|
+
def get_critical_load_m1_mode(self, threshold=0.9):
|
|
233
|
+
"""
|
|
234
|
+
Gibt die kleinste kritische Beullast für Modi mit m=1 zurück.
|
|
235
|
+
|
|
236
|
+
Parameters:
|
|
237
|
+
- threshold (float): Schwellenwert für den Anteil der m=1 Komponenten
|
|
238
|
+
|
|
239
|
+
Returns:
|
|
240
|
+
- lambda_cr_m1 (float): Kritischer Lastfaktor für m=1 Modus
|
|
241
|
+
- eigenvector_m1 (ndarray): Eigenvektor des m=1 Modus
|
|
242
|
+
"""
|
|
243
|
+
if not hasattr(self, 'eigenvalues'):
|
|
244
|
+
self.solve_eigenvalue_problem()
|
|
245
|
+
|
|
246
|
+
indices_m1_modes = np.where(self.fraction_m1_array >= threshold)[0]
|
|
247
|
+
|
|
248
|
+
if len(indices_m1_modes) > 0:
|
|
249
|
+
idx = indices_m1_modes[0]
|
|
250
|
+
lambda_cr_m1 = self.eigenvalues[idx]
|
|
251
|
+
eigenvector_m1 = self.eigenvectors[:, idx]
|
|
252
|
+
self.plot_modes_along_transverse_stiffeners(None,10,100)
|
|
253
|
+
return lambda_cr_m1, eigenvector_m1
|
|
254
|
+
else:
|
|
255
|
+
print("Auswahl des dominanten Modes:")
|
|
256
|
+
self.plot_modes_along_transverse_stiffeners(None,10,100)
|
|
257
|
+
print("Auf der sicheren Seite liegend, kann der Wert 1 für die erste Eigenform angesetzt werden. ")
|
|
258
|
+
mode = int(input(f"Vorgabe des anzusetzenden Eigenmodes: \n"))
|
|
259
|
+
|
|
260
|
+
return self.eigenvalues[mode-1], self.eigenvectors[:, mode-1] # -1, Da Matrix / Vektor-Zählweise
|
|
261
|
+
|
|
262
|
+
def get_buckling_mode(self, eigenvector=None, num_points=50, normalize=True):
|
|
263
|
+
"""
|
|
264
|
+
Berechnet die Beulform für einen gegebenen Eigenvektor.
|
|
265
|
+
|
|
266
|
+
Parameters:
|
|
267
|
+
- eigenvector (ndarray): Eigenvektor, der die Beulform definiert
|
|
268
|
+
- num_points (int): Anzahl der Punkte in x- und y-Richtung für die Darstellung
|
|
269
|
+
- normalize (bool): Ob die Beulform auf maximale Amplitude 1 normiert werden soll
|
|
270
|
+
|
|
271
|
+
Returns:
|
|
272
|
+
- X, Y (ndarray): Meshgrid der x- und y-Koordinaten
|
|
273
|
+
- W (ndarray): Beulformwerte an den Gitterpunkten
|
|
274
|
+
"""
|
|
275
|
+
m_terms = self.m_terms
|
|
276
|
+
n_terms = self.n_terms
|
|
277
|
+
a = self.a
|
|
278
|
+
b = self.b
|
|
279
|
+
x = np.linspace(0, a, num_points)
|
|
280
|
+
y = np.linspace(0, b, num_points)
|
|
281
|
+
X, Y = np.meshgrid(x, y)
|
|
282
|
+
W = np.zeros_like(X)
|
|
283
|
+
|
|
284
|
+
if eigenvector is None:
|
|
285
|
+
eigenvector = self.eigenvectors[:, 0] # Standardmäßig erste Beulform
|
|
286
|
+
|
|
287
|
+
idx = 0
|
|
288
|
+
for m in m_terms:
|
|
289
|
+
for n in n_terms:
|
|
290
|
+
phi = np.sin(m * np.pi * X / a) * np.sin(n * np.pi * Y / b)
|
|
291
|
+
W += eigenvector[idx] * phi
|
|
292
|
+
idx += 1
|
|
293
|
+
|
|
294
|
+
if normalize:
|
|
295
|
+
max_W = np.max(np.abs(W))
|
|
296
|
+
if max_W != 0:
|
|
297
|
+
W = W / max_W
|
|
298
|
+
|
|
299
|
+
return X, Y, W
|
|
300
|
+
|
|
301
|
+
def get_critical_load(self):
|
|
302
|
+
"""
|
|
303
|
+
Gibt die kleinste kritische Beullast zurück.
|
|
304
|
+
|
|
305
|
+
Returns:
|
|
306
|
+
- lambda_cr (float): Kritischer Lastfaktor
|
|
307
|
+
- eigenvector (ndarray): Eigenvektor zur kleinsten kritischen Last
|
|
308
|
+
"""
|
|
309
|
+
if not hasattr(self, 'eigenvalues'):
|
|
310
|
+
self.solve_eigenvalue_problem()
|
|
311
|
+
|
|
312
|
+
lambda_cr = self.eigenvalues[0]
|
|
313
|
+
eigenvector = self.eigenvectors[:, 0]
|
|
314
|
+
return lambda_cr, eigenvector
|
|
315
|
+
|
|
316
|
+
def write_latex_output(
|
|
317
|
+
self, filename, include_k_matrix=False, include_g_matrix=False, matrix_size=10
|
|
318
|
+
):
|
|
319
|
+
"""
|
|
320
|
+
Schreibt die Dokumentation der Berechnung in eine LaTeX-Datei.
|
|
321
|
+
|
|
322
|
+
Parameters:
|
|
323
|
+
- filename (str): Pfad zur Ausgabedatei (.tex)
|
|
324
|
+
- include_k_matrix (bool): Ob die Steifigkeitsmatrix K ausgegeben werden soll
|
|
325
|
+
- include_g_matrix (bool): Ob die Massenmatrix G ausgegeben werden soll
|
|
326
|
+
- matrix_size (int): Größe der auszuschreibenden Matrix (z.B. 10 für eine 10x10 Matrix)
|
|
327
|
+
"""
|
|
328
|
+
# Stellen Sie sicher, dass die Matrizen und Eigenwerte berechnet sind
|
|
329
|
+
if not hasattr(self, "K") or not hasattr(self, "G"):
|
|
330
|
+
self.assemble_matrices()
|
|
331
|
+
if not hasattr(self, "eigenvalues") or not hasattr(self, "eigenvectors"):
|
|
332
|
+
self.solve_eigenvalue_problem()
|
|
333
|
+
|
|
334
|
+
with open(filename, "w", encoding="utf-8") as f:
|
|
335
|
+
# Präambel
|
|
336
|
+
f.write(r"\documentclass{article}" + "\n")
|
|
337
|
+
f.write(r"\usepackage{amsmath, amssymb, booktabs, geometry}" + "\n")
|
|
338
|
+
f.write(r"\usepackage{graphicx}" + "\n")
|
|
339
|
+
f.write(r"\usepackage[utf8]{inputenc}" + "\n") # UTF-8 Eingabe
|
|
340
|
+
f.write(r"\usepackage[T1]{fontenc}" + "\n") # Schriftkodierung
|
|
341
|
+
f.write(r"\usepackage{lmodern}" + "\n") # Latin Modern Schriftart
|
|
342
|
+
f.write(r"\usepackage{psfrag,epsfig}" + "\n")
|
|
343
|
+
f.write(r"\usepackage{siunitx}")
|
|
344
|
+
f.write(
|
|
345
|
+
r"\allowdisplaybreaks % Erlaubt Seitenumbrüche in Gleichungsumgebungen"
|
|
346
|
+
+ "\n"
|
|
347
|
+
)
|
|
348
|
+
f.write(r"\geometry{a4paper, margin=1in}" + "\n")
|
|
349
|
+
f.write(r"\begin{document}" + "\n\n")
|
|
350
|
+
|
|
351
|
+
# Titel
|
|
352
|
+
f.write(r"\title{Dokumentation der Plattenbeulanalyse}" + "\n")
|
|
353
|
+
f.write(r"\author{Erstellt mit PlateBucklingRitz}" + "\n")
|
|
354
|
+
f.write(r"\date{\today}" + "\n")
|
|
355
|
+
f.write(r"\maketitle" + "\n\n")
|
|
356
|
+
|
|
357
|
+
# Einleitung
|
|
358
|
+
f.write(r"\section{Einleitung}" + "\n")
|
|
359
|
+
f.write(
|
|
360
|
+
"Diese Dokumentation enthält die Ergebnisse der Plattenbeulanalyse unter Verwendung der Ritz-Methode. "
|
|
361
|
+
"Die Berechnung umfasst die Bestimmung der kritischen Beullasten sowie der zugehörigen Beulformen.\n\n"
|
|
362
|
+
)
|
|
363
|
+
|
|
364
|
+
# Parameterübersicht in einer Tabelle
|
|
365
|
+
f.write(r"\section{Eingangsparameter}" + "\n")
|
|
366
|
+
f.write(
|
|
367
|
+
"Die folgenden Tabellen fassen die Eingangsparameter der Berechnung zusammen.\n\n"
|
|
368
|
+
)
|
|
369
|
+
|
|
370
|
+
f.write(r"\begin{table}[h!]" + "\n")
|
|
371
|
+
f.write(r"\centering" + "\n")
|
|
372
|
+
f.write(r"\begin{tabular}{ll}" + "\n")
|
|
373
|
+
f.write(r"\toprule" + "\n")
|
|
374
|
+
f.write(r"\textbf{Parameter} & \textbf{Wert} \\" + "\n")
|
|
375
|
+
f.write(r"\midrule" + "\n")
|
|
376
|
+
# Tabelle mit den Eingangsparametern
|
|
377
|
+
f.write(f"Länge der Platte in x-Richtung, $a$ (m) & {self.a} \\\\" + "\n")
|
|
378
|
+
f.write(f"Breite der Platte in y-Richtung, $b$ (m) & {self.b} \\\\" + "\n")
|
|
379
|
+
f.write(f"Dicke der Platte, $t$ (m) & {self.t} \\\\" + "\n")
|
|
380
|
+
f.write(f"Elastizitätsmodul, $E$ (MPa) & {self.E} \\\\" + "\n")
|
|
381
|
+
f.write(f"Poissonzahl, $\\nu$ & {self.nu} \\\\" + "\n")
|
|
382
|
+
f.write(
|
|
383
|
+
f"Normalkraft in x-Richtung, $N_x(y)$ (MN/m) & $N_{{x0}}$ = {self.Nx0}, $N_{{x1}}$ = {self.Nx1} \\\\"
|
|
384
|
+
+ "\n"
|
|
385
|
+
)
|
|
386
|
+
f.write(
|
|
387
|
+
f"Normalkraft in y-Richtung, $N_y(x)$ (MN/m) & $N_{{y0}}$ = {self.Ny0}, $N_{{y1}}$ = {self.Ny1} \\\\"
|
|
388
|
+
+ "\n"
|
|
389
|
+
)
|
|
390
|
+
f.write(
|
|
391
|
+
f"Schubkraft pro Längeneinheit, $N_{{xy}}$ (MN/m) & {self.Nxy} \\\\"
|
|
392
|
+
+ "\n"
|
|
393
|
+
)
|
|
394
|
+
f.write(f"Ansatzfunktionen: m & {self.m_terms} \\\\" + "\n")
|
|
395
|
+
f.write(f"Ansatzfunktionen: n & {self.n_terms} \\\\" + "\n")
|
|
396
|
+
f.write(
|
|
397
|
+
f"Positionen der Quersteifen (x-Richtung) (m) & {self.x_s_positions} \\\\"
|
|
398
|
+
+ "\n"
|
|
399
|
+
)
|
|
400
|
+
f.write(
|
|
401
|
+
f"Flächenmomente der Quersteifen (m$^4$) & {self.I_s_values} \\\\"
|
|
402
|
+
+ "\n"
|
|
403
|
+
)
|
|
404
|
+
f.write(
|
|
405
|
+
f"Positionen der Längssteifen (y-Richtung) (m) & {self.y_s_positions} \\\\"
|
|
406
|
+
+ "\n"
|
|
407
|
+
)
|
|
408
|
+
f.write(
|
|
409
|
+
f"Flächenmomente der Längssteifen (m$^4$) & {self.I_t_values} \\\\"
|
|
410
|
+
+ "\n"
|
|
411
|
+
)
|
|
412
|
+
f.write(r"\bottomrule" + "\n")
|
|
413
|
+
f.write(r"\end{tabular}" + "\n")
|
|
414
|
+
f.write(r"\caption{Übersicht der Eingangsparameter}" + "\n")
|
|
415
|
+
f.write(r"\label{tab:input_parameters}" + "\n")
|
|
416
|
+
f.write(r"\end{table}" + "\n\n")
|
|
417
|
+
|
|
418
|
+
# Eigenwerte
|
|
419
|
+
f.write(r"\section{Eigenwerte und Kritische Lasten}" + "\n")
|
|
420
|
+
f.write(
|
|
421
|
+
"Die folgenden Eigenwerte repräsentieren die kritischen Beullasten der Platte. "
|
|
422
|
+
"Nur die positiven Eigenwerte werden berücksichtigt.\n\n"
|
|
423
|
+
)
|
|
424
|
+
|
|
425
|
+
# Tabelle der Eigenwerte
|
|
426
|
+
f.write(r"\begin{table}[htbp!]" + "\n")
|
|
427
|
+
f.write(r"\centering" + "\n")
|
|
428
|
+
f.write(r"\begin{tabular}{|c|c|}" + "\n")
|
|
429
|
+
f.write(r"\hline" + "\n")
|
|
430
|
+
f.write(r"Index & Kritische Last ($\lambda_{\text{cr}}$) \\" + "\n")
|
|
431
|
+
f.write(r"\hline" + "\n")
|
|
432
|
+
for idx, eigenvalue in enumerate(self.eigenvalues[0:10]):
|
|
433
|
+
f.write(f"{idx+1} & {eigenvalue:.4f} \\\\" + "\n")
|
|
434
|
+
f.write(r"\hline" + "\n")
|
|
435
|
+
f.write(r"\end{tabular}" + "\n")
|
|
436
|
+
f.write(r"\caption{Liste der positiven Eigenwerte}" + "\n")
|
|
437
|
+
f.write(r"\label{tab:eigenvalues}" + "\n")
|
|
438
|
+
f.write(r"\end{table}" + "\n\n")
|
|
439
|
+
|
|
440
|
+
f.write(r"\clearpage" + "\n")
|
|
441
|
+
|
|
442
|
+
# Kritische Beulspannung
|
|
443
|
+
f.write(r"\subsection{Kritische Beulspannung}" + "\n")
|
|
444
|
+
f.write(
|
|
445
|
+
"Die kleinste kritische Beullast ist der erste Eigenwert und entspricht der "
|
|
446
|
+
"kritischen Beulspannung der Platte.\n\n"
|
|
447
|
+
)
|
|
448
|
+
f.write(r"\begin{flalign*}" + "\n")
|
|
449
|
+
f.write(r"& \lambda_{\text{cr}} = " + f"{self.eigenvalues[0]:.4f} & " + "\n")
|
|
450
|
+
f.write(r"\end{flalign*}" + "\n\n")
|
|
451
|
+
|
|
452
|
+
|
|
453
|
+
f.write(
|
|
454
|
+
"Für den Beulwert für das maßgebende Gesamtfeldbeulen gilt: \n\n"
|
|
455
|
+
)
|
|
456
|
+
f.write(r"\begin{flalign*}" + "\n")
|
|
457
|
+
f.write(r"& \lambda_{\text{cr}} = " + f"{self.get_critical_load_m1_mode()[0]:.4f} & " + "\n")
|
|
458
|
+
f.write(r"\end{flalign*}" + "\n\n")
|
|
459
|
+
|
|
460
|
+
# Weitere Berechnungen (z.B. sigma_e, k_sigma, k_tau)
|
|
461
|
+
sigma_e = (
|
|
462
|
+
np.pi**2 * self.E / (12 * (1 - self.nu**2)) * (self.t / self.b) ** 2
|
|
463
|
+
)
|
|
464
|
+
k_sigma = self.eigenvalues[0] * self.Nx0 / self.t / sigma_e
|
|
465
|
+
k_tau = self.eigenvalues[0] * self.Nxy / self.t / sigma_e
|
|
466
|
+
|
|
467
|
+
f.write(r"\subsection{Zusätzliche Berechnungen}" + "\n")
|
|
468
|
+
f.write(
|
|
469
|
+
"Basierend auf der kleinsten kritischen Last werden weitere Spannungen berechnet:\n\n"
|
|
470
|
+
)
|
|
471
|
+
f.write(r"\begin{align}" + "\n")
|
|
472
|
+
f.write(
|
|
473
|
+
f"k_\\sigma &= \\frac{{\\lambda_{{\\text{{cr}}}} \\cdot N_x0}}{{t \\cdot \\sigma_e}} = {k_sigma:.4f} \\\\"
|
|
474
|
+
+ "\n"
|
|
475
|
+
)
|
|
476
|
+
f.write(
|
|
477
|
+
f"k_\\tau &= \\frac{{\\lambda_{{\\text{{cr}}}} \\cdot N_{{xy}}}}{{t \\cdot \\sigma_e}} = {k_tau:.4f}"
|
|
478
|
+
+ "\n"
|
|
479
|
+
)
|
|
480
|
+
f.write(r"\end{align}" + "\n\n")
|
|
481
|
+
|
|
482
|
+
f.write(r"Hierbei ist $\sigma_e$ gegeben durch: \\" + "\n")
|
|
483
|
+
f.write(r"\begin{equation}" + "\n")
|
|
484
|
+
f.write(
|
|
485
|
+
r"\sigma_e = \frac{\pi^2 E}{12(1-\nu^2)} \left(\frac{t}{b}\right)^2 = "
|
|
486
|
+
+ f"{sigma_e:.4f} , "
|
|
487
|
+
+ r"\si{MN/m^2}"
|
|
488
|
+
+ "\n"
|
|
489
|
+
)
|
|
490
|
+
f.write(r"\end{equation} " + "\n")
|
|
491
|
+
|
|
492
|
+
# Optionale Ausgabe der Steifigkeitsmatrix K
|
|
493
|
+
if include_k_matrix:
|
|
494
|
+
f.write(r"\section{Steifigkeitsmatrix $K$}" + "\n")
|
|
495
|
+
f.write(
|
|
496
|
+
f"Die Steifigkeitsmatrix $K$ wird bis zur Größe {matrix_size}x{matrix_size} angezeigt.\n\n"
|
|
497
|
+
)
|
|
498
|
+
f.write(r"\begin{table}[htbp!]" + "\n")
|
|
499
|
+
f.write(r"\centering" + "\n")
|
|
500
|
+
f.write(r"\begin{tabular}{|" + "c|" * (matrix_size + 1) + "}" + "\n")
|
|
501
|
+
f.write(r"\hline" + "\n")
|
|
502
|
+
# Korrigierte Header-Zeile ohne 'i'
|
|
503
|
+
header = (
|
|
504
|
+
"Index & "
|
|
505
|
+
+ " & ".join([f"$K_{{{j+1}}}$" for j in range(matrix_size)])
|
|
506
|
+
+ r" \\"
|
|
507
|
+
+ "\n"
|
|
508
|
+
)
|
|
509
|
+
f.write(header)
|
|
510
|
+
f.write(r"\hline" + "\n")
|
|
511
|
+
for i in range(matrix_size):
|
|
512
|
+
row = (
|
|
513
|
+
f"{i+1} & "
|
|
514
|
+
+ " & ".join([f"{self.K[i,j]:.4e}" for j in range(matrix_size)])
|
|
515
|
+
+ r" \\"
|
|
516
|
+
+ "\n"
|
|
517
|
+
)
|
|
518
|
+
f.write(row)
|
|
519
|
+
f.write(r"\hline" + "\n")
|
|
520
|
+
f.write(r"\end{tabular}" + "\n")
|
|
521
|
+
f.write(r"\caption{Steifigkeitsmatrix $K$ (Teilansicht)}" + "\n")
|
|
522
|
+
f.write(r"\label{tab:K_matrix}" + "\n")
|
|
523
|
+
f.write(r"\end{table}" + "\n\n")
|
|
524
|
+
|
|
525
|
+
# Optionale Ausgabe der Massenmatrix G
|
|
526
|
+
if include_g_matrix:
|
|
527
|
+
f.write(r"\section{Geometrische Steifigkeitsmatrix $G$}" + "\n")
|
|
528
|
+
f.write(
|
|
529
|
+
f"Die geometrische Steifigkeitsmatrix $G$ wird bis zur Größe {matrix_size}x{matrix_size} angezeigt.\n\n"
|
|
530
|
+
)
|
|
531
|
+
f.write(r"\begin{table}[htbp!]" + "\n")
|
|
532
|
+
f.write(r"\centering" + "\n")
|
|
533
|
+
f.write(r"\begin{tabular}{|" + "c|" * (matrix_size + 1) + "}" + "\n")
|
|
534
|
+
f.write(r"\hline" + "\n")
|
|
535
|
+
# Korrigierte Header-Zeile ohne 'i'
|
|
536
|
+
header = (
|
|
537
|
+
"Index & "
|
|
538
|
+
+ " & ".join([f"$G_{{{j+1}}}$" for j in range(matrix_size)])
|
|
539
|
+
+ r" \\"
|
|
540
|
+
+ "\n"
|
|
541
|
+
)
|
|
542
|
+
f.write(header)
|
|
543
|
+
f.write(r"\hline" + "\n")
|
|
544
|
+
for i in range(matrix_size):
|
|
545
|
+
row = (
|
|
546
|
+
f"{i+1} & "
|
|
547
|
+
+ " & ".join([f"{self.G[i,j]:.4e}" for j in range(matrix_size)])
|
|
548
|
+
+ r" \\"
|
|
549
|
+
+ "\n"
|
|
550
|
+
)
|
|
551
|
+
f.write(row)
|
|
552
|
+
f.write(r"\hline" + "\n")
|
|
553
|
+
f.write(r"\end{tabular}" + "\n")
|
|
554
|
+
f.write(r"\caption{Massenmatrix $G$ (Teilansicht)}" + "\n")
|
|
555
|
+
f.write(r"\label{tab:G_matrix}" + "\n")
|
|
556
|
+
f.write(r"\end{table}" + "\n\n")
|
|
557
|
+
|
|
558
|
+
# Eigenvektoren (Beulformen)
|
|
559
|
+
f.write(r"\section{Eigenvektoren (Beulformen)}" + "\n")
|
|
560
|
+
f.write(
|
|
561
|
+
"Die Eigenvektoren entsprechen den Beulformen der Platte für die jeweiligen kritischen Lasten.\n\n"
|
|
562
|
+
)
|
|
563
|
+
|
|
564
|
+
# Beispiel für die erste Beulform
|
|
565
|
+
f.write(r"\subsection{Beulform für die kleinste kritische Last}" + "\n")
|
|
566
|
+
f.write(
|
|
567
|
+
"Die folgende Abbildung zeigt die Beulform der Platte für die kleinste kritische Last.\n\n"
|
|
568
|
+
)
|
|
569
|
+
|
|
570
|
+
# Berechnung und Einfügen der Beulform
|
|
571
|
+
X, Y, W = self.get_buckling_mode()
|
|
572
|
+
# Speichern der Beulform als Bild
|
|
573
|
+
plot_filename = "buckling_mode"
|
|
574
|
+
# Plotten beider Eigenformen nebeneinander
|
|
575
|
+
import matplotlib.pyplot as plt
|
|
576
|
+
from mpl_toolkits.mplot3d import Axes3D
|
|
577
|
+
|
|
578
|
+
fig = plt.figure(figsize=(16, 6))
|
|
579
|
+
|
|
580
|
+
# Plot für die erste Eigenform
|
|
581
|
+
ax1 = fig.add_subplot(1, 2, 1, projection="3d")
|
|
582
|
+
ax1.plot_surface(X_first, Y_first, W_first, cmap="viridis", alpha=0.5)
|
|
583
|
+
ax1.set_xlabel("x (m)")
|
|
584
|
+
ax1.set_ylabel("y (m)")
|
|
585
|
+
ax1.set_zlabel("w (m)")
|
|
586
|
+
ax1.set_title("Erste Eigenform (kleinste kritische Last)")
|
|
587
|
+
|
|
588
|
+
# Plotten der Längssteifen (x-Richtung)
|
|
589
|
+
for x_s, I_s in zip(plate.x_s_positions, plate.I_s_values):
|
|
590
|
+
if I_s > 1e-8:
|
|
591
|
+
x_idx = (np.abs(X_first[0, :] - x_s)).argmin()
|
|
592
|
+
x_val = X_first[0, x_idx]
|
|
593
|
+
y_vals = Y_first[:, x_idx]
|
|
594
|
+
w_vals = W_first[:, x_idx]
|
|
595
|
+
ax1.plot([x_val] * len(y_vals), y_vals, w_vals, color="black", linewidth=10)
|
|
596
|
+
|
|
597
|
+
# Plotten der Quersteifen (y-Richtung)
|
|
598
|
+
for y_s, I_t in zip(plate.y_s_positions, plate.I_t_values):
|
|
599
|
+
if I_t > 1e-8:
|
|
600
|
+
y_idx = (np.abs(Y_first[:, 0] - y_s)).argmin()
|
|
601
|
+
y_val = Y_first[y_idx, 0]
|
|
602
|
+
x_vals = X_first[y_idx, :]
|
|
603
|
+
w_vals = W_first[y_idx, :]
|
|
604
|
+
ax1.plot(x_vals, [y_val] * len(x_vals), w_vals, color="black", linewidth=10)
|
|
605
|
+
|
|
606
|
+
# Plot für den dominanten m=1 Modus
|
|
607
|
+
ax2 = fig.add_subplot(1, 2, 2, projection="3d")
|
|
608
|
+
if X_m1 is not None:
|
|
609
|
+
ax2.plot_surface(X_m1, Y_m1, W_m1, cmap="viridis", alpha=0.5)
|
|
610
|
+
ax2.set_xlabel("x (m)")
|
|
611
|
+
ax2.set_ylabel("y (m)")
|
|
612
|
+
ax2.set_zlabel("w (m)")
|
|
613
|
+
ax2.set_title("Dominanter Eigenmodus mit m=1")
|
|
614
|
+
|
|
615
|
+
# Plotten der Längssteifen (x-Richtung)
|
|
616
|
+
for x_s, I_s in zip(plate.x_s_positions, plate.I_s_values):
|
|
617
|
+
if I_s > 1e-8:
|
|
618
|
+
x_idx = (np.abs(X_m1[0, :] - x_s)).argmin()
|
|
619
|
+
x_val = X_m1[0, x_idx]
|
|
620
|
+
y_vals = Y_m1[:, x_idx]
|
|
621
|
+
w_vals = W_m1[:, x_idx]
|
|
622
|
+
ax2.plot([x_val] * len(y_vals), y_vals, w_vals, color="black", linewidth=10)
|
|
623
|
+
|
|
624
|
+
# Plotten der Quersteifen (y-Richtung)
|
|
625
|
+
for y_s, I_t in zip(plate.y_s_positions, plate.I_t_values):
|
|
626
|
+
if I_t > 1e-8:
|
|
627
|
+
y_idx = (np.abs(Y_m1[:, 0] - y_s)).argmin()
|
|
628
|
+
y_val = Y_m1[y_idx, 0]
|
|
629
|
+
x_vals = X_m1[y_idx, :]
|
|
630
|
+
w_vals = W_m1[y_idx, :]
|
|
631
|
+
ax2.plot(x_vals, [y_val] * len(x_vals), w_vals, color="black", linewidth=10)
|
|
632
|
+
else:
|
|
633
|
+
ax2.text(0.5, 0.5, 0.5, "Kein dominanter m=1 Modus gefunden.", ha='center')
|
|
634
|
+
ax2.axis('off')
|
|
635
|
+
plt.savefig(r"Dokumentation/Abbildungen/" + plot_filename + ".png")
|
|
636
|
+
plt.savefig(r"Dokumentation/Abbildungen/" + plot_filename + ".eps", format="eps")
|
|
637
|
+
plt.close(fig)
|
|
638
|
+
|
|
639
|
+
# Einfügen des Bildes in LaTeX
|
|
640
|
+
f.write(r"\begin{figure}[h!]" + "\n")
|
|
641
|
+
f.write(r"\centering" + "\n")
|
|
642
|
+
f.write(
|
|
643
|
+
r"\includegraphics[width=0.8\textwidth]{Abbildungen/"
|
|
644
|
+
+ f"{plot_filename}.eps"
|
|
645
|
+
+ "}"
|
|
646
|
+
+ "\n"
|
|
647
|
+
)
|
|
648
|
+
f.write(
|
|
649
|
+
r"\caption{Beulform der Platte für die kleinste kritische Last}" + "\n"
|
|
650
|
+
)
|
|
651
|
+
f.write(r"\label{fig:buckling_mode}" + "\n")
|
|
652
|
+
f.write(r"\end{figure}" + "\n\n")
|
|
653
|
+
|
|
654
|
+
# Abschluss des Dokuments
|
|
655
|
+
f.write(r"\end{document}" + "\n")
|
|
656
|
+
|
|
657
|
+
print(f"LaTeX-Dokument erfolgreich erstellt: {filename}")
|
|
658
|
+
|
|
File without changes
|