• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

scikit-rf / scikit-rf / 25805732079

13 May 2026 02:30PM UTC coverage: 79.567% (-0.01%) from 79.577%
25805732079

Pull #1372

github

web-flow
Merge ec1d18217 into 950534a59
Pull Request #1372: Lazy load most modules

211 of 271 new or added lines in 28 files covered. (77.86%)

4 existing lines in 4 files now uncovered.

18053 of 22689 relevant lines covered (79.57%)

3.98 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

86.27
/skrf/media/rectangularWaveguide.py
1
"""
2
rectangularWaveguide (:mod:`skrf.media.rectangularWaveguide`)
3
================================================================
4

5
Represents a single mode of a homogeneously filled rectangular
6
waveguide of cross-section `a` x `b`. The mode is determined by
7
`mode-type` (`'te'` or `'tm'`) and mode indices ( `m` and `n` ).
8

9

10
====================================  =============  ===============
11
Quantity                              Symbol         Variable
12
====================================  =============  ===============
13
Characteristic Wave Number            :math:`k_0`    :attr:`k0`
14
Cut-off Wave Number                   :math:`k_c`    :attr:`kc`
15
Longitudinal Wave Number              :math:`k_z`    :attr:`gamma`
16
Transverse Wave Number (a)            :math:`k_x`    :attr:`kx`
17
Transverse Wave Number (b)            :math:`k_y`    :attr:`ky`
18
Characteristic Impedance              :math:`z_0`    :attr:`z0`
19
====================================  =============  ===============
20

21
.. autosummary::
22
   :toctree: generated/
23

24
   RectangularWaveguide
25

26
"""
27
from __future__ import annotations
5✔
28

29
from numbers import Number
5✔
30
from typing import TYPE_CHECKING
5✔
31

32
import numpy as np
5✔
33
from numpy import exp, pi, sqrt, where
5✔
34

35
from .. import constants as _const
5✔
36
from ..data import materials
5✔
37
from ..tlineFunctions import skin_depth
5✔
38
from .freespace import Freespace
5✔
39
from .media import Media
5✔
40

41
if TYPE_CHECKING:
42
    from ..constants import NumberLike
43
    from ..frequency import Frequency
44

45

46
class RectangularWaveguide(Media):
5✔
47
    r"""
48
    A single mode of a homogeneously filled rectangular waveguide.
49

50
    Parameters
51
    ----------
52
    frequency : :class:`~skrf.frequency.Frequency` object
53
        frequency band of this transmission line medium
54
    z0_port : number, array-like, or None
55
        `z0_port` is the port impedance for networks generated by the media.
56
        If `z0_port` is not None, the networks generated by the media are
57
        renormalized (or in other words embedded) from the characteristic
58
        impedance z0 of the media to `z0_port`.
59
        Else if `z0_port` is None, the networks port impedances will be the raw
60
        characteristic impedance z0 of the media.
61
        (Default is None)
62
    z0_override : number, array-like, or None
63
        `z0_override` override the characteristic impedance for the media.
64
        If `z0_override` is not None, the networks generated by the media have
65
        their characteristic impedance `z0` overridden by `z0_override`.
66
        (Default is None)
67
    z0 : number, array-like, or None
68
        deprecated parameter, alias to `z0_override` if `z0_override` is None.
69
        Emit a deprecation warning.
70
    a : number, optional
71
        width of waveguide, in meters.
72
        Default is 1.
73
    b : number or None, optional
74
        height of waveguide, in meters.
75
        If `None` defaults to a/2.
76
        Default is None
77
    mode_type : ['te','tm']
78
        mode type, transverse electric (te) or transverse magnetic
79
        (tm) to-z. where z is direction of propagation
80
    m : int
81
        mode index in 'a'-direction
82
    n : int
83
        mode index in 'b'-direction
84
    ep_r : number, array-like,
85
        filling material's relative permittivity
86
    mu_r : number, array-like
87
        filling material's relative permeability
88
    rho : number, array-like, string
89
        resistivity (ohm-m) of the conductor walls. If array-like
90
        must be same length as frequency. if str, it must be a key in
91
        :data:`skrf.data.materials`.
92
    roughness : number, or array-like
93
        surface roughness of the conductor walls in units of RMS
94
        deviation from surface
95
    \*args, \*\*kwargs : arguments, keyword arguments
96
            passed to :class:`~skrf.media.media.Media`'s constructor
97
            (:func:`~skrf.media.media.Media.__init__`
98

99
    Examples
100
    --------
101
    Most common usage is standard aspect ratio (2:1) dominant
102
    mode, TE10 mode of wr10 waveguide can be constructed by
103

104
    >>> freq = rf.Frequency(75,110,101,'ghz')
105
    >>> rf.RectangularWaveguide(freq,a= 100*mil)
106
    """
107

108
    def __init__(self, frequency: Frequency | None = None,
5✔
109
                 z0_port: NumberLike | None = None,
110
                 z0_override: NumberLike | None = None,
111
                 z0: NumberLike | None = None,
112
                 a: float = 1, b: float | None = None,
113
                 mode_type: str = 'te', m: int = 1, n: int = 0,
114
                 ep_r: None | NumberLike = 1, mu_r: None | NumberLike = 1,
115
                 rho: None | NumberLike = None,
116
                 roughness: None | NumberLike = None,
117
                 *args, **kwargs):
118
        Media.__init__(self, frequency = frequency,
5✔
119
                       z0_port = z0_port, z0_override = z0_override, z0 = z0)
120

121
        if b is None:
5✔
122
            b = a/2.
5✔
123
        if mode_type.lower() not in ['te','tm']:
5✔
124
            raise ValueError('mode_type must be either \'te\' or \'tm\'')
×
125

126

127

128
        self.a = a
5✔
129
        self.b = b
5✔
130
        self.mode_type = mode_type.lower()
5✔
131
        self.m = m
5✔
132
        self.n = n
5✔
133
        self.ep_r = ep_r
5✔
134
        self.mu_r = mu_r
5✔
135
        self.rho = rho
5✔
136
        self.roughness = roughness
5✔
137

138

139
    def __str__(self):
5✔
140
        f=self.frequency
×
141
        output = (
×
142
                f'Rectangular Waveguide Media.  {f.f_scaled[0]}-{f.f_scaled[-1]} {f.unit}.  {f.npoints} points'
143
                f'\n a= {self.a:.2e}m, b= {self.b:.2e}m')
144
        return output
×
145

146
    def __repr__(self):
5✔
147
        return self.__str__()
×
148

149

150
    @classmethod
5✔
151
    def from_z0(cls, frequency: Frequency, z0: NumberLike, f: Number,
5✔
152
                ep_r=1, mu_r=1, **kw) -> Media:
153
        """
154
        Initialize from specified impedance at a given frequency, assuming
155
        the fundamental TE10 mode.
156

157
        Parameters
158
        ----------
159
        frequency : Frequency Object
160
        z0 : number /array
161
            characteristic impedance to create at `f`
162
        f : number
163
            frequency (in Hz) at which the resultant waveguide has the
164
            characteristic impedance z0
165
        ep_r : number, array-like,
166
            filling material's relative permittivity
167
        mu_r : number, array-like
168
            filling material's relative permeability
169
        """
170

NEW
171
        mu = _const.mu_0*mu_r
×
NEW
172
        ep = _const.epsilon_0*ep_r
×
173
        w = 2*pi*f
×
174
        a =pi/(w*mu) * 1./sqrt(1/(z0*1j)**2+ep/mu)
×
175

176
        kw.update(dict(frequency=frequency,a=a, m=1, n=0, ep_r=ep_r, mu_r=mu_r))
×
177

178
        return cls(**kw)
×
179

180
    @property
5✔
181
    def ep(self) -> NumberLike:
5✔
182
        r"""
183
        The permittivity of the filling material.
184

185
        .. math:
186

187
            \varepsilon = \varepsilon_r \varepsilon_0
188

189
        Returns
190
        -------
191
        ep : number
192
            filling material's permittivity in F/m.
193
        """
194
        return self.ep_r * _const.epsilon_0
5✔
195

196
    @property
5✔
197
    def mu(self) -> NumberLike:
5✔
198
        r"""
199
        The permeability of the filling material.
200

201
        .. math::
202

203
            \mu = \mu_r \mu_0
204

205
        Returns
206
        -------
207
        mu : number
208
            filling material's permeability in H/m.
209

210
        """
211
        return self.mu_r * _const.mu_0
