rspice/
transient_result.rs

1use crate::BasicComponent;
2use crate::ComponentRef;
3use crate::ConnectionRef;
4use crate::NetRef;
5
6/// The result of running a transient simulation.
7///
8/// Can be queried for voltages and currents at different points in time.
9pub struct TransientResult {
10    // for each time point, a vector of values as appearing in the matrix
11    pub(crate) values_over_time: Vec<Vec<f64>>,
12    pub(crate) step: f64,
13    pub(crate) n_nets: usize,
14    // basic component, list of connected nets, index of first connection
15    pub(crate) components: Vec<(Vec<usize>, usize)>,
16}
17
18impl TransientResult {
19    fn voltage_at_step(&self, net: NetRef, step: usize) -> f64 {
20        self.values_over_time[step][net.index * 2]
21    }
22
23    pub fn voltage_at(&self, net: NetRef, time: f64) -> f64 {
24        let prev = (time / self.step).floor() as usize;
25        let next = (time / self.step).ceil() as usize;
26        let voltage_at_prev = self.voltage_at_step(net, prev);
27        if prev == next {
28            voltage_at_prev
29        } else {
30            let voltage_at_next = self.voltage_at_step(net, next);
31            let x = time / self.step - prev as f64;
32            x * voltage_at_next + (1. - x) * voltage_at_prev
33        }
34    }
35
36    fn current_at_step(&self, component: &ComponentRef, terminal: usize, step: usize) -> f64 {
37        self.values_over_time[step][(self.n_nets + component.connections[terminal]) * 2]
38    }
39
40    pub fn current_at(&self, component: &ComponentRef, terminal: usize, time: f64) -> f64 {
41        let prev = (time / self.step).floor() as usize;
42        let next = (time / self.step).ceil() as usize;
43        let current_at_prev = self.current_at_step(component, terminal, prev);
44        if prev == next {
45            current_at_prev
46        } else {
47            let current_at_next = self.current_at_step(component, terminal, next);
48            let x = time / self.step - prev as f64;
49            x * current_at_next + (1. - x) * current_at_prev
50        }
51    }
52
53    pub fn connected_net(&self, connection: &ConnectionRef) -> NetRef {
54        for component in &self.components {
55            let index = connection.index - component.1;
56            if index < component.0.len() {
57                return NetRef {
58                    index: component.0[index],
59                };
60            }
61        }
62        panic!();
63    }
64}