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

其他的場輸出也可以按照自己的想法進行修改,希望本次提供的案例能給大家在數據轉化上帶來一些靈感,可以借鑒一些優秀的開源代碼,同時也可以進行修改,實現自己的功能。

數據文件獲取方法


登錄后免費查看全文
立即登錄
App下載
技術鄰APP
工程師必備
  • 項目客服
  • 培訓客服
  • 平臺客服

TOP

17
5
26