Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 24 additions & 5 deletions docs/source/io_formats/settings.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1166,11 +1166,12 @@ attributes/sub-elements:

The ``<surf_source_write>`` element triggers OpenMC to bank particles crossing
certain surfaces and write out the source bank in a separate file called
``surface_source.h5``. One or multiple surface IDs and one cell ID can be used
to select the surfaces of interest. If no surface IDs are declared, every surface
of the model is eligible to bank particles. In that case, a cell ID (using
either the ``cell``, ``cellfrom`` or ``cellto`` attributes) can be used to select
every surface of a specific cell. This element has the following
``surface_source.h5``. One or multiple surface IDs and one or multiple cell IDs can be used
to select the surfaces of interest. The cell IDs can have direction flags assosciated with them
to further filter the banked particles. Allowed directions are ``to``, ``from`` or ``both``.
If only one cell ID is used in banking, the ``cell``, ``cellfrom`` or ``cellto`` attributes
can be used instead of the ``cells`` and ``directions`` attributes. If no surface IDs are declared,
every surface of the model is eligible to bank particles. This element has the following
attributes/sub-elements:

:surface_ids:
Expand Down Expand Up @@ -1206,6 +1207,18 @@ attributes/sub-elements:

.. _MCPL: https://mctools.github.io/mcpl/mcpl.pdf

:cells:
A list of integers representing the cell IDs used to determine if particles crossing
identified surfaces are to be banked.

*Default*: None

:directions:
A list of strings representing the directions corresponding to the cell IDs. Allowed values are
``to``, ``from`` or ``both``. Must have the same length as ``cells``.

*Default*: None

:cell:
An integer representing the cell ID used to determine if particles crossing
identified surfaces are to be banked. Particles coming from or going to this
Expand All @@ -1227,9 +1240,15 @@ attributes/sub-elements:

*Default*: None

.. note:: The ``cell``, ``cellfrom`` or ``cellto`` attributes cannot be
used simultaneously with ``cells`` attribute.

.. note:: The ``cell``, ``cellfrom`` and ``cellto`` attributes cannot be
used simultaneously.

.. note:: If ``cells`` attribute is defined and ``directions`` attribute is not,
all the directions of in ``cells`` will default to ``both``.

.. note:: Surfaces with boundary conditions that are not "transmission" or "vacuum"
are not eligible to store any particles when using ``cell``, ``cellfrom``
or ``cellto`` attributes. It is recommended to use surface IDs instead.
Expand Down
32 changes: 28 additions & 4 deletions docs/source/usersguide/settings.rst
Original file line number Diff line number Diff line change
Expand Up @@ -323,8 +323,32 @@ crossing any surface of the model will be banked::

settings.surf_source_write = {'max_particles': 10000}

A cell ID can also be used to bank particles that are crossing any surface of
a cell that particles are either coming from or going to::
A list of cell IDs can also be used to bank particles that are crossing surfaces of
cells that particles are either coming from or going to::

settings.surf_source_write = {
'surfaces_ids': [1, 2, 3],
'cells': [1, 2]
'max_particles': 10000
}

In this example, particles that are crossing surfaces with IDs of 1, 2, or 3 and
entering or exiting cells with IDs 1 or 2 are banked.

To account specifically for particles leaving or entering a given cell,
a list of directions can be used to further filter particles banked::

settings.surf_source_write = {
'surfaces_ids': [1, 2, 3],
'cells': [1, 2]
'directions': '"to", "from"'
'max_particles': 10000
}

In this example, particles that are crossing surfaces with IDs of 1, 2, or 3 and
entering cell with ID 1 or exiting cell with ID 2 are banked.

If only one cell is used to filter particles, an alternative syntax can be used to bank particles::

settings.surf_source_write = {'cell': 1, 'max_particles': 10000}

Expand All @@ -333,10 +357,10 @@ be banked excluding any surface that does not use a 'transmission' or 'vacuum'
boundary condition.

.. note:: Surfaces with boundary conditions that are not "transmission" or "vacuum"
are not eligible to store any particles when using ``cell``, ``cellfrom``
are not eligible to store any particles when using ``cells``, ``cell``, ``cellfrom``
or ``cellto`` attributes. It is recommended to use surface IDs instead.

Surface IDs can be used in combination with a cell ID::
Another example that combines surface IDs with a cell ID::

settings.surf_source_write = {
'cell': 1,
Expand Down
11 changes: 8 additions & 3 deletions include/openmc/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include <cstdint>
#include <string>
#include <unordered_map>
#include <unordered_set>

#include "pugixml.hpp"
Expand Down Expand Up @@ -178,9 +179,11 @@ extern int64_t ssw_max_particles; //!< maximum number of particles to be
extern int64_t ssw_max_files; //!< maximum number of surface source files
//!< to be created
extern int64_t ssw_cell_id; //!< Cell id for the surface source
//!< write setting
extern SSWCellType ssw_cell_type; //!< Type of option for the cell
//!< argument of surface source write

extern std::unordered_map<int64_t, SSWCellType>
ssw_cells; //!< Cell ids and directions
//!< for the surface source write setting

extern TemperatureMethod
temperature_method; //!< method for choosing temperatures
extern double
Expand Down Expand Up @@ -213,6 +216,8 @@ void read_settings_xml(pugi::xml_node root);

void free_memory_settings();

SSWCellType ssw_cell_type_from_string(std::string_view s);

} // namespace openmc

