From 46ce147a81c963f23150c9bf4b1d77baf520eb67 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Tue, 13 Aug 2019 17:47:34 -0500 Subject: [PATCH] Revert ebf2f25ab and add from_operator class method TalliedFissionYieldHelper instances must be passed the number of burnable materials at construction again. To make things easier for the Operator, a from_operator class method has been added to the FissionYieldHelper and TalliedFissionYieldHelper abstract classes, as well as more explicit versions on the ConstantFissionYieldHelper and FissionYieldCutoffHelper. All have the call signature cls.from_operator(operator, **kwargs) The concrete classes have explicitely declared what the allowed key word arguments are, while the abstract classes forward kwargs directly onto __init__. All explicit keyword arguments should have a counterpart in the __init__ method. --- openmc/deplete/abc.py | 51 ++++++++++++++++++++++++-------------- openmc/deplete/helpers.py | 48 +++++++++++++++++++++++++++++++++++ openmc/deplete/operator.py | 11 +++----- 3 files changed, 85 insertions(+), 25 deletions(-) diff --git a/openmc/deplete/abc.py b/openmc/deplete/abc.py index 7f6de6d62e..5efda87029 100644 --- a/openmc/deplete/abc.py +++ b/openmc/deplete/abc.py @@ -466,6 +466,20 @@ class FissionYieldHelper(ABC): """ return tuple(sorted(self._chain_set & set(nuclides))) + @classmethod + def from_operator(cls, operator, **kwargs): + """Create a new instance by pulling data from the operator + + Parameters + ---------- + operator : openmc.deplete.TransportOperator + Operator with a depletion chain + kwargs: optional + Optional keyword arguments to be passed to the underlying + ``__init__`` method + """ + return cls(operator.chain.nuclides, **kwargs) + class TalliedFissionYieldHelper(FissionYieldHelper): """Abstract class for computing fission yields with tallies @@ -480,14 +494,13 @@ class TalliedFissionYieldHelper(FissionYieldHelper): chain_nuclides : iterable of openmc.deplete.Nuclide Nuclides tracked in the depletion chain. Not necessary that all have yield data. - n_bmats : int, optional + n_bmats : int Number of burnable materials tracked in the problem. Attributes ---------- n_bmats : int Number of burnable materials tracked in the problem. - Must be set prior to generating tallies constant_yields : dict of str to :class:`openmc.deplete.FissionYield` Fission yields for all nuclides that only have one set of fission yield data. Can be accessed as ``{parent: {product: yield}}`` @@ -495,26 +508,13 @@ class TalliedFissionYieldHelper(FissionYieldHelper): _upper_energy = 20.0e6 # upper energy for tallies - def __init__(self, chain_nuclides, n_bmats=None): + def __init__(self, chain_nuclides, n_bmats): super().__init__(chain_nuclides) self.n_bmats = n_bmats self._local_indexes = None self._fission_rate_tally = None self._tally_index = {} - @property - def n_bmats(self): - return self._n_bmats - - @n_bmats.setter - def n_bmats(self, value): - if value is None: - self._n_bmats = None - return - check_type("n_bmats", value, Integral) - check_greater_than("n_bmats", value, 0) - sef._n_bmats = value - def generate_tallies(self, materials, mat_indexes): """Construct the fission rate tally @@ -526,8 +526,6 @@ class TalliedFissionYieldHelper(FissionYieldHelper): Indexes for materials in ``materials`` tracked on this process """ - if self._n_bmat is None: - raise AttributeError("Number of burnable materials is not set") self._local_indexes = asarray(mat_indexes) # Tally group-wise fission reaction rates @@ -571,6 +569,23 @@ class TalliedFissionYieldHelper(FissionYieldHelper): tally data. """ + @classmethod + def from_operator(cls, operator, **kwargs): + """Create a new instance by pulling data from the operator + + Require the more concrete :class:`openmc.deplete.Operator` + because this needs knowledge of burnable materials + + Parameters + ---------- + operator : openmc.deplete.TransportOperator + Operator with a depletion chain + kwargs: optional + Optional keyword arguments to be passed to the underlying + ``__init__`` method + """ + return cls(operator.chain.nuclides, len(operator.burnable_mats), + **kwargs) class Integrator(ABC): """Abstract class for solving the time-integration for depletion diff --git a/openmc/deplete/helpers.py b/openmc/deplete/helpers.py index d6051c6dd3..b66c9ba5e7 100644 --- a/openmc/deplete/helpers.py +++ b/openmc/deplete/helpers.py @@ -202,6 +202,24 @@ class ConstantFissionYieldHelper(FissionYieldHelper): self._constant_yields[name] = ( nuc.yield_data[nuc.yield_energies[min_index]]) + @classmethod + def from_operator(cls, operator, energy=0.0253): + """Return a new ConstantFissionYieldHelper using operator data + + Parameters + ---------- + operator : openmc.deplete.TransportOperator + operator with a depletion chain + energy : float, optional + Energy for default fission yield libraries for nuclides with + multiple sets of yield data + + Returns + ------- + ConstantFissionYieldHelper + """ + return cls(operator.chain.nuclides, energy=energy) + @property def energy(self): return self._energy @@ -302,6 +320,36 @@ class FissionYieldCutoffHelper(TalliedFissionYieldHelper): self._thermal_yields[name] = thermal self._fast_yields[name] = fast + @classmethod + def from_operator(cls, operator, cutoff=112.0, + thermal_energy=0.0253, fast_energy=500e3): + """Construct a helper from an operator + + All keyword arguments are identical to their counterpart + in the main ``__init__`` method + + Parameters + ---------- + operator : openmc.deplete.Operator + Operator with a chain and burnable materials + cutoff : float, optional + Cutoff energy for tallying fast and thermal fissions + thermal_energy : float, optional + Energy to use when pulling thermal fission yields from + nuclides with multiple sets of yields + fast_energy : float, optional + Energy to use when pulling fast fission yields from + nuclides with multiple sets of yields + + Returns + ------- + FissionYieldCutoffHelper + + """ + return cls(operator.chain.nuclides, len(operator.burnable_mats), + cutoff=cutoff, thermal_energy=thermal_energy, + fast_energy=fast_energy) + @staticmethod def _find_fallback_energy(name, energies, cutoff, check_under): cutoff_func = operator.ge if check_under else operator.le diff --git a/openmc/deplete/operator.py b/openmc/deplete/operator.py index 11fded8e44..e967dc85d1 100644 --- a/openmc/deplete/operator.py +++ b/openmc/deplete/operator.py @@ -209,13 +209,10 @@ class Operator(TransportOperator): # Select and create fission yield helper fission_helper = self._fission_helpers_[fission_yield_mode] - if fission_yield_opts is None: - self._fsn_yield_helper = fission_helper(self.chain.nuclides) - else: - self._fsn_yield_helper = fission_yield_mode( - self.chain.nuclides, **fission_yield_opts) - if hasattr(self._fsn_yield_helper, "n_bmats"): - self._fsn_yield_helper.n_bmats = len(self.burnable_mats) + fission_yield_opts = ( + {} if fission_yield_opts is None else fission_yield_opts) + self._fsn_yield_helper = fission_helper.from_operator( + self, **fission_yield_opts) def __call__(self, vec, power): """Runs a simulation.