mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-27 13:45:36 -04:00
Use dictionary to create FissionYieldDistribution
Removes the FissionYieldDistribution.from_dict method as the most natural way to create such a distribution is with a dictionary.
This commit is contained in:
parent
f977962113
commit
60f89794f6
5 changed files with 38 additions and 66 deletions
|
|
@ -10,7 +10,6 @@ import math
|
|||
import re
|
||||
from collections import OrderedDict, defaultdict
|
||||
from collections.abc import Mapping, Iterable
|
||||
from numbers import Real
|
||||
from warnings import warn
|
||||
|
||||
from openmc.checkvalue import check_type, check_less_than
|
||||
|
|
@ -127,8 +126,8 @@ class Chain(object):
|
|||
fission_yields : None or iterable of dict
|
||||
List of effective fission yields for materials. Each dictionary
|
||||
should be of the form ``{parent: {product: yield}}`` with
|
||||
types ``{str: {str: float}}``, where ``yield`` is the fission product yield
|
||||
for isotope ``parent`` producing isotope ``product``.
|
||||
types ``{str: {str: float}}``, where ``yield`` is the fission product
|
||||
yield for isotope ``parent`` producing isotope ``product``.
|
||||
A single entry indicates yields are constant across all materials.
|
||||
Otherwise, an entry can be added for each material to be burned.
|
||||
Ordering should be identical to how the operator orders reaction
|
||||
|
|
@ -222,7 +221,8 @@ class Chain(object):
|
|||
if mode.daughter in decay_data:
|
||||
target = mode.daughter
|
||||
else:
|
||||
print('missing {} {} {}'.format(parent, ','.join(mode.modes), mode.daughter))
|
||||
print('missing {} {} {}'.format(
|
||||
parent, ','.join(mode.modes), mode.daughter))
|
||||
target = replace_missing(mode.daughter, decay_data)
|
||||
|
||||
# Write branching ratio, taking care to ensure sum is unity
|
||||
|
|
@ -285,7 +285,7 @@ class Chain(object):
|
|||
yield_replace = 0.0
|
||||
yields = defaultdict(float)
|
||||
for product, y in table.items():
|
||||
# Handle fission products that have no decay data available
|
||||
# Handle fission products that have no decay data
|
||||
if product not in decay_data:
|
||||
daughter = replace_missing(product, decay_data)
|
||||
product = daughter
|
||||
|
|
@ -297,8 +297,7 @@ class Chain(object):
|
|||
missing_fp.append((parent, E, yield_replace))
|
||||
yield_data[E] = yields
|
||||
|
||||
nuclide.yield_data = (
|
||||
FissionYieldDistribution.from_dict(yield_data))
|
||||
nuclide.yield_data = FissionYieldDistribution(yield_data)
|
||||
|
||||
# Display warnings
|
||||
if missing_daughter:
|
||||
|
|
|
|||
|
|
@ -3,16 +3,15 @@
|
|||
Contains the per-nuclide components of a depletion chain.
|
||||
"""
|
||||
|
||||
from numbers import Real
|
||||
from collections import namedtuple
|
||||
from collections.abc import Iterable, Mapping
|
||||
from collections.abc import Mapping
|
||||
|
||||
try:
|
||||
import lxml.etree as ET
|
||||
except ImportError:
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
from numpy import asarray, empty
|
||||
from numpy import empty
|
||||
|
||||
from openmc.checkvalue import check_type
|
||||
|
||||
|
|
@ -132,7 +131,7 @@ class Nuclide(object):
|
|||
check_type("fission_yields", fission_yields, Mapping)
|
||||
if isinstance(fission_yields, FissionYieldDistribution):
|
||||
self._yield_data = fission_yields
|
||||
self._yield_data = FissionYieldDistribution.from_dict(fission_yields)
|
||||
self._yield_data = FissionYieldDistribution(fission_yields)
|
||||
|
||||
@property
|
||||
def yield_energies(self):
|
||||
|
|
@ -245,7 +244,7 @@ class FissionYieldDistribution(Mapping):
|
|||
Can be used as a dictionary mapping energies and products to fission
|
||||
yields::
|
||||
|
||||
>>> fydist = FissionYieldDistribution.from_dict({
|
||||
>>> fydist = FissionYieldDistribution{
|
||||
... {0.0253: {"Xe135": 0.021}})
|
||||
>>> fydist[0.0253]["Xe135"]
|
||||
0.021
|
||||
|
|
@ -266,11 +265,10 @@ class FissionYieldDistribution(Mapping):
|
|||
Attributes
|
||||
----------
|
||||
energies : tuple
|
||||
Energies for which fission yields exist. Converted for
|
||||
indexing
|
||||
Energies for which fission yields exist. Sorted by
|
||||
increasing energy
|
||||
products : tuple
|
||||
Fission products produced at all energies. Converted
|
||||
for indexing
|
||||
Fission products produced at all energies. Sorted by name.
|
||||
yield_matrix : numpy.ndarray
|
||||
Array ``(n_energy, n_products)`` where
|
||||
``yield_matrix[g, j]`` is the fission yield of product
|
||||
|
|
@ -278,22 +276,28 @@ class FissionYieldDistribution(Mapping):
|
|||
|
||||
See Also
|
||||
--------
|
||||
* :meth:`from_xml_element`, :meth:`from_dict` - Construction methods
|
||||
* :meth:`from_xml_element` - Construction methods
|
||||
* :class:`FissionYield` - Class used for storing yields at a given energy
|
||||
"""
|
||||
|
||||
def __init__(self, energies, products, yield_matrix):
|
||||
check_type("energies", energies, Iterable, Real)
|
||||
def __init__(self, fission_yields):
|
||||
# mapping {energy: {product: value}}
|
||||
energies = sorted(fission_yields)
|
||||
|
||||
# Get a consistent set of products to produce a matrix of yields
|
||||
shared_prod = set.union(*(set(x) for x in fission_yields.values()))
|
||||
ordered_prod = sorted(shared_prod)
|
||||
|
||||
yield_matrix = empty((len(energies), len(shared_prod)))
|
||||
|
||||
for g_index, energy in enumerate(energies):
|
||||
prod_map = fission_yields[energy]
|
||||
for prod_ix, product in enumerate(ordered_prod):
|
||||
yield_val = prod_map.get(product)
|
||||
yield_matrix[g_index, prod_ix] = (
|
||||
0.0 if yield_val is None else yield_val)
|
||||
self.energies = tuple(energies)
|
||||
check_type("products", products, Iterable, str)
|
||||
self.products = tuple(products)
|
||||
yield_matrix = asarray(yield_matrix, dtype=float)
|
||||
if yield_matrix.shape != (len(self.energies), len(self.products)):
|
||||
raise ValueError(
|
||||
"Shape of yield matrix inconsistent. "
|
||||
"Should be ({}, {}), is {}".format(
|
||||
len(energies), len(products),
|
||||
yield_matrix.shape))
|
||||
self.products = tuple(ordered_prod)
|
||||
self.yield_matrix = yield_matrix
|
||||
|
||||
def __len__(self):
|
||||
|
|
@ -329,38 +333,7 @@ class FissionYieldDistribution(Mapping):
|
|||
# Get a map of products to their corresponding yield
|
||||
all_yields[energy] = dict(zip(products, yields))
|
||||
|
||||
return cls.from_dict(all_yields)
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, fission_yields):
|
||||
"""Construct a distribution from a dictionary of yields
|
||||
|
||||
Parameters
|
||||
-----------
|
||||
fission_yields : dict
|
||||
Dictionary ``{energy: {product: yield}}``
|
||||
|
||||
Returns
|
||||
-------
|
||||
FissionYieldDistribution
|
||||
"""
|
||||
# mapping {energy: {product: value}}
|
||||
energies = sorted(fission_yields)
|
||||
|
||||
# Get a consistent set of products to produce a matrix of yields
|
||||
shared_prod = set.union(*(set(x) for x in fission_yields.values()))
|
||||
ordered_prod = sorted(shared_prod)
|
||||
|
||||
yield_matrix = empty((len(energies), len(shared_prod)))
|
||||
|
||||
for g_index, energy in enumerate(energies):
|
||||
prod_map = fission_yields[energy]
|
||||
for prod_ix, product in enumerate(ordered_prod):
|
||||
yield_val = prod_map.get(product)
|
||||
yield_matrix[g_index, prod_ix] = (
|
||||
0.0 if yield_val is None else yield_val)
|
||||
|
||||
return cls(energies, ordered_prod, yield_matrix)
|
||||
return cls(all_yields)
|
||||
|
||||
def to_xml_element(self, root):
|
||||
"""Write fission yield data to an xml element
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@ def test_export_to_xml(run_in_tmpdir):
|
|||
nuclide.ReactionTuple("(n,gamma)", "A", 0.0, 0.7),
|
||||
nuclide.ReactionTuple("(n,gamma)", "B", 0.0, 0.3)
|
||||
]
|
||||
C.yield_data = nuclide.FissionYieldDistribution.from_dict({
|
||||
C.yield_data = nuclide.FissionYieldDistribution({
|
||||
0.0253: {"A": 0.0292737, "B": 0.002566345}})
|
||||
|
||||
chain = Chain()
|
||||
|
|
|
|||
|
|
@ -21,11 +21,11 @@ def nuclide_bundle():
|
|||
5.0e5: {"Xe135": 7.85e-4, "Sm149": 1.71e-12},
|
||||
1.40e7: {"Xe135": 4.54e-3, "Gd155": 5.83e-8}}
|
||||
u235 = Nuclide("U235")
|
||||
u235.yield_data = FissionYieldDistribution.from_dict(u5yield_dict)
|
||||
u235.yield_data = FissionYieldDistribution(u5yield_dict)
|
||||
|
||||
u8yield_dict = {5.00e5: {"Xe135": 1.12e-3, "Gd155": 1.32e-12}}
|
||||
u238 = Nuclide("U238")
|
||||
u238.yield_data = FissionYieldDistribution.from_dict(u8yield_dict)
|
||||
u238.yield_data = FissionYieldDistribution(u8yield_dict)
|
||||
|
||||
xe135 = Nuclide("Xe135")
|
||||
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ def test_from_xml():
|
|||
nuclide.ReactionTuple('(n,gamma)', 'U236', 6545200.0, 1.0),
|
||||
nuclide.ReactionTuple('fission', None, 193405400.0, 1.0),
|
||||
]
|
||||
expected_yield_data = nuclide.FissionYieldDistribution.from_dict({
|
||||
expected_yield_data = nuclide.FissionYieldDistribution({
|
||||
0.0253: {"Xe138": 0.0481413, "Zr100": 0.0497641, "Te134": 0.062155}})
|
||||
assert u235.yield_data == expected_yield_data
|
||||
# test accessing the yield energies through the FissionYieldDistribution
|
||||
|
|
@ -94,7 +94,7 @@ def test_to_xml_element():
|
|||
nuclide.ReactionTuple('fission', None, 2.0e8, 1.0),
|
||||
nuclide.ReactionTuple('(n,gamma)', 'A', 0.0, 1.0)
|
||||
]
|
||||
C.yield_data = nuclide.FissionYieldDistribution.from_dict(
|
||||
C.yield_data = nuclide.FissionYieldDistribution(
|
||||
{0.0253: {"A": 0.0292737, "B": 0.002566345}})
|
||||
element = C.to_xml_element()
|
||||
|
||||
|
|
@ -127,7 +127,7 @@ def test_fission_yield_distribution():
|
|||
1.40e7: {"Xe135": 4.54e-3, "Gd155": 5.83e-8, "Sm149": 2.69e-8},
|
||||
5.00e5: {"Xe135": 1.12e-3, "Gd155": 1.32e-12}, # drop Sm149
|
||||
}
|
||||
yield_dist = nuclide.FissionYieldDistribution.from_dict(yield_dict)
|
||||
yield_dist = nuclide.FissionYieldDistribution(yield_dict)
|
||||
assert len(yield_dist) == len(yield_dict)
|
||||
assert yield_dist.energies == tuple(sorted(yield_dict.keys()))
|
||||
for exp_ene, exp_dist in yield_dict.items():
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue