///|
fn pressure_table() -> Array[Double] {
[10.0, 50.0, 100.0, 101.325, 200.0, 500.0, 1000.0, 2000.0]
}
///|
fn saturation_temperature_table() -> Array[Double] {
[45.81, 81.32, 99.61, 100.0, 120.23, 151.83, 179.88, 212.38]
}
///|
fn table_bracket(values : Array[Double], target : Double) -> (Int, Int) {
if values.length() < 2 {
(0, 0)
} else if target <= values[0] {
(0, 1)
} else if target >= values[values.length() - 1] {
(values.length() - 2, values.length() - 1)
} else {
let mut lower = 0
for i in 0..<(values.length() - 1) {
if values[i] <= target && target <= values[i + 1] {
lower = i
break
}
}
(lower, lower + 1)
}
}
///|
pub fn tabulated_saturation_temperature_c(
pressure_kpa : Double,
) -> SteamTableResult {
let pressure = pressure_table()
let temperatures = saturation_temperature_table()
let (lower, upper) = table_bracket(pressure, pressure_kpa)
interpolate_table(
pressure[lower],
temperatures[lower],
pressure[upper],
temperatures[upper],
pressure_kpa,
)
}
///|
pub fn tabulated_saturated_liquid_enthalpy(
pressure_kpa : Double,
) -> SteamTableResult {
let temperature = tabulated_saturation_temperature_c(pressure_kpa)
let estimate = saturated_liquid_enthalpy_kj_per_kg(temperature.value)
{ ..temperature, value: estimate }
}
///|
pub fn tabulated_saturated_vapor_enthalpy(
pressure_kpa : Double,
) -> SteamTableResult {
let temperature = tabulated_saturation_temperature_c(pressure_kpa)
let estimate = saturated_vapor_enthalpy_kj_per_kg(temperature.value)
{ ..temperature, value: estimate }
}
///|
pub fn table_quality_from_enthalpy(
pressure_kpa : Double,
enthalpy_kj_per_kg : Double,
) -> SteamTableResult {
let liquid = tabulated_saturated_liquid_enthalpy(pressure_kpa)
let vapor = tabulated_saturated_vapor_enthalpy(pressure_kpa)
if vapor.value <= liquid.value {
{
value: 0.0,
lower_bound: liquid.value,
upper_bound: vapor.value,
clamped: false,
valid: false,
}
} else {
let x = (enthalpy_kj_per_kg - liquid.value) / (vapor.value - liquid.value)
{
value: x.max(0.0).min(1.0),
lower_bound: 0.0,
upper_bound: 1.0,
clamped: x < 0.0 || x > 1.0,
valid: true,
}
}
}
///|
pub fn table_state_from_pressure_quality(
pressure_kpa : Double,
quality : Double,
) -> SteamState {
let table = tabulated_saturation_temperature_c(pressure_kpa)
let state = steam_state_from_quality(pressure_kpa, quality)
{ ..state, temperature_c: table.value }
}
///|
pub fn pressure_from_saturation_temperature_c(temperature_c : Double) -> Double {
steam_saturation_pressure_kpa(temperature_c)
}
///|
pub fn saturated_water_density_kg_per_m3(temperature_c : Double) -> Double {
let value = 1000.0 -
0.3 * (temperature_c - 4.0) -
0.000002 * (temperature_c - 4.0) * (temperature_c - 4.0)
value.max(850.0)
}
///|
pub fn steam_density_kg_per_m3(
temperature_c : Double,
pressure_kpa : Double,
) -> Double {
let volume = saturated_vapor_specific_volume_m3_per_kg(
temperature_c, pressure_kpa,
)
if volume <= 0.0 {
0.0
} else {
1.0 / volume
}
}
///|
pub fn steam_volume_flow_m3_per_s(
mass_flow_kg_per_s : Double,
temperature_c : Double,
pressure_kpa : Double,
) -> Double {
mass_flow_kg_per_s *
saturated_vapor_specific_volume_m3_per_kg(temperature_c, pressure_kpa)
}
///|
pub fn condensate_recovery_heat_kj_per_kg(
pressure_kpa : Double,
condensate_temperature_c : Double,
) -> Double {
let saturation = steam_saturation_temperature_c(pressure_kpa)
saturated_liquid_enthalpy_kj_per_kg(saturation) -
saturated_liquid_enthalpy_kj_per_kg(condensate_temperature_c)
}