import numpy as np
class FiniteElementAnalysis:
def __init__(self, nodes, elements, material_properties):
self.nodes = nodes
self.elements = elements
self.material_properties = material_properties
self.global_stiffness_matrix = None
def shape_functions(self, xi, eta, zeta):
# 二次等參單元的形函式
N = [
(1 - xi) * (1 - eta) * (1 - zeta) / 8,
(1 + xi) * (1 - eta) * (1 - zeta) / 8,
(1 + xi) * (1 + eta) * (1 - zeta) / 8,
(1 - xi) * (1 + eta) * (1 - zeta) / 8,
(1 - xi) * (1 - eta) * (1 + zeta) / 8,
(1 + xi) * (1 - eta) * (1 + zeta) / 8,
(1 + xi) * (1 + eta) * (1 + zeta) / 8,
(1 - xi) * (1 + eta) * (1 + zeta) / 8
]
return N
def compute_element_stiffness_matrix(self, element):
# 計算單元剛度矩陣
node_ids = element['nodes']
E = self.material_properties['E']
nu = self.material_properties['nu']
t = self.material_properties['t']
Ke = np.zeros((24, 24))
# 高斯積分點
gauss_points = [(0.57735, 0.57735, 0.57735), (-0.57735, 0.57735, 0.57735), ...] # 更多積分點
for xi, eta, zeta in gauss_points:
N = self.shape_functions(xi, eta, zeta)
# 計算雅可比矩陣和其逆
J = np.array([[...], [...], [...]]) # 雅可比矩陣
det_J = np.linalg.det(J)
inv_J = np.linalg.inv(J)
# 計算B矩陣
B = np.array([[...], [...], [...]]) # B矩陣
Ke += B.T @ np.array([[E / (1 - nu**2) * np.array([[1, nu, 0], [nu, 1, 0], [0, 0, (1 - nu) / 2]])]]) @ B * det_J * t
return Ke
def assemble_global_stiffness_matrix(self):
num_nodes = len(self.nodes)
self.global_stiffness_matrix = np.zeros((3 * num_nodes, 3 * num_nodes))
for element in self.elements:
Ke = self.compute_element_stiffness_matrix(element)
for i, node_i in enumerate(element['nodes']):
for j, node_j in enumerate(element['nodes']):
self.global_stiffness_matrix[3*node_i:3*node_i+3, 3*node_j:3*node_j+3] += Ke[3*i:3*i+3, 3*j:3*j+3]
def apply_boundary_conditions(self, bc):
for node_id, dof in bc.items():
for d in dof:
self.global_stiffness_matrix[3*node_id+d, :] = 0
self.global_stiffness_matrix[:, 3*node_id+d] = 0
self.global_stiffness_matrix[3*node_id+d, 3*node_id+d] = 1
def solve(self, forces):
displacements = np.linalg.solve(self.global_stiffness_matrix, forces)
return displacements
# 示例資料
nodes = 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]])
elements = [{'nodes': [0, 1, 2, 3, 4, 5, 6, 7]}]
material_properties = {'E': 210e9, 'nu': 0.3, 't': 1}
# 建立有限元分析物件
fea = FiniteElementAnalysis(nodes, elements, material_properties)
fea.assemble_global_stiffness_matrix()
# 應用邊界條件
bc = {0: [0, 1, 2], 1: [0, 1, 2]} # 例如,節點0和1的x, y, z方向固定
fea.apply_boundary_conditions(bc)
# 施加外力
forces = np.zeros(24)
forces[3*2+2] = -1000 # 在節點2的z方向施加1000N的力
# 求解
displacements = fea.solve(forces)
print("Displacements:", displacements)