In [1]:
AHKAB_PATH = "/Users/nikolas/src/ahkab"
import sys
if not AHKAB_PATH in sys.path: sys.path.append(AHKAB_PATH)
In [2]:
import ahkab
In [17]:
from ahkab import new_ac, run
from ahkab.circuit import Circuit
from ahkab.plotting import plot_results # calls matplotlib for you
import numpy as np
# Define the circuit
cir = Circuit('lowpass filter')
cir.add_vsource('V1', 'n1', cir.gnd, dc_value=0., ac_value=1.)
cir.add_resistor('R1', 'n1', 'n2', 1)
cir.add_capacitor('C1', 'n2', cir.gnd, 1)
# Define the analysis
ac1 = new_ac(2.*np.pi*1e-2, 2.*np.pi*1e1, 100, x0=None)
# run it
res = run(cir, ac1)
# plot the results
plot_results('Lowpass', [('|Vn2|',"")], res['ac'],
outfilename='lowpass.png')
In [4]:
import cirq; cirq.init_js()
In [74]:
net = cirq.Domain(name="net", causal=False)
n = cirq.Port(name="n", domain=net, direction="inout")
p = cirq.Port(name="p", domain=net, direction="inout")
vsource = cirq.ComponentType(name="VoltageSource",
ports=cirq.clone_ports([p, n]),
parameters=["dc_value", "ac_value"])
resistor = cirq.ComponentType(name="Resistor",
ports = cirq.clone_ports([p, n]),
parameters=["value"])
capacitor = cirq.ComponentType(name="Capacitor",
ports = cirq.clone_ports([p, n]),
parameters=["value"])
In [75]:
lowpass = cirq.CircuitBuilder([net], [vsource, resistor, capacitor], cirq.Circuit(name="LowPass"))
lowpass
In [106]:
lowpass.circuit.c.R1._inner_svg ="""
<path
d="M 0 -40 l 0 10 l -5 5
l 10 10 l -10 10 l 10 10 l -10 10 l 10 10
l -5 5 L 0 40"
stroke="black"
stroke-width="2px"
fill="none"/>
"""
lowpass.circuit.c.R1._x_label=20
lowpass.circuit.c.R1._label_color = "black"
lowpass.circuit.c.R1.p.p._x = 0
lowpass.circuit.c.R1.p.p._y = 40
lowpass.circuit.c.R1.p.p._phi = pi/2.
lowpass.circuit.c.R1.p.n._x = 0
lowpass.circuit.c.R1.p.n._y = -40
lowpass.circuit.c.R1.p.n._phi = -pi/2.
In [107]:
# reset
lowpass.circuit.c.R1._inner_svg = ""
lowpass.circuit.c.R1._x_label=0
lowpass.circuit.c.R1._label_color = "white"
lowpass.circuit.c.R1.layout_ports(lowpass.circuit.c.R1.ports)
In [105]:
def translate_to_ahkab(circuit):
"""
Convert a cirq Circuit representation into an ahkab model.
"""
ret = Circuit(circuit.name.encode("ascii", "ignore"))
# find groups/cliques of connected ports, treat GND specially
nets = {circuit.p.GND: (0, set([circuit.p.GND]))}
# each entry of nets has as the key the overall port within the circuit
# and as value a tuple of a number identifying the clique/group
# and a set containing all other members
nk = 1
nets_by_nk = {}
# add other external ports
for p in circuit.ports:
if p.name == "GND":
continue
nets[p] = (nk, set([p]))
nk += 1
# add internal ports
for c in circuit.component_instances:
for p in c.ports:
nets[p] = (nk, set([p]))
nk +=1
# resolve connections
for c in circuit.connections:
# source and target are of same clique, so combine them
s, t = c.source, c.target
(ns, pss), (nt, pts) = nets[s], nets[t]
mn = min(ns, nt)
ma = max(ns, nt)
clique = pss | pts
for pp in clique:
# for all members of the clique,
# set the net index to the lowest possible index
# store all members of the clique
nets[pp] = mn, clique
nets_by_nk[mn] = clique
if ns != nt and ma in nets_by_nk:
del nets_by_nk[ma]
# extend this to allow for more components!
methods = {
vsource: ret.add_vsource,
resistor: ret.add_resistor,
capacitor: ret.add_capacitor
}
# find which nets are connected to non-GND external ports
ext = {p: "n{}".format(nets[p][0]) for p in circuit.ports if p is not circuit.p.GND}
# create ahkab object
for c in circuit.component_instances:
nn = []
for p in c.ports:
if nets[p][0] == 0: # connected to gnd
nn.append(ret.gnd)
else:
nn.append("n{}".format(nets[p][0]))
methods[c.ctype](c.name.encode("ascii", "ignore"), nn[0], nn[1], **c.param_assignments)
return ret, ext, nets_by_nk
In [77]:
def analyze(RR = 1., CC = 1.):
lowpass.circuit.c.R1.param_assignments = dict(value=RR)
lowpass.circuit.c.C1.param_assignments = dict(value=CC)
lowpass.circuit.c.V1.param_assignments = dict(dc_value=0., ac_value=1)
cir2, ext, nets = translate_to_ahkab(lowpass.circuit)
# Define the analysis
ac1 = new_ac(2.*np.pi*1e-2, 2.*np.pi*1e1, 100, x0=None)
# run it
res2 = run(cir2, ac1)
OUT_index = '|V{}|'.format(ext[lowpass.circuit.p.OUT]).encode("ascii", "ignore")
# plot the results
plot_results('Lowpass', [(OUT_index,"")], res2['ac'],
outfilename='lowpass.png')
In [78]:
from IPython.html.widgets import interact
interact(analyze,
RR = (.5, 1.5, .1),
CC = (.5, 1.5, .1))
In [ ]: