I am trying to calculate the RLC tank transfer function using LCAPY. I know what the answer should be but I want to do it with code. The issue is there isn't a current()
or voltage()
function in LCAPY and only impedance()
and transfer()
. Here is the code so far:
import lcapy
from lcapy import s, expr
from IPython.display import display, Math
from sympy import symbols, collect, sqrt
import sympy as sp
# Define the circuit netlist with components
netlist = """
Iin 1 0
Cp 1 0 C
Rp 1 0 R
Lp 1 0 L
"""
# Create a Circuit object from the netlist
circuit = lcapy.Circuit(netlist)
s_model = circuit.s_model()
# Calculate the transfer function H = I_out / I_in
# H(s) = transfer from node 1 (current source) to ground (node 0)
# Calculate the output current I_out
I_out = s_model.current(1, 0) # Current through resistor Rp at node 1
# Calculate the input current I_in from the current source
I_in = s_model.Iin(1) # Current from the current source at node 1
# H(s) = I_out / I_in
H_final = I_out / I_in
# Display the transfer function H
display(Math(sp.latex(H_final)))
I was hoping to get the following:
You don't need a voltage here, since both currents will be proportional to it. You just need the resistance (effectively the impedance of the resistor) and the total impedance (resistor+capacitor+inductor) between the two lines. If you want your frequency response then you will need to specify this explicitly.
Since they end at the same nodes and I(in)=I(total)
, writing Z
for combined impedance of resistor, capacitor, inductor:
V = I(total).Z = I(resistor).R
Hence,
H = abs( I(resistor) / I(total) ) = abs( Z / R )
Run the following in, e.g., a jupyter notebook:
import lcapy
from lcapy import s, j, omega
from IPython.display import display, Math, Latex
import sympy as sp
# Define the circuit netlist with components
netlist = """
Iin 1 0
Cp 1 0 C
Rp 1 0 R
Lp 1 0 L
"""
circuit = lcapy.Circuit(netlist)
S = circuit.s_model()
# Calculate the transfer function
# H = S.resistance( 1, 0 ) / S.impedance( 1, 0 ) # Note that resistance() actually returns abs(Z*Z)/R
H = S.impedance( 1, 0 ) / circuit.Rp.R # H = I(resistor) / I(total) = Z(total) / Z(resistor)
A = H( j * omega ).magnitude
display(Math(sp.latex( A )))
Output:
Note: in the (commented-out) version of H, resistance() does not return R; it appears to actually return what I would call abs(Z2)/R, where Z is the complex impedance (which is returned correctly); hence the transfer function looks "the wrong way up".