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