5✔
212

213
    @property
5✔
214
    def k0(self) -> NumberLike:
5✔
215
        r"""
216
        Characteristic wave number.
217

218
        .. math::
219

220
            k_0 = \frac{\omega}{v} = \omega \sqrt{\varepsilon_r \mu_r}
221

222
        Returns
223
        -------
224
        k0 : number
225
            characteristic wave number
226
        """
227
        return 2*pi*self.frequency.f*sqrt(self.ep * self.mu)
5✔
228

229
    @property
5✔
230
    def ky(self) -> NumberLike:
5✔
231
        r"""
232
        Eigenvalue in the `b` direction.
233

234
        Defined as
235

236
        .. math::
237

238
            k_y = n \frac{\pi}{b}
239

240
        Returns
241
        -------
242
        ky : number
243
                eigenvalue in `b` direction
244
        """
245
        return self.n*pi/self.b
5✔
246

247
    @property
5✔
248
    def kx(self) -> NumberLike:
5✔
249
        r"""
250
        Eigenvalue in the 'a' direction.
251

252
        Defined as
253

254
        .. math::
255

256
            k_x = m \frac{\pi}{a}
257

258
        Returns
259
        -------
260
        kx : number
261
                eigenvalue in `a` direction
262
        """
263
        return self.m*pi/self.a
5✔
264

265
    @property
5✔
266
    def kc(self) -> NumberLike:
5✔
267
        r"""
268
        Cut-off wave number.
269

270
        Defined as
271

272
        .. math::
273

274
            k_c = \sqrt {k_x^2 + k_y^2} = \sqrt {
275
                {m \frac{\pi}{a}}^2 + {n \frac{\pi}{b}}^2}
276

277
        Returns
278
        -------
279
        kc : number
280
                cut-off wavenumber
281
        """
282
        return sqrt( self.kx**2 + self.ky**2)
5✔
283

284

285
    @property
5✔
286
    def f_cutoff(self) -> NumberLike:
5✔
287
        r"""
288
        cutoff frequency for this mode.
289

290
        .. math::
291

292
            f_c = \frac{v}{2 \pi} \sqrt {
293
                {m \frac{\pi}{a}}^2 + {n \frac{\pi}{b}}^2}
294

295
        where :math:`v= 1/\sqrt{\varepsilon \mu}`.
296

297
        """
298
        v = 1/sqrt(self.ep*self.mu)
5✔
299
        return v* self.kc/(2*np.pi)
5✔
300

301
    @property
5✔
302
    def f_norm(self) -> NumberLike:
5✔
303
        """
304
        Frequency vector normalized to cutoff.
305
        """
306
        return self.frequency.f/self.f_cutoff
5✔
307

308
    @property
5✔
309
    def rho(self) -> NumberLike:
5✔
310
        """
311
        Conductivity of sidewalls in ohm*m.
312

313
        Parameters
314
        ----------
315
        val : float, array-like or str
316
            the conductivity in ohm*m. If array-like must be same length
317
            as self.frequency. if str, it must be a key in
318
            :data:`skrf.data.materials`.
319

320
        Examples
321
        ---------
322
        >>> wg.rho = 2.8e-8
323
        >>> wg.rho = 2.8e-8 * ones(len(wg.frequency))
324
        >>> wg.rho = 'al'
325
        >>> wg.rho = 'aluminum'
326
        """
327
        if self.roughness is not None:
5✔
328
            delta = skin_depth(self.frequency.f, self._rho, self.mu_r)
5✔
329
            k_w = 1. +exp(-(delta/(2*self.roughness))**1.6)
5✔
330
            return self._rho*k_w**2
5✔
331

332
        return self._rho
5✔
333

334
    @rho.setter
5✔
335
    def rho(self, val: NumberLike | str):
5✔
336
        if isinstance(val, str):
5✔
337
            self._rho = materials[val.lower()]['resistivity(ohm*m)']
5✔
338
        else:
339
            self._rho=val
5✔
340

341
    @property
5✔
342
    def lambda_guide(self) -> NumberLike:
5✔
343
        r"""
344
        Guide wavelength.
345

346
        .. math::
347

348
            \lambda_g = \frac{2\pi}{\beta}
349

350
        The distance in which the phase of the field increases by 2 pi.
351

352
        See Also
353
        --------
354
        k0
355
        """
