def test_noisy1(self): a = Circuit() a.add('R1 1 0') a.add('R2 1 0') an = a.noisy() b = Circuit() b.add('R1 1 0 {R1 * R2 / (R1 + R2)}') bn = b.noisy() self.assertEqual(an[1].V.n.expr, bn[1].V.n.expr, "Incorrect noise")
def test_V1(self): """Lcapy: test V1""" a = Circuit() a.add('V1 1 0 10') self.assertEqual(a.V1.V.dc, 10, "Incorrect voltage")
def test_RC1(self): """Lcapy: check RC network """ a = Circuit() a.add('R1 1 2') a.add('C1 2 0') self.assertEqual2(a.impedance(1, 2), R('R1').impedance, "Z incorrect for R1.") self.assertEqual2(a.impedance(2, 0), C('C1').impedance, "Z incorrect for C1.") self.assertEqual2(a.impedance(1, 0), (R('R1') + C('C1')).impedance, "Z incorrect for R1 + C1.") self.assertEqual2(a.admittance(1, 2), R('R1').Y, "Y incorrect for R1.") self.assertEqual2(a.admittance(2, 0), C('C1').Y, "Y incorrect for C1.") self.assertEqual2(a.admittance(1, 0), (R('R1') + C('C1')).Y, "Y incorrect for R1 + C1.") self.assertEqual2(a.Isc(1, 0), I(0).Isc, "Isc incorrect") self.assertEqual(a.R1.Z, expr('R1'), "Z incorrect") self.assertEqual(a.R1.R, expr('R1'), "R incorrect") self.assertEqual(a.R1.X, 0, "X incorrect") self.assertEqual(a.C1.Y, expr('j * omega * C1'), "Y incorrect") self.assertEqual(a.C1.G, 0, "G incorrect") self.assertEqual(a.C1.B, expr('-omega * C1'), "B incorrect")
def test_filtered_noise1(self): """Lcapy: check circuit filtered noise""" a = Circuit() a.add('V1 1 0 noise 3') a.add('R1 1 2 2') a.add('C1 2 0 4')
def test_VRC1(self): """Lcapy: check VRC circuit """ a = Circuit() a.add('V1 1 0 {V1 / s}') a.add('R1 1 2') a.add('C1 2 0') # Note, V1 acts as a short-circuit for the impedance/admittance self.assertEqual2(a.impedance(1, 2), (R('R1') | C('C1')).Z, "Z incorrect across R1") self.assertEqual2(a.impedance(2, 0), (R('R1') | C('C1')).Z, "Z incorrect across C1") self.assertEqual2(a.impedance(1, 0), R(0).Z, "Z incorrect across V1") self.assertEqual2(a.admittance(1, 2), (R('R1') | C('C1')).Y, "Y incorrect across R1") self.assertEqual2(a.admittance(2, 0), (R('R1') | C('C1')).Y, "Y incorrect across C1") # This has a non-invertible A matrix. # self.assertEqual2(a.admittance(1, 0), R(0).Y, "Y incorrect across V1") self.assertEqual2( a.Voc(1, 0).s, V('V1 / s').Voc.s, "Voc incorrect across V1") self.assertEqual(a.is_ivp, False, "Initial value problem incorrect") self.assertEqual(a.is_dc, False, "DC incorrect") self.assertEqual(a.is_ac, False, "AC incorrect")
def test_TF(self): a = Circuit(""" TF 2 0 1 0 k R 2 0""") self.assertEqual(a.impedance(1, 0), expr('R / k**2'), "incorrect impedance")
def test_IV_parallel(self): a = Circuit(""" V 1 0 dc I 1 0 dc R 1 0""") self.assertEqual(a.R.v, expr('V'), "R voltage incorrect") self.assertEqual(a.R.i, expr('V / R'), "R current incorrect")
def test_IV_series(self): a = Circuit(""" V 2 1 dc I 1 0 dc R 2 0""") self.assertEqual(a.R.v, expr('I * R'), "R voltage incorrect") self.assertEqual(a.R.i, expr('I'), "R current incorrect")
def test_sub(self): a = Circuit(""" V1 1 0 {u(t)} R1 1 2 L1 2 0""") self.assertEqual(a.ac().R1.V, 0, "AC model incorrect") self.assertEqual(a.dc().R1.V, 0, "DC model incorrect")
def test_directive(self): # This has a deliberate empty line. a = Circuit(""" V 2 0 10 R 2 0 1""") self.assertEqual(a.R.i, 10, "i incorrect")
def test_filtered_noise3(self): """Lcapy: check circuit filtered noise""" a = Circuit() a.add('V1 1 0 noise 20') a.add('R1 1 2 1') a.add('C1 2 0 2') self.assertEqual(a.C1.V.n.rms(), 5 * sqrt(2), "Incorrect capacitor voltage")
def test_filtered_noise2(self): """Lcapy: check circuit filtered noise""" a = Circuit() a.add('V1 1 0 noise {sqrt(4 * k * T * R)}') a.add('R1 1 2 R') a.add('C1 2 0 C') self.assertEqual2(a.C1.V.n.rms(), Vt('sqrt(k * T / C)'), "Incorrect capacitor voltage")
def test_noise2(self): """Lcapy: check circuit noise for pair of sources""" a = Circuit() a.add('V1 1 0 noise 3') a.add('V2 2 1 noise 4') a.add('R1 2 0 5') V1 = a.R1.V.n self.assertEqual2(V1, Vn(5, nid=V1.nid), "Incorrect noise sum")
def test_noise1(self): """Lcapy: check circuit noise for voltage divider""" a = Circuit() a.add('V1 1 0 noise 3') a.add('R1 1 2 2') a.add('R2 2 0 4') V1 = a.R1.V.n self.assertEqual2(V1, Vn(1, nid=V1.nid), "Incorrect ratio")
def test_simplify(self): a = Circuit(""" R1 1 2 R2 2 3""") b = a.simplify() self.assertEqual(b.impedance(1, 3), a.impedance(1, 3), "simplify series") a = Circuit(""" R1 1 2 R2 1 2""") b = a.simplify() self.assertEqual(b.impedance(1, 2), a.impedance(1, 2), "simplify parallel")
def test_causal1(self): a = Circuit() a.add('V1 1 0 {4 + 2 * u(t)}; down') a.add('R1 1 2 2; right=2') a.add('L1 2 3 2; down') a.add('W 0 3; right') self.assertEqual(a.sub['s'].is_causal, True, "Causal incorrect") self.assertEqual2(a.L1.v, 2 * exp(-t) * u(t), "L current incorrect")
def test_IR1(self): """Lcapy: check IR circuit """ a = Circuit() a.add('I1 1 0 2') a.add('R1 1 0 1') self.assertEqual2(a.R1.V, V(2).Voc, "Incorrect voltage") self.assertEqual2(a[1].V, V(2).Voc, "Incorrect node voltage")
def test_VCCS1(self): """Lcapy: check VCCS """ a = Circuit() a.add('V1 1 0 2') a.add('R1 1 0 1') a.add('G1 2 0 1 0 3') a.add('R2 2 0 1') self.assertEqual2(a.R2.V, V(6).Voc, "Incorrect voltage")
def test_CCVS2(self): """Lcapy: check CCVS """ a = Circuit() a.add('H1 1 0 H1 -4') t = a.thevenin(1, 0) self.assertEqual(t.V, 0, "Incorrect Thevenin voltage") self.assertEqual(t.Z, -4, "Incorrect Thevenin impedance") self.assertEqual(a.H1.Voc, 0, "Incorrect cpt voltage") self.assertEqual(a.H1.Z, 0, "Incorrect cpt impedance")
def test_VRC2(self): """Lcapy: check VRC circuit with arbitrary s-domain source """ a = Circuit() a.add('V1 1 0 {V(s)}') a.add('R1 1 2') a.add('C1 2 0 C1 0') H = a[2].V.s / a[1].V.s self.assertEqual2(H, 1 / (s * 'R1' * 'C1' + 1), "Incorrect ratio")
def test_CCVS1(self): """Lcapy: check CCVS """ a = Circuit() a.add('V1 1 0 10') a.add('R1 1 2 2') a.add('V2 2 0 0') a.add('H1 3 0 V2 2') a.add('R2 3 0 1') self.assertEqual2(a.R2.V, V(10).Voc, "Incorrect voltage")
def test_VRL1_dc(self): """Lcapy: check VRL circuit at dc """ a = Circuit() a.add('V1 1 0 dc') a.add('R1 1 2') a.add('L1 2 0') self.assertEqual(a.is_ivp, False, "Initial value problem incorrect") self.assertEqual(a.is_dc, True, "DC incorrect") self.assertEqual(a.is_ac, False, "AC incorrect")
def test_RC_ivp(self): """Lcapy: check RC IVP""" a = Circuit(""" C 1 0 C v0 R 1 0""") self.assertEqual(a.is_ivp, True, "Initial value problem incorrect") self.assertEqual(a.R.I, -a.C.I, "R + C current different") self.assertEqual(a.R.V, a.C.V, "R + C voltage different") self.assertEqual(a.C.I(s), sympify('-v0 / (s * R + 1 / C)'), "C current wrong")
def push_pull_coupled_lossless_clamp_image(): cct = Circuit() cct.add(''' P1 p1a p1b; down=10,v=V_{in} W p1a c1a; right W p1b c1b; right C1 c1a c1b; down W c1a clampret1; right=1 W clampret1 clampret2; right=4 W clampret2 t1c1; right=3 W t1c1 t1c2; down=2 W t1c2 t1c3; right LW1 l1a t1c3; down LW2 t1c3 l2b; down W l1a lleak21; left=2 W lleak21 lleak2a; down=3 Lleak2 lleak2a lleak2b; down,color=red CS2 lleak2b cs2b; left=2,color=blue,v=$V_{CS}$ W cs2b ds2a; up=2,color=blue DS2 ds2a ds2b; up=2.5,color=blue W ds2b clampret2; up,color=blue W ds2a lw3a1; right=3,color=blue W lw3a1 lw3a2; down=1,color=blue LW3 lw3a2 lw3b; down,color=blue LW4 lw3b lw4b; down,color=blue,fixed W l2b lleak1a1; left=6 W lleak1a1 lleak1a; down=1.5 Lleak1 lleak1a lleak1b; down,color=red CS1 lleak1b cs1b; left=2,color=blue,v=$V_{CS}$ W cs1b ds1a; up=2,color=blue DS1 ds1a ds1b; up=2.5,color=blue W ds1b clampret1; up,color=blue W lleak1b m1d; down=0.5 W lleak2b m2d; down=0.5 M1 m1d m1g m1s nmos; right,size=1 M2 m2d m2g m2s nmos; right,size=1 W cs1b lw4b1; down=2.5,color=blue W lw4b1 lw4b2; right=8,color=blue W lw4b2 lw4b; up,color=blue W m1s m2s; right=4 RS m1s rsb; down=2 W c1b rsb; right W lw3b lw3b1; left=1,color=blue W lw3b1 lw3b2; down=4,color=blue W lw3b2 rsb; left=5,color=blue A1 lw3a2; l={\ \ \ \ \ •} A2 lw3b; l={\ \ \ \ \ •} A3 l1a; l={\ \ \ \ \ •} A4 t1c3; l={\ \ \ \ \ •} ''') return cct
def half_bridge_topology_image(): cct = Circuit() # the input (switches-capacitors-transformer) cct.add(''' P1 p1a p1b; down,v=V_{in} C1 c1a c1b; down=3 C2 c1b c2b; down=3 R1 r1a r1b; down=3,l=Rb R2 r1b r2b; down=3,l=Rb W r1b c1b; right W p1a r1a; right W p1b r2b; right W r1a c1a; right W r2b c2b; right W c1a 1d; right=2 M1 1d 1g 1s nmos; right W 1s 2d1; down W 2d1 2d; down M2 2d 2g 2s nmos; right W c2b 2s; right=2 TF1 t1 t2 t3 t4 tapcore _t5 _t6; right, size=1.5 W 2d1 t3; right Cb c1b t4; right=2 ''') # First body diode cct.add(''' W 1d dm1b; right=0.5 W 1s dm1a; right=0.5 DM1 dm1a dm1b; up ''') # Second body diode cct.add(''' W 2d dm2b; right=0.5 W 2s dm2a; right=0.5 DM2 dm2a dm2b; up ''') # The output (transformer-rectifier-inductor-capacitor) cct.add(''' W _t6 t6; right=2 W t6 go1; down W go1 go2; right D1 t1 d1b; right D2 t2 d2b; right W d2b d1b; up Lo d1b coa; right Co coa go2; down P2 p2a p2b; down, v=V_{out} W coa p2a; right W go2 p2b; right ''') return cct
def test_in_series(self): a = Circuit(""" V 1 0 dc R1 1 2 R2 2 3 R3 3 0 R4 3 4 R5 4 0""") self.assertEqual(a.in_series('R1'), set(('V', 'R1', 'R2')), "in_series(R1)") self.assertEqual(a.in_series('R3'), set(), "in_series(R3)") self.assertEqual(a.in_series('R4'), set(('R4', 'R5')), "in_series(R4)")
def test_VRL1_dc3(self): """Lcapy: check VRL circuit at dc but with initial conditions """ # TODO: This currently fails due to two symbols of the same name # having different assumptions. a = Circuit() a.add('V1 1 0 V1') a.add('R1 1 2') a.add('L1 2 0 L1 0') self.assertEqual(a.is_dc, False, "DC incorrect") self.assertEqual(a.is_ac, False, "AC incorrect")
def test_VRL1_ac(self): """Lcapy: check VRL circuit at ac """ a = Circuit() a.add('V1 1 0 ac') a.add('R1 1 2') a.add('L1 2 0') self.assertEqual(a.is_ivp, False, "Initial value problem incorrect") self.assertEqual(a.is_dc, False, "DC incorrect") self.assertEqual(a.is_ac, True, "AC incorrect") self.assertEqual(a.R1.I, a.L1.I, "currents different") self.assertEqual(a.V1.I, a.L1.I, "currents different")
def test_RL_ivp(self): """Lcapy: check RL IVP""" a = Circuit(""" L 1 0 L i0 R 1 0""") self.assertEqual(a.is_ivp, True, "Initial value problem incorrect") # Note, a positive current through an inductor is from the # positive node to the negative node. self.assertEqual(a.R.I, -a.L.I, "R + L current different") self.assertEqual(a.R.V, a.L.V, "R + L voltage different") self.assertEqual(a.L.I(s), sympify('i0 / (s + R / L)'), "L current wrong")
def test_VRL_ivp(self): """Lcapy: check VRL IVP""" a = Circuit(""" V 1 0 dc; down R 1 2; right L 2 3 L I0; down W 0 3; right""") self.assertEqual(a.is_ivp, True, "Initial value problem incorrect") self.assertEqual(a.R.I, a.L.I, "R + L current different") self.assertEqual(a.V.I, a.L.I, "V + L current different") self.assertEqual(a.V.V, a.R.V + a.L.V, "KVL fail") a = Circuit(""" V 1 0 dc; down R 2 3; right L 1 2 L I0; down W 0 3; right""") self.assertEqual(a.is_ivp, True, "Initial value problem incorrect") self.assertEqual(a.R.I, a.L.I, "R + L current different") self.assertEqual(a.V.I, a.L.I, "V + L current different") self.assertEqual(a.V.V, a.R.V + a.L.V, "KVL fail")