You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

268 lines
10 KiB
Python

# import necessary modules to handle Abaqus output database, files and string
from odbAccess import *
from textRepr import *
from string import *
import os
import time
def ConvertOdb2Vtk(): # Modify the default value of filename here to specify the default configuration file
starttime = time.time()
# display the reading result of odb2vtk file
print("odb2vtk reading finished, time elapsed: "), time.time()-starttime
print("Basic Information:")
print("Model:", odb_path, "; Mesh type:",
mesh_name, "; Number of blocks:", 1)
print("Convert frames: ", input_frame[0], " to ", input_frame[-1])
print("Step & Instance : ", str(input_step), ", ", str(input_instance))
# open an ODB ( Abaqus output database )
odb = openOdb(os.path.join(odb_path), readOnly=True)
print("ODB opened")
# access geometry and topology information ( odb->rootAssembly->instances->(nodes, elements) )
rootassembly = odb.rootAssembly
instance = rootassembly.instances
# access attribute information
step = odb.steps
# get instance & step information : Quantity and all names
allinstancestr = str(instance)
autoins = allinstancestr.split("'")
inslen = len(autoins)/4
instance_N = range(0, inslen)
allstepstr = str(step)
autostep = allstepstr.split("'")
steplen = len(autostep)/4
step_N = range(0, steplen)
for i in input_step:
if (steplen < int(i)):
print("input step exceeds the range of steps")
os._exit(0)
for i in input_instance:
if (inslen < int(i)):
print("input instance exceeds the range of instances")
os._exit(0)
# step cycle
for step_i in input_step:
n = int(step_i)*4+1
stepname = autostep[n]
print("Step: ", stepname)
# instance cycle
for ins_i in input_instance:
n = int(ins_i)*4+1
instancename = autoins[n]
print("Instance: ", instancename)
# access nodes & elements
node = instance[instancename].nodes
element = instance[instancename].elements
n_nodes = len(node)
n_elements = len(element)
# access attribute(fieldOutputs) information
frame = step[stepname].frames
print('all frame',frame)
# compute the number of element of each block
p_elements = n_elements/1 + 1
lp_elements = n_elements - (p_elements*(1-1)) # last block
# match nodes' label and its order in sequence (for empty nodes in tetra mesh)
MLN = node[n_nodes-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
# frame cycle
for i_frame in input_frame:
# Detect whether the input frame is out of range
try:
odb.steps[stepname].frames[int(i_frame)]
except:
print("input frame exceeds the range of frames")
os._exit(0)
break
# Access a frame
N_Frame = odb.steps[stepname].frames[int(i_frame)]
print("Frame:", i_frame)
print("Partitionning model and writing vtk files ......")
# piece cycle, to partion the model and create each piece for vtk files
time1 = time.time()
print("frame:", i_frame, ";")
# Reorganization
# Control&Storage
# 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)
M = range(0, n_elements)
for i in M:
for j in range(mesh_conner):
k = element[i].connectivity[j] - 1
if (stg_p[k] < 0):
stg_p[k] = nodecount
stg_n.append(L[k])
stg_e.append(nodecount)
nodecount += 1
else:
stg_e.append(stg_p[k])
# compute point quantity
n_reop = len(stg_n)
reop_N = range(0, len(stg_n))
# create and open a VTK(.vtu) files
outfile = open(os.path.join(vtk_path)+'_'+stepname +
'_'+instancename+'f%03d' % int(i_frame)+'.vtu', 'w')
# <VTKFile>, including the type of mesh, version, and byte_order
outfile.write(
'<VTKFile type="UnstructuredGrid" version="0.1" byte_order="LittleEndian">'+'\n')
# <UnstructuredGrid>
outfile.write('<UnstructuredGrid>'+'\n')
# <Piece>, including the number of points and cells
outfile.write('<Piece NumberOfPoints="'+str(n_reop) +
'"'+' '+'NumberOfCells="'+str(lp_elements)+'">'+'\n')
print("Writing Nodes ......")
# <Points> Write nodes into vtk files
outfile.write('<Points>'+'\n')
outfile.write(
'<DataArray type="Float64" NumberOfComponents="3" format="ascii">'+'\n')
for i in reop_N:
nt = stg_n[i]
k = node[stg_n[i]].label-1
# base shape
X, Y, Z = node[nt].coordinates[0], node[nt].coordinates[1], node[nt].coordinates[2]
# modify shape
# X,Y,Z = node[nt].coordinates[0]+ux,node[nt].coordinates[1]+uy,node[nt].coordinates[2]+uz
outfile.write(' '+'%11.8e' % X+' '+'%11.8e' %
Y+' '+'%11.8e' % Z+'\n')
outfile.write('</DataArray>'+'\n')
outfile.write('</Points>'+'\n')
# </Points>
print("Writing Results data ......")
# <PointData> Write results data into vtk files
col = {"Scalars": [], "Vevtors": [], "Tensors": []}
# 'U','A', 'V', 'RF','PEEQ','S'
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"])+'"'
outfile.write("<"+"PointData"+" "+con+">"+'\n')
for var_id in ['NT11']:
fieldOutputs = N_Frame.fieldOutputs[var_id]
from utils_odb import NT11 as pq_class
pq_class(fieldOutputs,outfile,reop_N)
outfile.write("</PointData>"+'\n')
# </PointData>
print("Writing Cells ......")
# <Cells> Write cells into vtk files
outfile.write('<Cells>'+'\n')
# Connectivity 8 node
outfile.write(
'<DataArray type="Int32" Name="connectivity" format="ascii">'+'\n')
if (mesh_type == 12):
for i in range(len(stg_e)/8):
outfile.write(str(stg_e[i*8])+' '+str(stg_e[i*8+1])+' '+str(stg_e[i*8+2])+' '+str(stg_e[i*8+3])+' '+str(
stg_e[i*8+4])+' '+str(stg_e[i*8+5])+' '+str(stg_e[i*8+6])+' '+str(stg_e[i*8+7])+'\n')
if (mesh_type == 10):
for i in range(len(stg_e)/4):
outfile.write(str(
stg_e[i*4])+' '+str(stg_e[i*4+1])+' '+str(stg_e[i*4+2])+' '+str(stg_e[i*4+3])+'\n')
outfile.write('</DataArray>'+'\n')
# Offsets
outfile.write(
'<DataArray type="Int32" Name="offsets" format="ascii">'+'\n')
for i in range(len(stg_e)/mesh_conner):
outfile.write(str(i*mesh_conner+mesh_conner)+'\n')
outfile.write('</DataArray>'+'\n')
# Mesh Type
outfile.write(
'<DataArray type="UInt8" Name="types" format="ascii">'+'\n')
for i in range(len(stg_e)/mesh_conner):
outfile.write(str(mesh_type)+'\n')
outfile.write('</DataArray>'+'\n')
outfile.write('</Cells>'+'\n')
# </Cells>
# </Piece>
outfile.write('</Piece>'+'\n')
# </UnstructuredGrid>
outfile.write('</UnstructuredGrid>'+'\n')
# </VTKFile>
outfile.write('</VTKFile>'+'\n')
outfile.close()
print("Time elapsed: ", time.time() - time1, "s")
odb.close()
print("Total time elapsed: ", time.time() - starttime, "s")
# 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/' # not.vtu,.vtk
# get the mesh type
mesh_type = 12 # c3d8?
mesh_conner = 0
if (mesh_type == 12):
mesh_conner = 8
mesh_name = "Hexahedron"
if (mesh_type == 10):
mesh_conner = 4
mesh_name = "Tetra"
if (mesh_conner == 0):
print("Mesh type error or unidentified")
os._exit(0)
# get the frame
input_frame = range(1, 4+1)
# get the step
input_step = '0'.split(",")
# get the instance
input_instance = '0'.split(",")
# end reding and close odb2vtk file
ConvertOdb2Vtk()