mirror of
https://github.com/ParticulateFlow/LPP.git
synced 2025-12-08 06:37:46 +00:00
move imports to top of files add from __future__ import commands module -> subprocesses module print statement -> print() function exec statement -> exec() function xrange -> range map() -> list(map()) StandardError -> Exception integer division: / -> // x.has_key(y) -> y in x sort(): use functools.cmp_to_key type(x) is y -> isinstance(x, y) raw_input -> input change variable names 'list' to avoid clashes with list class
908 lines
31 KiB
Python
908 lines
31 KiB
Python
# Pizza.py toolkit, www.cs.sandia.gov/~sjplimp/pizza.html
|
|
# Steve Plimpton, sjplimp@sandia.gov, Sandia National Laboratories
|
|
#
|
|
# Copyright (2005) Sandia Corporation. Under the terms of Contract
|
|
# DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
|
|
# certain rights in this software. This software is distributed under
|
|
# the GNU General Public License.
|
|
|
|
# mdump tool
|
|
|
|
# Imports and external programs
|
|
|
|
from __future__ import absolute_import
|
|
import sys, subprocess, re, glob, types
|
|
import functools
|
|
from os import popen
|
|
from math import * # any function could be used by set()
|
|
|
|
oneline = "Read, write, manipulate mesh dump files"
|
|
|
|
docstr = """
|
|
m = mdump("mesh.one") read in one or more mesh dump files
|
|
m = mdump("mesh.1 mesh.2.gz") can be gzipped
|
|
m = mdump("mesh.*") wildcard expands to multiple files
|
|
m = mdump("mesh.*",0) two args = store filenames, but don't read
|
|
|
|
incomplete and duplicate snapshots are deleted
|
|
|
|
time = m.next() read next snapshot from dump files
|
|
|
|
used with 2-argument constructor to allow reading snapshots one-at-a-time
|
|
snapshot will be skipped only if another snapshot has same time stamp
|
|
return time stamp of snapshot read
|
|
return -1 if no snapshots left or last snapshot is incomplete
|
|
no column name assignment or unscaling is performed
|
|
|
|
m.map(2,"temperature") assign names to element value columns (1-N)
|
|
|
|
m.tselect.all() select all timesteps
|
|
m.tselect.one(N) select only timestep N
|
|
m.tselect.none() deselect all timesteps
|
|
m.tselect.skip(M) select every Mth step
|
|
m.tselect.test("$t >= 100 and $t < 10000") select matching timesteps
|
|
m.delete() delete non-selected timesteps
|
|
|
|
selecting a timestep also selects all elements in the timestep
|
|
skip() and test() only select from currently selected timesteps
|
|
test() uses a Python Boolean expression with $t for timestep value
|
|
Python comparison syntax: == != < > <= >= and or
|
|
|
|
m.eselect.all() select all elems in all steps
|
|
m.eselect.all(N) select all elems in one step
|
|
m.eselect.test("$id > 100 and $type == 2") select match elems in all steps
|
|
m.eselect.test("$id > 100 and $type == 2",N) select matching elems in one step
|
|
|
|
all() with no args selects atoms from currently selected timesteps
|
|
test() with one arg selects atoms from currently selected timesteps
|
|
test() sub-selects from currently selected elements
|
|
test() uses a Python Boolean expression with $ for atom attributes
|
|
Python comparison syntax: == != < > <= >= and or
|
|
$name must end with a space
|
|
|
|
t = m.time() return vector of selected timestep values
|
|
fx,fy,... = m.vecs(1000,"fx","fy",...) return vector(s) for timestep N
|
|
|
|
vecs() returns vectors with one value for each selected elem in the timestep
|
|
|
|
index,time,flag = m.iterator(0/1) loop over mesh dump snapshots
|
|
time,box,atoms,bonds,tris,lines = m.viz(index) return list of viz objects
|
|
nodes,elements,nvalues,evalues = m.mviz(index) return list of mesh viz objects
|
|
m.etype = "color" set column returned as "type" by viz
|
|
|
|
iterator() loops over selected timesteps
|
|
iterator() called with arg = 0 first time, with arg = 1 on subsequent calls
|
|
index = index within dump object (0 to # of snapshots)
|
|
time = timestep value
|
|
flag = -1 when iteration is done, 1 otherwise
|
|
viz() returns info for selected elements for specified timestep index
|
|
can also call as viz(time,1) and will find index of preceding snapshot
|
|
time = timestep value
|
|
box = \[xlo,ylo,zlo,xhi,yhi,zhi\]
|
|
atoms = NULL
|
|
bonds = NULL
|
|
tris = id,type,x1,y1,z1,x2,y2,z2,x3,y3,z3,nx,ny,nz for each tri as 2d array
|
|
each element is decomposed into tris
|
|
lines = NULL
|
|
mviz() returns info for all elements for specified timestep index
|
|
can also call as mviz(time,1) and will find index of preceding snapshot
|
|
time = timestep value
|
|
box = \[xlo,ylo,zlo,xhi,yhi,zhi\]
|
|
nodes = list of nodes = id,type,x,y,z
|
|
elements = list of elements = id,type,node1,node2,...
|
|
nvalues = list of node values = id,type,value1,value2,...
|
|
evalues = list of element values = id,type,value1,value2,...
|
|
etype is column name viz() will return as element type (def = "" = elem type)
|
|
"""
|
|
|
|
# History
|
|
# 11/06, Steve Plimpton (SNL): original version
|
|
# 12/09, David Hart (SNL): allow use of NumPy or Numeric
|
|
|
|
# Variables
|
|
# flist = list of dump file names
|
|
# increment = 1 if reading snapshots one-at-a-time
|
|
# nextfile = which file to read from via next()
|
|
# eof = ptr into current file for where to read via next()
|
|
# nsnaps = # of snapshots
|
|
# nselect = # of selected snapshots
|
|
# snaps = list of snapshots
|
|
# names = dictionary of column names:
|
|
# key = "id", value = column # (0 to M-1)
|
|
# tselect = class for time selection
|
|
# eselect = class for element selection
|
|
# etype = name of vector used as element type by viz extract (def = "")
|
|
# Snap = one snapshot
|
|
# time = time stamp
|
|
# tselect = 0/1 if this snapshot selected
|
|
# nflag = 0/1 if this snapshot has nodal coords (may be copies)
|
|
# eflag = 0/n if this snapshot has elements (may be copies)
|
|
# 1 = tri, 2 = tet, 3 = square, 4 = cube
|
|
# nvalueflag = 0/1 if this snapshot has nodal values
|
|
# evalueflag = 0/1 if this snapshot has element values
|
|
# nselect = # of selected elements in this snapshot
|
|
# eselect[i] = 0/1 for each element
|
|
# xlo,xhi,ylo,yhi,zlo,zhi = box bounds (float)
|
|
# nnodes = # of nodes
|
|
# nodes[i][j] = 2d array of floats, i = 0 to Nnod-1, j = 0 to Ncol
|
|
# nelements = # of elements
|
|
# elements[i][j] = 2d array of floats, i = 0 to Nel-1, j = 0 to Ncol
|
|
# nnvalues = # of node values
|
|
# nvalues[i][j] = 2d array of floats, i = 0 to Nnod-1, j = 0 to Ncol
|
|
# nevalues = # of node values
|
|
# evalues[i][j] = 2d array of floats, i = 0 to Nel-1, j = 0 to Ncol
|
|
|
|
try:
|
|
import numpy as np
|
|
oldnumeric = False
|
|
except:
|
|
import Numeric as np
|
|
oldnumeric = True
|
|
|
|
try: from DEFAULTS import PIZZA_GUNZIP
|
|
except: PIZZA_GUNZIP = "gunzip"
|
|
|
|
# Class definition
|
|
|
|
class mdump:
|
|
|
|
# --------------------------------------------------------------------
|
|
|
|
def __init__(self,*list):
|
|
self.snaps = []
|
|
self.nsnaps = self.nselect = 0
|
|
self.names = {}
|
|
self.tselect = tselect(self)
|
|
self.eselect = eselect(self)
|
|
self.etype = ""
|
|
|
|
# flist = list of all dump file names
|
|
|
|
words = list[0].split()
|
|
self.flist = []
|
|
for word in words: self.flist += glob.glob(word)
|
|
if len(self.flist) == 0 and len(list) == 1:
|
|
raise Exception("no dump file specified")
|
|
|
|
if len(list) == 1:
|
|
self.increment = 0
|
|
self.read_all()
|
|
else:
|
|
self.increment = 1
|
|
self.nextfile = 0
|
|
self.eof = 0
|
|
|
|
# --------------------------------------------------------------------
|
|
|
|
def read_all(self):
|
|
|
|
# read all snapshots from each file
|
|
# test for gzipped files
|
|
|
|
for file in self.flist:
|
|
if file[-3:] == ".gz":
|
|
f = popen("%s -c %s" % (PIZZA_GUNZIP,file),'r')
|
|
else: f = open(file)
|
|
|
|
snap = self.read_snapshot(f)
|
|
while snap:
|
|
self.snaps.append(snap)
|
|
print(snap.time, end=' ')
|
|
sys.stdout.flush()
|
|
snap = self.read_snapshot(f)
|
|
|
|
f.close()
|
|
print()
|
|
|
|
# sort entries by timestep, cull and combine duplicates
|
|
|
|
self.snaps.sort(key = functools.cmp_to_key(self.compare_time))
|
|
self.cull()
|
|
|
|
# sort all node, element, nvalue, evalue arrays by ID
|
|
|
|
for snap in self.snaps:
|
|
if snap.nflag:
|
|
array = snap.nodes
|
|
ids = array[:,0]
|
|
ordering = np.argsort(ids)
|
|
for i in range(len(array[0])):
|
|
array[:,i] = np.take(array[:,i],ordering)
|
|
if snap.eflag:
|
|
array = snap.elements
|
|
ids = array[:,0]
|
|
ordering = np.argsort(ids)
|
|
for i in range(len(array[0])):
|
|
array[:,i] = np.take(array[:,i],ordering)
|
|
if snap.nvalueflag:
|
|
array = snap.nvalues
|
|
ids = array[:,0]
|
|
ordering = np.argsort(ids)
|
|
for i in range(len(array[0])):
|
|
array[:,i] = np.take(array[:,i],ordering)
|
|
if snap.evalueflag:
|
|
array = snap.evalues
|
|
ids = array[:,0]
|
|
ordering = np.argsort(ids)
|
|
for i in range(len(array[0])):
|
|
array[:,i] = np.take(array[:,i],ordering)
|
|
|
|
# reference definitions of nodes and elements in previous timesteps
|
|
|
|
self.reference()
|
|
|
|
self.nsnaps = len(self.snaps)
|
|
print("read %d snapshots" % self.nsnaps)
|
|
|
|
# select all timesteps and elements
|
|
|
|
self.tselect.all()
|
|
|
|
# --------------------------------------------------------------------
|
|
# read next snapshot from list of files
|
|
|
|
def next(self):
|
|
|
|
if not self.increment: raise Exception("cannot read incrementally")
|
|
|
|
# read next snapshot in current file using eof as pointer
|
|
# if fail, try next file
|
|
# if new snapshot time stamp already exists, read next snapshot
|
|
|
|
while 1:
|
|
f = open(self.flist[self.nextfile],'rb')
|
|
f.seek(self.eof)
|
|
snap = self.read_snapshot(f)
|
|
if not snap:
|
|
self.nextfile += 1
|
|
if self.nextfile == len(self.flist): return -1
|
|
f.close()
|
|
self.eof = 0
|
|
continue
|
|
self.eof = f.tell()
|
|
f.close()
|
|
try:
|
|
self.findtime(snap.time)
|
|
continue
|
|
except: break
|
|
|
|
# select the new snapshot with all its elements
|
|
|
|
self.snaps.append(snap)
|
|
snap = self.snaps[self.nsnaps]
|
|
snap.tselect = 1
|
|
snap.nselect = snap.nelements
|
|
if snap.eflag:
|
|
for i in range(snap.nelements): snap.eselect[i] = 1
|
|
self.nsnaps += 1
|
|
self.nselect += 1
|
|
|
|
return snap.time
|
|
|
|
# --------------------------------------------------------------------
|
|
# read a single snapshot from file f
|
|
# return snapshot or 0 if failed
|
|
|
|
def read_snapshot(self,f):
|
|
try:
|
|
snap = Snap()
|
|
item = f.readline()
|
|
snap.time = int(f.readline())
|
|
snap.nflag = snap.eflag = snap.nvalueflag = snap.evalueflag = 0
|
|
str = f.readline()
|
|
if "NUMBER OF NODES" in str: snap.nflag = 1
|
|
elif "NUMBER OF TRIANGLES" in str: snap.eflag = 1
|
|
elif "NUMBER OF TETS" in str: snap.eflag = 2
|
|
elif "NUMBER OF SQUARES" in str: snap.eflag = 3
|
|
elif "NUMBER OF CUBES" in str: snap.eflag = 4
|
|
elif "NUMBER OF NODE VALUES" in str: snap.nvalueflag = 1
|
|
elif "NUMBER OF ELEMENT VALUES" in str: snap.evalueflag = 1
|
|
else: raise Exception("unrecognized snapshot in dump file")
|
|
n = int(f.readline())
|
|
|
|
if snap.eflag: snap.eselect = np.zeros(n)
|
|
|
|
if snap.nflag:
|
|
item = f.readline()
|
|
words = f.readline().split()
|
|
snap.xlo,snap.xhi = float(words[0]),float(words[1])
|
|
words = f.readline().split()
|
|
snap.ylo,snap.yhi = float(words[0]),float(words[1])
|
|
words = f.readline().split()
|
|
snap.zlo,snap.zhi = float(words[0]),float(words[1])
|
|
|
|
item = f.readline()
|
|
if n:
|
|
words = f.readline().split()
|
|
ncol = len(words)
|
|
for i in range(1,n):
|
|
words += f.readline().split()
|
|
floats = list(map(float,words))
|
|
if oldnumeric: values = np.zeros((n,ncol),np.Float)
|
|
else: values = np.zeros((n,ncol),np.float)
|
|
start = 0
|
|
stop = ncol
|
|
for i in range(n):
|
|
values[i] = floats[start:stop]
|
|
start = stop
|
|
stop += ncol
|
|
else: values = None
|
|
|
|
if snap.nflag:
|
|
snap.nodes = values; snap.nnodes = n
|
|
elif snap.eflag:
|
|
snap.elements = values; snap.nelements = n
|
|
elif snap.nvalueflag:
|
|
snap.nvalues = values; snap.nnvalues = n
|
|
elif snap.evalueflag:
|
|
snap.evalues = values; snap.nevalues = n
|
|
return snap
|
|
except:
|
|
return 0
|
|
|
|
# --------------------------------------------------------------------
|
|
# map atom column names
|
|
|
|
def map(self,*pairs):
|
|
if len(pairs) % 2 != 0:
|
|
raise Exception("mdump map() requires pairs of mappings")
|
|
for i in range(0,len(pairs),2):
|
|
j = i + 1
|
|
self.names[pairs[j]] = pairs[i]-1
|
|
|
|
# delete unselected snapshots
|
|
|
|
# --------------------------------------------------------------------
|
|
|
|
def delete(self):
|
|
ndel = i = 0
|
|
while i < self.nsnaps:
|
|
if not self.snaps[i].tselect:
|
|
del self.snaps[i]
|
|
self.nsnaps -= 1
|
|
ndel += 1
|
|
else: i += 1
|
|
print("%d snapshots deleted" % ndel)
|
|
print("%d snapshots remaining" % self.nsnaps)
|
|
|
|
# --------------------------------------------------------------------
|
|
# sort elements by ID in all selected timesteps or one timestep
|
|
|
|
def sort(self,*list):
|
|
if len(list) == 0:
|
|
print("Sorting selected snapshots ...")
|
|
id = self.names["id"]
|
|
for snap in self.snaps:
|
|
if snap.tselect: self.sort_one(snap,id)
|
|
else:
|
|
i = self.findtime(list[0])
|
|
id = self.names["id"]
|
|
self.sort_one(self.snaps[i],id)
|
|
|
|
|
|
# --------------------------------------------------------------------
|
|
# sort a single snapshot by ID column
|
|
|
|
def sort_one(self,snap,id):
|
|
atoms = snap.atoms
|
|
ids = atoms[:,id]
|
|
ordering = np.argsort(ids)
|
|
for i in range(len(atoms[0])):
|
|
atoms[:,i] = np.take(atoms[:,i],ordering)
|
|
|
|
# --------------------------------------------------------------------
|
|
# return vector of selected snapshot time stamps
|
|
|
|
def time(self):
|
|
vec = self.nselect * [0]
|
|
i = 0
|
|
for snap in self.snaps:
|
|
if not snap.tselect: continue
|
|
vec[i] = snap.time
|
|
i += 1
|
|
return vec
|
|
|
|
# --------------------------------------------------------------------
|
|
# extract vector(s) of values for selected elements at chosen timestep
|
|
|
|
def vecs(self,n,*list):
|
|
snap = self.snaps[self.findtime(n)]
|
|
if not snap.evalues:
|
|
raise Exception("snapshot has no element values")
|
|
|
|
if len(list) == 0:
|
|
raise Exception("no columns specified")
|
|
columns = []
|
|
values = []
|
|
for name in list:
|
|
columns.append(self.names[name])
|
|
values.append(snap.nselect * [0])
|
|
ncol = len(columns)
|
|
|
|
m = 0
|
|
for i in range(len(snap.evalues)):
|
|
if not snap.eselect[i]: continue
|
|
for j in range(ncol):
|
|
values[j][m] = snap.evalues[i][columns[j]]
|
|
m += 1
|
|
|
|
if len(list) == 1: return values[0]
|
|
else: return values
|
|
|
|
# --------------------------------------------------------------------
|
|
# sort snapshots on time stamp
|
|
|
|
def compare_time(self,a,b):
|
|
if a.time < b.time:
|
|
return -1
|
|
elif a.time > b.time:
|
|
return 1
|
|
else:
|
|
return 0
|
|
|
|
# --------------------------------------------------------------------
|
|
# delete successive snapshots with duplicate time stamp
|
|
# if have same timestamp, combine them if internal flags are different
|
|
|
|
def cull(self):
|
|
i = 1
|
|
while i < len(self.snaps):
|
|
if self.snaps[i].time == self.snaps[i-1].time:
|
|
if self.snaps[i].nflag:
|
|
if not self.snaps[i-1].nflag:
|
|
self.snaps[i-1].nflag = 1
|
|
self.snaps[i-1].nnodes = self.snaps[i].nnodes
|
|
self.snaps[i-1].nodes = self.snaps[i].nodes
|
|
self.snaps[i-1].xlo = self.snaps[i].xlo
|
|
self.snaps[i-1].xhi = self.snaps[i].xhi
|
|
self.snaps[i-1].ylo = self.snaps[i].ylo
|
|
self.snaps[i-1].yhi = self.snaps[i].yhi
|
|
self.snaps[i-1].zlo = self.snaps[i].zlo
|
|
self.snaps[i-1].zhi = self.snaps[i].zhi
|
|
elif self.snaps[i].eflag:
|
|
if not self.snaps[i-1].eflag:
|
|
self.snaps[i-1].eflag = self.snaps[i].eflag
|
|
self.snaps[i-1].nelements = self.snaps[i].nelements
|
|
self.snaps[i-1].elements = self.snaps[i].elements
|
|
self.snaps[i-1].eselect = self.snaps[i].eselect
|
|
elif self.snaps[i].nvalueflag:
|
|
if not self.snaps[i-1].nvalueflag:
|
|
self.snaps[i-1].nvalueflag = 1
|
|
self.snaps[i-1].nnvalues = self.snaps[i].nnvalues
|
|
self.snaps[i-1].nvalues = self.snaps[i].nvalues
|
|
elif self.snaps[i].evalueflag:
|
|
if not self.snaps[i-1].evalueflag:
|
|
self.snaps[i-1].evalueflag = 1
|
|
self.snaps[i-1].nevalues = self.snaps[i].nevalues
|
|
self.snaps[i-1].evalues = self.snaps[i].evalues
|
|
del self.snaps[i]
|
|
else:
|
|
i += 1
|
|
|
|
# --------------------------------------------------------------------
|
|
# insure every snapshot has node and element connectivity info
|
|
# if not, point it at most recent shapshot that does
|
|
|
|
def reference(self):
|
|
for i in range(len(self.snaps)):
|
|
if not self.snaps[i].nflag:
|
|
for j in range(i,-1,-1):
|
|
if self.snaps[j].nflag:
|
|
self.snaps[i].nflag = self.snaps[j].nflag
|
|
self.snaps[i].nnodes = self.snaps[j].nnodes
|
|
self.snaps[i].nodes = self.snaps[j].nodes
|
|
self.snaps[i].xlo = self.snaps[j].xlo
|
|
self.snaps[i].xhi = self.snaps[j].xhi
|
|
self.snaps[i].ylo = self.snaps[j].ylo
|
|
self.snaps[i].yhi = self.snaps[j].yhi
|
|
self.snaps[i].zlo = self.snaps[j].zlo
|
|
self.snaps[i].zhi = self.snaps[j].zhi
|
|
break
|
|
if not self.snaps[i].nflag:
|
|
raise Exception("no nodal coords found in previous snapshots")
|
|
if not self.snaps[i].eflag:
|
|
for j in range(i,-1,-1):
|
|
if self.snaps[j].eflag:
|
|
self.snaps[i].eflag = self.snaps[j].eflag
|
|
self.snaps[i].nelements = self.snaps[j].nelements
|
|
self.snaps[i].elements = self.snaps[j].elements
|
|
self.snaps[i].eselect = self.snaps[j].eselect
|
|
break
|
|
if not self.snaps[i].eflag:
|
|
raise Exception("no elem connections found in previous snapshots")
|
|
|
|
# --------------------------------------------------------------------
|
|
# iterate over selected snapshots
|
|
|
|
def iterator(self,flag):
|
|
start = 0
|
|
if flag: start = self.iterate + 1
|
|
for i in range(start,self.nsnaps):
|
|
if self.snaps[i].tselect:
|
|
self.iterate = i
|
|
return i,self.snaps[i].time,1
|
|
return 0,0,-1
|
|
|
|
# --------------------------------------------------------------------
|
|
# return list of triangles to viz for snapshot isnap
|
|
# if called with flag, then index is timestep, so convert to snapshot index
|
|
|
|
def viz(self,index,flag=0):
|
|
if not flag: isnap = index
|
|
else:
|
|
times = self.time()
|
|
n = len(times)
|
|
i = 0
|
|
while i < n:
|
|
if times[i] > index: break
|
|
i += 1
|
|
isnap = i - 1
|
|
snap = self.snaps[isnap]
|
|
|
|
time = snap.time
|
|
box = [snap.xlo,snap.ylo,snap.zlo,snap.xhi,snap.yhi,snap.zhi]
|
|
if self.etype == "": type = -1
|
|
else: type = self.names[self.etype]
|
|
|
|
atoms = []
|
|
bonds = []
|
|
|
|
# create triangle list from all elements
|
|
# for type, either use element type (-1) or user-defined column in evalues
|
|
|
|
tris = []
|
|
nodes = snap.nodes
|
|
for i in range(snap.nelements):
|
|
if not snap.eselect[i]: continue
|
|
element = snap.elements[i]
|
|
if snap.evalueflag: evalue = snap.evalues[i]
|
|
else: evalues = []
|
|
|
|
# single tri, normal = up
|
|
|
|
if snap.eflag == 1:
|
|
v1 = nodes[int(element[2])-1][2:5].tolist()
|
|
v2 = nodes[int(element[3])-1][2:5].tolist()
|
|
v3 = nodes[int(element[4])-1][2:5].tolist()
|
|
list = v1 + v2 + v3
|
|
n = normal(list[0:3],list[3:6],list[6:9])
|
|
if type == -1: tris.append([element[0],element[1]] + list + n)
|
|
else: tris.append([element[0],evalue[type]] + list + n)
|
|
|
|
# single tet, convert to 4 tris, normals = out
|
|
|
|
elif snap.eflag == 2:
|
|
v1 = nodes[int(element[2])-1][2:5].tolist()
|
|
v2 = nodes[int(element[3])-1][2:5].tolist()
|
|
v3 = nodes[int(element[4])-1][2:5].tolist()
|
|
v4 = nodes[int(element[5])-1][2:5].tolist()
|
|
list = v1 + v2 + v4
|
|
n = normal(list[0:3],list[3:6],list[6:9])
|
|
if type == -1: tris.append([element[0],element[1]] + list + n)
|
|
else: tris.append([element[0],evalue[type]] + list + n)
|
|
list = v2 + v3 + v4
|
|
n = normal(list[0:3],list[3:6],list[6:9])
|
|
if type == -1: tris.append([element[0],element[1]] + list + n)
|
|
else: tris.append([element[0],evalue[type]] + list + n)
|
|
list = v1 + v4 + v3
|
|
n = normal(list[0:3],list[3:6],list[6:9])
|
|
if type == -1: tris.append([element[0],element[1]] + list + n)
|
|
else: tris.append([element[0],evalue[type]] + list + n)
|
|
list = v1 + v3 + v2
|
|
n = normal(list[0:3],list[3:6],list[6:9])
|
|
if type == -1: tris.append([element[0],element[1]] + list + n)
|
|
else: tris.append([element[0],evalue[type]] + list + n)
|
|
|
|
# single square, convert to 2 tris, normals = up
|
|
|
|
elif snap.eflag == 3:
|
|
v1 = nodes[int(element[2])-1][2:5].tolist()
|
|
v2 = nodes[int(element[3])-1][2:5].tolist()
|
|
v3 = nodes[int(element[4])-1][2:5].tolist()
|
|
v4 = nodes[int(element[5])-1][2:5].tolist()
|
|
list = v1 + v2 + v3
|
|
n = normal(list[0:3],list[3:6],list[6:9])
|
|
if type == -1: tris.append([element[0],element[1]] + list + n)
|
|
else: tris.append([element[0],evalue[type]] + list + n)
|
|
list = v1 + v3 + v4
|
|
n = normal(list[0:3],list[3:6],list[6:9])
|
|
if type == -1: tris.append([element[0],element[1]] + list + n)
|
|
else: tris.append([element[0],evalue[type]] + list + n)
|
|
|
|
# single cube, convert to 12 tris, normals = out
|
|
|
|
elif snap.eflag == 4:
|
|
v1 = nodes[int(element[2])-1][2:5].tolist()
|
|
v2 = nodes[int(element[3])-1][2:5].tolist()
|
|
v3 = nodes[int(element[4])-1][2:5].tolist()
|
|
v4 = nodes[int(element[5])-1][2:5].tolist()
|
|
v5 = nodes[int(element[6])-1][2:5].tolist()
|
|
v6 = nodes[int(element[7])-1][2:5].tolist()
|
|
v7 = nodes[int(element[8])-1][2:5].tolist()
|
|
v8 = nodes[int(element[9])-1][2:5].tolist()
|
|
list = v1 + v3 + v2 # lower z face
|
|
n = normal(list[0:3],list[3:6],list[6:9])
|
|
if type == -1: tris.append([element[0],element[1]] + list + n)
|
|
else: tris.append([element[0],evalue[type]] + list + n)
|
|
list = v1 + v4 + v3
|
|
n = normal(list[0:3],list[3:6],list[6:9])
|
|
if type == -1: tris.append([element[0],element[1]] + list + n)
|
|
else: tris.append([element[0],evalue[type]] + list + n)
|
|
list = v5 + v6 + v7 # upper z face
|
|
n = normal(list[0:3],list[3:6],list[6:9])
|
|
if type == -1: tris.append([element[0],element[1]] + list + n)
|
|
else: tris.append([element[0],evalue[type]] + list + n)
|
|
list = v5 + v7 + v8
|
|
n = normal(list[0:3],list[3:6],list[6:9])
|
|
if type == -1: tris.append([element[0],element[1]] + list + n)
|
|
else: tris.append([element[0],evalue[type]] + list + n)
|
|
list = v1 + v2 + v6 # lower y face
|
|
n = normal(list[0:3],list[3:6],list[6:9])
|
|
if type == -1: tris.append([element[0],element[1]] + list + n)
|
|
else: tris.append([element[0],evalue[type]] + list + n)
|
|
list = v1 + v6 + v5
|
|
n = normal(list[0:3],list[3:6],list[6:9])
|
|
if type == -1: tris.append([element[0],element[1]] + list + n)
|
|
else: tris.append([element[0],evalue[type]] + list + n)
|
|
list = v4 + v7 + v3 # upper y face
|
|
n = normal(list[0:3],list[3:6],list[6:9])
|
|
if type == -1: tris.append([element[0],element[1]] + list + n)
|
|
else: tris.append([element[0],evalue[type]] + list + n)
|
|
list = v4 + v8 + v7
|
|
n = normal(list[0:3],list[3:6],list[6:9])
|
|
if type == -1: tris.append([element[0],element[1]] + list + n)
|
|
else: tris.append([element[0],evalue[type]] + list + n)
|
|
list = v1 + v8 + v4 # lower x face
|
|
n = normal(list[0:3],list[3:6],list[6:9])
|
|
if type == -1: tris.append([element[0],element[1]] + list + n)
|
|
else: tris.append([element[0],evalue[type]] + list + n)
|
|
list = v1 + v5 + v8
|
|
n = normal(list[0:3],list[3:6],list[6:9])
|
|
if type == -1: tris.append([element[0],element[1]] + list + n)
|
|
else: tris.append([element[0],evalue[type]] + list + n)
|
|
list = v2 + v3 + v7 # upper x face
|
|
n = normal(list[0:3],list[3:6],list[6:9])
|
|
if type == -1: tris.append([element[0],element[1]] + list + n)
|
|
else: tris.append([element[0],evalue[type]] + list + n)
|
|
list = v2 + v7 + v6
|
|
n = normal(list[0:3],list[3:6],list[6:9])
|
|
if type == -1: tris.append([element[0],element[1]] + list + n)
|
|
else: tris.append([element[0],evalue[type]] + list + n)
|
|
|
|
lines = []
|
|
|
|
return time,box,atoms,bonds,tris,lines
|
|
|
|
# --------------------------------------------------------------------
|
|
# return lists of node/element info for snapshot isnap
|
|
# if called with flag, then index is timestep, so convert to snapshot index
|
|
|
|
def mviz(self,index,flag=0):
|
|
if not flag: isnap = index
|
|
else:
|
|
times = self.time()
|
|
n = len(times)
|
|
i = 0
|
|
while i < n:
|
|
if times[i] > index: break
|
|
i += 1
|
|
isnap = i - 1
|
|
snap = self.snaps[isnap]
|
|
|
|
time = snap.time
|
|
box = [snap.xlo,snap.ylo,snap.zlo,snap.xhi,snap.yhi,snap.zhi]
|
|
nvalues = []
|
|
if snap.nvalueflag: nvalues = snap.nvalues
|
|
evalues = []
|
|
if snap.nvalueflag: evalues = snap.evalues
|
|
|
|
return time,box,snap.nodes,snap.elements,nvalues,evalues
|
|
|
|
# --------------------------------------------------------------------
|
|
|
|
def findtime(self,n):
|
|
for i in range(self.nsnaps):
|
|
if self.snaps[i].time == n: return i
|
|
raise Exception("no step %d exists" % n)
|
|
|
|
# --------------------------------------------------------------------
|
|
# return maximum box size across all selected snapshots
|
|
|
|
def maxbox(self):
|
|
xlo = ylo = zlo = None
|
|
xhi = yhi = zhi = None
|
|
for snap in self.snaps:
|
|
if not snap.tselect: continue
|
|
if xlo == None or snap.xlo < xlo: xlo = snap.xlo
|
|
if xhi == None or snap.xhi > xhi: xhi = snap.xhi
|
|
if ylo == None or snap.ylo < ylo: ylo = snap.ylo
|
|
if yhi == None or snap.yhi > yhi: yhi = snap.yhi
|
|
if zlo == None or snap.zlo < zlo: zlo = snap.zlo
|
|
if zhi == None or snap.zhi > zhi: zhi = snap.zhi
|
|
return [xlo,ylo,zlo,xhi,yhi,zhi]
|
|
|
|
# --------------------------------------------------------------------
|
|
|
|
def compare_atom(self,a,b):
|
|
if a[0] < b[0]:
|
|
return -1
|
|
elif a[0] > b[0]:
|
|
return 1
|
|
else:
|
|
return 0
|
|
|
|
# --------------------------------------------------------------------
|
|
# one snapshot
|
|
|
|
class Snap:
|
|
pass
|
|
|
|
# --------------------------------------------------------------------
|
|
# time selection class
|
|
|
|
class tselect:
|
|
|
|
def __init__(self,data):
|
|
self.data = data
|
|
|
|
# --------------------------------------------------------------------
|
|
|
|
def all(self):
|
|
data = self.data
|
|
for snap in data.snaps:
|
|
snap.tselect = 1
|
|
data.nselect = len(data.snaps)
|
|
data.eselect.all()
|
|
print("%d snapshots selected out of %d" % (data.nselect,data.nsnaps))
|
|
|
|
# --------------------------------------------------------------------
|
|
|
|
def one(self,n):
|
|
data = self.data
|
|
for snap in data.snaps:
|
|
snap.tselect = 0
|
|
i = data.findtime(n)
|
|
data.snaps[i].tselect = 1
|
|
data.nselect = 1
|
|
data.eselect.all()
|
|
print("%d snapshots selected out of %d" % (data.nselect,data.nsnaps))
|
|
|
|
# --------------------------------------------------------------------
|
|
|
|
def none(self):
|
|
data = self.data
|
|
for snap in data.snaps:
|
|
snap.tselect = 0
|
|
data.nselect = 0
|
|
print("%d snapshots selected out of %d" % (data.nselect,data.nsnaps))
|
|
|
|
# --------------------------------------------------------------------
|
|
|
|
def skip(self,n):
|
|
data = self.data
|
|
count = n-1
|
|
for snap in data.snaps:
|
|
if not snap.tselect: continue
|
|
count += 1
|
|
if count == n:
|
|
count = 0
|
|
continue
|
|
snap.tselect = 0
|
|
data.nselect -= 1
|
|
data.eselect.all()
|
|
print("%d snapshots selected out of %d" % (data.nselect,data.nsnaps))
|
|
|
|
# --------------------------------------------------------------------
|
|
|
|
def test(self,teststr):
|
|
data = self.data
|
|
snaps = data.snaps
|
|
cmd = "flag = " + teststr.replace("$t","snaps[i].time")
|
|
ccmd = compile(cmd,'','single')
|
|
for i in range(data.nsnaps):
|
|
if not snaps[i].tselect: continue
|
|
ldict = {'data':data,'snaps':snaps,'i':i}
|
|
exec(ccmd,globals(),ldict)
|
|
flag = ldict['flag']
|
|
if not flag:
|
|
snaps[i].tselect = 0
|
|
data.nselect -= 1
|
|
data.eselect.all()
|
|
print("%d snapshots selected out of %d" % (data.nselect,data.nsnaps))
|
|
|
|
# --------------------------------------------------------------------
|
|
# element selection class
|
|
|
|
class eselect:
|
|
|
|
def __init__(self,data):
|
|
self.data = data
|
|
|
|
# --------------------------------------------------------------------
|
|
|
|
def all(self,*args):
|
|
data = self.data
|
|
if len(args) == 0: # all selected timesteps
|
|
for snap in data.snaps:
|
|
if not snap.tselect: continue
|
|
for i in range(snap.nelements): snap.eselect[i] = 1
|
|
snap.nselect = snap.nelements
|
|
else: # one timestep
|
|
n = data.findtime(args[0])
|
|
snap = data.snaps[n]
|
|
for i in range(snap.nelements): snap.eselect[i] = 1
|
|
snap.nselect = snap.nelements
|
|
|
|
# --------------------------------------------------------------------
|
|
|
|
def test(self,teststr,*args):
|
|
data = self.data
|
|
|
|
# replace all $var with snap.atoms references and compile test string
|
|
|
|
pattern = "\$\w*"
|
|
list = re.findall(pattern,teststr)
|
|
for item in list:
|
|
name = item[1:]
|
|
column = data.names[name]
|
|
insert = "snap.atoms[i][%d]" % column
|
|
teststr = teststr.replace(item,insert)
|
|
cmd = "flag = " + teststr
|
|
ccmd = compile(cmd,'','single')
|
|
|
|
if len(args) == 0: # all selected timesteps
|
|
for snap in data.snaps:
|
|
if not snap.tselect: continue
|
|
for i in range(snap.nelements):
|
|
if not snap.eselect[i]: continue
|
|
exec(ccmd)
|
|
if not flag:
|
|
snap.eselect[i] = 0
|
|
snap.nselect -= 1
|
|
for i in range(data.nsnaps):
|
|
if data.snaps[i].tselect:
|
|
print("%d atoms of %d selected in first step %d" % \
|
|
(data.snaps[i].nselect,data.snaps[i].nelements,data.snaps[i].time))
|
|
break
|
|
for i in range(data.nsnaps-1,-1,-1):
|
|
if data.snaps[i].tselect:
|
|
print("%d atoms of %d selected in last step %d" % \
|
|
(data.snaps[i].nselect,data.snaps[i].nelements,data.snaps[i].time))
|
|
break
|
|
|
|
else: # one timestep
|
|
n = data.findtime(args[0])
|
|
snap = data.snaps[n]
|
|
for i in range(snap.nelements):
|
|
if not snap.eselect[i]: continue
|
|
exec(ccmd)
|
|
if not flag:
|
|
snap.eselect[i] = 0
|
|
snap.nselect -= 1
|
|
|
|
# --------------------------------------------------------------------
|
|
# compute normal for a triangle with 3 vertices
|
|
|
|
def normal(x,y,z):
|
|
v1 = 3*[0]
|
|
v1[0] = y[0] - x[0]
|
|
v1[1] = y[1] - x[1]
|
|
v1[2] = y[2] - x[2]
|
|
|
|
v2 = 3*[0]
|
|
v2[0] = z[0] - y[0]
|
|
v2[1] = z[1] - y[1]
|
|
v2[2] = z[2] - y[2]
|
|
|
|
n = 3*[0]
|
|
n[0] = v1[1]*v2[2] - v1[2]*v2[1]
|
|
n[1] = v1[2]*v2[0] - v1[0]*v2[2]
|
|
n[2] = v1[0]*v2[1] - v1[1]*v2[0]
|
|
|
|
length = sqrt(n[0]*n[0] + n[1]*n[1] + n[2]*n[2])
|
|
n[0] /= length
|
|
n[1] /= length
|
|
n[2] /= length
|
|
|
|
return n
|