Files
LPP/src/mdump.py
danielque 597e606bde python 3 compatibility for src/*.py files
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
2023-08-10 13:19:02 +02:00

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