Improve generator control and status displays
This commit is contained in:
@@ -44,6 +44,7 @@ class Reactor:
|
||||
turbine_unit_active: list[bool] = field(default_factory=lambda: [True, True, True])
|
||||
shutdown: bool = False
|
||||
meltdown: bool = False
|
||||
generator_auto: bool = True
|
||||
poison_alerts: 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,
|
||||
steam_quality=0.0,
|
||||
)
|
||||
primary_pumps = [PumpState(active=self.primary_pump_active, flow_rate=0.0, pressure=0.5) for _ in range(2)]
|
||||
secondary_pumps = [PumpState(active=self.secondary_pump_active, flow_rate=0.0, pressure=0.5) for _ in range(2)]
|
||||
primary_pumps = [
|
||||
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 = [
|
||||
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
|
||||
]
|
||||
turbine_states = [
|
||||
@@ -218,6 +227,14 @@ class Reactor:
|
||||
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
|
||||
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
|
||||
loop_pressure = max(loop_pressure, pump_state.pressure)
|
||||
state.primary_loop.mass_flow_rate = total_flow
|
||||
@@ -239,6 +256,7 @@ class Reactor:
|
||||
pump_state.pressure = self._ramp_value(
|
||||
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:
|
||||
total_flow = 0.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.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
|
||||
loop_pressure = max(loop_pressure, pump_state.pressure)
|
||||
state.secondary_loop.mass_flow_rate = total_flow
|
||||
@@ -278,6 +304,7 @@ class Reactor:
|
||||
pump_state.pressure = self._ramp_value(
|
||||
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)
|
||||
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]
|
||||
if idx in active_indices:
|
||||
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:
|
||||
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)
|
||||
|
||||
def _reset_turbine_state(self, turbine_state: TurbineState) -> None:
|
||||
@@ -343,6 +375,7 @@ class Reactor:
|
||||
turbine_state.electrical_output_mw = 0.0
|
||||
turbine_state.load_demand_mw = 0.0
|
||||
turbine_state.load_supplied_mw = 0.0
|
||||
turbine_state.status = "OFF"
|
||||
|
||||
@staticmethod
|
||||
def _ramp_value(current: float, target: float, dt: float, time_constant: float) -> float:
|
||||
@@ -405,6 +438,8 @@ class Reactor:
|
||||
self.shutdown = True
|
||||
overrides["rod_fraction"] = self.control.scram()
|
||||
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:
|
||||
self.control.set_power_setpoint(command.power_setpoint)
|
||||
if command.rod_manual is not None:
|
||||
@@ -512,17 +547,18 @@ class Reactor:
|
||||
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)
|
||||
if deficit > 0.0:
|
||||
for idx, gen_state in enumerate(state.generators):
|
||||
if not (gen_state.running or gen_state.starting):
|
||||
self.generators[idx].start(gen_state)
|
||||
deficit -= self.generators[idx].rated_output_mw
|
||||
if deficit <= 0:
|
||||
break
|
||||
elif turbine_electric > aux_demand:
|
||||
for idx, gen_state in enumerate(state.generators):
|
||||
if gen_state.running and not gen_state.starting:
|
||||
self.generators[idx].stop(gen_state)
|
||||
if self.generator_auto:
|
||||
if deficit > 0.0:
|
||||
for idx, gen_state in enumerate(state.generators):
|
||||
if not (gen_state.running or gen_state.starting):
|
||||
self.generators[idx].start(gen_state)
|
||||
deficit -= self.generators[idx].rated_output_mw
|
||||
if deficit <= 0:
|
||||
break
|
||||
elif turbine_electric > aux_demand:
|
||||
for idx, gen_state in enumerate(state.generators):
|
||||
if gen_state.running and not gen_state.starting:
|
||||
self.generators[idx].stop(gen_state)
|
||||
|
||||
total_power = 0.0
|
||||
remaining = max(0.0, aux_demand - turbine_electric)
|
||||
@@ -640,6 +676,7 @@ class Reactor:
|
||||
"turbine_units": self.turbine_unit_active,
|
||||
"shutdown": self.shutdown,
|
||||
"meltdown": self.meltdown,
|
||||
"generator_auto": self.generator_auto,
|
||||
"maintenance_active": list(self.maintenance_active),
|
||||
"generators": [
|
||||
{
|
||||
@@ -648,6 +685,7 @@ class Reactor:
|
||||
"spool_remaining": g.spool_remaining,
|
||||
"power_output_mw": g.power_output_mw,
|
||||
"battery_charge": g.battery_charge,
|
||||
"status": g.status,
|
||||
}
|
||||
for g in state.generators
|
||||
],
|
||||
@@ -671,6 +709,7 @@ class Reactor:
|
||||
self.turbine_active = metadata.get("turbine_active", any(self.turbine_unit_active))
|
||||
self.shutdown = metadata.get("shutdown", self.shutdown)
|
||||
self.meltdown = metadata.get("meltdown", self.meltdown)
|
||||
self.generator_auto = metadata.get("generator_auto", self.generator_auto)
|
||||
maint = metadata.get("maintenance_active")
|
||||
if maint is not None:
|
||||
self.maintenance_active = set(maint)
|
||||
@@ -691,7 +730,12 @@ class Reactor:
|
||||
# Back-fill pump state lists for compatibility.
|
||||
if not plant.primary_pumps or len(plant.primary_pumps) < 2:
|
||||
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)
|
||||
]
|
||||
if not plant.secondary_pumps or len(plant.secondary_pumps) < 2:
|
||||
@@ -700,6 +744,7 @@ class Reactor:
|
||||
active=self.secondary_pump_active,
|
||||
flow_rate=plant.secondary_loop.mass_flow_rate / 2,
|
||||
pressure=plant.secondary_loop.pressure,
|
||||
status="OFF",
|
||||
)
|
||||
for _ in range(2)
|
||||
]
|
||||
@@ -726,6 +771,7 @@ class Reactor:
|
||||
spool_remaining=0.0,
|
||||
power_output_mw=0.0,
|
||||
battery_charge=1.0,
|
||||
status="OFF",
|
||||
)
|
||||
)
|
||||
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.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.status = cfg.get("status", gen_state.status)
|
||||
return plant
|
||||
|
||||
def _handle_heat_sink_loss(self, state: PlantState) -> None:
|
||||
|
||||
Reference in New Issue
Block a user