This document details the development of my circuit solver and simulator capable of analyzing and visualizing the behavior of electrical circuits. The project goes beyond the introductory circuit analysis covered in class by exploring advanced techniques such as nodal analysis and incorporating interactive visualization. This report documents the theoretical components, implementation details, and practical applications of the developed software, hopefully allowing readers to gain a more comprehensive understanding of electrical circuit principles than they started with.
Understanding electrical circuits is fundamental to modern technology. While basic circuit analysis techniques like series and parallel resistor combinations provide a foundation, real-world circuits often require more sophisticated methods. This project aims to bridge the gap between theoretical concepts and practical application by creating a software tool that can:
This project not only reinforces the concepts learned in class but also expands upon them by exploring numerical methods for solving complex circuit configurations and providing a foundation for future development of interactive graphical representations of circuit behavior.
Nodal analysis is a very powerful technique for solving complex circuits. It's based on Kirchhoff's Current Law (which simply states that the algebraic sum of currents entering a node is zero). By applying KCL at each non-reference node in a circuit, you can obtain a system of linear equations that can be solved to find the node voltages. These voltages can then be used to determine branch currents using Ohm's Law.
For a node with voltage , connected to nodes with conductance , and with independent current sources entering the node, KCL gives:
This can be rearranged into a matrix equation of the form:
where is the conductance matrix, is the vector of node voltages, and is the vector of independent current sources. Solving for involves matrix inversion or other numerical methods.
Matrix inversion is the process of finding a matrix that, when multiplied by the original matrix, results in the identity matrix. The identity matrix is just the original matrix but with 's along its main diagonal (from the top-left to the bottom-right) and zeros elsewhere:
While important, a deep dive into the specifics of matrix inversion is outside the scope and focus of my report. So, we'll leave it at that and just take note of the practical usage of the method.
For circuits containing capacitors and inductors, the behavior is time-dependent. The governing equations become differential equations:
To simulate these circuits, numerical integration techniques such as the Euler method or more advanced methods like the Runge-Kutta methods are employed to approximate the solutions to these differential equations over time.
Although the implementation of these numerical integration techniques proved to be beyond the scope of this current project iteration due to time constraints, I will still present the detailed mathematical framework and planned code implementation strategy for dynamic circuit simulation, as this remains a key area for future development.
This detailed plan will serve as a valuable personal reference for future development (I will definitely be revisiting this project once I have more time lol...) and as a guide for others who might be interested in extending or utilizing its capabilities. Most of the difficulties I faced throughout this project stemmed from the lack of online resources regarding the simulation implementation and other technical aspects. I hope that anyone in the future attempting to build something similar can learn from my experience.
The circuit solver and simulator was initially intended to utilize JavaScript (TypeScript) for the user interface and Rust (WASM) for solving equations and performing simulations. However, due to time constraints, the current implementation relies solely on JavaScript. Future development will explore integrating Rust as planned to leverage its performance benefits for the computationally intensive simulation tasks.
The circuit is represented internally as a graph data structure. Nodes represent connection points, and edges represent circuit components (resistors, capacitors, inductors, voltage sources, current sources, etc.). Each component is characterized by its parameters (resistance, capacitance, inductance, voltage, current).
A significant challenge in the implementation is translating the user's circuit design from the visual user interface into the underlying graph representation. This involves:
The nodal analysis solver implements the following steps:
The simulation engine would use a time-stepping approach to solve the differential equations governing the behavior of capacitors and inductors.
The user interface (UI) allows users to:

