feat: add reactor control persistence and tests
This commit is contained in:
77
src/reactor_sim/state.py
Normal file
77
src/reactor_sim/state.py
Normal file
@@ -0,0 +1,77 @@
|
||||
"""Dataclasses that capture the thermal-hydraulic state of the plant."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass, field, asdict
|
||||
|
||||
|
||||
def clamp(value: float, min_value: float, max_value: float) -> float:
|
||||
return max(min_value, min(max_value, value))
|
||||
|
||||
|
||||
@dataclass
|
||||
class CoreState:
|
||||
fuel_temperature: float # Kelvin
|
||||
neutron_flux: float # neutrons/cm^2-s equivalent
|
||||
reactivity_margin: float # delta rho
|
||||
power_output_mw: float # MW thermal
|
||||
burnup: float # fraction of fuel consumed
|
||||
|
||||
def update_burnup(self, dt: float) -> None:
|
||||
produced_energy_mwh = self.power_output_mw * (dt / 3600.0)
|
||||
self.burnup = clamp(self.burnup + produced_energy_mwh * 1e-5, 0.0, 0.99)
|
||||
|
||||
|
||||
@dataclass
|
||||
class CoolantLoopState:
|
||||
temperature_in: float # K
|
||||
temperature_out: float # K
|
||||
pressure: float # MPa
|
||||
mass_flow_rate: float # kg/s
|
||||
steam_quality: float # fraction of vapor
|
||||
|
||||
def average_temperature(self) -> float:
|
||||
return 0.5 * (self.temperature_in + self.temperature_out)
|
||||
|
||||
|
||||
@dataclass
|
||||
class TurbineState:
|
||||
steam_enthalpy: float # kJ/kg
|
||||
shaft_power_mw: float
|
||||
electrical_output_mw: float
|
||||
condenser_temperature: float
|
||||
load_demand_mw: float = 0.0
|
||||
load_supplied_mw: float = 0.0
|
||||
|
||||
|
||||
@dataclass
|
||||
class PlantState:
|
||||
core: CoreState
|
||||
primary_loop: CoolantLoopState
|
||||
secondary_loop: CoolantLoopState
|
||||
turbine: TurbineState
|
||||
time_elapsed: float = field(default=0.0)
|
||||
|
||||
def snapshot(self) -> dict[str, float]:
|
||||
return {
|
||||
"time_elapsed": self.time_elapsed,
|
||||
"core_temp": self.core.fuel_temperature,
|
||||
"core_power": self.core.power_output_mw,
|
||||
"neutron_flux": self.core.neutron_flux,
|
||||
"primary_outlet_temp": self.primary_loop.temperature_out,
|
||||
"secondary_pressure": self.secondary_loop.pressure,
|
||||
"turbine_electric": self.turbine.electrical_output_mw,
|
||||
}
|
||||
|
||||
def to_dict(self) -> dict:
|
||||
return asdict(self)
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, data: dict) -> "PlantState":
|
||||
return cls(
|
||||
core=CoreState(**data["core"]),
|
||||
primary_loop=CoolantLoopState(**data["primary_loop"]),
|
||||
secondary_loop=CoolantLoopState(**data["secondary_loop"]),
|
||||
turbine=TurbineState(**data["turbine"]),
|
||||
time_elapsed=data.get("time_elapsed", 0.0),
|
||||
)
|
||||
Reference in New Issue
Block a user