Source code for flash.flmake.setup_globals

"""Declares global symbols for use in FLASH setup"""

##################################################################
########### Internal Implementation ##############################
##################################################################

import string
import sys
import os.path
import types

# Different levels of verbosity
PPDEBUG = 10  # Used for debugging Config file preprocessing
PPWARN = 20   # Prints preprocessor warnings as well
DEBUG = 30    # Use for "current value of variable x is this
INFO = 40     # Information about what the code is doing (not needed on normal runs)
WARN = 50     # WARNINGs to the user
IMPINFO = 60  # Important information which user should usually be told
ERROR = 70    # Critical Error which must be flagged to user
ALWAYS = 80   # Information which must always be displayed (SUCESS / FAILURE)

# Different grid interpolations
GRID_INTERP_NATIVE = "GRID_INTERP_NATIVE"
GRID_INTERP_MONOTONIC = "GRID_INTERP_MONOTONIC"

# Different geometries
GRID_GEOM_CARTESIAN = "GRID_GEOM_CARTESIAN"
GRID_GEOM_CYLINDRICAL = "GRID_GEOM_CYLINDRICAL"
GRID_GEOM_SPHERICAL = "GRID_GEOM_SPHERICAL"
GRID_GEOM_POLAR = "GRID_GEOM_POLAR"
GRID_GEOM_UNDEF = "GRID_GEOM_UNDEF"

# This string is used many times in the code
# reduces chance of typos
SIM_SETUP_DIR = 'Simulation/SimulationMain'
SETUP_UNITS_FILENAME = 'setup_units'
UNITS_FILENAME = 'Units'
SETUP_PARAMS_FILENAME = "setup_params"
SETUP_VARS_FILENAME = "setup_vars"
SETUP_DEFINES_FILENAME = "setup_defines"
SETUP_CALL_FILENAME = "setup_call"
FLASH_DEFINES_FILENAME = "Flash.h"
SIM_INT_TO_STR_FILENAME = 'Simulation_mapIntToStr.F90'
SIM_STR_TO_INT_FILENAME = 'Simulation_mapStrToInt.F90'
SIM_PARTICLES_VAR_FILENAME = 'Simulation_mapParticlesVar.F90'
BUILD_STAMP_GEN_FILENAME = 'make_bstamp'
SETUP_LIBRARIES_FILENAME = 'setup_libraries'
RP_INIT_PARAMS_FILENAME = 'rp_initParameters.F90'
RP_DEFAULT_PAR_FILENAME = 'default.par'
SETUP_FLASH_UNITS_FILENAME = 'setup_getFlashUnits.F90'
RENORM_GROUP_FILENAME = 'Simulation_getRenormGroup.F90'
VARNAME_TYPE_FILENAME = 'Simulation_getVarnameType.F90'
PM3_RP_FILENAME = 'amr_runtime_parameters'
SUCCESS_FILENAME = ".success"
SIM_PARTICLE_TYPE_FILENAME = 'Particles_specifyMethods.F90'
EOS_MAP_FILENAME = 'eos_variableMap.F90'

# Names of template files. Usually located in bin directory
MAKEFILE_TEMPLATE = 'Makefile.tpl'
BUILD_STAMP_TEMPLATE = 'BuildStamp.tpl'
FLASH_DEFINES_TEMPLATE = 'Flash.h.tpl'
SIM_INT_TO_STR_TEMPLATE = 'MapIntStr.F90.tpl'
SIM_STR_TO_INT_TEMPLATE = 'MapStrInt.F90.tpl'
SIM_PARTICLES_VAR_TEMPLATE = 'getParticlesVarMap.F90.tpl'
SETUP_FLASH_UNITS_TEMPLATE = 'FlashUnits.F90.tpl'
MAKEFILE_STUB_TEMPLATE = 'MakefileStub.tpl'
RENORM_GROUP_TEMPLATE = 'GetRenormGroup.F90.tpl'
VARNAME_TYPE_TEMPLATE = 'GetVarnameType.F90.tpl'
PM3_RP_TEMPLATE = 'amr_runtime_parameters.tpl'
SIM_PARTICLE_TYPE_TEMPLATE = 'Particles_specifyMethods.F90.tpl'
EOS_MAP_TEMPLATE = 'eos_variableMap.F90.tpl'

