Use defaultdict(dict) when weighting fission yields

The Chain.form_matrix method looks for information and
fission yields for all isotopes with a fission reaction.
However, the AveragedFissionYieldHelper and FissionYieldCutoffHelper
are not guaranteed to return yields to all isotopes with
fission reactions. Instead, the union on two sets of yields
are returned:
1) yields from isotopes with a single set of fission yields
2) weighted yields computed for isotopes with both multiple sets of
   fission yields **and** non-zero densities.

This later item can cause some isotopes that the Chain anticipates
having fission yields, since they have a fission reaction, to not
exist in the yields library. An isotope with multiple sets of
yields but that is not physically present in the problem will not
have reaction rates and also not have fission yields computed
by these helpers. This will cause a KeyError during Chain.form_matrix
when fission yields for these isotopes are requested.

This commit changes the return type from weighted_yields on
ConstantFissionYieldHelper, AveragedFissionYieldHelper, and
FissionYieldCutoffHelper to be defaultdict(dict). This resolves
the above issue by returning an "empty" set of yields for isotopes
that potentially *should* have fission yields, but have zero density
across the problem, and therefore do not have tallied reaction
rates nor fission yields.

Documentation for the changes to these classes have been updated
This commit is contained in:
Andrew Johnson 2019-09-11 10:26:45 -05:00
parent 3df4f94fbf
commit 2c965ef7f8
No known key found for this signature in database
GPG key ID: 253418E91B7F6FEB
2 changed files with 34 additions and 17 deletions

View file

@ -5,6 +5,7 @@ to run a full depletion simulation.
"""
from collections import namedtuple
from collections import defaultdict
from collections.abc import Iterable
import os
from pathlib import Path
@ -376,14 +377,17 @@ class FissionYieldHelper(ABC):
Attributes
----------
constant_yields : dict of str to :class:`openmc.deplete.FissionYield`
constant_yields : collections.defaultdict
Fission yields for all nuclides that only have one set of
fission yield data. Can be accessed as ``{parent: {product: yield}}``
fission yield data. Dictionary of form ``{str: {str: float}}``
representing yields for ``{parent: {product: yield}}``. Default
return object is an empty dictionary
"""
def __init__(self, chain_nuclides):
self._chain_nuclides = {}
self._constant_yields = {}
self._constant_yields = defaultdict(dict)
# Get all nuclides with fission yield data
for nuc in chain_nuclides:
@ -407,14 +411,16 @@ class FissionYieldHelper(ABC):
Parameters
----------
local_mat_index : int
Index for material tracked on this process that
exists in :attr:`local_mat_index` and fits within
the first axis in :attr:`results`
Index for the material with requested fission yields.
Should correspond to the material represented in
``mat_indexes[local_mat_index]`` during
:meth:`generate_tallies`.
Returns
-------
library : dict
Dictionary of ``{parent: {product: fyield}}``
library : collections.abc.Mapping
Dictionary-like object mapping ``{str: {str: float}``.
This reflects fission yields for ``{parent: {product: fyield}}``.
"""
@staticmethod

View file

@ -5,6 +5,7 @@ from copy import deepcopy
from itertools import product
from numbers import Real
import bisect
from collections import defaultdict
from numpy import dot, zeros, newaxis
@ -179,9 +180,11 @@ class ConstantFissionYieldHelper(FissionYieldHelper):
Attributes
----------
constant_yields : dict of str to :class:`openmc.deplete.FissionYield`
constant_yields : collections.defaultdict
Fission yields for all nuclides that only have one set of
fission yield data. Can be accessed as ``{parent: {product: yield}}``
fission yield data. Dictionary of form ``{str: {str: float}}``
representing yields for ``{parent: {product: yield}}``. Default
return object is an empty dictionary
energy : float
Energy of fission yield libraries.
"""
@ -237,7 +240,7 @@ class ConstantFissionYieldHelper(FissionYieldHelper):
Returns
-------
library : dict
library : collections.defaultdict
Dictionary of ``{parent: {product: fyield}}``
"""
return self.constant_yields
@ -282,6 +285,11 @@ class FissionYieldCutoffHelper(TalliedFissionYieldHelper):
fast_yields : dict
Dictionary of the form ``{parent: {product: yield}}``
with fast yields
constant_yields : collections.defaultdict
Fission yields for all nuclides that only have one set of
fission yield data. Dictionary of form ``{str: {str: float}}``
representing yields for ``{parent: {product: yield}}``. Default
return object is an empty dictionary
results : numpy.ndarray
Array of fission rate fractions with shape
``(n_mats, 2, n_nucs)``. ``results[:, 0]``
@ -417,7 +425,7 @@ class FissionYieldCutoffHelper(TalliedFissionYieldHelper):
Returns
-------
library : dict
library : collections.defaultdict
Dictionary of ``{parent: {product: fyield}}``
"""
yields = self.constant_yields
@ -469,9 +477,11 @@ class AveragedFissionYieldHelper(TalliedFissionYieldHelper):
Attributes
----------
constant_yields : dict of str to :class:`openmc.deplete.FissionYield`
constant_yields : collections.defaultdict
Fission yields for all nuclides that only have one set of
fission yield data. Can be accessed as ``{parent: {product: yield}}``
fission yield data. Dictionary of form ``{str: {str: float}}``
representing yields for ``{parent: {product: yield}}``. Default
return object is an empty dictionary
results : None or numpy.ndarray
If tallies have been generated and unpacked, then the array will
have shape ``(n_mats, n_tnucs)``, where ``n_mats`` is the number
@ -569,12 +579,13 @@ class AveragedFissionYieldHelper(TalliedFissionYieldHelper):
Returns
-------
library : dict
Dictionary of ``{parent: {product: fyield}}``
library : collections.defaultdict
Dictionary of ``{parent: {product: fyield}}``. Default return
value is an empty dictionary
"""
if not self._tally_nucs:
return self.constant_yields
mat_yields = {}
mat_yields = defaultdict(dict)
average_energies = self.results[local_mat_index]
for avg_e, nuc in zip(average_energies, self._tally_nucs):
nuc_energies = nuc.yield_energies