use num_complex::Complex;
use crate::network::ShuntAdm;
use crate::types::{Bus, BusType, Line, Transformer};
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct GridoxideComplex {
pub re: f64,
pub im: f64,
}
impl From<GridoxideComplex> for Complex<f64> {
fn from(value: GridoxideComplex) -> Self {
Complex::new(value.re, value.im)
}
}
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum GridoxideBusType {
Slack = 0,
Pv = 1,
Pq = 2,
}
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct GridoxideBus {
pub bus_type: GridoxideBusType,
pub voltage_magnitude: f64,
pub voltage_angle: f64,
pub p_spec: f64,
pub q_spec: f64,
pub q_min: f64,
pub q_max: f64,
pub u_rated: f64,
}
impl GridoxideBus {
pub(crate) fn to_bus(self, idx: usize) -> Bus {
Bus {
idx,
bus_type: match self.bus_type {
GridoxideBusType::Slack => BusType::Slack,
GridoxideBusType::Pv => BusType::PV,
GridoxideBusType::Pq => BusType::PQ,
},
voltage_mag: self.voltage_magnitude,
voltage_ang: self.voltage_angle,
p_spec: self.p_spec,
q_spec: self.q_spec,
q_min: self.q_min,
q_max: self.q_max,
u_rated: self.u_rated,
zip_terms: Vec::new(),
}
}
}
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct GridoxideLine {
pub from: usize,
pub to: usize,
pub r: f64,
pub x: f64,
pub b_shunt: f64,
pub g_shunt: f64,
}
impl From<GridoxideLine> for Line {
fn from(value: GridoxideLine) -> Self {
Line {
from: value.from,
to: value.to,
r: value.r,
x: value.x,
b_shunt: value.b_shunt,
g_shunt: value.g_shunt,
}
}
}
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct GridoxideTransformer {
pub from: usize,
pub to: usize,
pub from_status: u8,
pub to_status: u8,
pub y_series: GridoxideComplex,
pub y_shunt: GridoxideComplex,
pub tap: GridoxideComplex,
}
impl From<GridoxideTransformer> for Transformer {
fn from(value: GridoxideTransformer) -> Self {
Transformer {
from: value.from,
to: value.to,
from_status: value.from_status,
to_status: value.to_status,
y_series: value.y_series.into(),
y_shunt: value.y_shunt.into(),
tap: value.tap.into(),
}
}
}
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct GridoxideShunt {
pub at: usize,
pub y: GridoxideComplex,
}
impl From<GridoxideShunt> for ShuntAdm {
fn from(value: GridoxideShunt) -> Self {
ShuntAdm {
at: value.at,
y: value.y.into(),
}
}
}
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum GridoxideBackend {
Scalar = 0,
Block = 1,
Klu = 2,
KluNative = 3,
Pardiso = 4,
}
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct GridoxideOptions {
pub backend: GridoxideBackend,
pub tolerance: f64,
pub max_iterations: usize,
pub s_base_va: f64,
pub frequency_hz: f64,
}
impl Default for GridoxideOptions {
fn default() -> Self {
Self {
backend: GridoxideBackend::KluNative,
tolerance: 1e-8,
max_iterations: 20,
s_base_va: 1e6,
frequency_hz: 50.0,
}
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn gridoxide_options_default(out: *mut GridoxideOptions) {
if out.is_null() {
return;
}
unsafe { *out = GridoxideOptions::default() };
}