You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

技术求助:用Python绘制Abaqus INP文件的10节点四面体网格并映射应力应变

处理百万级二次四面体单元INP文件的Python可视化方案

针对你的大规模Abaqus模型(近百万C3D10单元),以下是用Python实现网格绘制及应力/应变映射的可行方案,适配多组仿真结果对比需求:

核心依赖库

优先选择PyVista(基于VTK,适合大规模3D网格可视化),搭配numpy处理数据:

pip install pyvista numpy

步骤1:解析INP文件关键数据

INP文件主要需提取三类信息:节点坐标、单元节点索引、单元应力/应变数据。以下是简化的解析函数(需根据你的INP格式调整,比如场数据的关键字段):

import numpy as np
import pyvista as pv

def parse_inp(file_path):
    nodes = {}
    elements = []
    el_stress = {}
    current_section = None

    with open(file_path, 'r') as f:
        for line in f:
            line = line.strip()
            if not line or line.startswith('**'):
                continue
            # 识别INP段
            if line.startswith('*NODE'):
                current_section = 'NODE'
                continue
            elif line.startswith('*ELEMENT, TYPE=C3D10'):
                current_section = 'ELEMENT'
                continue
            elif line.startswith('*EL FILE,'):
                current_section = 'EL_STRESS'
                # 跳过表头行(比如S11,S22等)
                next(f)
                continue

            # 读取节点数据
            if current_section == 'NODE':
                parts = line.split(',')
                node_id = int(parts[0].strip())
                x, y, z = map(float, [p.strip() for p in parts[1:4]])
                nodes[node_id] = (x, y, z)
            # 读取单元数据(C3D10是10个节点)
            elif current_section == 'ELEMENT':
                parts = line.split(',')
                el_id = int(parts[0].strip())
                node_ids = [int(p.strip()) for p in parts[1:11]]
                elements.append((el_id, node_ids))
            # 读取单元应力数据(示例为S11,按需修改)
            elif current_section == 'EL_STRESS':
                parts = line.split(',')
                el_id = int(parts[0].strip())
                s11 = float(parts[1].strip())
                el_stress[el_id] = s11

    # 转换为numpy数组适配PyVista
    node_coords = np.array([nodes[pid] for pid in sorted(nodes.keys())])
    # PyVista的单元格式:先指定单元类型(VTK_QUADRATIC_TETRA=24),再按节点索引(注意要减1,因为VTK是0基)
    cells = []
    for el_id, node_ids in elements:
        cells.append(10)  # 单元节点数
        cells.extend([pid-1 for pid in node_ids])  # 转换为0基索引
    cells = np.array(cells)

    # 创建PyVista网格对象
    grid = pv.UnstructuredGrid(cells, [pv.CellType.QUADRATIC_TETRA]*len(elements), node_coords)
    # 添加应力数据到网格
    stress_array = np.array([el_stress[el_id] for el_id, _ in elements])
    grid['S11'] = stress_array

    return grid

步骤2:单组结果可视化

解析完成后,可直接绘制带应力映射的3D网格:

# 读取单个INP文件
grid = parse_inp('your_model.inp')

# 创建绘图窗口
plotter = pv.Plotter()
# 添加网格,按S11着色
plotter.add_mesh(grid, scalars='S11', cmap='viridis', show_edges=False)
# 添加颜色条
plotter.add_scalar_bar(title='Stress S11')
# 显示
plotter.show()

步骤3:多组结果对比(迭代仿真)

针对多组载荷下的结果,可创建子图对比:

# 读取多组仿真结果
grid_list = [parse_inp(f'model_load_{i}.inp') for i in range(3)]
titles = ['Load Case 1', 'Load Case 2', 'Load Case 3']

# 创建多子图窗口
plotter = pv.Plotter(shape=(1,3))
for i in range(3):
    plotter.subplot(0, i)
    plotter.add_mesh(grid_list[i], scalars='S11', cmap='viridis', clim=[grid['S11'].min(), grid['S11'].max()])
    plotter.add_scalar_bar(title='S11')
    plotter.add_title(titles[i])
plotter.link_views()  # 同步视角
plotter.show()

性能优化建议

  • 对于百万级单元,建议关闭边显示(show_edges=False),减少渲染压力;
  • 若内存不足,可使用PyVista的grid.extract_subset()提取部分单元预览,或使用pyvista.global_theme.load_theme('document')降低渲染精度;
  • 解析INP时可采用分块读取,避免一次性加载全部数据到内存。

内容的提问来源于stack exchange,提问作者siddarth swaminathan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 19:50:31