Improve reactor controls, reactions, and maintenance UI
This commit is contained in:
@@ -39,6 +39,7 @@ class Reactor:
|
||||
turbine_active: bool = True
|
||||
turbine_unit_active: list[bool] = field(default_factory=lambda: [True, True, True])
|
||||
shutdown: bool = False
|
||||
poison_alerts: set[str] = field(default_factory=set)
|
||||
|
||||
def __post_init__(self) -> None:
|
||||
if not self.turbines:
|
||||
@@ -72,6 +73,8 @@ class Reactor:
|
||||
reactivity_margin=-0.02,
|
||||
power_output_mw=0.1,
|
||||
burnup=0.0,
|
||||
fission_product_inventory={},
|
||||
emitted_particles={},
|
||||
)
|
||||
primary = CoolantLoopState(
|
||||
temperature_in=ambient,
|
||||
@@ -111,15 +114,28 @@ class Reactor:
|
||||
overrides = self._apply_command(command, state)
|
||||
rod_fraction = overrides.get("rod_fraction", rod_fraction)
|
||||
|
||||
self.neutronics.step(state.core, rod_fraction, dt)
|
||||
decay_power, decay_neutron_source, decay_products, decay_particles = self.fuel.decay_reaction_effects(
|
||||
state.core
|
||||
)
|
||||
self.neutronics.step(state.core, rod_fraction, dt, external_source_rate=decay_neutron_source)
|
||||
|
||||
prompt_power, fission_rate, fission_event = self.fuel.prompt_energy_rate(
|
||||
state.core.neutron_flux, rod_fraction
|
||||
)
|
||||
decay_power = decay_heat_fraction(state.core.burnup) * state.core.power_output_mw
|
||||
total_power = prompt_power + decay_power
|
||||
decay_heat = decay_heat_fraction(state.core.burnup) * state.core.power_output_mw
|
||||
total_power = prompt_power + decay_heat + decay_power
|
||||
state.core.power_output_mw = total_power
|
||||
state.core.update_burnup(dt)
|
||||
# Track fission products and emitted particles for diagnostics.
|
||||
products: dict[str, float] = {}
|
||||
for atom in fission_event.products:
|
||||
products[atom.symbol] = products.get(atom.symbol, 0.0) + fission_rate * dt
|
||||
for k, v in decay_products.items():
|
||||
products[k] = products.get(k, 0.0) + v * dt
|
||||
particles: dict[str, float] = {k: v * dt for k, v in decay_particles.items()}
|
||||
state.core.add_products(products)
|
||||
state.core.add_emitted_particles(particles)
|
||||
self._check_poison_alerts(state)
|
||||
|
||||
pump_demand = overrides.get("coolant_demand", self.control.coolant_demand(state.primary_loop))
|
||||
if self.primary_pump_active:
|
||||
@@ -371,3 +387,11 @@ class Reactor:
|
||||
)
|
||||
)
|
||||
return plant
|
||||
|
||||
def _check_poison_alerts(self, state: PlantState) -> None:
|
||||
inventory = state.core.fission_product_inventory or {}
|
||||
for symbol, threshold in constants.KEY_POISON_THRESHOLDS.items():
|
||||
amount = inventory.get(symbol, 0.0)
|
||||
if amount >= threshold and symbol not in self.poison_alerts:
|
||||
self.poison_alerts.add(symbol)
|
||||
LOGGER.warning("Poison level high: %s inventory %.2e exceeds %.2e", symbol, amount, threshold)
|
||||
|
||||
Reference in New Issue
Block a user