mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-21 14:35:27 -04:00
Addressing comments from @paulromano
This commit is contained in:
parent
145594ebb8
commit
f3bcad37b7
6 changed files with 85 additions and 88 deletions
|
|
@ -43,7 +43,8 @@ def _process_CLI_arguments(volume=False, geometry_debug=False, particles=None,
|
|||
MPI execute command and any additional MPI arguments to pass,
|
||||
e.g. ['mpiexec', '-n', '8'].
|
||||
path_input : str or Pathlike
|
||||
Name of a single XML input file for the OpenMC executable to read.
|
||||
Path to a single XML file or a directory containing XML files for the
|
||||
OpenMC executable to read.
|
||||
|
||||
.. versionadded:: 0.13.0
|
||||
|
||||
|
|
@ -135,7 +136,8 @@ def plot_geometry(output=True, openmc_exec='openmc', cwd='.', path_input=None):
|
|||
cwd : str, optional
|
||||
Path to working directory to run in
|
||||
path_input : str
|
||||
Name of a single XML input file for the OpenMC executable to read.
|
||||
Path to a single XML file or a directory containing XML files for the
|
||||
OpenMC executable to read.
|
||||
|
||||
Raises
|
||||
------
|
||||
|
|
@ -146,7 +148,7 @@ def plot_geometry(output=True, openmc_exec='openmc', cwd='.', path_input=None):
|
|||
args = [openmc_exec, '-p']
|
||||
if path_input is not None:
|
||||
args += [path_input]
|
||||
_run([openmc_exec, '-p'], output, cwd)
|
||||
_run(args, output, cwd)
|
||||
|
||||
|
||||
def plot_inline(plots, openmc_exec='openmc', cwd='.', path_input=None):
|
||||
|
|
@ -166,7 +168,8 @@ def plot_inline(plots, openmc_exec='openmc', cwd='.', path_input=None):
|
|||
cwd : str, optional
|
||||
Path to working directory to run in
|
||||
path_input : str
|
||||
Name of a single XML input file for the OpenMC executable to read.
|
||||
Path to a single XML file or a directory containing XML files for the
|
||||
OpenMC executable to read.
|
||||
|
||||
Raises
|
||||
------
|
||||
|
|
@ -224,7 +227,9 @@ def calculate_volumes(threads=None, output=True, cwd='.',
|
|||
Path to working directory to run in. Defaults to the current working
|
||||
directory.
|
||||
path_input : str or Pathlike
|
||||
Name of a single XML input file for the OpenMC executable to read.
|
||||
Path to a single XML file or a directory containing XML files for the
|
||||
OpenMC executable to read.
|
||||
|
||||
|
||||
Raises
|
||||
------
|
||||
|
|
@ -256,17 +261,17 @@ def run(particles=None, threads=None, geometry_debug=False,
|
|||
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
|
||||
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
|
||||
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.
|
||||
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.
|
||||
output : bool
|
||||
Capture OpenMC output from standard out
|
||||
cwd : str, optional
|
||||
|
|
@ -275,15 +280,16 @@ def run(particles=None, threads=None, geometry_debug=False,
|
|||
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'].
|
||||
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
|
||||
|
||||
path_input : str or Pathlike
|
||||
Name of a single XML input file for the OpenMC executable to read.
|
||||
Path to a single XML file or a directory containing XML files for the
|
||||
OpenMC executable to read.
|
||||
|
||||
Raises
|
||||
------
|
||||
|
|
|
|||
|
|
@ -179,6 +179,11 @@ class Geometry:
|
|||
Geometry object
|
||||
|
||||
"""
|
||||
mats = dict()
|
||||
if materials is not None:
|
||||
mats.update({str(m.id): m for m in materials})
|
||||
mats['void'] = None
|
||||
|
||||
# Helper function for keeping a cache of Universe instances
|
||||
universes = {}
|
||||
def get_universe(univ_id):
|
||||
|
|
@ -236,7 +241,7 @@ class Geometry:
|
|||
child_of[u].append(lat)
|
||||
|
||||
for e in elem.findall('cell'):
|
||||
c = openmc.Cell.from_xml_element(e, surfaces, materials, get_universe)
|
||||
c = openmc.Cell.from_xml_element(e, surfaces, mats, get_universe)
|
||||
if c.fill_type in ('universe', 'lattice'):
|
||||
child_of[c.fill].append(c)
|
||||
|
||||
|
|
@ -266,17 +271,15 @@ class Geometry:
|
|||
Geometry object
|
||||
|
||||
"""
|
||||
tree = ET.parse(path)
|
||||
root = tree.getroot()
|
||||
|
||||
# Create dictionary to easily look up materials
|
||||
# Create dictionary to easily look up materials
|
||||
if materials is None:
|
||||
filename = Path(path).parent / 'materials.xml'
|
||||
materials = openmc.Materials.from_xml(str(filename))
|
||||
mats = {str(m.id): m for m in materials}
|
||||
mats['void'] = None
|
||||
|
||||
return cls.from_xml_element(root, mats)
|
||||
tree = ET.parse(path)
|
||||
root = tree.getroot()
|
||||
|
||||
return cls.from_xml_element(root, materials)
|
||||
|
||||
def find(self, point):
|
||||
"""Find cells/universes/lattices which contain a given point
|
||||
|
|
|
|||
|
|
@ -256,8 +256,7 @@ class Model:
|
|||
|
||||
model.settings = openmc.Settings.from_xml_element(root.find('settings'))
|
||||
model.materials = openmc.Materials.from_xml_element(root.find('materials'))
|
||||
materials = {str(m.id): m for m in model.materials}
|
||||
model.geometry = openmc.Geometry.from_xml_element(root.find('geometry'), materials)
|
||||
model.geometry = openmc.Geometry.from_xml_element(root.find('geometry'), model.materials)
|
||||
|
||||
# gather meshes from other classes before reading the tally node
|
||||
meshes = {}
|
||||
|
|
@ -435,30 +434,7 @@ class Model:
|
|||
depletion_operator.cleanup_when_done = True
|
||||
depletion_operator.finalize()
|
||||
|
||||
def export_to_xml(self, directory='.', remove_surfs=False, separate_xmls=True, path='model.xml'):
|
||||
"""Export model to an XML file(s).
|
||||
|
||||
Parameters
|
||||
----------
|
||||
directory : str
|
||||
Directory to write XML files to. If it doesn't exist already, it
|
||||
will be created. Only used if :math:`separate_xmls` is True.
|
||||
remove_surfs : bool
|
||||
Whether or not to remove redundant surfaces from the geometry when
|
||||
exporting.
|
||||
path : str
|
||||
Path to an output filename or directory. Only used if :math:`separate_xmls` is False.
|
||||
|
||||
.. versionadded:: 0.13.1
|
||||
separate_xmls : bool
|
||||
Whether or not to write a single model.xml file or many XML files.
|
||||
"""
|
||||
if separate_xmls:
|
||||
self._export_to_separate_xmls(directory, remove_surfs)
|
||||
else:
|
||||
self._export_to_single_xml(path, remove_surfs)
|
||||
|
||||
def _export_to_separate_xmls(self, directory='.', remove_surfs=False):
|
||||
def export_to_xml(self, directory='.', remove_surfs=False):
|
||||
"""Export model to separate XML files.
|
||||
|
||||
Parameters
|
||||
|
|
@ -495,13 +471,14 @@ class Model:
|
|||
if self.plots:
|
||||
self.plots.export_to_xml(d)
|
||||
|
||||
def _export_to_single_xml(self, path='model.xml', remove_surfs=False):
|
||||
def export_to_model_xml(self, path='model.xml', remove_surfs=False):
|
||||
"""Export model to a single XML file.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
path : str or Pathlike
|
||||
Location of the XML file to write. Can be a directory or file path.
|
||||
Location of the XML file to write (default is 'model.xml'). Can be a
|
||||
directory or file path.
|
||||
remove_surfs : bool
|
||||
Whether or not to remove redundant surfaces from the geometry when
|
||||
exporting.
|
||||
|
|
|
|||
|
|
@ -1074,31 +1074,33 @@ class Settings:
|
|||
subelement.text = str(value)
|
||||
|
||||
def _create_entropy_mesh_subelement(self, root, mesh_memo=None):
|
||||
if self.entropy_mesh is not None:
|
||||
# use default heuristic for entropy mesh if not set by user
|
||||
if self.entropy_mesh.dimension is None:
|
||||
if self.particles is None:
|
||||
raise RuntimeError("Number of particles must be set in order to " \
|
||||
"use entropy mesh dimension heuristic")
|
||||
else:
|
||||
n = ceil((self.particles / 20.0)**(1.0 / 3.0))
|
||||
d = len(self.entropy_mesh.lower_left)
|
||||
self.entropy_mesh.dimension = (n,)*d
|
||||
if self.entropy_mesh is None:
|
||||
return
|
||||
|
||||
# add mesh ID to this element
|
||||
subelement = ET.SubElement(root, "entropy_mesh")
|
||||
subelement.text = str(self.entropy_mesh.id)
|
||||
# use default heuristic for entropy mesh if not set by user
|
||||
if self.entropy_mesh.dimension is None:
|
||||
if self.particles is None:
|
||||
raise RuntimeError("Number of particles must be set in order to " \
|
||||
"use entropy mesh dimension heuristic")
|
||||
else:
|
||||
n = ceil((self.particles / 20.0)**(1.0 / 3.0))
|
||||
d = len(self.entropy_mesh.lower_left)
|
||||
self.entropy_mesh.dimension = (n,)*d
|
||||
|
||||
# If this mesh has already been written outside the
|
||||
# settings element, skip writing it again
|
||||
if mesh_memo and self.entropy_mesh.id in mesh_memo:
|
||||
return
|
||||
# add mesh ID to this element
|
||||
subelement = ET.SubElement(root, "entropy_mesh")
|
||||
subelement.text = str(self.entropy_mesh.id)
|
||||
|
||||
# See if a <mesh> element already exists -- if not, add it
|
||||
path = f"./mesh[@id='{self.entropy_mesh.id}']"
|
||||
if root.find(path) is None:
|
||||
root.append(self.entropy_mesh.to_xml_element())
|
||||
if mesh_memo is not None: mesh_memo.add(self.entropy_mesh.id)
|
||||
# If this mesh has already been written outside the
|
||||
# settings element, skip writing it again
|
||||
if mesh_memo and self.entropy_mesh.id in mesh_memo:
|
||||
return
|
||||
|
||||
# See if a <mesh> element already exists -- if not, add it
|
||||
path = f"./mesh[@id='{self.entropy_mesh.id}']"
|
||||
if root.find(path) is None:
|
||||
root.append(self.entropy_mesh.to_xml_element())
|
||||
if mesh_memo is not None: mesh_memo.add(self.entropy_mesh.id)
|
||||
|
||||
def _create_trigger_subelement(self, root):
|
||||
if self._trigger_active is not None:
|
||||
|
|
@ -1149,15 +1151,21 @@ class Settings:
|
|||
element = ET.SubElement(root, "track")
|
||||
element.text = ' '.join(map(str, itertools.chain(*self._track)))
|
||||
|
||||
def _create_ufs_mesh_subelement(self, root):
|
||||
if self.ufs_mesh is not None:
|
||||
# See if a <mesh> element already exists -- if not, add it
|
||||
path = f"./mesh[@id='{self.ufs_mesh.id}']"
|
||||
if root.find(path) is None:
|
||||
root.append(self.ufs_mesh.to_xml_element())
|
||||
def _create_ufs_mesh_subelement(self, root, mesh_memo=None):
|
||||
if self.ufs_mesh is None:
|
||||
return
|
||||
|
||||
subelement = ET.SubElement(root, "ufs_mesh")
|
||||
subelement.text = str(self.ufs_mesh.id)
|
||||
subelement = ET.SubElement(root, "ufs_mesh")
|
||||
subelement.text = str(self.ufs_mesh.id)
|
||||
|
||||
if mesh_memo and self.ufs_mesh.id in mesh_memo:
|
||||
return
|
||||
|
||||
# See if a <mesh> element already exists -- if not, add it
|
||||
path = f"./mesh[@id='{self.ufs_mesh.id}']"
|
||||
if root.find(path) is None:
|
||||
root.append(self.ufs_mesh.to_xml_element())
|
||||
if mesh_memo is not None: mesh_memo.add(self.ufs_mesh.id)
|
||||
|
||||
def _create_resonance_scattering_subelement(self, root):
|
||||
res = self.resonance_scattering
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ class ModelXMLTestHarness(PyAPITestHarness):
|
|||
self.results_true = 'results_true.dat' if results_true is None else results_true
|
||||
|
||||
def _build_inputs(self):
|
||||
self._model.export_to_xml(separate_xmls=False)
|
||||
self._model.export_to_model_xml()
|
||||
|
||||
def _get_inputs(self):
|
||||
return open('model.xml').read()
|
||||
|
|
@ -77,21 +77,24 @@ def test_input_arg(run_in_tmpdir):
|
|||
pincell.settings.particles = 100
|
||||
|
||||
# export to separate XML files and run
|
||||
pincell.export_to_xml(separate_xmls=True)
|
||||
pincell.export_to_xml()
|
||||
openmc.run()
|
||||
|
||||
# make sure the executable isn't falling back on the separate XMLs
|
||||
for f in glob.glob('*.xml'):
|
||||
os.remove(f)
|
||||
# now export to a single XML file with a custom name
|
||||
pincell.export_to_xml(path='pincell.xml', separate_xmls=False)
|
||||
pincell.export_to_model_xml('pincell.xml')
|
||||
assert Path('pincell.xml').exists()
|
||||
|
||||
# run by specifying that single file
|
||||
openmc.run(path_input='pincell.xml')
|
||||
|
||||
# check that this works for plotting too
|
||||
openmc.plot_geometry(path_input='pincell.xml')
|
||||
|
||||
# now ensure we get an error for an incorrect filename,
|
||||
# even in the presence of other, valid XML files
|
||||
pincell.export_to_xml(separate_xmls=True)
|
||||
pincell.export_to_model_xml()
|
||||
with pytest.raises(RuntimeError, match='ex-em-ell.xml'):
|
||||
openmc.run(path_input='ex-em-ell.xml')
|
||||
|
|
@ -542,18 +542,18 @@ def test_model_xml(run_in_tmpdir):
|
|||
pwr_model.geometry.export_to_xml('geometry_ref.xml')
|
||||
|
||||
# now write and read a model.xml file
|
||||
pwr_model.export_to_xml(separate_xmls=False)
|
||||
pwr_model.export_to_model_xml()
|
||||
new_model = openmc.Model.from_model_xml()
|
||||
|
||||
# make sure we can also export this again to separate
|
||||
# XML files
|
||||
new_model.export_to_xml(separate_xmls=True)
|
||||
new_model.export_to_xml()
|
||||
|
||||
def test_model_exec(run_in_tmpdir):
|
||||
def test_single_xml_exec(run_in_tmpdir):
|
||||
|
||||
pincell_model = openmc.examples.pwr_pin_cell()
|
||||
|
||||
pincell_model.export_to_xml(path='pwr_pincell.xml', separate_xmls=False)
|
||||
pincell_model.export_to_model_xml('pwr_pincell.xml')
|
||||
|
||||
openmc.run(path_input='pwr_pincell.xml')
|
||||
|
||||
|
|
@ -562,7 +562,7 @@ def test_model_exec(run_in_tmpdir):
|
|||
|
||||
# test that a file in a different directory can be used
|
||||
os.mkdir('inputs')
|
||||
pincell_model.export_to_xml(path='./inputs/pincell.xml', separate_xmls=False)
|
||||
pincell_model.export_to_model_xml('./inputs/pincell.xml')
|
||||
openmc.run(path_input='./inputs/pincell.xml')
|
||||
|
||||
with pytest.raises(RuntimeError, match='input_dir'):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue