Source code for boutpy.boutdata.restart

"""Routines for manipulating restart files. """

__all__ = ['split', 'expand', 'create']


import os
import glob

from numpy import mean

from boutpy.boututils import DataFile


[docs]def split(nxpe, nype, path="data", output="./", informat="nc", outformat=None): """Split restart files across NXPE x NYPE processors. Returns True on success """ if outformat is None: outformat = informat mxg = 2 myg = 2 npes = nxpe * nype if npes <= 0: print "ERROR: Negative or zero number of processors" return False if path == output: print "ERROR: Can't overwrite restart files" return False file_list = glob.glob(os.path.join(path, "BOUT.restart.*." + informat)) nfiles = len(file_list) if nfiles == 0: print "ERROR: No restart files found" return False # Read old processor layout f = DataFile(os.path.join(path, file_list[0])) # Get list of variables var_list = f.list() if len(var_list) == 0: print "ERROR: No data found" return False old_npes = f.read('NPES') old_nxpe = f.read('NXPE') if nfiles != old_npes: print "WARNING: Number of restart files inconsistent with NPES" print "Setting nfiles = " + str(old_npes) nfiles = old_npes if old_npes % old_nxpe != 0: print "ERROR: Old NPES is not a multiple of old NXPE" return False old_nype = old_npes / old_nxpe if nype % old_nype != 0: print "SORRY: New nype must be a multiple of old nype" return False if nxpe % old_nxpe != 0: print "SORRY: New nxpe must be a multiple of old nxpe" return False # Get dimension sizes old_mxsub = 0 old_mysub = 0 mz = 0 for v in var_list: if f.ndims(v) == 3: s = f.size(v) old_mxsub = s[0] - 2 * mxg old_mysub = s[1] - 2 * myg mz = s[2] break f.close() # Calculate total size of the grid nx = old_mxsub * old_nxpe ny = old_mysub * old_nype print "Grid sizes: ", nx, ny, mz # Create the new restart files for mype in range(npes): # Calculate X and Y processor numbers pex = mype % nxpe pey = int(mype / nxpe) old_pex = int(pex / xs) old_pey = int(pey / ys) old_x = pex % xs old_y = pey % ys # Old restart file number old_mype = old_nxpe * old_pey + old_pex # Calculate indices in old restart file xmin = old_x * mxsub xmax = xmin + mxsub - 1 + 2 * mxg ymin = old_y * mysub ymax = ymin + mysub - 1 + 2 * myg print "New: " + str(mype) + " (" + str(pex) + ", " + str(pey) + ")" print " => " + str(old_mype) + " (" + str(old_pex) + ", " + \ str(old_pey) + ") : (" + str(old_x) + ", " + str(old_y) + ")"
#
[docs]def expand(newz, path="data", output="./", informat="nc", outformat=None): """Increase the number of Z points in restart files """ if outformat is None: outformat = informat if path == output: print "ERROR: Can't overwrite restart files when expanding" return False def is_pow2(x): """Returns true if x is a power of 2""" return (x > 0) and ((x & (x - 1)) == 0) if not is_pow2(newz - 1): print "ERROR: New Z size must be a power of 2 + 1" return False file_list = glob.glob(os.path.join(path, "BOUT.restart.*." + informat)) nfiles = len(file_list) # Get the file extension ind = file_list[0].rfind(".")
[docs]def create(averagelast=1, final=-1, path="data", output="./", informat="nc", outformat=None): """Create restart files from data (dmp) files. Parameters ---------- averagelast : int, optional, default: 1 Number of time points to average over. Just take last time-point by default. final : int, optional, default: -1 The last time point to use. Default is last (-1) path : str, optional, default: "data" Path to the input data files output : str, optional, default: "./" Path where the output restart files should go informat : str, optional, default: "nc" Format of the input data files outformat : str, optional, default: None Format of the output restart files, it's same as ``informat`` by default. """ if outformat is None: outformat = informat file_list = glob.glob(os.path.join(path, "BOUT.dmp.*." + informat)) nfiles = len(file_list) print "Number of data files: ", nfiles for i in range(nfiles): # Open each data file infname = os.path.join(path, "BOUT.dmp." + str(i) + "." + informat) outfname = os.path.join( output, "BOUT.restart." + str(i) + "." + outformat) print infname, " -> ", outfname infile = DataFile(infname) outfile = DataFile(outfname, create=True) # Get the data always needed in restart files hist_hi = infile.read("iteration") print "hist_hi = ", hist_hi outfile.write("hist_hi", hist_hi) t_array = infile.read("t_array") tt = t_array[final] print "tt = ", tt outfile.write("tt", tt) NXPE = infile.read("NXPE") NYPE = infile.read("NYPE") NPES = NXPE * NYPE print "NPES = ", NPES, " NXPE = ", NXPE outfile.write("NPES", NPES) outfile.write("NXPE", NXPE) # Get a list of variables varnames = infile.list() for var in varnames: if infile.ndims(var) == 4: # Could be an evolving variable print " -> ", var data = infile.read(var) if averagelast == 1: slice = data[final, :, :, :] else: slice = mean(data[(final - averagelast):final, :, :, :], axis=0) print slice.shape outfile.write(var, slice) infile.close() outfile.close()