mirror of
https://github.com/ParticulateFlow/LPP.git
synced 2025-12-08 06:37:46 +00:00
284 lines
7.7 KiB
Python
284 lines
7.7 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.
|
|
|
|
# bdump tool
|
|
|
|
oneline = "Read dump files with bond info"
|
|
|
|
docstr = """
|
|
b = bdump("dump.one") read in one or more dump files
|
|
b = bdump("dump.1 dump.2.gz") can be gzipped
|
|
b = bdump("dump.*") wildcard expands to multiple files
|
|
b = bdump("dump.*",0) two args = store filenames, but don't read
|
|
|
|
incomplete and duplicate snapshots are deleted
|
|
no column name assignment is performed
|
|
|
|
time = b.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 is performed
|
|
|
|
b.map(1,"id",3,"x") assign names to atom columns (1-N)
|
|
|
|
must assign id,type,atom1,atom2
|
|
|
|
time,box,atoms,bonds,tris,lines = b.viz(index) return list of viz objects
|
|
|
|
viz() returns line info for specified timestep index
|
|
can also call as viz(time,1) and will find index of preceding snapshot
|
|
time = timestep value
|
|
box = NULL
|
|
atoms = NULL
|
|
bonds = id,type,atom1,atom2 for each line as 2d array
|
|
tris = NULL
|
|
lines = NULL
|
|
"""
|
|
|
|
# History
|
|
# 11/10, Steve Plimpton (SNL): original version
|
|
|
|
# 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
|
|
# snaps = list of snapshots
|
|
# names = dictionary of column names:
|
|
# key = "id", value = column # (0 to M-1)
|
|
# Snap = one snapshot
|
|
# time = time stamp
|
|
# natoms = # of atoms
|
|
# atoms[i][j] = 2d array of floats, i = 0 to natoms-1, j = 0 to ncols-1
|
|
|
|
# Imports and external programs
|
|
|
|
import sys, commands, re, glob, types
|
|
from os import popen
|
|
|
|
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 bdump:
|
|
|
|
# --------------------------------------------------------------------
|
|
|
|
def __init__(self,*list):
|
|
self.snaps = []
|
|
self.nsnaps = 0
|
|
self.names = {}
|
|
|
|
# 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 StandardError,"no bdump 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,
|
|
sys.stdout.flush()
|
|
snap = self.read_snapshot(f)
|
|
|
|
f.close()
|
|
print
|
|
|
|
# sort entries by timestep, cull duplicates
|
|
|
|
self.snaps.sort(self.compare_time)
|
|
self.cull()
|
|
self.nsnaps = len(self.snaps)
|
|
print "read %d snapshots" % self.nsnaps
|
|
|
|
# --------------------------------------------------------------------
|
|
# read next snapshot from list of files
|
|
|
|
def next(self):
|
|
|
|
if not self.increment: raise StandardError,"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
|
|
|
|
self.snaps.append(snap)
|
|
snap = self.snaps[self.nsnaps]
|
|
self.nsnaps += 1
|
|
|
|
return snap.time
|
|
|
|
# --------------------------------------------------------------------
|
|
# read a single snapshot from file f
|
|
# return snapshot or 0 if failed
|
|
# assign column names if not already done and file is self-describing
|
|
# convert xs,xu to x
|
|
|
|
def read_snapshot(self,f):
|
|
try:
|
|
snap = Snap()
|
|
item = f.readline()
|
|
snap.time = int(f.readline().split()[0]) # just grab 1st field
|
|
item = f.readline()
|
|
snap.natoms = int(f.readline())
|
|
item = f.readline()
|
|
|
|
if snap.natoms:
|
|
words = f.readline().split()
|
|
ncol = len(words)
|
|
for i in xrange(1,snap.natoms):
|
|
words += f.readline().split()
|
|
floats = map(float,words)
|
|
if oldnumeric: atoms = np.zeros((snap.natoms,ncol),np.Float)
|
|
else: atoms = np.zeros((snap.natoms,ncol),np.float)
|
|
start = 0
|
|
stop = ncol
|
|
for i in xrange(snap.natoms):
|
|
atoms[i] = floats[start:stop]
|
|
start = stop
|
|
stop += ncol
|
|
else: atoms = None
|
|
snap.atoms = atoms
|
|
return snap
|
|
except:
|
|
return 0
|
|
|
|
# --------------------------------------------------------------------
|
|
# map atom column names
|
|
|
|
def map(self,*pairs):
|
|
if len(pairs) % 2 != 0:
|
|
raise StandardError, "bdump map() requires pairs of mappings"
|
|
for i in range(0,len(pairs),2):
|
|
j = i + 1
|
|
self.names[pairs[j]] = pairs[i]-1
|
|
|
|
# --------------------------------------------------------------------
|
|
# return vector of snapshot time stamps
|
|
|
|
def time(self):
|
|
vec = self.nsnaps * [0]
|
|
i = 0
|
|
for snap in self.snaps:
|
|
vec[i] = snap.time
|
|
i += 1
|
|
return vec
|
|
|
|
# --------------------------------------------------------------------
|
|
# 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
|
|
|
|
def cull(self):
|
|
i = 1
|
|
while i < len(self.snaps):
|
|
if self.snaps[i].time == self.snaps[i-1].time:
|
|
del self.snaps[i]
|
|
else:
|
|
i += 1
|
|
|
|
# --------------------------------------------------------------------
|
|
# return list of bonds 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
|
|
id = self.names["id"]
|
|
type = self.names["type"]
|
|
atom1 = self.names["atom1"]
|
|
atom2 = self.names["atom2"]
|
|
|
|
# create line list from id,type,atom1,atom2
|
|
# abs() of type since could be negative
|
|
|
|
bonds = []
|
|
for i in xrange(snap.natoms):
|
|
atom = snap.atoms[i]
|
|
bonds.append([int(atom[id]),abs(int(atom[type])),
|
|
int(atom[atom1]),int(atom[atom2])])
|
|
|
|
return time,None,None,bonds,None,None
|
|
|
|
# --------------------------------------------------------------------
|
|
# one snapshot
|
|
|
|
class Snap:
|
|
pass
|