use uom::si::electric_current::kiloampere;
use uom::si::electric_potential::kilovolt;
use uom::si::f64::{ElectricCurrent, Length, RadiantExposure, Time};
use uom::si::length::millimeter as mm;
use uom::si::radiant_exposure::joule_per_square_centimeter;
use uom::si::time::millisecond as ms;
use crate::common::NominalVoltage;
use crate::cubicle::Cubicle;
use crate::tables::{Table3_4_5Row, TABLE_1, TABLE_3, TABLE_4, TABLE_5};
pub fn i_arc_intermediate(
c: &Cubicle,
v_oc: NominalVoltage,
i_bf: ElectricCurrent,
) -> ElectricCurrent {
let i_bf = i_bf.get::<kiloampere>();
let g = c.g.get::<mm>();
let k = TABLE_1.get(&(c.ec, v_oc)).unwrap();
let x1 = k.k1 + k.k2 * f64::log10(i_bf) + k.k3 * f64::log10(g);
let x2 = k.k4 * i_bf.powi(6)
+ k.k5 * i_bf.powi(5)
+ k.k6 * i_bf.powi(4)
+ k.k7 * i_bf.powi(3)
+ k.k8 * i_bf.powi(2)
+ k.k9 * i_bf.powi(1)
+ k.k10;
let i_a = 10.0_f64.powf(x1) * x2;
ElectricCurrent::new::<kiloampere>(i_a)
}
pub fn i_arc_min(c: &Cubicle, i_arc: ElectricCurrent) -> ElectricCurrent {
let i_arc = i_arc.get::<kiloampere>();
ElectricCurrent::new::<kiloampere>(i_arc * (1.0 - 0.5 * c.var_cf))
}
pub fn intermediate_e(
c: &Cubicle,
v_oc: NominalVoltage,
i_arc: ElectricCurrent,
i_bf: ElectricCurrent,
t: Time,
i_arc_600: Option<ElectricCurrent>,
) -> RadiantExposure {
let i_arc: f64 = i_arc.get::<kiloampere>();
let i_bf: f64 = i_bf.get::<kiloampere>();
let t: f64 = t.get::<ms>();
let i_arc_600: Option<f64> = if i_arc_600.is_none() {
None
} else {
Some(i_arc_600.unwrap().get::<kiloampere>())
};
let g = c.g.get::<mm>();
let cf = c.cf;
let d = c.d.get::<mm>();
let k: &Table3_4_5Row = match v_oc {
NominalVoltage::V600 => TABLE_3.get(&c.ec).unwrap(),
NominalVoltage::V2700 => TABLE_4.get(&c.ec).unwrap(),
NominalVoltage::V14300 => TABLE_5.get(&c.ec).unwrap(),
};
let x1 = 12.552 / 50.0 * t;
let x2 = k.k1 + k.k2 * f64::log10(g);
let x3_num = if let Some(i_arc_600) = i_arc_600 {
k.k3 * i_arc_600
} else {
k.k3 * i_arc
};
let x3_den = k.k4 * i_bf.powi(7)
+ k.k5 * i_bf.powi(6)
+ k.k6 * i_bf.powi(5)
+ k.k7 * i_bf.powi(4)
+ k.k8 * i_bf.powi(3)
+ k.k9 * i_bf.powi(2)
+ k.k10 * i_bf;
let x3 = x3_num / x3_den;
let x4 = k.k11 * f64::log10(i_bf) + k.k13 * f64::log10(i_arc) + f64::log10(1.0 / cf);
let x5 = k.k12 * f64::log10(d);
let e = x1 * 10.0_f64.powf(x2 + x3 + x4 + x5);
RadiantExposure::new::<joule_per_square_centimeter>(e) }
pub fn intermediate_afb_from_e(c: &Cubicle, v_oc: NominalVoltage, e: RadiantExposure) -> Length {
let e = e.get::<joule_per_square_centimeter>();
let d = c.d.get::<mm>();
let k: &Table3_4_5Row = match v_oc {
NominalVoltage::V600 => TABLE_3.get(&c.ec).unwrap(),
NominalVoltage::V2700 => TABLE_4.get(&c.ec).unwrap(),
NominalVoltage::V14300 => TABLE_5.get(&c.ec).unwrap(),
};
let f = e / d.powf(k.k12);
let afb = (5.0208 / f).powf(1.0 / k.k12);
Length::new::<mm>(afb)
}
macro_rules! interpolate {
($c:expr, $x_600:expr, $x_2700:expr, $x_14300:expr) => {{
let v_oc = $c.v_oc.get::<uom::si::electric_potential::kilovolt>();
let x1 = ((($x_2700 - $x_600) / 2.1) * (v_oc - 2.7)) + $x_2700;
let x2 = ((($x_14300 - $x_2700) / 11.6) * (v_oc - 14.3)) + $x_14300;
let x3 = ((x1 * (2.7 - v_oc)) / 2.1) + ((x2 * (v_oc - 0.6)) / 2.1);
if 0.600 < v_oc && v_oc <= 2.7 {
x3
} else if v_oc > 2.7 {
x2
} else {
unreachable!()
}
}};
}
pub(crate) use interpolate;
pub fn i_arc_final_lv(
c: &Cubicle,
i_arc_600: ElectricCurrent,
i_bf: ElectricCurrent,
) -> ElectricCurrent {
let v_oc = c.v_oc.get::<kilovolt>();
let i_arc_600 = i_arc_600.get::<kiloampere>();
let i_bf = i_bf.get::<kiloampere>();
let x1 = (0.6 / v_oc).powi(2);
let x2 = 1.0 / i_arc_600.powi(2);
let x3 = (0.6_f64.powi(2) - v_oc.powi(2)) / (0.6_f64.powi(2) * i_bf.powi(2));
let x4 = f64::sqrt(x1 * (x2 - x3));
ElectricCurrent::new::<kiloampere>(1.0 / x4)
}