from odbAccess import *
from textRepr import *
from string import *
import os
import time
class VTKFile(object):
def __init__(self, outfile, this_model, N_Frame):
# compute point quantity
self.this_model = this_model
self.N_Frame = N_Frame
self.outfile = open(outfile, 'w')
self.before_Results_data()
self.Results_data()
self.after_Results_data()
self.outfile.close()
def before_Results_data(self):
# compute the number of element of each block
p_elements = len(self.this_model.element)/1 + 1
lp_elements = len(self.this_model.element) - \
(p_elements*(1-1)) # last block
# , including the type of mesh, version, and byte_order
self.outfile.write(
''+'\n')
#
self.outfile.write(''+'\n')
# , including the number of points and cells
self.outfile.write(''+'\n')
print("Writing Nodes ......")
# Write nodes into vtk files
self.outfile.write(''+'\n')
self.outfile.write(
''+'\n')
for i in range(0, len(self.this_model.stg_n)):
nt = self.this_model.stg_n[i]
# base shape
X, Y, Z = self.this_model.node[nt].coordinates[0], self.this_model.node[
nt].coordinates[1], self.this_model.node[nt].coordinates[2]
# modify shape
# X,Y,Z = node[nt].coordinates[0]+ux,node[nt].coordinates[1]+uy,node[nt].coordinates[2]+uz
self.outfile.write(' '+'%11.8e' % X+' '+'%11.8e' %
Y+' '+'%11.8e' % Z+'\n')
self.outfile.write(''+'\n')
self.outfile.write(''+'\n')
#
def Results_data(self):
print("Writing Results data ......")
# Write results data into vtk files
# 'U','A', 'V', 'RF','PEEQ','S'
col = {"Scalars": [], "Vevtors": [], "Tensors": []}
for var_id in ['NT11']:
try:
col["Scalars"].append("Temperature")
except:
print('jump', var_id)
con = "Scalars="+'"'+','.join(col["Scalars"])+'"'
# con = "Tensors="+'"'+','.join(col["Tensors"])+'"' + " "+ \
# "Vevtors="+'"'+','.join(col["Vevtors"])+'"' + " "+ \
# "Scalars="+'"'+','.join(col["Scalars"])+'"'
self.outfile.write("<"+"PointData"+" "+con+">"+'\n')
for var_id in ['NT11']:
fieldOutputs = self.N_Frame.fieldOutputs[var_id]
from utils_odb import NT11 as pq_class
pq_class(fieldOutputs, self.outfile, self.this_model.stg_n)
self.outfile.write(""+'\n')
#
def after_Results_data(self):
print("Writing Cells ......")
# Write cells into vtk files
self.outfile.write(''+'\n')
# Connectivity 8 node
self.outfile.write(
''+'\n')
if (self.this_model.mesh_type == 12):
for i in range(len(self.this_model.stg_e)/8):
self.outfile.write(
' '.join([str(self.this_model.stg_e[i*8+idx]) for idx in range(8)])+'\n')
if (self.this_model.mesh_type == 10):
for i in range(len(self.this_model.stg_e)/4):
self.outfile.write(
' '.join([str(self.this_model.stg_e[i*4+idx]) for idx in range(4)])+'\n')
self.outfile.write(''+'\n')
# Offsets
self.outfile.write(
''+'\n')
for i in range(len(self.this_model.stg_e)/self.this_model.mesh_conner):
self.outfile.write(
str(i*self.this_model.mesh_conner+self.this_model.mesh_conner)+'\n')
self.outfile.write(''+'\n')
# Mesh Type
self.outfile.write(
''+'\n')
for i in range(len(self.this_model.stg_e)/self.this_model.mesh_conner):
self.outfile.write(str(self.this_model.mesh_type)+'\n')
self.outfile.write(''+'\n')
self.outfile.write(''+'\n')
#
#
self.outfile.write(''+'\n')
#
self.outfile.write(''+'\n')
#
self.outfile.write(''+'\n')
class MODEL(object):
def __init__(self, this_instance, mesh_type):
self.mesh_type = mesh_type
self.mesh()
# access nodes & elements
self.this_instance = this_instance
self.count()
def mesh(self):
if (self.mesh_type == 12):
mesh_conner = 8
mesh_name = "Hexahedron"
elif (self.mesh_type == 10):
mesh_conner = 4
mesh_name = "Tetra"
else:
print("Mesh type error or unidentified")
os._exit(0)
print("Mesh type:", mesh_name)
self.mesh_conner = mesh_conner
def count(self):
node = self.this_instance.nodes
element = self.this_instance.elements
# match nodes' label and its order in sequence (for empty nodes in tetra mesh)
MLN = node[len(node)-1].label
TOTAL = []
# read node in sequence, and get the largest label of node(non-empty)
# MLN is the max label of nodeset
for i in node:
TOTAL.append(i.label)
if (i.label > MLN):
MLN = i.label
# match (the key)
L = []
n = 0
for i in range(MLN):
L.append(0)
for i in TOTAL:
L[i-1] = n
n += 1
# estimate whether the node has already existed
stg_p = []
# store the reorganized node for element
stg_e = []
# store the reorganized node for node
stg_n = []
for i in range(MLN):
stg_p.append(-1)
nodecount = 0
# reorganize the node and element (reconstruct the mesh)
for i in range(0, len(element)):
for j in range(self.mesh_conner):
k = element[i].connectivity[j] - 1
if (stg_p[k] < 0):
stg_p[k] = nodecount
stg_n.append(int(L[k]))
stg_e.append(nodecount)
nodecount += 1
else:
stg_e.append(stg_p[k])
self.stg_p = stg_p
self.stg_e = stg_e
self.stg_n = stg_n
self.element = element
self.node = node
# Modify the default value of filename here to specify the default configuration file
def ConvertOdb2Vtk(odb_path):
# open an ODB ( Abaqus output database )
odb = openOdb(odb_path, readOnly=True)
print("ODB opened")
# instance cycle # access geometry and topology information ( odb->rootAssembly->instances->(nodes, elements) )
instance = odb.rootAssembly.instances
for instancename in instance.keys():
print("Instance: ", instancename)
this_model = MODEL(
mesh_type=mesh_type, this_instance=instance[instancename])
# step cycle
step = odb.steps
for stepname in step.keys():
print("Step: ", stepname)
# frame cycle # access attribute(fieldOutputs) information
for i_frame, N_Frame in enumerate(step[stepname].frames):
# if i_frame 20:
# continue
# Access a frame
print("Frame:", i_frame)
time_temp = time.time()
# create and open a VTK(.vtu) files
VTKFile(outfile=os.path.join(vtk_path)+stepname +
'_'+instancename+'_f%04d' % int(i_frame)+'.vtu',
this_model=this_model,
N_Frame=N_Frame)
print("Time elapsed: ", time.time() - time_temp, "s")
odb.close()
# get odb file's path
odb_path = 'C:/Users/OPTX/Downloads/Digital-Twin/odb2vtk/Thermal.odb'
# get the output files' path
vtk_path = 'C:/Users/OPTX/Downloads/Digital-Twin/odb2vtk/output/' # not.vtu,.vtk
mesh_type = 12
ConvertOdb2Vtk(odb_path)