Electronic Circuit Simulation - Static Analysis Implementation (part 3) [Python] by drifter1

View this thread on steempeak.com
· @drifter1 ·
$18.73
Electronic Circuit Simulation - Static Analysis Implementation (part 3) [Python]
<html>
https://i.postimg.cc/3rpy62Ww/circuit-sim-series.jpg<br>
[Custom Thumbnail]<br>
All the Code of the series can be found at the <strong>Github repository</strong>:
https://github.com/drifter1/circuitsim
<hr>
<h1>Introduction</h1>&nbsp;&nbsp;&nbsp;&nbsp;Hello it's a me again @drifter1! Today we continue with the <strong>Electronic Circuit Simulation series</strong>, a tutorial series where we will be implementing a full-on electronic circuit simulator (like SPICE) studying the whole concept and mainly physics behind it! In this article we continue with the <strong>Implementation of a complete simulator for Static Analysis</strong>. In this third and final step we will loop through the components list of the last article(s) to fill the MNA Matrices and solve the MNA System...
<h2>Requirements:</h2>
<ul>
<li>Physics and more specifically <strong>Electromagnetism Knowledge</strong></li>
<li>Knowing <strong>how to solve Linear Systems</strong> using Linear Algebra</li>
<li>Some understanding of the <strong>Programming Language Python</strong></li>
</ul>
<h2>Difficulty:</h2>Talking about the <strong>series in general</strong> this series can be rated:
<ul><li>Intermediate to Advanced</li></ul>
<strong>Today's topic(s)</strong> can be rated:
<ul><li>Intermediate</li></ul>
<hr>
<h1>Actual Tutorial Content</h1>
<h2>Fill MNA Matrices</h2>&nbsp;&nbsp;&nbsp;&nbsp;In the <strong>Modified Nodal Analysis</strong> (MNA) articles I talked you through the whole mathematics that give us the linear system, which <strong>solves Electronic Circuits for Node potentials and currents through Group 2 components</strong>. The final linear system that we got for Static Analysis is:<br>
<img src="https://steemitimages.com/640x0/https://quicklatex.com/cache3/66/ql_332e2ef426bbb259ea8cb0faacaf4966_l3.png"><br><br>
As we showed in this article, the <strong>A-matrix</strong> contains 4 matrices:<br>
<ul>
<li><strong>G</strong> β†’ Conductance matrix:</li>
<ul>
<li>each line and row corresponds to a specific node</li>
<li>diagonal is positive and containing the total "self" conductance of each node</li>
<li>the non-diagonal are negative and containing the mutual conductance between nodes</li>
</ul>
<li><strong>B</strong> β†’ Group 2 component incidence matrix:</li>
<ul>
<li>each column corresponds to a specific Group 2 component (voltage source)</li>
<li>'1' when node connected to '+' pole, '-1' when node connected to '-' pole and '0' when not incident</li>
</ul>
<li><strong>C</strong> β†’ Transpose of B</li>
<li><strong>D</strong> β†’ All-zero when only independent sources are considered</li>
</ul><br>
&nbsp;&nbsp;&nbsp;&nbsp;The <strong>b-matrix</strong> on the other hand contains the constant output of all independent sources (current and voltage), with the current values following the logic:<br>
<ul>
<li>positive when entering the node</li>
<li>negative when leaving the node</li>
</ul>
<h3>FIlling Procedure</h3>In our Code we will have to:<br>
<ol>
<li><strong>Calculate</strong> the number of Group 2 components and the Matrix size</li>
<li><strong>Define the matrices</strong> as numpy arrays (A is two-dimensional, b is one-dimensional)</li>
<li><strong>Define a variable that keeps track of the current Group 2 component index</strong> to help us fill the correct spot in the Matrices</li>
<li><strong>Loop through all the components</strong> and <strong>fill the Matrices</strong> depending on their type:</li>
<ul>
<li>Resistance affect the G-matrix of A</li>
<li>Capacitance is an open circuit in Static Analysis</li>
<li>Inductance works like an closed circuit with 0 resistance and 0 voltage affecting the B and C matrices of A and the b-matrix with a value of '0'</li>
<li>Voltage sources affect the B and C matrices of A and the b-matrix with their value</li>
<li>Current sources only affect the b-matrix with negative impact on the high node and negative impact on the low node</li>
</ul>
</ol>
<h3>Python Code</h3>The Code looks like this:<br>
<pre><code>def <strong>calculateMatrices</strong>(components, nodeCount):<br>
    # use global scope variables for component counts
    global voltageCount, inductorCount<br>
    # <strong>calculate g2 components</strong>
    g2Count = voltageCount + inductorCount
    print("Group 2 count:", g2Count)<br>
    # <strong>calculate matrix size</strong>
    matrixSize = nodeCount + g2Count - 1
    print("Matrix size:", matrixSize, "\n")<br>
    # <strong>define Matrices</strong>
    A = np.zeros((matrixSize, matrixSize))
    b = np.zeros(matrixSize)<br>
    # <strong>Group 2 component index</strong>
    g2Index = matrixSize - g2Count<br>
    # <strong>loop through all components</strong>
    for component in components:
        # store component info in temporary variable
        high = component.high
        low = component.low
        value = component.value<br>
        if <strong>component.comp_type == 'R'</strong>:
            # affects G-matrix of A
            # diagonal self-conductance of node
            if high != 0:
                A[high - 1][high - 1] = A[high - 1][high - 1] + 1/value
            if low != 0:
                A[low - 1][low - 1] = A[low - 1][low - 1] + 1/value<br>
            # mutual conductance between nodes
            if high != 0 and low != 0:
                A[high - 1][low - 1] = A[high - 1][low - 1] - 1/value
                A[low - 1][high - 1] = A[low - 1][high - 1] - 1/value<br>
        # elif <strong>component.comp_type == 'C'</strong>:
            # Capacitance is an open circuit for Static Analysis<br>
        elif <strong>component.comp_type == 'L'</strong>:
            # closed circuit  in Static Analysis: 0 resistance and 0 voltage
            # affects the B and C matrices of A
            if high != 0:
                A[high - 1][g2Index] = A[high - 1][g2Index] + 1
                A[g2Index][high - 1] = A[g2Index][high - 1] + 1
            if low != 0:
                A[low - 1][g2Index] = A[low - 1][g2Index] - 1
                A[g2Index][low - 1] = A[g2Index][low - 1] - 1<br>
            # affects b-matrix
            b[g2Index] = 0<br>
            # increase G2 index
            g2Index = g2Index + 1<br>
        elif <strong>component.comp_type == 'V'</strong>:
            # affects the B and C matrices of A
            if high != 0:
                A[high - 1][g2Index] = A[high - 1][g2Index] + 1
                A[g2Index][high - 1] = A[g2Index][high - 1] + 1
            if low != 0:
                A[low - 1][g2Index] = A[low - 1][g2Index] - 1
                A[g2Index][low - 1] = A[g2Index][low - 1] - 1<br>
            # affects b-matrix
            b[g2Index] = value<br>
            # increase G2 counter
            g2Index = g2Index + 1<br>
        elif <strong>component.comp_type == 'I'</strong>:
            # affects b-matrix
            if high != 0:
                b[high - 1] = b[high - 1] - value
            if low != 0:
                b[low - 1] = b[low - 1] + value<br>
    return A, b</code></pre>