# List of prefixes for files created by setup. files with following prefixes
# should not be touched by noClobber
NO_CLOBBER_EXCEPTION_LIST = ["setup_",
                             FLASH_DEFINES_FILENAME,
                             SIM_INT_TO_STR_FILENAME,
                             SIM_STR_TO_INT_FILENAME,
                             UNITS_FILENAME,
                             BUILD_STAMP_GEN_FILENAME,
                             RP_INIT_PARAMS_FILENAME,
                             RENORM_GROUP_FILENAME,
                             ]

SHORTCUT_CHAR = "+"

# for processing internal and external libraries
COMPILERS = ('FFLAGS', 'CFLAGS', 'LFLAGS', 'LIB')
DEFLTFLAG = 'OPT'

# unit prefixes which setup knows about
GRID_PREFIX = "Grid/GridMain"
GRID_CHOICES = ["UG", "paramesh", "Samrai", "Chombo"]
SIMULATION_PREFIX = "Simulation/SimulationMain"


[docs]class SetupError(Exception): """Class for SetupError Exception""" pass
[docs]class IndentedOutput: """Pretty printing class""" def __init__(self, num_spaces=4, file=None, debuglevel=WARN): self.WRAP = 80 self.indent = 0 self.num_spaces = num_spaces self.debuglevel = debuglevel if not file: self.file = sys.stdout else: self.file = file def __pretty(self, text, wrap): """Return a list of strings so that each string has length <= wrap and consist of full words only. If one word is too long it may be an entry in the list.""" # soln so far ans = [] more = text while more: if len(more) <= wrap: ans.append(more) break # find last space before or equal to wrap length a = more.rfind(" ", 0, wrap + 1) if a < 0: # first word is long b = more.find(" ") if b < 0: ans.append(more) more = "" else: ans.append(more[:b]) more = more[b:] else: # a >= 0 ans.append(more[:a]) more = more[a:] # if anything left remove leading spaces more = more.strip() return ans def put(self, text, level=WARN): # info not important if level < self.debuglevel: return for line in map(string.strip, string.split(text, '\n')): nsp = self.indent * self.num_spaces ans = self.__pretty(line, self.WRAP - nsp) # printing an empty string if not ans: self.file.write('\n') self.file.flush() continue for a in ans: self.file.write("%s%s\n" % (' ' * nsp, a)) self.file.flush()
[docs] def pop(self, numLevs=1): """Remove numLevs indentation levels""" self.indent = self.indent - numLevs if self.indent < 0: raise SetupError('Popped indentation one time too many!')
def push(self, numLevs=1): self.indent += numLevs
[docs]class SetupVarsClass: """Handle setup variables""" def __init__(self): # actually contains the variables and values self.vars = {} # fbs is true by default self.set("fixedBlockSize", True)
[docs] def addunit(self, unitname, val=False): """Add a with variable for toplevel unit of specified unit.""" parts = unitname.split(os.sep) while parts and parts[0] and not parts[0][0].isupper(): del parts[0] if parts: self.set("with%s" % parts[0], val)
[docs] def set(self, key, value): """Set key to value, value may be a quoted string""" if not value: value = "" # direct store if type(value) != types.StringType: self.vars[key] = value return # we have a string which may require type change if len(value) >= 2 and value[0] == value[-1] and value[0] in ["'", '"']: value = str(value[1:-1]) elif value.lower() in ["true", "false", "yes", "no"]: # make it boolean value = value.lower() in ["true", "yes"] else: try: a = int(value) except: pass else: value = a self.vars[key] = value
def get(self, key): return self.vars.get(key, "")
[docs] def printvars(self, file, ignoreprefix="with"): """File is a file object opened for writing.""" vi = self.vars.items() vi.sort() for k, v in vi: if ignoreprefix and k.startswith(ignoreprefix): continue file.write('%s --> %s %s\n' % (k, v, type(v))) file.write('\n') ######################## ### Global Variables ### ########################
[docs]class GVarsClass(object): """Stores Global variables (visible to most of the code). Also includes parsed version of command line options""" _defaults = {'project_setup_dir': 'setup', 'project_build_dir': 'build', 'project_source_dir': 'source', 'project_simulations_dir': 'simulations', } def init(self, flash_src_dir, hard=False): self.out = IndentedOutput() # pretty printer self.setup_vars = SetupVarsClass() # handles setup variables self.indexReorder = False # reorder indices in unk or not # set or reset default values for k, v in self._defaults.items(): if not hasattr(self, k) or hard: setattr(self, k, v) self.portable = 0 # copy or link files self.verbose = WARN # level of verbose printing self.report = 0 self.dimension = 2 # dimensionality of problem trying to solve self.defines = [] # PreProcessor symbols to inform compiler self.maxblocks = None self.makedisplay = 1 # dont display lines as they are executed in makefile self.makefileext = "" # link to Makefile.h+Thisextension self.nxb = None # domain size self.nyb = None self.nzb = None self.build_site = None self.build_tau = None self.build_os = None self.desc_filename = 'flash_desc.json' self.auto = 0 self.simulation_name = None self.simulation_dir = None self.run_dir_prefix = 'run-' self.run_id = None self.run_dir = None self.buildFlag = 'OPT' # other options are 'DEBUG' and 'TEST' and 'OPT' self.npg = 0 self.withUnits = [] self.with_libraries = {} self.noClobber = 0 # list of unix patterns for files to be copied over to object directory self.datafiles = [] # list of unix patterns for files to be copied over to object directory self.parfile = "" # units to be removed after all conditions have been met (USER BEWARE) self.killUnits = {} self.withoutUnits = {} # units not needed (unless really needed) self.unitsfile = "" # name of Units file to pick the units from # for completeness store all withoutLibrary options (now dont do anyting with it) self.withoutLibraries = {} self.gridInterpolation = None self.gridGeometry = GRID_GEOM_UNDEF self.curvilinear = 0 self.strictParams = 0 self.particleMethods = {} self.particlesUnitIncluded = False self.nonexistent = "NONEXISTENT" self.flash_src_dir = flash_src_dir self.source_dir = os.path.join(self.flash_src_dir, 'source') self.source_path = [self.project_source_dir, self.source_dir] self.simulations_dir = os.path.join(self.source_dir, SIM_SETUP_DIR) self.simulations_path = [self.project_simulations_dir] + \ [os.path.join(sp, SIM_SETUP_DIR) for sp in self.source_path] self.libDir = os.path.join(self.flash_src_dir, 'lib') self.binDir = os.path.join(self.flash_src_dir, 'bin') self.tauDir = os.path.join(self.flash_src_dir, 'tools', 'tau') self.topUnitNames = self.get_top_unit_names() self.unit_aliases = {self.project_simulations_dir: SIM_SETUP_DIR} self.extra_runtime_files = ['amr_runtime_parameters']
[docs] def get_top_unit_names(self, path=None, ignoreUnits=("flashUtilities",), init_path=None): """Return the list of all top level unit names. path may be a list of str, a str, or None. When None (default) the value from self.source_path is taken. """ if path is None: path = self.source_path elif isinstance(path, basestring): path = [path] if init_path is None: init_path = path # verify that we have at least one directory to look in if not any([os.path.isdir(p) for p in path]): return [] # Find units ans = [] for p in path: if not os.path.exists(p): continue basename = os.path.basename(os.path.abspath(p)) ch = basename[0] # Are we a unit if 'A' <= ch <= 'Z': return [os.path.relpath(p, ip) for ip in init_path if p.startswith(ip)] # we are only an organizational directory for dir in os.listdir(p): if dir[0] == "." or (dir in ignoreUnits): continue subdir = os.path.join(p, dir) if not os.path.isdir(subdir): continue ans.extend(self.get_top_unit_names(subdir, ignoreUnits, init_path)) # make unique and return ans = sorted(set(ans)) return ans ############################################################################# ##################### initialization code ################################# #############################################################################
gvars = GVarsClass()