Abaqus&Paraview梦幻联动!(Python二次开发篇)

之前号内分享过一篇基于Matlab对Abaqus-odb结果文件进行modify的推文,大家有兴趣可点击阅览Matlab“稍作修改”Abaqus-odb结果!!!,本次想要分享的是如何将Abaqus产生的odb文件转入Paraview中进行后处理显示?


灵感来源

相信有的小伙伴在网上会发现有一项开源项目正是解决这个问题,地址:https://github.com/haiiliin/odb2vtk,木木也曾下载跑过几次,确实很强大,能实现的功能很多,代码量也相应较多,六百行左右吧,木木心里就想能不能搞出代码量尽可能少,能让刚接触的小白灵活使用,想输出那个量就按照自己的需求进行自定义输出,完全掌握数据格式的转化!有关vtk语法可参照推文:自编有限元程序如何与Paraview进行梦幻联动?,或者官网:https://docs.vtk.org/en/latest/

本次推文会先教大家使用开源odb2vtk函数,然后从小白的角度带着大家一步步编写属于自己odb2vtk函数。

odb2vtk使用方法

按照原作者给出的使用方案需要我们将odb2vtk函数文件放至Abaqus的Python文件夹下,如:C:\SIMULIA\EstProducts\2022\win_b64\code\python2.7\lib

Abaqus&Paraview梦幻联动!(Python二次开发篇)的图1

接下来就是在命令提示符中输入以下命令:

>>Abaqus Python
>>from odb2vtk import*
>>ConvertOdb2Vtk('odb2vtk.txt路径目录')

odb2vtk.txt中将会控制后处理参数,本算例中的odb2vtk.txt内容如下:

----------input and output path----------
odb_path = 'D:\YLX\GZH\odb2vtk\odb2vtk-master\odb2vtk-master\ODB'
odb_name = 'CP10_L6_DP1'
vtk_path = 'D:\YLX\GZH\odb2vtk\odb2vtk-master\odb2vtk-master\VTK'
--------------type of mesh--------------
mesh_type = '12'
-------------number of piece-------------
piecenum = '1'
----setting frame, step and instance----
frame = '1-20'
step = '0'
instance = '0'

CP10_L6_DP1.odb在Abaqus中的显示如下:

Abaqus&Paraview梦幻联动!(Python二次开发篇)的图2

使用的是三维六面体单元,在vtk中的单元类型对应12,piecenum参数我还不晓得嘛意思,就默认设置的1,影响不大,选择输出第一个instance的第一个step的第1-20个frame,然后程序就开始运行,运行截图如下:

Abaqus&Paraview梦幻联动!(Python二次开发篇)的图3

最终输出20个vtu文件,在paraview中显示如下:

Abaqus&Paraview梦幻联动!(Python二次开发篇)的图4

场变量输出类型有如下几种:

Abaqus&Paraview梦幻联动!(Python二次开发篇)的图5

如果单元类型为C3D4单元,更改单元类型对应的编号即可:mesh_type = '10',效果如下:

Abaqus&Paraview梦幻联动!(Python二次开发篇)的图6Abaqus&Paraview梦幻联动!(Python二次开发篇)的图7

对于以上使用方法,我觉得有些许繁琐,因为每次使用都要搞一下前面的头文件,还不如搞一个正常的python脚本进行run,进行了如下修改:

Abaqus&Paraview梦幻联动!(Python二次开发篇)的图8

在最后一行输入odb2vtk.txt目录即可,然后在Abaqus中运行脚本,每次更改只需修改odb2vtk.txt内容即可。

对于该函数文件的官方使用方法就介绍到这里,接下来讲一下使用过程中需要注意的地方。

该函数默认输出的场变量为:U,A,V,RF,S,LE,PE,PEEQ,如果你输出的场变量正好是这几个,那么恭喜你,你可以随意的使用该文件,如果,你的场变量输出缺少其中几个,就需要将缺少的场变量输出的源代码进行注释;如果你的场变量输出不在这几个里面,你就需要按照vtu的输出格式和该函数的风格进行自己编咯,这也就是我想自己编写odb2vtk函数的初衷。

自编odb2vtk函数

使用方法

函数名字为convert_abaqus_to_vtk,形参依次写入odb文件、输出的vtk名称、单元类型(C3D4/C3D8),想要输出的step name,frame帧数(第几帧),运行即可。

