Quantize manual rod steps to 0.025
This commit is contained in:
@@ -14,6 +14,7 @@ MAX_PRESSURE = 15.0 # MPa typical PWR primary loop limit
|
||||
CONTROL_ROD_SPEED = 0.03 # fraction insertion per second
|
||||
CONTROL_ROD_WORTH = 0.042 # delta rho contribution when fully withdrawn
|
||||
CONTROL_ROD_BANK_WEIGHTS = (0.4, 0.35, 0.25)
|
||||
ROD_MANUAL_STEP = 0.025
|
||||
STEAM_TURBINE_EFFICIENCY = 0.34
|
||||
GENERATOR_EFFICIENCY = 0.96
|
||||
ENVIRONMENT_TEMPERATURE = 295.0 # K
|
||||
|
||||
@@ -45,7 +45,7 @@ class ControlSystem:
|
||||
return self.rod_fraction
|
||||
|
||||
def set_rods(self, fraction: float) -> float:
|
||||
self.rod_target = clamp(fraction, 0.0, 0.95)
|
||||
self.rod_target = self._quantize_manual(fraction)
|
||||
self._advance_banks(self.rod_target, 0.0)
|
||||
LOGGER.info("Manual rod target set to %.3f", self.rod_target)
|
||||
return self.rod_target
|
||||
@@ -127,6 +127,11 @@ class ControlSystem:
|
||||
def _sync_fraction(self) -> None:
|
||||
self.rod_fraction = self.effective_insertion()
|
||||
|
||||
def _quantize_manual(self, fraction: float) -> float:
|
||||
step = constants.ROD_MANUAL_STEP
|
||||
quantized = round(fraction / step) * step
|
||||
return clamp(quantized, 0.0, 0.95)
|
||||
|
||||
|
||||
def save_state(
|
||||
self,
|
||||
|
||||
@@ -177,10 +177,10 @@ class ReactorDashboard:
|
||||
self._toggle_turbine_unit(idx)
|
||||
elif ch in (ord("+"), ord("=")):
|
||||
# Insert rods (increase fraction)
|
||||
self._queue_command(ReactorCommand(rod_position=self._clamped_rod(0.05)))
|
||||
self._queue_command(ReactorCommand(rod_position=self._clamped_rod(constants.ROD_MANUAL_STEP)))
|
||||
elif ch == ord("-"):
|
||||
# Withdraw rods (decrease fraction)
|
||||
self._queue_command(ReactorCommand(rod_position=self._clamped_rod(-0.05)))
|
||||
self._queue_command(ReactorCommand(rod_position=self._clamped_rod(-constants.ROD_MANUAL_STEP)))
|
||||
elif ch == ord("["):
|
||||
demand = self._current_demand() - 50.0
|
||||
self._queue_command(ReactorCommand(consumer_demand=max(0.0, demand)))
|
||||
@@ -710,7 +710,9 @@ class ReactorDashboard:
|
||||
|
||||
def _clamped_rod(self, delta: float) -> float:
|
||||
new_fraction = self.reactor.control.rod_fraction + delta
|
||||
return max(0.0, min(0.95, new_fraction))
|
||||
step = constants.ROD_MANUAL_STEP
|
||||
quantized = round(new_fraction / step) * step
|
||||
return max(0.0, min(0.95, quantized))
|
||||
|
||||
def _install_log_capture(self) -> None:
|
||||
if self._log_handler:
|
||||
|
||||
40
tests/test_control.py
Normal file
40
tests/test_control.py
Normal file
@@ -0,0 +1,40 @@
|
||||
import pytest
|
||||
|
||||
from reactor_sim.control import ControlSystem
|
||||
from reactor_sim import constants
|
||||
from reactor_sim.state import CoreState
|
||||
|
||||
|
||||
def _core_state() -> CoreState:
|
||||
return CoreState(
|
||||
fuel_temperature=300.0,
|
||||
neutron_flux=1e5,
|
||||
reactivity_margin=0.0,
|
||||
power_output_mw=0.0,
|
||||
burnup=0.0,
|
||||
)
|
||||
|
||||
|
||||
def test_manual_rods_quantized_to_step():
|
||||
control = ControlSystem()
|
||||
control.manual_control = True
|
||||
core = _core_state()
|
||||
|
||||
control.set_rods(0.333)
|
||||
assert control.rod_target == 0.325
|
||||
control.update_rods(core, dt=100.0)
|
||||
assert control.rod_fraction == pytest.approx(0.325, rel=1e-6)
|
||||
|
||||
control.increment_rods(0.014)
|
||||
assert control.rod_target == pytest.approx(0.35)
|
||||
control.update_rods(core, dt=100.0)
|
||||
assert control.rod_fraction == pytest.approx(0.35, rel=1e-6)
|
||||
|
||||
# Clamp upper bound
|
||||
control.set_rods(1.0)
|
||||
control.update_rods(core, dt=100.0)
|
||||
assert control.rod_fraction == 0.95
|
||||
|
||||
|
||||
def test_dashboard_step_constant_exposed():
|
||||
assert constants.ROD_MANUAL_STEP == 0.025
|
||||
Reference in New Issue
Block a user