feat: link turbine output to transferred heat

This commit is contained in:
Andrii Prokhorov
2025-11-21 18:15:11 +02:00
parent 4873777ba8
commit 5c0ad3fb72
4 changed files with 23 additions and 12 deletions

View File

@@ -14,6 +14,7 @@ class ElectricalConsumer:
demand_mw: float demand_mw: float
online: bool = False online: bool = False
power_received_mw: float = 0.0 power_received_mw: float = 0.0
_under_supply_logged: bool = False
def request_power(self) -> float: def request_power(self) -> float:
return self.demand_mw if self.online else 0.0 return self.demand_mw if self.online else 0.0
@@ -30,11 +31,16 @@ class ElectricalConsumer:
def update_power_received(self, supplied_mw: float) -> None: def update_power_received(self, supplied_mw: float) -> None:
self.power_received_mw = supplied_mw self.power_received_mw = supplied_mw
if supplied_mw < self.request_power(): if supplied_mw + 1e-6 < self.request_power():
LOGGER.warning( if not self._under_supply_logged:
"%s under-supplied: %.1f/%.1f MW", LOGGER.warning(
self.name, "%s under-supplied: %.1f/%.1f MW",
supplied_mw, self.name,
self.request_power(), supplied_mw,
) self.request_power(),
)
self._under_supply_logged = True
else:
if self._under_supply_logged:
LOGGER.info("%s demand satisfied", self.name)
self._under_supply_logged = False

View File

@@ -127,7 +127,7 @@ class Reactor:
self.thermal.step_secondary(state.secondary_loop, transferred) self.thermal.step_secondary(state.secondary_loop, transferred)
if self.turbine_active: if self.turbine_active:
self.turbine.step(state.secondary_loop, state.turbine, self.consumer) self.turbine.step(state.secondary_loop, state.turbine, self.consumer, steam_power_mw=transferred)
else: else:
state.turbine.shaft_power_mw = 0.0 state.turbine.shaft_power_mw = 0.0
state.turbine.electrical_output_mw = 0.0 state.turbine.electrical_output_mw = 0.0

View File

@@ -5,6 +5,8 @@ from __future__ import annotations
from dataclasses import dataclass from dataclasses import dataclass
import logging import logging
import math
from . import constants from . import constants
from .state import CoolantLoopState, CoreState from .state import CoolantLoopState, CoreState
@@ -14,8 +16,9 @@ LOGGER = logging.getLogger(__name__)
def heat_transfer(primary: CoolantLoopState, secondary: CoolantLoopState, core_power_mw: float) -> float: def heat_transfer(primary: CoolantLoopState, secondary: CoolantLoopState, core_power_mw: float) -> float:
"""Return MW transferred to the secondary loop.""" """Return MW transferred to the secondary loop."""
delta_t = max(0.0, primary.temperature_out - secondary.temperature_in) delta_t = max(0.0, primary.temperature_out - secondary.temperature_in)
conductance = 0.05 # steam generator effectiveness conductance = 0.15 # steam generator effectiveness
transferred = min(core_power_mw, conductance * delta_t) efficiency = 1.0 - math.exp(-conductance * delta_t)
transferred = min(core_power_mw, core_power_mw * efficiency)
LOGGER.debug("Heat transfer %.2f MW with ΔT=%.1fK", transferred, delta_t) LOGGER.debug("Heat transfer %.2f MW with ΔT=%.1fK", transferred, delta_t)
return transferred return transferred

View File

@@ -34,10 +34,12 @@ class Turbine:
loop: CoolantLoopState, loop: CoolantLoopState,
state: TurbineState, state: TurbineState,
consumer: Optional[ElectricalConsumer] = None, consumer: Optional[ElectricalConsumer] = None,
steam_power_mw: float = 0.0,
) -> None: ) -> None:
enthalpy = 2_700.0 + loop.steam_quality * 600.0 enthalpy = 2_700.0 + loop.steam_quality * 600.0
mass_flow = loop.mass_flow_rate * 0.6 mass_flow = loop.mass_flow_rate * 0.6
shaft_power_mw = (enthalpy * mass_flow / 1_000.0) * self.mechanical_efficiency / 1_000.0 available_power = max(steam_power_mw, (enthalpy * mass_flow / 1_000.0) / 1_000.0)
shaft_power_mw = available_power * self.mechanical_efficiency
electrical = shaft_power_mw * self.generator_efficiency electrical = shaft_power_mw * self.generator_efficiency
if consumer: if consumer:
load_demand = consumer.request_power() load_demand = consumer.request_power()