#!/user/bin/python
# -* - coding:UTF-8 -*-
from odbAccess import *
def convert_abaqus_to_vtk(odb_path, output_vtk_path, element_type,step_name,frame):
...
convert_abaqus_to_vtk('test_C3D8.odb', 'output_C3D8.vtk', 'C3D8','Step-1',1)

应用C3D8 和C3D4两种单元类型,展示程序的适用性,做了一个简单案例,边界条件如下设置:

Abaqus&Paraview梦幻联动!(Python二次开发篇)的图9

输出的output_C3D8.vtk显示如下(位移结果),

Abaqus&Paraview梦幻联动!(Python二次开发篇)的图10Abaqus&Paraview梦幻联动!(Python二次开发篇)的图11

当改变单元类型时,更改形参即可:convert_abaqus_to_vtk('test_C3D4.odb', 'output_C3D4.vtk', 'C3D4','Step-1',1)

Abaqus&Paraview梦幻联动!(Python二次开发篇)的图12

输出的output_C3D8.vtk显示如下(位移结果),

Abaqus&Paraview梦幻联动!(Python二次开发篇)的图13Abaqus&Paraview梦幻联动!(Python二次开发篇)的图14

编制过程

以下部分对代码关键地方进行详解。

获取单元节点信息

assembly = odb.rootAssembly
nodes = []
elements = []
for name, instance in assembly.instances.items():
    for node in instance.nodes:
    # 获取节点信息
        nodes.append(node.coordinates)

    for element in instance.elements:
    #获取单元连接信息
        elements.append(element.connectivity)

单元类型判断

vtk_file.write("CELL_TYPES {}\n".format(len(elements)))
# 对单元类型进行判断
if element_type == 'C3D8':
    for elem in elements:
        vtk_file.write("12\n") 
elif element_type == 'C3D4':
    for elem in elements:
        vtk_file.write("10\n")  

读取场输出数据

# 获取step name
step1 = odb.steps[step_name]
# 获取指定step的frame
lastFrame = step1.frames[frame]
# 获取该frame下的位移(得到的位移分量有三个:x y z)
displacement = lastFrame.fieldOutputs['U']

写入节点位移

vtk_file.write("POINT_DATA {}\n".format(len(displacement.values)))
vtk_file.write("VECTORS Displacements float\n")
# 对节点位移值进行循环写入,依次写入UX UY UZ
for v in displacement.values:
    vtk_file.write("{} {} {}\n".format(v.data[0], v.data[1], v.data[2]))

以上就是写入节点位移的程序,写入其他场变量时,也同样的在此基础上进行开发,比如想输出Mises应力,OK,看看怎么在基础上进行开发:

s = lastFrame.fieldOutputs['S']
# s.values[0].mises表示第一个积分点的mises应力
for s_mises in s.values:
      vtk_file.write("{}\n".format(s_mises.mises)) 

Abaqus&Paraview梦幻联动!(Python二次开发篇)的图15Abaqus&Paraview梦幻联动!(Python二次开发篇)的图16

对于C3D4单元或C3D8R单元的积分点就只有一个,以上语句的添加不会有任何问题,但是对于C3D8单元,每个单元有8个积分点,写起来就需要进一步操作了,我选择的方法是,将单元中8个积分点的应力做一个平均,相当于每个单元有一个平均应力,代码修改如下:

# 定义取平均应力的函数
def get_average_mises_C3D8(s, unit_id):
    sum_mises = 0
    count = 0
    for i in range(8):
        node_id = unit_id * 8 + i
        if node_id < len(s.values):
            sum_mises += s.values[node_id].mises
            count += 1
    return sum_mises / count
# 写入vtk文件中
for i in range(len(elements)): 
    vtk_file.write("{}\n".format(get_average_mises_C3D8(s, i)))

这样以来,显示的应力结果如下显示:

Abaqus&Paraview梦幻联动!(Python二次开发篇)的图17Paraview

Abaqus&Paraview梦幻联动!(Python二次开发篇)的图18Abaqus

会出现应力不平滑,Abaqus采取的措施是将积分点的应力外插到节点上进行显示,大家也可以在step模块中选择节点应力输出,然后对每个节点进行绕节点平均处理,最后以节点力的形式显示,会减小不平滑现象。

Abaqus&Paraview梦幻联动!(Python二次开发篇)的图19

其他的场输出也可以按照自己的想法进行修改,希望本次提供的案例能给大家在数据转化上带来一些灵感,可以借鉴一些优秀的开源代码,同时也可以进行修改,实现自己的功能。

数据文件获取方法


默认 最新
当前暂无评论,小编等你评论哦!
点赞 7 评论 收藏 9
关注