/// <summary> /// Applies device impact on the circuit equation system. If behavior of the device is nonlinear, this method is /// called once every Newton-Raphson iteration. /// </summary> /// <param name="context">Context of current simulation.</param> public override void ApplyModelValues(ISimulationContext context) { vt = Parameters.EmissionCoefficient * PhysicalConstants.Boltzmann * PhysicalConstants.CelsiusToKelvin(Parameters.NominalTemperature) / PhysicalConstants.DevicearyCharge; gmin = Parameters.MinimalResistance ?? context.SimulationParameters.MinimalResistance; smallBiasTreshold = -5 * vt; capacitanceTreshold = Parameters.ForwardBiasDepletionCapacitanceCoefficient * Parameters.JunctionPotential; var vd = Voltage - Parameters.SeriesResistance * Current; var(id, geq, cd) = GetModelValues(vd); var ieq = id - geq * vd; // Diode stamper.Stamp(geq, -ieq); // Capacitance var(cieq, cgeq) = IntegrationMethod.GetEquivalents(cd / context.TimeStep); if (initialConditionCapacitor) // initial condition { capacitorStamper.Stamp(0, 0); } else { capacitorStamper.Stamp(cieq, cgeq); } Current = id + ic; Conductance = geq; }
/// <summary> /// Applies device impact on the circuit equation system. If behavior of the device is nonlinear, this method is /// called once every Newton-Raphson iteration. /// </summary> /// <param name="context">Context of current simulation.</param> public override void ApplyModelValues(ISimulationContext context) { double ieq, geq; if (firtDcPoint) { if (DefinitionDevice.InitialVoltage.HasValue) { ieq = DefinitionDevice.InitialVoltage.Value; geq = 1; } else { ieq = geq = 0; // open circuit } } else { (ieq, geq) = IntegrationMethod.GetEquivalents(DefinitionDevice.Capacity / context.TimeStep); } stamper.Stamp(ieq, geq); }
/// <summary> /// Applies device impact on the circuit equation system. If behavior of the device is nonlinear, this method is /// called once every Newton-Raphson iteration. /// </summary> /// <param name="context">Context of current simulation.</param> public override void ApplyModelValues(ISimulationContext context) { // cache params vT = PhysicalConstants.Boltzmann * PhysicalConstants.CelsiusToKelvin(Parameters.NominalTemperature) / PhysicalConstants.DevicearyCharge; var iS = Parameters.SaturationCurrent; var iSe = Parameters.EmitterSaturationCurrent; var iSc = Parameters.CollectorSaturationCurrent; var nF = Parameters.ForwardEmissionCoefficient; var nR = Parameters.ReverseEmissionCoefficient; var nE = Parameters.EmitterSaturationCoefficient; var nC = Parameters.CollectorSaturationCoefficient; var bF = Parameters.ForwardBeta; var bR = Parameters.ReverseBeta; var earlyVoltageForward = Parameters.ForwardEarlyVoltage; var earlyVolrateReverse = Parameters.ReverseEarlyVoltage; var iKf = Parameters.ForwardCurrentCorner; var iKr = Parameters.ReverseCurrentCorner; var gmin = Parameters.MinimalResistance ?? context.SimulationParameters.MinimalResistance; var polarity = Parameters.IsPnp ? -1 : +1; var ggb = Parameters.BaseResistance > 0 ? 1 / Parameters.BaseResistance : 0; var ggc = Parameters.CollectorResistance > 0 ? 1 / Parameters.CollectorResistance : 0; var gge = Parameters.EmitterCapacitance > 0 ? 1 / Parameters.EmitterCapacitance : 0; var vbe = VoltageBaseEmitter; var vbc = VoltageBaseCollector; // calculate junction currents var(ibe, gbe) = DeviceHelpers.PnBJT(iS, vbe, nF * vT, gmin); var(iben, gben) = DeviceHelpers.PnBJT(iSe, vbe, nE * vT, 0); var(ibc, gbc) = DeviceHelpers.PnBJT(iS, vbc, nR * vT, gmin); var(ibcn, gbcn) = DeviceHelpers.PnBJT(iSc, vbc, nC * vT, 0); // base charge calculation var q1 = 1 / (1 - vbc / earlyVoltageForward - vbe / earlyVolrateReverse); var q2 = ibe / iKf + ibc / iKr; var sqrt = Math.Sqrt(1 + 4 * q2); var qB = q1 / 2 * (1 + sqrt); var dQdbUbe = q1 * (qB / earlyVolrateReverse + gbe / (iKf * sqrt)); var dQbdUbc = q1 * (qB / earlyVoltageForward + gbc / (iKr * sqrt)); // excess phase missing var ic = (ibe - ibc) / qB - ibc / bR - ibcn; var ib = ibe / bF + iben + ibc / bR + ibcn; var gpi = gbe / bF + gben; var gmu = gbc / bR + gbcn; var go = (gbc + (ibe - ibc) * dQbdUbc / qB) / qB; var gm = (gbe - (ibe - ibc) * dQdbUbe / qB) / qB - go; // terminal currents var ceqbe = polarity * (ic + ib - vbe * (gm + go + gpi) + vbc * go); var ceqbc = polarity * (-ic + vbe * (gm + go) - vbc * (gmu + go)); CurrentBase = ib; CurrentCollector = ic; CurrentEmitter = -ib - ic; CurrentBaseEmitter = ibe; CurrentBaseCollector = ibc; Transconductance = gm; OutputConductance = go; ConductancePi = gpi; ConductanceMu = gmu; stamper.Stamp(gpi, gmu, gm, -go, ceqbe, ceqbc); gb.Stamp(ggb); ge.Stamp(gge); gc.Stamp(ggc); if (!(context.TimePoint > 0)) { return; } var vcs = voltageCs.GetValue(); var tf = Parameters.ForwardTransitTime; var tr = Parameters.ReverseTransitTime; var fc = Parameters.ForwardBiasDepletionCoefficient; var cje = Parameters.EmitterCapacitance; var mje = Parameters.EmitterExponentialFactor; var vje = Parameters.EmitterPotential; var cjc = Parameters.CollectorCapacitance; var mjc = Parameters.CollectorExponentialFactor; var vjc = Parameters.CollectorPotential; var cjs = Parameters.SubstrateCapacitance; var mjs = Parameters.SubstrateExponentialFactor; var vjs = Parameters.SubstratePotential; var cbe = DeviceHelpers.JunctionCapacitance(vbe, cje, mje, vje, gbe * tf, fc); var cbc = DeviceHelpers.JunctionCapacitance(vbc, cjc, mjc, vjc, gbc * tr, fc); var ccs = DeviceHelpers.JunctionCapacitance(vcs, cjs, mjs, vjs, 0, fc); // stamp capacitors double cieq; (cieq, cgeqbe) = chargebe.GetEquivalents(cbe / context.TimeStep); capacbe.Stamp(cieq, cgeqbe); (cieq, cgeqbc) = chargebe.GetEquivalents(cbc / context.TimeStep); capacbc.Stamp(cieq, cgeqbc); (cieq, cgeqcs) = chargebe.GetEquivalents(ccs / context.TimeStep); capaccs.Stamp(cieq, cgeqcs); }