feat: add reactor control persistence and tests
This commit is contained in:
56
src/reactor_sim/fuel.py
Normal file
56
src/reactor_sim/fuel.py
Normal file
@@ -0,0 +1,56 @@
|
||||
"""Fuel behavior, burnup, and decay heat modeling."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass, field
|
||||
import logging
|
||||
|
||||
from . import constants
|
||||
from .atomic import Atom, AtomicPhysics, FissionEvent, make_atom
|
||||
from .state import CoreState
|
||||
|
||||
LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def fuel_reactivity_penalty(burnup: float) -> float:
|
||||
"""Simplistic model that penalizes reactivity as burnup increases."""
|
||||
# Burnup is 0-1, penalty grows quadratically to mimic depletion.
|
||||
return 0.4 * burnup**2
|
||||
|
||||
|
||||
def decay_heat_fraction(burnup: float) -> float:
|
||||
"""Return remaining decay heat fraction relative to nominal power."""
|
||||
return min(0.07 + 0.2 * burnup, 0.15)
|
||||
|
||||
|
||||
@dataclass
|
||||
class FuelAssembly:
|
||||
enrichment: float # fraction U-235
|
||||
mass_kg: float
|
||||
fissile_atom: Atom = field(default_factory=lambda: make_atom(92, 143))
|
||||
atomic_physics: AtomicPhysics = field(default_factory=AtomicPhysics)
|
||||
|
||||
def available_energy_j(self, state: CoreState) -> float:
|
||||
fraction_remaining = max(0.0, 1.0 - state.burnup)
|
||||
return self.mass_kg * constants.FUEL_ENERGY_DENSITY * fraction_remaining
|
||||
|
||||
def simulate_electron_hit(self) -> FissionEvent:
|
||||
return self.atomic_physics.electron_induced_fission(self.fissile_atom)
|
||||
|
||||
def prompt_energy_rate(self, flux: float, control_fraction: float) -> tuple[float, FissionEvent]:
|
||||
"""Compute MW thermal from prompt fission by sampling atomic physics."""
|
||||
event = self.simulate_electron_hit()
|
||||
effective_flux = max(0.0, flux * max(0.0, 1.0 - control_fraction))
|
||||
atoms = self.mass_kg / self.fissile_atom.atomic_mass_kg
|
||||
event_rate = effective_flux * constants.ELECTRON_FISSION_CROSS_SECTION * atoms * self.enrichment
|
||||
power_watts = event_rate * event.energy_mev * constants.MEV_TO_J
|
||||
power_mw = power_watts / constants.MEGAWATT
|
||||
LOGGER.debug(
|
||||
"Prompt fission products %s-%d + %s-%d yielding %.2f MW",
|
||||
event.products[0].symbol,
|
||||
event.products[0].mass_number,
|
||||
event.products[1].symbol,
|
||||
event.products[1].mass_number,
|
||||
power_mw,
|
||||
)
|
||||
return max(0.0, power_mw), event
|
||||
Reference in New Issue
Block a user