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