mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-28 14:15:42 -04:00
Merge pull request #1298 from paulromano/particle-filter-str
Use strings instead of arbitrary numbers for particle filter
This commit is contained in:
commit
cca3012a53
6 changed files with 82 additions and 39 deletions
|
|
@ -4,9 +4,6 @@
|
|||
Test Suite
|
||||
==========
|
||||
|
||||
Running Tests
|
||||
-------------
|
||||
|
||||
The OpenMC test suite consists of two parts, a regression test suite and a unit
|
||||
test suite. The regression test suite is based on regression or integrated
|
||||
testing where different types of input files are configured and the full OpenMC
|
||||
|
|
@ -14,27 +11,35 @@ code is executed. Results from simulations are compared with expected
|
|||
results. The unit tests are primarily intended to test individual
|
||||
functions/classes in the OpenMC Python API.
|
||||
|
||||
The test suite relies on the third-party `pytest <https://pytest.org>`_
|
||||
package. To run either or both the regression and unit test suites, it is
|
||||
assumed that you have OpenMC fully installed, i.e., the :ref:`scripts_openmc`
|
||||
executable is available on your :envvar:`PATH` and the :mod:`openmc` Python
|
||||
module is importable. In development where it would be onerous to continually
|
||||
install OpenMC every time a small change is made, it is recommended to install
|
||||
OpenMC in development/editable mode. With setuptools, this is accomplished by
|
||||
running::
|
||||
Prerequisites
|
||||
-------------
|
||||
|
||||
python setup.py develop
|
||||
- The test suite relies on the third-party `pytest <https://pytest.org>`_
|
||||
package. To run either or both the regression and unit test suites, it is
|
||||
assumed that you have OpenMC fully installed, i.e., the :ref:`scripts_openmc`
|
||||
executable is available on your :envvar:`PATH` and the :mod:`openmc` Python
|
||||
module is importable. In development where it would be onerous to continually
|
||||
install OpenMC every time a small change is made, it is recommended to install
|
||||
OpenMC in development/editable mode. With setuptools, this is accomplished by
|
||||
running::
|
||||
|
||||
or using pip (recommended)::
|
||||
python setup.py develop
|
||||
|
||||
pip install -e .[test]
|
||||
or using pip (recommended)::
|
||||
|
||||
It is also assumed that you have cross section data available that is pointed to
|
||||
by the :envvar:`OPENMC_CROSS_SECTIONS` environment variables. Furthermore, to
|
||||
run unit tests for the :mod:`openmc.data` module, it is necessary to have
|
||||
ENDF/B-VII.1 data available and pointed to by the :envvar:`OPENMC_ENDF_DATA`
|
||||
environment variable. All data sources can be obtained using the
|
||||
``tools/ci/travis-before-script.sh`` script.
|
||||
pip install -e .[test]
|
||||
|
||||
- The test suite requires a specific set of cross section data in order for
|
||||
tests to pass. A download URL for the data that OpenMC expects can be found
|
||||
within ``tools/ci/download-xs.sh``.
|
||||
- In addition to the HDF5 data, some tests rely on ENDF files. A download URL
|
||||
for those can also be found in ``tools/ci/download-xs.sh``.
|
||||
- Some tests require `NJOY <https://www.njoy21.io/NJOY2016>`_ to preprocess
|
||||
cross section data. The test suite assumes that you have an ``njoy``
|
||||
executable available on your :envvar:`PATH`.
|
||||
|
||||
Running Tests
|
||||
-------------
|
||||
|
||||
To execute the test suite, go to the ``tests/`` directory and run::
|
||||
|
||||
|
|
@ -46,6 +51,17 @@ installed and run::
|
|||
|
||||
pytest --cov=../openmc --cov-report=html
|
||||
|
||||
Generating XML Inputs
|
||||
---------------------
|
||||
|
||||
Many of the regression tests rely on the Python API to build an appropriate
|
||||
model. However, it can sometimes be desirable to work directly with the XML
|
||||
input files rather than having to run a script in order to run the problem/test.
|
||||
To build the input files for a test without actually running the test, you can
|
||||
run::
|
||||
|
||||
pytest --build-inputs <name-of-test>
|
||||
|
||||
Adding Tests to the Regression Suite
|
||||
------------------------------------
|
||||
|
||||
|
|
|
|||
|
|
@ -411,7 +411,7 @@ class Library(EqualityMixin):
|
|||
# after it). If it's too short, then we apply the ENDF float regular
|
||||
# expression. We don't do this by default because it's expensive!
|
||||
if xss.size != nxs[1] + 1:
|
||||
datastr = ENDF_FLOAT_RE.sub(r'\1e\2', datastr)
|
||||
datastr = ENDF_FLOAT_RE.sub(r'\1e\2\3', datastr)
|
||||
xss = np.fromstring(datastr, sep=' ')
|
||||
assert xss.size == nxs[1] + 1
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,8 @@ _CURRENT_NAMES = (
|
|||
'z-min out', 'z-min in', 'z-max out', 'z-max in'
|
||||
)
|
||||
|
||||
_PARTICLE_IDS = {'neutron': 1, 'photon': 2, 'electron': 3, 'positron': 4}
|
||||
_PARTICLES = {'neutron', 'photon', 'electron', 'positron'}
|
||||
|
||||
|
||||
class FilterMeta(ABCMeta):
|
||||
def __new__(cls, name, bases, namespace, **kwargs):
|
||||
|
|
@ -547,10 +548,9 @@ class ParticleFilter(Filter):
|
|||
|
||||
Parameters
|
||||
----------
|
||||
bins : str, int, or iterable of Integral
|
||||
The Particles to tally. Either str with particle type or their
|
||||
ID numbers can be used ('neutron' = 1, 'photon' = 2, 'electron' = 3,
|
||||
'positron' = 4).
|
||||
bins : str, or iterable of str
|
||||
The particles to tally represented as strings ('neutron', 'photon',
|
||||
'electron', 'positron').
|
||||
filter_id : int
|
||||
Unique identifier for the filter
|
||||
|
||||
|
|
@ -571,16 +571,22 @@ class ParticleFilter(Filter):
|
|||
@bins.setter
|
||||
def bins(self, bins):
|
||||
bins = np.atleast_1d(bins)
|
||||
cv.check_iterable_type('filter bins', bins, (Integral, str))
|
||||
cv.check_iterable_type('filter bins', bins, str)
|
||||
for edge in bins:
|
||||
if isinstance(edge, Integral):
|
||||
cv.check_value('filter bin', edge, _PARTICLE_IDS.values())
|
||||
else:
|
||||
cv.check_value('filter bin', edge, _PARTICLE_IDS.keys())
|
||||
bins = np.atleast_1d([b if isinstance(b, Integral) else _PARTICLE_IDS[b]
|
||||
for b in bins])
|
||||
cv.check_value('filter bin', edge, _PARTICLES)
|
||||
self._bins = bins
|
||||
|
||||
@classmethod
|
||||
def from_hdf5(cls, group, **kwargs):
|
||||
if group['type'][()].decode() != cls.short_name.lower():
|
||||
raise ValueError("Expected HDF5 data for filter type '"
|
||||
+ cls.short_name.lower() + "' but got '"
|
||||
+ group['type'][()].decode() + " instead")
|
||||
|
||||
particles = [b.decode() for b in group['bins'][()]]
|
||||
filter_id = int(group.name.split('/')[-1].lstrip('filter '))
|
||||
return cls(particles, filter_id=filter_id)
|
||||
|
||||
|
||||
class MeshFilter(Filter):
|
||||
"""Bins tally event locations onto a regular, rectangular mesh.
|
||||
|
|
|
|||
|
|
@ -7,12 +7,20 @@ namespace openmc {
|
|||
void
|
||||
ParticleFilter::from_xml(pugi::xml_node node)
|
||||
{
|
||||
auto particles = get_node_array<int>(node, "bins");
|
||||
auto particles = get_node_array<std::string>(node, "bins");
|
||||
|
||||
// Convert to vector of Particle::Type
|
||||
std::vector<Particle::Type> types;
|
||||
for (auto& p : particles) {
|
||||
types.push_back(static_cast<Particle::Type>(p - 1));
|
||||
if (p == "neutron") {
|
||||
types.push_back(Particle::Type::neutron);
|
||||
} else if (p == "photon") {
|
||||
types.push_back(Particle::Type::photon);
|
||||
} else if (p == "electron") {
|
||||
types.push_back(Particle::Type::electron);
|
||||
} else if (p == "positron") {
|
||||
types.push_back(Particle::Type::positron);
|
||||
}
|
||||
}
|
||||
this->set_particles(types);
|
||||
}
|
||||
|
|
@ -47,9 +55,22 @@ void
|
|||
ParticleFilter::to_statepoint(hid_t filter_group) const
|
||||
{
|
||||
Filter::to_statepoint(filter_group);
|
||||
std::vector<int> particles;
|
||||
std::vector<std::string> particles;
|
||||
for (auto p : particles_) {
|
||||
particles.push_back(static_cast<int>(p) + 1);
|
||||
switch (p) {
|
||||
case Particle::Type::neutron:
|
||||
particles.push_back("neutron");
|
||||
break;
|
||||
case Particle::Type::photon:
|
||||
particles.push_back("photon");
|
||||
break;
|
||||
case Particle::Type::electron:
|
||||
particles.push_back("electron");
|
||||
break;
|
||||
case Particle::Type::positron:
|
||||
particles.push_back("positron");
|
||||
break;
|
||||
}
|
||||
}
|
||||
write_dataset(filter_group, "bins", particles);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@
|
|||
<bins>9</bins>
|
||||
</filter>
|
||||
<filter id="2" type="particle">
|
||||
<bins>2</bins>
|
||||
<bins>photon</bins>
|
||||
</filter>
|
||||
<tally id="1">
|
||||
<filters>1 2</filters>
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<tallies>
|
||||
<filter id="1" type="particle">
|
||||
<bins>2</bins>
|
||||
<bins>photon</bins>
|
||||
</filter>
|
||||
<tally id="1">
|
||||
<filters>1</filters>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue