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 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中的显示如下:
使用的是三维六面体单元,在vtk中的单元类型对应12,piecenum参数我还不晓得嘛意思,就默认设置的1,影响不大,选择输出第一个instance的第一个step的第1-20个frame,然后程序就开始运行,运行截图如下:
最终输出20个vtu
文件,在paraview中显示如下:
场变量输出类型有如下几种:
如果单元类型为C3D4单元,更改单元类型对应的编号即可:mesh_type = '10'
,效果如下:
对于以上使用方法,我觉得有些许繁琐,因为每次使用都要搞一下前面的头文件,还不如搞一个正常的python脚本进行run,进行了如下修改:
在最后一行输入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两种单元类型,展示程序的适用性,做了一个简单案例,边界条件如下设置:
输出的output_C3D8.vtk显示如下(位移结果),
当改变单元类型时,更改形参即可:convert_abaqus_to_vtk('test_C3D4.odb', 'output_C3D4.vtk', 'C3D4','Step-1',1)
输出的output_C3D8.vtk显示如下(位移结果),
编制过程
以下部分对代码关键地方进行详解。
获取单元节点信息
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))
对于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)))
这样以来,显示的应力结果如下显示:
Paraview
Abaqus
会出现应力不平滑,Abaqus采取的措施是将积分点的应力外插到节点上进行显示,大家也可以在step模块中选择节点应力输出,然后对每个节点进行绕节点平均处理,最后以节点力的形式显示,会减小不平滑现象。
其他的场输出也可以按照自己的想法进行修改,希望本次提供的案例能给大家在数据转化上带来一些灵感,可以借鉴一些优秀的开源代码,同时也可以进行修改,实现自己的功能。