30  Pi Filter

Figure 30.1: Pi filter schematic

30.1 Introduction

A question posted on Electronics Stackexchange by user15174 (2023) looked interesting, he asked:

Am trying to apply the FACTS method to find out the transfer function for this circuit as shown below. This is a Pi-filter circuit with all its component parasitics and also including the source and load resistances. I would like to find out the transfer function of this circuit and match its plot from Mathcad with simulation.

First, to find out the zeros of this transfer function by inspection, I placed all circuit elements in its high frequency state. I can observe the response Vout is still present. In that case, can I assume that this circuit has 6 zeros associated with it?

But as per the answer provided in this link, we have to place the other associated circuit element in its DC state and observe if the response is still present. Since this circuit has around 6 reactive elements, how do I decide which circuit element should be in DC State and which circuit element should be in high frequency state?

I was able to follow some examples done based on 2nd and 3rd order circuits shared in the above links. But with this circuit configuration and so many reactive elements, frankly I am lost. It would be great if you could share some insight on how to derive the transfer function for this circuit including its poles and zeros.

The FACTS (Fast Analytical Circuits Techniques) method refers to a circuit analysis technique that enables engineers to obtain the transfer functions and input and output impedances of a circuit by inspection without resorting to too much algebra. The circuits offered as illustrations of the technique are small with one or two reactive elements. Middlebrook (1991) seems to have been the first proponent of the method and describes what he calls design oriented analysis. He talks about low entropy equations, in which the terms and elements are ordered or grouped in such a way that their physical origin, where they come from in the circuit, and what part of the circuit contributes to this part of the final expression becomes obvious. The method is also described in Middlebrook (1992).

30.2 Community answers

There were two answers provided by the community. User Franc (2023) provided a detailed solution based on reducing the circuit to Z1, Z2 and Z3 as shown in Figure 30.2 and then substituting back into the transfer function the impedances for each of the Z’s. User Telsa23 provided a shorter answer, also based on reducing the circuit to Z1, Z2 and Z3, but where a different expression for the transfer function was obtained. Neither of these answers follow the FACTS method, since the Extra Element Theorem was not employed during the analysis.

30.3 Circuit description

Figure 30.1 shows the schematic as I re-drew it in LTSpice with all the values set to one. I numbered each of the nodes and made some changes to the reference designators. In the original question, no component values were provided. user15174 (2023) stated that component parasitics are included, but he didn’t indicate which circuit elements he considered parasitic. I’m going to consider C1, L3 and C2 as the main components of the Pi-Filter. \(R_{in}\) and \(R_{out}\) are the source and load impedances. All other elements in the schematic are parasitic and the values will be assigned later in the analysis.

With C1, L3 and C2 being considered as the main components, the circuit is a three section low pass filter, sometimes called a Pi filter because the connection represents the greek letter \(\pi\). The schematic in Figure 30.1 has 13 branches and 8 nodes.

30.4 Circuit analysis

user15174 (2023) asked for a FACTS analysis. However, I think the circuit has too many reactive components for a FACTS analysis since this is a 6th order circuit. Following my review of FACTS, I present a ‘brute force’ analysis followed by a rework of Franc (2023)’s solution. A MNA of the filter with the parasitic components removed is presented. This is a third order circuit and SymPy can obtain solutions for the poles of the transfer function.

30.5 FACTS

The origin of the FACTS circuit analysis method, as stated above, is from Middlebrook (1991). IEEE technical papers and books by Basso (2016) and Vorpérian (2002) have been written on the subject, however these are not free or available to download for free. FACTS is a circuit analysis method where the transfer function is determined by applying the Extra Element Theorem. Christophe Basso, Vatché Vorpérian and others have open source content available:

According to the open source FACTS literature:

The well-known and widely used methods of nodal or loop analysis, while effective for obtaining numerical solutions, are largely ineffective for deriving analytical solutions in symbolic form, except for simple circuits. Attempting to invert a matrix with symbolic entries, even for low-order matrices, results in tedious algebra and complex, high-entropy expressions that provide little meaningful insight.

The FACTS procedure, as illustrated in the open source literature, employs example circuits that are usually of order 1 or 2. The procedure results in equations that keep circuit elements grouped together and thus the equations are more intuitive. For 3rd order and higher circuits, the procedure becomes rather involved and I didn’t see any circuit analysis examples beyond a 2nd order circuit.

Traditional circuit analysis techniques usually don’t produce analytical answers, i.e. equations in terms of symbols. Both the FACTS procedure and the MNA Python code in this book yield analytical answers, with the FACTS results possibly being more intuitive and the MNA Python code providing an automated solution, which would then have to be algebraically manipulated to be put into a FACTS type solution. The circuit in question is a 6th order network and much too difficult to analyze by hand or with the FACTS method.

30.6 ‘Brute Force’ MNA procedure

Doing a so called brute force analysis. The goal is to get the transfer function, \(H(s)=\frac {V_2}{V_8}\) and the poles and zeros of \(H(s)\). SymPy will be used to ‘brute force’ analyze the circuit and solve for the transfer function and find the poles and zeros.

The net list for the filter is:

V1 8 0 1
R_in 1 8 1
R1 1 4 1
Ra 3 1 1
R2 2 3 1
R3 2 6 1
R_out 2 0 1
L1 4 5 1 Rser=0
L2 3 2 1 Rser=0
L3 6 7 1 Rser=0
C1 5 0 1
C2 2 3 1
C3 7 0 1

The following Python modules are used in this notebook.

from sympy import *
import numpy as np
from tabulate import tabulate
import pandas as pd
from scipy import signal
import matplotlib.pyplot as plt
import SymMNA
from IPython.display import display, Markdown, Math, Latex
init_printing()

Load the netlist generated from Figure 30.1.

net_list = '''
V1 8 0 1
R_in 1 8 1
R1 1 4 1
Ra 3 1 1
R2 2 3 1
R3 2 6 1
R_out 2 0 1
L1 4 5 1 
L2 3 2 1 
L3 6 7 1
C1 5 0 1
C2 2 3 1
C3 7 0 1
'''

Call the symbolic modified nodal analysis function.

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

Build the network equations.

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

NE_sym = Eq(A*X,Z)

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

\(0 = v_{1} \cdot \left(\frac{1}{Ra} + \frac{1}{R_{in}} + \frac{1}{R_{1}}\right) - \frac{v_{3}}{Ra} - \frac{v_{8}}{R_{in}} - \frac{v_{4}}{R_{1}}\)
\(0 = - I_{L2} + v_{2} \left(C_{2} s + \frac{1}{R_{out}} + \frac{1}{R_{3}} + \frac{1}{R_{2}}\right) + v_{3} \left(- C_{2} s - \frac{1}{R_{2}}\right) - \frac{v_{6}}{R_{3}}\)
\(0 = I_{L2} + v_{2} \left(- C_{2} s - \frac{1}{R_{2}}\right) + v_{3} \left(C_{2} s + \frac{1}{Ra} + \frac{1}{R_{2}}\right) - \frac{v_{1}}{Ra}\)
\(0 = I_{L1} - \frac{v_{1}}{R_{1}} + \frac{v_{4}}{R_{1}}\)
\(0 = C_{1} s v_{5} - I_{L1}\)
\(0 = I_{L3} - \frac{v_{2}}{R_{3}} + \frac{v_{6}}{R_{3}}\)
\(0 = C_{3} s v_{7} - I_{L3}\)
\(0 = I_{V1} - \frac{v_{1}}{R_{in}} + \frac{v_{8}}{R_{in}}\)
\(V_{1} = v_{8}\)
\(0 = - I_{L1} L_{1} s + v_{4} - v_{5}\)
\(0 = - I_{L2} L_{2} s - v_{2} + v_{3}\)
\(0 = - I_{L3} L_{3} s + v_{6} - v_{7}\)

As shown above, MNA generated many equations and these would be difficult to solve by hand and a symbolic soultion would take a lot of computing time.

Turn the free symbols into SymPy variables.

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

\(\displaystyle \left( L_{2}, \ v_{1}, \ I_{L2}, \ I_{V1}, \ I_{L3}, \ v_{2}, \ v_{4}, \ R_{out}, \ R_{2}, \ C_{2}, \ C_{3}, \ v_{3}, \ R_{1}, \ v_{8}, \ Ra, \ R_{3}, \ s, \ v_{5}, \ L_{1}, \ L_{3}, \ C_{1}, \ I_{L1}, \ v_{7}, \ v_{6}, \ V_{1}, \ R_{in}\right)\)

Generate the symbolic solution, which takes a couple of minutes on my laptop (i3-8130U 2.20GHz).

U_sym = solve(NE_sym,X)

Display the symbolic solution. The espressions are long, so code to display is commented.

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

# Markdown(temp)

Solve for the transfer function \(H(s)=\frac {V_2}{V_8}\) in symbolic form. As you can see the expression is long.

H_sym = (U_sym[v2]/U_sym[v8]).simplify().collect(s)
H_sym

\(\displaystyle \frac{R_{out} \left(C_{1} C_{2} C_{3} L_{1} L_{2} L_{3} R_{2} s^{6} + R_{2} + s^{5} \left(C_{1} C_{2} C_{3} L_{1} L_{2} R_{2} R_{3} + C_{1} C_{2} C_{3} L_{2} L_{3} R_{1} R_{2} + C_{1} C_{3} L_{1} L_{2} L_{3}\right) + s^{4} \left(C_{1} C_{2} C_{3} L_{2} R_{1} R_{2} R_{3} + C_{1} C_{2} L_{1} L_{2} R_{2} + C_{1} C_{3} L_{1} L_{2} R_{3} + C_{1} C_{3} L_{1} L_{3} R_{2} + C_{1} C_{3} L_{2} L_{3} R_{1} + C_{2} C_{3} L_{2} L_{3} R_{2}\right) + s^{3} \left(C_{1} C_{2} L_{2} R_{1} R_{2} + C_{1} C_{3} L_{1} R_{2} R_{3} + C_{1} C_{3} L_{2} R_{1} R_{3} + C_{1} C_{3} L_{3} R_{1} R_{2} + C_{1} L_{1} L_{2} + C_{2} C_{3} L_{2} R_{2} R_{3} + C_{3} L_{2} L_{3}\right) + s^{2} \left(C_{1} C_{3} R_{1} R_{2} R_{3} + C_{1} L_{1} R_{2} + C_{1} L_{2} R_{1} + C_{2} L_{2} R_{2} + C_{3} L_{2} R_{3} + C_{3} L_{3} R_{2}\right) + s \left(C_{1} R_{1} R_{2} + C_{3} R_{2} R_{3} + L_{2}\right)\right)}{R_{2} R_{in} + R_{2} R_{out} + R_{2} Ra + s^{6} \left(C_{1} C_{2} C_{3} L_{1} L_{2} L_{3} R_{2} R_{in} + C_{1} C_{2} C_{3} L_{1} L_{2} L_{3} R_{2} R_{out} + C_{1} C_{2} C_{3} L_{1} L_{2} L_{3} R_{2} Ra\right) + s^{5} \left(C_{1} C_{2} C_{3} L_{1} L_{2} R_{2} R_{3} R_{in} + C_{1} C_{2} C_{3} L_{1} L_{2} R_{2} R_{3} R_{out} + C_{1} C_{2} C_{3} L_{1} L_{2} R_{2} R_{3} Ra + C_{1} C_{2} C_{3} L_{1} L_{2} R_{2} R_{in} R_{out} + C_{1} C_{2} C_{3} L_{1} L_{2} R_{2} R_{out} Ra + C_{1} C_{2} C_{3} L_{2} L_{3} R_{1} R_{2} R_{in} + C_{1} C_{2} C_{3} L_{2} L_{3} R_{1} R_{2} R_{out} + C_{1} C_{2} C_{3} L_{2} L_{3} R_{1} R_{2} Ra + C_{1} C_{2} C_{3} L_{2} L_{3} R_{2} R_{in} R_{out} + C_{1} C_{2} C_{3} L_{2} L_{3} R_{2} R_{in} Ra + C_{1} C_{3} L_{1} L_{2} L_{3} R_{2} + C_{1} C_{3} L_{1} L_{2} L_{3} R_{in} + C_{1} C_{3} L_{1} L_{2} L_{3} R_{out} + C_{1} C_{3} L_{1} L_{2} L_{3} Ra\right) + s^{4} \left(C_{1} C_{2} C_{3} L_{2} R_{1} R_{2} R_{3} R_{in} + C_{1} C_{2} C_{3} L_{2} R_{1} R_{2} R_{3} R_{out} + C_{1} C_{2} C_{3} L_{2} R_{1} R_{2} R_{3} Ra + C_{1} C_{2} C_{3} L_{2} R_{1} R_{2} R_{in} R_{out} + C_{1} C_{2} C_{3} L_{2} R_{1} R_{2} R_{out} Ra + C_{1} C_{2} C_{3} L_{2} R_{2} R_{3} R_{in} R_{out} + C_{1} C_{2} C_{3} L_{2} R_{2} R_{3} R_{in} Ra + C_{1} C_{2} C_{3} L_{2} R_{2} R_{in} R_{out} Ra + C_{1} C_{2} L_{1} L_{2} R_{2} R_{in} + C_{1} C_{2} L_{1} L_{2} R_{2} R_{out} + C_{1} C_{2} L_{1} L_{2} R_{2} Ra + C_{1} C_{3} L_{1} L_{2} R_{2} R_{3} + C_{1} C_{3} L_{1} L_{2} R_{2} R_{out} + C_{1} C_{3} L_{1} L_{2} R_{3} R_{in} + C_{1} C_{3} L_{1} L_{2} R_{3} R_{out} + C_{1} C_{3} L_{1} L_{2} R_{3} Ra + C_{1} C_{3} L_{1} L_{2} R_{in} R_{out} + C_{1} C_{3} L_{1} L_{2} R_{out} Ra + C_{1} C_{3} L_{1} L_{3} R_{2} R_{in} + C_{1} C_{3} L_{1} L_{3} R_{2} R_{out} + C_{1} C_{3} L_{1} L_{3} R_{2} Ra + C_{1} C_{3} L_{2} L_{3} R_{1} R_{2} + C_{1} C_{3} L_{2} L_{3} R_{1} R_{in} + C_{1} C_{3} L_{2} L_{3} R_{1} R_{out} + C_{1} C_{3} L_{2} L_{3} R_{1} Ra + C_{1} C_{3} L_{2} L_{3} R_{2} R_{in} + C_{1} C_{3} L_{2} L_{3} R_{in} R_{out} + C_{1} C_{3} L_{2} L_{3} R_{in} Ra + C_{2} C_{3} L_{2} L_{3} R_{2} R_{in} + C_{2} C_{3} L_{2} L_{3} R_{2} R_{out} + C_{2} C_{3} L_{2} L_{3} R_{2} Ra\right) + s^{3} \left(C_{1} C_{2} L_{2} R_{1} R_{2} R_{in} + C_{1} C_{2} L_{2} R_{1} R_{2} R_{out} + C_{1} C_{2} L_{2} R_{1} R_{2} Ra + C_{1} C_{2} L_{2} R_{2} R_{in} R_{out} + C_{1} C_{2} L_{2} R_{2} R_{in} Ra + C_{1} C_{3} L_{1} R_{2} R_{3} R_{in} + C_{1} C_{3} L_{1} R_{2} R_{3} R_{out} + C_{1} C_{3} L_{1} R_{2} R_{3} Ra + C_{1} C_{3} L_{1} R_{2} R_{in} R_{out} + C_{1} C_{3} L_{1} R_{2} R_{out} Ra + C_{1} C_{3} L_{2} R_{1} R_{2} R_{3} + C_{1} C_{3} L_{2} R_{1} R_{2} R_{out} + C_{1} C_{3} L_{2} R_{1} R_{3} R_{in} + C_{1} C_{3} L_{2} R_{1} R_{3} R_{out} + C_{1} C_{3} L_{2} R_{1} R_{3} Ra + C_{1} C_{3} L_{2} R_{1} R_{in} R_{out} + C_{1} C_{3} L_{2} R_{1} R_{out} Ra + C_{1} C_{3} L_{2} R_{2} R_{3} R_{in} + C_{1} C_{3} L_{2} R_{2} R_{in} R_{out} + C_{1} C_{3} L_{2} R_{3} R_{in} R_{out} + C_{1} C_{3} L_{2} R_{3} R_{in} Ra + C_{1} C_{3} L_{2} R_{in} R_{out} Ra + C_{1} C_{3} L_{3} R_{1} R_{2} R_{in} + C_{1} C_{3} L_{3} R_{1} R_{2} R_{out} + C_{1} C_{3} L_{3} R_{1} R_{2} Ra + C_{1} C_{3} L_{3} R_{2} R_{in} R_{out} + C_{1} C_{3} L_{3} R_{2} R_{in} Ra + C_{1} L_{1} L_{2} R_{2} + C_{1} L_{1} L_{2} R_{in} + C_{1} L_{1} L_{2} R_{out} + C_{1} L_{1} L_{2} Ra + C_{2} C_{3} L_{2} R_{2} R_{3} R_{in} + C_{2} C_{3} L_{2} R_{2} R_{3} R_{out} + C_{2} C_{3} L_{2} R_{2} R_{3} Ra + C_{2} C_{3} L_{2} R_{2} R_{in} R_{out} + C_{2} C_{3} L_{2} R_{2} R_{out} Ra + C_{3} L_{2} L_{3} R_{2} + C_{3} L_{2} L_{3} R_{in} + C_{3} L_{2} L_{3} R_{out} + C_{3} L_{2} L_{3} Ra\right) + s^{2} \left(C_{1} C_{3} R_{1} R_{2} R_{3} R_{in} + C_{1} C_{3} R_{1} R_{2} R_{3} R_{out} + C_{1} C_{3} R_{1} R_{2} R_{3} Ra + C_{1} C_{3} R_{1} R_{2} R_{in} R_{out} + C_{1} C_{3} R_{1} R_{2} R_{out} Ra + C_{1} C_{3} R_{2} R_{3} R_{in} R_{out} + C_{1} C_{3} R_{2} R_{3} R_{in} Ra + C_{1} C_{3} R_{2} R_{in} R_{out} Ra + C_{1} L_{1} R_{2} R_{in} + C_{1} L_{1} R_{2} R_{out} + C_{1} L_{1} R_{2} Ra + C_{1} L_{2} R_{1} R_{2} + C_{1} L_{2} R_{1} R_{in} + C_{1} L_{2} R_{1} R_{out} + C_{1} L_{2} R_{1} Ra + C_{1} L_{2} R_{2} R_{in} + C_{1} L_{2} R_{in} R_{out} + C_{1} L_{2} R_{in} Ra + C_{2} L_{2} R_{2} R_{in} + C_{2} L_{2} R_{2} R_{out} + C_{2} L_{2} R_{2} Ra + C_{3} L_{2} R_{2} R_{3} + C_{3} L_{2} R_{2} R_{out} + C_{3} L_{2} R_{3} R_{in} + C_{3} L_{2} R_{3} R_{out} + C_{3} L_{2} R_{3} Ra + C_{3} L_{2} R_{in} R_{out} + C_{3} L_{2} R_{out} Ra + C_{3} L_{3} R_{2} R_{in} + C_{3} L_{3} R_{2} R_{out} + C_{3} L_{3} R_{2} Ra\right) + s \left(C_{1} R_{1} R_{2} R_{in} + C_{1} R_{1} R_{2} R_{out} + C_{1} R_{1} R_{2} Ra + C_{1} R_{2} R_{in} R_{out} + C_{1} R_{2} R_{in} Ra + C_{3} R_{2} R_{3} R_{in} + C_{3} R_{2} R_{3} R_{out} + C_{3} R_{2} R_{3} Ra + C_{3} R_{2} R_{in} R_{out} + C_{3} R_{2} R_{out} Ra + L_{2} R_{2} + L_{2} R_{in} + L_{2} R_{out} + L_{2} Ra\right)}\)

As shown above the symbolic solution is long on not very insightful. The FACTS method is supposed to reveal aspects of the circuit’s operation that is hidden by the algebra. I think the Pi Filter with parasitic elements included is too complex.

The numerator and denominator of the transfer function can be extracted for analysis.

n, d = fraction(H_sym)
display('numerator', n, 'denominator', d)
'numerator'

\(\displaystyle R_{out} \left(C_{1} C_{2} C_{3} L_{1} L_{2} L_{3} R_{2} s^{6} + R_{2} + s^{5} \left(C_{1} C_{2} C_{3} L_{1} L_{2} R_{2} R_{3} + C_{1} C_{2} C_{3} L_{2} L_{3} R_{1} R_{2} + C_{1} C_{3} L_{1} L_{2} L_{3}\right) + s^{4} \left(C_{1} C_{2} C_{3} L_{2} R_{1} R_{2} R_{3} + C_{1} C_{2} L_{1} L_{2} R_{2} + C_{1} C_{3} L_{1} L_{2} R_{3} + C_{1} C_{3} L_{1} L_{3} R_{2} + C_{1} C_{3} L_{2} L_{3} R_{1} + C_{2} C_{3} L_{2} L_{3} R_{2}\right) + s^{3} \left(C_{1} C_{2} L_{2} R_{1} R_{2} + C_{1} C_{3} L_{1} R_{2} R_{3} + C_{1} C_{3} L_{2} R_{1} R_{3} + C_{1} C_{3} L_{3} R_{1} R_{2} + C_{1} L_{1} L_{2} + C_{2} C_{3} L_{2} R_{2} R_{3} + C_{3} L_{2} L_{3}\right) + s^{2} \left(C_{1} C_{3} R_{1} R_{2} R_{3} + C_{1} L_{1} R_{2} + C_{1} L_{2} R_{1} + C_{2} L_{2} R_{2} + C_{3} L_{2} R_{3} + C_{3} L_{3} R_{2}\right) + s \left(C_{1} R_{1} R_{2} + C_{3} R_{2} R_{3} + L_{2}\right)\right)\)

'denominator'

\(\displaystyle R_{2} R_{in} + R_{2} R_{out} + R_{2} Ra + s^{6} \left(C_{1} C_{2} C_{3} L_{1} L_{2} L_{3} R_{2} R_{in} + C_{1} C_{2} C_{3} L_{1} L_{2} L_{3} R_{2} R_{out} + C_{1} C_{2} C_{3} L_{1} L_{2} L_{3} R_{2} Ra\right) + s^{5} \left(C_{1} C_{2} C_{3} L_{1} L_{2} R_{2} R_{3} R_{in} + C_{1} C_{2} C_{3} L_{1} L_{2} R_{2} R_{3} R_{out} + C_{1} C_{2} C_{3} L_{1} L_{2} R_{2} R_{3} Ra + C_{1} C_{2} C_{3} L_{1} L_{2} R_{2} R_{in} R_{out} + C_{1} C_{2} C_{3} L_{1} L_{2} R_{2} R_{out} Ra + C_{1} C_{2} C_{3} L_{2} L_{3} R_{1} R_{2} R_{in} + C_{1} C_{2} C_{3} L_{2} L_{3} R_{1} R_{2} R_{out} + C_{1} C_{2} C_{3} L_{2} L_{3} R_{1} R_{2} Ra + C_{1} C_{2} C_{3} L_{2} L_{3} R_{2} R_{in} R_{out} + C_{1} C_{2} C_{3} L_{2} L_{3} R_{2} R_{in} Ra + C_{1} C_{3} L_{1} L_{2} L_{3} R_{2} + C_{1} C_{3} L_{1} L_{2} L_{3} R_{in} + C_{1} C_{3} L_{1} L_{2} L_{3} R_{out} + C_{1} C_{3} L_{1} L_{2} L_{3} Ra\right) + s^{4} \left(C_{1} C_{2} C_{3} L_{2} R_{1} R_{2} R_{3} R_{in} + C_{1} C_{2} C_{3} L_{2} R_{1} R_{2} R_{3} R_{out} + C_{1} C_{2} C_{3} L_{2} R_{1} R_{2} R_{3} Ra + C_{1} C_{2} C_{3} L_{2} R_{1} R_{2} R_{in} R_{out} + C_{1} C_{2} C_{3} L_{2} R_{1} R_{2} R_{out} Ra + C_{1} C_{2} C_{3} L_{2} R_{2} R_{3} R_{in} R_{out} + C_{1} C_{2} C_{3} L_{2} R_{2} R_{3} R_{in} Ra + C_{1} C_{2} C_{3} L_{2} R_{2} R_{in} R_{out} Ra + C_{1} C_{2} L_{1} L_{2} R_{2} R_{in} + C_{1} C_{2} L_{1} L_{2} R_{2} R_{out} + C_{1} C_{2} L_{1} L_{2} R_{2} Ra + C_{1} C_{3} L_{1} L_{2} R_{2} R_{3} + C_{1} C_{3} L_{1} L_{2} R_{2} R_{out} + C_{1} C_{3} L_{1} L_{2} R_{3} R_{in} + C_{1} C_{3} L_{1} L_{2} R_{3} R_{out} + C_{1} C_{3} L_{1} L_{2} R_{3} Ra + C_{1} C_{3} L_{1} L_{2} R_{in} R_{out} + C_{1} C_{3} L_{1} L_{2} R_{out} Ra + C_{1} C_{3} L_{1} L_{3} R_{2} R_{in} + C_{1} C_{3} L_{1} L_{3} R_{2} R_{out} + C_{1} C_{3} L_{1} L_{3} R_{2} Ra + C_{1} C_{3} L_{2} L_{3} R_{1} R_{2} + C_{1} C_{3} L_{2} L_{3} R_{1} R_{in} + C_{1} C_{3} L_{2} L_{3} R_{1} R_{out} + C_{1} C_{3} L_{2} L_{3} R_{1} Ra + C_{1} C_{3} L_{2} L_{3} R_{2} R_{in} + C_{1} C_{3} L_{2} L_{3} R_{in} R_{out} + C_{1} C_{3} L_{2} L_{3} R_{in} Ra + C_{2} C_{3} L_{2} L_{3} R_{2} R_{in} + C_{2} C_{3} L_{2} L_{3} R_{2} R_{out} + C_{2} C_{3} L_{2} L_{3} R_{2} Ra\right) + s^{3} \left(C_{1} C_{2} L_{2} R_{1} R_{2} R_{in} + C_{1} C_{2} L_{2} R_{1} R_{2} R_{out} + C_{1} C_{2} L_{2} R_{1} R_{2} Ra + C_{1} C_{2} L_{2} R_{2} R_{in} R_{out} + C_{1} C_{2} L_{2} R_{2} R_{in} Ra + C_{1} C_{3} L_{1} R_{2} R_{3} R_{in} + C_{1} C_{3} L_{1} R_{2} R_{3} R_{out} + C_{1} C_{3} L_{1} R_{2} R_{3} Ra + C_{1} C_{3} L_{1} R_{2} R_{in} R_{out} + C_{1} C_{3} L_{1} R_{2} R_{out} Ra + C_{1} C_{3} L_{2} R_{1} R_{2} R_{3} + C_{1} C_{3} L_{2} R_{1} R_{2} R_{out} + C_{1} C_{3} L_{2} R_{1} R_{3} R_{in} + C_{1} C_{3} L_{2} R_{1} R_{3} R_{out} + C_{1} C_{3} L_{2} R_{1} R_{3} Ra + C_{1} C_{3} L_{2} R_{1} R_{in} R_{out} + C_{1} C_{3} L_{2} R_{1} R_{out} Ra + C_{1} C_{3} L_{2} R_{2} R_{3} R_{in} + C_{1} C_{3} L_{2} R_{2} R_{in} R_{out} + C_{1} C_{3} L_{2} R_{3} R_{in} R_{out} + C_{1} C_{3} L_{2} R_{3} R_{in} Ra + C_{1} C_{3} L_{2} R_{in} R_{out} Ra + C_{1} C_{3} L_{3} R_{1} R_{2} R_{in} + C_{1} C_{3} L_{3} R_{1} R_{2} R_{out} + C_{1} C_{3} L_{3} R_{1} R_{2} Ra + C_{1} C_{3} L_{3} R_{2} R_{in} R_{out} + C_{1} C_{3} L_{3} R_{2} R_{in} Ra + C_{1} L_{1} L_{2} R_{2} + C_{1} L_{1} L_{2} R_{in} + C_{1} L_{1} L_{2} R_{out} + C_{1} L_{1} L_{2} Ra + C_{2} C_{3} L_{2} R_{2} R_{3} R_{in} + C_{2} C_{3} L_{2} R_{2} R_{3} R_{out} + C_{2} C_{3} L_{2} R_{2} R_{3} Ra + C_{2} C_{3} L_{2} R_{2} R_{in} R_{out} + C_{2} C_{3} L_{2} R_{2} R_{out} Ra + C_{3} L_{2} L_{3} R_{2} + C_{3} L_{2} L_{3} R_{in} + C_{3} L_{2} L_{3} R_{out} + C_{3} L_{2} L_{3} Ra\right) + s^{2} \left(C_{1} C_{3} R_{1} R_{2} R_{3} R_{in} + C_{1} C_{3} R_{1} R_{2} R_{3} R_{out} + C_{1} C_{3} R_{1} R_{2} R_{3} Ra + C_{1} C_{3} R_{1} R_{2} R_{in} R_{out} + C_{1} C_{3} R_{1} R_{2} R_{out} Ra + C_{1} C_{3} R_{2} R_{3} R_{in} R_{out} + C_{1} C_{3} R_{2} R_{3} R_{in} Ra + C_{1} C_{3} R_{2} R_{in} R_{out} Ra + C_{1} L_{1} R_{2} R_{in} + C_{1} L_{1} R_{2} R_{out} + C_{1} L_{1} R_{2} Ra + C_{1} L_{2} R_{1} R_{2} + C_{1} L_{2} R_{1} R_{in} + C_{1} L_{2} R_{1} R_{out} + C_{1} L_{2} R_{1} Ra + C_{1} L_{2} R_{2} R_{in} + C_{1} L_{2} R_{in} R_{out} + C_{1} L_{2} R_{in} Ra + C_{2} L_{2} R_{2} R_{in} + C_{2} L_{2} R_{2} R_{out} + C_{2} L_{2} R_{2} Ra + C_{3} L_{2} R_{2} R_{3} + C_{3} L_{2} R_{2} R_{out} + C_{3} L_{2} R_{3} R_{in} + C_{3} L_{2} R_{3} R_{out} + C_{3} L_{2} R_{3} Ra + C_{3} L_{2} R_{in} R_{out} + C_{3} L_{2} R_{out} Ra + C_{3} L_{3} R_{2} R_{in} + C_{3} L_{3} R_{2} R_{out} + C_{3} L_{3} R_{2} Ra\right) + s \left(C_{1} R_{1} R_{2} R_{in} + C_{1} R_{1} R_{2} R_{out} + C_{1} R_{1} R_{2} Ra + C_{1} R_{2} R_{in} R_{out} + C_{1} R_{2} R_{in} Ra + C_{3} R_{2} R_{3} R_{in} + C_{3} R_{2} R_{3} R_{out} + C_{3} R_{2} R_{3} Ra + C_{3} R_{2} R_{in} R_{out} + C_{3} R_{2} R_{out} Ra + L_{2} R_{2} + L_{2} R_{in} + L_{2} R_{out} + L_{2} Ra\right)\)

Solve for the roots of the numerator.

solve(n,s)

\(\displaystyle \left[ \frac{- C_{1} R_{1} - \sqrt{C_{1}^{2} R_{1}^{2} - 4 C_{1} L_{1}}}{2 C_{1} L_{1}}, \ \frac{- C_{1} R_{1} + \sqrt{C_{1}^{2} R_{1}^{2} - 4 C_{1} L_{1}}}{2 C_{1} L_{1}}, \ \frac{- C_{3} R_{3} - \sqrt{C_{3}^{2} R_{3}^{2} - 4 C_{3} L_{3}}}{2 C_{3} L_{3}}, \ \frac{- C_{3} R_{3} + \sqrt{C_{3}^{2} R_{3}^{2} - 4 C_{3} L_{3}}}{2 C_{3} L_{3}}, \ \frac{- L_{2} - \sqrt{- 4 C_{2} L_{2} R_{2}^{2} + L_{2}^{2}}}{2 C_{2} L_{2} R_{2}}, \ \frac{- L_{2} + \sqrt{- 4 C_{2} L_{2} R_{2}^{2} + L_{2}^{2}}}{2 C_{2} L_{2} R_{2}}\right]\)

We can see that there are six zeros in the transfer function. Here can see what components are influncing the zeros. One of the gaols of the FACTS method was to determine the zeros of the network and express them in terms of the components.

Solve for the roots of the denominator

#solve(d,s)

SymPy could not find a solution for roots of denominator.

30.6.1 Use numerical values for components

Built a dictionary of element values. The LTSpice schematic had all the component values set to one.

element_values = SymMNA.get_part_values(network_df)
element_values

\(\displaystyle \left\{ C_{1} : 1.0, \ C_{2} : 1.0, \ C_{3} : 1.0, \ L_{1} : 1.0, \ L_{2} : 1.0, \ L_{3} : 1.0, \ R_{1} : 1.0, \ R_{2} : 1.0, \ R_{3} : 1.0, \ R_{in} : 1.0, \ R_{out} : 1.0, \ Ra : 1.0, \ V_{1} : 1.0\right\}\)

In this analysis, we are going to assum that the circuit is a low pass filter and the parasitics component values are scalled by 1000 from the value of the main components.

# the values of the main components 
Ca = 1 
Cb = 1
La = 2
sf = 1e3 # parasitic scale factor

element_values[R1] = Ca/sf
element_values[Ra] = La/sf
element_values[R2] = La*sf
element_values[R3] = Cb/sf

element_values[L1] = Ca/sf
element_values[L2] = La
element_values[L3] = Cb/sf
element_values[C1] = Ca
element_values[C2] = La/sf
element_values[C3] = Cb

element_values

\(\displaystyle \left\{ C_{1} : 1, \ C_{2} : 0.002, \ C_{3} : 1, \ L_{1} : 0.001, \ L_{2} : 2, \ L_{3} : 0.001, \ R_{1} : 0.001, \ R_{2} : 2000.0, \ R_{3} : 0.001, \ R_{in} : 1.0, \ R_{out} : 1.0, \ Ra : 0.002, \ V_{1} : 1.0\right\}\)

30.6.2 Numerical solution

Display the equations with component values.

NE = NE_sym.subs(element_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 = 1501.0 v_{1} - 500.0 v_{3} - 1000.0 v_{4} - 1.0 v_{8}\)
\(0 = - I_{L2} + v_{2} \cdot \left(0.002 s + 1001.0005\right) + v_{3} \left(- 0.002 s - 0.0005\right) - 1000.0 v_{6}\)
\(0 = I_{L2} - 500.0 v_{1} + v_{2} \left(- 0.002 s - 0.0005\right) + v_{3} \cdot \left(0.002 s + 500.0005\right)\)
\(0 = I_{L1} - 1000.0 v_{1} + 1000.0 v_{4}\)
\(0 = - I_{L1} + s v_{5}\)
\(0 = I_{L3} - 1000.0 v_{2} + 1000.0 v_{6}\)
\(0 = - I_{L3} + s v_{7}\)
\(0 = I_{V1} - 1.0 v_{1} + 1.0 v_{8}\)
\(1.0 = v_{8}\)
\(0 = - 0.001 I_{L1} s + v_{4} - v_{5}\)
\(0 = - 2 I_{L2} s - v_{2} + v_{3}\)
\(0 = - 0.001 I_{L3} s + v_{6} - v_{7}\)

Solve for voltages and currents and display the results.

U = solve(NE,X)

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

Markdown(temp)

\(v_{1} = \frac{2004.0 s^{6} + 1008509.0 s^{5} + 1006517006.0 s^{4} + 3012013501.0 s^{3} + 1005009503000.0 s^{2} + 1002503000000.0 s + 501000000000.0}{4004.0 s^{6} + 5017009.0 s^{5} + 2020025006.0 s^{4} + 1009025015001.0 s^{3} + 2011013003000.0 s^{2} + 2005003000000.0 s + 1001000000000.0}\)
\(v_{2} = \frac{2000.0 s^{6} + 4500.0 s^{5} + 4503000.0 s^{4} + 6000500.0 s^{3} + 3001500000.0 s^{2} + 1500000000.0 s + 500000000000.0}{4004.0 s^{6} + 5017009.0 s^{5} + 2020025006.0 s^{4} + 1009025015001.0 s^{3} + 2011013003000.0 s^{2} + 2005003000000.0 s + 1001000000000.0}\)
\(v_{3} = \frac{2000.0 s^{6} + 1004500.0 s^{5} + 1006503000.0 s^{4} + 3007000500.0 s^{3} + 1005001500000.0 s^{2} + 1001500000000.0 s + 500000000000.0}{4004.0 s^{6} + 5017009.0 s^{5} + 2020025006.0 s^{4} + 1009025015001.0 s^{3} + 2011013003000.0 s^{2} + 2005003000000.0 s + 1001000000000.0}\)
\(v_{4} = \frac{2004.0 s^{6} + 1006505.0 s^{5} + 1005510501.0 s^{4} + 2008507000.0 s^{3} + 1004007501000.0 s^{2} + 1002002000000.0 s + 501000000000.0}{4004.0 s^{6} + 5017009.0 s^{5} + 2020025006.0 s^{4} + 1009025015001.0 s^{3} + 2011013003000.0 s^{2} + 2005003000000.0 s + 1001000000000.0}\)
\(v_{5} = \frac{2004000.0 s^{4} + 1006505000.0 s^{3} + 1003506501000.0 s^{2} + 1002002000000.0 s + 501000000000.0}{4004.0 s^{6} + 5017009.0 s^{5} + 2020025006.0 s^{4} + 1009025015001.0 s^{3} + 2011013003000.0 s^{2} + 2005003000000.0 s + 1001000000000.0}\)
\(v_{6} = \frac{2000.0 s^{6} + 2500.0 s^{5} + 4500500.0 s^{4} + 3500000.0 s^{3} + 3000500000.0 s^{2} + 1000000000.0 s + 500000000000.0}{4004.0 s^{6} + 5017009.0 s^{5} + 2020025006.0 s^{4} + 1009025015001.0 s^{3} + 2011013003000.0 s^{2} + 2005003000000.0 s + 1001000000000.0}\)
\(v_{7} = \frac{2000000.0 s^{4} + 2500000.0 s^{3} + 2500500000.0 s^{2} + 1000000000.0 s + 500000000000.0}{4004.0 s^{6} + 5017009.0 s^{5} + 2020025006.0 s^{4} + 1009025015001.0 s^{3} + 2011013003000.0 s^{2} + 2005003000000.0 s + 1001000000000.0}\)
\(v_{8} = 1.0\)
\(I_{V1} = \frac{- 2000.0 s^{6} - 4008500.0 s^{5} - 1013508000.0 s^{4} - 1006013001500.0 s^{3} - 1006003500000.0 s^{2} - 1002500000000.0 s - 500000000000.0}{4004.0 s^{6} + 5017009.0 s^{5} + 2020025006.0 s^{4} + 1009025015001.0 s^{3} + 2011013003000.0 s^{2} + 2005003000000.0 s + 1001000000000.0}\)
\(I_{L1} = \frac{2004000.0 s^{5} + 1006505000.0 s^{4} + 1003506501000.0 s^{3} + 1002002000000.0 s^{2} + 501000000000.0 s}{4004.0 s^{6} + 5017009.0 s^{5} + 2020025006.0 s^{4} + 1009025015001.0 s^{3} + 2011013003000.0 s^{2} + 2005003000000.0 s + 1001000000000.0}\)
\(I_{L2} = \frac{500000.0 s^{2} + 500000.0 s + 500000000.0}{4004.0 s^{4} + 1009005.0 s^{3} + 1006007001.0 s^{2} + 1003002000.0 s + 1001000000.0}\)
\(I_{L3} = \frac{2000000.0 s^{5} + 2500000.0 s^{4} + 2500500000.0 s^{3} + 1000000000.0 s^{2} + 500000000000.0 s}{4004.0 s^{6} + 5017009.0 s^{5} + 2020025006.0 s^{4} + 1009025015001.0 s^{3} + 2011013003000.0 s^{2} + 2005003000000.0 s + 1001000000000.0}\)

H = (U[v2]/U[v8]).nsimplify().simplify().expand().together()
H

\(\displaystyle \frac{500 \cdot \left(4 s^{6} + 9 s^{5} + 9006 s^{4} + 12001 s^{3} + 6003000 s^{2} + 3000000 s + 1000000000\right)}{4004 s^{6} + 5017009 s^{5} + 2020025006 s^{4} + 1009025015001 s^{3} + 2011013003000 s^{2} + 2005003000000 s + 1001000000000}\)

The code below converst the SymPy equations into NumPy format. Extract the numerator and denominator polynomials so that the system can be defined in SciPy.

H_num, H_denom = fraction(H) #returns numerator and denominator

The SciPy function, TransferFunction, represents the system as the continuous-time transfer function and takes as inputs the coeeficients of the numerator and denominator polynominals.

# convert symbolic to NumPy polynomial
a = np.array(Poly(H_num, s).all_coeffs(), dtype=float)
b = np.array(Poly(H_denom, s).all_coeffs(), dtype=float)
sys = signal.TransferFunction(a,b)

30.6.3 Poles and zeros of the low pass transfer function

The poles and zeros of the transfer function can easly be obtained and plotted with the following code:

sys_zeros = np.roots(sys.num)
sys_poles = np.roots(sys.den)

# plot the poles and zeros
plt.plot(np.real(sys_zeros), np.imag(sys_zeros), 'ob', markerfacecolor='none')
plt.plot(np.real(sys_poles), np.imag(sys_poles), 'xr')
plt.legend(['Zeros', 'Poles'], loc=0)
plt.title('Pole / Zero Plot')
plt.xlabel('real part, \u03B1')
plt.ylabel('imaginary part, j\u03C9')
#plt.ylim((-2,2))
#plt.xlim((-4,0))
plt.grid()
plt.show()

Printing the value of the poles and zeros in radians per second.

print('number of zeros: {:d}'.format(len(sys_zeros)))
for i in sys_zeros:
    print('{:,.3f} rad/s'.format(i))
number of zeros: 6
-0.500+31.619j rad/s
-0.500-31.619j rad/s
-0.500+31.619j rad/s
-0.500-31.619j rad/s
-0.125+15.811j rad/s
-0.125-15.811j rad/s
print('number of poles: {:d}'.format(len(sys_poles)))
for i in sys_poles:
    print('{:,.3f} rad/s'.format(i))
number of poles: 6
-1,000.000+0.000j rad/s
-125.501+485.024j rad/s
-125.501-485.024j rad/s
-1.000+0.000j rad/s
-0.499+0.865j rad/s
-0.499-0.865j rad/s

30.6.4 Bode plot

Use the SciPy function bode to plot the magnitude and phase of the filter.

x = np.logspace(-2, 2, 1000, endpoint=False) #*2*np.pi
w, mag, phase = signal.bode(sys, w=x) # returns: rad/s, mag in dB, phase in deg

fig, ax1 = plt.subplots()
ax1.set_ylabel('magnitude, dB')
ax1.set_xlabel('frequency, radians')

plt.semilogx(w, mag,'-b')    # Bode magnitude plot

ax1.tick_params(axis='y')
#ax1.set_ylim((-30,20))
plt.grid()

# instantiate a second y-axes that shares the same x-axis
ax2 = ax1.twinx()
color = 'tab:blue'

plt.semilogx(w, phase,':',color='tab:red')  # Bode phase plot

ax2.set_ylabel('phase, deg',color=color)
ax2.tick_params(axis='y', labelcolor=color)
#ax2.set_ylim((-5,25))

plt.title('Magnitude and phase response')
plt.show()

30.7 Re-work of Franc (2023)’s solution

The solution provided by Franc (2023) is not a solution that following the FACTS method. He calculates the transfer function based on the ratio of the impedances of a voltage divider. Figure 30.2, shows the orginal circuit re-drawn with the branches replaced by their transformed impedances.

Figure 30.2: Pi filter schematic with branch impedances replaced by Z1, Z2 and Z3

The components for the branches are replace by Z1, Z2 and Z3.

Z1 = series connection of R1, L1 and C1

Z2 = series connection of Ra and (L2 || C2 || R2)

Z3 = series connection of R3, L3 and C3

Z4 = Z3 || R_out

The following defines the SymPy symbols used in the calculations. The function symbols takes a string of variable names separated by spaces or commas, and creates Symbols out of them.

L1, L2, L3, R1, R2, R3, Ra, R, R_out, R_in, C1, C2, C3, s, V1 = symbols('L1, L2, L3, R1, R2, R3, Ra, R, R_out, R_in, C1, C2, C3, s, V1')

30.7.1 Branches of the circuit

Z1 is the series connection of R1, C1 and L1.

Z1_sym = R1+s*L1+1/(s*C1)
Z1_sym

\(\displaystyle L_{1} s + R_{1} + \frac{1}{C_{1} s}\)

Z2 is the series connection of Ra and the paralle connection of R2, L2 and C2

Z2_sym = (Ra+1/(1/(1/(s*C2)) + 1/(s*L2) + 1/R2))
Z2_sym

\(\displaystyle Ra + \frac{1}{C_{2} s + \frac{1}{R_{2}} + \frac{1}{L_{2} s}}\)

Z3 is the series connection of R3, L3 and C3

Z3_sym = R3+s*L3+1/(s*C3)
Z3_sym

\(\displaystyle L_{3} s + R_{3} + \frac{1}{C_{3} s}\)

Z4 is the parallel combination of R_out and Z3.

Z4 = R_out || Z3

Z4_sym = R_out*Z3_sym/(R_out+Z3_sym)
Z4_sym

\(\displaystyle \frac{R_{out} \left(L_{3} s + R_{3} + \frac{1}{C_{3} s}\right)}{L_{3} s + R_{3} + R_{out} + \frac{1}{C_{3} s}}\)

Franc (2023) provided a MatCAD like set of calculations. Using “||” to indicate a parallel combination of components and a “+” to indicate a series combination of componets, some of his calculations are shown here:

\(Z_1 = R_2 + sL_1 + \frac {1}{sC_1}\)
\(Z_2 = R_6 + R_3 || sL_2 || \frac {1}{sC_2}\)
\(Z_3 = R_4 + sL_3 + \frac {1}{sC_3}\)
\(Z_4 = Z_3 || R_2\)

\(V_1 = \frac {(Z_1 || (Z_2+Z_4))} {(R_1+Z_1 || (Z_2+Z_4))} V_i\)

\(V_o = \frac {Z_4} {(Z_4+Z_2)} V_1\)

\(V_o = \frac {Z_4} {(Z_4+Z_2)} \frac {(Z_1 || (Z_2+Z_4))} {(R_1+Z_1 || (Z_2+Z_4))} V_i\)

Z1, Z2, Z3, Z4, R_in, R_out, V1 = symbols('Z1, Z2, Z3, Z4, R_in, R_out, V1')

Zx is the parallel combination of Z1, Z2 and Z4.

Zx = Z1*(Z2+Z4)/(Z1+Z2+Z4)
Zx

\(\displaystyle \frac{Z_{1} \left(Z_{2} + Z_{4}\right)}{Z_{1} + Z_{2} + Z_{4}}\)

The voltage at node 1 is calculated by using the voltage divider formula for Zx and Rin.

v_node1 = V1*Zx/(R_in+Zx)
v_node1

\(\displaystyle \frac{V_{1} Z_{1} \left(Z_{2} + Z_{4}\right)}{\left(R_{in} + \frac{Z_{1} \left(Z_{2} + Z_{4}\right)}{Z_{1} + Z_{2} + Z_{4}}\right) \left(Z_{1} + Z_{2} + Z_{4}\right)}\)

Vout is the voltage divider of Z2 and Z4.

V_out =  v_node1*Z4/(Z2+Z4)
V_out

\(\displaystyle \frac{V_{1} Z_{1} Z_{4}}{\left(R_{in} + \frac{Z_{1} \left(Z_{2} + Z_{4}\right)}{Z_{1} + Z_{2} + Z_{4}}\right) \left(Z_{1} + Z_{2} + Z_{4}\right)}\)

The trasfer function is Vout/Vin. H_franc_sym

H_franc_z = V_out/V1
H_franc_z

\(\displaystyle \frac{Z_{1} Z_{4}}{\left(R_{in} + \frac{Z_{1} \left(Z_{2} + Z_{4}\right)}{Z_{1} + Z_{2} + Z_{4}}\right) \left(Z_{1} + Z_{2} + Z_{4}\right)}\)

H_franc_z.simplify()

\(\displaystyle \frac{Z_{1} Z_{4}}{R_{in} \left(Z_{1} + Z_{2} + Z_{4}\right) + Z_{1} \left(Z_{2} + Z_{4}\right)}\)

Repeating the calculations from above, but using symbolic expressions for Z1, Z2, Z3 and Z4.

Zx is the combination of Z’s looking towards the output of the filter. Zx = Z1 || (Z2+Z4)

Zx_sym = Z1_sym*(Z2_sym+Z4_sym)/(Z1_sym+Z2_sym+Z4_sym)
Zx_sym

\(\displaystyle \frac{\left(L_{1} s + R_{1} + \frac{1}{C_{1} s}\right) \left(\frac{R_{out} \left(L_{3} s + R_{3} + \frac{1}{C_{3} s}\right)}{L_{3} s + R_{3} + R_{out} + \frac{1}{C_{3} s}} + Ra + \frac{1}{C_{2} s + \frac{1}{R_{2}} + \frac{1}{L_{2} s}}\right)}{L_{1} s + R_{1} + \frac{R_{out} \left(L_{3} s + R_{3} + \frac{1}{C_{3} s}\right)}{L_{3} s + R_{3} + R_{out} + \frac{1}{C_{3} s}} + Ra + \frac{1}{C_{2} s + \frac{1}{R_{2}} + \frac{1}{L_{2} s}} + \frac{1}{C_{1} s}}\)

The voltage at node 1 is

v_node1 = V1*Zx/(R_in+Zx)
v_node1_sym = V1*Zx_sym/(R_in+Zx_sym)
v_node1_sym

\(\displaystyle \frac{V_{1} \left(L_{1} s + R_{1} + \frac{1}{C_{1} s}\right) \left(\frac{R_{out} \left(L_{3} s + R_{3} + \frac{1}{C_{3} s}\right)}{L_{3} s + R_{3} + R_{out} + \frac{1}{C_{3} s}} + Ra + \frac{1}{C_{2} s + \frac{1}{R_{2}} + \frac{1}{L_{2} s}}\right)}{\left(R_{in} + \frac{\left(L_{1} s + R_{1} + \frac{1}{C_{1} s}\right) \left(\frac{R_{out} \left(L_{3} s + R_{3} + \frac{1}{C_{3} s}\right)}{L_{3} s + R_{3} + R_{out} + \frac{1}{C_{3} s}} + Ra + \frac{1}{C_{2} s + \frac{1}{R_{2}} + \frac{1}{L_{2} s}}\right)}{L_{1} s + R_{1} + \frac{R_{out} \left(L_{3} s + R_{3} + \frac{1}{C_{3} s}\right)}{L_{3} s + R_{3} + R_{out} + \frac{1}{C_{3} s}} + Ra + \frac{1}{C_{2} s + \frac{1}{R_{2}} + \frac{1}{L_{2} s}} + \frac{1}{C_{1} s}}\right) \left(L_{1} s + R_{1} + \frac{R_{out} \left(L_{3} s + R_{3} + \frac{1}{C_{3} s}\right)}{L_{3} s + R_{3} + R_{out} + \frac{1}{C_{3} s}} + Ra + \frac{1}{C_{2} s + \frac{1}{R_{2}} + \frac{1}{L_{2} s}} + \frac{1}{C_{1} s}\right)}\)

V_out is the output of the voltage divider circuit formed by Z2 and Z4

V_out_sym =  v_node1_sym*Z4_sym/(Z2_sym+Z4_sym)
V_out_sym

\(\displaystyle \frac{R_{out} V_{1} \left(L_{1} s + R_{1} + \frac{1}{C_{1} s}\right) \left(L_{3} s + R_{3} + \frac{1}{C_{3} s}\right)}{\left(R_{in} + \frac{\left(L_{1} s + R_{1} + \frac{1}{C_{1} s}\right) \left(\frac{R_{out} \left(L_{3} s + R_{3} + \frac{1}{C_{3} s}\right)}{L_{3} s + R_{3} + R_{out} + \frac{1}{C_{3} s}} + Ra + \frac{1}{C_{2} s + \frac{1}{R_{2}} + \frac{1}{L_{2} s}}\right)}{L_{1} s + R_{1} + \frac{R_{out} \left(L_{3} s + R_{3} + \frac{1}{C_{3} s}\right)}{L_{3} s + R_{3} + R_{out} + \frac{1}{C_{3} s}} + Ra + \frac{1}{C_{2} s + \frac{1}{R_{2}} + \frac{1}{L_{2} s}} + \frac{1}{C_{1} s}}\right) \left(L_{3} s + R_{3} + R_{out} + \frac{1}{C_{3} s}\right) \left(L_{1} s + R_{1} + \frac{R_{out} \left(L_{3} s + R_{3} + \frac{1}{C_{3} s}\right)}{L_{3} s + R_{3} + R_{out} + \frac{1}{C_{3} s}} + Ra + \frac{1}{C_{2} s + \frac{1}{R_{2}} + \frac{1}{L_{2} s}} + \frac{1}{C_{1} s}\right)}\)

30.7.2 H_franc_sym

The transfer function as determined by taking the impedance of branches and combining by series and parallel combinations can be expressed below.

H_franc_sym = V_out_sym/V1
H_franc_sym

\(\displaystyle \frac{R_{out} \left(L_{1} s + R_{1} + \frac{1}{C_{1} s}\right) \left(L_{3} s + R_{3} + \frac{1}{C_{3} s}\right)}{\left(R_{in} + \frac{\left(L_{1} s + R_{1} + \frac{1}{C_{1} s}\right) \left(\frac{R_{out} \left(L_{3} s + R_{3} + \frac{1}{C_{3} s}\right)}{L_{3} s + R_{3} + R_{out} + \frac{1}{C_{3} s}} + Ra + \frac{1}{C_{2} s + \frac{1}{R_{2}} + \frac{1}{L_{2} s}}\right)}{L_{1} s + R_{1} + \frac{R_{out} \left(L_{3} s + R_{3} + \frac{1}{C_{3} s}\right)}{L_{3} s + R_{3} + R_{out} + \frac{1}{C_{3} s}} + Ra + \frac{1}{C_{2} s + \frac{1}{R_{2}} + \frac{1}{L_{2} s}} + \frac{1}{C_{1} s}}\right) \left(L_{3} s + R_{3} + R_{out} + \frac{1}{C_{3} s}\right) \left(L_{1} s + R_{1} + \frac{R_{out} \left(L_{3} s + R_{3} + \frac{1}{C_{3} s}\right)}{L_{3} s + R_{3} + R_{out} + \frac{1}{C_{3} s}} + Ra + \frac{1}{C_{2} s + \frac{1}{R_{2}} + \frac{1}{L_{2} s}} + \frac{1}{C_{1} s}\right)}\)

The expression above, probably comes closest to the reults that would be obtained from a FACTS analysis.

H_franc_sym_1a = H_franc_sym.simplify()
H_franc_sym_1a

\(\displaystyle \frac{R_{out} \left(C_{1} s \left(L_{1} s + R_{1}\right) + 1\right) \left(C_{3} s \left(L_{3} s + R_{3}\right) + 1\right) \left(C_{2} L_{2} R_{2} s^{2} + L_{2} s + R_{2}\right)}{R_{in} \left(C_{1} L_{2} R_{2} s^{2} \left(C_{3} s \left(L_{3} s + R_{3} + R_{out}\right) + 1\right) + C_{1} R_{out} s \left(C_{3} s \left(L_{3} s + R_{3}\right) + 1\right) \left(C_{2} L_{2} R_{2} s^{2} + L_{2} s + R_{2}\right) + C_{1} s \left(C_{3} s \left(L_{3} s + R_{3} + R_{out}\right) + 1\right) \left(L_{1} s + R_{1} + Ra\right) \left(C_{2} L_{2} R_{2} s^{2} + L_{2} s + R_{2}\right) + \left(C_{3} s \left(L_{3} s + R_{3} + R_{out}\right) + 1\right) \left(C_{2} L_{2} R_{2} s^{2} + L_{2} s + R_{2}\right)\right) + \left(C_{1} s \left(L_{1} s + R_{1}\right) + 1\right) \left(L_{2} R_{2} s \left(C_{3} s \left(L_{3} s + R_{3} + R_{out}\right) + 1\right) + R_{out} \left(C_{3} s \left(L_{3} s + R_{3}\right) + 1\right) \left(C_{2} L_{2} R_{2} s^{2} + L_{2} s + R_{2}\right) + Ra \left(C_{3} s \left(L_{3} s + R_{3} + R_{out}\right) + 1\right) \left(C_{2} L_{2} R_{2} s^{2} + L_{2} s + R_{2}\right)\right)}\)

n, d = fraction(H_franc_sym_1a)
display('numerator', n, 'denominator', d)
'numerator'

\(\displaystyle R_{out} \left(C_{1} s \left(L_{1} s + R_{1}\right) + 1\right) \left(C_{3} s \left(L_{3} s + R_{3}\right) + 1\right) \left(C_{2} L_{2} R_{2} s^{2} + L_{2} s + R_{2}\right)\)

'denominator'

\(\displaystyle R_{in} \left(C_{1} L_{2} R_{2} s^{2} \left(C_{3} s \left(L_{3} s + R_{3} + R_{out}\right) + 1\right) + C_{1} R_{out} s \left(C_{3} s \left(L_{3} s + R_{3}\right) + 1\right) \left(C_{2} L_{2} R_{2} s^{2} + L_{2} s + R_{2}\right) + C_{1} s \left(C_{3} s \left(L_{3} s + R_{3} + R_{out}\right) + 1\right) \left(L_{1} s + R_{1} + Ra\right) \left(C_{2} L_{2} R_{2} s^{2} + L_{2} s + R_{2}\right) + \left(C_{3} s \left(L_{3} s + R_{3} + R_{out}\right) + 1\right) \left(C_{2} L_{2} R_{2} s^{2} + L_{2} s + R_{2}\right)\right) + \left(C_{1} s \left(L_{1} s + R_{1}\right) + 1\right) \left(L_{2} R_{2} s \left(C_{3} s \left(L_{3} s + R_{3} + R_{out}\right) + 1\right) + R_{out} \left(C_{3} s \left(L_{3} s + R_{3}\right) + 1\right) \left(C_{2} L_{2} R_{2} s^{2} + L_{2} s + R_{2}\right) + Ra \left(C_{3} s \left(L_{3} s + R_{3} + R_{out}\right) + 1\right) \left(C_{2} L_{2} R_{2} s^{2} + L_{2} s + R_{2}\right)\right)\)

Solve for the roots of the numberator.

n.simplify().expand()

\(\displaystyle C_{1} C_{2} C_{3} L_{1} L_{2} L_{3} R_{2} R_{out} s^{6} + C_{1} C_{2} C_{3} L_{1} L_{2} R_{2} R_{3} R_{out} s^{5} + C_{1} C_{2} C_{3} L_{2} L_{3} R_{1} R_{2} R_{out} s^{5} + C_{1} C_{2} C_{3} L_{2} R_{1} R_{2} R_{3} R_{out} s^{4} + C_{1} C_{2} L_{1} L_{2} R_{2} R_{out} s^{4} + C_{1} C_{2} L_{2} R_{1} R_{2} R_{out} s^{3} + C_{1} C_{3} L_{1} L_{2} L_{3} R_{out} s^{5} + C_{1} C_{3} L_{1} L_{2} R_{3} R_{out} s^{4} + C_{1} C_{3} L_{1} L_{3} R_{2} R_{out} s^{4} + C_{1} C_{3} L_{1} R_{2} R_{3} R_{out} s^{3} + C_{1} C_{3} L_{2} L_{3} R_{1} R_{out} s^{4} + C_{1} C_{3} L_{2} R_{1} R_{3} R_{out} s^{3} + C_{1} C_{3} L_{3} R_{1} R_{2} R_{out} s^{3} + C_{1} C_{3} R_{1} R_{2} R_{3} R_{out} s^{2} + C_{1} L_{1} L_{2} R_{out} s^{3} + C_{1} L_{1} R_{2} R_{out} s^{2} + C_{1} L_{2} R_{1} R_{out} s^{2} + C_{1} R_{1} R_{2} R_{out} s + C_{2} C_{3} L_{2} L_{3} R_{2} R_{out} s^{4} + C_{2} C_{3} L_{2} R_{2} R_{3} R_{out} s^{3} + C_{2} L_{2} R_{2} R_{out} s^{2} + C_{3} L_{2} L_{3} R_{out} s^{3} + C_{3} L_{2} R_{3} R_{out} s^{2} + C_{3} L_{3} R_{2} R_{out} s^{2} + C_{3} R_{2} R_{3} R_{out} s + L_{2} R_{out} s + R_{2} R_{out}\)

solve(n.simplify().expand(),s)

\(\displaystyle \left[ \frac{- C_{1} R_{1} - \sqrt{C_{1}^{2} R_{1}^{2} - 4 C_{1} L_{1}}}{2 C_{1} L_{1}}, \ \frac{- C_{1} R_{1} + \sqrt{C_{1}^{2} R_{1}^{2} - 4 C_{1} L_{1}}}{2 C_{1} L_{1}}, \ \frac{- C_{3} R_{3} - \sqrt{C_{3}^{2} R_{3}^{2} - 4 C_{3} L_{3}}}{2 C_{3} L_{3}}, \ \frac{- C_{3} R_{3} + \sqrt{C_{3}^{2} R_{3}^{2} - 4 C_{3} L_{3}}}{2 C_{3} L_{3}}, \ \frac{- L_{2} - \sqrt{- 4 C_{2} L_{2} R_{2}^{2} + L_{2}^{2}}}{2 C_{2} L_{2} R_{2}}, \ \frac{- L_{2} + \sqrt{- 4 C_{2} L_{2} R_{2}^{2} + L_{2}^{2}}}{2 C_{2} L_{2} R_{2}}\right]\)

We can see that there are six zeros in the transfer function. Here can see what components are influncing the zeros. Once of the gaols of the FACTS method was to determine the zeros of the network.

Solve for the roots of the denominator

d.simplify().expand().together()

\(\displaystyle C_{1} C_{2} C_{3} L_{1} L_{2} L_{3} R_{2} R_{in} s^{6} + C_{1} C_{2} C_{3} L_{1} L_{2} L_{3} R_{2} R_{out} s^{6} + C_{1} C_{2} C_{3} L_{1} L_{2} L_{3} R_{2} Ra s^{6} + C_{1} C_{2} C_{3} L_{1} L_{2} R_{2} R_{3} R_{in} s^{5} + C_{1} C_{2} C_{3} L_{1} L_{2} R_{2} R_{3} R_{out} s^{5} + C_{1} C_{2} C_{3} L_{1} L_{2} R_{2} R_{3} Ra s^{5} + C_{1} C_{2} C_{3} L_{1} L_{2} R_{2} R_{in} R_{out} s^{5} + C_{1} C_{2} C_{3} L_{1} L_{2} R_{2} R_{out} Ra s^{5} + C_{1} C_{2} C_{3} L_{2} L_{3} R_{1} R_{2} R_{in} s^{5} + C_{1} C_{2} C_{3} L_{2} L_{3} R_{1} R_{2} R_{out} s^{5} + C_{1} C_{2} C_{3} L_{2} L_{3} R_{1} R_{2} Ra s^{5} + C_{1} C_{2} C_{3} L_{2} L_{3} R_{2} R_{in} R_{out} s^{5} + C_{1} C_{2} C_{3} L_{2} L_{3} R_{2} R_{in} Ra s^{5} + C_{1} C_{2} C_{3} L_{2} R_{1} R_{2} R_{3} R_{in} s^{4} + C_{1} C_{2} C_{3} L_{2} R_{1} R_{2} R_{3} R_{out} s^{4} + C_{1} C_{2} C_{3} L_{2} R_{1} R_{2} R_{3} Ra s^{4} + C_{1} C_{2} C_{3} L_{2} R_{1} R_{2} R_{in} R_{out} s^{4} + C_{1} C_{2} C_{3} L_{2} R_{1} R_{2} R_{out} Ra s^{4} + C_{1} C_{2} C_{3} L_{2} R_{2} R_{3} R_{in} R_{out} s^{4} + C_{1} C_{2} C_{3} L_{2} R_{2} R_{3} R_{in} Ra s^{4} + C_{1} C_{2} C_{3} L_{2} R_{2} R_{in} R_{out} Ra s^{4} + C_{1} C_{2} L_{1} L_{2} R_{2} R_{in} s^{4} + C_{1} C_{2} L_{1} L_{2} R_{2} R_{out} s^{4} + C_{1} C_{2} L_{1} L_{2} R_{2} Ra s^{4} + C_{1} C_{2} L_{2} R_{1} R_{2} R_{in} s^{3} + C_{1} C_{2} L_{2} R_{1} R_{2} R_{out} s^{3} + C_{1} C_{2} L_{2} R_{1} R_{2} Ra s^{3} + C_{1} C_{2} L_{2} R_{2} R_{in} R_{out} s^{3} + C_{1} C_{2} L_{2} R_{2} R_{in} Ra s^{3} + C_{1} C_{3} L_{1} L_{2} L_{3} R_{2} s^{5} + C_{1} C_{3} L_{1} L_{2} L_{3} R_{in} s^{5} + C_{1} C_{3} L_{1} L_{2} L_{3} R_{out} s^{5} + C_{1} C_{3} L_{1} L_{2} L_{3} Ra s^{5} + C_{1} C_{3} L_{1} L_{2} R_{2} R_{3} s^{4} + C_{1} C_{3} L_{1} L_{2} R_{2} R_{out} s^{4} + C_{1} C_{3} L_{1} L_{2} R_{3} R_{in} s^{4} + C_{1} C_{3} L_{1} L_{2} R_{3} R_{out} s^{4} + C_{1} C_{3} L_{1} L_{2} R_{3} Ra s^{4} + C_{1} C_{3} L_{1} L_{2} R_{in} R_{out} s^{4} + C_{1} C_{3} L_{1} L_{2} R_{out} Ra s^{4} + C_{1} C_{3} L_{1} L_{3} R_{2} R_{in} s^{4} + C_{1} C_{3} L_{1} L_{3} R_{2} R_{out} s^{4} + C_{1} C_{3} L_{1} L_{3} R_{2} Ra s^{4} + C_{1} C_{3} L_{1} R_{2} R_{3} R_{in} s^{3} + C_{1} C_{3} L_{1} R_{2} R_{3} R_{out} s^{3} + C_{1} C_{3} L_{1} R_{2} R_{3} Ra s^{3} + C_{1} C_{3} L_{1} R_{2} R_{in} R_{out} s^{3} + C_{1} C_{3} L_{1} R_{2} R_{out} Ra s^{3} + C_{1} C_{3} L_{2} L_{3} R_{1} R_{2} s^{4} + C_{1} C_{3} L_{2} L_{3} R_{1} R_{in} s^{4} + C_{1} C_{3} L_{2} L_{3} R_{1} R_{out} s^{4} + C_{1} C_{3} L_{2} L_{3} R_{1} Ra s^{4} + C_{1} C_{3} L_{2} L_{3} R_{2} R_{in} s^{4} + C_{1} C_{3} L_{2} L_{3} R_{in} R_{out} s^{4} + C_{1} C_{3} L_{2} L_{3} R_{in} Ra s^{4} + C_{1} C_{3} L_{2} R_{1} R_{2} R_{3} s^{3} + C_{1} C_{3} L_{2} R_{1} R_{2} R_{out} s^{3} + C_{1} C_{3} L_{2} R_{1} R_{3} R_{in} s^{3} + C_{1} C_{3} L_{2} R_{1} R_{3} R_{out} s^{3} + C_{1} C_{3} L_{2} R_{1} R_{3} Ra s^{3} + C_{1} C_{3} L_{2} R_{1} R_{in} R_{out} s^{3} + C_{1} C_{3} L_{2} R_{1} R_{out} Ra s^{3} + C_{1} C_{3} L_{2} R_{2} R_{3} R_{in} s^{3} + C_{1} C_{3} L_{2} R_{2} R_{in} R_{out} s^{3} + C_{1} C_{3} L_{2} R_{3} R_{in} R_{out} s^{3} + C_{1} C_{3} L_{2} R_{3} R_{in} Ra s^{3} + C_{1} C_{3} L_{2} R_{in} R_{out} Ra s^{3} + C_{1} C_{3} L_{3} R_{1} R_{2} R_{in} s^{3} + C_{1} C_{3} L_{3} R_{1} R_{2} R_{out} s^{3} + C_{1} C_{3} L_{3} R_{1} R_{2} Ra s^{3} + C_{1} C_{3} L_{3} R_{2} R_{in} R_{out} s^{3} + C_{1} C_{3} L_{3} R_{2} R_{in} Ra s^{3} + C_{1} C_{3} R_{1} R_{2} R_{3} R_{in} s^{2} + C_{1} C_{3} R_{1} R_{2} R_{3} R_{out} s^{2} + C_{1} C_{3} R_{1} R_{2} R_{3} Ra s^{2} + C_{1} C_{3} R_{1} R_{2} R_{in} R_{out} s^{2} + C_{1} C_{3} R_{1} R_{2} R_{out} Ra s^{2} + C_{1} C_{3} R_{2} R_{3} R_{in} R_{out} s^{2} + C_{1} C_{3} R_{2} R_{3} R_{in} Ra s^{2} + C_{1} C_{3} R_{2} R_{in} R_{out} Ra s^{2} + C_{1} L_{1} L_{2} R_{2} s^{3} + C_{1} L_{1} L_{2} R_{in} s^{3} + C_{1} L_{1} L_{2} R_{out} s^{3} + C_{1} L_{1} L_{2} Ra s^{3} + C_{1} L_{1} R_{2} R_{in} s^{2} + C_{1} L_{1} R_{2} R_{out} s^{2} + C_{1} L_{1} R_{2} Ra s^{2} + C_{1} L_{2} R_{1} R_{2} s^{2} + C_{1} L_{2} R_{1} R_{in} s^{2} + C_{1} L_{2} R_{1} R_{out} s^{2} + C_{1} L_{2} R_{1} Ra s^{2} + C_{1} L_{2} R_{2} R_{in} s^{2} + C_{1} L_{2} R_{in} R_{out} s^{2} + C_{1} L_{2} R_{in} Ra s^{2} + C_{1} R_{1} R_{2} R_{in} s + C_{1} R_{1} R_{2} R_{out} s + C_{1} R_{1} R_{2} Ra s + C_{1} R_{2} R_{in} R_{out} s + C_{1} R_{2} R_{in} Ra s + C_{2} C_{3} L_{2} L_{3} R_{2} R_{in} s^{4} + C_{2} C_{3} L_{2} L_{3} R_{2} R_{out} s^{4} + C_{2} C_{3} L_{2} L_{3} R_{2} Ra s^{4} + C_{2} C_{3} L_{2} R_{2} R_{3} R_{in} s^{3} + C_{2} C_{3} L_{2} R_{2} R_{3} R_{out} s^{3} + C_{2} C_{3} L_{2} R_{2} R_{3} Ra s^{3} + C_{2} C_{3} L_{2} R_{2} R_{in} R_{out} s^{3} + C_{2} C_{3} L_{2} R_{2} R_{out} Ra s^{3} + C_{2} L_{2} R_{2} R_{in} s^{2} + C_{2} L_{2} R_{2} R_{out} s^{2} + C_{2} L_{2} R_{2} Ra s^{2} + C_{3} L_{2} L_{3} R_{2} s^{3} + C_{3} L_{2} L_{3} R_{in} s^{3} + C_{3} L_{2} L_{3} R_{out} s^{3} + C_{3} L_{2} L_{3} Ra s^{3} + C_{3} L_{2} R_{2} R_{3} s^{2} + C_{3} L_{2} R_{2} R_{out} s^{2} + C_{3} L_{2} R_{3} R_{in} s^{2} + C_{3} L_{2} R_{3} R_{out} s^{2} + C_{3} L_{2} R_{3} Ra s^{2} + C_{3} L_{2} R_{in} R_{out} s^{2} + C_{3} L_{2} R_{out} Ra s^{2} + C_{3} L_{3} R_{2} R_{in} s^{2} + C_{3} L_{3} R_{2} R_{out} s^{2} + C_{3} L_{3} R_{2} Ra s^{2} + C_{3} R_{2} R_{3} R_{in} s + C_{3} R_{2} R_{3} R_{out} s + C_{3} R_{2} R_{3} Ra s + C_{3} R_{2} R_{in} R_{out} s + C_{3} R_{2} R_{out} Ra s + L_{2} R_{2} s + L_{2} R_{in} s + L_{2} R_{out} s + L_{2} Ra s + R_{2} R_{in} + R_{2} R_{out} + R_{2} Ra\)

#solve(d,s)

SymPy could not find a solution for roots of denominator.

30.7.3 Use numerical values for components

The element vaules can be put into the equation.

element_values

\(\displaystyle \left\{ C_{1} : 1, \ C_{2} : 0.002, \ C_{3} : 1, \ L_{1} : 0.001, \ L_{2} : 2, \ L_{3} : 0.001, \ R_{1} : 0.001, \ R_{2} : 2000.0, \ R_{3} : 0.001, \ R_{in} : 1.0, \ R_{out} : 1.0, \ Ra : 0.002, \ V_{1} : 1.0\right\}\)

H_franc = H_franc_sym.subs(element_values)
H_franc

\(\displaystyle \frac{1.0 \left(0.001 s + 0.001 + \frac{1}{s}\right)^{2}}{\left(\frac{\left(0.001 s + 0.001 + \frac{1}{s}\right) \left(\frac{1.0 \cdot \left(0.001 s + 0.001 + \frac{1}{s}\right)}{0.001 s + 1.001 + \frac{1}{s}} + 0.002 + \frac{1}{0.002 s + 0.0005 + \frac{1}{2 s}}\right)}{0.001 s + \frac{1.0 \cdot \left(0.001 s + 0.001 + \frac{1}{s}\right)}{0.001 s + 1.001 + \frac{1}{s}} + 0.003 + \frac{1}{0.002 s + 0.0005 + \frac{1}{2 s}} + \frac{1}{s}} + 1.0\right) \left(0.001 s + 1.001 + \frac{1}{s}\right) \left(0.001 s + \frac{1.0 \cdot \left(0.001 s + 0.001 + \frac{1}{s}\right)}{0.001 s + 1.001 + \frac{1}{s}} + 0.003 + \frac{1}{0.002 s + 0.0005 + \frac{1}{2 s}} + \frac{1}{s}\right)}\)

Simplifying the expression.

H_franc = H_franc.nsimplify().simplify().expand().together()
H_franc

\(\displaystyle \frac{500 \cdot \left(4 s^{6} + 9 s^{5} + 9006 s^{4} + 12001 s^{3} + 6003000 s^{2} + 3000000 s + 1000000000\right)}{4004 s^{6} + 5017009 s^{5} + 2020025006 s^{4} + 1009025015001 s^{3} + 2011013003000 s^{2} + 2005003000000 s + 1001000000000}\)

30.7.4 Poles and zeros of the low pass transfer function

The poles and zeros of the transfer function can easly be obtained with the following code:

H_franc_num, H_franc_denom = fraction(H_franc) #returns numerator and denominator

The SciPy function, TransferFunction, represents the system as the continuous-time transfer function and takes as inputs the coeeficients of the numerator and denominator polynominals.

# convert symbolic to NumPy polynomial
a = np.array(Poly(H_franc_num, s).all_coeffs(), dtype=float)
b = np.array(Poly(H_franc_denom, s).all_coeffs(), dtype=float)
franc_sys = signal.TransferFunction(a,b)
franc_sys_zeros = np.roots(franc_sys.num)
franc_sys_poles = np.roots(franc_sys.den)

30.7.5 Pole zero plot

The poles and zeros of the function are plotted on the complex plane.

plt.plot(np.real(franc_sys_zeros), np.imag(franc_sys_zeros), 'ob', markerfacecolor='none')
plt.plot(np.real(franc_sys_poles), np.imag(franc_sys_poles), 'xr')
plt.legend(['Zeros', 'Poles'], loc=0)
plt.title('Pole / Zero Plot')
plt.xlabel('real part, \u03B1')
plt.ylabel('imaginary part, j\u03C9')
#plt.ylim((-2,2))
#plt.xlim((-2,0))
plt.grid()
plt.show()

Printing the value of the poles and zeros in radians per second.

print('number of zeros: {:d}'.format(len(franc_sys_zeros)))
for i in franc_sys_zeros:
    print('{:,.3f} rad/s'.format(i))
number of zeros: 6
-0.500+31.619j rad/s
-0.500-31.619j rad/s
-0.500+31.619j rad/s
-0.500-31.619j rad/s
-0.125+15.811j rad/s
-0.125-15.811j rad/s
print('number of poles: {:d}'.format(len(franc_sys_poles)))
for i in franc_sys_poles:
    print('{:,.3f} rad/s'.format(i))
number of poles: 6
-1,000.000+0.000j rad/s
-125.501+485.024j rad/s
-125.501-485.024j rad/s
-1.000+0.000j rad/s
-0.499+0.865j rad/s
-0.499-0.865j rad/s

30.7.6 Bode plot

Use the SciPy function bode to plot the magnitude and phase of the filter.

x = np.logspace(-2, 2, 1000, endpoint=False) #*2*np.pi
w_franc, mag_franc, phase_franc = signal.bode(franc_sys, w=x) # returns: rad/s, mag in dB, phase in deg

fig, ax1 = plt.subplots()
ax1.set_ylabel('magnitude, dB')
ax1.set_xlabel('frequency, radians')

plt.semilogx(w_franc, mag_franc,'-b')    # Bode magnitude plot

ax1.tick_params(axis='y')
#ax1.set_ylim((-30,20))
plt.grid()

# instantiate a second y-axes that shares the same x-axis
ax2 = ax1.twinx()
color = 'tab:blue'

plt.semilogx(w_franc, phase_franc,':',color='tab:red')  # Bode phase plot

ax2.set_ylabel('phase, deg',color=color)
ax2.tick_params(axis='y', labelcolor=color)
#ax2.set_ylim((-5,25))

plt.title('Magnitude and phase response')
plt.show()

30.8 Comapring solutions

Load the csv file from LTSpice.

fn = 'Pi-Filter-LTSpice.csv' # data from LTSpice
LTSpice_data = np.genfromtxt(fn, delimiter=',',skip_header=1)

# initaliaze some empty arrays
frequency = np.zeros(len(LTSpice_data))
voltage = np.zeros(len(LTSpice_data)).astype(complex)

# convert the csv data to complez numbers and store in the array
for i in range(len(LTSpice_data)):
    frequency[i] = LTSpice_data[i][0]
    voltage[i] = LTSpice_data[i][1] + LTSpice_data[i][2]*1j
fig, ax1 = plt.subplots()
ax1.set_ylabel('magnitude, dB')
ax1.set_xlabel('frequency, Hz')

plt.semilogx(frequency, 20*np.log10(np.abs(voltage)),'-k')    # LTSpice magnitude plot
plt.semilogx(w/(2*np.pi), mag,'-b')    # MNA magnitude plot
plt.semilogx(w_franc/(2*np.pi), mag_franc,'-r')    # FACTS magnitude plot

ax1.tick_params(axis='y')
#ax1.set_ylim((-30,20))
plt.grid()

# instantiate a second y-axes that shares the same x-axis
ax2 = ax1.twinx()
color = 'b'

plt.semilogx(frequency, np.unwrap(2*np.angle(voltage)/2) *180/np.pi,':',color='k',label='LTSpice')  # LTSpice phase plot
plt.semilogx(w/(2*np.pi), phase,':',color='b',label='MNA')  # MNA phase plot
plt.semilogx(w_franc/(2*np.pi), phase_franc,':',color='r',label='Franc')  # FACTS phase plot

ax2.set_ylabel('phase, deg',color=color)
ax2.tick_params(axis='y', labelcolor=color)
#ax2.set_ylim((-5,25))

ax2.plot(np.NaN, np.NaN, color='k', label='LTSpice')
ax2.plot(np.NaN, np.NaN, color='b', label='MNA')
ax2.plot(np.NaN, np.NaN, color='r', label='Franc')

plt.legend()
plt.title('Magnitude and phase response')
plt.show()

LTSpice, SMNA and Franc results agree.

30.9 Community answers

Both comunity answers did not provide a solution based on the FACTS method. Missing was the steps to extract the time constants of the circuit and from there find the zeros of the network.

The answer from Franc (2023) replaces each leg of the filter with Z’s and then uses series and parallel equalivent conbinations. As shown above this analysis provides only an approximate solution and probably would not cut the mustard in an acedemic or critical design reviwe.

The answer provided by Tesla23 is also suspect and seems wrong. The following calculations walk through some of his steps.

R, Z1, Z2, Z3 = symbols(‘R Z1 Z2 Z3’)

H_telsa23 = ((R*Z1*Z3)/(R*((Z2+2*Z1)*Z3 + Z1*Z2) + R**2*(Z3+Z2+Z1) + Z1*Z2*Z3)).subs({R:1})
H_telsa23

\(\displaystyle \frac{Z_{1} Z_{3}}{Z_{1} Z_{2} Z_{3} + Z_{1} Z_{2} + Z_{1} + Z_{2} + Z_{3} \cdot \left(2 Z_{1} + Z_{2}\right) + Z_{3}}\)

H_telsa23.simplify()

\(\displaystyle \frac{Z_{1} Z_{3}}{Z_{1} Z_{2} Z_{3} + Z_{1} Z_{2} + Z_{1} + Z_{2} + Z_{3} \cdot \left(2 Z_{1} + Z_{2}\right) + Z_{3}}\)

Comparing the results above to my rendition of FACTS, you can see that they are not the same.

H_franc_z.simplify()

\(\displaystyle \frac{Z_{1} Z_{4}}{R_{in} \left(Z_{1} + Z_{2} + Z_{4}\right) + Z_{1} \left(Z_{2} + Z_{4}\right)}\)

It’s not worth my time to analyze Tesla23’s answer to determine why there is a difference, especially since the thrust of these notebooks is MNA.

30.10 Reduced complexity circuit with source and load impedance

The following analysis finds the transfer function for the circuit below. The parasitic components have been removed from the schematic. The circuit is now a third order circuit. As shown below the poles of the transferfunction expressed symbolically are long and complex. It’s hard to see how a FACTS solution would yield design oriented results.

Figure 30.3: Pi filter with out parasitics
net_list = '''
V1 3 0 1
R_in 1 3 1
R_out 2 0 1
C1 1 0 1
C2 2 0 1
L1 1 2 1
'''

30.10.1 Call the symbolic modified nodal analysis function

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

The network equations for the circuit can be obtained from the A, X and Z values returned from the smna function. The A, X and Z are formulated into equations and displayed below. Markdown is an IPython function and latex is a SymPy printing function.

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

NE_sym = Eq(A*X,Z)

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

\(0 = I_{L1} + v_{1} \left(C_{1} s + \frac{1}{R_{in}}\right) - \frac{v_{3}}{R_{in}}\)
\(0 = - I_{L1} + v_{2} \left(C_{2} s + \frac{1}{R_{out}}\right)\)
\(0 = I_{V1} - \frac{v_{1}}{R_{in}} + \frac{v_{3}}{R_{in}}\)
\(V_{1} = v_{3}\)
\(0 = - I_{L1} L_{1} s + v_{1} - v_{2}\)

Turn the free symbols into SymPy variables.

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

\(\displaystyle \left( s, \ v_{1}, \ I_{V1}, \ L_{1}, \ C_{1}, \ I_{L1}, \ v_{2}, \ C_{2}, \ R_{out}, \ V_{1}, \ v_{3}, \ R_{in}\right)\)

30.10.2 Symbolic solution

The network equations can be solved symbolically.

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)

\(v_{1} = \frac{C_{2} L_{1} R_{out} V_{1} s^{2} + L_{1} V_{1} s + R_{out} V_{1}}{C_{1} C_{2} L_{1} R_{in} R_{out} s^{3} + C_{1} L_{1} R_{in} s^{2} + C_{1} R_{in} R_{out} s + C_{2} L_{1} R_{out} s^{2} + C_{2} R_{in} R_{out} s + L_{1} s + R_{in} + R_{out}}\)
\(v_{2} = \frac{R_{out} V_{1}}{C_{1} C_{2} L_{1} R_{in} R_{out} s^{3} + C_{1} L_{1} R_{in} s^{2} + C_{1} R_{in} R_{out} s + C_{2} L_{1} R_{out} s^{2} + C_{2} R_{in} R_{out} s + L_{1} s + R_{in} + R_{out}}\)
\(v_{3} = V_{1}\)
\(I_{V1} = \frac{- C_{1} C_{2} L_{1} R_{out} V_{1} s^{3} - C_{1} L_{1} V_{1} s^{2} - C_{1} R_{out} V_{1} s - C_{2} R_{out} V_{1} s - V_{1}}{C_{1} C_{2} L_{1} R_{in} R_{out} s^{3} + C_{1} L_{1} R_{in} s^{2} + C_{1} R_{in} R_{out} s + C_{2} L_{1} R_{out} s^{2} + C_{2} R_{in} R_{out} s + L_{1} s + R_{in} + R_{out}}\)
\(I_{L1} = \frac{C_{2} R_{out} V_{1} s + V_{1}}{C_{1} C_{2} L_{1} R_{in} R_{out} s^{3} + C_{1} L_{1} R_{in} s^{2} + C_{1} R_{in} R_{out} s + C_{2} L_{1} R_{out} s^{2} + C_{2} R_{in} R_{out} s + L_{1} s + R_{in} + R_{out}}\)

30.10.3 Transfer function

H_sym_1  = (U_sym[v2]/U_sym[v3]).simplify()
H_sym_1

\(\displaystyle \frac{R_{out}}{C_{1} C_{2} L_{1} R_{in} R_{out} s^{3} + C_{1} L_{1} R_{in} s^{2} + C_{1} R_{in} R_{out} s + C_{2} L_{1} R_{out} s^{2} + C_{2} R_{in} R_{out} s + L_{1} s + R_{in} + R_{out}}\)

n, d = fraction(H_sym_1)
display('numerator', n, 'denominator', d)
'numerator'

\(\displaystyle R_{out}\)

'denominator'

\(\displaystyle C_{1} C_{2} L_{1} R_{in} R_{out} s^{3} + C_{1} L_{1} R_{in} s^{2} + C_{1} R_{in} R_{out} s + C_{2} L_{1} R_{out} s^{2} + C_{2} R_{in} R_{out} s + L_{1} s + R_{in} + R_{out}\)

Solve for the roots of the denominator

d.simplify().expand().together()
#d.simplify().expand()

\(\displaystyle C_{1} C_{2} L_{1} R_{in} R_{out} s^{3} + C_{1} L_{1} R_{in} s^{2} + C_{1} R_{in} R_{out} s + C_{2} L_{1} R_{out} s^{2} + C_{2} R_{in} R_{out} s + L_{1} s + R_{in} + R_{out}\)

solve(d,s)

\(\displaystyle \left[ - \frac{- \frac{3 \left(C_{1} R_{in} R_{out} + C_{2} R_{in} R_{out} + L_{1}\right)}{C_{1} C_{2} L_{1} R_{in} R_{out}} + \frac{\left(C_{1} R_{in} + C_{2} R_{out}\right)^{2}}{C_{1}^{2} C_{2}^{2} R_{in}^{2} R_{out}^{2}}}{3 \sqrt[3]{\frac{\sqrt{- 4 \left(- \frac{3 \left(C_{1} R_{in} R_{out} + C_{2} R_{in} R_{out} + L_{1}\right)}{C_{1} C_{2} L_{1} R_{in} R_{out}} + \frac{\left(C_{1} R_{in} + C_{2} R_{out}\right)^{2}}{C_{1}^{2} C_{2}^{2} R_{in}^{2} R_{out}^{2}}\right)^{3} + \left(\frac{27 \left(R_{in} + R_{out}\right)}{C_{1} C_{2} L_{1} R_{in} R_{out}} - \frac{9 \left(C_{1} R_{in} + C_{2} R_{out}\right) \left(C_{1} R_{in} R_{out} + C_{2} R_{in} R_{out} + L_{1}\right)}{C_{1}^{2} C_{2}^{2} L_{1} R_{in}^{2} R_{out}^{2}} + \frac{2 \left(C_{1} R_{in} + C_{2} R_{out}\right)^{3}}{C_{1}^{3} C_{2}^{3} R_{in}^{3} R_{out}^{3}}\right)^{2}}}{2} + \frac{27 \left(R_{in} + R_{out}\right)}{2 C_{1} C_{2} L_{1} R_{in} R_{out}} - \frac{9 \left(C_{1} R_{in} + C_{2} R_{out}\right) \left(C_{1} R_{in} R_{out} + C_{2} R_{in} R_{out} + L_{1}\right)}{2 C_{1}^{2} C_{2}^{2} L_{1} R_{in}^{2} R_{out}^{2}} + \frac{\left(C_{1} R_{in} + C_{2} R_{out}\right)^{3}}{C_{1}^{3} C_{2}^{3} R_{in}^{3} R_{out}^{3}}}} - \frac{\sqrt[3]{\frac{\sqrt{- 4 \left(- \frac{3 \left(C_{1} R_{in} R_{out} + C_{2} R_{in} R_{out} + L_{1}\right)}{C_{1} C_{2} L_{1} R_{in} R_{out}} + \frac{\left(C_{1} R_{in} + C_{2} R_{out}\right)^{2}}{C_{1}^{2} C_{2}^{2} R_{in}^{2} R_{out}^{2}}\right)^{3} + \left(\frac{27 \left(R_{in} + R_{out}\right)}{C_{1} C_{2} L_{1} R_{in} R_{out}} - \frac{9 \left(C_{1} R_{in} + C_{2} R_{out}\right) \left(C_{1} R_{in} R_{out} + C_{2} R_{in} R_{out} + L_{1}\right)}{C_{1}^{2} C_{2}^{2} L_{1} R_{in}^{2} R_{out}^{2}} + \frac{2 \left(C_{1} R_{in} + C_{2} R_{out}\right)^{3}}{C_{1}^{3} C_{2}^{3} R_{in}^{3} R_{out}^{3}}\right)^{2}}}{2} + \frac{27 \left(R_{in} + R_{out}\right)}{2 C_{1} C_{2} L_{1} R_{in} R_{out}} - \frac{9 \left(C_{1} R_{in} + C_{2} R_{out}\right) \left(C_{1} R_{in} R_{out} + C_{2} R_{in} R_{out} + L_{1}\right)}{2 C_{1}^{2} C_{2}^{2} L_{1} R_{in}^{2} R_{out}^{2}} + \frac{\left(C_{1} R_{in} + C_{2} R_{out}\right)^{3}}{C_{1}^{3} C_{2}^{3} R_{in}^{3} R_{out}^{3}}}}{3} - \frac{C_{1} R_{in} + C_{2} R_{out}}{3 C_{1} C_{2} R_{in} R_{out}}, \ - \frac{- \frac{3 \left(C_{1} R_{in} R_{out} + C_{2} R_{in} R_{out} + L_{1}\right)}{C_{1} C_{2} L_{1} R_{in} R_{out}} + \frac{\left(C_{1} R_{in} + C_{2} R_{out}\right)^{2}}{C_{1}^{2} C_{2}^{2} R_{in}^{2} R_{out}^{2}}}{3 \left(- \frac{1}{2} - \frac{\sqrt{3} i}{2}\right) \sqrt[3]{\frac{\sqrt{- 4 \left(- \frac{3 \left(C_{1} R_{in} R_{out} + C_{2} R_{in} R_{out} + L_{1}\right)}{C_{1} C_{2} L_{1} R_{in} R_{out}} + \frac{\left(C_{1} R_{in} + C_{2} R_{out}\right)^{2}}{C_{1}^{2} C_{2}^{2} R_{in}^{2} R_{out}^{2}}\right)^{3} + \left(\frac{27 \left(R_{in} + R_{out}\right)}{C_{1} C_{2} L_{1} R_{in} R_{out}} - \frac{9 \left(C_{1} R_{in} + C_{2} R_{out}\right) \left(C_{1} R_{in} R_{out} + C_{2} R_{in} R_{out} + L_{1}\right)}{C_{1}^{2} C_{2}^{2} L_{1} R_{in}^{2} R_{out}^{2}} + \frac{2 \left(C_{1} R_{in} + C_{2} R_{out}\right)^{3}}{C_{1}^{3} C_{2}^{3} R_{in}^{3} R_{out}^{3}}\right)^{2}}}{2} + \frac{27 \left(R_{in} + R_{out}\right)}{2 C_{1} C_{2} L_{1} R_{in} R_{out}} - \frac{9 \left(C_{1} R_{in} + C_{2} R_{out}\right) \left(C_{1} R_{in} R_{out} + C_{2} R_{in} R_{out} + L_{1}\right)}{2 C_{1}^{2} C_{2}^{2} L_{1} R_{in}^{2} R_{out}^{2}} + \frac{\left(C_{1} R_{in} + C_{2} R_{out}\right)^{3}}{C_{1}^{3} C_{2}^{3} R_{in}^{3} R_{out}^{3}}}} - \frac{\left(- \frac{1}{2} - \frac{\sqrt{3} i}{2}\right) \sqrt[3]{\frac{\sqrt{- 4 \left(- \frac{3 \left(C_{1} R_{in} R_{out} + C_{2} R_{in} R_{out} + L_{1}\right)}{C_{1} C_{2} L_{1} R_{in} R_{out}} + \frac{\left(C_{1} R_{in} + C_{2} R_{out}\right)^{2}}{C_{1}^{2} C_{2}^{2} R_{in}^{2} R_{out}^{2}}\right)^{3} + \left(\frac{27 \left(R_{in} + R_{out}\right)}{C_{1} C_{2} L_{1} R_{in} R_{out}} - \frac{9 \left(C_{1} R_{in} + C_{2} R_{out}\right) \left(C_{1} R_{in} R_{out} + C_{2} R_{in} R_{out} + L_{1}\right)}{C_{1}^{2} C_{2}^{2} L_{1} R_{in}^{2} R_{out}^{2}} + \frac{2 \left(C_{1} R_{in} + C_{2} R_{out}\right)^{3}}{C_{1}^{3} C_{2}^{3} R_{in}^{3} R_{out}^{3}}\right)^{2}}}{2} + \frac{27 \left(R_{in} + R_{out}\right)}{2 C_{1} C_{2} L_{1} R_{in} R_{out}} - \frac{9 \left(C_{1} R_{in} + C_{2} R_{out}\right) \left(C_{1} R_{in} R_{out} + C_{2} R_{in} R_{out} + L_{1}\right)}{2 C_{1}^{2} C_{2}^{2} L_{1} R_{in}^{2} R_{out}^{2}} + \frac{\left(C_{1} R_{in} + C_{2} R_{out}\right)^{3}}{C_{1}^{3} C_{2}^{3} R_{in}^{3} R_{out}^{3}}}}{3} - \frac{C_{1} R_{in} + C_{2} R_{out}}{3 C_{1} C_{2} R_{in} R_{out}}, \ - \frac{- \frac{3 \left(C_{1} R_{in} R_{out} + C_{2} R_{in} R_{out} + L_{1}\right)}{C_{1} C_{2} L_{1} R_{in} R_{out}} + \frac{\left(C_{1} R_{in} + C_{2} R_{out}\right)^{2}}{C_{1}^{2} C_{2}^{2} R_{in}^{2} R_{out}^{2}}}{3 \left(- \frac{1}{2} + \frac{\sqrt{3} i}{2}\right) \sqrt[3]{\frac{\sqrt{- 4 \left(- \frac{3 \left(C_{1} R_{in} R_{out} + C_{2} R_{in} R_{out} + L_{1}\right)}{C_{1} C_{2} L_{1} R_{in} R_{out}} + \frac{\left(C_{1} R_{in} + C_{2} R_{out}\right)^{2}}{C_{1}^{2} C_{2}^{2} R_{in}^{2} R_{out}^{2}}\right)^{3} + \left(\frac{27 \left(R_{in} + R_{out}\right)}{C_{1} C_{2} L_{1} R_{in} R_{out}} - \frac{9 \left(C_{1} R_{in} + C_{2} R_{out}\right) \left(C_{1} R_{in} R_{out} + C_{2} R_{in} R_{out} + L_{1}\right)}{C_{1}^{2} C_{2}^{2} L_{1} R_{in}^{2} R_{out}^{2}} + \frac{2 \left(C_{1} R_{in} + C_{2} R_{out}\right)^{3}}{C_{1}^{3} C_{2}^{3} R_{in}^{3} R_{out}^{3}}\right)^{2}}}{2} + \frac{27 \left(R_{in} + R_{out}\right)}{2 C_{1} C_{2} L_{1} R_{in} R_{out}} - \frac{9 \left(C_{1} R_{in} + C_{2} R_{out}\right) \left(C_{1} R_{in} R_{out} + C_{2} R_{in} R_{out} + L_{1}\right)}{2 C_{1}^{2} C_{2}^{2} L_{1} R_{in}^{2} R_{out}^{2}} + \frac{\left(C_{1} R_{in} + C_{2} R_{out}\right)^{3}}{C_{1}^{3} C_{2}^{3} R_{in}^{3} R_{out}^{3}}}} - \frac{\left(- \frac{1}{2} + \frac{\sqrt{3} i}{2}\right) \sqrt[3]{\frac{\sqrt{- 4 \left(- \frac{3 \left(C_{1} R_{in} R_{out} + C_{2} R_{in} R_{out} + L_{1}\right)}{C_{1} C_{2} L_{1} R_{in} R_{out}} + \frac{\left(C_{1} R_{in} + C_{2} R_{out}\right)^{2}}{C_{1}^{2} C_{2}^{2} R_{in}^{2} R_{out}^{2}}\right)^{3} + \left(\frac{27 \left(R_{in} + R_{out}\right)}{C_{1} C_{2} L_{1} R_{in} R_{out}} - \frac{9 \left(C_{1} R_{in} + C_{2} R_{out}\right) \left(C_{1} R_{in} R_{out} + C_{2} R_{in} R_{out} + L_{1}\right)}{C_{1}^{2} C_{2}^{2} L_{1} R_{in}^{2} R_{out}^{2}} + \frac{2 \left(C_{1} R_{in} + C_{2} R_{out}\right)^{3}}{C_{1}^{3} C_{2}^{3} R_{in}^{3} R_{out}^{3}}\right)^{2}}}{2} + \frac{27 \left(R_{in} + R_{out}\right)}{2 C_{1} C_{2} L_{1} R_{in} R_{out}} - \frac{9 \left(C_{1} R_{in} + C_{2} R_{out}\right) \left(C_{1} R_{in} R_{out} + C_{2} R_{in} R_{out} + L_{1}\right)}{2 C_{1}^{2} C_{2}^{2} L_{1} R_{in}^{2} R_{out}^{2}} + \frac{\left(C_{1} R_{in} + C_{2} R_{out}\right)^{3}}{C_{1}^{3} C_{2}^{3} R_{in}^{3} R_{out}^{3}}}}{3} - \frac{C_{1} R_{in} + C_{2} R_{out}}{3 C_{1} C_{2} R_{in} R_{out}}\right]\)

30.11 Summary

  • FACTS method is applicable to low order circuits, since for higher order circuits, say N greater than 2 or 3, N-element Extra Element Theorem requires a lot of steps. The resultant analytical expression might be useful and insightful since series and parallel combinations of components and their grouping, or the circuit’s time constants, could be preserived in a relational way in the equation.
    • In Figure 30.1, a 6th order circuit, analytic expressions for the roots of the poles and zeros would be very long and of doubious utility.
    • The brute force solution for the transfer function of Figure 30.1, was a long expression. SymPy could solve for the roots of the numerator, but not for the denominator.
  • The assurtion that brute force is complicated and error prone is not true if computer algebra tools are used. Some of the same proported advantages of using FACTS, that is, less math, less algebra and some insight into the circuit operation are available with SMNA, since the computer does all the heavy lifting.
  • Python based symbolic MNA code provides an easy and less error prone method of obtaining analytic solutions to circuit problems.