用户国营 发表于 2025-4-8 07:49:42

震源车:震源引发平板模态分析

https://i-blog.csdnimg.cn/direct/158e9cccad854366ab6fd330054d6add.jpeg
勘探震源引发平板模态分析
import numpy as np
import scipy.linalg as la
from scipy.sparse import coo_matrix, csr_matrix, lil_matrix
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D


# ======================
# 有限元建模模块
# ======================
class PlateStructure:
    def __init__(self, Lx=2.0, Ly=1.5, h=0.05, E=210e9, rho=7850):
      """震源激发平板结构参数
      Args:
            Lx: 平板长度(m)
            Ly: 平板宽度(m)
            h: 厚度(m)
            E: 弹性模量(Pa)
            rho: 密度(kg/m³)
      """
      self.geometry = (Lx, Ly, h)
      self.material = (E, rho)

      # 网格参数
      self.nx = 8# X方向单元数
      self.ny = 6# Y方向单元数
      self.nodes = None
      self.elements = []

    def generate_mesh(self):
      """生成结构化四边形网格"""
      x = np.linspace(0, self.geometry, self.nx + 1)
      y = np.linspace(0, self.geometry, self.ny + 1)

      # 生成节点坐标 (Nx3数组: )
      self.nodes = np.array([ for yi in y for xi in x])

      # 生成单元连接关系 (四节点单元)
      for j in range(self.ny):
            for i in range(self.nx):
                n1 = i + j * (self.nx + 1)
                n2 = n1 + 1
                n3 = n2 + (self.nx + 1)
                n4 = n3 - 1
                self.elements.append()

    def get_stiffness_matrix(self):
      """生成四节点板单元刚度矩阵(简化版本)"""
      E, nu = self.material, 0.3
      D = E * self.geometry ** 3 / (12 * (1 - nu ** 2))

      # 简化的12x12刚度矩阵(弯曲主导)
      Ke = np.array([
            ,
            ,
            ,
            [-6, -3, 0, 12, -3, 0, 6, 3, 0, -12, 3, 0],
            ,
            ,
            [-12, -3, 0, 6, -3, 0, 12, 3, 0, -6, 3, 0],
            [-3, -12, 0, 3, -6, 0, 3, 12, 0, -3, 6, 0],
            ,
            ,
            [-3, -6, 0, 3, -12, 0, 3, 6, 0, -3, 12, 0],
            
      ]) * D / (self.geometry ** 3)

      return csr_matrix(Ke)

    def get_mass_matrix(self):
      """生成一致质量矩阵"""
      rho = self.material
      h = self.geometry
      area = (self.geometry / self.nx) * (self.geometry / self.ny)

      # 单元质量均分到各节点
      Me = np.eye(12) * (rho * h * area) / 4
      return csr_matrix(Me)


# ======================
# 模态分析模块
# ======================
class ModalAnalyzer:
    def __init__(self, structure):
      self.struct = structure
      self.K = None# 全局刚度矩阵
      self.M = None# 全局质量矩阵
      self.freqs = None# 固有频率(Hz)
      self.modes = None# 模态振型

    def assemble_matrices(self):
      """组装全局刚度矩阵和质量矩阵"""
      n_nodes = len(self.struct.nodes)
      ndof = 3 * n_nodes# 总自由度

      # 初始化稀疏矩阵
      K = lil_matrix((ndof, ndof), dtype=np.float64)
      M = lil_matrix((ndof, ndof), dtype=np.float64)

      # 遍历所有单元进行组装
      for elem in self.struct.elements:
            Ke = self.struct.get_stiffness_matrix()
            Me = self.struct.get_mass_matrix()

            # 获取单元自由度索引
            dof_indices = []
            for node in elem:
                dof_indices.extend()

            # 将单元矩阵添加到全局矩阵
            for i in range(12):
                for j in range(12):
                  K, dof_indices] += Ke
                  M, dof_indices] += Me

      self.K = K.tocsr()
      self.M = M.tocsr()

    def apply_boundary_conditions(self):
      """应用固定边界条件(四角节点全约束)"""
      fix_nodes =
      fixed_dofs = []

      for n in fix_nodes:
            fixed_dofs.extend()# 约束x,y,z方向

      # 创建自由度的掩码
      free_dofs = np.setdiff1d(np.arange(self.K.shape), fixed_dofs)
      return free_dofs

    def solve_modes(self, num_modes=6):
      """求解特征值问题"""
      free_dofs = self.apply_boundary_conditions()

      # 提取缩减矩阵
      K_red = self.K[:, free_dofs]
      M_red = self.M[:, free_dofs]

      # 求解广义特征值问题
      evals, evecs = la.eigh(K_red.toarray(), M_red.toarray())

      # 重构全局模态振型
      self.freqs = np.sqrt(np.abs(evals[:num_modes])) / (2 * np.pi)
      self.modes = np.zeros((self.K.shape, num_modes))
      self.modes = evecs[:, :num_modes]


