public override void Analyze(Analysis Mna) { int sign; switch (Type) { case BjtType.NPN: sign = 1; break; case BjtType.PNP: sign = -1; break; default: throw new NotSupportedException("Unknown BJT structure."); } Expression Vbc = Mna.AddUnknownEqualTo(Name + "bc", sign * (Base.V - Collector.V)); Expression Vbe = Mna.AddUnknownEqualTo(Name + "be", sign * (Base.V - Emitter.V)); Expression aR = BR / (1 + (Expression)BR); Expression aF = BF / (1 + (Expression)BF); Expression iF = IS * (LinExp(Vbe / VT) - 1); Expression iR = IS * (LinExp(Vbc / VT) - 1); // TODO: Algebraically rearranging these results in dramatically different stability behavior. // It would be nice to understand this. //Expression ie = iF - aR * iR; Expression ic = aF * iF - iR; Expression ib = (1 - aF) * iF + (1 - aR) * iR; ic = Mna.AddUnknownEqualTo("i" + Name + "c", ic); ib = Mna.AddUnknownEqualTo("i" + Name + "b", ib); Mna.AddTerminal(Collector, sign * ic); Mna.AddTerminal(Base, sign * ib); Mna.AddTerminal(Emitter, -sign * (ic + ib)); }
public override void Analyze(Analysis Mna) { Expression Vpk = Mna.AddUnknownEqualTo(Name + "pk", p.V - k.V); Expression Vgk = Mna.AddUnknownEqualTo(Name + "gk", g.V - k.V); Expression ip, ig; switch (model) { case TriodeModel.ChildLangmuir: Expression Ed = Mu * Vgk + Vpk; ip = Call.If(Ed > 0, K * (Ed ^ 1.5), 0); ig = 0; break; case TriodeModel.Koren: Expression E1 = Ln1Exp(Kp * (1.0 / Mu + Vgk * (Kvb + Vpk ^ 2) ^ (-0.5))) * Vpk / Kp; ip = (Call.Max(E1, 0) ^ Ex) / Kg; ig = Call.Max(Vgk - Vg, 0) / Rgk; break; default: throw new NotImplementedException("Triode model " + model.ToString()); } ip = Mna.AddUnknownEqualTo("i" + Name + "p", ip); ig = Mna.AddUnknownEqualTo("i" + Name + "g", ig); Mna.AddTerminal(p, ip); Mna.AddTerminal(g, ig); Mna.AddTerminal(k, -(ip + ig)); }
public static Expression Analyze(Analysis Mna, string Name, Node Anode, Node Cathode, Expression IS, Expression n, Expression VT) { // V = Va - Vc Expression Vac = Mna.AddUnknownEqualTo("V" + Name, Anode.V - Cathode.V); // Evaluate the model. Expression i = IS * (LinExp(Vac / (n * VT)) - 1); i = Mna.AddUnknownEqualTo("i" + Name, i); Mna.AddPassiveComponent(Anode, Cathode, i); return i; }
public static Expression Analyze(Analysis Mna, string Name, Node Anode, Node Cathode, Expression IS, Expression n, Expression VT) { // V = Va - Vc Expression Vac = Mna.AddUnknownEqualTo("V" + Name, Anode.V - Cathode.V); // Evaluate the model. Expression i = IS * (LinExp(Vac / (n * VT)) - 1); i = Mna.AddUnknownEqualTo("i" + Name, i); Mna.AddPassiveComponent(Anode, Cathode, i); return(i); }
public override void Analyze(Analysis Mna) { Expression Vpk = Mna.AddUnknownEqualTo(Name + "pk", p.V - k.V); Expression Vgk = Mna.AddUnknownEqualTo(Name + "gk", g.V - k.V); Expression ip, ig; Analyze(Mna, Vgk, Vpk, out ip, out ig); ip = Mna.AddUnknownEqualTo("i" + Name + "p", ip); ig = Mna.AddUnknownEqualTo("i" + Name + "g", ig); Mna.AddTerminal(p, ip); Mna.AddTerminal(g, ig); Mna.AddTerminal(k, -(ip + ig)); }
public override void Analyze(Analysis Mna) { Diode.Analyze(Mna, Gate, Source, IS, n); Diode.Analyze(Mna, Gate, Drain, IS, n); // The drain and source terminals are reversible in the JFET model, this // formulation is simpler than explicitly identifying normal/inverted mode. Expression Vgds = Gate.V - Call.Min(Source.V, Drain.V); Expression Vds = Drain.V - Source.V; Expression AbsVds = Call.Abs(Vds); //Vgds = Mna.AddUnknownEqualTo(Name + "gds", Vgds); Expression Vgds_t0 = Vgds - Vt0; Expression id = Call.Sign(Vds) * (Vgds >= Vt0) * Beta * (1 + Lambda * AbsVds) * Call.If(AbsVds < Vgds_t0, // Linear region. AbsVds * (2 * Vgds_t0 - 1), // Saturation region. Vgds_t0 ^ 2); id = Mna.AddUnknownEqualTo("i" + Name + "d", id); CurrentSource.Analyze(Mna, Drain, Source, id); }
public static Expression Analyze(Analysis Mna, string Name, Node Anode, Node Cathode, Expression C) { // Ensure that V is not multiple variables. Expression V = Mna.AddUnknownEqualTo("V" + Name, Anode.V - Cathode.V); // i = C*dV/dt Expression i = C * D(V, t); Mna.AddPassiveComponent(Anode, Cathode, i); return(i); }
public override void Analyze(Analysis Mna) { int sign; switch (Type) { case BjtType.NPN: sign = 1; break; case BjtType.PNP: sign = -1; break; default: throw new NotSupportedException("Unknown BJT structure."); } Expression Vbc = sign * (Base.V - Collector.V); Expression Vbe = sign * (Base.V - Emitter.V); Vbc = Mna.AddUnknownEqualTo(Name + "bc", Vbc); Vbe = Mna.AddUnknownEqualTo(Name + "be", Vbe); Expression aR = BR / (1 + (Expression)BR); Expression aF = BF / (1 + (Expression)BF); Expression iF = IS * LinExpm1(Vbe / VT); Expression iR = IS * LinExpm1(Vbc / VT); Expression ie = iF - aR * iR; Expression ic = aF * iF - iR; Expression ib = (1 - aF) * iF + (1 - aR) * iR; ic = Mna.AddUnknownEqualTo("i" + Name + "c", ic); ib = Mna.AddUnknownEqualTo("i" + Name + "b", ib); ie = Mna.AddUnknownEqualTo("i" + Name + "e", ie); Mna.AddTerminal(Collector, sign * ic); Mna.AddTerminal(Base, sign * ib); Mna.AddTerminal(Emitter, -sign * ie); }
public override void Analyze(Analysis Mna) { Diode.Analyze(Mna, Gate, Source, IS, 1, VT); Diode.Analyze(Mna, Gate, Drain, IS, 1, VT); // The drain and source terminals are reversible in the JFET model, this // formulation is simpler than explicitly identifying normal/inverted mode. Expression Vgs = Gate.V - Call.Min(Source.V, Drain.V); Expression Vds = Call.Abs(Drain.V - Source.V); //Vgs = Mna.AddNewUnknownEqualTo(Name + "gs", Vgs); Expression Vgst0 = Vgs - Vt0; Expression id = (Vgs >= Vt0) * Beta * (1 + Lambda * Vds) * Call.If(Vds < Vgst0, // Linear region. Vds * (2 * Vgst0 - 1), // Saturation region. Vgst0 ^ 2); id = Mna.AddUnknownEqualTo("i" + Name + "d", id); CurrentSource.Analyze(Mna, Drain, Source, id); }