One junction network: the exponential law over one or two antiparallel legs. More...
#include <junction.hpp>
Public Member Functions | |
| double | theta () const |
| θ = n·V_T, the exponential's scale in volts. | |
| double | current (double v) const |
| i(v). | |
| double | conductance (double v) const |
| di/dv — the incremental conductance a Newton solve needs. | |
| double | antiderivative (double v) const |
| ∫i(v)dv, in closed form — no numerical quadrature. | |
| double | conduction_estimate (double v_drive, double resistance) const |
| A closed-form estimate of where a clipped node voltage will land, for use as a solver's warm start. | |
| double | knee_voltage (double target_current) const |
| The junction voltage at which the network conducts target_current on its forward leg — the conduction knee, inverted from the same law. | |
| double | adaa_current (double v, double previous, double epsilon) const |
| First-order antiderivative-antialiasing evaluation of the current between two consecutive junction voltages. | |
| double | adaa_conductance (double v, double previous, double epsilon) const |
| d/dv of adaa_current — the Jacobian a Newton solve needs when its residual is built on the ADAA quotient rather than on current. | |
Public Attributes | |
| double | saturation_current = 1e-14 |
| Is, the reverse saturation current. | |
| double | ideality = 1.0 |
| n, the ideality factor. Sets the knee's SOFTNESS: higher is softer. | |
| double | leg_a = 1.0 |
| Reciprocal series-diode count of the forward leg. | |
| double | leg_b = 1.0 |
| Reciprocal series-diode count of the reverse leg. | |
One junction network: the exponential law over one or two antiparallel legs.
A consuming module fills in (saturation_current, ideality) from its own declared device rows, and (leg_a, leg_b) from its own topology.
|
inline |
d/dv of adaa_current — the Jacobian a Newton solve needs when its residual is built on the ADAA quotient rather than on current.
This exists because pairing the ADAA residual with conductance() is a silent catastrophe rather than a slow one. conductance is the slope of the PLAIN current; the quotient's slope is a different function, and feeding Newton a Jacobian that does not belong to its residual makes the step direction wrong rather than merely inaccurate. Measured, a diode clipper diverged geometrically at roughly 3300x per sample to 5.8e25 — full-scale noise, from a solver that never reported failure because every value stayed finite.
Differentiating (F1(v) − F1(p))/(v − p) gives [i(v)·(v − p) − (F1(v) − F1(p))] / (v − p)², and it stays strictly positive for the same reason conductance does: the quotient is the MEAN of i over [p, v], i is increasing, so i(v) is never below that mean. The bracketed solver's monotone-residual precondition therefore still holds — which is what makes the safeguard safe rather than merely present.
|
inline |
First-order antiderivative-antialiasing evaluation of the current between two consecutive junction voltages.
Falls back to direct evaluation when the two are too close for the difference quotient to carry precision — the standard ADAA guard. The epsilon lives with its one consumer here rather than being copied into every solver that wants antialiasing.
|
inline |
∫i(v)dv, in closed form — no numerical quadrature.
Even, for the reason given in the file doc block.
|
inline |
di/dv — the incremental conductance a Newton solve needs.
Strictly positive, which is what makes a residual built on it monotone.
|
inline |
A closed-form estimate of where a clipped node voltage will land, for use as a solver's warm start.
This matters more than it looks. Newton on an exponential advances by roughly one thermal voltage per iteration when it starts deep in conduction — 26 mV at a time — so a cold start two volts away needs dozens of iterations against a typical RT cap of eight. Solving the conducting branch directly, with v ≪ v_drive, (v_drive − v)/R = Is·exp(a·v/θ) gives v ≈ (θ/a)·ln(v_drive/(R·Is)) — for a silicon diode at 2 V through 10 kΩ that is 0.613 V, the knee to three figures. From there Newton converges in two or three steps.
Below conduction, or with the relevant leg absent, the node follows the drive, which is the fallthrough.
|
inline |
i(v).
The two legs' −1 terms cancel exactly, which is why this is a difference of exponentials rather than of expm1s.
|
inline |
The junction voltage at which the network conducts target_current on its forward leg — the conduction knee, inverted from the same law.
This is how a bias point is derived rather than declared: a module states its operating current and the knee falls out, so the documented ~0.36 V germanium / ~0.69 V silicon figures are consequences of (Is, n) rather than separately maintained constants that can drift from them.
|
inline |
θ = n·V_T, the exponential's scale in volts.
| double pulp::signal::junction::JunctionPair::ideality = 1.0 |
n, the ideality factor. Sets the knee's SOFTNESS: higher is softer.
| double pulp::signal::junction::JunctionPair::leg_a = 1.0 |
Reciprocal series-diode count of the forward leg.
1 is a single diode, 1/2 is two in series (turns on at twice the voltage), 0 removes it.
| double pulp::signal::junction::JunctionPair::leg_b = 1.0 |
Reciprocal series-diode count of the reverse leg.
0 makes the network a single junction — half-wave, even harmonics.
| double pulp::signal::junction::JunctionPair::saturation_current = 1e-14 |
Is, the reverse saturation current.
Units are whatever the consuming module works in — SI amps or calibration-relative — because every formula here is homogeneous in it.