rspice 0.1.0

Pure-Rust circuit simulation backend
Documentation
use crate::BasicComponent;
use crate::Circuit;
use crate::ComponentRef;
use crate::ConnectionRef;
use crate::EquationRef;
use crate::NetRef;
use crate::TransientMatrix;
use crate::TransientVector;

/// Ideal inductor.
pub struct Inductor {
    nets: Vec<NetRef>,
    connections: Vec<ConnectionRef>,
    equations: Vec<EquationRef>,
    value: f64,
}

impl BasicComponent for Inductor {
    fn initCircuit(
        &mut self,
        nets: Vec<NetRef>,
        connections: Vec<ConnectionRef>,
        equations: Vec<EquationRef>,
    ) {
        self.nets = nets;
        self.connections = connections;
        self.equations = equations;
    }

    fn initTransient(&mut self, matrix: &mut TransientMatrix) {
        // equation 0: net zero outgoing current
        // 1 * net1.I + 1 * net2.I = 0
        matrix.clear_equation(self.equations[0]);
        *matrix.current_term(self.equations[0], self.connections[0]) = 1.0;
        *matrix.current_term(self.equations[0], self.connections[1]) = 1.0;

        // equation 1: net zero current derivative
        // 1 * net1.dI/dt + 1 * net2.dI/dt = 0
        matrix.clear_equation(self.equations[1]);
        *matrix.current_derivative_term(self.equations[1], self.connections[0]) = 1.0;
        *matrix.current_derivative_term(self.equations[1], self.connections[1]) = 1.0;

        // equation 2: instantaneous current (initialize to zero)
        // 1 * net1.I = I
        matrix.clear_equation(self.equations[2]);
        *matrix.current_term(self.equations[2], self.connections[0]) = 1.0;
        *matrix.constant_term(self.equations[2]) = 0.0;

        // equation 3: inductor operation
        // 1 * net1.V - 1 * net2.V + L * net1.dI/dt = 0
        matrix.clear_equation(self.equations[3]);
        *matrix.voltage_term(self.equations[3], self.nets[0]) = 1.0;
        *matrix.voltage_term(self.equations[3], self.nets[1]) = -1.0;
        *matrix.current_derivative_term(self.equations[3], self.connections[0]) = self.value;
    }

    fn updateTransient(
        &mut self,
        matrix: &mut TransientMatrix,
        vector: &TransientVector,
        t: f64,
        step: f64,
    ) {
        // discrete derivative
        let dI_dt = vector.current_derivative(self.connections[0]);
        *matrix.constant_term(self.equations[2]) += step * dI_dt;
    }
}

impl Inductor {
    /// Create an inductor of `value` Henrys, connected to `net1` and `net2`.
    pub fn create(circuit: &mut Circuit, net1: NetRef, net2: NetRef, value: f64) -> ComponentRef {
        let component = Self {
            nets: Vec::new(),
            connections: Vec::new(),
            equations: Vec::new(),
            value: value,
        };
        circuit.createBasicComponent(Box::new(component), vec![net1, net2])
    }
}