LCOV - code coverage report
Current view: top level - src/components - rectline.cpp (source / functions) Hit Total Coverage
Test: qucs-core-0.0.19 Code Coverage Lines: 0 122 0.0 %
Date: 2015-01-05 16:01:02 Functions: 0 13 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 148 0.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * rectline.cpp - rectangular waveguide class implementation
       3                 :            :  *
       4                 :            :  * Copyright (C) 2008 Bastien ROUCARIES <roucaries.bastien@gmail.com>
       5                 :            :  * Copyright (C) 2008 Andrea Zonca <andrea.zonca@gmail.com>
       6                 :            :  *
       7                 :            :  * This is free software; you can redistribute it and/or modify
       8                 :            :  * it under the terms of the GNU General Public License as published by
       9                 :            :  * the Free Software Foundation; either version 2, or (at your option)
      10                 :            :  * any later version.
      11                 :            :  *
      12                 :            :  * This software is distributed in the hope that it will be useful,
      13                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      14                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15                 :            :  * GNU General Public License for more details.
      16                 :            :  *
      17                 :            :  * You should have received a copy of the GNU General Public License
      18                 :            :  * along with this package; see the file COPYING.  If not, write to
      19                 :            :  * the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
      20                 :            :  * Boston, MA 02110-1301, USA.
      21                 :            :  *
      22                 :            :  * $Id$
      23                 :            :  *
      24                 :            :  */
      25                 :            : 
      26                 :            : #if HAVE_CONFIG_H
      27                 :            : # include <config.h>
      28                 :            : #endif
      29                 :            : 
      30                 :            : #include "component.h"
      31                 :            : #include "rectline.h"
      32                 :            : 
      33                 :            : /*!\file rectangular.cpp
      34                 :            :    A TE10 rectangular waveguide
      35                 :            : 
      36                 :            :    References:
      37                 :            :    [1] Microwave engineering
      38                 :            :        David M. Pozar
      39                 :            :        John Wiley & sons
      40                 :            :        2d edition
      41                 :            :        1998
      42                 :            :        isbn 0-471-17096-8
      43                 :            : 
      44                 :            :    [2] Fundation for Microwave Engineering
      45                 :            :        The {IEEE} press serie on Electromagnetics Wave Theory
      46                 :            :        Robert E. Collin
      47                 :            :        IEEE Press,
      48                 :            :        2d edition
      49                 :            :        1992
      50                 :            :        isbn 0-7803-6331-1
      51                 :            : 
      52                 :            : */
      53                 :            : 
      54                 :            : 
      55                 :            : using namespace qucs;
      56                 :            : 
      57                 :          0 : rectline::rectline () : circuit (2) {
      58                 :          0 :   alpha = beta = fc_low = fc_high = 0.0;
      59                 :          0 :   zl = 0.0;
      60                 :          0 :   type = CIR_RECTANGULAR;
      61                 :          0 : }
      62                 :            : 
      63                 :          0 : void rectline::calcResistivity (const char * const Mat, nr_double_t T) {
      64         [ #  # ]:          0 :   if (!strcmp (Mat, "Copper")) {
      65         [ #  # ]:          0 :     if (T < 7) {
      66                 :          0 :       rho = 2e-11;
      67                 :            :     }
      68         [ #  # ]:          0 :     else if (T < 15) {
      69                 :          0 :       rho = 6.66667e-17 * qucs::pow (T, 5.0) - 3.88549e-15 * qucs::pow (T, 4.0) +
      70                 :          0 :         9.82267e-14 * qucs::pow (T, 3.0) - 1.29684e-12 * qucs::pow (T, 2.0) +
      71                 :          0 :         8.68341e-12 * T - 2.72120e-12;
      72                 :            :     }
      73         [ #  # ]:          0 :     else if (T < 45) {
      74                 :          0 :       rho = 6.60731e-15 * qucs::pow (T, 3.0) - 1.14812e-13 * qucs::pow (T, 2.0) -
      75                 :          0 :         1.11681e-12 * T + 4.23709e-11;
      76                 :            :     }
      77         [ #  # ]:          0 :     else if (T < 100) {
      78                 :          0 :       rho = -6.53059e-15 * qucs::pow (T, 3.0) + 1.73783e-12 * qucs::pow (T, 2.0) -
      79                 :          0 :         8.73888e-11 * T + 1.37016e-9;
      80                 :            :     }
      81         [ #  # ]:          0 :     else if (T < 350) {
      82                 :          0 :       rho = 1.00018e-17 * qucs::pow (T, 3.0) - 8.72408e-15 * qucs::pow (T, 2.0) +
      83                 :          0 :         7.06020e-11 * T - 3.51125e-9;
      84                 :            :     }
      85                 :            :     else {
      86                 :          0 :       rho = 0.000000020628;
      87                 :            :     }
      88                 :            :     // in ADS iT_K is forced T_Ko Cu_300K:
      89                 :            :     //rho = 1.7e-8;
      90                 :            :   }
      91         [ #  # ]:          0 :   else if (!strcmp (Mat, "StainlessSteel")) {
      92                 :          0 :     rho = 7.4121e-17 * qucs::pow (T, 4.0) - 5.3504e-14 * qucs::pow (T, 3.0) +
      93                 :          0 :       1.2902e-11 * qucs::pow (T, 2.0) - 2.9186e-10 * T +4.9320e-7;
      94                 :            :   }
      95         [ #  # ]:          0 :   else if (!strcmp (Mat, "Gold")) {
      96         [ #  # ]:          0 :     if (T < 20) {
      97                 :          0 :       rho = 0.00000000024;
      98                 :            :     }
      99         [ #  # ]:          0 :     else if (T < 65) {
     100                 :          0 :       rho = 2e-12 * qucs::pow (T, 2.0) - 8e-11 * T + 1e-9;
     101                 :            :     }
     102         [ #  # ]:          0 :     else if (T < 80) {
     103                 :          0 :       rho = 5e-13 * qucs::pow (T, 3.0) - 1e-10 * qucs::pow (T, 2.0) + 9e-9 * T - 2e-7;
     104                 :            :     }
     105         [ #  # ]:          0 :     else if (T < 300) {
     106                 :          0 :       rho = 8e-11 * T - 1e-10;
     107                 :            :     }
     108                 :            :     else {
     109                 :          0 :       rho = 2.4e-8;
     110                 :            :     }
     111                 :            :   }
     112                 :          0 : }
     113                 :            : 
     114                 :            : /*! Compute propagation constant
     115                 :            : 
     116                 :            :     According to [1] table 3.2 p 128
     117                 :            :     Wawe number in vacuum is:
     118                 :            :     \f[
     119                 :            :     k=\omega\sqrt{\mu\varepsilon}=\omega\sqrt{\mu_r \varepsilon_r \mu_0 \varepsilon_0}
     120                 :            :     \f]
     121                 :            :     Where \f$\omega=2\pi f\f$, \f$f\f$ is the frequency, $\f\mu\f$ the magnetic permeability,
     122                 :            :     \f$\varepsilon_r\f$ the permitivity. Using well known formula \f$c^2\mu_0\varepsilon_0=1\f$, we found:
     123                 :            :     \f[
     124                 :            :     k=\frac{\omega}{c} std::sqrt{\mu_r \varepsilon_r}
     125                 :            :     \f]
     126                 :            :     In general case \f$k_c\f$ is:
     127                 :            :     \f[
     128                 :            :     k_c = \sqrt{\left(\frac{m\pi}{a}\right)^2+\left(\frac{n\pi}{b}\right)^2}
     129                 :            :     \f]
     130                 :            :     Where \f$a\f$ is the wider dimension of the guide and \f$b\f$ the smaller and \f$(n,m)\in\mathbb{N}^2\f$.
     131                 :            :     In the TE10 case it simplifies to:
     132                 :            :     \f[
     133                 :            :     k_c = \sqrt{\left(\frac{\pi}{a}\right)^2} = \frac{\pi}{a}
     134                 :            :     \f]
     135                 :            :     The propagation constant is:
     136                 :            :     \f[
     137                 :            :     \beta = \sqrt{k^2 - k_c^2}
     138                 :            :     \f]
     139                 :            :     Loss could be divised in dielectric and resistive loss.
     140                 :            :     Dielectric loss are computed using:
     141                 :            :     \f[
     142                 :            :     \alpha_d = \frac{k^2 \tan \delta}{2\beta}
     143                 :            :     \f]
     144                 :            :     Resistive using [1] eq (3.96) p 125 (valid only for TE10 mode)
     145                 :            :     \f[
     146                 :            :     \alpha_c=\frac{R_s}{a^3 b \beta k Z_0} \left( 2 b \pi^2 + a^3  k^2 \right)
     147                 :            :     \f]
     148                 :            :     Wave impedance is for TE10:
     149                 :            :     \f[
     150                 :            :     Z = \frac{k Z_0}{\beta}
     151                 :            :     \f]
     152                 :            : */
     153                 :          0 : void rectline::calcPropagation (nr_double_t frequency) {
     154                 :          0 :   nr_double_t er   = getPropertyDouble ("er");
     155                 :          0 :   nr_double_t mur  = getPropertyDouble ("mur");
     156                 :          0 :   nr_double_t tand = getPropertyDouble ("tand");
     157                 :          0 :   nr_double_t a    = getPropertyDouble ("a");
     158                 :          0 :   nr_double_t b    = getPropertyDouble ("b");
     159                 :            : 
     160                 :            :   /* wave number */
     161                 :            :   nr_double_t k0;
     162                 :            :   nr_double_t kc;
     163                 :            :   /* dielectric loss */
     164                 :            :   nr_double_t ad, ac, rs;
     165                 :            : 
     166                 :            :   // check cutoff frequency
     167         [ #  # ]:          0 :   if (frequency >= fc_high) {
     168                 :            :     logprint (LOG_ERROR, "WARNING: Operating frequency (%g) outside TE10 "
     169                 :            :               "band (%g <= TE10 <= %g) or outside non propagative mode "
     170                 :          0 :               "<= %g\n", frequency, fc_low, fc_high, fc_low);
     171                 :            :   }
     172                 :            :   // calculate wave number
     173                 :          0 :   k0 = (2.0 * M_PI * frequency * std::sqrt (er * mur)) / C0;
     174                 :          0 :   kc = M_PI / a;
     175                 :            : 
     176                 :            :   // calculate losses only for propagative mode
     177         [ #  # ]:          0 :   if (frequency >= fc_low) {
     178                 :            :     // calculate beta
     179                 :          0 :     beta = std::sqrt (sqr (k0) - sqr (kc));
     180                 :            : 
     181                 :            :     // dielectric
     182                 :          0 :     ad = (sqr(k0) * tand) / (2.0 * beta);
     183                 :            :     // resistive
     184                 :          0 :     rs = std::sqrt (M_PI * frequency * mur * MU0 * rho);
     185                 :          0 :     ac = rs * (2.0 * b * sqr (M_PI) + cubic (a) * sqr (k0)) /
     186                 :          0 :       (cubic (a) * b * beta * k0 *  Z0);
     187                 :          0 :     alpha = (ad + ac);
     188                 :            : 
     189                 :            :     // wave impedance
     190                 :          0 :     zl = (k0 * Z0) / beta;
     191                 :            : 
     192                 :            :   } else {
     193                 :            :     /* according to [2] eq 3.207 */
     194                 :          0 :     beta = 0;
     195                 :          0 :     alpha = -std::sqrt (- (sqr (k0) - sqr (kc)));
     196                 :            :     // wave impedance
     197         [ #  # ]:          0 :     zl = (k0 * Z0) / nr_complex_t (0, -alpha) ;
     198                 :            :   }
     199                 :          0 : }
     200                 :            : 
     201                 :            : /*! Compute noise parameter */
     202                 :          0 : void rectline::calcNoiseSP (nr_double_t) {
     203         [ #  # ]:          0 :   nr_double_t l = getPropertyDouble ("L");
     204         [ #  # ]:          0 :   if (l < 0) return;
     205                 :            :   // calculate noise using Bosma's theorem
     206         [ #  # ]:          0 :   nr_double_t T = getPropertyDouble ("Temp");
     207         [ #  # ]:          0 :   matrix s = getMatrixS ();
     208         [ #  # ]:          0 :   matrix e = eye (getSize ());
     209 [ #  # ][ #  # ]:          0 :   setMatrixN (kelvin (T) / T0 * (e - s * transpose (conj (s))));
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     210                 :            : }
     211                 :            : 
     212                 :            : /*! Check validity of parameter and compute cutoff frequencies
     213                 :            :     \note do not check validity of epsr or mur because some research stuff could use epsr < 1 (plasma)
     214                 :            : */
     215                 :          0 : void rectline::initCheck (void) {
     216                 :          0 :   nr_double_t a = getPropertyDouble ("a");
     217                 :          0 :   nr_double_t b = getPropertyDouble ("b");
     218                 :          0 :   nr_double_t epsr = getPropertyDouble ("er");
     219                 :          0 :   nr_double_t mur = getPropertyDouble ("mur");
     220                 :            :   // check validity
     221         [ #  # ]:          0 :   if (a < b) {
     222                 :          0 :     logprint (LOG_ERROR, "ERROR: a < b should be a >= b.\n");
     223                 :            :   }
     224                 :          0 :   nr_double_t c = std::sqrt (epsr * mur);
     225                 :          0 :   fc_low =  C0 / (2.0 * a * c);
     226                 :            :   /* min of second TE mode and first TM mode */
     227         [ #  # ]:          0 :   fc_high = MIN (C0 / (a * c),  C0 / (2.0  * b * c));
     228                 :            :   // calculation of resistivity
     229                 :          0 :   rho  = getPropertyDouble ("rho");
     230                 :          0 :   nr_double_t T = getPropertyDouble ("Temp");
     231                 :          0 :   calcResistivity (getPropertyString ("Material"), kelvin (T));
     232                 :          0 : }
     233                 :            : 
     234                 :          0 : void rectline::saveCharacteristics (nr_complex_t) {
     235                 :          0 :   setCharacteristic ("Zl", real (zl));
     236                 :          0 : }
     237                 :            : 
     238                 :            : /*! initialize S-parameters */
     239                 :          0 : void rectline::initSP (void) {
     240                 :            :   // allocate S-parameter matrix
     241                 :          0 :   allocMatrixS ();
     242                 :          0 :   initCheck ();
     243                 :          0 : }
     244                 :            : 
     245                 :            : /*! Compute S parameter use generic transmission line formulae */
     246                 :          0 : void rectline::calcSP (nr_double_t frequency) {
     247         [ #  # ]:          0 :   nr_double_t l = getPropertyDouble ("L");
     248                 :            : 
     249                 :            :   // calculate propagation constants
     250         [ #  # ]:          0 :   calcPropagation (frequency);
     251                 :            : 
     252                 :            :   // calculate S-parameters
     253                 :          0 :   nr_complex_t z = zl / z0;
     254         [ #  # ]:          0 :   nr_complex_t y = 1.0 / z;
     255                 :          0 :   nr_complex_t g = nr_complex_t (alpha, beta);
     256 [ #  # ][ #  # ]:          0 :   nr_complex_t n = 2.0 * cosh (g * l) + (z + y) * sinh (g * l);
         [ #  # ][ #  # ]
                 [ #  # ]
     257 [ #  # ][ #  # ]:          0 :   nr_complex_t s11 = (z - y) * sinh (g * l) / n;
         [ #  # ][ #  # ]
     258         [ #  # ]:          0 :   nr_complex_t s21 = 2.0 / n;
     259 [ #  # ][ #  # ]:          0 :   setS (NODE_1, NODE_1, s11); setS (NODE_2, NODE_2, s11);
     260 [ #  # ][ #  # ]:          0 :   setS (NODE_1, NODE_2, s21); setS (NODE_2, NODE_1, s21);
     261                 :          0 : }
     262                 :            : 
     263                 :            : /* ! Compute DC
     264                 :            :      \note below cut off it is an open circuit
     265                 :            : */
     266                 :          0 : void rectline::initDC (void) {
     267                 :          0 :   allocMatrixMNA ();
     268                 :            :   // open circuit
     269                 :          0 :   clearY ();
     270                 :          0 : }
     271                 :            : 
     272                 :            : /*! init AC */
     273                 :          0 : void rectline::initAC (void) {
     274                 :          0 :   setVoltageSources (0);
     275                 :          0 :   allocMatrixMNA ();
     276                 :          0 :   initCheck ();
     277                 :          0 : }
     278                 :            : 
     279                 :            : /*! calc propagation using classical transmission line formulae */
     280                 :          0 : void rectline::calcAC (nr_double_t frequency) {
     281         [ #  # ]:          0 :   nr_double_t l = getPropertyDouble ("L");
     282                 :            : 
     283                 :            :   // calculate propagation constants
     284         [ #  # ]:          0 :   calcPropagation (frequency);
     285                 :            : 
     286                 :            :   // calculate Y-parameters
     287                 :          0 :   nr_complex_t g = nr_complex_t (alpha, beta);
     288 [ #  # ][ #  # ]:          0 :   nr_complex_t y11 = coth (g * l) / zl;
     289 [ #  # ][ #  # ]:          0 :   nr_complex_t y21 = -cosech (g * l) / zl;
     290 [ #  # ][ #  # ]:          0 :   setY (NODE_1, NODE_1, y11); setY (NODE_2, NODE_2, y11);
     291 [ #  # ][ #  # ]:          0 :   setY (NODE_1, NODE_2, y21); setY (NODE_2, NODE_1, y21);
     292                 :          0 : }
     293                 :            : 
     294                 :            : /*! Compute noise */
     295                 :          0 : void rectline::calcNoiseAC (nr_double_t) {
     296                 :          0 :   nr_double_t l = getPropertyDouble ("L");
     297         [ #  # ]:          0 :   if (l < 0) return;
     298                 :            :   // calculate noise using Bosma's theorem
     299                 :          0 :   nr_double_t T = getPropertyDouble ("Temp");
     300 [ #  # ][ #  # ]:          0 :   setMatrixN (4.0 * kelvin (T) / T0 * real (getMatrixY ()));
         [ #  # ][ #  # ]
                 [ #  # ]
     301                 :            : }
     302                 :            : 
     303                 :            : // properties
     304                 :            : PROP_REQ [] = {
     305                 :            :   { "a", PROP_REAL, { 2.86e-2, PROP_NO_STR }, PROP_POS_RANGEX },
     306                 :            :   { "b", PROP_REAL, { 1.016e-2, PROP_NO_STR }, PROP_POS_RANGEX },
     307                 :            :   { "L", PROP_REAL, { 1500e-3, PROP_NO_STR }, PROP_NO_RANGE },
     308                 :            :   { "er", PROP_REAL, { 1, PROP_NO_STR }, PROP_RNGII (1, 100) },
     309                 :            :   { "mur", PROP_REAL, { 1, PROP_NO_STR }, PROP_RNGII (1, 100) },
     310                 :            :   { "tand", PROP_REAL, { 4e-4, PROP_NO_STR }, PROP_POS_RANGE },
     311                 :            :   { "rho", PROP_REAL, { 0.022e-6, PROP_NO_STR }, PROP_POS_RANGE },
     312                 :            :   PROP_NO_PROP };
     313                 :            : PROP_OPT [] = {
     314                 :            :   { "Temp", PROP_REAL, { 26.85, PROP_NO_STR }, PROP_MIN_VAL (K) },
     315                 :            :   { "Material", PROP_STR, { PROP_NO_VAL, "unspecified" },
     316                 :            :     PROP_RNG_STR4 ("unspecified", "Copper", "StainlessSteel", "Gold") },
     317                 :            :   PROP_NO_PROP };
     318                 :            : struct define_t rectline::cirdef =
     319                 :            :   { "RECTLINE", 2, PROP_COMPONENT, PROP_NO_SUBSTRATE, PROP_LINEAR, PROP_DEF };

Generated by: LCOV version 1.11