<br>
Don't forget to <strong>import the numpy library</strong> using:<br>
<pre><code>import numpy as np</code></pre>
<hr>
<h2>Solve MNA System</h2>&nbsp;&nbsp;&nbsp;&nbsp;To solve the MNA System we basically only have to call the "np.linalg.solve()" function. So, the <strong>Code</strong> for solving is:<br>
<pre><code>def solveSystem(A, b):
    x = np.linalg.solve(A, b)
    return x</code></pre>
<br>
Let's tweak the <strong>main function</strong> from last time...<br>
<pre><code># Initialize component counters
voltageCount = 0
currentCount = 0
resistorCount = 0
capacitorCount = 0
inductorCount = 0<br>
# Parse File
fileName = "example.spice"
print("Parsing file...\n")
components = parseFile(fileName)<br>
# Map nodes
print("Mapping nodes...\n")
components, hashtable = mapNodes(components)<br>
# Print Information
print("Circuit Info")
print("Component count: ", len(components))
print("Voltage count: ", voltageCount)
print("Current count: ", currentCount)
print("Resistance count: ", resistorCount)
print("Capacitance count: ", capacitorCount)
print("Inductance count: ", inductorCount)
print("Node count: ", hashtable.nodeCount)<br>
print("\nNodes are mapped as following:")
for key, val in hashtable.nodes.items():
    print("\"" + key + "\" :", val)<br>
print("\nCircuit Components:")
for i in range(0, len(components)):
    print(components[i])<br>
# Calculate and solve system
print("\nCalculating MNA Matrices...\n")
A, b = calculateMatrices(components, hashtable.nodeCount)
print("A:\n", A)
print("b:\n", b)<br>
print("\nSolving System...\n")
x = solveSystem(A, b)
print("x:\n", x)</code></pre>
<br>
&nbsp;&nbsp;&nbsp;&nbsp;The numpy arrays are printed out with maximum precision and scientific notation. To get rid of it and make them print out in a more"pretty" way, let's define the following <strong>print options</strong>:<br>
<pre><code>np.set_printoptions(precision=3, suppress=True)</code></pre>
<hr>
<h2>Running the Examples</h2>
<h3>Simple Example</h3>Suppose the simple circuit (that we used way to often):<br>
<img src="https://steemitimages.com/640x0/https://i.postimg.cc/rwDXGXsG/Untitled-1.jpg"><br><br>
Running our simulator for this simple example we get:<br>
<img src="https://i.postimg.cc/BZp9BcKF/image.png"><br><br>
&nbsp;&nbsp;&nbsp;&nbsp;You can see that the system got filled with the same values that we found in the article <a href="https://steemit.com/utopian-io/@drifter1/electronic-circuit-simulation-modified-nodal-analysis-part-2-python">Modified Nodal Analysis (part 2)</a>, which was:<br>
<img src="https://steemitimages.com/640x0/https://quicklatex.com/cache3/f6/ql_2a03bbd062a53d2b4ae667bf91d417f6_l3.png"><br><br>
&nbsp;&nbsp;&nbsp;&nbsp;Of course it also gives us the same solution that we got with "manual" Code! Having the same exact order in the solution was just random luck, as the <strong>nodes could have been mapped way differently</strong> giving us a mixed up solution! That's exactly what happens in more advanced circuits...
<h3>Advanced Circuit 1</h3>Running our simulator for the first Netlist of the previous article we get:<br>
<img src="https://i.postimg.cc/k5KL6xCB/image.png"><br>
<img src="https://i.postimg.cc/pTB7kRpv/image.png">
<h3>Advanced Circuit 2</h3>Running our simulator for the second Netlist of the previous article we get:<br>
<img src="https://i.postimg.cc/65qSLsws/image.png"><br>
<img src="https://i.postimg.cc/cJybSr3Z/image.png"><br><br>
The last two circuits would take much more time to solve "by hand"!<br><br>
&nbsp;&nbsp;&nbsp;&nbsp;And with that we are actually finished with the Implementation for Static Analysis, or are we? Well, the <strong>A matrix contains lots of zeros</strong> and so we are not really that memory optimized right now. To optimize our simulator we can use a so called <strong>Sparse matrix to store the two-dimensional array A</strong>, which is exactly what we will be doing next time!
<hr>
<h2>RESOURCES</h2>
<h3>References:</h3>
<ol>
<li>https://www.geeksforgeeks.org/python-numpy/</li>
</ol>
<br>
Mathematical Equations were made using <a href="https://www.quicklatex.com/">quicklatex</a>
<hr>
<h2>Previous parts of the series</h2>
<h3>Introduction and Electromagnetism Background</h3>
<ul>
<li><a href="https://steemit.com/utopian-io/@drifter1/electronic-circuit-simulation-introduction-python">Introduction</a></li>
<li><a href="https://steemit.com/utopian-io/@drifter1/electronic-circuit-simulation-electromagnetism-background-part-1-python">Electromagnetism Background (part 1)</a></li>
<li><a href="https://steemit.com/utopian-io/@drifter1/electronic-circuit-simulation-electromagnetism-background-part-2-python">Electromagnetism Background (part 2)</a></li>
</ul>
<h3>Mesh and Nodal Analysis</h3>
<ul>
<li><a href="https://steemit.com/utopian-io/@drifter1/electronic-circuit-simulation-mesh-analysis-python">Mesh Analysis</a></li>
<li><a href="https://steemit.com/utopian-io/@drifter1/electronic-circuit-simulation-nodal-analysis-python">Nodal Analysis</a></li>
<li><a href="https://steemit.com/utopian-io/@drifter1/electronic-circuit-simulation-modified-mesh-analysis-by-inspection-python">Modified Mesh Analysis by Inspection</a></li>
<li><a href="https://steemit.com/utopian-io/@drifter1/electronic-circuit-simulation-modified-nodal-analysis-by-inspection-python">Modified Nodal Analysis by Inspection</a></li>
</ul>
<h3>Modified Nodal Analysis</h3>
<ul>
<li><a href="https://steemit.com/utopian-io/@drifter1/electronic-circuit-simulation-incidence-matrix-and-modified-kirchhoff-laws-python">Incidence Matrix and Modified Kirchhoff Laws</a></li>
<li><a href="https://steemit.com/utopian-io/@drifter1/electronic-circuit-simulation-modified-nodal-analysis-part-1-python">Modified Nodal Analysis (part 1)</a></li>
<li><a href="https://steemit.com/utopian-io/@drifter1/electronic-circuit-simulation-modified-nodal-analysis-part-2-python">Modified Nodal Analysis (part 2)</a></li>
</ul>
<h3>Static Analysis</h3>
<ul>
<li><a href="https://steemit.com/utopian-io/@drifter1/electronic-circuit-simulation-static-analysis-implementation-part-1-python">Static Analysis Implementation (part 1)</a></li>
<li><a href="https://steemit.com/utopian-io/@drifter1/electronic-circuit-simulation-static-analysis-implementation-part-2-python">Static Analysis Implementation (part 2)</a></li>
</ul>
<hr>
<h2>Final words | Next up on the project</h2>&nbsp;&nbsp;&nbsp;&nbsp;And this is actually it for today's post and I hope that you enjoyed it!<br><br>
&nbsp;&nbsp;&nbsp;&nbsp;Next time we will talk about Sparse Matrices, which will be used to optimize our Simulator for Memory, as we will not store 0 values anymore...<br><br>
So, see ya next time!
<hr>
<h2>GitHub Account:</h2>
https://github.com/drifter1<br>
https://steemitimages.com/0x0/https://media.giphy.com/media/ybITzMzIyabIs/giphy.gif
<br>
Keep on drifting! ;)
</html>
πŸ‘  , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , and 116 others
properties (23)
post_id74,623,927
authordrifter1
permlinkelectronic-circuit-simulation-static-analysis-implementation-part-3-python
categoryutopian-io
json_metadata{"community":"busy","app":"busy\/2.5.6","format":"markdown","tags":["utopian-io","tutorials","busy","programming","physics"],"users":["drifter1"],"links":["https:\/\/github.com\/drifter1\/circuitsim","\/@drifter1","https:\/\/steemit.com\/utopian-io\/@drifter1\/electronic-circuit-simulation-modified-nodal-analysis-part-2-python","https:\/\/www.geeksforgeeks.org\/python-numpy\/","https:\/\/www.quicklatex.com\/","https:\/\/steemit.com\/utopian-io\/@drifter1\/electronic-circuit-simulation-introduction-python","https:\/\/steemit.com\/utopian-io\/@drifter1\/electronic-circuit-simulation-electromagnetism-background-part-1-python","https:\/\/steemit.com\/utopian-io\/@drifter1\/electronic-circuit-simulation-electromagnetism-background-part-2-python","https:\/\/steemit.com\/utopian-io\/@drifter1\/electronic-circuit-simulation-mesh-analysis-python","https:\/\/steemit.com\/utopian-io\/@drifter1\/electronic-circuit-simulation-nodal-analysis-python"],"image":["https:\/\/i.postimg.cc\/3rpy62Ww\/circuit-sim-series.jpg","https:\/\/steemitimages.com\/640x0\/https:\/\/quicklatex.com\/cache3\/66\/ql_332e2ef426bbb259ea8cb0faacaf4966_l3.png","https:\/\/steemitimages.com\/640x0\/https:\/\/i.postimg.cc\/rwDXGXsG\/Untitled-1.jpg","https:\/\/i.postimg.cc\/BZp9BcKF\/image.png","https:\/\/steemitimages.com\/640x0\/https:\/\/quicklatex.com\/cache3\/f6\/ql_2a03bbd062a53d2b4ae667bf91d417f6_l3.png","https:\/\/i.postimg.cc\/k5KL6xCB\/image.png","https:\/\/i.postimg.cc\/pTB7kRpv\/image.png","https:\/\/i.postimg.cc\/65qSLsws\/image.png","https:\/\/i.postimg.cc\/cJybSr3Z\/image.png","https:\/\/steemitimages.com\/0x0\/https:\/\/media.giphy.com\/media\/ybITzMzIyabIs\/giphy.gif"]}
created2019-05-12 15:57:42
last_update2019-05-12 15:57:42
depth0
children4
net_rshares36,329,878,862,025
last_payout2019-05-19 15:57:42
cashout_time1969-12-31 23:59:59
total_payout_value14.217 SBD
curator_payout_value4.508 SBD
pending_payout_value0.000 SBD
promoted0.000 SBD
body_length13,834
author_reputation59,186,440,518,630
root_title"Electronic Circuit Simulation - Static Analysis Implementation (part 3) [Python]"
beneficiaries[]
max_accepted_payout1,000,000.000 SBD
percent_steem_dollars10,000
author_curate_reward""
vote details (180)
@portugalcoin ·
$7.53
Thank you for your contribution @drifter1.
We have been analyzing your tutorial and we suggest the following points:

