Hello community,
how do create a .vtu file with quad and triangle elements? I want to convert a FEM input file to a .vtu file.
I have tried to create a python code, but I only get either a .vtu file with only quad or triangle elements. Is there a way to combine both element types to write it to the output file?
import vtk
import numpy as np
inputFile = 'mixed.inp'
with open(inputFile) as f:
lines = f.readlines()
class Node:
def __init__(self, nid):
self.nid = np.uint8(nid)
self.coordinates = []
class Element:
def __init__(self, eid: str):
self.eid = np.uint8(eid)
self.attached_nodes = []
bNode = False
bElem = False
nodes, elements = {}, {}
for line in lines:
line = line.strip()
# NODES
if line.lower().startswith('*node'):
bNode = True
bElem = False
elif bNode and not line.startswith('*'):
lineSplit = line.split(',')
nid = int(lineSplit[0])-1
nodes[nid] = Node(nid)
x = lineSplit[1].strip()
y = lineSplit[2].strip()
z = lineSplit[3].strip()
nodes[nid].coordinates = np.array([x, y, z], dtype=np.float64)
# ELEMENTS
elif line.lower().startswith('*element'):
bNode = False
bElem = True
lineSplit = line.split(',')
elemType: str = lineSplit[1].split('=')[1]
elif bElem and 'S4' == elemType.upper():
if not line.startswith('**') or not line.startswith('*'):
lineSplit = line.split(',')
eid = lineSplit[0]
elements[eid] = Element(eid)
tmp = []
for i in [x for x in range(len(lineSplit)-1)]:
nid = int(lineSplit[i+1])-1
tmp.append(nid)
elements[eid].attached_nodes = np.asarray(tmp, dtype=np.uint8)
elif bElem and 'S3' == elemType.upper():
if not line.startswith('**') or not line.startswith('*'):
lineSplit = line.split(',')
eid = lineSplit[0]
elements[eid] = Element(eid)
tmp = []
for i in [x for x in range(len(lineSplit)-1)]:
nid = int(lineSplit[i+1])-1
tmp.append(nid)
elements[eid].attached_nodes = np.asarray(tmp, dtype=np.uint8)
else:
bNode = False
bElem = False
# for nid in nodes.keys():
# print(nodes[nid].nid, nodes[nid].coordinates)
# for eid in elements.keys():
# print(elements[eid].eid, elements[eid].attached_nodes)
# Define VTK Points
vtk_points = vtk.vtkPoints()
for nid in nodes.keys():
vtk_points.InsertNextPoint(nodes[nid].coordinates[0], nodes[nid].coordinates[1], nodes[nid].coordinates[2])
vtk_quads = vtk.vtkCellArray()
vtk_trias = vtk.vtkCellArray()
for eid in elements.keys():
# Define quad elements
if len(elements[eid].attached_nodes) == 4:
quad = vtk.vtkQuad()
quad.GetPointIds().SetId(0, elements[eid].attached_nodes[0])
quad.GetPointIds().SetId(1, elements[eid].attached_nodes[1])
quad.GetPointIds().SetId(2, elements[eid].attached_nodes[2])
quad.GetPointIds().SetId(3, elements[eid].attached_nodes[3])
vtk_quads.InsertNextCell(quad)
elif len(elements[eid].attached_nodes) == 3:
tria = vtk.vtkTriangle()
tria.GetPointIds().SetId(0, elements[eid].attached_nodes[0])
tria.GetPointIds().SetId(1, elements[eid].attached_nodes[1])
tria.GetPointIds().SetId(2, elements[eid].attached_nodes[2])
vtk_trias.InsertNextCell(tria)
# Create unstructured grid
ugrid = vtk.vtkUnstructuredGrid()
ugrid.SetPoints(vtk_points)
# How to merge both cell types ?
ugrid.SetCells(vtk.VTK_TRIANGLE, vtk_trias)
ugrid.SetCells(vtk.VTK_QUAD, vtk_quads)
# Write to binary file
writer = vtk.vtkXMLUnstructuredGridWriter()
writer.SetInputData(ugrid)
writer.SetFileName("output2.vtu")
writer.SetDataModeToBinary()
writer.Write()
Thank you in advance