Tunnel-diode oscillator
A tunnel-diode oscillator: an inductor and a capacitor in parallel with a negative-resistance diode.
- Name:
tunnel_diode_oscillator - Field:
engineering/circuits - Formalism: ordinary differential equations
- References: van der Pol 1926; Trzaska 2023
Factory
@register_model(
field='engineering/circuits',
tags=('circuit', 'oscillation', 'limit cycle', 'ode'),
references=('van der Pol 1926', 'Trzaska 2023'),
defaults={'until': 50.0, 'dt': 0.05},
)
def tunnel_diode_oscillator(
V: float = 0.1,
i: float = 0.0,
*,
L: float = 1.0,
C: float = 1.0,
alpha: float = 1.0,
gamma: float = 1.0,
) -> System:
"""Return a tunnel-diode oscillator: an inductor and a capacitor in parallel with a negative-resistance diode.
The diode current is `h(V) = gamma V^3 - alpha V`, so Kirchhoff's laws give `C V' = -h(V) - i` and `L i' = V`,
which is the van der Pol oscillator with `ε = alpha sqrt(L / C)`. The voltage settles on a limit cycle of
amplitude near `2 sqrt(alpha / (3 gamma))`.
Args:
V:
The initial voltage.
i:
The initial current of the inductor.
L:
The inductance.
C:
The capacitance.
alpha:
The negative conductance of the diode at zero voltage.
gamma:
The cubic coefficient of the diode.
Returns:
system:
The model, with the voltage `circuit.V` and the inductor current `circuit.i`.
Examples:
>>> from skcomplex.models.engineering.circuits import tunnel_diode_oscillator
>>> tunnel_diode_oscillator(alpha=2.0).elements[0].alpha
2.0
"""
return System(elements=[TunnelDiodeCircuitElement('circuit', V=V, i=i, L=L, C=C, alpha=alpha, gamma=gamma)])
Components
class TunnelDiodeCircuitElement(Element):
"""Oscillator of a tunnel diode with a cubic current, of the van der Pol type."""
def __init__(
self,
label: str,
visual: VisualSpec | None = None,
*,
V: Annotated[object, StateSpec()] = 0.1,
i: Annotated[object, StateSpec()] = 0.0,
L: Annotated[object, ParameterSpec(domain=RealSet.open(0, oo))] = 1.0,
C: Annotated[object, ParameterSpec(domain=RealSet.open(0, oo))] = 1.0,
alpha: Annotated[object, ParameterSpec(domain=RealSet.open(0, oo))] = 1.0,
gamma: Annotated[object, ParameterSpec(domain=RealSet.open(0, oo))] = 1.0,
) -> None:
super().__init__(label, visual=visual)
self.V = V
self.i = i
self.L = L
self.C = C
self.alpha = alpha
self.gamma = gamma
def _get_laws(self, s: SimpleNamespace) -> list[BaseLaw]:
"""Return the rates of the states of the circuit."""
return [
RateLaw(s.V, -(s.gamma * s.V**3 - s.alpha * s.V + s.i) / s.C),
RateLaw(s.i, s.V / s.L),
]
Equations
circuit.V: diff(V_circuit(t), t) == -(gamma_circuit*V_circuit(t)^3 - alpha_circuit*V_circuit(t) + i_circuit(t))/C_circuit
circuit.i: diff(i_circuit(t), t) == V_circuit(t)/L_circuit
