From c1d66bc0226b721620e1aad78b684074acb0c080 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Wed, 14 Aug 2019 10:49:46 -0500 Subject: [PATCH] Ensure # fission yields == # burnable materials in cram.deplete If the fission yields are a single entry, then itertools.repeat is used to apply the fission yields to all burnable materials. Otherwise, check that the number of fission yield libraries is equal to the number of materials to be burned. --- openmc/deplete/cram.py | 12 ++++++++---- openmc/deplete/nuclide.py | 21 +++++++++++---------- tests/unit_tests/test_deplete_chain.py | 9 ++++++++- 3 files changed, 27 insertions(+), 15 deletions(-) diff --git a/openmc/deplete/cram.py b/openmc/deplete/cram.py index d0c868004c..184c411bf3 100644 --- a/openmc/deplete/cram.py +++ b/openmc/deplete/cram.py @@ -42,10 +42,14 @@ def deplete(chain, x, rates, dt, matrix_func=None): Updated atom number vectors for each material """ - if not hasattr(chain, "fission_yields"): - fission_yields = repeat(chain.get_thermal_fission_yields()) - else: - fission_yields = chain.fission_yields + fission_yields = chain.fission_yields + if len(fission_yields) == 1: + fission_yields = repeat(fission_yields[0]) + elif len(fission_yields) != len(x): + raise ValueError( + "Number of material fission yield distributions {} is not equal " + "to the number of compositions {}".format(len(fission_yields), + len(x))) # Use multiprocessing pool to distribute work with Pool() as pool: diff --git a/openmc/deplete/nuclide.py b/openmc/deplete/nuclide.py index 615761cde9..5217831f49 100644 --- a/openmc/deplete/nuclide.py +++ b/openmc/deplete/nuclide.py @@ -86,9 +86,9 @@ class Nuclide(object): reactions : list of openmc.deplete.ReactionTuple Reaction information. Each element of the list is a named tuple with attribute 'type', 'target', 'Q', and 'branching_ratio'. - yield_data : dict of float to list - Maps tabulated energy to list of (product, yield) for all - neutron-induced fission products. + yield_data : dict of float to :class:`openmc.deplete.FissionYieldDistribution` + Fission product yields at tabulated energies for this nuclide. Can be + treated as a nested dictionary ``{energy: {product: yield}}`` yield_energies : list of float Energies at which fission product yields exist @@ -300,15 +300,15 @@ class FissionYieldDistribution(Mapping): ------- FissionYieldDistribution """ - yields = {} + all_yields = {} for elem_index, yield_elem in enumerate(element.iter("fission_yields")): energy = float(yield_elem.get("energy")) products = yield_elem.find("products").text.split() - yield_mapobj = map(float, yield_elem.find("data").text.split()) + yields = map(float, yield_elem.find("data").text.split()) # Get a map of products to their corresponding yield - yields[energy] = dict(zip(products, yield_mapobj)) + all_yields[energy] = dict(zip(products, yields)) - return cls.from_dict(yields) + return cls.from_dict(all_yields) @classmethod def from_dict(cls, fission_yields): @@ -327,9 +327,7 @@ class FissionYieldDistribution(Mapping): energies = sorted(fission_yields) # Get a consistent set of products to produce a matrix of yields - shared_prod = set() - for prod_set in map(set, fission_yields.values()): - shared_prod |= prod_set + 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))) @@ -422,6 +420,9 @@ class FissionYield(Mapping): def __iter__(self): return iter(self.products) + def items(self): + return zip(self.products, self.yields) + def __add__(self, other): new = self.copy() new += other diff --git a/tests/unit_tests/test_deplete_chain.py b/tests/unit_tests/test_deplete_chain.py index 2e5ad09832..dcb5127cba 100644 --- a/tests/unit_tests/test_deplete_chain.py +++ b/tests/unit_tests/test_deplete_chain.py @@ -7,7 +7,7 @@ from itertools import product import numpy as np from openmc.data import zam, ATOMIC_SYMBOL -from openmc.deplete import comm, Chain, reaction_rates, nuclide +from openmc.deplete import comm, Chain, reaction_rates, nuclide, cram import pytest from tests import cdtemp @@ -359,3 +359,10 @@ def test_fission_yield_attribute(simple_chain): empty_chain.fission_yields = [thermal_yields] * 2 assert empty_chain.fission_yields[0] == thermal_yields assert empty_chain.fission_yields[1] == thermal_yields + + # test failure with deplete function + # number fission yields != number of materials + dummy_conc = [[1, 2]] * (len(empty_chain.fission_yields) + 1) + with pytest.raises( + ValueError, match="fission yield.*not equal.*compositions"): + cram.deplete(empty_chain, dummy_conc, None, 0.5)