#455 calculate reactor temp high limit

This commit is contained in:
Mikayla Fischler 2024-04-29 22:03:54 -04:00
parent e91fd2fcaa
commit eb45ff899b
5 changed files with 44 additions and 13 deletions

View File

@ -29,7 +29,7 @@ local annunc = {}
annunc.RCSFlowLow_H2O = -3.2 -- flow < -3.2 mB/s annunc.RCSFlowLow_H2O = -3.2 -- flow < -3.2 mB/s
annunc.RCSFlowLow_NA = -2.0 -- flow < -2.0 mB/s annunc.RCSFlowLow_NA = -2.0 -- flow < -2.0 mB/s
annunc.CoolantLevelLow = 0.4 -- fill < 40% annunc.CoolantLevelLow = 0.4 -- fill < 40%
annunc.ReactorTempHigh = 1000 -- temp > 1000K annunc.OpTempTolerance = 5 -- high temp if >= operational temp + X
annunc.ReactorHighDeltaT = 50 -- rate > 50K/s annunc.ReactorHighDeltaT = 50 -- rate > 50K/s
annunc.FuelLevelLow = 0.05 -- fill <= 5% annunc.FuelLevelLow = 0.05 -- fill <= 5%
annunc.WasteLevelHigh = 0.80 -- fill >= 80% annunc.WasteLevelHigh = 0.80 -- fill >= 80%
@ -101,9 +101,11 @@ constants.EXTREME_RADIATION = 100.0
---@class _mek_constants ---@class _mek_constants
local mek = {} local mek = {}
mek.TURBINE_GAS_PER_TANK = 64000 -- mekanism: turbineGasPerTank mek.BASE_BOIL_TEMP = 373.15 -- mekanism: HeatUtils.BASE_BOIL_TEMP
mek.TURBINE_DISPERSER_FLOW = 1280 -- mekanism: turbineDisperserGasFlow mek.JOULES_PER_MB = 1000000 -- mekanism: energyPerFissionFuel
mek.TURBINE_VENT_FLOW = 32000 -- mekanism: turbineVentGasFlow mek.TURBINE_GAS_PER_TANK = 64000 -- mekanism: turbineGasPerTank
mek.TURBINE_DISPERSER_FLOW = 1280 -- mekanism: turbineDisperserGasFlow
mek.TURBINE_VENT_FLOW = 32000 -- mekanism: turbineVentGasFlow
constants.mek = mek constants.mek = mek

View File

