744 lines
22 KiB
Python
744 lines
22 KiB
Python
# -*- coding: UTF-8 no BOM -*-
|
|
|
|
# This tool converts a msc.marc result file into the vtk format that
|
|
# can be viewed by Paraview software (Kitware), or MayaVi (needs xml-vtk, or ...
|
|
#
|
|
# About the vtk format: http://www.vtk.org/VTK/project/about.html
|
|
# Some example vtk files: http://people.sc.fsu.edu/~jburkardt/data/vtk/vtk.html
|
|
# www.paraview.org
|
|
|
|
import os,sys,re
|
|
import numpy as np
|
|
|
|
import py_post # MSC closed source module to access marc result files
|
|
|
|
class MARC_POST():
|
|
def __init__(self):
|
|
self.projdir='./'
|
|
|
|
def opent16(self,incr=None):
|
|
self.fpath=os.path.join(self.projdir,self.postname)
|
|
print('Trying to open ',self.fpath,' ...')
|
|
self.p=py_post.post_open(self.fpath)
|
|
if self.p is None:
|
|
print('Could not open %s.'%self.postname); #return 'err'#; sys.exit(1)
|
|
raise Exception('Could not open t16')
|
|
print('Postfile %s%s is open ...'%(self.projdir,self.postname))
|
|
self.maxincr=self.p.increments()
|
|
print('and has %i increments'%self.maxincr)
|
|
if incr is None:
|
|
self.p.moveto(self.maxincr-1)
|
|
else:
|
|
self.p.moveto(incr+1)
|
|
print('moved to increment ', self.p.increment)
|
|
self.p.extrapolation('translate') # linear, translate, average. query with p.extrapolate
|
|
print('extrapolation method is ', self.p.extrapolate)
|
|
print('collecting model information')
|
|
self.t16info(printFlag=0)
|
|
print('t16 is open')
|
|
self.p
|
|
|
|
def t16info(self, printFlag=1
|
|
):
|
|
if not self.p:
|
|
self.p=self.opent16()#post_open(self.postname)
|
|
print(self.p)
|
|
oldincr=self.p.position
|
|
if oldincr==0:
|
|
self.p.moveto(1)
|
|
|
|
self.nnodes=self.p.nodes() #self.p.node(self.nnodes) crashes; only to nnodes-1 possible
|
|
self.nodes=range(0,self.nnodes)
|
|
self.nscals=self.p.node_scalars(); #print 'nscals', nscals
|
|
self.nscal_list=['']*self.nscals
|
|
self.nel=self.p.elements()
|
|
self.elscals=self.p.element_scalars()
|
|
self.elscal_list=['']*self.elscals
|
|
self.eltens=self.p.element_tensors()
|
|
self.elten_list=['']*self.eltens
|
|
for i in range(0,self.nscals):
|
|
self.nscal_list[i]=self.p.node_scalar_label(i)
|
|
for i in range (0,self.elscals):
|
|
self.elscal_list[i]=self.p.element_scalar_label(i)
|
|
if printFlag==1: print(i, self.elscal_list[i])
|
|
for i in range (0,self.eltens):
|
|
self.elten_list[i]=self.p.element_tensor_label(i)
|
|
if printFlag==1: print(i, self.elten_list[i])
|
|
for i in range(0,self.p.element_tensors()):
|
|
if printFlag==1: print('Element Tensor: ', i, self.p.element_tensor_label(i))
|
|
if printFlag==1: print('')
|
|
for i in range(0,self.p.element_scalars()):
|
|
if printFlag==1: print('Element Scalar: ', i, self.p.element_scalar_label(i))
|
|
if oldincr==0:
|
|
self.p.moveto(0)
|
|
|
|
def closet16(self):
|
|
print('Trying to close FEM result file ...')
|
|
try:
|
|
if self.p:
|
|
self.p.close()
|
|
print('FEM result file closed.')
|
|
self.p=None
|
|
else:
|
|
print('post object not open?')
|
|
except:
|
|
print('ERROR. Could not close FEM result file.')
|
|
|
|
def getLabelNr(self, label=None, type='Scalar'):
|
|
if type[0]=='S' or type[0]=='s': # element scalar
|
|
labelNr=self.elscal_list.index(label)
|
|
elif type[0]=='N': # node scalar
|
|
labelNr=self.nscal_list.index(label)
|
|
elif type[0]=='T' or type[0]=='t': # tensor
|
|
labelNr=self.elten_list.index(label)
|
|
print('Found label %s at index %i'%(label,labelNr))
|
|
return labelNr
|
|
|
|
|
|
def writeNodes2VTK(self, fobj):
|
|
self.points=[]
|
|
self.VTKcnt=200 # number of values per line in vtk file
|
|
fobj.write('POINTS %i'%self.p.nodes()+' float\n')
|
|
self.nodes_dict={} # store the node IDs in case of holes in the numbering
|
|
for iNd in self.nodes:
|
|
nd=self.p.node(iNd)
|
|
disp=self.p.node_displacement(iNd)
|
|
nd_xyz=[nd.x+disp[0], nd.y+disp[1], nd.z+disp[2]]
|
|
self.points.append(nd_xyz) # for pyvtk
|
|
fobj.write('%f %f %f \n'%
|
|
(nd.x+disp[0], nd.y+disp[1], nd.z+disp[2]))
|
|
self.nodes_dict[nd.id-1]=iNd
|
|
fobj.write('\n')
|
|
print('Nodes written to VTK: %i'%self.p.nodes())
|
|
|
|
def writeElements2VTK(self, fobj):
|
|
fobj.write('\nCELLS %i %i'%(self.p.elements(),self.p.elements()*9)+'\n')
|
|
self.cells=[] #for pyvtk
|
|
for iEl in range(0,self.nel):
|
|
el=self.p.element(iEl)
|
|
cell_nodes=[] # for pyvtk
|
|
ndlist=el.items
|
|
for k in [0, 1, 2, 3, 4, 5, 6, 7]: # FOR CELL TYPE VTK_HEXAHEDRON
|
|
node=ndlist[k]-1
|
|
cell_nodes.append(self.nodes_dict[node])
|
|
self.cells.append(cell_nodes) # for pyvtk
|
|
for e in self.cells:
|
|
fobj.write('8 ')
|
|
for n in e:
|
|
fobj.write('%6i '%n)
|
|
fobj.write('\n')
|
|
fobj.write('\nCELL_TYPES %i'%self.p.elements()+'\n')
|
|
cnt=0
|
|
for iEl in range(0,self.nel):
|
|
cnt=cnt+1
|
|
#fobj.write('11\n') #VTK_VOXEL
|
|
fobj.write('12 ') #VTK_HEXAHEDRON
|
|
if cnt>self.VTKcnt:
|
|
fobj.write('\n');cnt=0
|
|
fobj.write('\n')
|
|
print('Elements written to VTK: %i'%self.p.elements())
|
|
|
|
def writeElScalars2NodesVTK(self,fobj):
|
|
fobj.write('\nPOINT_DATA %i\n'%self.p.nodes())
|
|
nScal=12
|
|
nComponents=1+nScal
|
|
fobj.write('SCALARS scalars float %i\n'%nComponents)
|
|
fobj.write('LOOKUP_TABLE default\n')
|
|
idxScal=self.nscal_list.index('Displacement Z')
|
|
for iNd in self.nodes:
|
|
fobj.write('%f '%(self.p.node_scalar(iNd,idxScal)))
|
|
for iEl in range(0,self.nel):
|
|
el=self.p.element(iEl)
|
|
ndlist=el.items
|
|
if (iNd+1) in ndlist:
|
|
idx=ndlist.index(iNd+1)
|
|
for iV in range(0,nScal):
|
|
elData=self.p.element_scalar(iEl,35+iV)
|
|
fobj.write('%f '%(elData[idx].value))
|
|
break
|
|
fobj.write('\n')
|
|
fobj.write('\n')
|
|
|
|
def writeNodeScalars2VTK(self,fobj):
|
|
fobj.write('\nPOINT_DATA %i\n'%self.p.nodes())
|
|
self.pointDataScalars=[]
|
|
for idxNdScal in range(-3,self.nscals): #now include node x,y,z
|
|
if idxNdScal>=0:
|
|
datalabel=self.nscal_list[idxNdScal]
|
|
datalabel=re.sub("\s",'_',datalabel)
|
|
else:
|
|
if idxNdScal==-3: datalabel='node.x'
|
|
if idxNdScal==-2: datalabel='node.y'
|
|
if idxNdScal==-1: datalabel='node.z'
|
|
fobj.write('SCALARS %s float %i\n'%(datalabel,1))#nComponents))
|
|
fobj.write('LOOKUP_TABLE default\n')
|
|
cnt=0
|
|
for iNd in range(0,self.nnodes):
|
|
cnt=cnt+1
|
|
if idxNdScal>=0:
|
|
ndData=self.p.node_scalar(iNd,idxNdScal)
|
|
else:
|
|
nd=self.p.node(iNd)
|
|
if idxNdScal==-3: ndData=nd.x
|
|
if idxNdScal==-2: ndData=nd.y
|
|
if idxNdScal==-1: ndData=nd.z
|
|
fobj.write('%E '%(ndData))
|
|
if cnt>self.VTKcnt:
|
|
fobj.write('\n')
|
|
cnt=0
|
|
fobj.write('\n')
|
|
fobj.write('\n')
|
|
|
|
def writeElementData2VTK(self,fobj):
|
|
self.sig_vMises=[]
|
|
self.sig33=[]
|
|
idx_sig_vMises=self.getLabelNr('Equivalent Von Mises Stress')
|
|
idx_sig33=self.getLabelNr('Comp 33 of Cauchy Stress')
|
|
fobj.write('\nCELL_DATA %i\n'%self.p.elements())
|
|
for idxElScal in range(0,self.elscals):
|
|
datalabel=self.elscal_list[idxElScal]
|
|
datalabel=re.sub("\s",'_',datalabel)
|
|
fobj.write('\n\nSCALARS %s float %i\n'%(datalabel,1))
|
|
fobj.write('LOOKUP_TABLE default\n')
|
|
cnt=0
|
|
for iEl in range(0,self.nel):
|
|
cnt=cnt+1
|
|
elData=self.p.element_scalar(iEl,idxElScal)
|
|
avgScal=0.0
|
|
if datalabel in ['phi1', 'PHI','phi2']: # Euler angles should not be averaged
|
|
avgScal=avgScal+elData[0].value
|
|
else:
|
|
for IP in range(0,8):
|
|
avgScal=avgScal+elData[IP].value
|
|
avgScal=avgScal/8.
|
|
fobj.write('%E '%(avgScal))
|
|
if idxElScal==idx_sig_vMises:
|
|
self.sig_vMises.append(avgScal)
|
|
elif idxElScal==idx_sig33:
|
|
self.sig33.append(avgScal)
|
|
if cnt>self.VTKcnt:
|
|
fobj.write('\n')
|
|
cnt=0
|
|
fobj.write('\n')
|
|
|
|
def get_avg_el_scal(self,idxElScal):
|
|
result=[]
|
|
datalabel=self.elscal_list[idxElScal]
|
|
print('Collecting %s from all elements'%datalabel)
|
|
for iEl in range(0,self.nel):
|
|
elData=self.p.element_scalar(iEl,idxElScal)
|
|
avgScal=0.0
|
|
for IP in range(0,8):
|
|
avgScal=avgScal+elData[IP].value
|
|
avgScal=avgScal/8.
|
|
result.append(avgScal)
|
|
return result
|
|
|
|
def writeUniaxiality2VTK(self,fobj):
|
|
datalabel='uniaxiality_sig_vMises_durch_sig33'
|
|
fobj.write('SCALARS %s float %i\n'%(datalabel,1))
|
|
fobj.write('LOOKUP_TABLE default\n')
|
|
cnt=0
|
|
for iEl in range(0,self.nel):
|
|
cnt=cnt+1
|
|
if abs(self.sig_vMises[iEl])<1e-5:
|
|
datum=0.
|
|
else:
|
|
datum=self.sig33[iEl]/self.sig_vMises[iEl]
|
|
fobj.write('%E '%(datum))
|
|
if cnt>self.VTKcnt:
|
|
fobj.write('\n')
|
|
cnt=0
|
|
fobj.write('\n')
|
|
|
|
def stress_per_element(self):
|
|
self.stress=[]
|
|
for iEl in range(0,self.nel):
|
|
sig=self.avg_elten(2,elID=iEl)
|
|
self.stress.append(sig[0])
|
|
|
|
def mean_stress_per_element(self):
|
|
self.mean_stress=[]
|
|
for iEl in range(0,self.nel):
|
|
sig=self.stress[iEl]
|
|
self.mean_stress.append(self.meanStress(sig))
|
|
|
|
def triaxiality_per_element(self):
|
|
# classical triaxiality
|
|
# 1/3 : uniax tension
|
|
self.triaxiality=[]
|
|
for iEl in range(0,self.nel):
|
|
t=self.mean_stress[iEl]/self.sig_vMises[iEl]
|
|
self.triaxiality.append(t)
|
|
|
|
def moreElData2VTK(self,fobj,data=[],label='datalabel'):
|
|
fobj.write('SCALARS %s float %i\n'%(label,1))
|
|
fobj.write('LOOKUP_TABLE default\n')
|
|
cnt=0
|
|
for iEl in range(0,self.nel):
|
|
cnt=cnt+1
|
|
fobj.write('%E '%(data[iEl]))
|
|
if cnt>self.VTKcnt:
|
|
fobj.write('\n')
|
|
cnt=0
|
|
fobj.write('\n')
|
|
|
|
def calc_lode_parameter(self):
|
|
self.lode=[]
|
|
try:
|
|
self.stress
|
|
except:
|
|
self.stress_per_element()
|
|
for iEl in range(0,self.nel):
|
|
sig=self.stress[iEl]
|
|
lode=self.stress2lode(sig)
|
|
self.lode.append(lode)
|
|
|
|
def stress2lode(self,stress):
|
|
[pStress,pAxes]=self.princStress(stress)
|
|
s1=pStress[0]
|
|
s2=pStress[1]
|
|
s3=pStress[2]
|
|
lode=(2*s2-s1-s3) / ( s1 - s3 )
|
|
return lode
|
|
|
|
def princStress(self, stress):
|
|
"""
|
|
Function to compute 3D principal stresses and sort them.
|
|
|
|
from: http://geodynamics.org/svn/cig/short/3D/PyLith/trunk/playpen/postproc/vtkcff.py
|
|
"""
|
|
stressMat=np.array(stress)
|
|
(princStress, princAxes) = np.linalg.eigh(stressMat)
|
|
idx = princStress.argsort()
|
|
princStressOrdered = princStress[idx]
|
|
princAxesOrdered = princAxes[:,idx]
|
|
return princStressOrdered, princAxesOrdered
|
|
|
|
def avg_elten(self,
|
|
idxElTen, mat=0, elID=None):
|
|
tensum=np.zeros((3,3));
|
|
T=np.zeros((3,3));
|
|
pts=0;
|
|
avg=np.zeros((3,3));
|
|
|
|
if elID is None:
|
|
averaged_elements=range(0,self.nel)
|
|
else:
|
|
averaged_elements=[elID]
|
|
for i in averaged_elements:
|
|
if mat==0 or int(self.p.element_scalar(i,4)[0].value)==mat:
|
|
T=self.p.element_tensor(i,idxElTen)
|
|
for k in range (0,8):
|
|
tensum[0][0] = tensum[0][0] + T[k].t11
|
|
tensum[0][1] = tensum[0][1] + T[k].t12
|
|
tensum[0][2] = tensum[0][2] + T[k].t13
|
|
tensum[1][1] = tensum[1][1] + T[k].t22
|
|
tensum[1][2] = tensum[1][2] + T[k].t23
|
|
tensum[2][2] = tensum[2][2] + T[k].t33
|
|
pts=pts+1
|
|
avg=tensum/pts
|
|
avg=self.fillComponents(avg)
|
|
del [T]
|
|
return (avg,tensum,pts)
|
|
|
|
def fillComponents(self,
|
|
halftensor
|
|
):
|
|
halftensor[1][0]=halftensor[0][1]
|
|
halftensor[2][0]=halftensor[0][2]
|
|
halftensor[2][1]=halftensor[1][2]
|
|
return halftensor
|
|
|
|
def vMises(self,tensor33):
|
|
t=tensor33
|
|
s=(t[0,0]-t[1,1])**2+(t[1,1]-t[2,2])**2+(t[0,0]-t[2,2])**2+\
|
|
6*(t[0,1]**2+t[1,2]**2+t[2,0]**2)
|
|
vM=np.sqrt(s/2.)
|
|
return vM
|
|
|
|
def meanStress(self,tensor33):
|
|
t=tensor33
|
|
s=t[0,0]+t[1,1]+t[2,2]
|
|
ms=s/3.
|
|
return ms
|
|
|
|
def invariants(self,tensor33):
|
|
t=tensor33
|
|
I1=t[0,0]+t[1,1]+t[2,2]
|
|
I2=t[0,0]*t[1,1]+t[1,1]*t[2,2]+t[0,0]*t[2,2]-\
|
|
t[0,1]**2-t[1,2]**2-t[0,2]**2
|
|
I3=t[0,0]*t[1,1]*t[2,2]+\
|
|
2*t[0,1]*t[1,2]*t[2,0]-\
|
|
t[2,2]*t[0,1]**2-t[0,0]*t[1,2]**2-t[1,1]*t[0,2]**2
|
|
return [ I1, I2, I3 ]
|
|
|
|
|
|
class VTK_WRITER():
|
|
"""
|
|
The resulting vtk-file can be imported in Paraview 3.12
|
|
|
|
Then use Filters: Cell Data to Point Data + Contour
|
|
to plot semi-transparent iso-surfaces.
|
|
"""
|
|
|
|
def __init__(self):
|
|
self.p=MARC_POST() # self.p
|
|
|
|
def openFile(self, filename='test.vtp'):
|
|
self.f=open(filename,'w+')
|
|
self.fname=filename
|
|
|
|
def writeFirstLines(self,
|
|
vtkFile=None,
|
|
version='2.0',
|
|
comment='Test',
|
|
dformat='ASCII', # BINARY | [ASCII]
|
|
dtype='UNSTRUCTURED_GRID' # UNSTRUCTURED GRID
|
|
):
|
|
if vtkFile is None:
|
|
vtkFile=self.f
|
|
# First Line contains Data format version
|
|
self.versionVTK=version
|
|
vtkFile.write('# vtk DataFile Version %s\n'%self.versionVTK)
|
|
# Comment goes to 2nd line and has maximum 256 chars
|
|
vtkFile.write(comment+'\n')
|
|
vtkFile.write(dformat+'\n')
|
|
vtkFile.write('DATASET '+dtype+'\n')
|
|
|
|
|
|
def marc2vtkBatch(self):
|
|
for iori in range(1,63):
|
|
self.p.postname='indent_fric0.3_R2.70_cA146.0_h0.320_ori%03i_OST_h19d.t16'%(iori)
|
|
if os.path.exists(self.p.postname):
|
|
self.marc2vtk(mode='fast', batchMode=1)
|
|
|
|
def marc2vtk(self, label=None, mode='fast',
|
|
batchMode=0,
|
|
incRange=None,
|
|
incStepMult=1.):
|
|
if batchMode==0:
|
|
try:
|
|
self.p
|
|
except:
|
|
self.p=MARC_POST()
|
|
### ---- CHANGE dir/job/model to process here
|
|
os.chdir('M:/nicu');
|
|
jobname='ori001'
|
|
self.p.postname='indent_fric0.3_R0.25_cA90.0_h0.010_4320els_'+jobname+'.t16'
|
|
### ----
|
|
|
|
self.p.opent16()
|
|
self.p.t16info()
|
|
|
|
incMax=self.p.p.increments();
|
|
if incRange is None:
|
|
incStep=5
|
|
incRange=range(0,incMax+1,incStep)
|
|
self.vtkPath=os.getcwd()+'/vtk_%s/'%self.p.postname
|
|
if not os.path.exists(self.vtkPath):
|
|
os.mkdir(self.vtkPath)
|
|
for inc in incRange:
|
|
print('Increment: %i'%inc)
|
|
self.p.p.moveto(inc)
|
|
t=self.p.p.time
|
|
sys.stdout.write('inc:%i, time:%.3f\n'%(self.p.p.increment,t))
|
|
self.incStr='inc%03i'%(inc*incStepMult)
|
|
self.openFile(filename=self.vtkPath+self.p.postname[0:-4]+'_'+
|
|
self.incStr+'.vtk')
|
|
self.writeFirstLines(comment=self.p.postname,
|
|
dtype='UNSTRUCTURED_GRID')
|
|
self.p.writeNodes2VTK(fobj=self.f)
|
|
self.p.writeElements2VTK(fobj=self.f)
|
|
self.p.writeNodeScalars2VTK(fobj=self.f)
|
|
self.p.writeElementData2VTK(fobj=self.f)
|
|
# insert generation and writing of derived post values
|
|
# *here*
|
|
|
|
self.f.close()
|
|
print('Increment (self.p.p.increment): %i'%self.p.p.increment)
|
|
print('Data written.')
|
|
print(self.p.postname+' ready.')
|
|
|
|
|
|
def scaleBar(self, length=1.0, posXYZ=[0., 0., 0.]):
|
|
self.fsb=open('micronbar_l%.1f.vtp'%length,'w+')
|
|
self.writeFirstLines(self.fsb, comment='micronbar')
|
|
pts=np.array([])
|
|
width=length*1.
|
|
height=length*1.
|
|
wVec=np.array([0., width, 0.])
|
|
lVec=np.array([length,0.,0.])
|
|
hVec=np.array([0.,0.,height])
|
|
posXYZ=posXYZ-0.5*wVec-0.5*lVec#-0.5*hVec # CENTERING Y/N
|
|
posXYZ=np.array(posXYZ)
|
|
pts=[posXYZ, posXYZ+lVec,
|
|
posXYZ+wVec,
|
|
posXYZ+wVec+lVec]
|
|
pts.extend([pts[0]+hVec,pts[1]+hVec,pts[2]+hVec,pts[3]+hVec])
|
|
print(len(pts), pts)
|
|
self.fsb.write('POINTS %i float\n'%len(pts))
|
|
for npts in range(0,len(pts)):
|
|
self.fsb.write('%f %f %f\n'%(pts[npts][0], pts[npts][1], pts[npts][2]))
|
|
if 1: #Triad
|
|
nCells=3
|
|
ptsPerCell=2 # Lines (Type=3)
|
|
cellSize=(ptsPerCell+1)*nCells
|
|
self.fsb.write('CELLS %i %i\n'%(nCells,cellSize))
|
|
self.fsb.write('2 0 1\n') #X-Line
|
|
self.fsb.write('2 0 2\n') #Y-Line
|
|
self.fsb.write('2 0 4\n') #Z-Line
|
|
self.fsb.write('CELL_TYPES %i\n'%(nCells))
|
|
self.fsb.write('3\n3\n3\n')#Line
|
|
else: # Cube, change posXYZ
|
|
nCells=1
|
|
ptsPerCell=2 # Lines (Type=3)
|
|
cellSize=(ptsPerCell+1)*nCells
|
|
self.fsb.write('CELLS %i %i\n'%(nCells,cellSize))
|
|
self.fsb.write('2 0 1\n') #Line
|
|
self.fsb.write('CELL_TYPES %i\n'%(nCells))
|
|
self.fsb.write('3\n')#Line
|
|
|
|
self.fsb.write('\n')
|
|
self.fsb.close()
|
|
print(self.fsb)
|
|
|
|
def example_unstructured(self):
|
|
self.openFile(filename='example_unstructured_grid.vtk')
|
|
self.f.write("""
|
|
# vtk DataFile Version 2.0
|
|
example_unstruct_grid
|
|
ASCII
|
|
|
|
POINTS 12 float
|
|
0 0 0
|
|
1 0 0
|
|
1 1 0
|
|
0 1 0
|
|
0 0 1
|
|
1 0 1
|
|
1 1 1
|
|
0 1 1
|
|
0 0 1.9
|
|
1 0 1.9
|
|
1 1 1.9
|
|
0 1 1.9
|
|
|
|
|
|
CELLS 2 18
|
|
8 0 1 2 3 4 5 6 7
|
|
8 4 5 6
|
|
7 8 9 10 11
|
|
|
|
CELL_TYPES 2
|
|
12
|
|
12
|
|
|
|
POINT_DATA 12
|
|
SCALARS nodex float 1
|
|
LOOKUP_TABLE default
|
|
2.34E+12
|
|
2.00
|
|
0.00
|
|
1.62
|
|
5.03
|
|
1.02
|
|
1.50
|
|
0.00
|
|
3 5 6 23423423423423423423.23423423""")
|
|
self.f.close()
|
|
|
|
|
|
|
|
def writeNodes2VTK(self, fobj):
|
|
self.VTKcnt=200 # how many numbers per line in vtk file
|
|
fobj.write('POINTS %i'%self.p.nodes()+' float\n')
|
|
for iNd in self.nodes:
|
|
nd=self.p.node(iNd)
|
|
disp=self.p.node_displacement(iNd)
|
|
fobj.write('%f %f %f \n'%
|
|
(nd.x+disp[0], nd.y+disp[1], nd.z+disp[2]))
|
|
fobj.write('\n')
|
|
print('Nodes written to VTK: %i'%self.p.nodes())
|
|
|
|
def writeElements2VTK(self, fobj):
|
|
fobj.write('\nCELLS %i %i'%(self.p.elements(),self.p.elements()*9)+'\n')
|
|
for iEl in range(0,self.nel):
|
|
el=self.p.element(iEl)
|
|
fobj.write('8 ')
|
|
ndlist=el.items
|
|
for k in [0, 1, 2, 3, 4, 5, 6, 7]: # FOR CELL TYPE VTK_HEXAHEDRON
|
|
fobj.write('%6i '%(ndlist[k]-1))
|
|
fobj.write('\n')
|
|
fobj.write('\nCELL_TYPES %i'%self.p.elements()+'\n')
|
|
cnt=0
|
|
for iEl in range(0,self.nel):
|
|
cnt=cnt+1
|
|
fobj.write('12 ') #VTK_HEXAHEDRON
|
|
if cnt>self.VTKcnt:
|
|
fobj.write('\n');cnt=0
|
|
fobj.write('\n')
|
|
print('Elements written to VTK: %i'%self.p.elements())
|
|
|
|
def writeElScalars2NodesVTK(self,fobj):
|
|
fobj.write('\nPOINT_DATA %i\n'%self.p.nodes())
|
|
nScal=12
|
|
nComponents=1+nScal
|
|
fobj.write('SCALARS scalars float %i\n'%nComponents)
|
|
fobj.write('LOOKUP_TABLE default\n')
|
|
idxScal=self.nscal_list.index('Displacement Z')
|
|
for iNd in self.nodes:
|
|
fobj.write('%f '%(self.p.node_scalar(iNd,idxScal)))
|
|
for iEl in range(0,self.nel):
|
|
el=self.p.element(iEl)
|
|
ndlist=el.items
|
|
if (iNd+1) in ndlist:
|
|
idx=ndlist.index(iNd+1)
|
|
for iV in range(0,nScal):
|
|
elData=self.p.element_scalar(iEl,35+iV)
|
|
fobj.write('%f '%(elData[idx].value))
|
|
break
|
|
fobj.write('\n')
|
|
fobj.write('\n')
|
|
|
|
def writeNodeScalars2VTK(self,fobj):
|
|
fobj.write('\nPOINT_DATA %i\n'%self.p.nodes())
|
|
for idxNdScal in range(-3,self.nscals): # include node x,y,z
|
|
if idxNdScal>=0:
|
|
datalabel=self.nscal_list[idxNdScal]
|
|
datalabel=re.sub("\s",'_',datalabel)
|
|
else:
|
|
if idxNdScal==-3: datalabel='node.x'
|
|
if idxNdScal==-2: datalabel='node.y'
|
|
if idxNdScal==-1: datalabel='node.z'
|
|
fobj.write('SCALARS %s float %i\n'%(datalabel,1))#nComponents))
|
|
fobj.write('LOOKUP_TABLE default\n')
|
|
cnt=0
|
|
for iNd in range(0,self.nnodes):
|
|
cnt=cnt+1
|
|
if idxNdScal>=0:
|
|
ndData=self.p.node_scalar(iNd,idxNdScal)
|
|
else:
|
|
nd=self.p.node(iNd)
|
|
if idxNdScal==-3: ndData=nd.x
|
|
if idxNdScal==-2: ndData=nd.y
|
|
if idxNdScal==-1: ndData=nd.z
|
|
fobj.write('%E '%(ndData))
|
|
if cnt>self.VTKcnt:
|
|
fobj.write('\n')
|
|
cnt=0
|
|
fobj.write('\n')
|
|
fobj.write('\n')
|
|
|
|
def writeElementData2VTK(self,fobj):
|
|
fobj.write('\nCELL_DATA %i\n'%self.p.elements())
|
|
for idxElScal in range(0,self.elscals):
|
|
datalabel=self.elscal_list[idxElScal]
|
|
datalabel=re.sub("\s",'_',datalabel)
|
|
fobj.write('\n\nSCALARS %s float %i\n'%(datalabel,1))#nComponents))
|
|
fobj.write('LOOKUP_TABLE default\n')
|
|
cnt=0
|
|
for iEl in range(0,self.nel):
|
|
cnt=cnt+1
|
|
elData=self.p.element_scalar(iEl,idxElScal)
|
|
avgScal=0.0
|
|
if datalabel in ['phi1', 'PHI','phi2']:
|
|
avgScal=avgScal+elData[0].value
|
|
else:
|
|
for IP in range(0,8):
|
|
avgScal=avgScal+elData[IP].value
|
|
avgScal=avgScal/8.
|
|
fobj.write('%E '%(avgScal))
|
|
if cnt>self.VTKcnt:
|
|
fobj.write('\n')
|
|
cnt=0
|
|
fobj.write('\n')
|
|
|
|
|
|
def example1(self):
|
|
self.openFile()
|
|
self.writeFirstLines()
|
|
self.f.write("""DATASET POLYDATA
|
|
POINTS 8 float
|
|
0.0 0.0 0.0
|
|
1.0 0.0 0.0
|
|
1.0 1.0 0.0
|
|
0.0 1.0 0.0
|
|
0.0 0.0 1.0
|
|
1.0 0.0 1.0
|
|
1.0 1.0 1.0
|
|
0.0 1.0 1.0
|
|
POLYGONS 6 30
|
|
4 0 1 2 3
|
|
4 4 5 6 7
|
|
4 0 1 5 4
|
|
4 2 3 7 6
|
|
4 0 4 7 3
|
|
4 1 2 6 5
|
|
|
|
CELL_DATA 6
|
|
SCALARS cell_scalars int 1
|
|
LOOKUP_TABLE default
|
|
0
|
|
1
|
|
2
|
|
3
|
|
4
|
|
5
|
|
NORMALS cell_normals float
|
|
0 0 -1
|
|
0 0 1
|
|
0 -1 0
|
|
0 1 0
|
|
-1 0 0
|
|
1 0 0
|
|
FIELD FieldData 2
|
|
cellIds 1 6 int
|
|
0 1 2 3 4 5
|
|
faceAttributes 2 6 float
|
|
0.0 1.0 1.0 2.0 2.0 3.0 3.0 4.0 4.0 5.0 5.0 6.0
|
|
|
|
POINT_DATA 8
|
|
SCALARS sample_scalars float 1
|
|
LOOKUP_TABLE my_table
|
|
0.0
|
|
1.0
|
|
2.0
|
|
3.0
|
|
4.0
|
|
5.0
|
|
6.0
|
|
7.0
|
|
LOOKUP_TABLE my_table 8
|
|
0.0 0.0 0.0 1.0
|
|
1.0 0.0 0.0 1.0
|
|
0.0 1.0 0.0 1.0
|
|
1.0 1.0 0.0 1.0
|
|
0.0 0.0 1.0 1.0
|
|
1.0 0.0 1.0 1.0
|
|
0.0 1.0 1.0 1.0
|
|
1.0 1.0 1.0 1.0""")
|
|
self.f.close()
|
|
|
|
|
|
import pyvtk
|
|
class marc_to_vtk():
|
|
"""
|
|
Anybody wants to implement it with pyvtk?
|
|
|
|
The advantage would be that pyvtk can also wirte the
|
|
<xml>-VTK format and binary.
|
|
These can be plotted with mayavi.
|
|
"""
|
|
|
|
def __init__(self):
|
|
self.p=[]#MARC_POST() # self.p
|
|
|
|
def run(self):
|
|
vtk = pyvtk.VtkData(\
|
|
pyvtk.UnstructuredGrid(self.p.points,
|
|
hexahedron=self.p.cells),
|
|
'm2v output')
|
|
vtk.tofile('m2v_file')
|
|
|