diff --git a/openmc/deplete/results.py b/openmc/deplete/results.py index adb0d3dbc04..c97de7bec56 100644 --- a/openmc/deplete/results.py +++ b/openmc/deplete/results.py @@ -103,7 +103,8 @@ def get_activity( mat: Material | str, units: str = "Bq/cm3", by_nuclide: bool = False, - volume: float | None = None + volume: float | None = None, + chain=None ) -> tuple[np.ndarray, np.ndarray | list[dict]]: """Get activity of material over time. @@ -122,6 +123,14 @@ def get_activity( volume : float, optional Volume of the material. If not passed, defaults to using the :attr:`Material.volume` attribute. + chain : openmc.deplete.Chain or PathLike, optional + Depletion chain to use for half-life values. If provided, half-life + values from the chain are preferred over the default ENDF/B-VIII.0 + values. Can be a Chain object or path to a chain XML file. For + nuclides not in the chain, the default values are used as a + fallback. + + .. versionadded:: 0.15.1 Returns ------- @@ -133,6 +142,8 @@ def get_activity( by_nuclide = True. """ + from openmc.deplete import Chain + if isinstance(mat, Material): mat_id = str(mat.id) elif isinstance(mat, str): @@ -140,6 +151,9 @@ def get_activity( else: raise TypeError('mat should be of type openmc.Material or str') + if chain is not None and not isinstance(chain, Chain): + chain = Chain.from_xml(chain) + times = np.empty_like(self, dtype=float) if by_nuclide: activities = [None] * len(self) @@ -149,7 +163,8 @@ def get_activity( # Evaluate activity for each depletion time for i, result in enumerate(self): times[i] = result.time[0] - activities[i] = result.get_material(mat_id).get_activity(units, by_nuclide, volume) + activities[i] = result.get_material(mat_id).get_activity( + units, by_nuclide, volume, chain=chain) return times, activities diff --git a/openmc/material.py b/openmc/material.py index eded9c3faa6..ece2af8cecf 100644 --- a/openmc/material.py +++ b/openmc/material.py @@ -1386,7 +1386,9 @@ def get_element_atom_densities(self, element: str | None = None) -> dict[str, fl def get_activity(self, units: str = 'Bq/cm3', by_nuclide: bool = False, - volume: float | None = None) -> dict[str, float] | float: + volume: float | None = None, + chain=None + ) -> dict[str, float] | float: """Return the activity of the material or each nuclide within. .. versionadded:: 0.13.1 @@ -1405,6 +1407,13 @@ def get_activity(self, units: str = 'Bq/cm3', by_nuclide: bool = False, :attr:`Material.volume` attribute. .. versionadded:: 0.13.3 + chain : openmc.deplete.Chain, optional + Depletion chain to use for half-life values. If provided, half-life + values from the chain are preferred over the default ENDF/B-VIII.0 + values. For nuclides not in the chain, the default values are used + as a fallback. + + .. versionadded:: 0.15.1 Returns ------- @@ -1413,6 +1422,7 @@ def get_activity(self, units: str = 'Bq/cm3', by_nuclide: bool = False, names and values are activity is returned. Otherwise the activity of the material is returned as a float. """ + import math cv.check_value('units', units, {'Bq', 'Bq/g', 'Bq/kg', 'Bq/cm3', 'Bq/m3', 'Ci', 'Ci/m3'}) cv.check_type('by_nuclide', by_nuclide, bool) @@ -1438,9 +1448,18 @@ def get_activity(self, units: str = 'Bq/cm3', by_nuclide: bool = False, elif units == 'Ci/m3': multiplier = 1e6 / _BECQUEREL_PER_CURIE + chain_nuclides = {} + if chain is not None: + for nuc in chain.nuclides: + chain_nuclides[nuc.name] = nuc.half_life + activity = {} for nuclide, atoms_per_bcm in self.get_nuclide_atom_densities().items(): - inv_seconds = openmc.data.decay_constant(nuclide) + if nuclide in chain_nuclides and chain_nuclides[nuclide] is not None: + t = chain_nuclides[nuclide] + inv_seconds = math.log(2) / t if t > 0.0 else 0.0 + else: + inv_seconds = openmc.data.decay_constant(nuclide) activity[nuclide] = inv_seconds * 1e24 * atoms_per_bcm * multiplier return activity if by_nuclide else sum(activity.values())