Source code for pmrf.models.nonideal

from abc import abstractmethod

import jax.numpy as jnp

from pmrf.models.lumped import Resistor
from pmrf.models.topological import PiCLC
from pmrf.models.model import Model
from pmrf.frequency import Frequency

[docs] class NonIdealResistor(Model): """ **Overview** An abstract base class for creating realistic resistor models that include parasitic effects. This class provides a framework for representing a physical resistor as a combination of an ideal resistive element and a network of parasitic components (like series inductance and parallel capacitance). Subclasses are required to implement the `ideal` and `parasitics` properties to define the specific topology of the non-ideal model. """ @property @abstractmethod def ideal(self) -> Model: """ An abstract property representing the ideal part of the component. Returns: Model: The model for the ideal resistor. """ raise Exception("Subclasses must implement the 'ideal' property.") @property @abstractmethod def parasitics(self) -> Model: """ An abstract property representing the parasitic network of the component. Returns: Model: The model for the parasitic network. """ raise Exception("Subclasses must implement the 'parasitics' property.")
[docs] class CLCResistor(NonIdealResistor): """ **Overview** A model for a non-ideal resistor with parasitic capacitance and inductance. This model represents a physical resistor as an ideal resistive element cascaded with a Pi-network (Capacitor-Inductor-Capacitor). This topology is common for modeling SMD resistors at high frequencies. **Example** ```python import pmrf as prf # Create a model for a 100-ohm resistor with parasitics non_ideal_r = prf.models.CLCResistor( res=prf.models.Resistor(R=100), clc=prf.models.PiCLC(C1=0.05e-12, L=0.1e-9, C2=0.05e-12) ) # You can access the ideal and parasitic parts print(f"Ideal Resistance: {non_ideal_r.ideal.R.value} Ohms") # Calculate the S-parameters of the complete non-ideal model freq = prf.Frequency(start=0.1, stop=20, npoints=201, unit='ghz') s = non_ideal_r.s(freq) print(f"S11 at 10 GHz: {s[freq.center_idx, 0, 0]:.2f}") ``` """ res: Resistor = Resistor() clc: PiCLC = PiCLC() @property def ideal(self) -> Model: """The ideal `Resistor` part of the model. Returns: Model: The ideal resistor component. """ return self.res @property def parasitics(self) -> Model: """The parasitic `PiCLC` network part of the model. Returns: Model: The PiCLC parasitic network. """ return self.clc
[docs] def a(self, freq: Frequency) -> jnp.ndarray: """Calculates the ABCD-matrix of the complete non-ideal resistor model. Args: freq (Frequency): The frequency axis for the calculation. Returns: np.ndarray: The resultant ABCD-matrix. """ cascaded = self.clc ** self.res return cascaded.a(freq)