8  Test 4

Test circuit number 4 has 26 branches, 13 nodes, 18 resistors, 3 independent voltage sources and 1 independednt current source. There are 4 dependent sources, one of each type. Theere are 18 passive components, all resistors. This circuit will test a large network with at least one of each type of source.

Figure 8.1: Test # 4 circuit

The net list generated by LTSpice.

* test_4.asc
V4 1 2 10
I2 3 4 5
F1 5 9 V1 5
E1 12 3 10 1 3
G1 7 10 9 4 2
H1 2 12 V2 2
R3 5 1 10
R4 3 7 1
R5 4 8 5
R9 1 9 9
R1 1 5 3
R10 8 0 10
R13 9 11 7
R14 10 9 10
R15 0 11 3
R2 3 5 5
R6 7 1 2
R7 8 7 6
R11 10 9 5
R12 0 10 9
R16 12 11 10
R8 3 8 5
R17 2 6 8
V1 6 3 0
V2 13 5 0
R18 12 13 4
.op
.backanno
.end
import os
from sympy import *
import numpy as np
from tabulate import tabulate
from scipy import signal
import matplotlib.pyplot as plt
import pandas as pd
import SymMNA
from IPython.display import display, Markdown, Math, Latex
init_printing()

8.1 Load the net list

net_list = '''
V4 1 2 10
I2 3 4 5
F1 5 9 V1 5
E1 12 3 10 1 3
G1 7 10 9 4 2
H1 2 12 V2 2
R3 5 1 10
R4 3 7 1
R5 4 8 5
R9 1 9 9
R1 1 5 3
R10 8 0 10
R13 9 11 7
R14 10 9 10
R15 0 11 3
R2 3 5 5
R6 7 1 2
R7 8 7 6
R11 10 9 5
R12 0 10 9
R16 12 11 10
R8 3 8 5
R17 2 6 8
V1 6 3 0
V2 13 5 0
R18 12 13 4
'''

8.2 Call the symbolic modified nodal analysis function

report, network_df, i_unk_df, A, X, Z = SymMNA.smna(net_list)

Display the equations

# reform X and Z into Matrix type for printing
Xp = Matrix(X)
Zp = Matrix(Z)
temp = ''
for i in range(len(X)):
    temp += '${:s}$<br>'.format(latex(Eq((A*Xp)[i:i+1][0],Zp[i])))

Markdown(temp)

\(I_{V4} + v_{1} \cdot \left(\frac{1}{R_{9}} + \frac{1}{R_{6}} + \frac{1}{R_{3}} + \frac{1}{R_{1}}\right) + v_{5} \left(- \frac{1}{R_{3}} - \frac{1}{R_{1}}\right) - \frac{v_{9}}{R_{9}} - \frac{v_{7}}{R_{6}} = 0\)
\(I_{H1} - I_{V4} + \frac{v_{2}}{R_{17}} - \frac{v_{6}}{R_{17}} = 0\)
\(- I_{Ea1} - I_{V1} + v_{3} \cdot \left(\frac{1}{R_{8}} + \frac{1}{R_{4}} + \frac{1}{R_{2}}\right) - \frac{v_{8}}{R_{8}} - \frac{v_{7}}{R_{4}} - \frac{v_{5}}{R_{2}} = - I_{2}\)
\(\frac{v_{4}}{R_{5}} - \frac{v_{8}}{R_{5}} = I_{2}\)
\(I_{F1} - I_{V2} + v_{1} \left(- \frac{1}{R_{3}} - \frac{1}{R_{1}}\right) + v_{5} \cdot \left(\frac{1}{R_{3}} + \frac{1}{R_{2}} + \frac{1}{R_{1}}\right) - \frac{v_{3}}{R_{2}} = 0\)
\(I_{V1} - \frac{v_{2}}{R_{17}} + \frac{v_{6}}{R_{17}} = 0\)
\(- g_{1} v_{4} + g_{1} v_{9} + v_{7} \cdot \left(\frac{1}{R_{7}} + \frac{1}{R_{6}} + \frac{1}{R_{4}}\right) - \frac{v_{8}}{R_{7}} - \frac{v_{1}}{R_{6}} - \frac{v_{3}}{R_{4}} = 0\)
\(v_{8} \cdot \left(\frac{1}{R_{8}} + \frac{1}{R_{7}} + \frac{1}{R_{5}} + \frac{1}{R_{10}}\right) - \frac{v_{3}}{R_{8}} - \frac{v_{7}}{R_{7}} - \frac{v_{4}}{R_{5}} = 0\)
\(- I_{F1} + v_{10} \left(- \frac{1}{R_{14}} - \frac{1}{R_{11}}\right) + v_{9} \cdot \left(\frac{1}{R_{9}} + \frac{1}{R_{14}} + \frac{1}{R_{13}} + \frac{1}{R_{11}}\right) - \frac{v_{1}}{R_{9}} - \frac{v_{11}}{R_{13}} = 0\)
\(g_{1} v_{4} + v_{10} \cdot \left(\frac{1}{R_{14}} + \frac{1}{R_{12}} + \frac{1}{R_{11}}\right) + v_{9} \left(- g_{1} - \frac{1}{R_{14}} - \frac{1}{R_{11}}\right) = 0\)
\(v_{11} \cdot \left(\frac{1}{R_{16}} + \frac{1}{R_{15}} + \frac{1}{R_{13}}\right) - \frac{v_{12}}{R_{16}} - \frac{v_{9}}{R_{13}} = 0\)
\(I_{Ea1} - I_{H1} + v_{12} \cdot \left(\frac{1}{R_{18}} + \frac{1}{R_{16}}\right) - \frac{v_{13}}{R_{18}} - \frac{v_{11}}{R_{16}} = 0\)
\(I_{V2} - \frac{v_{12}}{R_{18}} + \frac{v_{13}}{R_{18}} = 0\)
\(v_{1} - v_{2} = V_{4}\)
\(- v_{3} + v_{6} = V_{1}\)
\(v_{13} - v_{5} = V_{2}\)
\(I_{F1} - I_{V1} f_{1} = 0\)
\(ea_{1} v_{1} - ea_{1} v_{10} + v_{12} - v_{3} = 0\)
\(- I_{V2} h_{1} - v_{12} + v_{2} = 0\)

8.2.1 Netlist statistics

print(report)
Net list report
number of lines in netlist: 26
number of branches: 26
number of nodes: 13
number of unknown currents: 6
number of RLC (passive components): 18
number of inductors: 0
number of independent voltage sources: 3
number of independent current sources: 1
number of Op Amps: 0
number of E - VCVS: 1
number of G - VCCS: 1
number of F - CCCS: 1
number of H - CCVS: 1
number of K - Coupled inductors: 0

8.2.2 Connectivity Matrix

A

\(\displaystyle \left[\begin{array}{ccccccccccccccccccc}\frac{1}{R_{9}} + \frac{1}{R_{6}} + \frac{1}{R_{3}} + \frac{1}{R_{1}} & 0 & 0 & 0 & - \frac{1}{R_{3}} - \frac{1}{R_{1}} & 0 & - \frac{1}{R_{6}} & 0 & - \frac{1}{R_{9}} & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0\\0 & \frac{1}{R_{17}} & 0 & 0 & 0 & - \frac{1}{R_{17}} & 0 & 0 & 0 & 0 & 0 & 0 & 0 & -1 & 0 & 0 & 0 & 0 & 1\\0 & 0 & \frac{1}{R_{8}} + \frac{1}{R_{4}} + \frac{1}{R_{2}} & 0 & - \frac{1}{R_{2}} & 0 & - \frac{1}{R_{4}} & - \frac{1}{R_{8}} & 0 & 0 & 0 & 0 & 0 & 0 & -1 & 0 & 0 & -1 & 0\\0 & 0 & 0 & \frac{1}{R_{5}} & 0 & 0 & 0 & - \frac{1}{R_{5}} & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\- \frac{1}{R_{3}} - \frac{1}{R_{1}} & 0 & - \frac{1}{R_{2}} & 0 & \frac{1}{R_{3}} + \frac{1}{R_{2}} + \frac{1}{R_{1}} & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & -1 & 1 & 0 & 0\\0 & - \frac{1}{R_{17}} & 0 & 0 & 0 & \frac{1}{R_{17}} & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0\\- \frac{1}{R_{6}} & 0 & - \frac{1}{R_{4}} & - g_{1} & 0 & 0 & \frac{1}{R_{7}} + \frac{1}{R_{6}} + \frac{1}{R_{4}} & - \frac{1}{R_{7}} & g_{1} & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 0 & - \frac{1}{R_{8}} & - \frac{1}{R_{5}} & 0 & 0 & - \frac{1}{R_{7}} & \frac{1}{R_{8}} + \frac{1}{R_{7}} + \frac{1}{R_{5}} + \frac{1}{R_{10}} & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\- \frac{1}{R_{9}} & 0 & 0 & 0 & 0 & 0 & 0 & 0 & \frac{1}{R_{9}} + \frac{1}{R_{14}} + \frac{1}{R_{13}} + \frac{1}{R_{11}} & - \frac{1}{R_{14}} - \frac{1}{R_{11}} & - \frac{1}{R_{13}} & 0 & 0 & 0 & 0 & 0 & -1 & 0 & 0\\0 & 0 & 0 & g_{1} & 0 & 0 & 0 & 0 & - g_{1} - \frac{1}{R_{14}} - \frac{1}{R_{11}} & \frac{1}{R_{14}} + \frac{1}{R_{12}} + \frac{1}{R_{11}} & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & - \frac{1}{R_{13}} & 0 & \frac{1}{R_{16}} + \frac{1}{R_{15}} + \frac{1}{R_{13}} & - \frac{1}{R_{16}} & 0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & - \frac{1}{R_{16}} & \frac{1}{R_{18}} + \frac{1}{R_{16}} & - \frac{1}{R_{18}} & 0 & 0 & 0 & 0 & 1 & -1\\0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & - \frac{1}{R_{18}} & \frac{1}{R_{18}} & 0 & 0 & 1 & 0 & 0 & 0\\1 & -1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 0 & -1 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 0 & 0 & 0 & -1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & - f_{1} & 0 & 1 & 0 & 0\\ea_{1} & 0 & -1 & 0 & 0 & 0 & 0 & 0 & 0 & - ea_{1} & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & -1 & 0 & 0 & 0 & - h_{1} & 0 & 0 & 0\end{array}\right]\)

8.2.3 Unknown voltages and currents

X

\(\displaystyle \left[ v_{1}, \ v_{2}, \ v_{3}, \ v_{4}, \ v_{5}, \ v_{6}, \ v_{7}, \ v_{8}, \ v_{9}, \ v_{10}, \ v_{11}, \ v_{12}, \ v_{13}, \ I_{V4}, \ I_{V1}, \ I_{V2}, \ I_{F1}, \ I_{Ea1}, \ I_{H1}\right]\)

8.2.4 Known voltages and currents

Z

\(\displaystyle \left[ 0, \ 0, \ - I_{2}, \ I_{2}, \ 0, \ 0, \ 0, \ 0, \ 0, \ 0, \ 0, \ 0, \ 0, \ V_{4}, \ V_{1}, \ V_{2}, \ 0, \ 0, \ 0\right]\)

8.2.5 Network dataframe

network_df
element p node n node cp node cn node Vout value Vname Lname1 Lname2
0 V4 1 2 NaN NaN NaN 10.0 NaN NaN NaN
1 V1 6 3 NaN NaN NaN 0.0 NaN NaN NaN
2 V2 13 5 NaN NaN NaN 0.0 NaN NaN NaN
3 I2 3 4 NaN NaN NaN 5.0 NaN NaN NaN
4 F1 5 9 NaN NaN NaN 5.0 V1 NaN NaN
5 Ea1 12 3 10 1 NaN 3.0 NaN NaN NaN
6 G1 7 10 9 4 NaN 2.0 NaN NaN NaN
7 H1 2 12 NaN NaN NaN 2.0 V2 NaN NaN
8 R3 5 1 NaN NaN NaN 10.0 NaN NaN NaN
9 R4 3 7 NaN NaN NaN 1.0 NaN NaN NaN
10 R5 4 8 NaN NaN NaN 5.0 NaN NaN NaN
11 R9 1 9 NaN NaN NaN 9.0 NaN NaN NaN
12 R1 1 5 NaN NaN NaN 3.0 NaN NaN NaN
13 R10 8 0 NaN NaN NaN 10.0 NaN NaN NaN
14 R13 9 11 NaN NaN NaN 7.0 NaN NaN NaN
15 R14 10 9 NaN NaN NaN 10.0 NaN NaN NaN
16 R15 0 11 NaN NaN NaN 3.0 NaN NaN NaN
17 R2 3 5 NaN NaN NaN 5.0 NaN NaN NaN
18 R6 7 1 NaN NaN NaN 2.0 NaN NaN NaN
19 R7 8 7 NaN NaN NaN 6.0 NaN NaN NaN
20 R11 10 9 NaN NaN NaN 5.0 NaN NaN NaN
21 R12 0 10 NaN NaN NaN 9.0 NaN NaN NaN
22 R16 12 11 NaN NaN NaN 10.0 NaN NaN NaN
23 R8 3 8 NaN NaN NaN 5.0 NaN NaN NaN
24 R17 2 6 NaN NaN NaN 8.0 NaN NaN NaN
25 R18 12 13 NaN NaN NaN 4.0 NaN NaN NaN

8.2.6 Unknown current dataframe

i_unk_df
element p node n node
0 V4 1 2
1 V1 6 3
2 V2 13 5
3 F1 5 9
4 Ea1 12 3
5 H1 2 12

8.2.7 Build the network equations

# Put matrices into SymPy 
X = Matrix(X)
Z = Matrix(Z)

NE_sym = Eq(A*X,Z)

Turn the free symbols into SymPy variables.

var(str(NE_sym.free_symbols).replace('{','').replace('}',''))

\(\displaystyle \left( R_{5}, \ I_{V2}, \ v_{8}, \ h_{1}, \ v_{11}, \ R_{12}, \ R_{7}, \ I_{Ea1}, \ V_{4}, \ R_{1}, \ R_{3}, \ V_{1}, \ ea_{1}, \ v_{12}, \ R_{11}, \ g_{1}, \ R_{14}, \ v_{4}, \ I_{2}, \ v_{2}, \ v_{6}, \ v_{1}, \ v_{5}, \ R_{15}, \ V_{2}, \ I_{F1}, \ v_{13}, \ R_{18}, \ R_{17}, \ R_{4}, \ R_{6}, \ v_{10}, \ v_{3}, \ R_{13}, \ R_{8}, \ v_{9}, \ R_{16}, \ f_{1}, \ I_{H1}, \ v_{7}, \ R_{10}, \ R_{9}, \ R_{2}, \ I_{V4}, \ I_{V1}\right)\)

8.3 Symbolic solution

The symbolic solution was taking longer than a couple of minutes on my i3-8130U CPU @ 2.20GHz, so I interruped the kernel and commended the code.

#U_sym = solve(NE_sym,X)

Display the symbolic solution

#temp = ''
#for i in U_sym.keys():
#    temp += '${:s} = {:s}$<br>'.format(latex(i),latex(U_sym[i]))

#Markdown(temp)

8.4 Construct a dictionary of element values

element_values = SymMNA.get_part_values(network_df)

# display the component values
for k,v in element_values.items():
    print('{:s} = {:s}'.format(str(k), str(v)))
V4 = 10.0
V1 = 0.0
V2 = 0.0
I2 = 5.0
f1 = 5.0
ea1 = 3.0
g1 = 2.0
h1 = 2.0
R3 = 10.0
R4 = 1.0
R5 = 5.0
R9 = 9.0
R1 = 3.0
R10 = 10.0
R13 = 7.0
R14 = 10.0
R15 = 3.0
R2 = 5.0
R6 = 2.0
R7 = 6.0
R11 = 5.0
R12 = 9.0
R16 = 10.0
R8 = 5.0
R17 = 8.0
R18 = 4.0

8.5 Numerical solution

Substitute numerical values in place the symbolic reference designators.

NE = NE_sym.subs(element_values)

Display the equations with numeric values.

temp = ''
for i in range(shape(NE.lhs)[0]):
    temp += '${:s} = {:s}$<br>'.format(latex(NE.rhs[i]),latex(NE.lhs[i]))

Markdown(temp)

\(0 = I_{V4} + 1.04444444444444 v_{1} - 0.433333333333333 v_{5} - 0.5 v_{7} - 0.111111111111111 v_{9}\)
\(0 = I_{H1} - I_{V4} + 0.125 v_{2} - 0.125 v_{6}\)
\(-5.0 = - I_{Ea1} - I_{V1} + 1.4 v_{3} - 0.2 v_{5} - 1.0 v_{7} - 0.2 v_{8}\)
\(5.0 = 0.2 v_{4} - 0.2 v_{8}\)
\(0 = I_{F1} - I_{V2} - 0.433333333333333 v_{1} - 0.2 v_{3} + 0.633333333333333 v_{5}\)
\(0 = I_{V1} - 0.125 v_{2} + 0.125 v_{6}\)
\(0 = - 0.5 v_{1} - 1.0 v_{3} - 2.0 v_{4} + 1.66666666666667 v_{7} - 0.166666666666667 v_{8} + 2.0 v_{9}\)
\(0 = - 0.2 v_{3} - 0.2 v_{4} - 0.166666666666667 v_{7} + 0.666666666666667 v_{8}\)
\(0 = - I_{F1} - 0.111111111111111 v_{1} - 0.3 v_{10} - 0.142857142857143 v_{11} + 0.553968253968254 v_{9}\)
\(0 = 0.411111111111111 v_{10} + 2.0 v_{4} - 2.3 v_{9}\)
\(0 = 0.576190476190476 v_{11} - 0.1 v_{12} - 0.142857142857143 v_{9}\)
\(0 = I_{Ea1} - I_{H1} - 0.1 v_{11} + 0.35 v_{12} - 0.25 v_{13}\)
\(0 = I_{V2} - 0.25 v_{12} + 0.25 v_{13}\)
\(10.0 = v_{1} - v_{2}\)
\(0 = - v_{3} + v_{6}\)
\(0 = v_{13} - v_{5}\)
\(0 = I_{F1} - 5.0 I_{V1}\)
\(0 = 3.0 v_{1} - 3.0 v_{10} + v_{12} - v_{3}\)
\(0 = - 2.0 I_{V2} - v_{12} + v_{2}\)

Solve for voltages and currents.

U = solve(NE,X)

Display the numerical solution

Six significant digits are displayed so that results can be compared to LTSpice.

table_header = ['unknown', 'mag']
table_row = []

for name, value in U.items():
    table_row.append([str(name),float(value)])

print(tabulate(table_row, headers=table_header,colalign = ('left','decimal'),tablefmt="simple",floatfmt=('5s','.6f')))
unknown           mag
---------  ----------
v1          -2.528148
v2         -12.528148
v3         -26.854161
v4          18.928828
v5         -21.885182
v6         -26.854161
v7         -14.774289
v8          -6.071172
v9          16.675687
v10          1.207520
v11          1.418845
v12        -15.647159
v13        -21.885182
I_V4       -12.377360
I_V1         1.790752
I_V2         1.559506
I_F1         8.953758
I_Ea1      -14.021017
I_H1       -14.168112

The node voltages and current through the sources are solved for. The Sympy generated solution matches the LTSpice results:

       --- Operating Point ---

V(1):    -2.52815    voltage
V(2):    -12.5281    voltage
V(3):    -26.8542    voltage
V(4):    18.9288     voltage
V(5):    -21.8852    voltage
V(9):    16.6757     voltage
V(12):   -15.6472    voltage
V(10):   1.20752     voltage
V(7):    -14.7743    voltage
V(8):    -6.07117    voltage
V(11):   1.41885     voltage
V(6):    -26.8542    voltage
V(13):   -21.8852    voltage
I(F1):   8.95376     device_current
I(H1):   -14.1681    device_current
I(I2):   5   device_current
I(R3):   -1.9357     device_current
I(R4):   -12.0799    device_current
I(R5):   5   device_current
I(R9):   -2.13376    device_current
I(R1):   6.45234     device_current
I(R10):  -0.607117   device_current
I(R13):  2.17955     device_current
I(R14):  -1.54682    device_current
I(R15):  -0.472948   device_current
I(R2):   -0.993796   device_current
I(R6):   -6.12307    device_current
I(R7):   1.45052     device_current
I(R11):  -3.09363    device_current
I(R12):  -0.134169   device_current
I(R16):  -1.7066     device_current
I(R8):   -4.1566     device_current
I(R17):  1.79075     device_current
I(R18):  1.55951     device_current
I(G1):   -4.50628    device_current
I(E1):   -14.021     device_current
I(V4):   -12.3774    device_current
I(V1):   1.79075     device_current
I(V2):   1.55951     device_current

The results from LTSpice agree with the SymPy results.