Newer
Older
from numbers import Integral
from pathlib import Path
import subprocess
from collections import Iterable
import warnings
from . import checkvalue as cv
from .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
"""
Patrick Shriwise
committed
def __init__(self, input, mesh=None, n_procs=1):
self.config = PyGriffinConfig()
self.input = input
Patrick Shriwise
committed
self.mesh = mesh
self.n_procs = n_procs
Patrick Shriwise
committed
def run(self, input=None, mesh=None, cwd=None, other_args=None, color=True):
"""
Execute Griffin
Parameters
----------
cwd : str or Path
Directory from which to run Griffin
Returns
-------
int
Errorcode of the Griffin run (0 is success)
"""
cmd = []
Patrick Shriwise
committed
# set custom values if requested in method call
input_file = self.input if input is None else input
mesh_file = self.mesh if mesh is None else mesh
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))
Patrick Shriwise
committed
cmd += ['-i', str(input_file)]
# append the mesh file to the command if needed
if str(mesh_file).endswith('.i'):
cmd.append(str(mesh_file))
Patrick Shriwise
committed
if cwd is not None:
cwd = Path(cwd)
else:
cwd = Path('.')
Patrick Shriwise
committed
if cwd and not cwd.is_dir():
msg = ("Specified working directory "
"doesn't exist: {}".format(cwd))
raise ValueError(msg)
Patrick Shriwise
committed
if other_args is not None:
cv.check_type('Additional Griffin arguments', other_args, Iterable)
cmd += other_args
Patrick Shriwise
committed
# request colorless output
if not color:
cmd += ['--color', 'off']
p = subprocess.Popen(cmd, universal_newlines=True, cwd=str(cwd))
return p.wait()
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
def process_xs(self, overwrite=False, particle='neutron', cwd=None):
"""
Runs ISOXML on the current set of cross sections
Parameters
----------
overwrite : bool
Overwrite the current xs file if True (default False)
particle : str
Indicates what particle type the cross section data is.
One of ('neutron', 'gamma', 'photon')
Returns
-------
Path to the resulting ISOXML file
"""
if str(self.xs).endswith('xml'):
return self.xs
cv.check_value('Particle data', particle, ('neutron', 'gamma', 'photon'))
if particle in ('gamma', 'photon'):
p_flag = '-p'
else:
p_flag = '-n'
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)
# run isoxml executable on the current xs file
Patrick Shriwise
committed
cmd = [str(self.config.isoxml_exec), p_flag, str(self.xs)]
p = subprocess.Popen(cmd, universal_newlines=True, cwd=str(cwd))
p.wait()
# construct the name of the new xs file and return it
name_parts = str(self.xs).split('.')
name_parts[-1] = 'xml'
xs_name = '.'.join(name_parts)
return xs_name
Patrick Shriwise
committed
def generate_mesh(self, overwrite=False):
"""
Generates the mesh for the griffin-problem if needed
Parameters
----------
overwrite : bool
Overwrite the current mesh if True (default False)
Patrick Shriwise
committed
Returns
-------
Path to the mesh file
"""
# if a mesh file was passed, no need to generate a new one
if str(self.mesh).endswith('.e'):
return self.mesh
# if a mesh input is set, generate the mesh file
if str(self.mesh).endswith('.i'):
name_parts = str(self.mesh).split('.')
name_parts[-1] = 'e'
mesh_name = '.'.join(name_parts)
self.run(input=self.mesh, other_args=['--mesh-only', mesh_name])
return Path(mesh_name).resolve().absolute()
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()
Patrick Shriwise
committed
@property
def mesh(self):
return self._mesh
@mesh.setter
def mesh(self, mesh):
cv.check_type('Griffin mesh', mesh, (str, Path))
Patrick Shriwise
committed
self._mesh = mesh
Patrick Shriwise
committed
@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 mpi_enabled(self):
return self.config.mpi_enabled
@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