用python写一段使用位移法和三维梁单元计算应力应变的有限元代码
时间: 2024-03-14 21:46:34 浏览: 170
Matlab编写的梁杆单元的有限元分析,分析应力、应变。.zip
好的,以下是一个使用位移法和三维梁单元计算应力应变的有限元代码的示例:
```python
import numpy as np
# 定义节点坐标
node_coords = np.array([
[0, 0, 0],
[1, 0, 0],
[1, 1, 0],
[0, 1, 0],
[0, 0, 1],
[1, 0, 1],
[1, 1, 1],
[0, 1, 1]
])
# 定义节点编号
node_numbers = np.array([
[1, 2, 3, 4],
[5, 6, 7, 8],
[1, 2, 6, 5],
[2, 3, 7, 6],
[3, 4, 8, 7],
[4, 1, 5, 8]
])
# 定义材料参数
E = 200e9
nu = 0.3
# 定义梁单元属性
beam_area = 0.1
beam_inertia = np.array([1/12, 1/12, 1/12]) * beam_area**3
# 初始化刚度矩阵和载荷向量
num_nodes = node_coords.shape[0]
num_elems = node_numbers.shape[0]
K = np.zeros((6*num_nodes, 6*num_nodes))
F = np.zeros((6*num_nodes, 1))
# 计算每个单元的刚度矩阵和载荷向量
for i in range(num_elems):
# 获取节点编号
node_nums = node_numbers[i]
# 获取节点坐标
node_coords_elem = node_coords[node_nums-1]
# 计算单元长度、方向余弦、位移矩阵和应变矩阵
L = np.sqrt((node_coords_elem[1, :] - node_coords_elem[0, :])**2).sum()
n = (node_coords_elem[1, :] - node_coords_elem[0, :]) / L
c = np.zeros((3, 6))
c[0, 0] = c[1, 1] = c[2, 2] = n[0]
c[0, 1] = c[1, 0] = n[1]
c[0, 2] = c[2, 0] = n[2]
c[1, 2] = c[2, 1] = 0.0
u = np.zeros((6, 12))
u[0, 0:3] = u[3, 3:6] = u[1, 6:9] = u[4, 9:12] = n
u[2, 0:3] = u[5, 3:6] = u[1, 9:12] = u[4, 6:9] = 1.0
B = np.zeros((6, 12))
B[0, 0:3] = B[3, 3:6] = B[2, 6:9] = B[5, 9:12] = n / L
B[1, 0:3] = B[4, 3:6] = B[2, 9:12] = B[5, 6:9] = np.array([0, -1, 0]) / L
# 计算单元刚度矩阵和载荷向量
K_elem = E * beam_area / L * (B.T @ beam_inertia @ B + nu * (c.T @ B).T @ (c.T @ beam_inertia @ B))
F_elem = np.zeros((12, 1))
# 将单元刚度矩阵和载荷向量加入总刚度矩阵和载荷向量
for j in range(4):
for k in range(3):
for l in range(4):
for m in range(3):
K[6*(node_nums[j]-1)+k, 6*(node_nums[l]-1)+m] += K_elem[3*j+k, 3*l+m]
F[6*(node_nums[j]-1)+k, 0] += F_elem[3*j+k, 0]
# 应用位移边界条件
K[0:6, :] = 0.0
K[:, 0:6] = 0.0
K[0:6, 0:6] = np.eye(6)
F[0:6, 0] = np.array([0.0, 0.0, 0.0, 0.0, 0.0, 1e3])
# 解线性方程组
U = np.linalg.solve(K, F)
# 计算应力和应变
stress = np.zeros((num_elems, 6))
strain = np.zeros((num_elems, 6))
for i in range(num_elems):
# 获取节点编号
node_nums = node_numbers[i]
# 获取节点坐标
node_coords_elem = node_coords[node_nums-1]
# 计算单元长度、方向余弦、位移矩阵和应变矩阵
L = np.sqrt((node_coords_elem[1, :] - node_coords_elem[0, :])**2).sum()
n = (node_coords_elem[1, :] - node_coords_elem[0, :]) / L
c = np.zeros((3, 6))
c[0, 0] = c[1, 1] = c[2, 2] = n[0]
c[0, 1] = c[1, 0] = n[1]
c[0, 2] = c[2, 0] = n[2]
c[1, 2] = c[2, 1] = 0.0
u = np.zeros((6, 12))
u[0, 0:3] = u[3, 3:6] = u[1, 6:9] = u[4, 9:12] = n
u[2, 0:3] = u[5, 3:6] = u[1, 9:12] = u[4, 6:9] = 1.0
B = np.zeros((6, 12))
B[0, 0:3] = B[3, 3:6] = B[2, 6:9] = B[5, 9:12] = n / L
B[1, 0:3] = B[4, 3:6] = B[2, 9:12] = B[5, 6:9] = np.array([0, -1, 0]) / L
# 计算应力和应变
strain[i, :] = B @ U[6*(node_nums-1):6*node_nums, 0]
stress[i, :] = E * (c.T @ strain[i, :]).T
# 输出结果
print('Node coordinates:')
print(node_coords)
print()
print('Node numbers:')
print(node_numbers)
print()
print('Stiffness matrix:')
print(K)
print()
print('Load vector:')
print(F)
print()
print('Displacement vector:')
print(U)
print()
print('Element stresses:')
print(stress)
print()
print('Element strains:')
print(strain)
```
这段代码中,我们首先定义了节点坐标和节点编号,然后定义了材料参数、梁单元属性和刚度矩阵、载荷向量的初始值。接着,我们循环计算每个单元的刚度矩阵和载荷向量,并将其加入总刚度矩阵和载荷向量中。然后,我们应用位移边界条件,解线性方程组,计算应力和应变,并输出结果。
需要注意的是,这段代码中的计算方法可能并不完全正确或者高效,仅供参考。如果您需要进行更精确或更复杂的有限元分析,建议使用专业的有限元软件或库。
阅读全文