mirror of
https://github.com/ParticulateFlow/LPP.git
synced 2025-12-08 06:37:46 +00:00
233 lines
7.4 KiB
Python
Executable File
233 lines
7.4 KiB
Python
Executable File
#!/usr/bin/env python
|
|
|
|
oneline = "writing pp-data in vtk format automatically, saving memory"
|
|
|
|
docstr = """this is the docstr of LIGGGHTSPostProcessing"""
|
|
|
|
from dump import dump
|
|
from math import floor
|
|
from math import ceil
|
|
import vtk
|
|
import glob
|
|
import multiprocessing
|
|
import sys
|
|
import time
|
|
import os
|
|
import exceptions
|
|
# changes py p.s. - include a few command line options
|
|
import getopt
|
|
|
|
class lpp:
|
|
|
|
#=============================================================================
|
|
# creates a filelist, seperates it to sublists
|
|
# creates multiple processes
|
|
# calls lppWorker for each sublist
|
|
# lppWorker
|
|
# calls dump, vtk and manyGran for the given list of files
|
|
# returns 0
|
|
#=============================================================================
|
|
|
|
def __init__(self, *list, **kwargs):
|
|
# do argument parsing, raise errors if non-integers were given
|
|
# this can be changed if one wants less overhead but use more memory:
|
|
# make this figure higher but if possible a multiple of 8
|
|
self.cpunum = multiprocessing.cpu_count()
|
|
self.chunksize = 8
|
|
self.overwrite = True
|
|
|
|
if "--chunksize" in kwargs:
|
|
try:
|
|
if int(kwargs["--chunksize"]) > 0:
|
|
self.chunksize = int(kwargs["--chunksize"])
|
|
else: raise ValueError
|
|
except ValueError:
|
|
raise ValueError, "Invalid or no argument given for chunksize"
|
|
|
|
if "--cpunum" in kwargs:
|
|
try:
|
|
if int(kwargs["--cpunum"]) > 0 and int(kwargs["--cpunum"]) <= self.cpunum:
|
|
self.cpunum = int(kwargs["--cpunum"])
|
|
else: raise ValueError
|
|
except ValueError:
|
|
raise ValueError, "Invalid or no argument given for cpunum"
|
|
|
|
# do not overwrite existing files
|
|
if "--no-overwrite" in kwargs:
|
|
self.overwrite = False
|
|
|
|
# suppress output with 'False'
|
|
if "--debug" in kwargs: self.debugMode = True
|
|
else: self.debugMode = False
|
|
|
|
if "--quiet" in kwargs:
|
|
self.output = False
|
|
self.debugMode = False
|
|
else: self.output = True
|
|
|
|
if self.output:
|
|
print "starting LIGGGHTS memory optimized parallel post processing"
|
|
print "chunksize:", self.chunksize, "-->",self.chunksize,\
|
|
"files are processed per chunk. If you run out of memory reduce chunksize."
|
|
starttime = time.time()
|
|
|
|
if self.debugMode: print "number of process:", os.getpid()
|
|
|
|
# check whether file-list is nonempty
|
|
self.flist = []
|
|
# get file list for windows
|
|
if os.name == 'nt':
|
|
for item in list[0]:
|
|
if '*' in item: # interpret wildcard with glob()
|
|
self.flist = self.flist + glob.glob(list[0][0])
|
|
else:
|
|
self.flist = self.flist + [item]
|
|
else: # unix: the input should be a valid list
|
|
self.flist = list[0]
|
|
listlen = len(self.flist)
|
|
if listlen == 0 and len(list) == 1:
|
|
raise StandardError, "no dump file specified"
|
|
if listlen == 1 and self.overwrite == False:
|
|
raise StandardError, "Cannot process single dump files with --no-overwrite."
|
|
|
|
if self.output:
|
|
print "Working with", self.cpunum, "processes..."
|
|
|
|
# seperate list in pieces+rest
|
|
self.slices = []
|
|
|
|
residualPresent = int(bool(listlen-floor(listlen/self.chunksize)*self.chunksize))
|
|
|
|
for i in xrange(int(floor(listlen/self.chunksize))+residualPresent):
|
|
slice = self.flist[i*self.chunksize:(i+1)*self.chunksize]
|
|
self.slices.append(slice)
|
|
self.flist = []
|
|
|
|
output = ""
|
|
if "-o" in kwargs: output = kwargs["-o"]
|
|
# generate input for lppWorker
|
|
dumpInput = [{"filelist":self.slices[i],\
|
|
"debugMode":self.debugMode,\
|
|
"output":output,\
|
|
"overwrite":self.overwrite} \
|
|
for i in xrange(len(self.slices))]
|
|
|
|
if self.debugMode: print "dumpInput:",dumpInput
|
|
|
|
numberOfRuns = len(dumpInput)
|
|
i = 0
|
|
while i < len(dumpInput):
|
|
|
|
if self.output:
|
|
print "calculating chunks",i+1,"-",min(i+self.cpunum,numberOfRuns),"of",numberOfRuns
|
|
|
|
if self.debugMode: print "input of this \"map\": ",dumpInput[i:i+self.cpunum]
|
|
|
|
# create job_server
|
|
job_server = multiprocessing.Pool(processes = self.cpunum)
|
|
|
|
# map lppWorker on all inputs via job_server (parallelly)
|
|
job_server.map_async(lppWorker,dumpInput[i:i+self.cpunum]).get(9999999)
|
|
|
|
# close jobserver
|
|
job_server.close()
|
|
job_server.join()
|
|
i += self.cpunum
|
|
|
|
endtime = time.time()
|
|
if self.output:
|
|
print "wrote", listlen,"granular snapshots in VTK format"
|
|
print "time needed:",endtime-starttime,"sec"
|
|
|
|
def lppWorker(input):
|
|
flist = input["filelist"]
|
|
debugMode = input["debugMode"]
|
|
outfileName = input["output"]
|
|
overwrite = input["overwrite"]
|
|
|
|
flistlen = len(flist)
|
|
# generate name of manyGran
|
|
splitfname = flist[0].rsplit(".")
|
|
if outfileName == "":
|
|
granName = splitfname[len(splitfname)-1]
|
|
elif outfileName.endswith("/"):
|
|
granName = outfileName + splitfname[len(splitfname)-1]
|
|
else:
|
|
granName = outfileName
|
|
|
|
# if no-overwrite: read timestamp in first line of file
|
|
# if corresponding dump-file does not already exists: add it to 'shortFlist'
|
|
# shortFlist ... list of files to finally be processed by dump, and vtk.
|
|
# elements of flist that are not in shortFlist already exist and will not be
|
|
# converted anew and replaced
|
|
shortFlist = []
|
|
if overwrite == True:
|
|
shortFlist = flist
|
|
else:
|
|
for f in flist:
|
|
try:
|
|
# read time
|
|
ff = open(f)
|
|
ff.readline()
|
|
time = int(ff.readline())
|
|
sys.stdout.flush()
|
|
ff.close()
|
|
except:
|
|
continue
|
|
|
|
# generate filename from time like in vtk,
|
|
# check if file exists; if yes: do not add to list
|
|
filename,file_bb,file_walls = vtk.generateFilename(granName,[time],0)
|
|
if not os.path.isfile(filename):
|
|
shortFlist.append(f)
|
|
|
|
# call dump, vtk, manyGran on shortFlist
|
|
try:
|
|
d = dump({"filelist":shortFlist, "debugMode":debugMode})
|
|
v = vtk.vtk(d)
|
|
if debugMode: print "\nfileNums: ",d.fileNums,"\n"
|
|
v.manyGran(granName,fileNos=d.fileNums,output=debugMode)
|
|
except KeyboardInterrupt:
|
|
raise
|
|
|
|
return 0
|
|
|
|
def printHelp():
|
|
print "usage: pizza [options] dump.example\n where dump.example is a filename",\
|
|
"or regular expression passing all relevant dump files to pizza."
|
|
print "Important command line options:"
|
|
print "-o fname : define output file name (default is liggghts + timestep number)"
|
|
print "--chunksize : sets the chunksize, default: 8"
|
|
print "--cpunum : sets the number of processes to start, default (and maximum)",\
|
|
"is the amout of cpu cores avaliable at your system"
|
|
print "--help : writes this help message and exits"
|
|
print "--no-overwrite: disables overwriting of already post-processed files."
|
|
print "For details, read README_GRANULAR.txt"
|
|
|
|
if __name__ == "__main__":
|
|
if len(sys.argv) > 1:
|
|
# parse options
|
|
optlist, args = getopt.gnu_getopt(sys.argv[1:],'o:',['chunksize=','cpunum=','debug','help','quiet','no-overwrite'])
|
|
optdict = dict(optlist)
|
|
if "--help" in optdict:
|
|
printHelp()
|
|
else:
|
|
try:
|
|
lpp(args,**optdict)
|
|
except KeyboardInterrupt:
|
|
print "aborted by user"
|
|
except BaseException, e:
|
|
print "aborting due to errors:", e
|
|
|
|
#===========================================================================
|
|
# except:
|
|
# if sys.exc_type == exceptions.SystemExit:
|
|
# pass
|
|
# else:
|
|
# print sys.exc_info()
|
|
#===========================================================================
|
|
else:
|
|
printHelp()
|
|
|
|
|