Branch data Line data Source code
1 : : /*
2 : : * msopen.cpp - microstrip open end class implementation
3 : : *
4 : : * Copyright (C) 2004, 2008 Stefan Jahn <stefan@lkcc.org>
5 : : * Copyright (C) 2004 Michael Margraf <Michael.Margraf@alumni.TU-Berlin.DE>
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$
23 : : *
24 : : */
25 : :
26 : : #if HAVE_CONFIG_H
27 : : # include <config.h>
28 : : #endif
29 : :
30 : : #include "component.h"
31 : : #include "substrate.h"
32 : : #include "msline.h"
33 : : #include "msopen.h"
34 : :
35 : : using namespace qucs;
36 : :
37 : 10 : msopen::msopen () : circuit (1) {
38 : 10 : type = CIR_MSOPEN;
39 : 10 : }
40 : :
41 : : // Returns the microstrip open end capacitance.
42 : 1500 : nr_double_t msopen::calcCend (nr_double_t frequency, nr_double_t W,
43 : : nr_double_t h, nr_double_t t, nr_double_t er,
44 : : const char * const SModel, const char * const DModel,
45 : : const char * const Model) {
46 : :
47 : : nr_double_t ZlEff, ErEff, WEff, ZlEffFreq, ErEffFreq;
48 [ + - ]: 1500 : msline::analyseQuasiStatic (W, h, t, er, SModel, ZlEff, ErEff, WEff);
49 : : msline::analyseDispersion (WEff, h, er, ZlEff, ErEff, frequency, DModel,
50 [ + - ]: 1500 : ZlEffFreq, ErEffFreq);
51 : :
52 : 1500 : W /= h;
53 : 1500 : nr_double_t dl = 0;
54 : : /* Kirschning, Jansen and Koster */
55 [ + - ]: 1500 : if (!strcmp (Model, "Kirschning")) {
56 [ + - ]: 1500 : nr_double_t Q6 = qucs::pow (ErEffFreq, 0.81);
57 [ + - ]: 1500 : nr_double_t Q7 = qucs::pow (W, 0.8544);
58 : : nr_double_t Q1 = 0.434907 *
59 : 1500 : (Q6 + 0.26) / (Q6 - 0.189) * (Q7 + 0.236) / (Q7 + 0.87);
60 [ + - ]: 1500 : nr_double_t Q2 = qucs::pow (W, 0.371) / (2.358 * er + 1.0) + 1.0;
61 [ + - ][ + - ]: 1500 : nr_double_t Q3 = qucs::atan (0.084 * qucs::pow (W, 1.9413 / Q2)) *
62 [ + - ]: 1500 : 0.5274 / qucs::pow (ErEffFreq, 0.9236) + 1.0;
63 [ + - ]: 1500 : nr_double_t Q4 = 0.0377 * (6.0 - 5.0 * qucs::exp (0.036 * (1.0 - er))) *
64 [ + - ][ + - ]: 1500 : qucs::atan (0.067 * qucs::pow (W, 1.456)) + 1.0;
65 [ + - ]: 1500 : nr_double_t Q5 = 1.0 - 0.218 * qucs::exp (-7.5 * W);
66 : 1500 : dl = Q1 * Q3 * Q5 / Q4;
67 : : }
68 : : /* Hammerstad */
69 [ # # ]: 0 : else if (!strcmp (Model, "Hammerstad")) {
70 : : dl = 0.102 * (W + 0.106) / (W + 0.264) *
71 [ # # ]: 0 : (1.166 + (er + 1) / er * (0.9 + qucs::log (W + 2.475)));
72 : : }
73 [ + - ]: 1500 : return dl * h * qucs::sqrt (ErEffFreq) / C0 / ZlEffFreq;
74 : : }
75 : :
76 : 1500 : void msopen::calcSP (nr_double_t frequency) {
77 [ + - ][ + - ]: 1500 : setS (NODE_1, NODE_1, ztor (1.0 / calcY (frequency)));
[ + - ][ + - ]
78 : 1500 : }
79 : :
80 : 1500 : nr_complex_t msopen::calcY (nr_double_t frequency) {
81 : :
82 : : /* how to get properties of this component, e.g. W */
83 [ + - ]: 1500 : nr_double_t W = getPropertyDouble ("W");
84 [ + - ]: 1500 : const char * SModel = getPropertyString ("MSModel");
85 [ + - ]: 1500 : const char * DModel = getPropertyString ("MSDispModel");
86 [ + - ]: 1500 : const char * Model = getPropertyString ("Model");
87 : :
88 : : /* how to get properties of the substrate, e.g. Er, H */
89 [ + - ]: 1500 : substrate * subst = getSubstrate ();
90 [ + - ]: 1500 : nr_double_t er = subst->getPropertyDouble ("er");
91 [ + - ]: 1500 : nr_double_t h = subst->getPropertyDouble ("h");
92 [ + - ]: 1500 : nr_double_t t = subst->getPropertyDouble ("t");
93 : :
94 : : /* local variables */
95 : 1500 : nr_complex_t y;
96 : 1500 : nr_double_t o = 2 * M_PI * frequency;
97 : :
98 : : /* Alexopoulos and Wu */
99 [ - + ]: 1500 : if (!strcmp (Model, "Alexopoulos")) {
100 : : nr_double_t ZlEff, ErEff, WEff, ZlEffFreq, ErEffFreq;
101 [ # # ]: 0 : msline::analyseQuasiStatic (W, h, t, er, SModel, ZlEff, ErEff, WEff);
102 : : msline::analyseDispersion (WEff, h, er, ZlEff, ErEff, frequency, DModel,
103 [ # # ]: 0 : ZlEffFreq, ErEffFreq);
104 : :
105 [ # # ]: 0 : if (fabs (er - 9.9) > 0.2) {
106 : : logprint (LOG_ERROR, "WARNING: Model for microstrip open end defined "
107 [ # # ]: 0 : "for er = 9.9 (er = %g)\n", er);
108 : : }
109 : :
110 : : nr_double_t c1, c2, l2, r2;
111 [ # # ]: 0 : c1 = (1.125 * qucs::tanh (1.358 * W / h) - 0.315) *
112 : 0 : h / 2.54e-5 / 25 / ZlEffFreq * 1e-12;
113 [ # # ]: 0 : c2 = (6.832 * qucs::tanh (0.0109 * W / h) + 0.919) *
114 : 0 : h / 2.54e-5 / 25 / ZlEffFreq * 1e-12;
115 [ # # ]: 0 : l2 = (0.008285 * qucs::tanh (0.5665 * W / h) + 0.0103) *
116 : 0 : h / 2.54e-5 / 25 * ZlEffFreq * 1e-9;
117 [ # # ]: 0 : r2 = (1.024 * qucs::tanh (2.025 * W / h)) * ZlEffFreq;
118 [ # # ][ # # ]: 0 : y = nr_complex_t (0, c1 * o) + 1.0 / nr_complex_t (r2, l2 * o - 1 / c2 / o);
119 : : }
120 : : else {
121 [ + - ]: 1500 : nr_double_t c = calcCend (frequency, W, h, t, er, SModel, DModel, Model);
122 : 1500 : y = nr_complex_t (0, c * o);
123 : : }
124 : 1500 : return y;
125 : : }
126 : :
127 : 0 : void msopen::initDC (void) {
128 : 0 : allocMatrixMNA ();
129 [ # # ]: 0 : setY (NODE_1, NODE_1, 0);
130 : 0 : }
131 : :
132 : 0 : void msopen::calcAC (nr_double_t frequency) {
133 : 0 : setY (NODE_1, NODE_1, calcY (frequency));
134 : 0 : }
135 : :
136 : : // properties
137 : : PROP_REQ [] = {
138 : : { "W", PROP_REAL, { 1e-3, PROP_NO_STR }, PROP_POS_RANGE },
139 : : { "Subst", PROP_STR, { PROP_NO_VAL, "Subst1" }, PROP_NO_RANGE },
140 : : { "MSDispModel", PROP_STR, { PROP_NO_VAL, "Kirschning" }, PROP_RNG_DIS },
141 : : { "MSModel", PROP_STR, { PROP_NO_VAL, "Hammerstad" }, PROP_RNG_MOD },
142 : : { "Model", PROP_STR, { PROP_NO_VAL, "Kirschning" },
143 : : PROP_RNG_STR3 ("Kirschning", "Hammerstad", "Alexopoulos") },
144 : : PROP_NO_PROP };
145 : : PROP_OPT [] = {
146 : : PROP_NO_PROP };
147 : : struct define_t msopen::cirdef =
148 : : { "MOPEN", 1, PROP_COMPONENT, PROP_NO_SUBSTRATE, PROP_LINEAR, PROP_DEF };
|