Source code for skrf.media.definedAEpTandZ0

"""
DefinedAEpTandZ0 (:mod:`skrf.media.definedAEpTandZ0`)
======================================================

Transmission line medium defined by A, Ep, Tand and Z0.

This medium is defined by attenuation A, relative permittivity Ep_r,
loss angle tand and characteristic impedance Z0.

Djirdjevic/Svennson dispersion model is provided for dielectric, default
behaviour is frequency invariant.

.. autosummary::
   :toctree: generated/

   DefinedAEpTandZ0
"""
from __future__ import annotations

import warnings

from numpy import imag, log, ones, pi, real, sqrt
from scipy.constants import c

from ..constants import NumberLike
from ..frequency import Frequency
from .media import Media


[docs] class DefinedAEpTandZ0(Media): r""" Transmission line medium defined by A, Ep, Tand and Z0. This medium is defined by attenuation `A`, relative permittivity `Ep_r`, loss angle `tand` and characteristic impedance `Z0`. Djirdjevic [#Djordjevic]_ / Svennson [#Svensson]_ dispersion model is provided for dielectric. Default behaviour is frequency invariant. Parameters ---------- frequency : :class:`~skrf.frequency.Frequency` object Frequency band of this transmission line medium z0_port : number, array-like, or None `z0_port` is the port impedance for networks generated by the media. If `z0_port` is not None, the networks generated by the media are renormalized (or in other words embedded) from the characteristic impedance z0 of the media to `z0_port`. Else if `z0_port` is None, the networks port impedances will be the raw characteristic impedance z0 of the media. (Default is None) A : number, array-like, default 0.0 Attenuation due to conductor loss in dB/m/sqrt(Hz) The attenuation :math:`A(f)`at frequency :math:`f` is: .. math:: A(f) = A\sqrt{\frac{f}{f_A}} f_A : number, default 1.0 Frequency scaling in Hz for the attenuation. See A. ep_r : number, array-like, default 1.0 Real part of the relative permittivity of the dielectric: :math:`\epsilon_r'=\Re[\epsilon]`. If `model='frequencyinvariant'`, the complex relative permittivity is: .. math:: \epsilon_r(f) = \epsilon'_r + j \cdot \epsilon'_r \cdot \tan\delta if `model='djordjevicsvensson'`, the complex relative permittivity is: .. math:: \epsilon_r(f) = \epsilon_\inf + m \cdot \ln{\frac{f_{high} + j f_\epsilon}{f_{low} + j f_\epsilon}} where :math:`\epsilon_\inf` is the permittivity value when frequency approaches infinity. In this case, the value of :math:`\epsilon_r` and :math:`\tan\delta` (tanD) are given for frequency :math:`f_\epsilon`: .. math:: \epsilon_r(f_\epsilon) = \epsilon'_r+ j \cdot \epsilon'_r \cdot \tan\delta tanD : number, array-like, default 0.0 Dielectric relative permittivity loss tangent :math:`\tan\delta`. See `ep_r`. z0 : number, array-like, default 50.0 Quasi-static characteristic impedance of the medium. Z0 : number, array-like, or None deprecated parameter, only emmit a deprecation warning. f_low : number, default 1e3, optional Low frequency in Hz for for Djirdjevic/Svennson dispersion model. See `ep_r`. f_high : number, default 1e12, optional High frequency in Hz for for Djirdjevic/Svennson dispersion model. See `ep_r`. f_ep : number, default 1e9, , optional Specification frequency in Hz for for Djirdjevic/Svennson dispersion model. `ep_r` and `tanD` parameters are specified for this frequency. See `ep_r`. model : string, 'frequencyinvariant' or 'djordjevicsvensson', optional Use Djirdjevic/Svennson wideband Debye dispersion model or not. Default is frequency invariant behaviour. \*args, \*\*kwargs : arguments and keyword arguments Examples -------- >>> from skrf.media.definedAEpTandZ0 import DefinedAEpTandZ0 >>> from skrf.frequency import Frequency >>> f = Frequency(75,110,101,'ghz') >>> DefinedAEpTandZ0(frequency=f, A=1, f_A=1e9, ep_r=3, z0=50) >>> DefinedAEpTandZ0(frequency=f, A=1, f_A=1e9, ep_r=3, tand=0.02, z0=50) >>> DefinedAEpTandZ0(frequency=f, A=1, f_A=1e9, ep_r=3, tand=0.02, z0=50, f_low=1e3, f_high=1e12, f_Ep=1e9, model='djordjevicsvensson') References ---------- .. [#Svensson] C. Svensson and G. E. Dermer, "Time Domain Modeling of Lossy Interconnects," IEEE Trans. Advanced Packaging, Vol. 24, No. 2, May 2001. https://doi.org/10.1109/6040.928754 .. [#Djordjevic] A. R. Djordjevic, R. M. Biljic, V. D. Likar-Smiljanic, and T. K. Sarkar, "Wideband Frequency-Domain Characterization of FR-4 and Time-Domain Causality," IEEE Trans. Electromagnetic Compatibility, Vol. 43, No. 4, November 2001. https://doi.org/10.1109/15.974647 """
[docs] def __init__(self, frequency: Frequency| None = None, A: float = 0.0, f_A: float = 1.0, ep_r: NumberLike = 1.0, tanD: NumberLike = 0.0, z0_port: NumberLike | None = None, z0: float = 50.0, Z0: NumberLike | None = None, f_low: float = 1.0e3, f_high: float = 1.0e12, f_ep: float = 1.0e9, model: str = 'frequencyinvariant', *args, **kwargs): Media.__init__(self, frequency=frequency, z0_port=z0_port) self.A, self.f_A = A, f_A self.ep_r, self.tanD = ep_r, tanD self.z0_characteristic = z0 self.f_low, self.f_high, self.f_ep = f_low, f_high, f_ep self.model = model if Z0 is not None: # warns of deprecation warnings.warn( 'Use of `Z0` in DefinedAEpTandZ0 initialization is deprecated.\n' '`Z0` has no effect. Use `z0` instead\n' '`Z0` will be removed in version 1.0', DeprecationWarning, stacklevel = 2)
def __str__(self): f = self.frequency output = 'DefinedAEpTandZ0 medium. %i-%i %s. %i points'%\ (f.f_scaled[0], f.f_scaled[-1], f.unit, f.npoints) return output def __repr__(self): return self.__str__() @property def ep_r_f(self) -> NumberLike: """ Frequency dependent complex relative permittivity of dielectric. """ ep_r, tand = self.ep_r, self.tanD f_low, f_high, f_ep = self.f_low, self.f_high, self.f_ep f = self.frequency.f if self.model == 'djordjevicsvensson': # compute the slope for a log frequency scale, tanD dependent. m = (ep_r*tand) * (pi/(2*log(10))) # value for frequency above f_high ep_inf = (ep_r - 1j*ep_r*tand - m*log((f_high + 1j*f_ep)/(f_low + 1j*f_ep))) return ep_inf + m*log((f_high + 1j*f)/(f_low + 1j*f)) elif self.model == 'frequencyinvariant': return ones(self.frequency.f.shape) * (ep_r - 1j*ep_r*tand) else: raise ValueError('Unknown dielectric dispersion model') @property def tand_f(self) -> NumberLike: """ Frequency dependent dielectric loss factor. """ ep_r = self.ep_r_f return -imag(ep_r) / real(ep_r) @property def alpha_conductor(self) -> NumberLike: """ Losses due to conductor resistivity. """ A, f_A, f = self.A, self.f_A, self.frequency.f return A * log(10)/20 * sqrt(f/f_A) @property def alpha_dielectric(self) -> NumberLike: """ Losses due to dielectric """ ep_r, tand = real(self.ep_r_f), self.tand_f f = self.frequency.f return pi*sqrt(ep_r)*f/c * tand @property def beta_phase(self) -> NumberLike: """ Phase parameter """ ep_r, f = real(self.ep_r_f), self.frequency.f return 2*pi*f*sqrt(ep_r)/c @property def gamma(self) -> NumberLike: """ Propagation constant. See Also -------- alpha_conductor : calculates conductor losses alpha_dielectric: calculates dielectric losses beta_phase : calculates phase parameter """ beta = self.beta_phase alpha = self.alpha_conductor + self.alpha_dielectric return alpha + 1j*beta @property def z0_characteristic(self) -> NumberLike: """ Characteristic Impedance, :math:`z_0` Returns ------- z0_characteristic : npy.ndarray Characteristic Impedance in units of ohms """ return self._z0 @z0_characteristic.setter def z0_characteristic(self, val): self._z0 = val