Use strings in representation of particle filter

This commit is contained in:
Paul Romano 2019-07-08 14:49:06 -05:00
parent 1f0e0bfcec
commit 481361ae79
4 changed files with 49 additions and 18 deletions

View file

@ -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,26 @@ 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")
if 'meshes' not in kwargs:
raise ValueError(cls.__name__ + " requires a 'meshes' keyword "
"argument.")
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.

View file

@ -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);
}

View file

@ -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>

View file

@ -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>