- Your tutorial is very complete, well structured and easy to understand.Good Job!

- It would be very interesting if you had some GIFs showing the results. We find that GIFs are more intuitive than images.

Thank you for your work in developing this tutorial.
Looking forward to your upcoming tutorials.

Your contribution has been evaluated according to [Utopian policies and guidelines](https://join.utopian.io/guidelines), as well as a predefined set of questions pertaining to the category.

To view those questions and the relevant answers related to your post, [click here](https://review.utopian.io/result/8/2-1-1-1-1-3-1-3-).

---- 
Need help? Chat with us on [Discord](https://discord.gg/uTyJkNm).

[[utopian-moderator]](https://join.utopian.io/)
πŸ‘  , , , , , , , , , , , , , , , , , , , , , , , , , ,
properties (23)
post_id74,631,321
authorportugalcoin
permlinkre-drifter1-electronic-circuit-simulation-static-analysis-implementation-part-3-python-20190512t190914449z
categoryutopian-io
json_metadata{"tags":["utopian-io"],"users":["drifter1"],"links":["https:\/\/join.utopian.io\/guidelines","https:\/\/review.utopian.io\/result\/8\/2-1-1-1-1-3-1-3-","https:\/\/discord.gg\/uTyJkNm","https:\/\/join.utopian.io\/"],"app":"steemit\/0.1"}
created2019-05-12 19:09:15
last_update2019-05-12 19:09:15
depth1
children1
net_rshares14,625,695,409,762
last_payout2019-05-19 19:09:15
cashout_time1969-12-31 23:59:59
total_payout_value5.716 SBD
curator_payout_value1.810 SBD
pending_payout_value0.000 SBD
promoted0.000 SBD
body_length874
author_reputation214,343,891,436,406
root_title"Electronic Circuit Simulation - Static Analysis Implementation (part 3) [Python]"
beneficiaries[]
max_accepted_payout1,000,000.000 SBD
percent_steem_dollars10,000
author_curate_reward""
vote details (27)
@utopian-io ·
Thank you for your review, @portugalcoin! Keep up the good work!
properties (22)
post_id74,746,267
authorutopian-io
permlinkre-re-drifter1-electronic-circuit-simulation-static-analysis-implementation-part-3-python-20190512t190914449z-20190514t225705z
categoryutopian-io
json_metadata{"app":"beem\/0.20.17"}
created2019-05-14 22:57:06
last_update2019-05-14 22:57:06
depth2
children0
net_rshares0
last_payout2019-05-21 22:57:06
cashout_time1969-12-31 23:59:59
total_payout_value0.000 SBD
curator_payout_value0.000 SBD
pending_payout_value0.000 SBD
promoted0.000 SBD
body_length64
author_reputation152,913,012,544,965
root_title"Electronic Circuit Simulation - Static Analysis Implementation (part 3) [Python]"
beneficiaries[]
max_accepted_payout1,000,000.000 SBD
percent_steem_dollars10,000
@steem-ua ·
#### Hi @drifter1!

Your post was upvoted by @steem-ua, new Steem dApp, using UserAuthority for algorithmic post curation!
Your post is eligible for our upvote, thanks to our collaboration with @utopian-io!
**Feel free to join our [@steem-ua Discord server](https://discord.gg/KpBNYGz)**
πŸ‘  
properties (23)
post_id74,633,923
authorsteem-ua
permlinkre-electronic-circuit-simulation-static-analysis-implementation-part-3-python-20190512t202141z
categoryutopian-io
json_metadata{"app":"beem\/0.20.19"}
created2019-05-12 20:21:42
last_update2019-05-12 20:21:42
depth1
children0
net_rshares13,688,818,831
last_payout2019-05-19 20:21:42
cashout_time1969-12-31 23:59:59
total_payout_value0.000 SBD
curator_payout_value0.000 SBD
pending_payout_value0.000 SBD
promoted0.000 SBD
body_length287
author_reputation23,203,609,903,979
root_title"Electronic Circuit Simulation - Static Analysis Implementation (part 3) [Python]"
beneficiaries[]
max_accepted_payout1,000,000.000 SBD
percent_steem_dollars10,000
author_curate_reward""
vote details (1)
@utopian-io ·
Hey, @drifter1!

**Thanks for contributing on Utopian**.
We’re already looking forward to your next contribution!

**Get higher incentives and support Utopian.io!**
 Simply set @utopian.pay as a 5% (or higher) payout beneficiary on your contribution post (via [SteemPlus](https://chrome.google.com/webstore/detail/steemplus/mjbkjgcplmaneajhcbegoffkedeankaj?hl=en) or [Steeditor](https://steeditor.app)).

**Want to chat? Join us on Discord https://discord.gg/h52nFrV.**

<a href='https://steemconnect.com/sign/account-witness-vote?witness=utopian-io&approve=1'>Vote for Utopian Witness!</a>
πŸ‘  ,
properties (23)
post_id74,635,865
authorutopian-io
permlinkre-electronic-circuit-simulation-static-analysis-implementation-part-3-python-20190512t213401z
categoryutopian-io
json_metadata{"app":"beem\/0.20.17"}
created2019-05-12 21:34:03
last_update2019-05-12 21:34:03
depth1
children0
net_rshares14,365,063,849
last_payout2019-05-19 21:34:03
cashout_time1969-12-31 23:59:59
total_payout_value0.000 SBD
curator_payout_value0.000 SBD
pending_payout_value0.000 SBD
promoted0.000 SBD
body_length590
author_reputation152,913,012,544,965
root_title"Electronic Circuit Simulation - Static Analysis Implementation (part 3) [Python]"
beneficiaries[]
max_accepted_payout1,000,000.000 SBD
percent_steem_dollars10,000
author_curate_reward""
vote details (2)