Qucs-core  0.0.18
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
mslange.cpp
Go to the documentation of this file.
1 /*
2  * mslange.cpp - parallel coupled microstrip lines class implementation
3  *
4  * Copyright (C) 2004, 2005, 2006, 2008 Stefan Jahn <stefan@lkcc.org>
5  *
6  * This is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2, or (at your option)
9  * any later version.
10  *
11  * This software is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this package; see the file COPYING. If not, write to
18  * the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  *
21  * $Id: mslange.cpp,v 1.25 2008/10/07 20:15:33 ela Exp $
22  *
23  */
24 
25 #if HAVE_CONFIG_H
26 # include <config.h>
27 #endif
28 
29 #include "component.h"
30 #include "substrate.h"
31 #include "msline.h"
32 #include "mslange.h"
33 
34 using namespace qucs;
35 
36 mslange::mslange () : circuit (4) {
37  type = CIR_MSLANGE;
38 }
39 
40 void mslange::calcPropagation (nr_double_t frequency) {
41 
42  // fetch line properties
43  nr_double_t W = getPropertyDouble ("W");
44  nr_double_t s = getPropertyDouble ("S");
45  char * SModel = getPropertyString ("Model");
46  char * DModel = getPropertyString ("DispModel");
47 
48  // fetch substrate properties
50  nr_double_t er = subst->getPropertyDouble ("er");
51  nr_double_t h = subst->getPropertyDouble ("h");
52  nr_double_t t = subst->getPropertyDouble ("t");
53  nr_double_t tand = subst->getPropertyDouble ("tand");
54  nr_double_t rho = subst->getPropertyDouble ("rho");
55  nr_double_t D = subst->getPropertyDouble ("D");
56 
57  // quasi-static analysis
58  nr_double_t Zle, ErEffe, Zlo, ErEffo;
59  analysQuasiStatic (W, h, s, t, er, SModel, Zle, Zlo, ErEffe, ErEffo);
60 
61  // analyse dispersion of Zl and Er
62  nr_double_t ZleFreq, ErEffeFreq, ZloFreq, ErEffoFreq;
63  analyseDispersion (W, h, s, er, Zle, Zlo, ErEffe, ErEffo, frequency, DModel,
64  ZleFreq, ZloFreq, ErEffeFreq, ErEffoFreq);
65 
66  // analyse losses of line
67  nr_double_t ace, aco, ade, ado;
68  msline::analyseLoss (W, t, er, rho, D, tand, Zle, Zlo, ErEffe,
69  frequency, "Hammerstad", ace, ade);
70  msline::analyseLoss (W, t, er, rho, D, tand, Zlo, Zle, ErEffo,
71  frequency, "Hammerstad", aco, ado);
72 
73  // compute propagation constants for even and odd mode
74  nr_double_t k0 = 2 * M_PI * frequency / C0;
75  ae = ace + ade;
76  ao = aco + ado;
77  be = qucs::sqrt (ErEffeFreq) * k0;
78  bo = qucs::sqrt (ErEffoFreq) * k0;
79  ze = ZleFreq;
80  zo = ZloFreq;
81  ee = ErEffeFreq;
82  eo = ErEffoFreq;
83 }
84 
85 void mslange::saveCharacteristics (nr_double_t) {
86  setCharacteristic ("ZlEven", ze);
87  setCharacteristic ("ErEven", ee);
88  setCharacteristic ("ZlOdd", zo);
89  setCharacteristic ("ErOdd", eo);
90 }
91 
92 void mslange::calcSP (nr_double_t frequency) {
93  // fetch line properties
94  nr_double_t l = getPropertyDouble ("L");
95 
96  // compute propagation constants for even and odd mode
97  calcPropagation (frequency);
100 
101  // compute abbreviations
102  nr_complex_t Ee, Eo, De, Do, Xe, Xo, Ye, Yo;
103  Ee = (sqr (ze) + sqr (z0)) * qucs::sinh (ge * l);
104  Eo = (sqr (zo) + sqr (z0)) * qucs::sinh (go * l);
105  De = 2 * ze * z0 * cosh (ge * l) + Ee;
106  Do = 2 * zo * z0 * cosh (go * l) + Eo;
107  Xe = (sqr (ze) - sqr (z0)) * qucs::sinh (ge * l) / 2.0 / De;
108  Xo = (sqr (zo) - sqr (z0)) * qucs::sinh (go * l) / 2.0 / Do;
109  Ye = ze * z0 / De;
110  Yo = zo * z0 / Do;
111 
112  // reflexion coefficients
113  setS (NODE_1, NODE_1, Xe + Xo); setS (NODE_2, NODE_2, Xe + Xo);
114  setS (NODE_3, NODE_3, Xe + Xo); setS (NODE_4, NODE_4, Xe + Xo);
115  // through paths
116  setS (NODE_1, NODE_2, Ye + Yo); setS (NODE_2, NODE_1, Ye + Yo);
117  setS (NODE_3, NODE_4, Ye + Yo); setS (NODE_4, NODE_3, Ye + Yo);
118  // coupled paths
119  setS (NODE_1, NODE_4, Xe - Xo); setS (NODE_4, NODE_1, Xe - Xo);
120  setS (NODE_2, NODE_3, Xe - Xo); setS (NODE_3, NODE_2, Xe - Xo);
121  // isolated paths
122  setS (NODE_1, NODE_3, Ye - Yo); setS (NODE_3, NODE_1, Ye - Yo);
123  setS (NODE_2, NODE_4, Ye - Yo); setS (NODE_4, NODE_2, Ye - Yo);
124 }
125 
126 void mslange::calcNoiseSP (nr_double_t) {
127  // calculate noise using Bosma's theorem
128  nr_double_t T = getPropertyDouble ("Temp");
129  matrix s = getMatrixS ();
130  matrix e = eye (getSize ());
131  setMatrixN (kelvin (T) / T0 * (e - s * transpose (conj (s))));
132 }
133 
134 /* The function calculates the quasi-static dielectric constants and
135  characteristic impedances for the even and odd mode based upon the
136  given line and substrate properties for parallel coupled microstrip
137  lines. */
138 void mslange::analysQuasiStatic (nr_double_t W, nr_double_t h, nr_double_t s,
139  nr_double_t t, nr_double_t er,
140  char * SModel, nr_double_t& Zle,
141  nr_double_t& Zlo, nr_double_t& ErEffe,
142  nr_double_t& ErEffo) {
143  // initialize default return values
144  ErEffe = ErEffo = er;
145  Zlo = 42.2; Zle = 55.7;
146 
147  // normalized width and gap
148  nr_double_t u = W / h;
149  nr_double_t g = s / h;
150 
151  // HAMMERSTAD and JENSEN
152  if (!strcmp (SModel, "Hammerstad")) {
153  nr_double_t Zl1, Fe, Fo, a, b, fo, Mu, Alpha, Beta, ErEff;
154  nr_double_t Pe, Po, r, fo1, q, p, n, Psi, Phi, m, Theta;
155 
156  // modifying equations for even mode
157  m = 0.2175 + qucs::pow (4.113 + qucs::pow (20.36 / g, 6.), -0.251) +
158  qucs::log (qucs::pow (g, 10.) / (1 + qucs::pow (g / 13.8, 10.))) / 323;
159  Alpha = 0.5 * qucs::exp (-g);
160  Psi = 1 + g / 1.45 + qucs::pow (g, 2.09) / 3.95;
161  Phi = 0.8645 * qucs::pow (u, 0.172);
162  Pe = Phi / (Psi * (Alpha * qucs::pow (u, m) + (1 - Alpha) * qucs::pow (u, -m)));
163  // TODO: is this ... Psi * (Alpha ... or ... Psi / (Alpha ... ?
164 
165  // modifying equations for odd mode
166  n = (1 / 17.7 + qucs::exp (-6.424 - 0.76 * qucs::log (g) - qucs::pow (g / 0.23, 5.))) *
167  qucs::log ((10 + 68.3 * sqr (g)) / (1 + 32.5 * qucs::pow (g, 3.093)));
168  Beta = 0.2306 + qucs::log (qucs::pow (g, 10.) / (1 + qucs::pow (g / 3.73, 10.))) / 301.8 +
169  qucs::log (1 + 0.646 * qucs::pow (g, 1.175)) / 5.3;
170  Theta = 1.729 + 1.175 * qucs::log (1 + 0.627 / (g + 0.327 * qucs::pow (g, 2.17)));
171  Po = Pe - Theta / Psi * qucs::exp (Beta * qucs::pow (u, -n) * qucs::log (u));
172 
173  // further modifying equations
174  r = 1 + 0.15 * (1 - qucs::exp (1 - sqr (er - 1) / 8.2) / (1 + qucs::pow (g, -6.)));
175  fo1 = 1 - qucs::exp (-0.179 * qucs::pow (g, 0.15) -
176  0.328 * qucs::pow (g, r) / qucs::log (M_E + qucs::pow (g / 7, 2.8)));
177  q = qucs::exp (-1.366 - g);
178  p = qucs::exp (-0.745 * qucs::pow (g, 0.295)) / qucs::cosh (qucs::pow (g, 0.68));
179  fo = fo1 * qucs::exp (p * qucs::log (u) + q * qucs::sin (M_PI * qucs::log10 (u)));
180 
181  Mu = g * qucs::exp (-g) + u * (20 + sqr (g)) / (10 + sqr (g));
182  msline::Hammerstad_ab (Mu, er, a, b);
183  Fe = qucs::pow (1 + 10 / Mu, -a * b);
184  msline::Hammerstad_ab (u, er, a, b);
185  Fo = fo * qucs::pow (1 + 10 / u, -a * b);
186 
187  // finally compute effective dielectric constants and impedances
188  ErEffe = (er + 1) / 2 + (er - 1) / 2 * Fe;
189  ErEffo = (er + 1) / 2 + (er - 1) / 2 * Fo;
190 
191  msline::Hammerstad_er (u, er, a, b, ErEff); // single microstrip
192 
193  // first variant
194  Zl1 = Z0 / (u + 1.98 * qucs::pow (u, 0.172));
195  Zl1 /= qucs::sqrt (ErEff);
196 
197  // second variant
198  msline::Hammerstad_zl (u, Zl1);
199  Zl1 /= qucs::sqrt (ErEff);
200 
201  Zle = Zl1 / (1 - Zl1 * Pe / Z0);
202  Zlo = Zl1 / (1 - Zl1 * Po / Z0);
203  }
204  // KIRSCHNING and JANSEN
205  else if (!strcmp (SModel, "Kirschning")) {
206  nr_double_t a, b, ae, be, ao, bo, v, co, d, ErEff, Zl1;
207  nr_double_t q1, q2, q3, q4, q5, q6, q7, q8, q9, q10;
208 
209  // consider effect of finite strip thickness (JANSEN only)
210  nr_double_t ue = u;
211  nr_double_t uo = u;
212  if (t != 0 && s > 10 * (2 * t)) {
213  nr_double_t dW = 0;
214  // SCHNEIDER, referred by JANSEN
215  if (u >= M_1_PI / 2 && M_1_PI / 2 > 2 * t / h)
216  dW = t * (1 + qucs::log (2 * h / t)) / M_PI;
217  else if (W > 2 * t)
218  dW = t * (1 + qucs::log (4 * M_PI * W / t)) / M_PI;
219  // JANSEN
220  nr_double_t dt = 2 * t * h / s / er;
221  nr_double_t We = W + dW * (1 - 0.5 * qucs::exp (-0.69 * dW / dt));
222  nr_double_t Wo = We + dt;
223  ue = We / h;
224  uo = Wo / h;
225  }
226 
227  // even relative dielectric constant
228  v = ue * (20 + sqr (g)) / (10 + sqr (g)) + g * qucs::exp (-g);
229  msline::Hammerstad_ab (v, er, ae, be);
230  msline::Hammerstad_er (v, er, ae, be, ErEffe);
231 
232  // odd relative dielectric constant
233  msline::Hammerstad_ab (uo, er, a, b);
234  msline::Hammerstad_er (uo, er, a, b, ErEff);
235  d = 0.593 + 0.694 * qucs::exp (-0.562 * uo);
236  bo = 0.747 * er / (0.15 + er);
237  co = bo - (bo - 0.207) * qucs::exp (-0.414 * uo);
238  ao = 0.7287 * (ErEff - (er + 1) / 2) * (1 - qucs::exp (-0.179 * uo));
239  ErEffo = ((er + 1) / 2 + ao - ErEff) * qucs::exp (-co * qucs::pow (g, d)) + ErEff;
240 
241  // characteristic impedance of single line
242  msline::Hammerstad_zl (u, Zl1);
243  Zl1 /= qucs::sqrt (ErEff);
244 
245  // even characteristic impedance
246  q1 = 0.8695 * qucs::pow (ue, 0.194);
247  q2 = 1 + 0.7519 * g + 0.189 * qucs::pow (g, 2.31);
248  q3 = 0.1975 + qucs::pow (16.6 + qucs::pow (8.4 / g, 6.), -0.387) +
249  qucs::log (qucs::pow (g, 10.) / (1 + qucs::pow (g / 3.4, 10.))) / 241;
250  q4 = q1 / q2 * 2 /
251  (qucs::exp (-g) * qucs::pow (ue, q3) + (2 - qucs::exp (-g)) * qucs::pow (ue, -q3));
252  Zle = qucs::sqrt (ErEff / ErEffe) * Zl1 / (1 - Zl1 * qucs::sqrt (ErEff) * q4 / Z0);
253 
254  // odd characteristic impedance
255  q5 = 1.794 + 1.14 * qucs::log (1 + 0.638 / (g + 0.517 * qucs::pow (g, 2.43)));
256  q6 = 0.2305 + qucs::log (qucs::pow (g, 10.) / (1 + qucs::pow (g / 5.8, 10.))) / 281.3 +
257  qucs::log (1 + 0.598 * qucs::pow (g, 1.154)) / 5.1;
258  q7 = (10 + 190 * sqr (g)) / (1 + 82.3 * cubic (g));
259  q8 = qucs::exp (-6.5 - 0.95 * qucs::log (g) - qucs::pow (g / 0.15, 5.));
260  q9 = qucs::log (q7) * (q8 + 1 / 16.5);
261  q10 = (q2 * q4 - q5 * qucs::exp (qucs::log (uo) * q6 * qucs::pow (uo, -q9))) / q2;
262  Zlo = qucs::sqrt (ErEff / ErEffo) * Zl1 / (1 - Zl1 * qucs::sqrt (ErEff) * q10 / Z0);
263  }
264 // nr_double_t Zle4, Zlo4, C, Z04;
265 
266  Zle = ((Zlo+Zle)/(3*Zlo+Zle))*Zle; //Pozar - Microwave engineering: eq 7.79a
267  Zlo = ((Zlo+Zle)/(3*Zle+Zlo))*Zlo; //Pozar - Microwave engineering: eq 7.79b
268 
269 }
270 
271 /* The function computes the dispersion effects on the dielectric
272  constants and characteristic impedances for the even and odd mode
273  of parallel coupled microstrip lines. */
274 void mslange::analyseDispersion (nr_double_t W, nr_double_t h, nr_double_t s,
275  nr_double_t er, nr_double_t Zle,
276  nr_double_t Zlo, nr_double_t ErEffe,
277  nr_double_t ErEffo, nr_double_t frequency,
278  char * DModel, nr_double_t& ZleFreq,
279  nr_double_t& ZloFreq,
280  nr_double_t& ErEffeFreq,
281  nr_double_t& ErEffoFreq) {
282 
283 
284  // initialize default return values
285  ZleFreq = Zle;
286  ErEffeFreq = ErEffe;
287  ZloFreq = Zlo;
288  ErEffoFreq = ErEffo;
289 
290  // normalized width and gap
291  nr_double_t u = W / h;
292  nr_double_t g = s / h;
293 
294  // GETSINGER
295  if (!strcmp (DModel, "Getsinger")) {
296  // even mode dispersion
297  msline::Getsinger_disp (h, er, ErEffe, Zle / 2,
298  frequency, ErEffeFreq, ZleFreq);
299  ZleFreq *= 2;
300  // odd mode dispersion
301  msline::Getsinger_disp (h, er, ErEffo, Zlo * 2,
302  frequency, ErEffoFreq, ZloFreq);
303  ZloFreq /= 2;
304  }
305  // KIRSCHNING and JANSEN
306  else if (!strcmp (DModel, "Kirschning")) {
307  nr_double_t p1, p2, p3, p4, p5, p6, p7, Fe;
308  nr_double_t fn = frequency * h * 1e-6;
309 
310  // even relative dielectric constant dispersion
311  p1 = 0.27488 * (0.6315 + 0.525 / qucs::pow (1 + 0.0157 * fn, 20.)) * u -
312  0.065683 * qucs::exp (-8.7513 * u);
313  p2 = 0.33622 * (1 - qucs::exp (-0.03442 * er));
314  p3 = 0.0363 * qucs::exp (-4.6 * u) * (1 - qucs::exp (- qucs::pow (fn / 38.7, 4.97)));
315  p4 = 1 + 2.751 * (1 - qucs::exp (- qucs::pow (er / 15.916, 8.)));
316  p5 = 0.334 * qucs::exp (-3.3 * cubic (er / 15)) + 0.746;
317  p6 = p5 * qucs::exp (- qucs::pow (fn / 18, 0.368));
318  p7 = 1 + 4.069 * p6 * qucs::pow (g, 0.479) *
319  qucs::exp (-1.347 * qucs::pow (g, 0.595) - 0.17 * qucs::pow (g, 2.5));
320  Fe = p1 * p2 * qucs::pow ((p3 * p4 + 0.1844 * p7) * fn, 1.5763);
321  ErEffeFreq = er - (er - ErEffe) / (1 + Fe);
322 
323  // odd relative dielectric constant dispersion
324  nr_double_t p8, p9, p10, p11, p12, p13, p14, p15, Fo;
325  p8 = 0.7168 * (1 + 1.076 / (1 + 0.0576 * (er - 1)));
326  p9 = p8 - 0.7913 * (1 - qucs::exp (- qucs::pow (fn / 20, 1.424))) *
327  qucs::atan (2.481 * qucs::pow (er / 8, 0.946));
328  p10 = 0.242 * qucs::pow (er - 1, 0.55);
329  p11 = 0.6366 * (qucs::exp (-0.3401 * fn) - 1) *
330  qucs::atan (1.263 * qucs::pow (u / 3, 1.629));
331  p12 = p9 + (1 - p9) / (1 + 1.183 * qucs::pow (u, 1.376));
332  p13 = 1.695 * p10 / (0.414 + 1.605 * p10);
333  p14 = 0.8928 + 0.1072 * (1 - qucs::exp (-0.42 * qucs::pow (fn / 20, 3.215)));
334  p15 = fabs (1 - 0.8928 * (1 + p11) *
335  qucs::exp (-p13 * qucs::pow (g, 1.092)) * p12 / p14);
336  Fo = p1 * p2 * qucs::pow ((p3 * p4 + 0.1844) * fn * p15, 1.5763);
337  ErEffoFreq = er - (er - ErEffo) / (1 + Fo);
338 
339  // dispersion of even characteristic impedance
340  nr_double_t t, q11, q12, q13, q14, q15, q16, q17, q18, q19, q20, q21;
341  q11 = 0.893 * (1 - 0.3 / (1 + 0.7 * (er - 1)));
342  t = qucs::pow (fn / 20, 4.91);
343  q12 = 2.121 * t / (1 + q11 * t) * qucs::exp (-2.87 * g) * qucs::pow (g, 0.902);
344  q13 = 1 + 0.038 * qucs::pow (er / 8, 5.1);
345  t = quadr (er / 15);
346  q14 = 1 + 1.203 * t / (1 + t);
347  q15 = 1.887 * qucs::exp (-1.5 * qucs::pow (g, 0.84)) * qucs::pow (g, q14) /
348  (1 + 0.41 * qucs::pow (fn / 15, 3.) *
349  qucs::pow (u, 2 / q13) / (0.125 + qucs::pow (u, 1.626 / q13)));
350  q16 = q15 * (1 + 9 / (1 + 0.403 * sqr (er - 1)));
351  q17 = 0.394 * (1 - qucs::exp (-1.47 * qucs::pow (u / 7, 0.672))) *
352  (1 - qucs::exp (-4.25 * qucs::pow (fn / 20, 1.87)));
353  q18 = 0.61 * (1 - qucs::exp (-2.31 * qucs::pow (u / 8, 1.593))) /
354  (1 + 6.544 * qucs::pow (g, 4.17));
355  q19 = 0.21 * quadr (g) / (1 + 0.18 * qucs::pow (g, 4.9)) / (1 + 0.1 * sqr (u)) /
356  (1 + qucs::pow (fn / 24, 3.));
357  q20 = q19 * (0.09 + 1 / (1 + 0.1 * qucs::pow (er - 1, 2.7)));
358  t = qucs::pow (u, 2.5);
359  q21 = fabs (1 - 42.54 * qucs::pow (g, 0.133) * qucs::exp (-0.812 * g) * t /
360  (1 + 0.033 * t));
361 
362  nr_double_t re, qe, pe, de, Ce, q0, ZlFreq, ErEffFreq;
363  msline::Kirschning_er (u, fn, er, ErEffe, ErEffFreq);
364  msline::Kirschning_zl (u, fn, er, ErEffe, ErEffFreq, Zle, q0, ZlFreq);
365  re = qucs::pow (fn / 28.843, 12.);
366  qe = 0.016 + qucs::pow (0.0514 * er * q21, 4.524);
367  pe = 4.766 * qucs::exp (-3.228 * qucs::pow (u, 0.641));
368  t = qucs::pow (er - 1, 6.);
369  de = 5.086 * qe * re / (0.3838 + 0.386 * qe) *
370  qucs::exp (-22.2 * qucs::pow (u, 1.92)) / (1 + 1.2992 * re) * t / (1 + 10 * t);
371  Ce = 1 + 1.275 * (1 - qucs::exp (-0.004625 * pe * qucs::pow (er, 1.674) *
372  qucs::pow (fn / 18.365, 2.745))) - q12 + q16 - q17 + q18 + q20;
373  ZleFreq = Zle * qucs::pow ((0.9408 * qucs::pow (ErEffFreq, Ce) - 0.9603) /
374  ((0.9408 - de) * qucs::pow (ErEffe, Ce) - 0.9603), q0);
375 
376  // dispersion of odd characteristic impedance
377  nr_double_t q22, q23, q24, q25, q26, q27, q28, q29;
378  msline::Kirschning_er (u, fn, er, ErEffo, ErEffFreq);
379  msline::Kirschning_zl (u, fn, er, ErEffo, ErEffFreq, Zlo, q0, ZlFreq);
380  q29 = 15.16 / (1 + 0.196 * sqr (er - 1));
381  t = sqr (er - 1);
382  q25 = 0.3 * sqr (fn) / (10 + sqr (fn)) * (1 + 2.333 * t / (5 + t));
383  t = qucs::pow ((er - 1) / 13, 12.);
384  q26 = 30 - 22.2 * t / (1 + 3 * t) - q29;
385  t = qucs::pow (er - 1, 1.5);
386  q27 = 0.4 * qucs::pow (g, 0.84) * (1 + 2.5 * t / (5 + t));
387  t = qucs::pow (er - 1, 3.);
388  q28 = 0.149 * t / (94.5 + 0.038 * t);
389  q22 = 0.925 * qucs::pow (fn / q26, 1.536) / (1 + 0.3 * qucs::pow (fn / 30, 1.536));
390  q23 = 1 + 0.005 * fn * q27 / (1 + 0.812 * qucs::pow (fn / 15, 1.9)) /
391  (1 + 0.025 * sqr (u));
392  t = qucs::pow (u, 0.894);
393  q24 = 2.506 * q28 * t / (3.575 + t) *
394  qucs::pow ((1 + 1.3 * u) * fn / 99.25, 4.29);
395  ZloFreq = ZlFreq + (Zlo * qucs::pow (ErEffoFreq / ErEffo, q22) - ZlFreq * q23) /
396  (1 + q24 + qucs::pow (0.46 * g, 2.2) * q25);
397 
398  }
399 }
400 
401 void mslange::initDC (void) {
402  nr_double_t l = getPropertyDouble ("L");
403  nr_double_t W = getPropertyDouble ("W")/2;
405  nr_double_t t = subst->getPropertyDouble ("t");
406  nr_double_t rho = subst->getPropertyDouble ("rho");
407 
408  if (t != 0.0 && rho != 0.0) {
409  // tiny resistances
410  nr_double_t g = t * W / rho / l;
411  setVoltageSources (0);
412  allocMatrixMNA ();
413  setY (NODE_1, NODE_1, +g); setY (NODE_2, NODE_2, +g);
414  setY (NODE_1, NODE_2, -g); setY (NODE_2, NODE_1, -g);
415  setY (NODE_3, NODE_3, +g); setY (NODE_4, NODE_4, +g);
416  setY (NODE_3, NODE_4, -g); setY (NODE_4, NODE_3, -g);
417  }
418  else {
419  // DC shorts (voltage sources V = 0 volts)
420  setVoltageSources (2);
422  allocMatrixMNA ();
423  clearY ();
426  setD (VSRC_1, VSRC_2, 0.0); setD (VSRC_2, VSRC_1, 0.0);
427  }
428 }
429 
430 void mslange::initAC (void) {
431  setVoltageSources (0);
432  allocMatrixMNA ();
433 }
434 
435 void mslange::calcAC (nr_double_t frequency) {
436  // fetch line properties
437  nr_double_t l = getPropertyDouble ("L");
438 
439  // compute propagation constants for even and odd mode
440  calcPropagation (frequency);
441  nr_complex_t ge = nr_complex_t (ae, be);
442  nr_complex_t go = nr_complex_t (ao, bo);
443 
444  // compute abbreviations
445  nr_complex_t De, Do, y1, y2, y3, y4;
446  De = 0.5 / (ze * qucs::sinh (ge * l));
447  Do = 0.5 / (zo * qucs::sinh (go * l));
448  y2 = -De - Do;
449  y3 = -De + Do;
450  De *= cosh (ge * l);
451  Do *= cosh (go * l);
452  y1 = De + Do;
453  y4 = De - Do;
454 
455  // store Y-parameters
456  setY (NODE_1, NODE_1, y1); setY (NODE_2, NODE_2, y1);
457  setY (NODE_3, NODE_3, y1); setY (NODE_4, NODE_4, y1);
458  setY (NODE_1, NODE_2, y2); setY (NODE_2, NODE_1, y2);
459  setY (NODE_3, NODE_4, y2); setY (NODE_4, NODE_3, y2);
460  setY (NODE_1, NODE_3, y3); setY (NODE_2, NODE_4, y3);
461  setY (NODE_3, NODE_1, y3); setY (NODE_4, NODE_2, y3);
462  setY (NODE_1, NODE_4, y4); setY (NODE_2, NODE_3, y4);
463  setY (NODE_3, NODE_2, y4); setY (NODE_4, NODE_1, y4);
464 }
465 
466 void mslange::calcNoiseAC (nr_double_t) {
467  // calculate noise using Bosma's theorem
468  nr_double_t T = getPropertyDouble ("Temp");
469  setMatrixN (4 * kelvin (T) / T0 * real (getMatrixY ()));
470 }
471 
472 // properties
473 PROP_REQ [] = {
474  { "W", PROP_REAL, { 1e-3, PROP_NO_STR }, PROP_POS_RANGE },
475  { "L", PROP_REAL, { 10e-3, PROP_NO_STR }, PROP_POS_RANGE },
476  { "S", PROP_REAL, { 1e-3, PROP_NO_STR }, PROP_POS_RANGE },
477  { "Subst", PROP_STR, { PROP_NO_VAL, "Subst1" }, PROP_NO_RANGE },
478  { "Model", PROP_STR, { PROP_NO_VAL, "Kirschning" },
479  PROP_RNG_STR2 ("Kirschning", "Hammerstad") },
480  { "DispModel", PROP_STR, { PROP_NO_VAL, "Kirschning" },
481  PROP_RNG_STR2 ("Kirschning", "Getsinger") },
482  PROP_NO_PROP };
483 PROP_OPT [] = {
484  { "Temp", PROP_REAL, { 26.85, PROP_NO_STR }, PROP_MIN_VAL (K) },
485  PROP_NO_PROP };
486 struct define_t mslange::cirdef =
#define M_E
Euler's constant ( )
Definition: consts.h:71
std::complex< nr_double_t > nr_complex_t
Definition: complex.h:31
#define PROP_POS_RANGE
Definition: netdefs.h:129
static void Hammerstad_ab(nr_double_t, nr_double_t, nr_double_t &, nr_double_t &)
Definition: msline.cpp:312
l
Definition: parse_vcd.y:213
void clearY(void)
Definition: circuit.cpp:740
#define NODE_2
Definition: circuit.h:35
matrix real(matrix a)
Real part matrix.
Definition: matrix.cpp:568
#define T0
standard temperature
Definition: constants.h:61
nr_double_t ao
Definition: mslange.h:52
#define kelvin(x)
Definition: constants.h:108
substrate * subst
Definition: circuit.h:350
nr_double_t ee
Definition: mslange.h:52
#define PROP_DEF
Definition: netdefs.h:189
#define PROP_RNG_STR2(s1, s2)
Definition: netdefs.h:145
static void analysQuasiStatic(nr_double_t, nr_double_t, nr_double_t, nr_double_t, nr_double_t, char *, nr_double_t &, nr_double_t &, nr_double_t &, nr_double_t &)
Definition: mslange.cpp:138
void saveCharacteristics(nr_double_t)
Definition: mslange.cpp:85
nr_double_t getPropertyDouble(const char *)
Definition: object.cpp:176
nr_complex_t pow(const nr_complex_t z, const nr_double_t d)
Compute power function with real exponent.
Definition: complex.cpp:238
void setD(int, int, nr_complex_t)
Definition: circuit.cpp:373
#define PROP_REAL
Definition: netdefs.h:174
substrate * getSubstrate(void)
Definition: circuit.cpp:332
void setInternalVoltageSource(bool i)
Definition: circuit.h:184
t
Definition: parse_vcd.y:290
static void analyseLoss(nr_double_t, nr_double_t, nr_double_t, nr_double_t, nr_double_t, nr_double_t, nr_double_t, nr_double_t, nr_double_t, nr_double_t, const char *, nr_double_t &, nr_double_t &)
Definition: msline.cpp:401
#define PROP_NO_PROP
Definition: netdefs.h:122
void setVoltageSources(int)
Definition: circuit.cpp:607
nr_complex_t atan(const nr_complex_t z)
Compute complex arc tangent.
Definition: complex.cpp:117
void initAC(void)
Definition: mslange.cpp:430
void initDC(void)
Definition: mslange.cpp:401
#define K
Absolute 0 in centigrade.
Definition: constants.h:59
#define PROP_NO_RANGE
Definition: netdefs.h:126
#define PROP_NO_STR
Definition: netdefs.h:125
nr_double_t eo
Definition: mslange.h:52
n
Definition: parse_citi.y:147
#define PROP_LINEAR
Definition: netdefs.h:120
static const nr_double_t z0
Definition: circuit.h:320
h
Definition: parse_vcd.y:214
r
Definition: parse_mdl.y:515
PROP_REQ[]
Definition: mslange.cpp:473
matrix getMatrixY(void)
Definition: circuit.cpp:696
int getSize(void)
Get the number of ports the circuit element has.
Definition: circuit.h:143
PROP_NO_SUBSTRATE
Definition: mslange.cpp:487
void calcAC(nr_double_t)
Definition: mslange.cpp:435
#define NODE_4
Definition: circuit.h:37
nr_complex_t cosh(const nr_complex_t z)
Compute complex hyperbolic cosine.
Definition: complex.cpp:135
#define VSRC_1
Definition: circuit.h:40
nr_complex_t sqr(const nr_complex_t z)
Square of complex number.
Definition: complex.cpp:673
nr_complex_t sqrt(const nr_complex_t z)
Compute principal value of square root.
Definition: complex.cpp:271
static void Getsinger_disp(nr_double_t, nr_double_t, nr_double_t, nr_double_t, nr_double_t, nr_double_t &, nr_double_t &)
Definition: msline.cpp:339
PROP_OPT[]
Definition: mslange.cpp:483
nr_complex_t sin(const nr_complex_t z)
Compute complex sine.
Definition: complex.cpp:66
#define PROP_COMPONENT
Definition: netdefs.h:116
nr_double_t quadr(const nr_double_t r)
Quartic function.
Definition: real.cpp:324
void calcNoiseSP(nr_double_t)
Definition: mslange.cpp:126
static void Kirschning_zl(nr_double_t, nr_double_t, nr_double_t, nr_double_t, nr_double_t, nr_double_t, nr_double_t &, nr_double_t &)
Definition: msline.cpp:369
static void analyseDispersion(nr_double_t, nr_double_t, nr_double_t, nr_double_t, nr_double_t, nr_double_t, nr_double_t, nr_double_t, nr_double_t, char *, nr_double_t &, nr_double_t &, nr_double_t &, nr_double_t &)
Definition: mslange.cpp:274
nr_double_t be
Definition: mslange.h:52
nr_complex_t log10(const nr_complex_t z)
Compute principal value of decimal logarithm of z.
Definition: complex.cpp:225
#define NODE_3
Definition: circuit.h:36
#define M_PI
Archimedes' constant ( )
Definition: consts.h:47
static void Hammerstad_zl(nr_double_t, nr_double_t &)
Definition: msline.cpp:331
matrix transpose(matrix a)
Matrix transposition.
Definition: matrix.cpp:492
nr_double_t ae
Definition: mslange.h:52
static void Kirschning_er(nr_double_t, nr_double_t, nr_double_t, nr_double_t, nr_double_t &)
Definition: msline.cpp:354
void calcPropagation(nr_double_t)
Definition: mslange.cpp:40
matrix getMatrixS(void)
Definition: circuit.cpp:654
void setY(int, int, nr_complex_t)
Definition: circuit.cpp:452
#define PROP_MIN_VAL(k)
Definition: netdefs.h:133
void calcSP(nr_double_t)
Definition: mslange.cpp:92
v
Definition: parse_zvr.y:141
void allocMatrixMNA(void)
Definition: circuit.cpp:267
#define M_1_PI
Inverse of Archimedes' constant ( )
Definition: consts.h:59
static void Hammerstad_er(nr_double_t, nr_double_t, nr_double_t, nr_double_t, nr_double_t &)
Definition: msline.cpp:322
nr_complex_t sinh(const nr_complex_t z)
Compute complex hyperbolic sine.
Definition: complex.cpp:144
#define PROP_STR
Definition: netdefs.h:175
#define NODE_1
Definition: circuit.h:34
#define C0
speed of light in vacuum ( )
Definition: constants.h:47
void voltageSource(int, int, int, nr_double_t value=0.0)
Definition: circuit.cpp:748
nr_double_t ze
Definition: mslange.h:52
void setMatrixN(matrix)
Definition: circuit.cpp:664
matrix eye(int rs, int cs)
Create identity matrix with specified number of rows and columns.
Definition: matrix.cpp:603
nr_complex_t exp(const nr_complex_t z)
Compute complex exponential.
Definition: complex.cpp:205
#define D(con)
void setS(int, int, nr_complex_t)
Definition: circuit.cpp:587
matrix conj(matrix a)
Conjugate complex matrix.
Definition: matrix.cpp:505
#define PROP_NO_VAL
Definition: netdefs.h:124
nr_double_t zo
Definition: mslange.h:52
void calcNoiseAC(nr_double_t)
Definition: mslange.cpp:466
void setCharacteristic(const char *, nr_double_t)
Definition: circuit.cpp:566
#define VSRC_2
Definition: circuit.h:41
char * getPropertyString(const char *)
Definition: object.cpp:159
nr_complex_t log(const nr_complex_t z)
Compute principal value of natural logarithm of z.
Definition: complex.cpp:215
#define Z0
Wave impedance in vacuum ( )
Definition: constants.h:53
nr_double_t bo
Definition: mslange.h:52
#define cubic(x)
Definition: constants.h:106