My Project  0.0.16
QUCS Mapping
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
bondwire.cpp
Go to the documentation of this file.
1 /*
2  * bondwire.cpp - bondwire class implementation
3  *
4  * Copyright (C) 2006 Bastien Roucaries <roucaries.bastien@gmail.com>
5  * Copyright (C) 2007, 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: bondwire.cpp 1825 2011-03-11 20:42:14Z ela $
23  *
24  */
25 
49 #if HAVE_CONFIG_H
50 # include <config.h>
51 #endif
52 
53 #include "component.h"
54 #include "substrate.h"
55 #include "bondwire.h"
56 
57 bondwire::bondwire () : circuit (2) {
58  type = CIR_BONDWIRE;
59 }
60 
61 
63 #define TABLE(x) { #x, x }
64 
65 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
66 
72 };
73 
75 struct modeltable_t {
76  const char * name;
77  int model;
78 };
79 
81 static const modeltable_t modeltable[] = {
83  TABLE(MIRROR),
84 };
85 
86 
92 void bondwire::getProperties (void) {
93  unsigned int i;
94 
95  R = 0;
96  l = getPropertyDouble ("L");
97  d = getPropertyDouble ("D");
98  h = getPropertyDouble ("H");
99  rho = getPropertyDouble ("rho");
100  mur = getPropertyDouble ("mur");
101 
102  /* model used */
103  char * Model = getPropertyString ("Model");
104  if (Model == NULL) {
105  model = FREESPACE;
106  logprint (LOG_STATUS, "Model is not specified force FREESPACE\n");
107  } else {
108  model = (enum bondwiremodel) -1;
109  for (i = 0 ; i < ARRAY_SIZE (modeltable); i++) {
110  if (!strcasecmp (modeltable[i].name, Model))
111  model = modeltable[i].model;
112  }
113 
114  if (model == -1)
115  /* XXXX: how to abort ? */
116  logprint (LOG_ERROR, "Model %s not defined\n", Model);
117  }
118 
119  /* For noise */
120  temp = getPropertyDouble ("Temp");
121 
122  /* how to get properties of the substrate, e.g. Er, H */
123  substrate * subst = getSubstrate ();
124  nr_double_t er = subst->getPropertyDouble ("er");
125  nr_double_t h = subst->getPropertyDouble ("h");
126  nr_double_t t = subst->getPropertyDouble ("t");
127 
128  /* Not yet used */
129  (void) er;
130  (void) h;
131  (void) t;
132 }
133 
141 static nr_double_t skindepth (const nr_double_t f,
142  const nr_double_t rho, const nr_double_t mur) {
143  return sqrt (rho / (M_PI * f * MU0 * mur));
144 }
145 
157 nr_double_t bondwire::resistance (const nr_double_t f) const {
158  nr_double_t delta, rout, rin;
159  rout = d / 2;
160  if (f > 0.0) {
161  delta = skindepth (f, rho, mur);
162  rin = rout - delta;
163  if (rin < 0.0)
164  rin = 0.0;
165  }
166  else
167  rin = 0.0;
168 
169  return (rho * M_1_PI * l) / (rout * rout - rin * rin);
170 }
171 
172 
196 static nr_double_t correctionfactor (const nr_double_t f,
197  const nr_double_t d,
198  const nr_double_t rho,
199  const nr_double_t mur) {
200  /* skin depth */
201  nr_double_t delta;
202 
203  if (f > 0.0 && rho > 0.0) {
204  delta = skindepth (f, rho, mur);
205  if (delta / d < 1e-2)
206  return delta / d;
207  else
208  return (mur / 4) * tanh ((4 * delta) / d);
209  }
210  return mur / 4;
211 }
212 
252 nr_double_t bondwire::Lfreespace (const nr_double_t f) const {
253  nr_double_t _2ld = (2.0 * l) / d;
254  nr_double_t d2l = d / (2.0 * l);
255  nr_double_t tmp;
256 
257  tmp = log (_2ld + sqrt (1 + _2ld * _2ld));
258  tmp += d2l - sqrt (1 + d2l * d2l);
259  tmp += correctionfactor (f, d, rho, mur);
260 
261  return MU0 * (M_1_PI / 2) * l * tmp;
262 }
263 
264 
295 nr_double_t bondwire::Lmirror (void) const {
296  nr_double_t tmp;
297 
298  /* compute \$\ln \frac{l+\sqrt{l^2+d^2/4}}{l+\sqrt{l^2+4h^2}}\$ */
299  tmp = log ((l + sqrt (l * l + d * d / 4)) / (l + sqrt (l * l + 4 * h * h)));
300  tmp += log (4 * h / d);
301  tmp += sqrt (1 + 4 * h * h / (l * l));
302  tmp -= sqrt (1 + d * d / (4 * l * l));
303  tmp -= 2 * h / l;
304  tmp += d / (2 * l);
305 
306  return MU0 * (M_1_PI / 2) * l * tmp;
307 }
308 
309 
312 matrix bondwire::calcMatrixY (const nr_double_t f) {
313  nr_double_t Lw;
314  L = 0;
315 
316  switch (model) {
317  case MIRROR:
318  L = Lmirror ();
319  R = resistance (f);
320  break;
321  case FREESPACE:
322  L = Lfreespace (f);
323  R = resistance (f);
324  break;
325  default:
326  break;
327  }
328 
329  Lw = L * 2 * M_PI * f;
330 
331  /* build Y-parameter matrix */
332  nr_complex_t yL = 1.0 / rect (R, Lw);
333 
334  matrix Y (2);
335  Y.set (NODE_1, NODE_1, +yL);
336  Y.set (NODE_1, NODE_2, -yL);
337  Y.set (NODE_2, NODE_1, -yL);
338  Y.set (NODE_2, NODE_2, +yL);
339  return Y;
340 }
341 
343 void bondwire::initSP (void) {
344  allocMatrixS ();
345  getProperties ();
346 }
347 
351 void bondwire::calcSP (const nr_double_t frequency) {
352  setMatrixS (ytos (calcMatrixY (frequency)));
353 }
354 
356 void bondwire::saveCharacteristics (nr_double_t) {
357  setCharacteristic ("L", L);
358  setCharacteristic ("R", R);
359 }
360 
364 void bondwire::initDC (void) {
365  nr_double_t g;
366 
367  getProperties ();
368 
369  /* for non-zero resistances usual MNA entries */
370  if (rho != 0.0) {
371  g = 1.0 / resistance (0);
372  setVoltageSources (0);
373  allocMatrixMNA ();
374  setY (NODE_1, NODE_1, +g); setY (NODE_2, NODE_2, +g);
375  setY (NODE_1, NODE_2, -g); setY (NODE_2, NODE_1, -g);
376  }
377  /* for zero resistances create a zero voltage source */
378  else {
379  setVoltageSources (1);
381  allocMatrixMNA ();
382  clearY ();
384  }
385 }
386 
388 void bondwire::initAC (void) {
389  getProperties ();
390  setVoltageSources (0);
391  allocMatrixMNA ();
392 }
393 
397 void bondwire::calcAC (const nr_double_t frequency) {
398  setMatrixY (calcMatrixY (frequency));
399 }
400 
401 void bondwire::calcNoiseSP (nr_double_t) {
402  // calculate noise correlation matrix
403  nr_double_t T = getPropertyDouble ("Temp");
404  nr_double_t f = kelvin (T) * 4.0 * R * z0 / norm (4.0 * z0 + R) / T0;
405  setN (NODE_1, NODE_1, +f); setN (NODE_2, NODE_2, +f);
406  setN (NODE_1, NODE_2, -f); setN (NODE_2, NODE_1, -f);
407 }
408 
409 void bondwire::calcNoiseAC (nr_double_t) {
410  // calculate noise current correlation matrix
411  nr_double_t y = 1 / R;
412  nr_double_t T = getPropertyDouble ("Temp");
413  nr_double_t f = kelvin (T) / T0 * 4.0 * y;
414  setN (NODE_1, NODE_1, +f); setN (NODE_2, NODE_2, +f);
415  setN (NODE_1, NODE_2, -f); setN (NODE_2, NODE_1, -f);
416 }
417 
418 // properties
419 PROP_REQ [] = {
420  { "D", PROP_REAL, { 25e-6, PROP_NO_STR }, PROP_POS_RANGE },
421  { "L", PROP_REAL, { 1e-3, PROP_NO_STR }, PROP_POS_RANGE },
422  { "H", PROP_REAL, { 1e-3, PROP_NO_STR }, PROP_POS_RANGE },
423  { "mur", PROP_REAL, { 1, PROP_NO_STR }, PROP_RNGII (1, 100) },
424  { "rho", PROP_REAL, { 0.022e-6, PROP_NO_STR }, PROP_POS_RANGE },
425  { "Model", PROP_STR, { PROP_NO_VAL, "FREESPACE" },
426  PROP_RNG_STR3 ("FREESPACE", "MIRROR", "DESCHARLES") },
427  { "Subst", PROP_STR, { PROP_NO_VAL, "Subst1" }, PROP_NO_RANGE },
428  PROP_NO_PROP };
429 PROP_OPT [] = {
430  { "Temp", PROP_REAL, { 26.85, PROP_NO_STR }, PROP_MIN_VAL (K) },
431  PROP_NO_PROP };
432 struct define_t bondwire::cirdef =