Struct JfetRoot
pub struct JfetRoot {
pub model: JfetModel,
/* private fields */
}Expand description
JFET nonlinear root for WDF trees.
Models the drain-source path as a nonlinear element controlled by an external gate-source voltage Vgs. Uses Newton-Raphson to solve the implicit WDF constraint equation.
Drain-source current follows the SPICE Level 1 model:
Triode (|Vds| < |Vgs - VTO|):
Ids = Beta × (2×(Vgs-VTO)×Vds - Vds²) × (1 + LAMBDA×|Vds|)
Saturation (|Vds| ≥ |Vgs - VTO|):
Ids = Beta × (Vgs-VTO)² × (1 + LAMBDA×|Vds|)
Cutoff (Vgs - VTO ≤ 0):
Ids = 0
Uses SPICE sign convention: internal voltages are sign × external,
where sign = +1 for N-channel and -1 for P-channel.
Fields§
§model: JfetModelImplementations§
§impl JfetRoot
impl JfetRoot
pub fn new(model: JfetModel) -> JfetRoot
pub fn from_mosfet(mosfet: MosfetModel) -> JfetRoot
pub fn from_mosfet(mosfet: MosfetModel) -> JfetRoot
Build a 1-port FET root that computes the enhancement-mode MOSFET
square law (MosfetModel::ids) instead of the JFET Level 1 law.
Both device families share the external-Vgs / drain-source-port
contract (set_vgs() + I(Vds) via NlDeviceIv), so a MOSFET can be
hosted by JfetRoot wherever only that contract is used — currently
the multi-NL MNA path (NlDeviceKind::Jfet), which has no dedicated
Mosfet variant. drain_current()/drain_current_derivative()
delegate to the embedded MosfetModel; everything else (NR solve,
warm start, clamps) is shared.
The model field is filled with an equivalent placeholder so that
JFET-parameterized code paths (initial NR guesses) see the correct
overdrive voltage: vov_jfet = sign*Vgs - VTO matches
vov_mosfet when VTO = sign*Vth. Gate junction parameters are
zeroed (enhancement MOSFET gates are insulated).
pub fn set_vgs(&mut self, vgs: f64)
pub fn set_vgs(&mut self, vgs: f64)
Set the gate-source voltage (external control from LFO, bias, etc.)
MOSFET-hosted roots (Self::from_mosfet) ignore this: the multi-NL
stage drives Vgs from the stage input (JFET pitch-sweep semantics),
but an enhancement-mode MOSFET whose gate is not part of the
WDF/MNA network must keep its floating-gate bias (0 V → channel off,
matching RootKind::Mosfet, where Vgs only changes via explicit
modulation). Driving Vgs from the audio signal would spuriously
switch the channel and short the drain node to the source.
pub fn set_operating_point(&mut self, vgs_bias: f64, vds_bias: f64)
pub fn set_operating_point(&mut self, vgs_bias: f64, vds_bias: f64)
Set the DC operating point used by the incremental WDF one-port.
pub fn rds_approx(&self) -> f64
pub fn rds_approx(&self) -> f64
Approximate drain-source resistance at Vds ≈ 0 (triode region onset). Rds = 1 / (2 × Beta × Vov), where Vov = Vgs - Vto. Returns a large resistance (1MΩ) if the JFET is in cutoff.
pub fn drain_current(&self, vds: f64) -> f64
pub fn drain_current(&self, vds: f64) -> f64
Compute drain current for given Vds at current Vgs.
Handles triode, saturation, and cutoff regions using SPICE sign convention for both N-channel and P-channel devices.
§impl JfetRoot
impl JfetRoot
pub fn process_source_follower(&mut self, a: f64, rp: f64, vgate: f64) -> f64
pub fn process_source_follower(&mut self, a: f64, rp: f64, vgate: f64) -> f64
Source follower processing: solve for Vs where Ids(Vgate - Vs) = Vs / Rs.
In a source follower:
- The gate voltage (Vgate) is the input signal
- The source voltage (Vs) follows the gate with ~unity gain
- Vgs = Vgate - Vs (computed during Newton-Raphson solve)
- The JFET operates in saturation: Ids ≈ Beta × (Vgs - VTO)²
- The WDF constraint: Ids = Vs / Rp (source current into load)
Returns the reflected wave b = 2*Vs - a.