Qucs-core
0.0.19
|
00001 /* 00002 * mscoupled.cpp - parallel coupled microstrip lines class implementation 00003 * 00004 * Copyright (C) 2004, 2005, 2006, 2008 Stefan Jahn <stefan@lkcc.org> 00005 * 00006 * This is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2, or (at your option) 00009 * any later version. 00010 * 00011 * This software is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this package; see the file COPYING. If not, write to 00018 * the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, 00019 * Boston, MA 02110-1301, USA. 00020 * 00021 * $Id$ 00022 * 00023 */ 00024 00025 #if HAVE_CONFIG_H 00026 # include <config.h> 00027 #endif 00028 00029 #include "component.h" 00030 #include "substrate.h" 00031 #include "msline.h" 00032 #include "mscoupled.h" 00033 00034 using namespace qucs; 00035 00036 mscoupled::mscoupled () : circuit (4) { 00037 type = CIR_MSCOUPLED; 00038 } 00039 00040 void mscoupled::calcPropagation (nr_double_t frequency) { 00041 00042 // fetch line properties 00043 nr_double_t W = getPropertyDouble ("W"); 00044 nr_double_t s = getPropertyDouble ("S"); 00045 const char * SModel = getPropertyString ("Model"); 00046 const char * DModel = getPropertyString ("DispModel"); 00047 00048 // fetch substrate properties 00049 substrate * subst = getSubstrate (); 00050 nr_double_t er = subst->getPropertyDouble ("er"); 00051 nr_double_t h = subst->getPropertyDouble ("h"); 00052 nr_double_t t = subst->getPropertyDouble ("t"); 00053 nr_double_t tand = subst->getPropertyDouble ("tand"); 00054 nr_double_t rho = subst->getPropertyDouble ("rho"); 00055 nr_double_t D = subst->getPropertyDouble ("D"); 00056 00057 // quasi-static analysis 00058 nr_double_t Zle, ErEffe, Zlo, ErEffo; 00059 analysQuasiStatic (W, h, s, t, er, SModel, Zle, Zlo, ErEffe, ErEffo); 00060 00061 // analyse dispersion of Zl and Er 00062 nr_double_t ZleFreq, ErEffeFreq, ZloFreq, ErEffoFreq; 00063 analyseDispersion (W, h, s, er, Zle, Zlo, ErEffe, ErEffo, frequency, DModel, 00064 ZleFreq, ZloFreq, ErEffeFreq, ErEffoFreq); 00065 00066 // analyse losses of line 00067 nr_double_t ace, aco, ade, ado; 00068 msline::analyseLoss (W, t, er, rho, D, tand, Zle, Zlo, ErEffe, 00069 frequency, "Hammerstad", ace, ade); 00070 msline::analyseLoss (W, t, er, rho, D, tand, Zlo, Zle, ErEffo, 00071 frequency, "Hammerstad", aco, ado); 00072 00073 // compute propagation constants for even and odd mode 00074 nr_double_t k0 = 2 * pi * frequency / C0; 00075 ae = ace + ade; 00076 ao = aco + ado; 00077 be = qucs::sqrt (ErEffeFreq) * k0; 00078 bo = qucs::sqrt (ErEffoFreq) * k0; 00079 ze = ZleFreq; 00080 zo = ZloFreq; 00081 ee = ErEffeFreq; 00082 eo = ErEffoFreq; 00083 } 00084 00085 void mscoupled::saveCharacteristics (nr_double_t) { 00086 setCharacteristic ("ZlEven", ze); 00087 setCharacteristic ("ErEven", ee); 00088 setCharacteristic ("ZlOdd", zo); 00089 setCharacteristic ("ErOdd", eo); 00090 } 00091 00092 void mscoupled::calcSP (nr_double_t frequency) { 00093 // fetch line properties 00094 nr_double_t l = getPropertyDouble ("L"); 00095 00096 // compute propagation constants for even and odd mode 00097 calcPropagation (frequency); 00098 nr_complex_t ge = nr_complex_t (ae, be); 00099 nr_complex_t go = nr_complex_t (ao, bo); 00100 00101 // compute abbreviations 00102 nr_complex_t Ee, Eo, De, Do, Xe, Xo, Ye, Yo; 00103 Ee = (sqr (ze) + sqr (z0)) * qucs::sinh (ge * l); 00104 Eo = (sqr (zo) + sqr (z0)) * qucs::sinh (go * l); 00105 De = 2 * ze * z0 * cosh (ge * l) + Ee; 00106 Do = 2 * zo * z0 * cosh (go * l) + Eo; 00107 Xe = (sqr (ze) - sqr (z0)) * qucs::sinh (ge * l) / 2.0 / De; 00108 Xo = (sqr (zo) - sqr (z0)) * qucs::sinh (go * l) / 2.0 / Do; 00109 Ye = ze * z0 / De; 00110 Yo = zo * z0 / Do; 00111 00112 // reflexion coefficients 00113 setS (NODE_1, NODE_1, Xe + Xo); setS (NODE_2, NODE_2, Xe + Xo); 00114 setS (NODE_3, NODE_3, Xe + Xo); setS (NODE_4, NODE_4, Xe + Xo); 00115 // through paths 00116 setS (NODE_1, NODE_2, Ye + Yo); setS (NODE_2, NODE_1, Ye + Yo); 00117 setS (NODE_3, NODE_4, Ye + Yo); setS (NODE_4, NODE_3, Ye + Yo); 00118 // coupled paths 00119 setS (NODE_1, NODE_4, Xe - Xo); setS (NODE_4, NODE_1, Xe - Xo); 00120 setS (NODE_2, NODE_3, Xe - Xo); setS (NODE_3, NODE_2, Xe - Xo); 00121 // isolated paths 00122 setS (NODE_1, NODE_3, Ye - Yo); setS (NODE_3, NODE_1, Ye - Yo); 00123 setS (NODE_2, NODE_4, Ye - Yo); setS (NODE_4, NODE_2, Ye - Yo); 00124 } 00125 00126 void mscoupled::calcNoiseSP (nr_double_t) { 00127 // calculate noise using Bosma's theorem 00128 nr_double_t T = getPropertyDouble ("Temp"); 00129 matrix s = getMatrixS (); 00130 matrix e = eye (getSize ()); 00131 setMatrixN (celsius2kelvin (T) / T0 * (e - s * transpose (conj (s)))); 00132 } 00133 00134 /* The function calculates the quasi-static dielectric constants and 00135 characteristic impedances for the even and odd mode based upon the 00136 given line and substrate properties for parallel coupled microstrip 00137 lines. */ 00138 void mscoupled::analysQuasiStatic (nr_double_t W, nr_double_t h, nr_double_t s, 00139 nr_double_t t, nr_double_t er, 00140 const char * const SModel, nr_double_t& Zle, 00141 nr_double_t& Zlo, nr_double_t& ErEffe, 00142 nr_double_t& ErEffo) { 00143 // initialize default return values 00144 ErEffe = ErEffo = er; 00145 Zlo = 42.2; Zle = 55.7; 00146 00147 // normalized width and gap 00148 nr_double_t u = W / h; 00149 nr_double_t g = s / h; 00150 00151 // HAMMERSTAD and JENSEN 00152 if (!strcmp (SModel, "Hammerstad")) { 00153 nr_double_t Zl1, Fe, Fo, a, b, fo, Mu, Alpha, Beta, ErEff; 00154 nr_double_t Pe, Po, r, fo1, q, p, n, Psi, Phi, m, Theta; 00155 00156 // modifying equations for even mode 00157 m = 0.2175 + qucs::pow (4.113 + qucs::pow (20.36 / g, 6.), -0.251) + 00158 qucs::log (qucs::pow (g, 10.) / (1 + qucs::pow (g / 13.8, 10.))) / 323; 00159 Alpha = 0.5 * qucs::exp (-g); 00160 Psi = 1 + g / 1.45 + qucs::pow (g, 2.09) / 3.95; 00161 Phi = 0.8645 * qucs::pow (u, 0.172); 00162 Pe = Phi / (Psi * (Alpha * qucs::pow (u, m) + (1 - Alpha) * qucs::pow (u, -m))); 00163 // TODO: is this ... Psi * (Alpha ... or ... Psi / (Alpha ... ? 00164 00165 // modifying equations for odd mode 00166 n = (1 / 17.7 + qucs::exp (-6.424 - 0.76 * qucs::log (g) - qucs::pow (g / 0.23, 5.))) * 00167 qucs::log ((10 + 68.3 * sqr (g)) / (1 + 32.5 * qucs::pow (g, 3.093))); 00168 Beta = 0.2306 + qucs::log (qucs::pow (g, 10.) / (1 + qucs::pow (g / 3.73, 10.))) / 301.8 + 00169 qucs::log (1 + 0.646 * qucs::pow (g, 1.175)) / 5.3; 00170 Theta = 1.729 + 1.175 * qucs::log (1 + 0.627 / (g + 0.327 * qucs::pow (g, 2.17))); 00171 Po = Pe - Theta / Psi * qucs::exp (Beta * qucs::pow (u, -n) * qucs::log (u)); 00172 00173 // further modifying equations 00174 r = 1 + 0.15 * (1 - qucs::exp (1 - sqr (er - 1) / 8.2) / (1 + qucs::pow (g, -6.))); 00175 fo1 = 1 - qucs::exp (-0.179 * qucs::pow (g, 0.15) - 00176 0.328 * qucs::pow (g, r) / qucs::log (euler + qucs::pow (g / 7, 2.8))); 00177 q = qucs::exp (-1.366 - g); 00178 p = qucs::exp (-0.745 * qucs::pow (g, 0.295)) / qucs::cosh (qucs::pow (g, 0.68)); 00179 fo = fo1 * qucs::exp (p * qucs::log (u) + q * qucs::sin (pi * qucs::log10 (u))); 00180 00181 Mu = g * qucs::exp (-g) + u * (20 + sqr (g)) / (10 + sqr (g)); 00182 msline::Hammerstad_ab (Mu, er, a, b); 00183 Fe = qucs::pow (1 + 10 / Mu, -a * b); 00184 msline::Hammerstad_ab (u, er, a, b); 00185 Fo = fo * qucs::pow (1 + 10 / u, -a * b); 00186 00187 // finally compute effective dielectric constants and impedances 00188 ErEffe = (er + 1) / 2 + (er - 1) / 2 * Fe; 00189 ErEffo = (er + 1) / 2 + (er - 1) / 2 * Fo; 00190 00191 msline::Hammerstad_er (u, er, a, b, ErEff); // single microstrip 00192 00193 // first variant 00194 Zl1 = Z0 / (u + 1.98 * qucs::pow (u, 0.172)); 00195 Zl1 /= qucs::sqrt (ErEff); 00196 00197 // second variant 00198 msline::Hammerstad_zl (u, Zl1); 00199 Zl1 /= qucs::sqrt (ErEff); 00200 00201 Zle = Zl1 / (1 - Zl1 * Pe / Z0); 00202 Zlo = Zl1 / (1 - Zl1 * Po / Z0); 00203 } 00204 // KIRSCHNING and JANSEN 00205 else if (!strcmp (SModel, "Kirschning")) { 00206 nr_double_t a, b, ae, be, ao, bo, v, co, d, ErEff, Zl1; 00207 nr_double_t q1, q2, q3, q4, q5, q6, q7, q8, q9, q10; 00208 00209 // consider effect of finite strip thickness (JANSEN only) 00210 nr_double_t ue = u; 00211 nr_double_t uo = u; 00212 if (t != 0 && s > 10 * (2 * t)) { 00213 nr_double_t dW = 0; 00214 // SCHNEIDER, referred by JANSEN 00215 if (u >= one_over_pi / 2 && one_over_pi / 2 > 2 * t / h) 00216 dW = t * (1 + qucs::log (2 * h / t)) / pi; 00217 else if (W > 2 * t) 00218 dW = t * (1 + qucs::log (4 * pi * W / t)) / pi; 00219 // JANSEN 00220 nr_double_t dt = 2 * t * h / s / er; 00221 nr_double_t We = W + dW * (1 - 0.5 * qucs::exp (-0.69 * dW / dt)); 00222 nr_double_t Wo = We + dt; 00223 ue = We / h; 00224 uo = Wo / h; 00225 } 00226 00227 // even relative dielectric constant 00228 v = ue * (20 + sqr (g)) / (10 + sqr (g)) + g * qucs::exp (-g); 00229 msline::Hammerstad_ab (v, er, ae, be); 00230 msline::Hammerstad_er (v, er, ae, be, ErEffe); 00231 00232 // odd relative dielectric constant 00233 msline::Hammerstad_ab (uo, er, a, b); 00234 msline::Hammerstad_er (uo, er, a, b, ErEff); 00235 d = 0.593 + 0.694 * qucs::exp (-0.562 * uo); 00236 bo = 0.747 * er / (0.15 + er); 00237 co = bo - (bo - 0.207) * qucs::exp (-0.414 * uo); 00238 ao = 0.7287 * (ErEff - (er + 1) / 2) * (1 - qucs::exp (-0.179 * uo)); 00239 ErEffo = ((er + 1) / 2 + ao - ErEff) * qucs::exp (-co * qucs::pow (g, d)) + ErEff; 00240 00241 // characteristic impedance of single line 00242 msline::Hammerstad_zl (u, Zl1); 00243 Zl1 /= qucs::sqrt (ErEff); 00244 00245 // even characteristic impedance 00246 q1 = 0.8695 * qucs::pow (ue, 0.194); 00247 q2 = 1 + 0.7519 * g + 0.189 * qucs::pow (g, 2.31); 00248 q3 = 0.1975 + qucs::pow (16.6 + qucs::pow (8.4 / g, 6.), -0.387) + 00249 qucs::log (qucs::pow (g, 10.) / (1 + qucs::pow (g / 3.4, 10.))) / 241; 00250 q4 = q1 / q2 * 2 / 00251 (qucs::exp (-g) * qucs::pow (ue, q3) + (2 - qucs::exp (-g)) * qucs::pow (ue, -q3)); 00252 Zle = qucs::sqrt (ErEff / ErEffe) * Zl1 / (1 - Zl1 * qucs::sqrt (ErEff) * q4 / Z0); 00253 00254 // odd characteristic impedance 00255 q5 = 1.794 + 1.14 * qucs::log (1 + 0.638 / (g + 0.517 * qucs::pow (g, 2.43))); 00256 q6 = 0.2305 + qucs::log (qucs::pow (g, 10.) / (1 + qucs::pow (g / 5.8, 10.))) / 281.3 + 00257 qucs::log (1 + 0.598 * qucs::pow (g, 1.154)) / 5.1; 00258 q7 = (10 + 190 * sqr (g)) / (1 + 82.3 * cubic (g)); 00259 q8 = qucs::exp (-6.5 - 0.95 * qucs::log (g) - qucs::pow (g / 0.15, 5.)); 00260 q9 = qucs::log (q7) * (q8 + 1 / 16.5); 00261 q10 = (q2 * q4 - q5 * qucs::exp (qucs::log (uo) * q6 * qucs::pow (uo, -q9))) / q2; 00262 Zlo = qucs::sqrt (ErEff / ErEffo) * Zl1 / (1 - Zl1 * qucs::sqrt (ErEff) * q10 / Z0); 00263 } 00264 } 00265 00266 /* The function computes the dispersion effects on the dielectric 00267 constants and characteristic impedances for the even and odd mode 00268 of parallel coupled microstrip lines. */ 00269 void mscoupled::analyseDispersion (nr_double_t W, nr_double_t h, nr_double_t s, 00270 nr_double_t er, nr_double_t Zle, 00271 nr_double_t Zlo, nr_double_t ErEffe, 00272 nr_double_t ErEffo, nr_double_t frequency, 00273 const char * const DModel, nr_double_t& ZleFreq, 00274 nr_double_t& ZloFreq, 00275 nr_double_t& ErEffeFreq, 00276 nr_double_t& ErEffoFreq) { 00277 00278 // initialize default return values 00279 ZleFreq = Zle; 00280 ErEffeFreq = ErEffe; 00281 ZloFreq = Zlo; 00282 ErEffoFreq = ErEffo; 00283 00284 // normalized width and gap 00285 nr_double_t u = W / h; 00286 nr_double_t g = s / h; 00287 00288 // GETSINGER 00289 if (!strcmp (DModel, "Getsinger")) { 00290 // even mode dispersion 00291 msline::Getsinger_disp (h, er, ErEffe, Zle / 2, 00292 frequency, ErEffeFreq, ZleFreq); 00293 ZleFreq *= 2; 00294 // odd mode dispersion 00295 msline::Getsinger_disp (h, er, ErEffo, Zlo * 2, 00296 frequency, ErEffoFreq, ZloFreq); 00297 ZloFreq /= 2; 00298 } 00299 // KIRSCHNING and JANSEN 00300 else if (!strcmp (DModel, "Kirschning")) { 00301 nr_double_t p1, p2, p3, p4, p5, p6, p7, Fe; 00302 nr_double_t fn = frequency * h * 1e-6; 00303 00304 // even relative dielectric constant dispersion 00305 p1 = 0.27488 * (0.6315 + 0.525 / qucs::pow (1 + 0.0157 * fn, 20.)) * u - 00306 0.065683 * qucs::exp (-8.7513 * u); 00307 p2 = 0.33622 * (1 - qucs::exp (-0.03442 * er)); 00308 p3 = 0.0363 * qucs::exp (-4.6 * u) * (1 - qucs::exp (- qucs::pow (fn / 38.7, 4.97))); 00309 p4 = 1 + 2.751 * (1 - qucs::exp (- qucs::pow (er / 15.916, 8.))); 00310 p5 = 0.334 * qucs::exp (-3.3 * cubic (er / 15)) + 0.746; 00311 p6 = p5 * qucs::exp (- qucs::pow (fn / 18, 0.368)); 00312 p7 = 1 + 4.069 * p6 * qucs::pow (g, 0.479) * 00313 qucs::exp (-1.347 * qucs::pow (g, 0.595) - 0.17 * qucs::pow (g, 2.5)); 00314 Fe = p1 * p2 * qucs::pow ((p3 * p4 + 0.1844 * p7) * fn, 1.5763); 00315 ErEffeFreq = er - (er - ErEffe) / (1 + Fe); 00316 00317 // odd relative dielectric constant dispersion 00318 nr_double_t p8, p9, p10, p11, p12, p13, p14, p15, Fo; 00319 p8 = 0.7168 * (1 + 1.076 / (1 + 0.0576 * (er - 1))); 00320 p9 = p8 - 0.7913 * (1 - qucs::exp (- qucs::pow (fn / 20, 1.424))) * 00321 qucs::atan (2.481 * qucs::pow (er / 8, 0.946)); 00322 p10 = 0.242 * qucs::pow (er - 1, 0.55); 00323 p11 = 0.6366 * (qucs::exp (-0.3401 * fn) - 1) * 00324 qucs::atan (1.263 * qucs::pow (u / 3, 1.629)); 00325 p12 = p9 + (1 - p9) / (1 + 1.183 * qucs::pow (u, 1.376)); 00326 p13 = 1.695 * p10 / (0.414 + 1.605 * p10); 00327 p14 = 0.8928 + 0.1072 * (1 - qucs::exp (-0.42 * qucs::pow (fn / 20, 3.215))); 00328 p15 = fabs (1 - 0.8928 * (1 + p11) * 00329 qucs::exp (-p13 * qucs::pow (g, 1.092)) * p12 / p14); 00330 Fo = p1 * p2 * qucs::pow ((p3 * p4 + 0.1844) * fn * p15, 1.5763); 00331 ErEffoFreq = er - (er - ErEffo) / (1 + Fo); 00332 00333 // dispersion of even characteristic impedance 00334 nr_double_t t, q11, q12, q13, q14, q15, q16, q17, q18, q19, q20, q21; 00335 q11 = 0.893 * (1 - 0.3 / (1 + 0.7 * (er - 1))); 00336 t = qucs::pow (fn / 20, 4.91); 00337 q12 = 2.121 * t / (1 + q11 * t) * qucs::exp (-2.87 * g) * qucs::pow (g, 0.902); 00338 q13 = 1 + 0.038 * qucs::pow (er / 8, 5.1); 00339 t = quadr (er / 15); 00340 q14 = 1 + 1.203 * t / (1 + t); 00341 q15 = 1.887 * qucs::exp (-1.5 * qucs::pow (g, 0.84)) * qucs::pow (g, q14) / 00342 (1 + 0.41 * qucs::pow (fn / 15, 3.) * 00343 qucs::pow (u, 2 / q13) / (0.125 + qucs::pow (u, 1.626 / q13))); 00344 q16 = q15 * (1 + 9 / (1 + 0.403 * sqr (er - 1))); 00345 q17 = 0.394 * (1 - qucs::exp (-1.47 * qucs::pow (u / 7, 0.672))) * 00346 (1 - qucs::exp (-4.25 * qucs::pow (fn / 20, 1.87))); 00347 q18 = 0.61 * (1 - qucs::exp (-2.31 * qucs::pow (u / 8, 1.593))) / 00348 (1 + 6.544 * qucs::pow (g, 4.17)); 00349 q19 = 0.21 * quadr (g) / (1 + 0.18 * qucs::pow (g, 4.9)) / (1 + 0.1 * sqr (u)) / 00350 (1 + qucs::pow (fn / 24, 3.)); 00351 q20 = q19 * (0.09 + 1 / (1 + 0.1 * qucs::pow (er - 1, 2.7))); 00352 t = qucs::pow (u, 2.5); 00353 q21 = fabs (1 - 42.54 * qucs::pow (g, 0.133) * qucs::exp (-0.812 * g) * t / 00354 (1 + 0.033 * t)); 00355 00356 nr_double_t re, qe, pe, de, Ce, q0, ZlFreq, ErEffFreq; 00357 msline::Kirschning_er (u, fn, er, ErEffe, ErEffFreq); 00358 msline::Kirschning_zl (u, fn, er, ErEffe, ErEffFreq, Zle, q0, ZlFreq); 00359 re = qucs::pow (fn / 28.843, 12.); 00360 qe = 0.016 + qucs::pow (0.0514 * er * q21, 4.524); 00361 pe = 4.766 * qucs::exp (-3.228 * qucs::pow (u, 0.641)); 00362 t = qucs::pow (er - 1, 6.); 00363 de = 5.086 * qe * re / (0.3838 + 0.386 * qe) * 00364 qucs::exp (-22.2 * qucs::pow (u, 1.92)) / (1 + 1.2992 * re) * t / (1 + 10 * t); 00365 Ce = 1 + 1.275 * (1 - qucs::exp (-0.004625 * pe * qucs::pow (er, 1.674) * 00366 qucs::pow (fn / 18.365, 2.745))) - q12 + q16 - q17 + q18 + q20; 00367 ZleFreq = Zle * qucs::pow ((0.9408 * qucs::pow (ErEffFreq, Ce) - 0.9603) / 00368 ((0.9408 - de) * qucs::pow (ErEffe, Ce) - 0.9603), q0); 00369 00370 // dispersion of odd characteristic impedance 00371 nr_double_t q22, q23, q24, q25, q26, q27, q28, q29; 00372 msline::Kirschning_er (u, fn, er, ErEffo, ErEffFreq); 00373 msline::Kirschning_zl (u, fn, er, ErEffo, ErEffFreq, Zlo, q0, ZlFreq); 00374 q29 = 15.16 / (1 + 0.196 * sqr (er - 1)); 00375 t = sqr (er - 1); 00376 q25 = 0.3 * sqr (fn) / (10 + sqr (fn)) * (1 + 2.333 * t / (5 + t)); 00377 t = qucs::pow ((er - 1) / 13, 12.); 00378 q26 = 30 - 22.2 * t / (1 + 3 * t) - q29; 00379 t = qucs::pow (er - 1, 1.5); 00380 q27 = 0.4 * qucs::pow (g, 0.84) * (1 + 2.5 * t / (5 + t)); 00381 t = qucs::pow (er - 1, 3.); 00382 q28 = 0.149 * t / (94.5 + 0.038 * t); 00383 q22 = 0.925 * qucs::pow (fn / q26, 1.536) / (1 + 0.3 * qucs::pow (fn / 30, 1.536)); 00384 q23 = 1 + 0.005 * fn * q27 / (1 + 0.812 * qucs::pow (fn / 15, 1.9)) / 00385 (1 + 0.025 * sqr (u)); 00386 t = qucs::pow (u, 0.894); 00387 q24 = 2.506 * q28 * t / (3.575 + t) * 00388 qucs::pow ((1 + 1.3 * u) * fn / 99.25, 4.29); 00389 ZloFreq = ZlFreq + (Zlo * qucs::pow (ErEffoFreq / ErEffo, q22) - ZlFreq * q23) / 00390 (1 + q24 + qucs::pow (0.46 * g, 2.2) * q25); 00391 00392 } 00393 } 00394 00395 void mscoupled::initDC (void) { 00396 nr_double_t l = getPropertyDouble ("L"); 00397 nr_double_t W = getPropertyDouble ("W"); 00398 substrate * subst = getSubstrate (); 00399 nr_double_t t = subst->getPropertyDouble ("t"); 00400 nr_double_t rho = subst->getPropertyDouble ("rho"); 00401 00402 if (t != 0.0 && rho != 0.0) { 00403 // tiny resistances 00404 nr_double_t g = t * W / rho / l; 00405 setVoltageSources (0); 00406 allocMatrixMNA (); 00407 setY (NODE_1, NODE_1, +g); setY (NODE_2, NODE_2, +g); 00408 setY (NODE_1, NODE_2, -g); setY (NODE_2, NODE_1, -g); 00409 setY (NODE_3, NODE_3, +g); setY (NODE_4, NODE_4, +g); 00410 setY (NODE_3, NODE_4, -g); setY (NODE_4, NODE_3, -g); 00411 } 00412 else { 00413 // DC shorts (voltage sources V = 0 volts) 00414 setVoltageSources (2); 00415 setInternalVoltageSource (1); 00416 allocMatrixMNA (); 00417 clearY (); 00418 voltageSource (VSRC_1, NODE_1, NODE_2); 00419 voltageSource (VSRC_2, NODE_3, NODE_4); 00420 setD (VSRC_1, VSRC_2, 0.0); setD (VSRC_2, VSRC_1, 0.0); 00421 } 00422 } 00423 00424 void mscoupled::initAC (void) { 00425 setVoltageSources (0); 00426 allocMatrixMNA (); 00427 } 00428 00429 void mscoupled::calcAC (nr_double_t frequency) { 00430 // fetch line properties 00431 nr_double_t l = getPropertyDouble ("L"); 00432 00433 // compute propagation constants for even and odd mode 00434 calcPropagation (frequency); 00435 nr_complex_t ge = nr_complex_t (ae, be); 00436 nr_complex_t go = nr_complex_t (ao, bo); 00437 00438 // compute abbreviations 00439 nr_complex_t De, Do, y1, y2, y3, y4; 00440 De = 0.5 / (ze * qucs::sinh (ge * l)); 00441 Do = 0.5 / (zo * qucs::sinh (go * l)); 00442 y2 = -De - Do; 00443 y3 = -De + Do; 00444 De *= cosh (ge * l); 00445 Do *= cosh (go * l); 00446 y1 = De + Do; 00447 y4 = De - Do; 00448 00449 // store Y-parameters 00450 setY (NODE_1, NODE_1, y1); setY (NODE_2, NODE_2, y1); 00451 setY (NODE_3, NODE_3, y1); setY (NODE_4, NODE_4, y1); 00452 setY (NODE_1, NODE_2, y2); setY (NODE_2, NODE_1, y2); 00453 setY (NODE_3, NODE_4, y2); setY (NODE_4, NODE_3, y2); 00454 setY (NODE_1, NODE_3, y3); setY (NODE_2, NODE_4, y3); 00455 setY (NODE_3, NODE_1, y3); setY (NODE_4, NODE_2, y3); 00456 setY (NODE_1, NODE_4, y4); setY (NODE_2, NODE_3, y4); 00457 setY (NODE_3, NODE_2, y4); setY (NODE_4, NODE_1, y4); 00458 } 00459 00460 void mscoupled::calcNoiseAC (nr_double_t) { 00461 // calculate noise using Bosma's theorem 00462 nr_double_t T = getPropertyDouble ("Temp"); 00463 setMatrixN (4 * celsius2kelvin (T) / T0 * real (getMatrixY ())); 00464 } 00465 00466 // properties 00467 PROP_REQ [] = { 00468 { "W", PROP_REAL, { 1e-3, PROP_NO_STR }, PROP_POS_RANGE }, 00469 { "L", PROP_REAL, { 10e-3, PROP_NO_STR }, PROP_POS_RANGE }, 00470 { "S", PROP_REAL, { 1e-3, PROP_NO_STR }, PROP_POS_RANGE }, 00471 { "Subst", PROP_STR, { PROP_NO_VAL, "Subst1" }, PROP_NO_RANGE }, 00472 { "Model", PROP_STR, { PROP_NO_VAL, "Kirschning" }, 00473 PROP_RNG_STR2 ("Kirschning", "Hammerstad") }, 00474 { "DispModel", PROP_STR, { PROP_NO_VAL, "Kirschning" }, 00475 PROP_RNG_STR2 ("Kirschning", "Getsinger") }, 00476 PROP_NO_PROP }; 00477 PROP_OPT [] = { 00478 { "Temp", PROP_REAL, { 26.85, PROP_NO_STR }, PROP_MIN_VAL (K) }, 00479 PROP_NO_PROP }; 00480 struct define_t mscoupled::cirdef = 00481 { "MCOUPLED", 4, PROP_COMPONENT, PROP_NO_SUBSTRATE, PROP_LINEAR, PROP_DEF };