use std::fs::File;
use std::path::Path;
use caseformat::{write_zip, Branch, Bus, Case, Gen, REF};
fn main() {
if let Err(err) = run() {
eprintln!("error: {}", err);
std::process::exit(2);
}
}
fn run() -> anyhow::Result<()> {
let (case, bus, gen, branch) = entsoe2()?;
const _P_GRID: f64 = 0.763;
const _Q_GRID: f64 = 1.209;
let zip_path = Path::new("entsoe2.case");
write_zip(
File::open(&zip_path.to_path_buf())?,
&case,
&bus,
&gen,
&branch,
&Vec::default(),
&Vec::default(),
Some(String::from(
"2-bus test case from \"Controller Tests in Test Grid Configurations\"
by ENTSO-E System Protection and Dynamics, Nov 2013.",
)),
None,
)?;
Ok(())
}
fn entsoe2() -> anyhow::Result<(Case, Vec<Bus>, Vec<Gen>, Vec<Branch>)> {
const SB: f64 = 100.0;
let case = Case::new("entsoe2").base_mva(SB).build()?;
const VB: f64 = 380.0;
const VB_HV: f64 = 419.0;
const VB_LV: f64 = 21.0;
const GRID_L: (f64, f64) = (475.0, 76.0);
const U_NGRID: f64 = 1.05;
let ngrid = Bus::new(1)
.bus_type(REF)
.base_kv(VB)
.pd(GRID_L.0)
.qd(GRID_L.1)
.build()?;
let grid = Gen::new(1).vg(U_NGRID).mbase(SB).build()?;
let ngen = Bus::new(2)
.pq()
.base_kv(VB_LV)
.vm(0.9917)
.va(9.2327)
.build()?;
const SG: f64 = 500.0;
const PF: f64 = 0.95;
let theta = f64::acos(PF);
let pg = -SG * PF;
let qg = -SG * f64::sin(theta);
let gen = Gen::new(ngen.bus_i)
.pg(pg)
.qg(qg)
.vg(U_NGRID)
.mbase(SB)
.build()?;
const SN: f64 = 500.0;
const UR: f64 = 0.15; const UK: f64 = 16.0;
let c = f64::powi(VB_HV / VB, 2) * (SB / SN);
let c2 = (f64::powi(VB_HV, 2) * SB) / (f64::powi(VB, 2) * SN); assert_eq!(c, c2);
let r_pu = (UR / 100.0) * c;
let z_pu = (UK / 100.0) * c;
let x_pu = f64::sqrt(z_pu.powi(2) - r_pu.powi(2));
let tap = VB_HV / VB;
let t_gen = Branch::new(ngrid.bus_i, ngen.bus_i)
.br_r(r_pu)
.br_x(x_pu)
.tap(tap)
.build()?;
Ok((case, vec![ngrid, ngen], vec![grid, gen], vec![t_gen]))
}