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.
- KIB_LAP/Betonbau/TEST_Rectangular.py +21 -0
- KIB_LAP/Betonbau/beam_rectangular.py +4 -0
- KIB_LAP/FACHWERKEBEN/Elements.py +209 -0
- KIB_LAP/FACHWERKEBEN/InputData.py +118 -0
- KIB_LAP/FACHWERKEBEN/Iteration.py +967 -0
- KIB_LAP/FACHWERKEBEN/Materials.py +30 -0
- KIB_LAP/FACHWERKEBEN/Plotting.py +681 -0
- KIB_LAP/FACHWERKEBEN/__init__.py +4 -0
- KIB_LAP/FACHWERKEBEN/main.py +27 -0
- KIB_LAP/Plattentragwerke/PlateBendingKirchhoff.py +36 -29
- KIB_LAP/STABRAUM/InputData.py +13 -2
- KIB_LAP/STABRAUM/Output_Data.py +61 -0
- KIB_LAP/STABRAUM/Plotting.py +1453 -0
- KIB_LAP/STABRAUM/Programm.py +518 -1026
- KIB_LAP/STABRAUM/Steifigkeitsmatrix.py +338 -117
- KIB_LAP/STABRAUM/main.py +58 -0
- KIB_LAP/STABRAUM/results.py +37 -0
- KIB_LAP/Scheibe/Assemble_Stiffness.py +246 -0
- KIB_LAP/Scheibe/Element_Stiffness.py +362 -0
- KIB_LAP/Scheibe/Meshing.py +365 -0
- KIB_LAP/Scheibe/Output.py +34 -0
- KIB_LAP/Scheibe/Plotting.py +722 -0
- KIB_LAP/Scheibe/Shell_Calculation.py +523 -0
- KIB_LAP/Scheibe/Testing_Mesh.py +25 -0
- KIB_LAP/Scheibe/__init__.py +14 -0
- KIB_LAP/Scheibe/main.py +33 -0
- KIB_LAP/StabEbenRitz/Biegedrillknicken.py +757 -0
- KIB_LAP/StabEbenRitz/Biegedrillknicken_Trigeometry.py +328 -0
- KIB_LAP/StabEbenRitz/Querschnittswerte.py +527 -0
- KIB_LAP/StabEbenRitz/Stabberechnung_Klasse.py +868 -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 → kib_lap-0.7.7.dist-info}/METADATA +1 -1
- {kib_lap-0.5.dist-info → kib_lap-0.7.7.dist-info}/RECORD +37 -19
- Examples/Cross_Section_Thin.py +0 -61
- KIB_LAP/Betonbau/Bemessung_Zust_II.py +0 -648
- KIB_LAP/Betonbau/Iterative_Design.py +0 -723
- KIB_LAP/Plattentragwerke/NumInte.cpp +0 -23
- KIB_LAP/Plattentragwerke/NumericalIntegration.cpp +0 -23
- KIB_LAP/Plattentragwerke/plate_bending_cpp.cp313-win_amd64.pyd +0 -0
- KIB_LAP/main.py +0 -2
- {Examples → KIB_LAP/StabEbenRitz}/__init__.py +0 -0
- {kib_lap-0.5.dist-info → kib_lap-0.7.7.dist-info}/WHEEL +0 -0
- {kib_lap-0.5.dist-info → kib_lap-0.7.7.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
from scipy.sparse import csr_matrix
|
|
3
|
+
from scipy.sparse.linalg import cg
|
|
4
|
+
import matplotlib.pyplot as plt
|
|
5
|
+
import matplotlib.patches as patches
|
|
6
|
+
from matplotlib.widgets import Slider
|
|
7
|
+
|
|
8
|
+
try:
|
|
9
|
+
from Element_Stiffness import Stiffness_Matrix
|
|
10
|
+
from Meshing import MeshingClass
|
|
11
|
+
except:
|
|
12
|
+
from KIB_LAP.Scheibe.Element_Stiffness import Stiffness_Matrix
|
|
13
|
+
from KIB_LAP.Scheibe.Meshing import MeshingClass
|
|
14
|
+
|
|
15
|
+
import pandas as pd
|
|
16
|
+
from tabulate import *
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class Assembled_Matrices:
|
|
20
|
+
def __init__(
|
|
21
|
+
self,
|
|
22
|
+
_mesh,
|
|
23
|
+
EL,
|
|
24
|
+
NL,
|
|
25
|
+
EL_Matrices,
|
|
26
|
+
_ElementLoadVector,
|
|
27
|
+
_ElementLoadVectorNodes,
|
|
28
|
+
_ElementLoadVectorAreaLoads,
|
|
29
|
+
_ElementLoadVectorAreaLoadsNodes,
|
|
30
|
+
load_input="csv",
|
|
31
|
+
bc_input="csv",
|
|
32
|
+
):
|
|
33
|
+
# Meshing
|
|
34
|
+
self.mesh = _mesh
|
|
35
|
+
|
|
36
|
+
self.EL = EL
|
|
37
|
+
self.NL = NL
|
|
38
|
+
# Generate element stiffness matrices
|
|
39
|
+
self.ElementLoadVector = _ElementLoadVector
|
|
40
|
+
self.ElementLoadVectorNodes = _ElementLoadVectorNodes
|
|
41
|
+
self.ElementLoadVectorAreaLoads = _ElementLoadVectorAreaLoads
|
|
42
|
+
self.ElementLoadVectorAreaLoadsNodes = _ElementLoadVectorAreaLoadsNodes
|
|
43
|
+
# Assemble Stiffness matrices
|
|
44
|
+
self._EL = np.array(EL)
|
|
45
|
+
self._NoE = self._EL.shape[0]
|
|
46
|
+
self._NPE = self._EL.shape[1]
|
|
47
|
+
self.NoN = len(NL)
|
|
48
|
+
self.PD = len(NL[0])
|
|
49
|
+
self._EL_Matrices = np.array(EL_Matrices)
|
|
50
|
+
self.load_input = load_input
|
|
51
|
+
self.bc_input = bc_input
|
|
52
|
+
|
|
53
|
+
self.K_Assemble = np.zeros((self.NoN * self.PD, self.NoN * self.PD))
|
|
54
|
+
self.K_Assemble_BC = None
|
|
55
|
+
self.Index_Vector_BC = []
|
|
56
|
+
|
|
57
|
+
def assemble_K(self):
|
|
58
|
+
for i in range(self._NoE):
|
|
59
|
+
Index_Vector = np.zeros(self._NPE * 2, dtype=int)
|
|
60
|
+
for j in range(self._NPE):
|
|
61
|
+
Index_Vector[j] = int(self._EL[i, j] * 2 - 2)
|
|
62
|
+
Index_Vector[j + self._NPE] = int(self._EL[i, j] * 2 - 1)
|
|
63
|
+
|
|
64
|
+
for row in range(len(Index_Vector)):
|
|
65
|
+
ind_row = Index_Vector[row]
|
|
66
|
+
for col in range(len(Index_Vector)):
|
|
67
|
+
ind_col = Index_Vector[col]
|
|
68
|
+
self.K_Assemble[ind_row, ind_col] += self._EL_Matrices[i][row][col]
|
|
69
|
+
|
|
70
|
+
def Load_BC(self):
|
|
71
|
+
if self.bc_input == "console":
|
|
72
|
+
# Implementieren Sie hier die Konsoleneingabe
|
|
73
|
+
pass
|
|
74
|
+
else:
|
|
75
|
+
try:
|
|
76
|
+
self.BC = pd.DataFrame(
|
|
77
|
+
pd.read_csv("Boundary_Conditions/Spring_Elements.csv")
|
|
78
|
+
)
|
|
79
|
+
except:
|
|
80
|
+
"""
|
|
81
|
+
This exception is used, if the main file is started from a subfolder (e.g. the parametric studies or testing) \n
|
|
82
|
+
folder \n
|
|
83
|
+
"""
|
|
84
|
+
self.BC = pd.DataFrame(
|
|
85
|
+
pd.read_csv("../Boundary_Conditions/Spring_Elements.csv")
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
def apply_BC(self):
|
|
89
|
+
self.K_Assemble_BC = np.copy(self.K_Assemble)
|
|
90
|
+
self.Index_Vector_BC = np.zeros(0, dtype=int)
|
|
91
|
+
self.stiffness_spring = []
|
|
92
|
+
|
|
93
|
+
for i in range(len(self.BC["No"])):
|
|
94
|
+
node = self.BC["No"][i]
|
|
95
|
+
dof = self.BC["DOF"][i]
|
|
96
|
+
stiffness = self.BC["cf in [MN/m]"][i]
|
|
97
|
+
print("Stiffness ", stiffness)
|
|
98
|
+
print(node)
|
|
99
|
+
# Überprüfen, ob der Knoten ein numerischer Wert ist
|
|
100
|
+
if str(node).isdigit():
|
|
101
|
+
node = int(node)
|
|
102
|
+
if dof == "x":
|
|
103
|
+
self.Index_Vector_BC = np.append(self.Index_Vector_BC, (node - 1) * 2)
|
|
104
|
+
elif dof == "z":
|
|
105
|
+
self.Index_Vector_BC = np.append(self.Index_Vector_BC, (node - 1) * 2 + 1)
|
|
106
|
+
elif node == "left":
|
|
107
|
+
nodes = self.mesh.get_left_border_nodes()
|
|
108
|
+
print("LEFT DOF")
|
|
109
|
+
print(dof)
|
|
110
|
+
for p in nodes:
|
|
111
|
+
if dof == "x":
|
|
112
|
+
self.Index_Vector_BC = np.append(self.Index_Vector_BC, (p - 1) * 2)
|
|
113
|
+
elif dof == "z":
|
|
114
|
+
self.Index_Vector_BC = np.append(self.Index_Vector_BC, (p - 1) * 2 + 1)
|
|
115
|
+
else:
|
|
116
|
+
print("Exception. No valid coordinate input for the left boundary.")
|
|
117
|
+
elif node == "right":
|
|
118
|
+
nodes = self.mesh.get_right_border_nodes()
|
|
119
|
+
for p in nodes:
|
|
120
|
+
if dof == "x":
|
|
121
|
+
self.Index_Vector_BC = np.append(self.Index_Vector_BC, (p - 1) * 2)
|
|
122
|
+
elif dof == "z":
|
|
123
|
+
self.Index_Vector_BC = np.append(self.Index_Vector_BC, (p - 1) * 2 + 1)
|
|
124
|
+
else:
|
|
125
|
+
print("Exception. No valid coordinate input for the right boundary.")
|
|
126
|
+
else:
|
|
127
|
+
print("The input isn't usable! Please change the DOF of the boundary condition at Position "
|
|
128
|
+
+ str(i + 1) + "\n")
|
|
129
|
+
|
|
130
|
+
try:
|
|
131
|
+
self.stiffness_spring.append(stiffness)
|
|
132
|
+
except:
|
|
133
|
+
print("Error with the spring stiffness")
|
|
134
|
+
|
|
135
|
+
self.Index_Vector_BC = sorted(self.Index_Vector_BC)
|
|
136
|
+
|
|
137
|
+
p = 0
|
|
138
|
+
for index in sorted(self.Index_Vector_BC, reverse=True):
|
|
139
|
+
self.K_Assemble_BC[index][index] += self.stiffness_spring[p]
|
|
140
|
+
p+=1
|
|
141
|
+
|
|
142
|
+
print(self.Index_Vector_BC)
|
|
143
|
+
|
|
144
|
+
def LoadInput(self):
|
|
145
|
+
self.Einzellasten = False
|
|
146
|
+
self.Linienlasten = False
|
|
147
|
+
if self.load_input == "console":
|
|
148
|
+
# Implementieren Sie hier die Konsoleneingabe
|
|
149
|
+
pass
|
|
150
|
+
else:
|
|
151
|
+
try:
|
|
152
|
+
self.NodalForces = pd.DataFrame(pd.read_csv("Loading/Nodal_Loads.csv"))
|
|
153
|
+
self.ElementLoads = pd.DataFrame(
|
|
154
|
+
pd.read_csv("Loading/Element_Loads.csv")
|
|
155
|
+
)
|
|
156
|
+
except:
|
|
157
|
+
self.NodalForces = pd.DataFrame(
|
|
158
|
+
pd.read_csv("../Loading/Nodal_Loads.csv")
|
|
159
|
+
)
|
|
160
|
+
self.ElementLoads = pd.DataFrame(
|
|
161
|
+
pd.read_csv("../Loading/Element_Loads.csv")
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
def GenerateLoadVector(self):
|
|
165
|
+
self.Load_Vector = np.zeros(len(self.K_Assemble_BC))
|
|
166
|
+
|
|
167
|
+
for i in range(0, len(self.NodalForces["DOF"])):
|
|
168
|
+
if self.NodalForces["DOF"][i] == "x":
|
|
169
|
+
index_load = (self.NodalForces["No"][i] - 1) * 2 # x-Direction
|
|
170
|
+
self.Load_Vector[index_load] = self.NodalForces["F in [MN]"][i]
|
|
171
|
+
elif self.NodalForces["DOF"][i] == "z":
|
|
172
|
+
index_load = (self.NodalForces["No"][i] - 1) * 2 + 1 # z-Direction
|
|
173
|
+
self.Load_Vector[index_load] = self.NodalForces["F in [MN]"][i]
|
|
174
|
+
|
|
175
|
+
else:
|
|
176
|
+
print(
|
|
177
|
+
"The input isn't usable! Please change the DOF of the boundary condition at Position "
|
|
178
|
+
+ i
|
|
179
|
+
+ 1
|
|
180
|
+
+ "\n"
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
for i in range(0, len(self.ElementLoadVectorNodes)):
|
|
184
|
+
index_load_x = int((self.ElementLoadVectorNodes[i] - 1) * 2)
|
|
185
|
+
index_load_z = int((self.ElementLoadVectorNodes[i] - 1) * 2 + 1)
|
|
186
|
+
|
|
187
|
+
self.Load_Vector[index_load_x] += self.ElementLoadVector[0][i]
|
|
188
|
+
self.Load_Vector[index_load_z] += self.ElementLoadVector[1][i]
|
|
189
|
+
|
|
190
|
+
for i in range(0, len(self.ElementLoadVectorAreaLoadsNodes), 1):
|
|
191
|
+
p = 0
|
|
192
|
+
for j in range(0, len(self.ElementLoadVectorAreaLoadsNodes[i]), 1):
|
|
193
|
+
index_load_x = int((self.ElementLoadVectorAreaLoadsNodes[i][j] - 1) * 2)
|
|
194
|
+
index_load_z = int(
|
|
195
|
+
(self.ElementLoadVectorAreaLoadsNodes[i][j] - 1) * 2 + 1
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
self.Load_Vector[index_load_x] += self.ElementLoadVectorAreaLoads[
|
|
199
|
+
p * 2
|
|
200
|
+
][i]
|
|
201
|
+
self.Load_Vector[index_load_z] += self.ElementLoadVectorAreaLoads[
|
|
202
|
+
p * 2 + 1
|
|
203
|
+
][i]
|
|
204
|
+
|
|
205
|
+
p += 1
|
|
206
|
+
|
|
207
|
+
def get_assembled(self):
|
|
208
|
+
return self.K_Assemble
|
|
209
|
+
|
|
210
|
+
def get_assembled_BC(self):
|
|
211
|
+
return self.K_Assemble_BC
|
|
212
|
+
|
|
213
|
+
def Solve(self):
|
|
214
|
+
if len(self.K_Assemble) < 20:
|
|
215
|
+
self.x_reduced = np.linalg.solve(self.K_Assemble_BC, self.Load_Vector)
|
|
216
|
+
else:
|
|
217
|
+
self.x_reduced, sparse_info = cg(self.K_Assemble_BC, self.Load_Vector)
|
|
218
|
+
print("Information about sparse solver ")
|
|
219
|
+
sparse_info
|
|
220
|
+
|
|
221
|
+
self.x_disp = self.x_reduced[::2]
|
|
222
|
+
self.z_disp = self.x_reduced[1::2]
|
|
223
|
+
|
|
224
|
+
def StoreElementDisplacements(self):
|
|
225
|
+
self.disp_element_matrix = np.zeros((8, self._NoE))
|
|
226
|
+
for row in range(0, len(self.EL), 1):
|
|
227
|
+
p = 0
|
|
228
|
+
for col in range(0, len(self.EL[0]), 1):
|
|
229
|
+
index_x = int((self.EL[row][col] - 1) * 2)
|
|
230
|
+
index_z = int((self.EL[row][col] - 1) * 2 + 1)
|
|
231
|
+
|
|
232
|
+
disp_x = self.x_reduced[index_x]
|
|
233
|
+
disp_z = self.x_reduced[index_z]
|
|
234
|
+
|
|
235
|
+
self.disp_element_matrix[p * 2][row] = disp_x
|
|
236
|
+
self.disp_element_matrix[p * 2 + 1][row] = disp_z
|
|
237
|
+
|
|
238
|
+
p += 1
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
def __str__(self):
|
|
242
|
+
output = "Assembled stiffness matrix\n"
|
|
243
|
+
output += tabulate(self.K_Assemble) + "\n"
|
|
244
|
+
output += "Assembled stiffness matrix with boundary conditions\n"
|
|
245
|
+
output += tabulate(self.K_Assemble_BC)
|
|
246
|
+
return output
|
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
import pandas as pd
|
|
3
|
+
from tabulate import *
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Linear_Algebra_Class:
|
|
7
|
+
def matrix_transpose_symmetric(self, matrix, result=None):
|
|
8
|
+
return np.transpose(matrix)
|
|
9
|
+
|
|
10
|
+
def matrix_multiplication(self, mat1, mat2):
|
|
11
|
+
return np.matmul(mat1, mat2)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class Gaucho_Method:
|
|
15
|
+
def __init__(self, J):
|
|
16
|
+
self.J = J
|
|
17
|
+
self.det_J = None
|
|
18
|
+
self.J_inv = None
|
|
19
|
+
|
|
20
|
+
def ldl_decomposition(self):
|
|
21
|
+
self.L = np.linalg.cholesky(self.J)
|
|
22
|
+
self.D = np.diag(np.diag(self.L))
|
|
23
|
+
self.L = self.L / np.sqrt(np.diag(self.L))[:, None]
|
|
24
|
+
|
|
25
|
+
def calculate_inverse_gaucho(self):
|
|
26
|
+
self.J_inv = np.linalg.inv(self.J)
|
|
27
|
+
return self.J_inv
|
|
28
|
+
|
|
29
|
+
def calculate_determinant_gaucho(self):
|
|
30
|
+
self.det_J = np.linalg.det(self.J)
|
|
31
|
+
return self.det_J
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class Stiffness_Matrix:
|
|
35
|
+
def __init__(self, coords, E, nu, t, gamma, _mesh=None):
|
|
36
|
+
self._coords = np.array(coords)
|
|
37
|
+
self._E = E
|
|
38
|
+
self._nu = nu
|
|
39
|
+
self._t = t
|
|
40
|
+
self._gamma = gamma
|
|
41
|
+
|
|
42
|
+
self._coords_T = np.transpose(self._coords)
|
|
43
|
+
self.K = np.zeros((len(coords), len(coords)))
|
|
44
|
+
self.K_ij = np.zeros((len(coords[0]), len(coords[0])))
|
|
45
|
+
self.J = np.zeros((len(coords[0]), len(coords[0])))
|
|
46
|
+
self.J_inv = np.zeros((len(coords[0]), len(coords[0])))
|
|
47
|
+
|
|
48
|
+
self.grad = np.zeros((len(coords[0]), len(coords)))
|
|
49
|
+
self.result_grad = np.zeros((len(coords[0]), len(coords)))
|
|
50
|
+
self.result_grad_T = np.zeros((len(coords), len(coords[0])))
|
|
51
|
+
|
|
52
|
+
self._NPE = len(coords)
|
|
53
|
+
self._PD = len(coords[0])
|
|
54
|
+
self._GPE = 4 # 4 GP for rectangular, 3 for triangular
|
|
55
|
+
|
|
56
|
+
# Gaussian integration
|
|
57
|
+
self.xi, self.eta, self.alpha = 0, 0, 0
|
|
58
|
+
|
|
59
|
+
# Material parameters
|
|
60
|
+
self.delta = 0
|
|
61
|
+
self.C = 0
|
|
62
|
+
self.det_J = 0
|
|
63
|
+
|
|
64
|
+
# Friends
|
|
65
|
+
self.lin_al = Linear_Algebra_Class()
|
|
66
|
+
self.gaucho_ptr = None
|
|
67
|
+
|
|
68
|
+
self.mesh_data = _mesh
|
|
69
|
+
|
|
70
|
+
def gauss_points(self, gp):
|
|
71
|
+
sqrt3_inv = 1 / np.sqrt(3)
|
|
72
|
+
gauss_points = [
|
|
73
|
+
(-sqrt3_inv, -sqrt3_inv, 1),
|
|
74
|
+
(sqrt3_inv, -sqrt3_inv, 1),
|
|
75
|
+
(sqrt3_inv, sqrt3_inv, 1),
|
|
76
|
+
(-sqrt3_inv, sqrt3_inv, 1),
|
|
77
|
+
]
|
|
78
|
+
if self._GPE == 4:
|
|
79
|
+
self.xi, self.eta, self.alpha = gauss_points[gp - 1]
|
|
80
|
+
|
|
81
|
+
def stiffness(self):
|
|
82
|
+
self.K = np.zeros((self._NPE * self._PD, self._NPE * self._PD))
|
|
83
|
+
self.det_J_store = np.zeros((2, 2))
|
|
84
|
+
|
|
85
|
+
self._coords_T = self.lin_al.matrix_transpose_symmetric(self._coords)
|
|
86
|
+
|
|
87
|
+
for i in range(self._NPE):
|
|
88
|
+
for j in range(self._NPE):
|
|
89
|
+
for gp in range(1, self._GPE + 1):
|
|
90
|
+
self.gauss_points(gp)
|
|
91
|
+
self.grad_N_nat()
|
|
92
|
+
self.J = self.lin_al.matrix_multiplication(
|
|
93
|
+
self._coords_T, self.result_grad_T
|
|
94
|
+
)
|
|
95
|
+
self.gaucho_ptr = Gaucho_Method(self.J)
|
|
96
|
+
|
|
97
|
+
self.gaucho_ptr.ldl_decomposition()
|
|
98
|
+
self.J_inv = self.gaucho_ptr.calculate_inverse_gaucho()
|
|
99
|
+
self.det_J = self.gaucho_ptr.calculate_determinant_gaucho()
|
|
100
|
+
|
|
101
|
+
self.grad = self.lin_al.matrix_multiplication( # Transformed B-Matrix (Isoparametric)
|
|
102
|
+
self.J_inv, self.result_grad
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
for a in range(self._PD):
|
|
106
|
+
for b in range(self._PD):
|
|
107
|
+
for c in range(self._PD):
|
|
108
|
+
for d in range(self._PD):
|
|
109
|
+
self.K[a * self._NPE + i, c * self._NPE + j] += (
|
|
110
|
+
self.grad[b, i]
|
|
111
|
+
* self.constitutive(a + 1, b + 1, c + 1, d + 1)
|
|
112
|
+
* self.grad[d, j]
|
|
113
|
+
* self.det_J
|
|
114
|
+
* self.alpha
|
|
115
|
+
* self._t
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
def grad_N_nat(self):
|
|
119
|
+
self.result_grad = np.zeros((self._PD, self._NPE))
|
|
120
|
+
self.result_grad_T = np.zeros((self._NPE, self._PD))
|
|
121
|
+
|
|
122
|
+
if self._NPE == 3:
|
|
123
|
+
self.result_grad[0][0] = 1
|
|
124
|
+
self.result_grad[0][1] = 0
|
|
125
|
+
self.result_grad[0][2] = -1
|
|
126
|
+
|
|
127
|
+
self.result_grad[1][0] = 0
|
|
128
|
+
self.result_grad[1][1] = 1
|
|
129
|
+
self.result_grad[1][2] = -1
|
|
130
|
+
|
|
131
|
+
if self._NPE == 4:
|
|
132
|
+
self.result_grad[0][0] = -0.25 * (1 - self.eta)
|
|
133
|
+
self.result_grad[0][1] = 0.25 * (1 - self.eta)
|
|
134
|
+
self.result_grad[0][2] = 0.25 * (1 + self.eta)
|
|
135
|
+
self.result_grad[0][3] = -0.25 * (1 + self.eta)
|
|
136
|
+
|
|
137
|
+
self.result_grad[1][0] = -0.25 * (1 - self.xi)
|
|
138
|
+
self.result_grad[1][1] = -0.25 * (1 + self.xi)
|
|
139
|
+
self.result_grad[1][2] = 0.25 * (1 + self.xi)
|
|
140
|
+
self.result_grad[1][3] = 0.25 * (1 - self.xi)
|
|
141
|
+
|
|
142
|
+
self.result_grad_T = self.lin_al.matrix_transpose_symmetric(self.result_grad)
|
|
143
|
+
|
|
144
|
+
def N_nat(self, xi, eta):
|
|
145
|
+
self.result_N = np.zeros((2, 8))
|
|
146
|
+
self.result_N_T = np.zeros((8, 2))
|
|
147
|
+
|
|
148
|
+
if self._NPE == 4:
|
|
149
|
+
self.result_N[0][0] = 0.25 * (1 - eta) * (1 - xi)
|
|
150
|
+
self.result_N[0][2] = 0.25 * (1 - eta) * (1 + xi)
|
|
151
|
+
self.result_N[0][4] = 0.25 * (1 + eta) * (1 + xi)
|
|
152
|
+
self.result_N[0][6] = 0.25 * (1 + eta) * (1 - xi)
|
|
153
|
+
|
|
154
|
+
self.result_N[1][1] = 0.25 * (1 - eta) * (1 - xi)
|
|
155
|
+
self.result_N[1][3] = 0.25 * (1 - eta) * (1 + xi)
|
|
156
|
+
self.result_N[1][5] = 0.25 * (1 + eta) * (1 + xi)
|
|
157
|
+
self.result_N[1][7] = 0.25 * (1 + eta) * (1 - xi)
|
|
158
|
+
|
|
159
|
+
self.result_N_T = self.lin_al.matrix_transpose_symmetric(self.result_N)
|
|
160
|
+
|
|
161
|
+
def delta_func(self, i, j):
|
|
162
|
+
return 1 if i == j else 0
|
|
163
|
+
|
|
164
|
+
def constitutive(self, i, j, k, l):
|
|
165
|
+
return (self._E / (2 * (1 + self._nu))) * (
|
|
166
|
+
self.delta_func(i, l) * self.delta_func(j, k)
|
|
167
|
+
+ self.delta_func(i, k) * self.delta_func(j, l)
|
|
168
|
+
) + (self._E * self._nu) / (1 - self._nu**2) * self.delta_func(
|
|
169
|
+
i, j
|
|
170
|
+
) * self.delta_func(
|
|
171
|
+
k, l
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
def element_load_vector(self):
|
|
175
|
+
try:
|
|
176
|
+
self.loading_table = pd.DataFrame(pd.read_csv("Loading/Element_Loads.csv"))
|
|
177
|
+
except:
|
|
178
|
+
self.loading_table = pd.DataFrame(
|
|
179
|
+
pd.read_csv("../Loading/Element_Loads.csv")
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
self.element_loading_vec = np.zeros(8)
|
|
183
|
+
|
|
184
|
+
for i in self.loading_table["type"]:
|
|
185
|
+
if i == "top":
|
|
186
|
+
self.loading_nodes = self.mesh_data.get_top_border_nodes()
|
|
187
|
+
self.node_loading_vec = np.zeros(
|
|
188
|
+
(2, int(len(self.loading_nodes) - 1) * 2)
|
|
189
|
+
)
|
|
190
|
+
self.node_store_vec = np.zeros(int((len(self.loading_nodes) - 1) * 2))
|
|
191
|
+
|
|
192
|
+
for p in range(0, len(self.loading_nodes) - 1):
|
|
193
|
+
npa = self.loading_nodes[p]
|
|
194
|
+
npe = self.loading_nodes[p + 1]
|
|
195
|
+
|
|
196
|
+
self.node_store_vec[p * 2] = npa
|
|
197
|
+
self.node_store_vec[p * 2 + 1] = npe
|
|
198
|
+
|
|
199
|
+
x_npa = self.mesh_data.get_coordinate_x(npa)
|
|
200
|
+
z_npa = self.mesh_data.get_coordinate_z(npa)
|
|
201
|
+
x_npe = self.mesh_data.get_coordinate_x(npe)
|
|
202
|
+
z_npe = self.mesh_data.get_coordinate_z(npa)
|
|
203
|
+
|
|
204
|
+
l_x = abs(x_npe - x_npa)
|
|
205
|
+
l_z = abs(z_npe - z_npa)
|
|
206
|
+
|
|
207
|
+
px = self.loading_table[self.loading_table["type"] == "top"][
|
|
208
|
+
"px"
|
|
209
|
+
].values
|
|
210
|
+
pz = self.loading_table[self.loading_table["type"] == "top"][
|
|
211
|
+
"pz"
|
|
212
|
+
].values
|
|
213
|
+
|
|
214
|
+
# Numerical integration of the load vector at each node with an loadings
|
|
215
|
+
|
|
216
|
+
eta = 1 # At the top boundary, the eta value is 1 for all loops
|
|
217
|
+
WP = 1 # Numerical integration with 2 Gauss Points
|
|
218
|
+
for x in range(0, 2, 1):
|
|
219
|
+
xi = -1 / np.sqrt(3) + 1 / np.sqrt(3) * 2 * x
|
|
220
|
+
self.N_nat(xi, eta)
|
|
221
|
+
|
|
222
|
+
self.p_a_x = (
|
|
223
|
+
self.result_N[0][6] * px
|
|
224
|
+
) # The beginning node is always form-function N4
|
|
225
|
+
self.p_a_z = self.result_N[1][7] * pz
|
|
226
|
+
self.p_e_x = self.result_N[0][4] * px
|
|
227
|
+
self.p_e_z = self.result_N[1][5] * pz
|
|
228
|
+
|
|
229
|
+
self.node_loading_vec[0][p * 2] += self.p_a_x * l_x / 2
|
|
230
|
+
self.node_loading_vec[1][p * 2] += self.p_a_z * l_x / 2
|
|
231
|
+
|
|
232
|
+
self.node_loading_vec[0][p * 2 + 1] += self.p_e_x * l_x / 2
|
|
233
|
+
self.node_loading_vec[1][p * 2 + 1] += self.p_e_z * l_x / 2
|
|
234
|
+
elif i == "bottom":
|
|
235
|
+
self.loading_nodes = self.mesh_data.get_bottom_border_nodes()
|
|
236
|
+
self.node_loading_vec = np.zeros(
|
|
237
|
+
(2, int(len(self.loading_nodes) - 1) * 2)
|
|
238
|
+
)
|
|
239
|
+
self.node_store_vec = np.zeros(int((len(self.loading_nodes) - 1) * 2))
|
|
240
|
+
|
|
241
|
+
for p in range(0, len(self.loading_nodes) - 1):
|
|
242
|
+
npa = self.loading_nodes[p]
|
|
243
|
+
npe = self.loading_nodes[p + 1]
|
|
244
|
+
|
|
245
|
+
self.node_store_vec[p * 2] = npa
|
|
246
|
+
self.node_store_vec[p * 2 + 1] = npe
|
|
247
|
+
|
|
248
|
+
x_npa = self.mesh_data.get_coordinate_x(npa)
|
|
249
|
+
z_npa = self.mesh_data.get_coordinate_z(npa)
|
|
250
|
+
x_npe = self.mesh_data.get_coordinate_x(npe)
|
|
251
|
+
z_npe = self.mesh_data.get_coordinate_z(npa)
|
|
252
|
+
|
|
253
|
+
l_x = abs(x_npe - x_npa)
|
|
254
|
+
l_z = abs(z_npe - z_npa)
|
|
255
|
+
|
|
256
|
+
px = self.loading_table[self.loading_table["type"] == "bottom"][
|
|
257
|
+
"px"
|
|
258
|
+
].values
|
|
259
|
+
pz = self.loading_table[self.loading_table["type"] == "bottom"][
|
|
260
|
+
"pz"
|
|
261
|
+
].values
|
|
262
|
+
|
|
263
|
+
# Numerical integration of the load vector at each node with an loadings
|
|
264
|
+
|
|
265
|
+
eta = 1 # At the top boundary, the eta value is 1 for all loops
|
|
266
|
+
WP = 1 # Numerical integration with 2 Gauss Points
|
|
267
|
+
for x in range(0, 2, 1):
|
|
268
|
+
xi = -1 / np.sqrt(3) + 1 / np.sqrt(3) * 2 * x
|
|
269
|
+
self.N_nat(xi, eta)
|
|
270
|
+
|
|
271
|
+
self.p_a_x = (
|
|
272
|
+
self.result_N[0][6] * px
|
|
273
|
+
) # The beginning node is always form-function N4
|
|
274
|
+
self.p_a_z = self.result_N[1][7] * pz
|
|
275
|
+
self.p_e_x = self.result_N[0][4] * px
|
|
276
|
+
self.p_e_z = self.result_N[1][5] * pz
|
|
277
|
+
|
|
278
|
+
self.node_loading_vec[0][p * 2] += self.p_a_x * l_x / 2
|
|
279
|
+
self.node_loading_vec[1][p * 2] += self.p_a_z * l_x / 2
|
|
280
|
+
|
|
281
|
+
self.node_loading_vec[0][p * 2 + 1] += self.p_e_x * l_x / 2
|
|
282
|
+
self.node_loading_vec[1][p * 2 + 1] += self.p_e_z * l_x / 2
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
if i == "selfweight":
|
|
287
|
+
"""_summary_
|
|
288
|
+
|
|
289
|
+
Note on the Jacobian: The Determinant is needed before the element load vector \n
|
|
290
|
+
from self weight can be calculated. Because it remains constant for all calculations, there is not need to calculate it \n
|
|
291
|
+
in each iteration \n
|
|
292
|
+
"""
|
|
293
|
+
self.q_self = np.zeros(8)
|
|
294
|
+
self.q_self[1:9:2] = self._gamma * self._t
|
|
295
|
+
|
|
296
|
+
WP_xi = 1 # Numerical integration with 2 Gauss Points
|
|
297
|
+
WP_eta = 1 # Numerical integration with 2 Gauss Points
|
|
298
|
+
|
|
299
|
+
for x in range(0, 2, 1):
|
|
300
|
+
xi = -1 / np.sqrt(3) + 1 / np.sqrt(3) * 2 * x
|
|
301
|
+
for y in range(0, 2, 1):
|
|
302
|
+
eta = -1 / np.sqrt(3) + 1 / np.sqrt(3) * 2 * y
|
|
303
|
+
|
|
304
|
+
self.N_nat(xi, eta)
|
|
305
|
+
|
|
306
|
+
self.element_loading_vec[1] += (
|
|
307
|
+
self.q_self[1]
|
|
308
|
+
* self.result_N[0][0]
|
|
309
|
+
* self.det_J
|
|
310
|
+
* WP_xi
|
|
311
|
+
* WP_eta
|
|
312
|
+
)
|
|
313
|
+
self.element_loading_vec[3] += (
|
|
314
|
+
self.q_self[3]
|
|
315
|
+
* self.result_N[0][2]
|
|
316
|
+
* self.det_J
|
|
317
|
+
* WP_xi
|
|
318
|
+
* WP_eta
|
|
319
|
+
)
|
|
320
|
+
self.element_loading_vec[5] += (
|
|
321
|
+
self.q_self[5]
|
|
322
|
+
* self.result_N[0][4]
|
|
323
|
+
* self.det_J
|
|
324
|
+
* WP_xi
|
|
325
|
+
* WP_eta
|
|
326
|
+
)
|
|
327
|
+
self.element_loading_vec[7] += (
|
|
328
|
+
self.q_self[7]
|
|
329
|
+
* self.result_N[0][6]
|
|
330
|
+
* self.det_J
|
|
331
|
+
* WP_xi
|
|
332
|
+
* WP_eta
|
|
333
|
+
)
|
|
334
|
+
|
|
335
|
+
def __str__(self):
|
|
336
|
+
output = "NODAL COORDINATES\n"
|
|
337
|
+
output += "\n".join(
|
|
338
|
+
" ".join(str(self._coords_T[i][j]) for j in range(len(self._coords_T[0])))
|
|
339
|
+
for i in range(len(self._coords_T))
|
|
340
|
+
)
|
|
341
|
+
|
|
342
|
+
output += "\ngrad\n"
|
|
343
|
+
output += "\n".join(
|
|
344
|
+
" ".join(str(self.grad[i][j]) for j in range(len(self.grad[0])))
|
|
345
|
+
for i in range(len(self.grad))
|
|
346
|
+
)
|
|
347
|
+
|
|
348
|
+
output += "\nResult grad T\n"
|
|
349
|
+
output += "\n".join(
|
|
350
|
+
" ".join(
|
|
351
|
+
str(self.result_grad_T[i][j]) for j in range(len(self.result_grad_T[0]))
|
|
352
|
+
)
|
|
353
|
+
for i in range(len(self.result_grad_T))
|
|
354
|
+
)
|
|
355
|
+
|
|
356
|
+
output += "\nStiffness matrix K\n"
|
|
357
|
+
output += "\n".join(
|
|
358
|
+
" ".join(str(self.K[i][j]) for j in range(len(self.K[0])))
|
|
359
|
+
for i in range(len(self.K))
|
|
360
|
+
)
|
|
361
|
+
|
|
362
|
+
return output
|