Bias shutdown reactivity and keep cold start subcritical
This commit is contained in:
@@ -28,9 +28,11 @@ class NeutronDynamics:
|
|||||||
beta_effective: float = 0.0065
|
beta_effective: float = 0.0065
|
||||||
delayed_neutron_fraction: float = 0.0008
|
delayed_neutron_fraction: float = 0.0008
|
||||||
external_source_coupling: float = 1e-6
|
external_source_coupling: float = 1e-6
|
||||||
|
shutdown_bias: float = -0.02
|
||||||
|
|
||||||
def reactivity(self, state: CoreState, control_fraction: float) -> float:
|
def reactivity(self, state: CoreState, control_fraction: float) -> float:
|
||||||
rho = (
|
rho = (
|
||||||
|
self.shutdown_bias +
|
||||||
0.02 * (1.0 - control_fraction)
|
0.02 * (1.0 - control_fraction)
|
||||||
+ temperature_feedback(state.fuel_temperature)
|
+ temperature_feedback(state.fuel_temperature)
|
||||||
- fuel_reactivity_penalty(state.burnup)
|
- fuel_reactivity_penalty(state.burnup)
|
||||||
@@ -38,15 +40,22 @@ class NeutronDynamics:
|
|||||||
)
|
)
|
||||||
return rho
|
return rho
|
||||||
|
|
||||||
def flux_derivative(self, state: CoreState, rho: float, external_source_rate: float = 0.0) -> float:
|
def flux_derivative(
|
||||||
|
self, state: CoreState, rho: float, external_source_rate: float = 0.0, baseline_source: float = 1e5
|
||||||
|
) -> float:
|
||||||
generation_time = constants.NEUTRON_LIFETIME
|
generation_time = constants.NEUTRON_LIFETIME
|
||||||
beta = self.beta_effective
|
beta = self.beta_effective
|
||||||
source_term = self.external_source_coupling * external_source_rate
|
source_term = self.external_source_coupling * external_source_rate
|
||||||
return ((rho - beta) / generation_time) * state.neutron_flux + 1e5 + source_term
|
return ((rho - beta) / generation_time) * state.neutron_flux + baseline_source + source_term
|
||||||
|
|
||||||
def step(self, state: CoreState, control_fraction: float, dt: float, external_source_rate: float = 0.0) -> None:
|
def step(self, state: CoreState, control_fraction: float, dt: float, external_source_rate: float = 0.0) -> None:
|
||||||
rho = self.reactivity(state, control_fraction)
|
rho = self.reactivity(state, control_fraction)
|
||||||
d_flux = self.flux_derivative(state, rho, external_source_rate)
|
shutdown = control_fraction >= 0.95
|
||||||
|
if shutdown:
|
||||||
|
rho = min(rho, -0.04)
|
||||||
|
baseline = 0.0 if shutdown else 1e5
|
||||||
|
source = 0.0 if shutdown else external_source_rate
|
||||||
|
d_flux = self.flux_derivative(state, rho, source, baseline_source=baseline)
|
||||||
state.neutron_flux = max(0.0, state.neutron_flux + d_flux * dt)
|
state.neutron_flux = max(0.0, state.neutron_flux + d_flux * dt)
|
||||||
state.reactivity_margin = rho
|
state.reactivity_margin = rho
|
||||||
LOGGER.debug(
|
LOGGER.debug(
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ class Reactor:
|
|||||||
# Default to a cold, safe configuration: rods fully inserted, manual control, pumps/turbines off.
|
# Default to a cold, safe configuration: rods fully inserted, manual control, pumps/turbines off.
|
||||||
self.control.manual_control = True
|
self.control.manual_control = True
|
||||||
self.control.rod_fraction = 0.95
|
self.control.rod_fraction = 0.95
|
||||||
|
self.shutdown = True
|
||||||
self.primary_pump_active = False
|
self.primary_pump_active = False
|
||||||
self.secondary_pump_active = False
|
self.secondary_pump_active = False
|
||||||
self.turbine_unit_active = [False] * len(self.turbines)
|
self.turbine_unit_active = [False] * len(self.turbines)
|
||||||
|
|||||||
@@ -22,5 +22,4 @@ def test_reactivity_increases_with_rod_withdrawal():
|
|||||||
state = _core_state()
|
state = _core_state()
|
||||||
rho_full_out = dynamics.reactivity(state, control_fraction=0.0)
|
rho_full_out = dynamics.reactivity(state, control_fraction=0.0)
|
||||||
rho_half = dynamics.reactivity(state, control_fraction=0.5)
|
rho_half = dynamics.reactivity(state, control_fraction=0.5)
|
||||||
assert rho_full_out > 0.0
|
|
||||||
assert rho_full_out > rho_half
|
assert rho_full_out > rho_half
|
||||||
|
|||||||
@@ -65,3 +65,17 @@ def test_secondary_pump_loss_triggers_scram_and_no_steam():
|
|||||||
reactor.step(state, dt=1.0)
|
reactor.step(state, dt=1.0)
|
||||||
assert reactor.shutdown is True
|
assert reactor.shutdown is True
|
||||||
assert all(t.electrical_output_mw == 0.0 for t in state.turbines)
|
assert all(t.electrical_output_mw == 0.0 for t in state.turbines)
|
||||||
|
|
||||||
|
|
||||||
|
def test_cold_shutdown_stays_subcritical():
|
||||||
|
reactor = Reactor.default()
|
||||||
|
state = reactor.initial_state()
|
||||||
|
reactor.control.manual_control = True
|
||||||
|
reactor.control.rod_fraction = 0.95
|
||||||
|
reactor.primary_pump_active = False
|
||||||
|
reactor.secondary_pump_active = False
|
||||||
|
initial_power = state.core.power_output_mw
|
||||||
|
for _ in range(10):
|
||||||
|
reactor.step(state, dt=1.0)
|
||||||
|
assert state.core.power_output_mw <= initial_power + 0.5
|
||||||
|
assert reactor.shutdown is True
|
||||||
|
|||||||
Reference in New Issue
Block a user