Add generator power model and meltdown handling
This commit is contained in:
@@ -53,8 +53,12 @@ class HealthMonitor:
|
||||
def __init__(self) -> None:
|
||||
self.components: Dict[str, ComponentHealth] = {
|
||||
"core": ComponentHealth("core"),
|
||||
"primary_pump": ComponentHealth("primary_pump"),
|
||||
"secondary_pump": ComponentHealth("secondary_pump"),
|
||||
"primary_pump_1": ComponentHealth("primary_pump_1"),
|
||||
"primary_pump_2": ComponentHealth("primary_pump_2"),
|
||||
"secondary_pump_1": ComponentHealth("secondary_pump_1"),
|
||||
"secondary_pump_2": ComponentHealth("secondary_pump_2"),
|
||||
"generator_1": ComponentHealth("generator_1"),
|
||||
"generator_2": ComponentHealth("generator_2"),
|
||||
}
|
||||
for idx in range(3):
|
||||
name = f"turbine_{idx + 1}"
|
||||
@@ -67,32 +71,48 @@ class HealthMonitor:
|
||||
def evaluate(
|
||||
self,
|
||||
state: PlantState,
|
||||
primary_active: bool,
|
||||
secondary_active: bool,
|
||||
primary_units: Iterable[bool],
|
||||
secondary_units: Iterable[bool],
|
||||
turbine_active: Iterable[bool],
|
||||
generator_states: Iterable,
|
||||
dt: float,
|
||||
) -> List[str]:
|
||||
events: list[str] = []
|
||||
turbine_flags = list(turbine_active)
|
||||
core = self.component("core")
|
||||
core_temp = state.core.fuel_temperature
|
||||
temp_stress = max(0.0, (core_temp - 900.0) / (constants.MAX_CORE_TEMPERATURE - 900.0))
|
||||
temp_stress = max(0.0, (core_temp - 900.0) / max(1e-6, (constants.MAX_CORE_TEMPERATURE - 900.0)))
|
||||
base_degrade = 0.0001 * dt
|
||||
core.degrade(base_degrade + temp_stress * 0.01 * dt)
|
||||
|
||||
if primary_active:
|
||||
primary_flow = state.primary_loop.mass_flow_rate
|
||||
flow_ratio = 0.0 if primary_flow <= 0 else min(1.0, primary_flow / 18_000.0)
|
||||
self.component("primary_pump").degrade((0.0002 + (1 - flow_ratio) * 0.005) * dt)
|
||||
else:
|
||||
self.component("primary_pump").degrade(0.0)
|
||||
prim_units = list(primary_units)
|
||||
sec_units = list(secondary_units)
|
||||
prim_states = state.primary_pumps or []
|
||||
sec_states = state.secondary_pumps or []
|
||||
for idx, active in enumerate(prim_units):
|
||||
comp = self.component(f"primary_pump_{idx + 1}")
|
||||
if idx < len(prim_states) and active:
|
||||
flow = prim_states[idx].flow_rate
|
||||
flow_ratio = 0.0 if flow <= 0 else min(1.0, flow / 9_000.0)
|
||||
comp.degrade((0.0002 + (1 - flow_ratio) * 0.005) * dt)
|
||||
else:
|
||||
comp.degrade(0.0)
|
||||
for idx, active in enumerate(sec_units):
|
||||
comp = self.component(f"secondary_pump_{idx + 1}")
|
||||
if idx < len(sec_states) and active:
|
||||
flow = sec_states[idx].flow_rate
|
||||
flow_ratio = 0.0 if flow <= 0 else min(1.0, flow / 8_000.0)
|
||||
comp.degrade((0.0002 + (1 - flow_ratio) * 0.004) * dt)
|
||||
else:
|
||||
comp.degrade(0.0)
|
||||
|
||||
if secondary_active:
|
||||
secondary_flow = state.secondary_loop.mass_flow_rate
|
||||
flow_ratio = 0.0 if secondary_flow <= 0 else min(1.0, secondary_flow / 16_000.0)
|
||||
self.component("secondary_pump").degrade((0.0002 + (1 - flow_ratio) * 0.004) * dt)
|
||||
else:
|
||||
self.component("secondary_pump").degrade(0.0)
|
||||
for idx, gen_state in enumerate(generator_states):
|
||||
comp = self.component(f"generator_{idx + 1}")
|
||||
running = getattr(gen_state, "running", False) or getattr(gen_state, "starting", False)
|
||||
if running:
|
||||
comp.degrade(0.00015 * dt)
|
||||
else:
|
||||
comp.degrade(0.0)
|
||||
|
||||
turbines = state.turbines if hasattr(state, "turbines") else []
|
||||
for idx, active in enumerate(turbine_flags):
|
||||
@@ -126,6 +146,11 @@ class HealthMonitor:
|
||||
mapped = "turbine_1" if name == "turbine" else name
|
||||
if mapped in self.components:
|
||||
self.components[mapped] = ComponentHealth.from_snapshot(comp_data)
|
||||
elif mapped == "primary_pump":
|
||||
self.components["primary_pump_1"] = ComponentHealth.from_snapshot(comp_data)
|
||||
self.components["primary_pump_2"] = ComponentHealth.from_snapshot(comp_data)
|
||||
elif mapped == "secondary_pump":
|
||||
self.components["secondary_pump_1"] = ComponentHealth.from_snapshot(comp_data)
|
||||
|
||||
def maintain(self, component: str, amount: float = 0.05) -> bool:
|
||||
comp = self.components.get(component)
|
||||
|
||||
Reference in New Issue
Block a user