#endif // OPENMC_SETTINGS_H
55 changes: 41 additions & 14 deletions openmc/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -280,15 +280,23 @@ class Settings:
process (int)
:max_source_files: Maximum number of surface source files to be created (int)
:mcpl: Output in the form of an MCPL-file (bool)
:cell: Cell ID used to determine if particles crossing identified
:cells: List of cell IDs used to determine if particles crossing identified
surfaces are to be banked. Particles coming from or going to this
declared cell will be banked (int)
:directions: List of directions corresponding to cells. Acceptable entries are:
"from", "to", or "both" (str)
:cell: Cell ID used to determine if particles crossing identified
surfaces are to be banked. Particles coming from or going to this
declared cell will be banked (int) ("cell" will be deprecated in the future,
use "cells" instead.)
:cellfrom: Cell ID used to determine if particles crossing identified
surfaces are to be banked. Particles coming from this
declared cell will be banked (int)
declared cell will be banked (int) ("cellfrom" will be deprecated in the future,
use "cells" and "directions" instead.)
:cellto: Cell ID used to determine if particles crossing identified
surfaces are to be banked. Particles going to this declared
cell will be banked (int)
cell will be banked (int) ("cellto" will be deprecated in the future,
use "cells" and "directions" instead.)
survival_biasing : bool
Indicate whether survival biasing is to be used
tabular_legendre : dict
Expand Down Expand Up @@ -848,16 +856,22 @@ def surf_source_write(self, surf_source_write: dict):
"surface source writing key",
key,
("surface_ids", "max_particles", "max_source_files",
"mcpl", "cell", "cellfrom", "cellto"),
"mcpl", "cells", "directions", "cell", "cellfrom", "cellto"),
)
if key == "surface_ids":
cv.check_type(
"surface ids for source banking", value, Iterable, Integral
)
for surf_id in value:
cv.check_greater_than(
"surface id for source banking", surf_id, 0)

if key in ("surface_ids", "cells"):
name = {
"surface_ids": "surface id(s) for source banking",
"cells": "Cell ID(s) for source banking",
}[key]
cv.check_type(name, value, Iterable, Integral)
for x in value:
cv.check_greater_than(name, x, 0)
elif key == "directions":
cv.check_type("directions corresponding to cells (from, to or both)", value, Iterable, str)
for direction in value:
if (direction not in ["from", "to", "both"]):
msg = "allowed values for direction: 'from', 'to', 'both' "
raise ValueError(msg)
elif key == "mcpl":
cv.check_type("write to an MCPL-format file", value, bool)
elif key in ("max_particles", "max_source_files", "cell", "cellfrom", "cellto"):
Expand Down Expand Up @@ -1538,19 +1552,29 @@ def _create_surf_source_read_subelement(self, root):
def _create_surf_source_write_subelement(self, root):
if self._surf_source_write:
element = ET.SubElement(root, "surf_source_write")

if "surface_ids" in self._surf_source_write:
subelement = ET.SubElement(element, "surface_ids")
subelement.text = " ".join(
str(x) for x in self._surf_source_write["surface_ids"]
)

if "mcpl" in self._surf_source_write:
subelement = ET.SubElement(element, "mcpl")
subelement.text = str(self._surf_source_write["mcpl"]).lower()

for key in ("max_particles", "max_source_files", "cell", "cellfrom", "cellto"):
if key in self._surf_source_write:
subelement = ET.SubElement(element, key)
subelement.text = str(self._surf_source_write[key])

for key in ("cells", "directions"):
if key in self._surf_source_write:
subelement = ET.SubElement(element, key)
subelement.text = " ".join(
str(x) for x in self._surf_source_write[key]
)

def _create_collision_track_subelement(self, root):
if self._collision_track:
element = ET.SubElement(root, "collision_track")
Expand Down Expand Up @@ -2047,9 +2071,11 @@ def _surf_source_write_from_xml_element(self, root):
elem = root.find('surf_source_write')
if elem is None:
return
for key in ('surface_ids', 'max_particles', 'max_source_files', 'mcpl', 'cell', 'cellto', 'cellfrom'):
if key == 'surface_ids':
for key in ('surface_ids', 'max_particles', 'max_source_files', 'mcpl', 'cells', 'directions', 'cell', 'cellto', 'cellfrom'):
if key in ['surface_ids', 'cells']:
value = get_elem_list(elem, key, int)
elif key == 'directions':
value = get_elem_list(elem, key, str)
else:
value = get_text(elem, key)
if value is not None:
Expand All @@ -2059,6 +2085,7 @@ def _surf_source_write_from_xml_element(self, root):
value = int(value)
self.surf_source_write[key] = value


def _collision_track_from_xml_element(self, root):
elem = root.find('collision_track')
if elem is not None:
Expand Down
1 change: 0 additions & 1 deletion src/finalize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,6 @@ int openmc_finalize()
settings::source_separate = false;
settings::source_write = true;
settings::ssw_cell_id = C_NONE;
settings::ssw_cell_type = SSWCellType::None;
settings::ssw_max_particles = 0;
settings::ssw_max_files = 1;
settings::survival_biasing = false;
Expand Down
Loading
Loading