356
        return 2*pi/self.beta
×
357

358
    @property
5✔
359
    def lambda_cutoff(self) -> NumberLike:
5✔
360
        r"""
361
        Cutoff wavelength.
362

363
        .. math::
364

365
            \lambda_c = v/f_c
366

367
        where :math:`v= 1/\sqrt{\varepsilon \mu}` and :math:`f_c` the cut-off frequency.
368

369
        See Also
370
        --------
371
        f_cutoff
372
        """
373
        v = 1/sqrt(self.ep*self.mu)
×
374
        return v/self.f_cutoff
×
375

376
    @property
5✔
377
    def gamma(self) -> NumberLike:
5✔
378
        r"""
379
        The propagation constant (aka Longitudinal wave number).
380

381
        Defined as
382

383
        .. math::
384

385
            k_z = \pm j \sqrt {k_0^2 - k_c^2}
386

387
        This is:
388

389
        * IMAGINARY for propagating modes
390
        * REAL for non-propagating modes,
391

392
        Returns
393
        -------
394
        gamma :  number
395
            The propagation constant
396
        """
397
        ## haringtons form
398
        if False:  #self.m==1 and self.n==0:
5✔
399
            fs = Freespace(frequency=self.frequency,
400
                           ep_r=self.ep_r,
401
                           mu_r=self.mu_r)
402

403

404
            g = where(self.f_norm>1.,
405
                     sqrt(1-self.f_norm**(-2))*fs.gamma,  # cutton
406
                 -1j*sqrt(1-self.f_norm**(2))*fs.gamma)  # cutoff
407

408
        else:
409
            # TODO:  fix this for lossy ep/mu (remove abs?)
410
            k0, kc = self.k0, self.kc
5✔
411
            g =  1j*sqrt(abs(k0**2 - kc**2)) * (k0>kc) +\
5✔
412
                    sqrt(abs(kc**2- k0**2))*(k0<kc) + \
413
                    0*(kc==k0)
414

415
        g = g + self.alpha_c *(self.rho is not None)
5✔
416

417
        return g
5✔
418

419

420
    @property
5✔
421
    def alpha_c(self) -> NumberLike:
5✔
422
        r"""
423
        Loss due to finite conductivity and roughness of sidewalls.
424

425
        In units of np/m
426
        See property `rho` for setting conductivity.
427

428
        Effects of finite conductivity are taken from [#]_. If
429
        :attr:`roughness` is not None, then its effects the conductivity
430
        by
431

432

433
        .. math::
434

435
            \sigma_c = \frac{\sigma}{k_w^2}
436

437

438
        where
439

440
        .. math::
441

442
            k_w = 1 + e^{(-\delta/2h)^{1.6}}
443

444
            \delta = \mbox{skin depth}
445

446
            h = \mbox{surface roughness }
447

448

449
        This is taken from Ansoft HFSS help documents.
450

451
        References
452
        ----------
453

454
        .. [#] Chapter 9, (eq 9.8.1) of Electromagnetic Waves and Antennas by Sophocles J. Orfanidis
455
            http://eceweb1.rutgers.edu/~orfanidi/ewa/
456
        """
457

458
        if self.rho is None:
5✔
459
            return 0
5✔
460

461
        a,b,w,ep,rho,f_n = self.a, self.b, self.frequency.w, self.ep, \
5✔
462
            self.rho, self.f_norm
463

464
        return 1./b * sqrt( (w*ep)/(2./rho) ) * (1+2.*b/a*(1/f_n)**2)/\
5✔
465
            sqrt(1-(1/f_n)**2)
466

467
    @property
5✔
468
    def z0_characteristic(self) -> NumberLike:
5✔
469
        """
470
        The characteristic impedance, :math:`z_0`.
471

472
        The characteristic impedance depends of the mode ('te' or 'tm').
473

474
        Returns
475
        -------
476
        z0_characteristic : np.ndarray
477
            Characteristic Impedance in units of ohms
478
        """
479
        omega = self.frequency.w
5✔
480
        impedance_dict = {'te':   1j*omega*self.mu/(self.gamma),
5✔
481
                          'tm':   -1j*self.gamma/(omega*self.ep),\
482
                         }
483

484
        return impedance_dict[self.mode_type]
5✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc