Source code for stream.physical_models.decay_heat.fissions

r"""Functions for creating a fission-following decay heat profile"""

import numpy as np

from stream import Aggregator
from stream.calculations import PointKinetics
from stream.calculations.point_kinetics import ReactivityController
from stream.composition import point_kinetics_steady_state
from stream.units import Array1D, DecayHeatFunction, PerS, Second, Value
from stream.utilities import identity

__all__ = ["profile", "profile_from_pk"]


[docs] def profile( time: Second, generation_time: Second, delayed_neutron_fractions: Array1D, delayed_groups_decay_rates: PerS, controls: ReactivityController | None = None, ) -> DecayHeatFunction: r""" Parameters ---------- time: Second Times on which the calculated profile should rely. generation_time: Second mean time between neutron generations. delayed_neutron_fractions: Array1D the fractional yield of neutrons in defined delay groups. 1$ worth is the total. delayed_groups_decay_rates: PerS each group's decay rate. controls: ReactivityController Reactor reactivity controls Returns ------- DecayHeatFunction The fission time profile :math:`\text{PK}(t, T)` """ pk = PointKinetics( generation_time=generation_time, delayed_neutron_fractions=delayed_neutron_fractions, delayed_groups_decay_rates=delayed_groups_decay_rates, controls=controls, ) agr = Aggregator.from_decoupled(pk, funcs={pk: dict(T=0, t=identity)}) sol = agr.solve( y0 := agr.load(point_kinetics_steady_state(pk, 1e6)), time, yp0=agr.compute(y0, time[0]), eq_type="DAE", ) prompt = agr.at_times(sol, pk, "power") / 1e6 CUTOFF = 1e-12 prompt[prompt < CUTOFF] = 0.0 def _fissions(t: Second, T: Second = np.inf) -> Value: """ Parameters ---------- t: Second Times after shutdown T: Second Operation time Returns ------- Value Profile at times `t` after shutdown """ return np.interp(t, time, prompt) return _fissions
[docs] def profile_from_pk(time: Second, pk: PointKinetics) -> DecayHeatFunction: r""" Parameters ---------- time: Second Times on which the calculated profile should rely. pk: PointKinetics Calculation on which the calculated profile should rely. Returns ------- DecayHeatFunction The fission time profile :math:`\text{PK}(t, T)` """ return profile( time, generation_time=pk.Lambda, delayed_groups_decay_rates=pk.lambdak, delayed_neutron_fractions=pk.betak, input_reactivity_func=pk.input_reactivity, )