Improve generator control and status displays
This commit is contained in:
@@ -24,6 +24,7 @@ class ReactorCommand:
|
|||||||
primary_pumps: dict[int, bool] | None = None
|
primary_pumps: dict[int, bool] | None = None
|
||||||
secondary_pumps: dict[int, bool] | None = None
|
secondary_pumps: dict[int, bool] | None = None
|
||||||
generator_units: dict[int, bool] | None = None
|
generator_units: dict[int, bool] | None = None
|
||||||
|
generator_auto: bool | None = None
|
||||||
maintenance_components: tuple[str, ...] = tuple()
|
maintenance_components: tuple[str, ...] = tuple()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ class ReactorDashboard:
|
|||||||
DashboardKey("k", "Toggle secondary pump 2"),
|
DashboardKey("k", "Toggle secondary pump 2"),
|
||||||
DashboardKey("b", "Toggle generator 1"),
|
DashboardKey("b", "Toggle generator 1"),
|
||||||
DashboardKey("v", "Toggle generator 2"),
|
DashboardKey("v", "Toggle generator 2"),
|
||||||
|
DashboardKey("x", "Toggle generator auto"),
|
||||||
DashboardKey("t", "Toggle turbine"),
|
DashboardKey("t", "Toggle turbine"),
|
||||||
DashboardKey("1/2/3", "Toggle turbine units 1-3"),
|
DashboardKey("1/2/3", "Toggle turbine units 1-3"),
|
||||||
DashboardKey("y/u/i", "Maintain turbine 1/2/3"),
|
DashboardKey("y/u/i", "Maintain turbine 1/2/3"),
|
||||||
@@ -146,6 +147,8 @@ class ReactorDashboard:
|
|||||||
self._toggle_generator_unit(0)
|
self._toggle_generator_unit(0)
|
||||||
elif ch in (ord("v"), ord("V")):
|
elif ch in (ord("v"), ord("V")):
|
||||||
self._toggle_generator_unit(1)
|
self._toggle_generator_unit(1)
|
||||||
|
elif ch in (ord("x"), ord("X")):
|
||||||
|
self._queue_command(ReactorCommand(generator_auto=not self.reactor.generator_auto))
|
||||||
elif ch in (ord("t"), ord("T")):
|
elif ch in (ord("t"), ord("T")):
|
||||||
self._queue_command(ReactorCommand(turbine_on=not self.reactor.turbine_active))
|
self._queue_command(ReactorCommand(turbine_on=not self.reactor.turbine_active))
|
||||||
elif ord("1") <= ch <= ord("9"):
|
elif ord("1") <= ch <= ord("9"):
|
||||||
@@ -259,6 +262,7 @@ class ReactorDashboard:
|
|||||||
self.reactor = Reactor.default()
|
self.reactor = Reactor.default()
|
||||||
self.start_state = None
|
self.start_state = None
|
||||||
self.pending_command = None
|
self.pending_command = None
|
||||||
|
self._last_state = None
|
||||||
self.reset_requested = False
|
self.reset_requested = False
|
||||||
self.log_buffer.clear()
|
self.log_buffer.clear()
|
||||||
|
|
||||||
@@ -468,9 +472,15 @@ class ReactorDashboard:
|
|||||||
def _turbine_status_lines(self) -> list[str]:
|
def _turbine_status_lines(self) -> list[str]:
|
||||||
if not self.reactor.turbine_unit_active:
|
if not self.reactor.turbine_unit_active:
|
||||||
return ["n/a"]
|
return ["n/a"]
|
||||||
return [
|
lines: list[str] = []
|
||||||
f"{idx + 1}:{'ON' if active else 'OFF'}" for idx, active in enumerate(self.reactor.turbine_unit_active)
|
for idx, active in enumerate(self.reactor.turbine_unit_active):
|
||||||
]
|
label = f"{idx + 1}:"
|
||||||
|
status = "ON" if active else "OFF"
|
||||||
|
if idx < len(getattr(self._last_state, "turbines", [])):
|
||||||
|
t_state = self._last_state.turbines[idx]
|
||||||
|
status = getattr(t_state, "status", status)
|
||||||
|
lines.append(f"{label}{status}")
|
||||||
|
return lines
|
||||||
|
|
||||||
def _total_load_supplied(self, state: PlantState) -> float:
|
def _total_load_supplied(self, state: PlantState) -> float:
|
||||||
return sum(t.load_supplied_mw for t in state.turbines)
|
return sum(t.load_supplied_mw for t in state.turbines)
|
||||||
@@ -551,7 +561,8 @@ class ReactorDashboard:
|
|||||||
if index >= len(pumps):
|
if index >= len(pumps):
|
||||||
return "n/a"
|
return "n/a"
|
||||||
state = pumps[index]
|
state = pumps[index]
|
||||||
return f"{'ON ' if state.active else 'OFF'} {state.flow_rate:6.0f} kg/s"
|
status = getattr(state, "status", "ON" if state.active else "OFF")
|
||||||
|
return f"{status:<8} {state.flow_rate:6.0f} kg/s"
|
||||||
|
|
||||||
def _current_demand(self) -> float:
|
def _current_demand(self) -> float:
|
||||||
if self.reactor.consumer:
|
if self.reactor.consumer:
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ class GeneratorState:
|
|||||||
spool_remaining: float
|
spool_remaining: float
|
||||||
power_output_mw: float
|
power_output_mw: float
|
||||||
battery_charge: float
|
battery_charge: float
|
||||||
|
status: str = "OFF"
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
@@ -32,6 +33,7 @@ class DieselGenerator:
|
|||||||
return
|
return
|
||||||
state.starting = True
|
state.starting = True
|
||||||
state.spool_remaining = self.spool_time
|
state.spool_remaining = self.spool_time
|
||||||
|
state.status = "STARTING"
|
||||||
LOGGER.info("Generator starting (spool %.0fs)", self.spool_time)
|
LOGGER.info("Generator starting (spool %.0fs)", self.spool_time)
|
||||||
|
|
||||||
def stop(self, state: GeneratorState) -> None:
|
def stop(self, state: GeneratorState) -> None:
|
||||||
@@ -41,6 +43,7 @@ class DieselGenerator:
|
|||||||
state.starting = False
|
state.starting = False
|
||||||
state.spool_remaining = 0.0
|
state.spool_remaining = 0.0
|
||||||
state.power_output_mw = 0.0
|
state.power_output_mw = 0.0
|
||||||
|
state.status = "OFF"
|
||||||
LOGGER.info("Generator stopped")
|
LOGGER.info("Generator stopped")
|
||||||
|
|
||||||
def step(self, state: GeneratorState, load_demand_mw: float, dt: float) -> float:
|
def step(self, state: GeneratorState, load_demand_mw: float, dt: float) -> float:
|
||||||
@@ -51,12 +54,15 @@ class DieselGenerator:
|
|||||||
if state.spool_remaining <= 0.0:
|
if state.spool_remaining <= 0.0:
|
||||||
state.starting = False
|
state.starting = False
|
||||||
state.running = True
|
state.running = True
|
||||||
|
state.status = "RUN"
|
||||||
LOGGER.info("Generator online at %.1f MW", self.rated_output_mw)
|
LOGGER.info("Generator online at %.1f MW", self.rated_output_mw)
|
||||||
elif state.running:
|
elif state.running:
|
||||||
available = self.rated_output_mw
|
available = self.rated_output_mw
|
||||||
state.power_output_mw = min(available, load_demand_mw)
|
state.power_output_mw = min(available, load_demand_mw)
|
||||||
|
state.status = "RUN" if state.power_output_mw > 0 else "IDLE"
|
||||||
else:
|
else:
|
||||||
state.power_output_mw = 0.0
|
state.power_output_mw = 0.0
|
||||||
|
state.status = "OFF"
|
||||||
|
|
||||||
if state.running:
|
if state.running:
|
||||||
state.battery_charge = min(1.0, state.battery_charge + 0.02 * dt)
|
state.battery_charge = min(1.0, state.battery_charge + 0.02 * dt)
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ class Reactor:
|
|||||||
turbine_unit_active: list[bool] = field(default_factory=lambda: [True, True, True])
|
turbine_unit_active: list[bool] = field(default_factory=lambda: [True, True, True])
|
||||||
shutdown: bool = False
|
shutdown: bool = False
|
||||||
meltdown: bool = False
|
meltdown: bool = False
|
||||||
|
generator_auto: bool = True
|
||||||
poison_alerts: set[str] = field(default_factory=set)
|
poison_alerts: set[str] = field(default_factory=set)
|
||||||
maintenance_active: set[str] = field(default_factory=set)
|
maintenance_active: set[str] = field(default_factory=set)
|
||||||
|
|
||||||
@@ -115,10 +116,18 @@ class Reactor:
|
|||||||
mass_flow_rate=0.0,
|
mass_flow_rate=0.0,
|
||||||
steam_quality=0.0,
|
steam_quality=0.0,
|
||||||
)
|
)
|
||||||
primary_pumps = [PumpState(active=self.primary_pump_active, flow_rate=0.0, pressure=0.5) for _ in range(2)]
|
primary_pumps = [
|
||||||
secondary_pumps = [PumpState(active=self.secondary_pump_active, flow_rate=0.0, pressure=0.5) for _ in range(2)]
|
PumpState(active=self.primary_pump_active and self.primary_pump_units[idx], flow_rate=0.0, pressure=0.5)
|
||||||
|
for idx in range(2)
|
||||||
|
]
|
||||||
|
secondary_pumps = [
|
||||||
|
PumpState(active=self.secondary_pump_active and self.secondary_pump_units[idx], flow_rate=0.0, pressure=0.5)
|
||||||
|
for idx in range(2)
|
||||||
|
]
|
||||||
generator_states = [
|
generator_states = [
|
||||||
GeneratorState(running=False, starting=False, spool_remaining=0.0, power_output_mw=0.0, battery_charge=1.0)
|
GeneratorState(
|
||||||
|
running=False, starting=False, spool_remaining=0.0, power_output_mw=0.0, battery_charge=1.0, status="OFF"
|
||||||
|
)
|
||||||
for _ in self.generators
|
for _ in self.generators
|
||||||
]
|
]
|
||||||
turbine_states = [
|
turbine_states = [
|
||||||
@@ -218,6 +227,14 @@ class Reactor:
|
|||||||
pump_state.pressure, desired_pressure, dt, self.primary_pump.spool_time
|
pump_state.pressure, desired_pressure, dt, self.primary_pump.spool_time
|
||||||
)
|
)
|
||||||
pump_state.active = (unit_enabled and power_ratio > 0.05) or pump_state.flow_rate > 1.0
|
pump_state.active = (unit_enabled and power_ratio > 0.05) or pump_state.flow_rate > 1.0
|
||||||
|
if unit_enabled and pump_state.flow_rate < max(1.0, desired_flow * 0.8):
|
||||||
|
pump_state.status = "STARTING"
|
||||||
|
elif not unit_enabled and pump_state.flow_rate > 1.0:
|
||||||
|
pump_state.status = "STOPPING"
|
||||||
|
elif pump_state.active:
|
||||||
|
pump_state.status = "RUN"
|
||||||
|
else:
|
||||||
|
pump_state.status = "OFF"
|
||||||
total_flow += pump_state.flow_rate
|
total_flow += pump_state.flow_rate
|
||||||
loop_pressure = max(loop_pressure, pump_state.pressure)
|
loop_pressure = max(loop_pressure, pump_state.pressure)
|
||||||
state.primary_loop.mass_flow_rate = total_flow
|
state.primary_loop.mass_flow_rate = total_flow
|
||||||
@@ -239,6 +256,7 @@ class Reactor:
|
|||||||
pump_state.pressure = self._ramp_value(
|
pump_state.pressure = self._ramp_value(
|
||||||
pump_state.pressure, state.primary_loop.pressure, dt, self.primary_pump.spool_time
|
pump_state.pressure, state.primary_loop.pressure, dt, self.primary_pump.spool_time
|
||||||
)
|
)
|
||||||
|
pump_state.status = "STOPPING" if pump_state.flow_rate > 0 else "OFF"
|
||||||
if self.secondary_pump_active:
|
if self.secondary_pump_active:
|
||||||
total_flow = 0.0
|
total_flow = 0.0
|
||||||
target_pressure = 12.0 * 0.75 + 2.0
|
target_pressure = 12.0 * 0.75 + 2.0
|
||||||
@@ -257,6 +275,14 @@ class Reactor:
|
|||||||
pump_state.pressure, desired_pressure, dt, self.secondary_pump.spool_time
|
pump_state.pressure, desired_pressure, dt, self.secondary_pump.spool_time
|
||||||
)
|
)
|
||||||
pump_state.active = unit_enabled or pump_state.flow_rate > 1.0
|
pump_state.active = unit_enabled or pump_state.flow_rate > 1.0
|
||||||
|
if unit_enabled and pump_state.flow_rate < max(1.0, desired_flow * 0.8):
|
||||||
|
pump_state.status = "STARTING"
|
||||||
|
elif not unit_enabled and pump_state.flow_rate > 1.0:
|
||||||
|
pump_state.status = "STOPPING"
|
||||||
|
elif pump_state.active:
|
||||||
|
pump_state.status = "RUN"
|
||||||
|
else:
|
||||||
|
pump_state.status = "OFF"
|
||||||
total_flow += pump_state.flow_rate
|
total_flow += pump_state.flow_rate
|
||||||
loop_pressure = max(loop_pressure, pump_state.pressure)
|
loop_pressure = max(loop_pressure, pump_state.pressure)
|
||||||
state.secondary_loop.mass_flow_rate = total_flow
|
state.secondary_loop.mass_flow_rate = total_flow
|
||||||
@@ -278,6 +304,7 @@ class Reactor:
|
|||||||
pump_state.pressure = self._ramp_value(
|
pump_state.pressure = self._ramp_value(
|
||||||
pump_state.pressure, state.secondary_loop.pressure, dt, self.secondary_pump.spool_time
|
pump_state.pressure, state.secondary_loop.pressure, dt, self.secondary_pump.spool_time
|
||||||
)
|
)
|
||||||
|
pump_state.status = "STOPPING" if pump_state.flow_rate > 0 else "OFF"
|
||||||
|
|
||||||
self.thermal.step_core(state.core, state.primary_loop, total_power, dt)
|
self.thermal.step_core(state.core, state.primary_loop, total_power, dt)
|
||||||
if not self.secondary_pump_active or state.secondary_loop.mass_flow_rate <= 1.0:
|
if not self.secondary_pump_active or state.secondary_loop.mass_flow_rate <= 1.0:
|
||||||
@@ -334,8 +361,13 @@ class Reactor:
|
|||||||
turbine_state = state.turbines[idx]
|
turbine_state = state.turbines[idx]
|
||||||
if idx in active_indices:
|
if idx in active_indices:
|
||||||
turbine.step(state.secondary_loop, turbine_state, steam_power_mw=power_per_unit, dt=dt)
|
turbine.step(state.secondary_loop, turbine_state, steam_power_mw=power_per_unit, dt=dt)
|
||||||
|
if turbine_state.electrical_output_mw < max(1.0, power_per_unit * 0.7):
|
||||||
|
turbine_state.status = "STARTING"
|
||||||
|
else:
|
||||||
|
turbine_state.status = "RUN"
|
||||||
else:
|
else:
|
||||||
self._spin_down_turbine(turbine_state, dt, turbine.spool_time)
|
self._spin_down_turbine(turbine_state, dt, turbine.spool_time)
|
||||||
|
turbine_state.status = "STOPPING" if turbine_state.electrical_output_mw > 0 else "OFF"
|
||||||
self._dispatch_consumer_load(state, active_indices)
|
self._dispatch_consumer_load(state, active_indices)
|
||||||
|
|
||||||
def _reset_turbine_state(self, turbine_state: TurbineState) -> None:
|
def _reset_turbine_state(self, turbine_state: TurbineState) -> None:
|
||||||
@@ -343,6 +375,7 @@ class Reactor:
|
|||||||
turbine_state.electrical_output_mw = 0.0
|
turbine_state.electrical_output_mw = 0.0
|
||||||
turbine_state.load_demand_mw = 0.0
|
turbine_state.load_demand_mw = 0.0
|
||||||
turbine_state.load_supplied_mw = 0.0
|
turbine_state.load_supplied_mw = 0.0
|
||||||
|
turbine_state.status = "OFF"
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _ramp_value(current: float, target: float, dt: float, time_constant: float) -> float:
|
def _ramp_value(current: float, target: float, dt: float, time_constant: float) -> float:
|
||||||
@@ -405,6 +438,8 @@ class Reactor:
|
|||||||
self.shutdown = True
|
self.shutdown = True
|
||||||
overrides["rod_fraction"] = self.control.scram()
|
overrides["rod_fraction"] = self.control.scram()
|
||||||
self._set_turbine_state(False)
|
self._set_turbine_state(False)
|
||||||
|
if command.generator_auto is not None:
|
||||||
|
self.generator_auto = command.generator_auto
|
||||||
if command.power_setpoint is not None:
|
if command.power_setpoint is not None:
|
||||||
self.control.set_power_setpoint(command.power_setpoint)
|
self.control.set_power_setpoint(command.power_setpoint)
|
||||||
if command.rod_manual is not None:
|
if command.rod_manual is not None:
|
||||||
@@ -512,6 +547,7 @@ class Reactor:
|
|||||||
GeneratorState(running=False, starting=False, spool_remaining=0.0, power_output_mw=0.0, battery_charge=1.0)
|
GeneratorState(running=False, starting=False, spool_remaining=0.0, power_output_mw=0.0, battery_charge=1.0)
|
||||||
)
|
)
|
||||||
deficit = max(0.0, aux_demand - turbine_electric)
|
deficit = max(0.0, aux_demand - turbine_electric)
|
||||||
|
if self.generator_auto:
|
||||||
if deficit > 0.0:
|
if deficit > 0.0:
|
||||||
for idx, gen_state in enumerate(state.generators):
|
for idx, gen_state in enumerate(state.generators):
|
||||||
if not (gen_state.running or gen_state.starting):
|
if not (gen_state.running or gen_state.starting):
|
||||||
@@ -640,6 +676,7 @@ class Reactor:
|
|||||||
"turbine_units": self.turbine_unit_active,
|
"turbine_units": self.turbine_unit_active,
|
||||||
"shutdown": self.shutdown,
|
"shutdown": self.shutdown,
|
||||||
"meltdown": self.meltdown,
|
"meltdown": self.meltdown,
|
||||||
|
"generator_auto": self.generator_auto,
|
||||||
"maintenance_active": list(self.maintenance_active),
|
"maintenance_active": list(self.maintenance_active),
|
||||||
"generators": [
|
"generators": [
|
||||||
{
|
{
|
||||||
@@ -648,6 +685,7 @@ class Reactor:
|
|||||||
"spool_remaining": g.spool_remaining,
|
"spool_remaining": g.spool_remaining,
|
||||||
"power_output_mw": g.power_output_mw,
|
"power_output_mw": g.power_output_mw,
|
||||||
"battery_charge": g.battery_charge,
|
"battery_charge": g.battery_charge,
|
||||||
|
"status": g.status,
|
||||||
}
|
}
|
||||||
for g in state.generators
|
for g in state.generators
|
||||||
],
|
],
|
||||||
@@ -671,6 +709,7 @@ class Reactor:
|
|||||||
self.turbine_active = metadata.get("turbine_active", any(self.turbine_unit_active))
|
self.turbine_active = metadata.get("turbine_active", any(self.turbine_unit_active))
|
||||||
self.shutdown = metadata.get("shutdown", self.shutdown)
|
self.shutdown = metadata.get("shutdown", self.shutdown)
|
||||||
self.meltdown = metadata.get("meltdown", self.meltdown)
|
self.meltdown = metadata.get("meltdown", self.meltdown)
|
||||||
|
self.generator_auto = metadata.get("generator_auto", self.generator_auto)
|
||||||
maint = metadata.get("maintenance_active")
|
maint = metadata.get("maintenance_active")
|
||||||
if maint is not None:
|
if maint is not None:
|
||||||
self.maintenance_active = set(maint)
|
self.maintenance_active = set(maint)
|
||||||
@@ -691,7 +730,12 @@ class Reactor:
|
|||||||
# Back-fill pump state lists for compatibility.
|
# Back-fill pump state lists for compatibility.
|
||||||
if not plant.primary_pumps or len(plant.primary_pumps) < 2:
|
if not plant.primary_pumps or len(plant.primary_pumps) < 2:
|
||||||
plant.primary_pumps = [
|
plant.primary_pumps = [
|
||||||
PumpState(active=self.primary_pump_active, flow_rate=plant.primary_loop.mass_flow_rate / 2, pressure=plant.primary_loop.pressure)
|
PumpState(
|
||||||
|
active=self.primary_pump_active,
|
||||||
|
flow_rate=plant.primary_loop.mass_flow_rate / 2,
|
||||||
|
pressure=plant.primary_loop.pressure,
|
||||||
|
status="OFF",
|
||||||
|
)
|
||||||
for _ in range(2)
|
for _ in range(2)
|
||||||
]
|
]
|
||||||
if not plant.secondary_pumps or len(plant.secondary_pumps) < 2:
|
if not plant.secondary_pumps or len(plant.secondary_pumps) < 2:
|
||||||
@@ -700,6 +744,7 @@ class Reactor:
|
|||||||
active=self.secondary_pump_active,
|
active=self.secondary_pump_active,
|
||||||
flow_rate=plant.secondary_loop.mass_flow_rate / 2,
|
flow_rate=plant.secondary_loop.mass_flow_rate / 2,
|
||||||
pressure=plant.secondary_loop.pressure,
|
pressure=plant.secondary_loop.pressure,
|
||||||
|
status="OFF",
|
||||||
)
|
)
|
||||||
for _ in range(2)
|
for _ in range(2)
|
||||||
]
|
]
|
||||||
@@ -726,6 +771,7 @@ class Reactor:
|
|||||||
spool_remaining=0.0,
|
spool_remaining=0.0,
|
||||||
power_output_mw=0.0,
|
power_output_mw=0.0,
|
||||||
battery_charge=1.0,
|
battery_charge=1.0,
|
||||||
|
status="OFF",
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
for idx, gen_state in enumerate(plant.generators):
|
for idx, gen_state in enumerate(plant.generators):
|
||||||
@@ -736,6 +782,7 @@ class Reactor:
|
|||||||
gen_state.spool_remaining = cfg.get("spool_remaining", gen_state.spool_remaining)
|
gen_state.spool_remaining = cfg.get("spool_remaining", gen_state.spool_remaining)
|
||||||
gen_state.power_output_mw = cfg.get("power_output_mw", gen_state.power_output_mw)
|
gen_state.power_output_mw = cfg.get("power_output_mw", gen_state.power_output_mw)
|
||||||
gen_state.battery_charge = cfg.get("battery_charge", gen_state.battery_charge)
|
gen_state.battery_charge = cfg.get("battery_charge", gen_state.battery_charge)
|
||||||
|
gen_state.status = cfg.get("status", gen_state.status)
|
||||||
return plant
|
return plant
|
||||||
|
|
||||||
def _handle_heat_sink_loss(self, state: PlantState) -> None:
|
def _handle_heat_sink_loss(self, state: PlantState) -> None:
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ class TurbineState:
|
|||||||
condenser_temperature: float
|
condenser_temperature: float
|
||||||
load_demand_mw: float = 0.0
|
load_demand_mw: float = 0.0
|
||||||
load_supplied_mw: float = 0.0
|
load_supplied_mw: float = 0.0
|
||||||
|
status: str = "OFF"
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
@@ -61,6 +62,7 @@ class PumpState:
|
|||||||
active: bool
|
active: bool
|
||||||
flow_rate: float
|
flow_rate: float
|
||||||
pressure: float
|
pressure: float
|
||||||
|
status: str = "OFF"
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
|
|||||||
@@ -206,6 +206,30 @@ def test_generator_spools_and_powers_pumps():
|
|||||||
assert state.primary_loop.mass_flow_rate > 0.0
|
assert state.primary_loop.mass_flow_rate > 0.0
|
||||||
|
|
||||||
|
|
||||||
|
def test_generator_manual_mode_allows_single_unit_and_stop():
|
||||||
|
reactor = Reactor.default()
|
||||||
|
state = reactor.initial_state()
|
||||||
|
reactor.shutdown = False
|
||||||
|
reactor.control.manual_control = True
|
||||||
|
reactor.control.rod_fraction = 0.95
|
||||||
|
reactor.generator_auto = False
|
||||||
|
reactor.primary_pump_units = [True, False]
|
||||||
|
reactor.secondary_pump_units = [False, False]
|
||||||
|
|
||||||
|
reactor.step(state, dt=1.0, command=ReactorCommand(generator_units={1: True}, primary_pumps={1: True}))
|
||||||
|
assert state.generators[0].starting or state.generators[0].running
|
||||||
|
|
||||||
|
for _ in range(15):
|
||||||
|
reactor.step(state, dt=1.0)
|
||||||
|
|
||||||
|
assert state.generators[0].running is True
|
||||||
|
reactor.step(state, dt=1.0, command=ReactorCommand(generator_units={1: False}))
|
||||||
|
for _ in range(5):
|
||||||
|
reactor.step(state, dt=1.0)
|
||||||
|
assert state.generators[0].running is False
|
||||||
|
assert state.generators[1].running is False
|
||||||
|
|
||||||
|
|
||||||
def test_meltdown_triggers_shutdown():
|
def test_meltdown_triggers_shutdown():
|
||||||
reactor = Reactor.default()
|
reactor = Reactor.default()
|
||||||
state = reactor.initial_state()
|
state = reactor.initial_state()
|
||||||
|
|||||||
Reference in New Issue
Block a user