# ======================
# 可视化模块
# ======================
class Visualizer:
    @staticmethod
    def plot_mode_shape(struct, mode, freq, ax=None):
      """绘制三维模态振型
      Args:
            mode: 模态振型向量
            freq: 对应频率
            ax: 可选的绘图轴对象
      """
      if ax is None:
            fig = plt.figure()
            ax = fig.add_subplot(111, projection='3d')

      nodes = struct.nodes.copy()
      scale = 0.2 * np.max(nodes[:, :2]) / np.max(np.abs(mode))

      # 将振型位移叠加到坐标
      nodes[:, 2] += mode[::3] * scale# 取Z方向位移

      # 绘制变形后的网格
      x = nodes[:, 0]
      y = nodes[:, 1]
      z = nodes[:, 2]

      # 绘制单元面
      for elem in struct.elements:
            verts = nodes
            ax.plot_trisurf(verts[:, 0], verts[:, 1], verts[:, 2], alpha=0.6)

      ax.set_title(f'Mode Shape @ {freq:.1f}Hz')
      ax.set_xlabel('X')
      ax.set_ylabel('Y')
      return ax

    @staticmethod
    def compare_frequencies(freq_orig, freq_opt):
      """绘制频率对比柱状图"""
      plt.figure(figsize=(10, 6))
      x = np.arange(len(freq_orig))
      plt.bar(x - 0.2, freq_orig, 0.4, label='Original Design')
      plt.bar(x + 0.2, freq_opt, 0.4, label='Optimized Design')

      plt.xticks(x, )
      plt.xlabel('Mode Order')
      plt.ylabel('Frequency (Hz)')
      plt.legend()
      plt.grid(True, alpha=0.3)
      plt.show()


# ======================
# 主程序
# ======================
if __name__ == "__main__":
    # 原始设计建模
    print("正在建立原始设计模型...")
    orig = PlateStructure(Lx=2.0, Ly=1.5, h=0.05)
    orig.generate_mesh()

    # 模态分析
    analyzer_orig = ModalAnalyzer(orig)
    analyzer_orig.assemble_matrices()
    analyzer_orig.solve_modes(num_modes=6)
    print("原始设计前6阶频率:", analyzer_orig.freqs)

    # 优化设计(增加厚度)
    print("\n正在建立优化设计模型...")
    optimized = PlateStructure(Lx=2.0, Ly=1.5, h=0.07)
    optimized.generate_mesh()

    analyzer_opt = ModalAnalyzer(optimized)
    analyzer_opt.assemble_matrices()
    analyzer_opt.solve_modes(num_modes=6)
    print("优化设计前6阶频率:", analyzer_opt.freqs)

    # 结果可视化
    print("\n生成可视化结果...")
    fig = plt.figure(figsize=(15, 10))

    # 原始设计前三阶振型
    for i in range(3):
      ax = fig.add_subplot(2, 3, i + 1, projection='3d')
      Visualizer.plot_mode_shape(orig, analyzer_orig.modes[:, i],
                                 analyzer_orig.freqs, ax)

    # 优化设计前三阶振型
    for i in range(3):
      ax = fig.add_subplot(2, 3, i + 4, projection='3d')
      Visualizer.plot_mode_shape(optimized, analyzer_opt.modes[:, i],
                                 analyzer_opt.freqs, ax)

    plt.tight_layout()

    # 频率对比
    Visualizer.compare_frequencies(analyzer_orig.freqs, analyzer_opt.freqs)
    plt.show()

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 震源车:震源引发平板模态分析