A screenshot of the circuit editor user interface.
// Simplified Example Code For Nodal Analysis Solver (Standalone!!)
const circuit = {
components: [
{ name: 'V1', type: 'voltageSource', value: 5, nodes: ['V_A', 'GND'] },
{ name: 'R1', type: 'resistor', value: 2, nodes: ['V_A', 'V_B'] },
{ name: 'R2', type: 'resistor', value: 3, nodes: ['V_B', 'GND'] },
{ name: 'R3', type: 'resistor', value: 6, nodes: ['V_B', 'GND'] },
],
nodes: 3,
nodeNames: ['V_A', 'V_B', 'GND'],
};
const numNodes = circuit.nodes - 1;
let conductanceMatrix = math.zeros(numNodes, numNodes);
let currentMatrix = math.zeros(numNodes, 1);
for (let i = 0; i < numNodes; i++) {
for (let j = 0; j < numNodes; j++) {
if (i === j) {
if (i === 0) {
conductanceMatrix = math.subset(
conductanceMatrix,
math.index(i, j),
1 / circuit.components[1].value + 1 / circuit.components[2].value
);
} else if (i === 1) {
conductanceMatrix = math.subset(
conductanceMatrix,
math.index(i, j),
1 / circuit.components[2].value + 1 / circuit.components[3].value
);
}
} else {
if ((i === 0 && j === 1) || (i === 1 && j === 0)) {
conductanceMatrix = math.subset(
conductanceMatrix,
math.index(i, j),
-1 / circuit.components[2].value
);
}
}
}
}
currentMatrix = math.subset(
currentMatrix,
math.index(0, 0),
circuit.components[0].value / circuit.components[1].value
);
const voltageMatrix = math.multiply(math.inv(conductanceMatrix), currentMatrix);
const V_A = voltageMatrix.subset(math.index(circuit.nodeNames.indexOf('V_A'), 0));
const V_B = voltageMatrix.subset(math.index(circuit.nodeNames.indexOf('V_B'), 0));
const V_R1 = circuit.components[0].value - V_A;
const V_R2 = V_A - V_B;
const V_R3 = V_B;
console.log('| Component | Value | Calculated Voltage |');
console.log('|---|---|---|');
console.log(`| ${circuit.components[1].name} | ${circuit.components[1].value}Ω | ${V_R1.toFixed(2)}V |`);
console.log(`| ${circuit.components[2].name} | ${circuit.components[2].value}Ω | ${V_R2.toFixed(2)}V |`);
console.log(`| ${circuit.components[3].name} | ${circuit.components[3].value}Ω | ${V_R3.toFixed(2)}V |`);
To demonstrate the solver's capabilities and illustrate the connection between different circuit analysis methods, we will analyze a simple circuit first using the familiar Kirchhoff's Laws, and then using the more general Nodal Analysis method (in this context, the word 'general' refers to the generalization of Kirchhoff's Laws).
Hopefully, using a simpler circuit will help in understanding how the different methods work and how they relate to each other.
Consider the following example circuit (visualized from the above):

Component Values:
We'll start by analyzing the circuit using Kirchhoff's Laws, a method most are familiar with from class. This will serve as a foundation for understanding the connection to the Nodal Analysis method presented later.
I. Equivalent Resistance:
In a series circuit, the equivalent resistance is the sum of all resistances:
II. Total Current:
Using Ohm's Law (), we can find the total current flowing through the circuit:
III. Voltage Drops:
The voltage drop across each resistor is then calculated using Ohm's Law:
IV. Verification:
Kirchhoff's Voltage Law (KVL) states that the sum of voltage drops around a closed loop is zero.
This confirms our calculations.
Nodal analysis is a more general method for solving circuits, based on Kirchhoff's Current Law (KCL). While it's more complex than necessary for this simple series circuit, it demonstrates a technique applicable to a wider range of circuit topologies.
I. Node Identification:
II. KCL Equations:
For Node A:
Applying KCL (current in = current out):
For Node B:
III. Matrix Form:
We can rewrite these equations in matrix form:
Simplifying the matrix, we get:
Solving this matrix equation (using methods like Gaussian elimination or matrix inversion), we get:
Therefore, and .
IV. Voltage Drops:
Now we can calculate the voltage drops across each resistor:
These results are consistent with those obtained using Kirchhoff's Laws.
The solver outputs these results as displayed in the following table, derived from the voltage drop calculations above:
| Component | Value | Calculated Voltage |
|---|---|---|
| R1 | 2Ω | 0.91V |
| R2 | 3Ω | 1.36V |
| R3 | 6Ω | 2.73V |
It didn't seem appropriate to include this earlier in the document. I want to keep it separate from the main report.
| Method | Description | Time Complexity | Accuracy | Advantages | Disadvantages | Best Suited For |
|---|---|---|---|---|---|---|
| Kirchhoff's Laws | Direct application of KCL and KVL to form a system of equations. | or ( = nodes, = branches) | Exact (within numerical) | Simple for basic circuits, provides exact solutions. | Cubic complexity can become a bottleneck, less straightforward for non-linear components or transient analysis. | Small, linear circuits with relatively few components. |
| Modified Nodal Analysis (MNA) | Systematic method combining KCL, KVL, and branch equations into a matrix form. | (can be less with sparse matrix techniques) | Exact (within numerical) | General, handles a wide range of elements, sparsity can improve efficiency. | Can still be cubic complexity, more complex to implement than basic Kirchhoff's. | Moderate to large circuits, including those with voltage sources and complex components. |
| Nodal Analysis | Simplified MNA focusing on node voltages. | (can be less with sparse matrix techniques) | Exact (within numerical) | Easier to implement than MNA, especially for circuits without many voltage sources. | Less general than MNA, may be less efficient with many current sources or complex branch relationships. | Circuits where branch currents are easily expressed in terms of node voltages. |
| Mesh Analysis | Another MNA specialization using mesh currents as unknowns, suitable for planar circuits. | ( = meshes) | Exact (within numerical) | Can be simpler than MNA for planar circuits with many voltage sources. | Limited to planar circuits, not as general as MNA. | Planar circuits with numerous voltage sources. |
| Relaxation Methods | Iterative techniques (Gauss-Seidel, SOR) refining an initial guess until convergence. | Variable, depends on convergence rate | Approximate | Can be efficient for large, sparse systems and non-linear circuits. | Convergence not guaranteed, sensitive to initial guess, may require more iterations for complex circuits. | Large, sparse systems, circuits with non-linear components. |
| Charge Behavior Simulation (My Initial Approach) | Simulating the movement of individual charges over time. | ( = charges, = per-charge complexity, = time steps) | Approximate | Handles non-linear components and transient behavior naturally, provides detailed insights. | Very computationally expensive, approximate solutions dependent on simulation parameters, requires detailed component models. | Circuits with complex device behavior, transient analysis where detailed charge movement is important. |
| Hybrid Methods (A Completely Made-up Approach..) | Combining various techniques (e.g., MNA formulation with mixed solvers and simplified models). | Highly variable, depends on the combination of methods | Varies | Should achieve a balance between accuracy and speed, handling a wide range of circuits and complexities. | Can be complex to implement, but should be possible. | General-purpose circuit simulation, aiming for efficiency and accuracy across different scenarios. |
Note:
A large part of this project was about trying to strike a balance between accuracy and speed, and how to handle a wide range of circuits and complexities. This table provides an overview of the characteristics, advantages, disadvantages, and suitability of each method. The best method for a specific circuit problem will depend on the specific requirements and constraints of that problem. Determining those constraints is most likely the key to successful and efficient circuit simulation.
Now with this in mind, continuing from Part 4: (My analysis and execution might not be elegant, but these are all the methods I researched and considered)
Description: A systematic and general method for solving circuits. It combines KCL, KVL, and branch constitutive equations (e.g., Ohm's Law) into a matrix form. Handles a wide variety of circuit elements, including voltage sources, current sources, and more complex components.
Walkthrough Example:
Using the same circuit as in the nodal analysis example:

Component Values:
1. Identify Nodes and Branches: We have nodes labeled , , and a reference node (ground). We have branches containing R1, R2, R3, and V1.
2. Assign Node Voltages: Assign voltages and to nodes A and B, respectively.
3. Apply KCL at Nodes:
4. Include Equations for Voltage Sources:
5. Formulate the MNA Matrix: We can rewrite the equations in matrix form, incorporating the voltage source V1 directly into our equations. Since V1 is connected between the source and node , we can express in terms of :
Substituting into the KCL equations and simplifying, we get:
Node A:
Node B:
This system simplifies to two equations:
We can represent this in matrix form as:
Thus, and , which matches the previous results from nodal analysis.
Time Complexity: , where N is the number of nodes and additional variables introduced by voltage sources and other elements. However, the use of sparse matrix techniques can significantly reduce this complexity for large circuits.
Accuracy: Exact (within numerical precision limits).
Advantages:
Disadvantages:
Best Suited For: Moderate to large circuits, including those with voltage sources, current sources, and complex components.
Description: Nodal Analysis is a specialization of MNA that focuses on node voltages as the primary unknowns. It is particularly well-suited for circuits where branch currents can be easily expressed in terms of node voltages (e.g., using Ohm's Law).
Execution:
We've already covered a detailed nodal analysis walkthrough in Section 4 of the main report. Here's a summary:
1. Choose a Reference Node:
Usually ground.
2. Assign Voltages to Other Nodes:
These are the unknowns
3. Apply KCL at Each Non-Reference Node:
Express currents in terms of node voltages and resistances
4. Solve the System of Equations:
The resulting system of equations is solved to find the node voltages.
Time Complexity: , where N is the number of nodes. Sparse matrix techniques may improve this.
Accuracy: Exact (within numerical precision).
Advantages:
Disadvantages:
Best Suited For: Circuits where branch currents are easily expressed in terms of node voltages. (If you already have MNA, there is no reason to look at this method for obvious reasons)
Description: Mesh Analysis is another specialization of MNA that uses mesh currents (currents circulating in the loops of a planar circuit) as the primary unknowns. It's particularly useful for planar circuits with many voltage sources. As you can probably tell by now, each method has its own advantages and disadvantages. This is actually the most interesting part of the report !
Walkthrough Example:
Consider a simple planar circuit with two meshes:
Time Complexity: , where M is the number of meshes.
Accuracy: Exact (within numerical precision).
Advantages:
Disadvantages:
Best Suited For: Planar circuits with numerous voltage sources.
Description: Relaxation methods, such as Gauss-Seidel and Successive Over-Relaxation (SOR), are iterative techniques that start with an initial guess for the solution and refine it until convergence is achieved.
Walkthrough Example (Gauss-Seidel):
Time Complexity: Variable, depends on the convergence rate.
Accuracy: Approximate. The accuracy depends on the convergence criteria.
Advantages:
Disadvantages:
Best Suited For: Large, sparse systems, circuits with non-linear components.
Description: This approach involves simulating the movement of individual charges within the circuit based on electric fields and component behavior.
Walkthrough:
Time Complexity: , where C is the number of charges, F is the complexity of calculations per charge per time step, and T is the number of time steps.
Accuracy: Approximate, depends on the simulation parameters (time step, number of charges).
Advantages:
Disadvantages:
Best Suited For: Circuits with complex device behavior, transient analysis where detailed charge movement is important. Not practical for large circuits.
Description: Hybrid methods would combine different techniques to leverage their strengths. For example, MNA could be used to formulate the circuit equations, but then a relaxation method could be used to solve the resulting system of equations. Simplified models for some components could be used to reduce complexity. There are many combinations possible, which makes this very very interesting.
Walkthrough: Highly variable depending on the specific hybrid approach.
Time Complexity: Highly variable.
Accuracy: Varies.
Advantages:
Disadvantages:
Best Suited For: General-purpose circuit simulation, aiming for efficiency and accuracy across different scenarios. Requires careful design and selection of appropriate methods.
This probably already exists somewhere in the wild, considering there are 8 billion people on the planet. But I think finding the right combination of methods is a timeless challenge in the realm of circuit simulation. And that's what this project is all about!
This project researched and developed circuit solver and simulator methods that goes beyond the concepts covered in class by implementing advanced analysis techniques and dynamic simulation capabilities. The project demonstrates a strong understanding of electrical circuit principles, numerical methods, and software development through the time complexity analysis of various methods. The resulting software provides a valuable tool for learning, experimenting with, and analyzing electrical circuits. The project also highlights the importance of connecting theoretical knowledge to real-world applications and provides a foundation for further exploration into the field of circuit simulation and design.
- for ongoing) | Task | Time Spent (hours) |
|---|---|
| Research and Planning | 10 |
| UI Design and Implementation | 16.1 |
| Circuit Representation and Data Structures | 19.7 |
| Nodal Analysis Solver Implementation | 8.2 |
| Simulation Engine Implementation | - |
| Testing and Debugging | NO |
| Report Writing | 8.5 |
| Total | 62.5 |
Stack Exchange (Initial Research):
More Technical References (In-Depth):
Grounding References (Precedes all technical aspects):
+all references from Section 6 of report
My research journey began with exploratory browsing on Stack Exchange to gain an initial understanding of circuit solving and simulation approaches. This groundwork laid the foundation for my initial plan. Subsequently, I delved into more technical literature to explore specific methods in greater depth.
During this phase, I frequently encountered concepts that were impossible for me to grasp independently. I tried using ChatGPT as a tool to aid in understanding these complex topics, but you cannot rely on a probabilistic model for technical accuracy.
So I named the third category "grounding". These resources provided a more tangible foundation in the basic principles, which was the only way to achieve a true understanding of the more advanced material.
Interestingly, I only discovered that first Stack Exchange post towards the end of my snooping around and binging. It was like a missing piece, connecting the various concepts explored and revealing the broader context of circuit analysis methods.
The entire process felt like navigating a rabbit hole. Each resource led to new questions and deeper investigations. Based on my current understanding, I hypothesize that the ultimate solution for optimal circuit analysis might lie in a machine learning model.
Such a model could potentially integrate the collective knowledge from existing research, intelligently selecting and combining the most efficient methods for any given circuit. This is feasible because decades of research have extensively explored and refined various circuit analysis techniques. The strengths, weaknesses, and ideal use cases for each method are now well-understood.
However, these individual pieces of knowledge often exist in isolation. A machine learning model could bridge this gap by combining the collective knowledge from existing research, effectively integrating the strengths of each approach to achieve unprecedented efficiency and accuracy in circuit analysis.