My Project  0.0.16
QUCS Mapping
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
msvia.cpp
Go to the documentation of this file.
1 /*
2  * msvia.cpp - microstrip via hole class implementation
3  *
4  * Copyright (C) 2004, 2005, 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: msvia.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 "msvia.h"
32 
33 msvia::msvia () : circuit (2) {
34  R = 0;
35  Z = 0;
36  type = CIR_MSVIA;
37 }
38 
39 void msvia::calcNoiseSP (nr_double_t) {
40  // calculate noise correlation matrix
41  nr_double_t T = getPropertyDouble ("Temp");
42  nr_double_t f = kelvin (T) * 4.0 * real (Z) * z0 / norm (4.0 * z0 + Z) / T0;
43  setN (NODE_1, NODE_1, +f); setN (NODE_2, NODE_2, +f);
44  setN (NODE_1, NODE_2, -f); setN (NODE_2, NODE_1, -f);
45 }
46 
47 void msvia::initSP (void) {
48  allocMatrixS ();
49  R = calcResistance ();
50 }
51 
52 void msvia::calcSP (nr_double_t frequency) {
53  // calculate s-parameters
54  Z = calcImpedance (frequency);
55  nr_complex_t z = Z / z0;
56  setS (NODE_1, NODE_1, z / (z + 2.0));
57  setS (NODE_2, NODE_2, z / (z + 2.0));
58  setS (NODE_1, NODE_2, 2.0 / (z + 2.0));
59  setS (NODE_2, NODE_1, 2.0 / (z + 2.0));
60 }
61 
62 nr_complex_t msvia::calcImpedance (nr_double_t frequency) {
63  // fetch substrate and component properties
64  substrate * subst = getSubstrate ();
65  nr_double_t h = subst->getPropertyDouble ("h");
66  nr_double_t t = subst->getPropertyDouble ("t");
67  nr_double_t rho = subst->getPropertyDouble ("rho");
68  nr_double_t r = getPropertyDouble ("D") / 2;
69 
70  // check frequency validity
71  if (frequency * h >= 0.03 * C0) {
72  logprint (LOG_ERROR, "WARNING: Model for microstrip via hole defined for "
73  "freq/C0*h < 0.03 (is %g)\n", frequency / C0 * h);
74  }
75 
76  // create Z-parameter
77  nr_double_t fs = M_PI * MU0 * sqr (t) / rho;
78  nr_double_t res = R * sqrt (1 + frequency * fs);
79  nr_double_t a = sqrt (sqr (r) + sqr (h));
80  nr_double_t ind = MU0 * (h * log ((h + a) / r) + 1.5 * (r - a));
81  return Z = rect (res, frequency * ind);
82 }
83 
84 nr_double_t msvia::calcResistance (void) {
85  // fetch substrate and component properties
86  substrate * subst = getSubstrate ();
87  nr_double_t h = subst->getPropertyDouble ("h");
88  nr_double_t t = subst->getPropertyDouble ("t");
89  nr_double_t rho = subst->getPropertyDouble ("rho");
90  nr_double_t r = getPropertyDouble ("D") / 2;
91  nr_double_t v = h / M_PI / (sqr (r) - sqr (r - t));
92  return R = rho * v;
93 }
94 
95 void msvia::initDC (void) {
96  nr_double_t r = calcResistance ();
97 
98  // for non-zero resistances usual MNA entries
99  if (r != 0.0) {
100  nr_double_t g = 1.0 / r;
101  setVoltageSources (0);
102  allocMatrixMNA ();
103  setY (NODE_1, NODE_1, +g); setY (NODE_2, NODE_2, +g);
104  setY (NODE_1, NODE_2, -g); setY (NODE_2, NODE_1, -g);
105  }
106  // for zero resistances create a zero voltage source
107  else {
108  setVoltageSources (1);
110  allocMatrixMNA ();
111  clearY ();
113  }
114 }
115 
116 void msvia::initAC (void) {
117  setVoltageSources (0);
118  allocMatrixMNA ();
119  R = calcResistance ();
120 }
121 
122 void msvia::calcAC (nr_double_t frequency) {
123  nr_complex_t y = 1.0 / calcImpedance (frequency);
124  setY (NODE_1, NODE_1, +y); setY (NODE_2, NODE_2, +y);
125  setY (NODE_1, NODE_2, -y); setY (NODE_2, NODE_1, -y);
126 }
127 
128 void msvia::calcNoiseAC (nr_double_t) {
129  // calculate noise current correlation matrix
130  nr_double_t y = real (1.0 / Z);
131  nr_double_t T = getPropertyDouble ("Temp");
132  nr_double_t f = kelvin (T) / T0 * 4.0 * y;
133  setN (NODE_1, NODE_1, +f); setN (NODE_2, NODE_2, +f);
134  setN (NODE_1, NODE_2, -f); setN (NODE_2, NODE_1, -f);
135 }
136 
137 // properties
138 PROP_REQ [] = {
139  { "D", PROP_REAL, { 100e-6, PROP_NO_STR }, PROP_POS_RANGE },
140  { "Subst", PROP_STR, { PROP_NO_VAL, "Subst1" }, PROP_NO_RANGE },
141  PROP_NO_PROP };
142 PROP_OPT [] = {
143  { "Temp", PROP_REAL, { 26.85, PROP_NO_STR }, PROP_MIN_VAL (K) },
144  PROP_NO_PROP };
145 struct define_t msvia::cirdef =