OpenMC/openmc/executor.py

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

281 lines
8.8 KiB
Python
Raw Permalink Normal View History

from collections.abc import Iterable
from numbers import Integral
import subprocess
import openmc
from .plots import _get_plot_image
def _process_CLI_arguments(volume=False, geometry_debug=False, particles=None,
plot=False, restart_file=None, threads=None,
tracks=False, event_based=None,
openmc_exec='openmc', mpi_args=None):
"""Converts user-readable flags in to command-line arguments to be run with
the OpenMC executable via subprocess.
Parameters
----------
volume : bool, optional
Run in stochastic volume calculation mode. Defaults to False.
geometry_debug : bool, optional
Turn on geometry debugging during simulation. Defaults to False.
particles : int, optional
Number of particles to simulate per generation.
plot : bool, optional
Run in plotting mode. Defaults to False.
restart_file : str, optional
Path to restart file to use
threads : int, optional
Number of OpenMP threads. If OpenMC is compiled with OpenMP threading
enabled, the default is implementation-dependent but is usually equal
to the number of hardware threads available (or a value set by the
:envvar:`OMP_NUM_THREADS` environment variable).
tracks : bool, optional
2022-09-09 11:40:15 +01:00
Enables the writing of particles tracks. The number of particle
tracks written to tracks.h5 is limited to 1000 unless
Settings.max_tracks is set. Defaults to False.
event_based : None or bool, optional
Turns on event-based parallelism if True. If None, the value in
the Settings will be used.
openmc_exec : str, optional
Path to OpenMC executable. Defaults to 'openmc'.
mpi_args : list of str, optional
MPI execute command and any additional MPI arguments to pass,
e.g. ['mpiexec', '-n', '8'].
.. versionadded:: 0.13.0
Returns
-------
args : Iterable of str
The runtime flags converted to CLI arguments of the OpenMC executable
"""
args = [openmc_exec]
if volume:
args.append('--volume')
if isinstance(particles, Integral) and particles > 0:
args += ['-n', str(particles)]
if isinstance(threads, Integral) and threads > 0:
args += ['-s', str(threads)]
if geometry_debug:
args.append('-g')
if event_based is not None:
if event_based:
args.append('-e')
if isinstance(restart_file, str):
args += ['-r', restart_file]
if tracks:
args.append('-t')
if plot:
args.append('-p')
if mpi_args is not None:
args = mpi_args + args
return args
def _run(args, output, cwd):
# Launch a subprocess
p = subprocess.Popen(args, cwd=cwd, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT, universal_newlines=True)
# Capture and re-print OpenMC output in real-time
lines = []
while True:
# If OpenMC is finished, break loop
line = p.stdout.readline()
if not line and p.poll() is not None:
break
lines.append(line)
2017-02-27 09:27:55 -06:00
if output:
# If user requested output, print to screen
print(line, end='')
# Raise an exception if return status is non-zero
if p.returncode != 0:
# Get error message from output and simplify whitespace
output = ''.join(lines)
if 'ERROR: ' in output:
_, _, error_msg = output.partition('ERROR: ')
elif 'what()' in output:
_, _, error_msg = output.partition('what(): ')
else:
error_msg = 'OpenMC aborted unexpectedly.'
error_msg = ' '.join(error_msg.split())
raise RuntimeError(error_msg)
def plot_geometry(output=True, openmc_exec='openmc', cwd='.'):
"""Run OpenMC in plotting mode
Parameters
----------
output : bool, optional
Capture OpenMC output from standard out
openmc_exec : str, optional
Path to OpenMC executable
cwd : str, optional
Path to working directory to run in
2018-01-23 07:18:33 -06:00
Raises
------
RuntimeError
2018-01-23 07:18:33 -06:00
If the `openmc` executable returns a non-zero status
"""
_run([openmc_exec, '-p'], output, cwd)
def plot_inline(plots, openmc_exec='openmc', cwd='.'):
"""Display plots inline in a Jupyter notebook.
.. versionchanged:: 0.13.0
The *convert_exec* argument was removed since OpenMC now produces
.png images directly.
Parameters
----------
plots : Iterable of openmc.Plot
Plots to display
openmc_exec : str
Path to OpenMC executable
cwd : str, optional
Path to working directory to run in
2018-01-23 07:18:33 -06:00
Raises
------
RuntimeError
2018-01-23 07:18:33 -06:00
If the `openmc` executable returns a non-zero status
"""
from IPython.display import display
if not isinstance(plots, Iterable):
plots = [plots]
# Create plots.xml
openmc.Plots(plots).export_to_xml(cwd)
# Run OpenMC in geometry plotting mode
plot_geometry(False, openmc_exec, cwd)
if plots is not None:
images = [_get_plot_image(p, cwd) for p in plots]
display(*images)
def calculate_volumes(threads=None, output=True, cwd='.',
openmc_exec='openmc', mpi_args=None):
"""Run stochastic volume calculations in OpenMC.
This function runs OpenMC in stochastic volume calculation mode. To specify
the parameters of a volume calculation, one must first create a
:class:`openmc.VolumeCalculation` instance and assign it to
:attr:`openmc.Settings.volume_calculations`. For example:
>>> vol = openmc.VolumeCalculation(domains=[cell1, cell2], samples=100000)
>>> settings = openmc.Settings()
>>> settings.volume_calculations = [vol]
>>> settings.export_to_xml()
>>> openmc.calculate_volumes()
Parameters
----------
threads : int, optional
Number of OpenMP threads. If OpenMC is compiled with OpenMP threading
enabled, the default is implementation-dependent but is usually equal
to the number of hardware threads available (or a value set by the
:envvar:`OMP_NUM_THREADS` environment variable).
output : bool, optional
Capture OpenMC output from standard out
openmc_exec : str, optional
Path to OpenMC executable. Defaults to 'openmc'.
mpi_args : list of str, optional
MPI execute command and any additional MPI arguments to pass,
e.g. ['mpiexec', '-n', '8'].
cwd : str, optional
Path to working directory to run in. Defaults to the current working
directory.
2018-01-23 07:18:33 -06:00
Raises
------
RuntimeError
2018-01-23 07:18:33 -06:00
If the `openmc` executable returns a non-zero status
See Also
--------
openmc.VolumeCalculation
"""
args = _process_CLI_arguments(volume=True, threads=threads,
openmc_exec=openmc_exec, mpi_args=mpi_args)
_run(args, output, cwd)
def run(particles=None, threads=None, geometry_debug=False,
2017-02-27 09:27:55 -06:00
restart_file=None, tracks=False, output=True, cwd='.',
openmc_exec='openmc', mpi_args=None, event_based=False):
"""Run an OpenMC simulation.
Parameters
----------
particles : int, optional
Number of particles to simulate per generation.
threads : int, optional
Number of OpenMP threads. If OpenMC is compiled with OpenMP threading
enabled, the default is implementation-dependent but is usually equal
to the number of hardware threads available (or a value set by the
:envvar:`OMP_NUM_THREADS` environment variable).
geometry_debug : bool, optional
Turn on geometry debugging during simulation. Defaults to False.
restart_file : str, optional
Path to restart file to use
tracks : bool, optional
2022-09-09 11:40:15 +01:00
Enables the writing of particles tracks. The number of particle
tracks written to tracks.h5 is limited to 1000 unless
Settings.max_tracks is set. Defaults to False.
2017-02-27 09:27:55 -06:00
output : bool
Capture OpenMC output from standard out
cwd : str, optional
Path to working directory to run in. Defaults to the current working
directory.
openmc_exec : str, optional
Path to OpenMC executable. Defaults to 'openmc'.
mpi_args : list of str, optional
MPI execute command and any additional MPI arguments to pass,
e.g. ['mpiexec', '-n', '8'].
event_based : bool, optional
Turns on event-based parallelism, instead of default history-based
.. versionadded:: 0.12
2018-01-23 07:18:33 -06:00
Raises
------
RuntimeError
2018-01-23 07:18:33 -06:00
If the `openmc` executable returns a non-zero status
2018-01-23 07:18:33 -06:00
"""
args = _process_CLI_arguments(
volume=False, geometry_debug=geometry_debug, particles=particles,
restart_file=restart_file, threads=threads, tracks=tracks,
event_based=event_based, openmc_exec=openmc_exec, mpi_args=mpi_args)
_run(args, output, cwd)