從開源中汲取營養,我們就是站在了巨人的肩膀上!
導讀:一個CAE軟體,需要從CAD生成網格,使用求解器求解,最後透過視覺化進行資料分析。整個過程中,每一步都不是容易的事。而我們只能從事其中一部分。
最近,我在寫有限元程式DinoFem過程中,就遇到了很多這方面的問題。
今天就推薦一個讀取和轉換工具,Meshio。
內容:
1、meshio 解決了什麼問題
2、meshio的使用
3、points
4、cells
5、網格資料的讀取
6、其他函式
7、建立和輸出
官方的文件寫得過於簡單,但是從原始碼可以看到詳細的使用方法。本文就介紹一下meshio的基本操作。
1、meshio 解決了什麼問題就在前天,我們國產自主CAE聯盟的群裡,大家都比較困擾于格式問題。確實,現在整個製造業、建築業、或者其他行業,大部分都在使用3D模型來進行產品設計,甚至於已經進入了生產運營的管理。例如現在比較火的#數字孿生#更是把3D模型和各方面的控制系統等都融合在了一起。
而,就3D模型而言,整個都是國外傳到中國的,所有的格式,都是國外的標準。在這一塊,我們就有先天不足。作為國際化的世界,我們可能無法左右標準,但是至少得做到有熟悉的開源的格式轉換工具。
就網格來說,meshio解決的是與各種標準格式互相支援的問題。包括讀取,寫入,轉換等。
支援:Abaqus,ANSYS,AVS-UCD,FLAC3D,VTK,Nastran等等。見下圖
meshio所支援的格式
檔案格式,就像我們的飲食習慣,更是文化的一部分。而文化是思想的承載者。
2、meshio使用官方的教程很簡單,主要介紹的內容都在第一個案例裡,其他的,本質上是字典操作。
import meshiomesh = meshio.read( filename, # string, os.PathLike, or a buffer/open file file_format="stl", # optional if filename is a path; inferred from extension)# mesh.points, mesh.cells, mesh.cells_dict, ...# mesh.vtk.read() is also possible
但是,實際上使用卻沒有那麼簡單,倒是也沒有那麼難。
Meshio是由一些字典和字典操作,資料操作組成的。主要的內容在_mesh.py檔案中有詳細的說明。實際上,每一個格式的支援,程式碼中都寫得很詳細。
3、points我們先看第一個點的資訊。以inp檔案為例
import meshiom = meshio.read("fem_test003.inp")print(type(m.points),m.points.shape)
輸出資訊:
<class 'numpy.ndarray'> (227, 3)
說明這個points就是按順序排的一個點列,numpy的ndarray型別。資料有227個點。三維座標。
4、cellscells的資訊同樣可以讀取,但是,cells有點不一樣,我們可以先打印出cells資訊看看
[<meshio CellBlock, type: line, num cells: 2>, <meshio CellBlock, type: line, num cells: 4>, <meshio CellBlock, type: line, num cells: 2>, <meshio CellBlock, type: line, num cells: 4>, <meshio CellBlock, type: line, num cells: 2>, <meshio CellBlock, type: line, num cells: 4>, <meshio CellBlock, type: line, num cells: 4>, <meshio CellBlock, type: line, num cells: 4>, <meshio CellBlock, type: line, num cells: 2>, <meshio CellBlock, type: line, num cells: 4>, <meshio CellBlock, type: line, num cells: 4>, <meshio CellBlock, type: line, num cells: 4>, <meshio CellBlock, type: line, num cells: 4>, <meshio CellBlock, type: line, num cells: 2>, <meshio CellBlock, type: line, num cells: 2>, <meshio CellBlock, type: line, num cells: 2>, <meshio CellBlock, type: line, num cells: 2>, <meshio CellBlock, type: line, num cells: 1>, <meshio CellBlock, type: line, num cells: 4>, <meshio CellBlock, type: line, num cells: 4>, <meshio CellBlock, type: line, num cells: 4>, <meshio CellBlock, type: line, num cells: 2>, <meshio CellBlock, type: line, num cells: 2>, <meshio CellBlock, type: line, num cells: 2>, <meshio CellBlock, type: line, num cells: 2>, <meshio CellBlock, type: line, num cells: 1>, <meshio CellBlock, type: line, num cells: 2>, <meshio CellBlock, type: line, num cells: 2>, <meshio CellBlock, type: line, num cells: 2>, <meshio CellBlock, type: line, num cells: 2>, <meshio CellBlock, type: line, num cells: 2>, <meshio CellBlock, type: line, num cells: 2>, <meshio CellBlock, type: line, num cells: 2>, <meshio CellBlock, type: triangle, num cells: 18>, <meshio CellBlock, type: triangle, num cells: 18>, <meshio CellBlock, type: triangle, num cells: 18>, <meshio CellBlock, type: triangle, num cells: 139>, <meshio CellBlock, type: triangle, num cells: 139>, <meshio CellBlock, type: triangle, num cells: 18>, <meshio CellBlock, type: triangle, num cells: 18>, <meshio CellBlock, type: triangle, num cells: 18>, <meshio CellBlock, type: triangle, num cells: 12>, <meshio CellBlock, type: triangle, num cells: 8>, <meshio CellBlock, type: triangle, num cells: 12>, <meshio CellBlock, type: triangle, num cells: 12>, <meshio CellBlock, type: triangle, num cells: 12>, <meshio CellBlock, type: tetra, num cells: 627>]
輸出的是一個資訊表,第一個是類的型別,CellBlock類。
type,名稱
num,數量
我們看一下這個CellBlock類的定義
class CellBlock(collections.namedtuple("CellBlock", ["type", "data"])): def __repr__(self): return f"<meshio CellBlock, type: {self.type}, num cells: {len(self.data)}>"
其實就是一個字典。是collection嚇的namedtuple類。
print列印的輸出形式,也在程式碼中寫得很清楚,和我們的輸出完全一致。
5、網格資料的讀取主要讀取的資料是cell_sets_dict屬性
a=[e for e in m.cell_sets_dict.keys()]print(a[0:10])print(a[10:20])print(a[20:30])print(a[30:40])print(a[40:])
我們可以列印這個屬性的key列表
['face1', 'face2', 'face3', 'Line1', 'Line2', 'Line3', 'Line4', 'Line5', 'Line6', 'Line7']
['Line8', 'Line9', 'Line10', 'Line11', 'Line12', 'Line13', 'Line14', 'Line15', 'Line16', 'Line17']
['Line18', 'Line19', 'Line20', 'Line21', 'Line22', 'Line23', 'Line24', 'Line25', 'Line26', 'Line27']
['Line28', 'Line29', 'Line30', 'Line31', 'Line32', 'Line33', 'Surface1', 'Surface2', 'Surface3', 'Surface4']
['Surface5', 'Surface6', 'Surface7', 'Surface8', 'Surface9', 'Surface10', 'Surface11', 'Surface12', 'Surface13', 'Volume1']
從這個列表可以看到每一個字典的物件。例如,我們要查詢face1的指標
圖中可以看到,結果是一系列的三角單元所在的指標。
我們需要從三角單元指標中去查。
print(m.get_cells_type("triangle"))
get_cells_type函式,就是提取每一個型別這裡是triangle的所有的編號,和對應的點列。每一個面由點列組成。
我們可以查詢原來的inp檔案對應一下
可以看到前三排是和剛才的輸出是一致的。不同的是,指標要減少1個,因為python是從0開始排的。
我們主要的操作,就在這個字典中進行。
6、其他函式prune函式,做了一些清理工作。
第一步,清理了低維數的數值(remove_lower_dimensional_cells),第二步,是去掉了離散的點(remove_orphaned_nodes)。
還有去掉z方向的值的,將3D轉化成2D的函式。
def prune_z_0(self, tol=1.0e-13): """Remove third (z) component of points if it is 0 everywhere (up to a tolerance). """
具體使用的時候,可以根據需求,再去看一下程式碼。
7、建立和輸出建立和輸出,官方文件有一些簡單的介紹。應該是夠用了。
8、結束做數值模擬是需要大量的工作的。從CAD到計算再到後處理。每一個工作都需要大量的技術人員參與。而且門檻都不低。