from numbers import Integral from pathlib import Path import subprocess from typing import Iterable import warnings import pygriffin.checkvalue as cv from pygriffin.config import PyGriffinConfig class PyGriffin: """ Class for connecting PyGriffin inputs and running the problems Parameters ---------- input : str or Path object Location of Griffin input file n_procs : int Number of processes in Griffin run """ def __init__(self, input, mesh=None, n_procs=1): self.config = PyGriffinConfig() self.input = input self.n_procs = n_procs def run(self, cwd=None, other_args=None): """ Execute Griffin Parameters ---------- cwd : str or Path Directory from which to run Griffin Returns ------- int Errorcode of the Griffin run (0 is success) """ cmd = [] if self.n_procs > 1: if self.config.mpi_enabled: cmd += ['mpirun', '-n', str(self.n_procs)] else: msg = ("MPI is not enabled for this Griffin executable. " "The n_procs argument will be ignored.") warnings.warn(msg) # add griffin executable to command line cmd.append(str(self.config.griffin_exec)) cmd += ['-i', str(self.input)] if cwd is not None: cwd = Path(cwd) else: cwd = Path('.') if cwd and not cwd.is_dir(): msg = ("Specified working directory " "doesn't exist: {}".format(cwd)) raise ValueError(msg) if other_args is not None: cv.check_type('Additional Griffin arguments', other_args, Iterable) cmd += other_args p = subprocess.Popen(cmd, universal_newlines=True, cwd=str(cwd)) return p.wait() def __call__(self, cwd=None): return self.run(cwd) @property def input(self): return self._input @input.setter def input(self, input): cv.check_type('Griffin input', input, (str, Path)) self._input = Path(input).absolute() @property def mesh(self): return self._mesh @mesh.setter def mesh(self, mesh): cv.check_type('Griffin mesh', mesh, (str, Path)) @property def xs(self): return self._xs @xs.setter def xs(self, xs): cv.check_type('Cross section file', xs, (str, Path)) self._xs = xs @property def n_procs(self): return self._n_procs @n_procs.setter def n_procs(self, procs): cv.check_type('Griffin processes', procs, Integral) cv.check_greater_than('Griffin processes', procs, 0) self._n_procs = procs