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;

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

impl BasicComponent for Resistor {
    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: Ohm's law
        // 1 * net1.V - 1 * net2.V + R * net1.I = 0
        matrix.clear_equation(self.equations[2]);
        *matrix.voltage_term(self.equations[2], self.nets[0]) = 1.0;
        *matrix.voltage_term(self.equations[2], self.nets[1]) = -1.0;
        *matrix.current_term(self.equations[2], self.connections[0]) = self.value;

        // equation 2: Ohm's law for derivatives
        // 1 * net1.dV/dt - 1 * net2.dV/dt + R * net1.dI/dt = 0
        matrix.clear_equation(self.equations[3]);
        *matrix.voltage_derivative_term(self.equations[3], self.nets[0]) = 1.0;
        *matrix.voltage_derivative_term(self.equations[3], self.nets[1]) = -1.0;
        *matrix.current_derivative_term(self.equations[3], self.connections[0]) = self.value;
    }
}

impl Resistor {
    /// Create a resistor of `value` Ohms, 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])
    }
}