@ -1,4 +1,5 @@
local comms = require("scada-common.comms") local comms = require("scada-common.comms")
local const = require("scada-common.constants")
local log = require("scada-common.log") local log = require("scada-common.log")
local mqueue = require("scada-common.mqueue") local mqueue = require("scada-common.mqueue")
local types = require("scada-common.types") local types = require("scada-common.types")
@ -105,6 +106,8 @@ function plc.new_session(id, s_addr, reactor_id, in_queue, out_queue, timeout, f
formed = false, formed = false,
rps_tripped = false, rps_tripped = false,
rps_trip_cause = "ok", ---@type rps_trip_cause rps_trip_cause = "ok", ---@type rps_trip_cause
max_op_temp_H2O = 1200,
max_op_temp_Na = 1200,
---@class rps_status ---@class rps_status
rps_status = { rps_status = {
high_dmg = false, high_dmg = false,
@ -138,11 +141,11 @@ function plc.new_session(id, s_addr, reactor_id, in_queue, out_queue, timeout, f
waste = 0, waste = 0,
waste_need = 0, waste_need = 0,
waste_fill = 0.0, waste_fill = 0.0,
ccool_type = "?", ccool_type = types.FLUID.EMPTY_GAS, ---@type fluid
ccool_amnt = 0, ccool_amnt = 0,
ccool_need = 0, ccool_need = 0,
ccool_fill = 0.0, ccool_fill = 0.0,
hcool_type = "?", hcool_type = types.FLUID.EMPTY_GAS, ---@type fluid
hcool_amnt = 0, hcool_amnt = 0,
hcool_need = 0, hcool_need = 0,
hcool_fill = 0.0 hcool_fill = 0.0
@ -169,6 +172,21 @@ function plc.new_session(id, s_addr, reactor_id, in_queue, out_queue, timeout, f
---@class plc_session ---@class plc_session
local public = {} local public = {}
-- compute maximum expected operational temperatures for high temp warnings
local function _compute_op_temps()
local JOULES_PER_MB = const.mek.JOULES_PER_MB
local BASE_BOIL_TEMP = const.mek.BASE_BOIL_TEMP
local heat_cap = self.sDB.mek_struct.heat_cap
local max_burn = self.sDB.mek_struct.max_burn
self.sDB.max_op_temp_H2O = max_burn * 2 * (JOULES_PER_MB * heat_cap ^ -1) + BASE_BOIL_TEMP
self.sDB.max_op_temp_Na = max_burn * (JOULES_PER_MB * heat_cap ^ -1) + BASE_BOIL_TEMP
log.info(util.sprintf(log_header .. "computed maximum operational temperatures %.3f (H2O) and %.3f (Na)",
self.sDB.max_op_temp_H2O, self.sDB.max_op_temp_Na))
end
-- copy in the RPS status -- copy in the RPS status
---@param rps_status table ---@param rps_status table
local function _copy_rps_status(rps_status) local function _copy_rps_status(rps_status)
@ -351,6 +369,7 @@ function plc.new_session(id, s_addr, reactor_id, in_queue, out_queue, timeout, f
local status = pcall(_copy_struct, pkt.data) local status = pcall(_copy_struct, pkt.data)
if status then if status then
-- copied in structure data OK -- copied in structure data OK
_compute_op_temps()
self.received_struct = true self.received_struct = true
out_queue.push_data(svqtypes.SV_Q_DATA.PLC_BUILD_CHANGED, reactor_id) out_queue.push_data(svqtypes.SV_Q_DATA.PLC_BUILD_CHANGED, reactor_id)
else else

View File

@ -21,7 +21,7 @@ local supervisor = require("supervisor.supervisor")
local svsessions = require("supervisor.session.svsessions") local svsessions = require("supervisor.session.svsessions")
local SUPERVISOR_VERSION = "v1.3.7" local SUPERVISOR_VERSION = "v1.3.8"
local println = util.println local println = util.println
local println_ts = util.println_ts local println_ts = util.println_ts

View File

@ -147,7 +147,8 @@ function unit.new(reactor_id, num_boilers, num_turbines, ext_idle)
}, },
damage = 0, damage = 0,
temp = 0, temp = 0,
waste = 0 waste = 0,
high_temp_lim = 1150
}, },
---@class alarm_monitors ---@class alarm_monitors
alarms = { alarms = {

View File

@ -133,7 +133,15 @@ function logic.update_annunciator(self)
self.last_heartbeat = plc_db.last_status_update self.last_heartbeat = plc_db.last_status_update
end end
local flow_low = util.trinary(plc_db.mek_status.ccool_type == types.FLUID.SODIUM, ANNUNC_LIMS.RCSFlowLow_NA, ANNUNC_LIMS.RCSFlowLow_H2O) local flow_low = ANNUNC_LIMS.RCSFlowLow_H2O
local high_temp = plc_db.max_op_temp_H2O
if plc_db.mek_status.ccool_type == types.FLUID.SODIUM then
flow_low = ANNUNC_LIMS.RCSFlowLow_NA
high_temp = plc_db.max_op_temp_Na
end
self.plc_cache.high_temp_lim = math.min(high_temp + ANNUNC_LIMS.OpTempTolerance, 1200)
-- update other annunciator fields -- update other annunciator fields
annunc.ReactorSCRAM = plc_db.rps_tripped annunc.ReactorSCRAM = plc_db.rps_tripped
@ -142,7 +150,7 @@ function logic.update_annunciator(self)
annunc.RCPTrip = plc_db.rps_tripped and (plc_db.rps_status.ex_hcool or plc_db.rps_status.low_cool) annunc.RCPTrip = plc_db.rps_tripped and (plc_db.rps_status.ex_hcool or plc_db.rps_status.low_cool)
annunc.RCSFlowLow = _get_dt(DT_KEYS.ReactorCCool) < flow_low annunc.RCSFlowLow = _get_dt(DT_KEYS.ReactorCCool) < flow_low
annunc.CoolantLevelLow = plc_db.mek_status.ccool_fill < ANNUNC_LIMS.CoolantLevelLow annunc.CoolantLevelLow = plc_db.mek_status.ccool_fill < ANNUNC_LIMS.CoolantLevelLow
annunc.ReactorTempHigh = plc_db.mek_status.temp > ANNUNC_LIMS.ReactorTempHigh annunc.ReactorTempHigh = plc_db.mek_status.temp >= self.plc_cache.high_temp_lim
annunc.ReactorHighDeltaT = _get_dt(DT_KEYS.ReactorTemp) > ANNUNC_LIMS.ReactorHighDeltaT annunc.ReactorHighDeltaT = _get_dt(DT_KEYS.ReactorTemp) > ANNUNC_LIMS.ReactorHighDeltaT
annunc.FuelInputRateLow = _get_dt(DT_KEYS.ReactorFuel) < -1.0 or plc_db.mek_status.fuel_fill <= ANNUNC_LIMS.FuelLevelLow annunc.FuelInputRateLow = _get_dt(DT_KEYS.ReactorFuel) < -1.0 or plc_db.mek_status.fuel_fill <= ANNUNC_LIMS.FuelLevelLow
annunc.WasteLineOcclusion = _get_dt(DT_KEYS.ReactorWaste) > 1.0 or plc_db.mek_status.waste_fill >= ANNUNC_LIMS.WasteLevelHigh annunc.WasteLineOcclusion = _get_dt(DT_KEYS.ReactorWaste) > 1.0 or plc_db.mek_status.waste_fill >= ANNUNC_LIMS.WasteLevelHigh
@ -542,7 +550,8 @@ function logic.update_alarms(self)
end end
-- High Temperature -- High Temperature
_update_alarm_state(self, plc_cache.temp >= ALARM_LIMS.HIGH_TEMP, self.alarms.ReactorHighTemp) local high_temp = math.min(math.max(self.plc_cache.high_temp_lim, 1100), 1199.995)
_update_alarm_state(self, plc_cache.temp >= high_temp, self.alarms.ReactorHighTemp)
-- Waste Leak -- Waste Leak
_update_alarm_state(self, plc_cache.waste >= 1.0, self.alarms.ReactorWasteLeak) _update_alarm_state(self, plc_cache.waste >= 1.0, self.alarms.ReactorWasteLeak)
@ -718,11 +727,11 @@ function logic.update_status_text(self)
self.status_text[2] = "elevated level of radiation" self.status_text[2] = "elevated level of radiation"
end end
elseif is_active(self.alarms.ReactorOverTemp) then elseif is_active(self.alarms.ReactorOverTemp) then
self.status_text = { "CORE OVER TEMP", "reactor core temperature >=1200K" } self.status_text = { "CORE OVER TEMP", "reactor core temp damaging" }
elseif is_active(self.alarms.ReactorWasteLeak) then elseif is_active(self.alarms.ReactorWasteLeak) then
self.status_text = { "WASTE LEAK", "radioactive waste leak detected" } self.status_text = { "WASTE LEAK", "radioactive waste leak detected" }
elseif is_active(self.alarms.ReactorHighTemp) then elseif is_active(self.alarms.ReactorHighTemp) then
self.status_text = { "CORE TEMP HIGH", "reactor core temperature >1150K" } self.status_text = { "CORE TEMP HIGH", "reactor core temperature high" }
elseif is_active(self.alarms.ReactorHighWaste) then elseif is_active(self.alarms.ReactorHighWaste) then
self.status_text = { "WASTE LEVEL HIGH", "waste accumulating in reactor" } self.status_text = { "WASTE LEVEL HIGH", "waste accumulating in reactor" }
elseif is_active(self.alarms.TurbineTrip) then elseif is_active(self.alarms.TurbineTrip) then