use crate::BasicComponent;
use crate::ComponentRef;
use crate::ConnectionRef;
use crate::NetRef;
pub struct TransientResult {
pub(crate) values_over_time: Vec<Vec<f64>>,
pub(crate) step: f64,
pub(crate) n_nets: usize,
pub(crate) components: Vec<(Vec<usize>, usize)>,
}
impl TransientResult {
fn voltage_at_step(&self, net: NetRef, step: usize) -> f64 {
self.values_over_time[step][net.index * 2]
}
pub fn voltage_at(&self, net: NetRef, time: f64) -> f64 {
let prev = (time / self.step).floor() as usize;
let next = (time / self.step).ceil() as usize;
let voltage_at_prev = self.voltage_at_step(net, prev);
if prev == next {
voltage_at_prev
} else {
let voltage_at_next = self.voltage_at_step(net, next);
let x = time / self.step - prev as f64;
x * voltage_at_next + (1. - x) * voltage_at_prev
}
}
fn current_at_step(&self, component: &ComponentRef, terminal: usize, step: usize) -> f64 {
self.values_over_time[step][(self.n_nets + component.connections[terminal]) * 2]
}
pub fn current_at(&self, component: &ComponentRef, terminal: usize, time: f64) -> f64 {
let prev = (time / self.step).floor() as usize;
let next = (time / self.step).ceil() as usize;
let current_at_prev = self.current_at_step(component, terminal, prev);
if prev == next {
current_at_prev
} else {
let current_at_next = self.current_at_step(component, terminal, next);
let x = time / self.step - prev as f64;
x * current_at_next + (1. - x) * current_at_prev
}
}
pub fn connected_net(&self, connection: &ConnectionRef) -> NetRef {
for component in &self.components {
let index = connection.index - component.1;
if index < component.0.len() {
return NetRef {
index: component.0[index],
};
}
}
panic!();
}
}