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

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * cpwline.cpp - coplanar waveguide line class implementation
       3                 :            :  *
       4                 :            :  * Copyright (C) 2004, 2005 Vincent Habchi, F5RCS <10.50@free.fr>
       5                 :            :  * Copyright (C) 2004, 2005, 2006, 2008 Stefan Jahn <stefan@lkcc.org>
       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 <limits>
      31                 :            : 
      32                 :            : #include "component.h"
      33                 :            : #include "substrate.h"
      34                 :            : #include "cpwline.h"
      35                 :            : 
      36                 :            : using namespace qucs;
      37                 :            : 
      38                 :          0 : cpwline::cpwline () : circuit (2) {
      39                 :          0 :   Zl = Er = 0;
      40                 :          0 :   type = CIR_CPWLINE;
      41                 :          0 : }
      42                 :            : 
      43                 :            : /*! K(k)
      44                 :            : 
      45                 :            :  The function computes the complete elliptic integral of first kind
      46                 :            :    K() and the second kind E() using the arithmetic-geometric mean
      47                 :            :    algorithm (AGM) by Abramowitz and Stegun.
      48                 :            : \todo move to common math
      49                 :            : */
      50                 :          0 : void cpwline::ellipke (nr_double_t arg, nr_double_t &k, nr_double_t &e) {
      51                 :          0 :   int iMax = 16;
      52         [ #  # ]:          0 :   if (arg == 1.0) {
      53                 :          0 :     k = std::numeric_limits<nr_double_t>::infinity();
      54                 :          0 :     e = 0;
      55                 :            :   }
      56 [ #  # ][ #  # ]:          0 :   else if (std::isinf (arg) && arg < 0) {
                 [ #  # ]
      57                 :          0 :     k = 0;
      58                 :          0 :     e = std::numeric_limits<nr_double_t>::infinity();
      59                 :            :   }
      60                 :            :   else {
      61                 :          0 :     nr_double_t a, b, c, f, s, fk = 1, fe = 1, t, da = arg;
      62                 :            :     int i;
      63         [ #  # ]:          0 :     if (arg < 0) {
      64                 :          0 :       fk = 1 / qucs::sqrt (1 - arg);
      65                 :          0 :       fe = qucs::sqrt (1 - arg);
      66                 :          0 :       da = -arg / (1 - arg);
      67                 :            :     }
      68                 :          0 :     a = 1;
      69                 :          0 :     b = qucs::sqrt (1 - da);
      70                 :          0 :     c = qucs::sqrt (da);
      71                 :          0 :     f = 0.5;
      72                 :          0 :     s = f * c * c;
      73         [ #  # ]:          0 :     for (i = 0; i < iMax; i++) {
      74                 :          0 :       t = (a + b) / 2;
      75                 :          0 :       c = (a - b) / 2;
      76                 :          0 :       b = qucs::sqrt (a * b);
      77                 :          0 :       a = t;
      78                 :          0 :       f *= 2;
      79                 :          0 :       s += f * c * c;
      80         [ #  # ]:          0 :       if (c / a < std::numeric_limits<nr_double_t>::epsilon()) break;
      81                 :            :     }
      82         [ #  # ]:          0 :     if (i >= iMax) {
      83                 :          0 :       k = 0; e = 0;
      84                 :            :     }
      85                 :            :     else {
      86                 :          0 :       k = M_PI_2 / a;
      87                 :          0 :       e = M_PI_2 * (1 - s) / a;
      88         [ #  # ]:          0 :       if (arg < 0) {
      89                 :          0 :         k *= fk;
      90                 :          0 :         e *= fe;
      91                 :            :       }
      92                 :            :     }
      93                 :            :   }
      94                 :          0 : }
      95                 :            : 
      96                 :            : /* We need to know only K(k), and if possible KISS. */
      97                 :          0 : nr_double_t cpwline::ellipk (nr_double_t k) {
      98                 :            :   nr_double_t r, lost;
      99         [ #  # ]:          0 :   ellipke (k, r, lost);
     100                 :          0 :   return r;
     101                 :            : }
     102                 :            : 
     103                 :            : /* More or less accurate approximation of K(k)/K'(k).  Suggested by
     104                 :            :    publications dealing with coplanar components. */
     105                 :          0 : nr_double_t cpwline::ellipa (nr_double_t k) {
     106                 :            :   nr_double_t r, kp;
     107         [ #  # ]:          0 :   if (k < M_SQRT1_2) {
     108                 :          0 :     kp = qucs::sqrt (1 - k * k);
     109                 :          0 :     r = M_PI / qucs::log (2 * (1 + qucs::sqrt (kp)) / (1 - qucs::sqrt (kp)));
     110                 :            :   }
     111                 :            :   else {
     112                 :          0 :     r = qucs::log (2 * (1 + qucs::sqrt (k)) / (1 - qucs::sqrt (k))) / M_PI;
     113                 :            :   }
     114                 :          0 :   return r;
     115                 :            : }
     116                 :            : 
     117                 :          0 : void cpwline::initSP (void) {
     118                 :            :   // allocate S-parameter matrix
     119                 :          0 :   allocMatrixS ();
     120                 :            :   // pre-compute propagation factors
     121                 :          0 :   initPropagation ();
     122                 :          0 : }
     123                 :            : 
     124                 :          0 : void cpwline::initPropagation (void) {
     125                 :            :   // get properties of substrate and coplanar line
     126                 :          0 :   nr_double_t W =  getPropertyDouble ("W");
     127                 :          0 :   nr_double_t s =  getPropertyDouble ("S");
     128                 :          0 :   substrate * subst = getSubstrate ();
     129                 :          0 :   nr_double_t er = subst->getPropertyDouble ("er");
     130                 :          0 :   nr_double_t h  = subst->getPropertyDouble ("h");
     131                 :          0 :   nr_double_t t  = subst->getPropertyDouble ("t");
     132                 :          0 :   int backMetal  = !strcmp (getPropertyString ("Backside"), "Metal");
     133                 :          0 :   int approx     = !strcmp (getPropertyString ("Approx"), "yes");
     134                 :            : 
     135                 :          0 :   tand = subst->getPropertyDouble ("tand");
     136                 :          0 :   rho  = subst->getPropertyDouble ("rho");
     137                 :          0 :   len  = getPropertyDouble ("L");
     138                 :            : 
     139                 :            :   // other local variables (quasi-static constants)
     140                 :          0 :   nr_double_t k1, kk1, kpk1, k2, k3, q1, q2, q3 = 0, qz, er0 = 0;
     141                 :            : 
     142                 :            :   // compute the necessary quasi-static approx. (K1, K3, er(0) and Z(0))
     143                 :          0 :   k1   = W / (W + s + s);
     144                 :          0 :   kk1  = ellipk (k1);
     145                 :          0 :   kpk1 = ellipk (qucs::sqrt (1 - k1 * k1));
     146         [ #  # ]:          0 :   if (approx) {
     147                 :          0 :     q1 = ellipa (k1);
     148                 :            :   } else {
     149                 :          0 :     q1 = kk1 / kpk1;
     150                 :            :   }
     151                 :            : 
     152                 :            :   // backside is metal
     153         [ #  # ]:          0 :   if (backMetal) {
     154                 :          0 :     k3  = qucs::tanh ((M_PI / 4) * (W / h)) / qucs::tanh ((M_PI / 4) * (W + s + s) / h);
     155         [ #  # ]:          0 :     if (approx) {
     156                 :          0 :       q3 = ellipa (k3);
     157                 :            :     } else {
     158                 :          0 :       q3 = ellipk (k3) / ellipk (qucs::sqrt (1 - k3 * k3));
     159                 :            :     }
     160                 :          0 :     qz  = 1 / (q1 + q3);
     161                 :          0 :     er0 = 1 + q3 * qz * (er - 1);
     162                 :          0 :     zl_factor = Z0 / 2 * qz;
     163                 :            :   }
     164                 :            :   // backside is air
     165                 :            :   else {
     166                 :          0 :     k2  = qucs::sinh ((M_PI / 4) * (W / h)) / qucs::sinh ((M_PI / 4) * (W + s + s) / h);
     167         [ #  # ]:          0 :     if (approx) {
     168                 :          0 :       q2 = ellipa (k2);
     169                 :            :     } else {
     170                 :          0 :       q2 = ellipk (k2) / ellipk (qucs::sqrt (1 - k2 * k2));
     171                 :            :     }
     172                 :          0 :     er0 = 1 + (er - 1) / 2 * q2 / q1;
     173                 :          0 :     zl_factor = Z0 / 4 / q1;
     174                 :            :   }
     175                 :            : 
     176                 :            :   // adds effect of strip thickness
     177         [ #  # ]:          0 :   if (t > 0) {
     178                 :            :     nr_double_t d, se, We, ke, qe;
     179                 :          0 :     d  = (t * 1.25 / M_PI) * (1 + qucs::log (4 * M_PI * W / t));
     180                 :          0 :     se = s - d;
     181                 :          0 :     We = W + d;
     182                 :            : 
     183                 :            :     // modifies k1 accordingly (k1 = ke)
     184                 :          0 :     ke = We / (We + se + se); // ke = k1 + (1 - k1 * k1) * d / 2 / s;
     185         [ #  # ]:          0 :     if (approx) {
     186                 :          0 :       qe = ellipa (ke);
     187                 :            :     } else {
     188                 :          0 :       qe = ellipk (ke) / ellipk (qucs::sqrt (1 - ke * ke));
     189                 :            :     }
     190                 :            :     // backside is metal
     191         [ #  # ]:          0 :     if (backMetal) {
     192                 :          0 :       qz  = 1 / (qe + q3);
     193                 :          0 :       er0 = 1 + q3 * qz * (er - 1);
     194                 :          0 :       zl_factor = Z0 / 2 * qz;
     195                 :            :     }
     196                 :            :     // backside is air
     197                 :            :     else {
     198                 :          0 :       zl_factor = Z0 / 4 / qe;
     199                 :            :     }
     200                 :            : 
     201                 :            :     // modifies er0 as well
     202                 :          0 :     er0 = er0 - (0.7 * (er0 - 1) * t / s) / (q1 + (0.7 * t / s));
     203                 :            :   }
     204                 :            : 
     205                 :            :   // pre-compute square roots
     206                 :          0 :   sr_er = qucs::sqrt (er);
     207                 :          0 :   sr_er0 = qucs::sqrt (er0);
     208                 :            : 
     209                 :            :   // cut-off frequency of the TE0 mode
     210                 :          0 :   fte = (C0 / 4) / (h * qucs::sqrt (er - 1));
     211                 :            : 
     212                 :            :   // dispersion factor G
     213                 :          0 :   nr_double_t p = qucs::log (W / h);
     214                 :          0 :   nr_double_t u = 0.54 - (0.64 - 0.015 * p) * p;
     215                 :          0 :   nr_double_t v = 0.43 - (0.86 - 0.54 * p) * p;
     216                 :          0 :   G = qucs::exp (u * qucs::log (W / s) + v);
     217                 :            : 
     218                 :            :   // loss constant factors (computed only once for efficency sake)
     219                 :          0 :   nr_double_t ac = 0;
     220         [ #  # ]:          0 :   if (t > 0) {
     221                 :            :     // equations by GHIONE
     222                 :          0 :     nr_double_t n  = (1 - k1) * 8 * M_PI / (t * (1 + k1));
     223                 :          0 :     nr_double_t a  = W / 2;
     224                 :          0 :     nr_double_t b  = a + s;
     225                 :          0 :     ac = (M_PI + qucs::log (n * a)) / a + (M_PI + qucs::log (n * b)) / b;
     226                 :            :   }
     227                 :          0 :   ac_factor  = ac / (4 * Z0 * kk1 * kpk1 * (1 - k1 * k1));
     228                 :          0 :   ac_factor *= qucs::sqrt (M_PI * MU0 * rho); // Rs factor
     229                 :          0 :   ad_factor  = (er / (er - 1)) * tand * M_PI / C0;
     230                 :            : 
     231                 :          0 :   bt_factor  = 2 * M_PI / C0;
     232                 :          0 : }
     233                 :            : 
     234                 :          0 : void cpwline::calcAB (nr_double_t f, nr_double_t& zl, nr_double_t& al,
     235                 :            :                       nr_double_t& bt) {
     236                 :          0 :   nr_double_t sr_er_f = sr_er0;
     237                 :          0 :   nr_double_t ac = ac_factor;
     238                 :          0 :   nr_double_t ad = ad_factor;
     239                 :            : 
     240                 :            :   // by initializing as much as possible outside this function, the
     241                 :            :   // overhead is minimal
     242                 :            : 
     243                 :            :   // add the dispersive effects to er0
     244                 :          0 :   sr_er_f += (sr_er - sr_er0) / (1 + G * qucs::pow (f / fte, -1.8));
     245                 :            : 
     246                 :            :   // computes impedance
     247                 :          0 :   zl /= sr_er_f;
     248                 :            : 
     249                 :            :   // for now, the loss are limited to strip losses (no radiation
     250                 :            :   // losses yet) losses in neper/length
     251                 :          0 :   ad *= f * (sr_er_f - 1 / sr_er_f);
     252                 :          0 :   ac *= qucs::sqrt (f) * sr_er0;
     253                 :            : 
     254                 :          0 :   al  = ac + ad;
     255                 :          0 :   bt *= sr_er_f * f;
     256                 :            : 
     257                 :          0 :   Er = sqr (sr_er_f);
     258                 :          0 :   Zl = zl;
     259                 :          0 : }
     260                 :            : 
     261                 :          0 : void cpwline::saveCharacteristics (nr_double_t) {
     262                 :          0 :   setCharacteristic ("Zl", Zl);
     263                 :          0 :   setCharacteristic ("Er", Er);
     264                 :          0 : }
     265                 :            : 
     266                 :          0 : void cpwline::calcSP (nr_double_t frequency) {
     267                 :            : 
     268                 :          0 :   nr_double_t zl = zl_factor;
     269                 :          0 :   nr_double_t beta = bt_factor;
     270                 :            :   nr_double_t alpha;
     271                 :            : 
     272         [ #  # ]:          0 :   calcAB (frequency, zl, alpha, beta);
     273                 :            : 
     274                 :            :   // calculate and set S-parameters
     275                 :          0 :   nr_double_t z = zl / z0;
     276                 :          0 :   nr_double_t y = 1 / z;
     277                 :          0 :   nr_complex_t g = nr_complex_t (alpha, beta);
     278 [ #  # ][ #  # ]:          0 :   nr_complex_t n = 2.0 * cosh (g * len) + (z + y) * sinh (g * len);
                 [ #  # ]
     279 [ #  # ][ #  # ]:          0 :   nr_complex_t s11 = (z - y) * sinh (g * len) / n;
     280         [ #  # ]:          0 :   nr_complex_t s21 = 2.0 / n;
     281                 :            : 
     282 [ #  # ][ #  # ]:          0 :   setS (NODE_1, NODE_1, s11); setS (NODE_2, NODE_2, s11);
     283 [ #  # ][ #  # ]:          0 :   setS (NODE_1, NODE_2, s21); setS (NODE_2, NODE_1, s21);
     284                 :          0 : }
     285                 :            : 
     286                 :            : /* The function calculates the quasi-static impedance of a coplanar
     287                 :            :    waveguide line and the value of the effective dielectric constant
     288                 :            :    for the given coplanar line and substrate properties. */
     289                 :          0 : void cpwline::analyseQuasiStatic (nr_double_t W, nr_double_t s, nr_double_t h,
     290                 :            :                                   nr_double_t t, nr_double_t er, int backMetal,
     291                 :            :                                   nr_double_t& ZlEff, nr_double_t& ErEff) {
     292                 :            : 
     293                 :            :   // local variables (quasi-static constants)
     294                 :          0 :   nr_double_t k1, k2, k3, q1, q2, q3 = 0, qz;
     295                 :            : 
     296                 :          0 :   ErEff = er;
     297                 :          0 :   ZlEff = 0;
     298                 :            : 
     299                 :            :   // compute the necessary quasi-static approx. (K1, K3, er(0) and Z(0))
     300                 :          0 :   k1 = W / (W + s + s);
     301                 :          0 :   q1 = ellipk (k1) / ellipk (qucs::sqrt (1 - k1 * k1));
     302                 :            : 
     303                 :            :   // backside is metal
     304         [ #  # ]:          0 :   if (backMetal) {
     305                 :          0 :     k3  = qucs::tanh ((M_PI / 4) * (W / h)) / qucs::tanh ((M_PI / 4) * (W + s + s) / h);
     306                 :          0 :     q3 = ellipk (k3) / ellipk (qucs::sqrt (1 - k3 * k3));
     307                 :          0 :     qz  = 1 / (q1 + q3);
     308                 :          0 :     ErEff = 1 + q3 * qz * (er - 1);
     309                 :          0 :     ZlEff = Z0 / 2 * qz;
     310                 :            :   }
     311                 :            :   // backside is air
     312                 :            :   else {
     313                 :          0 :     k2  = qucs::sinh ((M_PI / 4) * (W / h)) / qucs::sinh ((M_PI / 4) * (W + s + s) / h);
     314                 :          0 :     q2 = ellipk (k2) / ellipk (qucs::sqrt (1 - k2 * k2));
     315                 :          0 :     ErEff = 1 + (er - 1) / 2 * q2 / q1;
     316                 :          0 :     ZlEff = Z0 / 4 / q1;
     317                 :            :   }
     318                 :            : 
     319                 :            :   // adds effect of strip thickness
     320         [ #  # ]:          0 :   if (t > 0) {
     321                 :            :     nr_double_t d, se, We, ke, qe;
     322                 :          0 :     d  = (t * 1.25 / M_PI) * (1 + qucs::log (4 * M_PI * W / t));
     323                 :          0 :     se = s - d;
     324                 :          0 :     We = W + d;
     325                 :            : 
     326                 :            :     // modifies k1 accordingly (k1 = ke)
     327                 :          0 :     ke = We / (We + se + se); // ke = k1 + (1 - k1 * k1) * d / 2 / s;
     328                 :          0 :     qe = ellipk (ke) / ellipk (qucs::sqrt (1 - ke * ke));
     329                 :            : 
     330                 :            :     // backside is metal
     331         [ #  # ]:          0 :     if (backMetal) {
     332                 :          0 :       qz  = 1 / (qe + q3);
     333                 :          0 :       ErEff = 1 + q3 * qz * (er - 1);
     334                 :          0 :       ZlEff = Z0 / 2 * qz;
     335                 :            :     }
     336                 :            :     // backside is air
     337                 :            :     else {
     338                 :          0 :       ZlEff = Z0 / 4 / qe;
     339                 :            :     }
     340                 :            : 
     341                 :            :     // modifies ErEff as well
     342                 :          0 :     ErEff = ErEff - (0.7 * (ErEff - 1) * t / s) / (q1 + (0.7 * t / s));
     343                 :            :   }
     344                 :          0 :   ErEff = qucs::sqrt (ErEff);
     345                 :          0 :   ZlEff /= ErEff;
     346                 :          0 : }
     347                 :            : 
     348                 :            : /* This function calculates the frequency dependent value of the
     349                 :            :    effective dielectric constant and the coplanar line impedance for
     350                 :            :    the given frequency. */
     351                 :          0 : void cpwline::analyseDispersion (nr_double_t W, nr_double_t s, nr_double_t h,
     352                 :            :                                  nr_double_t er, nr_double_t ZlEff,
     353                 :            :                                  nr_double_t ErEff, nr_double_t frequency,
     354                 :            :                                  nr_double_t& ZlEffFreq,
     355                 :            :                                  nr_double_t& ErEffFreq) {
     356                 :            :   // local variables
     357                 :            :   nr_double_t fte, G;
     358                 :            : 
     359                 :          0 :   ErEffFreq = ErEff;
     360                 :          0 :   ZlEffFreq = ZlEff * ErEff;
     361                 :            : 
     362                 :            :   // cut-off frequency of the TE0 mode
     363                 :          0 :   fte = (C0 / 4) / (h * qucs::sqrt (er - 1));
     364                 :            : 
     365                 :            :   // dispersion factor G
     366                 :          0 :   nr_double_t p = qucs::log (W / h);
     367                 :          0 :   nr_double_t u = 0.54 - (0.64 - 0.015 * p) * p;
     368                 :          0 :   nr_double_t v = 0.43 - (0.86 - 0.54 * p) * p;
     369                 :          0 :   G = qucs::exp (u * qucs::log (W / s) + v);
     370                 :            : 
     371                 :            :   // add the dispersive effects to er0
     372                 :          0 :   ErEffFreq += (qucs::sqrt (er) - ErEff) / (1 + G * qucs::pow (frequency / fte, -1.8));
     373                 :            : 
     374                 :            :   // computes impedance
     375                 :          0 :   ZlEffFreq /= ErEffFreq;
     376                 :          0 : }
     377                 :            : 
     378                 :          0 : void cpwline::calcNoiseSP (nr_double_t) {
     379                 :            :   // calculate noise using Bosma's theorem
     380         [ #  # ]:          0 :   nr_double_t T = getPropertyDouble ("Temp");
     381         [ #  # ]:          0 :   matrix s = getMatrixS ();
     382         [ #  # ]:          0 :   matrix e = eye (getSize ());
     383 [ #  # ][ #  # ]:          0 :   setMatrixN (kelvin (T) / T0 * (e - s * transpose (conj (s))));
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     384                 :          0 : }
     385                 :            : 
     386                 :          0 : void cpwline::initDC (void) {
     387                 :            :   // a DC short (voltage source V = 0 volts)
     388                 :          0 :   setVoltageSources (1);
     389                 :          0 :   setInternalVoltageSource (1);
     390                 :          0 :   allocMatrixMNA ();
     391                 :          0 :   clearY ();
     392                 :          0 :   voltageSource (VSRC_1, NODE_1, NODE_2);
     393                 :          0 : }
     394                 :            : 
     395                 :          0 : void cpwline::initTR (void) {
     396                 :          0 :   initDC ();
     397                 :          0 : }
     398                 :            : 
     399                 :          0 : void cpwline::initAC (void) {
     400                 :          0 :   setVoltageSources (0);
     401                 :          0 :   allocMatrixMNA ();
     402                 :          0 :   initPropagation ();
     403                 :          0 : }
     404                 :            : 
     405                 :          0 : void cpwline::calcAC (nr_double_t frequency) {
     406                 :            : 
     407                 :          0 :   nr_double_t zl = zl_factor;
     408                 :          0 :   nr_double_t beta = bt_factor;
     409                 :            :   nr_double_t alpha;
     410                 :            : 
     411         [ #  # ]:          0 :   calcAB (frequency, zl, alpha, beta);
     412                 :            : 
     413                 :            :   // calculate and set Y-parameters
     414                 :          0 :   nr_complex_t g = nr_complex_t (alpha, beta);
     415         [ #  # ]:          0 :   nr_complex_t y11 = coth (g * len) / zl;
     416         [ #  # ]:          0 :   nr_complex_t y21 = -cosech (g * len) / zl;
     417                 :            : 
     418 [ #  # ][ #  # ]:          0 :   setY (NODE_1, NODE_1, y11); setY (NODE_2, NODE_2, y11);
     419 [ #  # ][ #  # ]:          0 :   setY (NODE_1, NODE_2, y21); setY (NODE_2, NODE_1, y21);
     420                 :          0 : }
     421                 :            : 
     422                 :          0 : void cpwline::calcNoiseAC (nr_double_t) {
     423                 :            :   // calculate noise using Bosma's theorem
     424                 :          0 :   nr_double_t T = getPropertyDouble ("Temp");
     425 [ #  # ][ #  # ]:          0 :   setMatrixN (4 * kelvin (T) / T0 * real (getMatrixY ()));
         [ #  # ][ #  # ]
                 [ #  # ]
     426                 :          0 : }
     427                 :            : 
     428                 :            : // properties
     429                 :            : PROP_REQ [] = {
     430                 :            :   { "W", PROP_REAL, { 1e-3, PROP_NO_STR }, PROP_POS_RANGE },
     431                 :            :   { "S", PROP_REAL, { 1e-3, PROP_NO_STR }, PROP_POS_RANGE },
     432                 :            :   { "L", PROP_REAL, { 10e-3, PROP_NO_STR }, PROP_POS_RANGE },
     433                 :            :   { "Subst", PROP_STR, { PROP_NO_VAL, "Subst1" }, PROP_NO_RANGE },
     434                 :            :   PROP_NO_PROP };
     435                 :            : PROP_OPT [] = {
     436                 :            :   { "Temp", PROP_REAL, { 26.85, PROP_NO_STR }, PROP_MIN_VAL (K) },
     437                 :            :   { "Backside", PROP_STR, { PROP_NO_VAL, "Metal" },
     438                 :            :     PROP_RNG_STR2 ("Metal", "Air") },
     439                 :            :   { "Approx", PROP_STR, { PROP_NO_VAL, "no" }, PROP_RNG_YESNO },
     440                 :            :   PROP_NO_PROP };
     441                 :            : struct define_t cpwline::cirdef =
     442                 :            :   { "CLIN", 2, PROP_COMPONENT, PROP_NO_SUBSTRATE, PROP_LINEAR, PROP_DEF };

Generated by: LCOV version 1.11