mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-27 21:55:41 -04:00
Improve/expand special methods for FissionYield
Remove copy method. __contains__ and __getitem__ now take advantage of the ordering of products. This can improve time searching for fission products and retrieving yields. radd and rmul methods defer to their left counterparts, e.g. x * fy => fy * x. Return NotImplemented types if addition is not done with another set of fission yields and multiplication is not done with a scalar. Improve/expand special methods for FissionYield Remove copy method. __contains__ and __getitem__ now take advantage of the ordering of products. This can improve time searching for fission products and retrieving yields. radd and rmul methods defer to their left counterparts, e.g. x * fy => fy * x. Return NotImplemented types if addition is not done with another set of fission yields and multiplication is not done with a scalar.
This commit is contained in:
parent
7b175961fa
commit
91c08ef323
2 changed files with 55 additions and 23 deletions
|
|
@ -3,9 +3,11 @@
|
|||
Contains the per-nuclide components of a depletion chain.
|
||||
"""
|
||||
|
||||
import bisect
|
||||
from collections.abc import Mapping
|
||||
from collections import namedtuple, defaultdict
|
||||
from warnings import warn
|
||||
from numbers import Real
|
||||
try:
|
||||
import lxml.etree as ET
|
||||
except ImportError:
|
||||
|
|
@ -339,6 +341,7 @@ class Nuclide(object):
|
|||
|
||||
return valid
|
||||
|
||||
|
||||
class FissionYieldDistribution(Mapping):
|
||||
"""Energy-dependent fission product yields for a single nuclide
|
||||
|
||||
|
|
@ -504,10 +507,15 @@ class FissionYield(Mapping):
|
|||
self.products = products
|
||||
self.yields = yields
|
||||
|
||||
def __contains__(self, product):
|
||||
ix = bisect.bisect_left(self.products, product)
|
||||
return ix != len(self.products) and self.products[ix] == product
|
||||
|
||||
def __getitem__(self, product):
|
||||
if product not in self.products:
|
||||
ix = bisect.bisect_left(self.products, product)
|
||||
if ix == len(self.products) or self.products[ix] != product:
|
||||
raise KeyError(product)
|
||||
return self.yields[self.products.index(product)]
|
||||
return self.yields[ix]
|
||||
|
||||
def __len__(self):
|
||||
return len(self.products)
|
||||
|
|
@ -516,35 +524,42 @@ class FissionYield(Mapping):
|
|||
return iter(self.products)
|
||||
|
||||
def items(self):
|
||||
"""Return pairs of product, yield"""
|
||||
return zip(self.products, self.yields)
|
||||
|
||||
def __add__(self, other):
|
||||
new = self.copy()
|
||||
if not isinstance(other, FissionYield):
|
||||
return NotImplemented
|
||||
new = FissionYield(self.products, self.yields.copy())
|
||||
new += other
|
||||
return new
|
||||
|
||||
def __iadd__(self, other):
|
||||
"""Increment value from other fission yield"""
|
||||
if not isinstance(other, FissionYield):
|
||||
return NotImplemented
|
||||
self.yields += other.yields
|
||||
return self
|
||||
|
||||
def __radd__(self, other):
|
||||
return self + other
|
||||
|
||||
def __imul__(self, scalar):
|
||||
if not isinstance(scalar, Real):
|
||||
return NotImplemented
|
||||
self.yields *= scalar
|
||||
return self
|
||||
|
||||
def __mul__(self, scalar):
|
||||
new = self.copy()
|
||||
if not isinstance(scalar, Real):
|
||||
return NotImplemented
|
||||
new = FissionYield(self.products, self.yields.copy())
|
||||
new *= scalar
|
||||
return new
|
||||
|
||||
def __rmul__(self, scalar):
|
||||
new = self.copy()
|
||||
new *= scalar
|
||||
return new
|
||||
return self * scalar
|
||||
|
||||
def __repr__(self):
|
||||
return "<{}: {}>".format(self.__class__.__name__, repr(dict(self)))
|
||||
|
||||
def copy(self):
|
||||
"""Return an identical yield object, with unique yields"""
|
||||
return FissionYield(self.products, self.yields.copy())
|
||||
return "<{} containing {} products and yields>".format(
|
||||
self.__class__.__name__, len(self))
|
||||
|
|
|
|||
|
|
@ -134,25 +134,42 @@ def test_fission_yield_distribution():
|
|||
act_dist = yield_dict[exp_ene]
|
||||
for exp_prod, exp_yield in exp_dist.items():
|
||||
assert act_dist[exp_prod] == exp_yield
|
||||
exp_yield_matrix = numpy.array([
|
||||
exp_yield = numpy.array([
|
||||
[4.08e-12, 1.71e-12, 7.85e-4],
|
||||
[1.32e-12, 0.0, 1.12e-3],
|
||||
[5.83e-8, 2.69e-8, 4.54e-3]])
|
||||
assert numpy.array_equal(yield_dist.yield_matrix, exp_yield_matrix)
|
||||
assert numpy.array_equal(yield_dist.yield_matrix, exp_yield)
|
||||
|
||||
# Test the operations / special methods for fission yield
|
||||
orig_yield_obj = yield_dist[0.0253]
|
||||
orig_yields = yield_dist[0.0253]
|
||||
assert len(orig_yields) == len(yield_dict[0.0253])
|
||||
for key, value in yield_dict[0.0253].items():
|
||||
assert key in orig_yields
|
||||
assert orig_yields[key] == value
|
||||
# __getitem__ return yields as a view into yield matrix
|
||||
assert orig_yield_obj.yields.base is yield_dist.yield_matrix
|
||||
copied_yield = orig_yield_obj.copy()
|
||||
# copied yields own their own memory -> not a view
|
||||
assert copied_yield.yields.base is None
|
||||
assert orig_yields.yields.base is yield_dist.yield_matrix
|
||||
|
||||
# Fission yield feature uses scaled and incremented
|
||||
mod_yields = orig_yield_obj * 2
|
||||
assert numpy.array_equal(orig_yield_obj.yields * 2, mod_yields.yields)
|
||||
mod_yields += orig_yield_obj
|
||||
assert numpy.array_equal(orig_yield_obj.yields * 3, mod_yields.yields)
|
||||
mod_yields = orig_yields * 2
|
||||
assert numpy.array_equal(orig_yields.yields * 2, mod_yields.yields)
|
||||
mod_yields += orig_yields
|
||||
assert numpy.array_equal(orig_yields.yields * 3, mod_yields.yields)
|
||||
|
||||
# Failure modes for adding, multiplying yields
|
||||
similar = numpy.empty_like(orig_yields.yields)
|
||||
with pytest.raises(TypeError):
|
||||
orig_yields + similar
|
||||
with pytest.raises(TypeError):
|
||||
similar + orig_yields
|
||||
with pytest.raises(TypeError):
|
||||
orig_yields += similar
|
||||
with pytest.raises(TypeError):
|
||||
orig_yields * similar
|
||||
with pytest.raises(TypeError):
|
||||
similar * orig_yields
|
||||
with pytest.raises(TypeError):
|
||||
orig_yields *= similar
|
||||
|
||||
|
||||
def test_validate():
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue