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()
30 Pi Filter
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:
- Fast Analytical Techniques for Electrical and Electronic Circuits
- Introduction to Fast Analytical Techniques: Application to Small-Signal Modeling
- A series of 21 YouTube videos starting with: Fast Analytical Techniques for Electrical and Electronic Circuits
- Extra Element Theorem: An Introduction (with Examples)
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.
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.
= SymMNA.smna(net_list) report, network_df, i_unk_df, A, X, Z
Build the network equations.
# Put matrices into SymPy
= Matrix(X)
X = Matrix(Z)
Z
= Eq(A*X,Z)
NE_sym
# display the equations
= ''
temp for i in range(shape(NE_sym.lhs)[0]):
+= '${:s} = {:s}$<br>'.format(latex(NE_sym.rhs[i]),latex(NE_sym.lhs[i]))
temp 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.
str(NE_sym.free_symbols).replace('{','').replace('}','')) var(
\(\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).
= solve(NE_sym,X) U_sym
Display the symbolic solution. The espressions are long, so code to display is commented.
= ''
temp for i in U_sym.keys():
+= '${:s} = {:s}$<br>'.format(latex(i),latex(U_sym[i]))
temp
# 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.
= (U_sym[v2]/U_sym[v8]).simplify().collect(s)
H_sym 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.
= fraction(H_sym)
n, d 'numerator', n, 'denominator', d) display(
'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.
= SymMNA.get_part_values(network_df)
element_values 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
= 1
Ca = 1
Cb = 2
La = 1e3 # parasitic scale factor
sf
= Ca/sf
element_values[R1] = La/sf
element_values[Ra] = La*sf
element_values[R2] = Cb/sf
element_values[R3]
= Ca/sf
element_values[L1] = La
element_values[L2] = Cb/sf
element_values[L3] = Ca
element_values[C1] = La/sf
element_values[C2] = Cb
element_values[C3]
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_sym.subs(element_values)
NE
= ''
temp for i in range(shape(NE.lhs)[0]):
+= '${:s} = {:s}$<br>'.format(latex(NE.rhs[i]),latex(NE.lhs[i]))
temp
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.
= solve(NE,X)
U
= ''
temp for i in U.keys():
+= '${:s} = {:s}$<br>'.format(latex(i),latex(U[i]))
temp
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}\)
= (U[v2]/U[v8]).nsimplify().simplify().expand().together()
H 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.
= fraction(H) #returns numerator and denominator H_num, H_denom
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
= np.array(Poly(H_num, s).all_coeffs(), dtype=float)
a = np.array(Poly(H_denom, s).all_coeffs(), dtype=float)
b = signal.TransferFunction(a,b) sys
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:
= np.roots(sys.num)
sys_zeros = np.roots(sys.den)
sys_poles
# plot the poles and zeros
'ob', markerfacecolor='none')
plt.plot(np.real(sys_zeros), np.imag(sys_zeros), 'xr')
plt.plot(np.real(sys_poles), np.imag(sys_poles), 'Zeros', 'Poles'], loc=0)
plt.legend(['Pole / Zero Plot')
plt.title('real part, \u03B1')
plt.xlabel('imaginary part, j\u03C9')
plt.ylabel(#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.
= np.logspace(-2, 2, 1000, endpoint=False) #*2*np.pi
x = signal.bode(sys, w=x) # returns: rad/s, mag in dB, phase in deg
w, mag, phase
= plt.subplots()
fig, ax1 'magnitude, dB')
ax1.set_ylabel('frequency, radians')
ax1.set_xlabel(
'-b') # Bode magnitude plot
plt.semilogx(w, mag,
='y')
ax1.tick_params(axis#ax1.set_ylim((-30,20))
plt.grid()
# instantiate a second y-axes that shares the same x-axis
= ax1.twinx()
ax2 = 'tab:blue'
color
':',color='tab:red') # Bode phase plot
plt.semilogx(w, phase,
'phase, deg',color=color)
ax2.set_ylabel(='y', labelcolor=color)
ax2.tick_params(axis#ax2.set_ylim((-5,25))
'Magnitude and phase response')
plt.title( 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.
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.
= symbols('L1, L2, L3, R1, R2, R3, Ra, R, R_out, R_in, C1, C2, C3, s, V1') 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.
= R1+s*L1+1/(s*C1)
Z1_sym 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
= (Ra+1/(1/(1/(s*C2)) + 1/(s*L2) + 1/R2))
Z2_sym 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
= R3+s*L3+1/(s*C3)
Z3_sym 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
= R_out*Z3_sym/(R_out+Z3_sym)
Z4_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\)
= symbols('Z1, Z2, Z3, Z4, R_in, R_out, V1') Z1, Z2, Z3, Z4, R_in, R_out, V1
Zx is the parallel combination of Z1, Z2 and Z4.
= Z1*(Z2+Z4)/(Z1+Z2+Z4)
Zx 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.
= V1*Zx/(R_in+Zx)
v_node1 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_node1*Z4/(Z2+Z4)
V_out 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
= V_out/V1
H_franc_z 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)
= Z1_sym*(Z2_sym+Z4_sym)/(Z1_sym+Z2_sym+Z4_sym)
Zx_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)
= V1*Zx_sym/(R_in+Zx_sym)
v_node1_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_node1_sym*Z4_sym/(Z2_sym+Z4_sym)
V_out_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.
= V_out_sym/V1
H_franc_sym 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.simplify()
H_franc_sym_1a 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)}\)
= fraction(H_franc_sym_1a)
n, d 'numerator', n, 'denominator', d) display(
'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_sym.subs(element_values)
H_franc 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.nsimplify().simplify().expand().together()
H_franc 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:
= fraction(H_franc) #returns numerator and denominator H_franc_num, H_franc_denom
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
= np.array(Poly(H_franc_num, s).all_coeffs(), dtype=float)
a = np.array(Poly(H_franc_denom, s).all_coeffs(), dtype=float)
b = signal.TransferFunction(a,b) franc_sys
= np.roots(franc_sys.num)
franc_sys_zeros = np.roots(franc_sys.den) franc_sys_poles
30.7.5 Pole zero plot
The poles and zeros of the function are plotted on the complex plane.
'ob', markerfacecolor='none')
plt.plot(np.real(franc_sys_zeros), np.imag(franc_sys_zeros), 'xr')
plt.plot(np.real(franc_sys_poles), np.imag(franc_sys_poles), 'Zeros', 'Poles'], loc=0)
plt.legend(['Pole / Zero Plot')
plt.title('real part, \u03B1')
plt.xlabel('imaginary part, j\u03C9')
plt.ylabel(#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.
= np.logspace(-2, 2, 1000, endpoint=False) #*2*np.pi
x = signal.bode(franc_sys, w=x) # returns: rad/s, mag in dB, phase in deg
w_franc, mag_franc, phase_franc
= plt.subplots()
fig, ax1 'magnitude, dB')
ax1.set_ylabel('frequency, radians')
ax1.set_xlabel(
'-b') # Bode magnitude plot
plt.semilogx(w_franc, mag_franc,
='y')
ax1.tick_params(axis#ax1.set_ylim((-30,20))
plt.grid()
# instantiate a second y-axes that shares the same x-axis
= ax1.twinx()
ax2 = 'tab:blue'
color
':',color='tab:red') # Bode phase plot
plt.semilogx(w_franc, phase_franc,
'phase, deg',color=color)
ax2.set_ylabel(='y', labelcolor=color)
ax2.tick_params(axis#ax2.set_ylim((-5,25))
'Magnitude and phase response')
plt.title( plt.show()
30.8 Comapring solutions
Load the csv file from LTSpice.
= 'Pi-Filter-LTSpice.csv' # data from LTSpice
fn = np.genfromtxt(fn, delimiter=',',skip_header=1)
LTSpice_data
# initaliaze some empty arrays
= np.zeros(len(LTSpice_data))
frequency = np.zeros(len(LTSpice_data)).astype(complex)
voltage
# convert the csv data to complez numbers and store in the array
for i in range(len(LTSpice_data)):
= LTSpice_data[i][0]
frequency[i] = LTSpice_data[i][1] + LTSpice_data[i][2]*1j voltage[i]
= plt.subplots()
fig, ax1 'magnitude, dB')
ax1.set_ylabel('frequency, Hz')
ax1.set_xlabel(
20*np.log10(np.abs(voltage)),'-k') # LTSpice magnitude plot
plt.semilogx(frequency, /(2*np.pi), mag,'-b') # MNA magnitude plot
plt.semilogx(w/(2*np.pi), mag_franc,'-r') # FACTS magnitude plot
plt.semilogx(w_franc
='y')
ax1.tick_params(axis#ax1.set_ylim((-30,20))
plt.grid()
# instantiate a second y-axes that shares the same x-axis
= ax1.twinx()
ax2 = 'b'
color
2*np.angle(voltage)/2) *180/np.pi,':',color='k',label='LTSpice') # LTSpice phase plot
plt.semilogx(frequency, np.unwrap(/(2*np.pi), phase,':',color='b',label='MNA') # MNA phase plot
plt.semilogx(w/(2*np.pi), phase_franc,':',color='r',label='Franc') # FACTS phase plot
plt.semilogx(w_franc
'phase, deg',color=color)
ax2.set_ylabel(='y', labelcolor=color)
ax2.tick_params(axis#ax2.set_ylim((-5,25))
='k', label='LTSpice')
ax2.plot(np.NaN, np.NaN, color='b', label='MNA')
ax2.plot(np.NaN, np.NaN, color='r', label='Franc')
ax2.plot(np.NaN, np.NaN, color
plt.legend()'Magnitude and phase response')
plt.title( 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’)
= ((R*Z1*Z3)/(R*((Z2+2*Z1)*Z3 + Z1*Z2) + R**2*(Z3+Z2+Z1) + Z1*Z2*Z3)).subs({R:1})
H_telsa23 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.
= '''
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
= SymMNA.smna(net_list) report, network_df, i_unk_df, A, X, Z
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
= Matrix(X)
X = Matrix(Z)
Z
= Eq(A*X,Z)
NE_sym
# display the equations
= ''
temp for i in range(shape(NE_sym.lhs)[0]):
+= '${:s} = {:s}$<br>'.format(latex(NE_sym.rhs[i]),latex(NE_sym.lhs[i]))
temp 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.
str(NE_sym.free_symbols).replace('{','').replace('}','')) var(
\(\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.
= solve(NE_sym,X) U_sym
Display the symbolic solution
= ''
temp for i in U_sym.keys():
+= '${:s} = {:s}$<br>'.format(latex(i),latex(U_sym[i]))
temp
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
= (U_sym[v2]/U_sym[v3]).simplify()
H_sym_1 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}}\)
= fraction(H_sym_1)
n, d 'numerator', n, 'denominator', d) display(
'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.