diff --git a/bc-asrc-tran-1.cir b/bc-asrc-tran-1.cir new file mode 100644 index 000000000..3378a77b3 --- /dev/null +++ b/bc-asrc-tran-1.cir @@ -0,0 +1,52 @@ +* test asrc branch current, tran, with feedback +* (exec-spice "ngspice %s" t) + +V1 in 0 SINE(0 1 1) + +BR1 in N3 i = v(in,N3)/1.0 $ artificial 1 Ohm Resistor +Vm1 N3 N5 0 +C1 N5 0 0.21 + +B1 out 0 V = I(BR1) + +.control + +* insertion of nodes and branches has to be checked for correct "unsetup" +* I saw a failing tran after an op, whilst tran alone worked + +op +rusage totiter + +tran 1ms 1.0 +rusage totiter + +plot v(out) i(Vm1)*0.99 + +* golden answer, derived with "maxima" +let R = 1.0 +let C = 0.21 +let tau = R * C +let omega = 2 * pi +let ot = omega * tau +let gold = (sin(time*omega)*ot + cos(time*omega) - exp(-time/tau)) * ot/(1+ot*ot)/R + +let err = vecmax(abs(v(out) - gold)) +echo "INFO: err =" $&err + +if err > 4e-6 + echo "ERROR: test failed" + quit 1 +else + echo "INFO: success" +end + +if 1 + plot v(out) i(Vm1)*0.99 gold*0.97 + plot v(out)-gold +else + quit 0 +end + +.endc + +.end diff --git a/bc-cap-ac-1.cir b/bc-cap-ac-1.cir new file mode 100644 index 000000000..560321ca4 --- /dev/null +++ b/bc-cap-ac-1.cir @@ -0,0 +1,51 @@ +* test capacitor branch current, ac, without feedback +* (exec-spice "ngspice %s" t) + +V1 in 0 SINE(0 1 1) ac = 2.31 + +C1 in N3 0.07 m = 3 +Vm1 N3 N5 0 +R2 N5 0 1.0 + +B1 out 0 V = I(C1) + +.control + +* insertion of nodes and branches has to be checked for correct "unsetup" +* I saw a failing tran after an op, whilst tran alone worked + +op +rusage totiter + +ac dec 20 0.01 100 +rusage totiter + +* golden answer +let R = 1 +let C = 0.07 * 3 +let tau = R * C +let s = (0,1) * 2 * pi * frequency +let gold = 2.31 / R * s*tau/(1 + s*tau) + +let ac_err = v(out) / gold - 1 +let ac_max_err = vecmax(abs(ac_err)) + +echo "INFO: ac_max_err =" $&ac_max_err + +if ac_max_err > 1e-12 + echo "ERROR: ac test failed" + quit 1 +else + echo "INFO: ac success" +end + +if 1 + plot vdb(out) db(abs(i(Vm1)))*0.99 db(abs(gold))*0.98 + plot abs(ac_err) +else + quit 0 +end + +.endc + +.end diff --git a/bc-cap-ac-2.cir b/bc-cap-ac-2.cir new file mode 100644 index 000000000..910a95f93 --- /dev/null +++ b/bc-cap-ac-2.cir @@ -0,0 +1,52 @@ +* test capacitor branch current, ac, with feedback +* (exec-spice "ngspice %s" t) + +V1 in 0 SINE(0 1 1) ac = 2.31 + +C1 in N3 0.07 m = 3 +Vm1 N3 N5 0 +R2 N5 0 2.42 +B2 N5 0 V = I(C1) $ extends R2 for a total of 1 Ohm + +B1 out 0 V = I(C1) + +.control + +* insertion of nodes and branches has to be checked for correct "unsetup" +* I saw a failing tran after an op, whilst tran alone worked + +op +rusage totiter + +ac dec 20 0.01 100 +rusage totiter + +* golden answer +let R = 1 +let C = 0.07 * 3 +let tau = R * C +let s = (0,1) * 2 * pi * frequency +let gold = 2.31 / R * s*tau/(1 + s*tau) + +let ac_err = v(out) / gold - 1 +let ac_max_err = vecmax(abs(ac_err)) + +echo "INFO: ac_max_err =" $&ac_max_err + +if ac_max_err > 1e-15 + echo "ERROR: ac test failed" + quit 1 +else + echo "INFO: ac success" +end + +if 1 + plot vdb(out) db(abs(i(Vm1)))*0.99 db(abs(gold))*0.98 + plot abs(ac_err) +else + quit 0 +end + +.endc + +.end diff --git a/bc-cap-pz-2.cir b/bc-cap-pz-2.cir new file mode 100644 index 000000000..6cf874266 --- /dev/null +++ b/bc-cap-pz-2.cir @@ -0,0 +1,59 @@ +* test capacitor branch current, pz, with feedback +* (exec-spice "ngspice %s" t) + +V1 in 0 ac = 2.31 + +C1 in N3 0.07 m = 3 +Vm1 N3 N5 0 +R2 N5 0 2.42 +B2 N5 0 V = I(C1) $ extends R2 for a total of 1 Ohm + +B1 out 0 V = I(C1) + +.control + +* insertion of nodes and branches has to be checked for correct "unsetup" +* I saw a failing tran after an op, whilst tran alone worked + +op +rusage totiter + +pz in 0 out 0 vol pz +rusage totiter + +* golden answer +let R = 1 +let C = 0.07 * 3 +let tau = R * C +let gold_pole = (-1,0)/tau +let gold_zero = (0,0) + +let pole_err = abs(pole(1)/gold_pole - 1) +let zero_err = abs(zero(1)) + +echo "INFO: pole_err =" $&pole_err +echo "INFO: zero_err =" $&zero_err + +if pole_err > 1e-6 + echo "ERROR: pz/pole test failed" + quit 1 +else + echo "INFO: pz/pole success" +end + +if zero_err > 1e-6 + echo "ERROR: pz/zero test failed" + quit 1 +else + echo "INFO: pz/zero success" +end + +if 1 + print pole(1) zero(1) gold_pole gold_zero +else + quit 0 +end + +.endc + +.end diff --git a/bc-cap-tran-1.cir b/bc-cap-tran-1.cir new file mode 100644 index 000000000..c573e5354 --- /dev/null +++ b/bc-cap-tran-1.cir @@ -0,0 +1,51 @@ +* test capacitor branch current, tran, without feedback +* (exec-spice "ngspice %s" t) + +V1 in 0 SINE(0 1 1) + +C1 in N3 0.07 m = 3 +Vm1 N3 N5 0 +R2 N5 0 1.0 + +B1 out 0 V = I(C1) + +.control + +* insertion of nodes and branches has to be checked for correct "unsetup" +* I saw a failing tran after an op, whilst tran alone worked + +op +rusage totiter + +tran 1ms 1.0 +rusage totiter + +* golden answer, derived with "maxima" +let R = 1 +let C = 0.07 * 3 +let tau = R * C +let omega = 2 * pi +let ot = omega * tau +let gold = (sin(time*omega)*ot + cos(time*omega) - exp(-time/tau)) * ot/(1+ot*ot)/R + + +let err = vecmax(abs(v(out) - gold)) +echo "INFO: err =" $&err + +if err > 4e-6 + echo "ERROR: test failed" + quit 1 +else + echo "INFO: success" +end + +if 1 + plot v(out) i(Vm1)*0.99 v(N5)*0.98 gold*0.97 + plot v(out)-gold +else + quit 0 +end + +.endc + +.end diff --git a/bc-cap-tran-1.maxima b/bc-cap-tran-1.maxima new file mode 100644 index 000000000..39972ff9c --- /dev/null +++ b/bc-cap-tran-1.maxima @@ -0,0 +1,10 @@ +/* R in series with C feed with vin*sin(omega*t) */ + +assume(omega > 0); + +vsource: laplace(vin*sin(t*omega), t, s); +iout: vsource/R * s*tau/(1 + s*tau); +ilt(iout, s, t), factor; + +f1: vin/R / (1 + (omega*tau)^2); +f2: %th(2) / f1; diff --git a/bc-cap-tran-2.cir b/bc-cap-tran-2.cir new file mode 100644 index 000000000..c949f95ce --- /dev/null +++ b/bc-cap-tran-2.cir @@ -0,0 +1,52 @@ +* test capacitor branch current, tran, with feedback +* (exec-spice "ngspice %s" t) + +V1 in 0 SINE(0 1 1) + +C1 in N3 0.07 m = 3 +Vm1 N3 N5 0 +R2 N5 0 2.42 +B2 N5 0 V = I(C1) $ extends R2 for a total of 1 Ohm + +B1 out 0 V = I(C1) + +.control + +* insertion of nodes and branches has to be checked for correct "unsetup" +* I saw a failing tran after an op, whilst tran alone worked + +op +rusage totiter + +tran 1ms 1.0 +rusage totiter + +* golden answer, derived with "maxima" +let R = 1 +let C = 0.07 * 3 +let tau = R * C +let omega = 2 * pi +let ot = omega * tau +let gold = (sin(time*omega)*ot + cos(time*omega) - exp(-time/tau)) * ot/(1+ot*ot)/R + + +let err = vecmax(abs(v(out) - gold)) +echo "INFO: err =" $&err + +if err > 4e-6 + echo "ERROR: test failed" + quit 1 +else + echo "INFO: success" +end + +if 1 + plot v(out) i(Vm1)*0.99 v(N5)*0.98 gold*0.97 + plot v(out)-gold +else + quit 0 +end + +.endc + +.end diff --git a/bc-ind-ac-2.cir b/bc-ind-ac-2.cir new file mode 100644 index 000000000..789fcbb7d --- /dev/null +++ b/bc-ind-ac-2.cir @@ -0,0 +1,52 @@ +* test inductor branch current, ac, with feedback +* (exec-spice "ngspice %s" t) + +V1 in 0 ac = 2.31 + +L1 in N3 0.21 m = 3 +Vm1 N3 N5 0 +R2 N5 0 2.42 +B2 N5 0 V = I(L1) $ extends R2 for a total of 1 Ohm + +B1 out 0 V = I(L1) + +.control + +* insertion of nodes and branches has to be checked for correct "unsetup" +* I saw a failing tran after an op, whilst tran alone worked + +op +rusage totiter + +ac dec 20 0.01 100 +rusage totiter + +* golden answer +let R = 1 +let L = 0.21 / 3 +let tau = L / R +let s = (0,2) * pi * frequency +let gold = 2.31/R * 1/(1 + s*tau) + +let ac_err = v(out) / gold - 1 +let ac_max_err = vecmax(abs(ac_err)) + +echo "INFO: ac_max_err =" $&ac_max_err + +if ac_max_err > 1e-12 + echo "ERROR: ac test failed" + quit 1 +else + echo "INFO: ac success" +end + +if 1 + plot vdb(out) db(abs(i(Vm1)))*0.99 db(abs(gold))*0.98 + plot abs(ac_err) +else + quit 0 +end + +.endc + +.end diff --git a/bc-ind-pz-2.cir b/bc-ind-pz-2.cir new file mode 100644 index 000000000..9e2dccb7b --- /dev/null +++ b/bc-ind-pz-2.cir @@ -0,0 +1,49 @@ +* test inductor branch current, pz, with feedback +* (exec-spice "ngspice %s" t) + +V1 in 0 ac = 2.31 + +L1 in N3 0.21 m = 3 +Vm1 N3 N5 0 +R2 N5 0 2.42 +B2 N5 0 V = I(L1) $ extends R2 for a total of 1 Ohm + +B1 out 0 V = I(L1) + +.control + +* insertion of nodes and branches has to be checked for correct "unsetup" +* I saw a failing tran after an op, whilst tran alone worked + +op +rusage totiter + +pz in 0 out 0 vol pz +rusage totiter + +* golden answer +let R = 1 +let L = 0.21 / 3 +let tau = L / R +let gold_pole = (-1,0)/tau + +let pole_err = abs(pole(1)/gold_pole - 1) + +echo "INFO: pole_err =" $&pole_err + +if pole_err > 1e-6 + echo "ERROR: pz/pole test failed" + quit 1 +else + echo "INFO: pz/pole success" +end + +if 1 + print pole(1) gold_pole +else + quit 0 +end + +.endc + +.end diff --git a/bc-ind-tran-1.cir b/bc-ind-tran-1.cir new file mode 100644 index 000000000..9cea74509 --- /dev/null +++ b/bc-ind-tran-1.cir @@ -0,0 +1,50 @@ +* test inductor branch current, tran, without feedback +* (exec-spice "ngspice %s" t) + +V1 in 0 SINE(0 1 1) + +L1 in N3 0.21 m = 3 +Vm1 N3 N5 0 +R2 N5 0 1.0 + +B1 out 0 V = I(L1) + +.control + +* insertion of nodes and branches has to be checked for correct "unsetup" +* I saw a failing tran after an op, whilst tran alone worked + +op +rusage totiter + +tran 1ms 1.0 +rusage totiter + +* golden answer, derived with "maxima" +let R = 1 +let L = 0.21 / 3 +let tau = L / R +let omega = 2 * pi +let ot = omega * tau +let gold = (sin(time*omega) - ot*cos(time*omega) + ot*exp(-time/tau)) / (1+ot*ot)/R + +let err = vecmax(abs(v(out) - gold)) +echo "INFO: err =" $&err + +if err > 6e-6 + echo "ERROR: test failed" + quit 1 +else + echo "INFO: success" +end + +if 1 + plot v(out) i(Vm1)*0.99 v(N5)*0.98 gold*0.97 + plot v(out)-gold +else + quit 0 +end + +.endc + +.end diff --git a/bc-ind-tran-1.maxima b/bc-ind-tran-1.maxima new file mode 100644 index 000000000..f4286b2d2 --- /dev/null +++ b/bc-ind-tran-1.maxima @@ -0,0 +1,10 @@ +/* R in series with L feed with vin*sin(omega*t) */ + +assume(omega > 0); + +vsource: laplace(vin*sin(t*omega), t, s); +iout: vsource/R * 1/(1 + s*tau); +ilt(iout, s, t), factor; + +f1: vin/R / (1 + (omega*tau)^2); +f2: %th(2) / f1; diff --git a/bc-ind-tran-2.cir b/bc-ind-tran-2.cir new file mode 100644 index 000000000..e75a212fe --- /dev/null +++ b/bc-ind-tran-2.cir @@ -0,0 +1,51 @@ +* test inductor branch current, tran, with feedback +* (exec-spice "ngspice %s" t) + +V1 in 0 SINE(0 1 1) + +L1 in N3 0.21 m = 3 +Vm1 N3 N5 0 +R2 N5 0 2.42 +B2 N5 0 V = I(L1) $ extends R2 for a total of 1 Ohm + +B1 out 0 V = I(L1) + +.control + +* insertion of nodes and branches has to be checked for correct "unsetup" +* I saw a failing tran after an op, whilst tran alone worked + +op +rusage totiter + +tran 1ms 1.0 +rusage totiter + +* golden answer, derived with "maxima" +let R = 1 +let L = 0.21 / 3 +let tau = L / R +let omega = 2 * pi +let ot = omega * tau +let gold = (sin(time*omega) - ot*cos(time*omega) + ot*exp(-time/tau)) / (1+ot*ot)/R + +let err = vecmax(abs(v(out) - gold)) +echo "INFO: err =" $&err + +if err > 6e-6 + echo "ERROR: test failed" + quit 1 +else + echo "INFO: success" +end + +if 1 + plot v(out) i(Vm1)*0.99 gold*0.97 + plot v(out)-gold +else + quit 0 +end + +.endc + +.end diff --git a/bc-res-ac-2.cir b/bc-res-ac-2.cir new file mode 100644 index 000000000..b710c4f1e --- /dev/null +++ b/bc-res-ac-2.cir @@ -0,0 +1,54 @@ +* test resistor branch current, ac, with feedback +* (exec-spice "ngspice %s" t) + +V1 in 0 dc=3.0 ac=2.31 + +R1 in out 1 +B1 out 0 v = i(R1)^3 + +.control + +* for more newton iterations, and increased precision, try +* set reltol = 1e-15 + +op +rusage totiter + +ac dec 20 0.01 100 +rusage totiter + +* golden answer, derived with "maxima" +let gold_dc_out = 1.786588337237788 +let gold_ac_out = 2.31 * 0.81539950577107 + +let dc_err = op1.v(out) / gold_dc_out - 1 +let ac_err = v(out) / gold_ac_out - 1 + +let ac_max_err = vecmax(abs(ac_err)) + +echo "INFO: dc_err =" $&dc_err +echo "INFO: ac_max_err =" $&ac_max_err + +if abs(dc_err) > 1e-6 + echo "ERROR: dc test failed" + quit 1 +else + echo "INFO: dc success" +end + +if ac_max_err > 1e-6 + echo "ERROR: ac test failed" + quit 1 +else + echo "INFO: ac success" +end + +if 1 + plot abs(ac_err) +else + quit 0 +end + +.endc + +.end diff --git a/bc-res-ac-2.maxima b/bc-res-ac-2.maxima new file mode 100644 index 000000000..583b9fdee --- /dev/null +++ b/bc-res-ac-2.maxima @@ -0,0 +1,19 @@ +/* vin ---R---+---- vout + * | + * u = i^3 + * | + */ + +batch("./bc-res-tran-2.maxima"); + +/* ac response */ +diff(x); +solve(%, del(vout))/del(vin), factor; +ac : rhs(first(%)); + +dc_vin: 3.0; +dc_vout: float(gold), vin=dc_vin; + +float(ac), vout=dc_vout, vin=dc_vin; + + diff --git a/bc-res-tran-1.cir b/bc-res-tran-1.cir new file mode 100644 index 000000000..7a1ca6b72 --- /dev/null +++ b/bc-res-tran-1.cir @@ -0,0 +1,48 @@ +* test resistor branch current, tran, no feedback +* (exec-spice "ngspice %s" t) + +V1 in 0 SINE(0 1 1) + +R1 in N3 3 m = 4 +Vm1 N3 N5 0 +C1 N5 0 0.21 + +B1 out 0 V = i(R1) + +.control + +* insertion of nodes and branches has to be checked for correct "unsetup" +* I saw a failing tran after an op, whilst tran alone worked + +op +tran 1ms 1.0 + +* golden answer, derived with "maxima" +let R = 3 / 4 +let C = 0.21 +let tau = R * C +let omega = 2 * pi +let ot = omega * tau +let gold = (sin(time*omega)*ot + cos(time*omega) - exp(-time/tau)) * ot/(1+ot*ot)/R + +let err = vecmax(abs(v(out) - gold)) +echo "INFO: err =" $&err + +if err > 4e-6 + echo "ERROR: test failed" + quit 1 +else + echo "INFO: success" +end + +if 1 + plot v(out) i(Vm1) * 0.99 + plot v(out) gold * 0.99 + plot v(out) - gold +else + quit 0 +end + +.endc + +.end diff --git a/bc-res-tran-2.cir b/bc-res-tran-2.cir new file mode 100644 index 000000000..bea3eae14 --- /dev/null +++ b/bc-res-tran-2.cir @@ -0,0 +1,47 @@ +* test resistor branch current, tran, with feedback +* (exec-spice "ngspice %s" t) + +V1 in 0 SINE(0 1 1) + +R1 in out 1 +B1 out 0 v = i(R1)^3 + +.control + +op +rusage totiter + +tran 1ms 1.0 +rusage totiter + +* syndrom +let x = v(in)^3 - 3*v(out)*v(in)^2 + 3*v(out)^2*v(in) - v(out)^3 - v(out) + +let xx = v(out)^3 * 1.0 + v(out) - v(in) + +* golden answer, derived with "maxima" +let P1 = sqrt(v(in)^2 + 4/27) - v(in) +let P2 = (P1 / 2) ^ (1/3) +let gold = P2 - 1 / (3*P2) + v(in) + +let err = vecmax(abs(v(out) - gold)) +echo "INFO: err =" $&err + +if err > 20e-6 + echo "ERROR: test failed" + quit 1 +else + echo "INFO: success" +end + +if 1 + plot v(out) + plot v(out) - gold + plot x +else + quit 0 +end + +.endc + +.end diff --git a/bc-res-tran-2.maxima b/bc-res-tran-2.maxima new file mode 100644 index 000000000..a7d3856b6 --- /dev/null +++ b/bc-res-tran-2.maxima @@ -0,0 +1,23 @@ +/* vin ---R---+---- vout + * | + * u = i^3 + * | + */ + +g1: u = vin - R*i; +g2: u = i^3; +g3: vout = u; + +x: eliminate([g1,g2,g3], [i,u]), R=1; + +solve(x, vout); +third(%); + +P1: sqrt(vin^2 + 4/27) - vin; +P2: (P1 / 2) ^ (1/3); +gold : P2 - 1 / (3*P2) + vin; + +/* check by substitution into x, shall be zero */ +x, vout=gold; +%, expand; +%, factor;