Branch data Line data Source code
1 : : /*
2 : : * cpwstep.cpp - coplanar waveguide step class implementation
3 : : *
4 : : * Copyright (C) 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 "cpwline.h"
32 : : #include "cpwstep.h"
33 : :
34 : : using namespace qucs;
35 : :
36 : 0 : cpwstep::cpwstep () : circuit (2) {
37 : 0 : type = CIR_CPWSTEP;
38 : 0 : }
39 : :
40 : : // Returns the coplanar step capacitances per unit length.
41 : 0 : void cpwstep::calcCends (nr_double_t frequency,
42 : : nr_double_t& C1, nr_double_t& C2) {
43 : :
44 : : // get properties of substrate and coplanar step
45 [ # # ]: 0 : nr_double_t W1 = getPropertyDouble ("W1");
46 [ # # ]: 0 : nr_double_t W2 = getPropertyDouble ("W2");
47 [ # # ]: 0 : nr_double_t s = getPropertyDouble ("S");
48 : 0 : nr_double_t s1 = (s - W1) / 2;
49 : 0 : nr_double_t s2 = (s - W2) / 2;
50 [ # # ]: 0 : substrate * subst = getSubstrate ();
51 [ # # ]: 0 : nr_double_t er = subst->getPropertyDouble ("er");
52 [ # # ]: 0 : nr_double_t h = subst->getPropertyDouble ("h");
53 [ # # ]: 0 : nr_double_t t = subst->getPropertyDouble ("t");
54 [ # # ]: 0 : int backMetal = !strcmp (getPropertyString ("Backside"), "Metal");
55 : :
56 : : nr_double_t ZlEff, ErEff, ZlEffFreq, ErEffFreq;
57 [ # # ]: 0 : cpwline::analyseQuasiStatic (W1, s1, h, t, er, backMetal, ZlEff, ErEff);
58 : : cpwline::analyseDispersion (W1, s1, h, er, ZlEff, ErEff, frequency,
59 [ # # ]: 0 : ZlEffFreq, ErEffFreq);
60 : 0 : C1 = ErEffFreq / C0 / ZlEffFreq;
61 [ # # ]: 0 : cpwline::analyseQuasiStatic (W2, s2, h, t, er, backMetal, ZlEff, ErEff);
62 : : cpwline::analyseDispersion (W2, s2, h, er, ZlEff, ErEff, frequency,
63 [ # # ]: 0 : ZlEffFreq, ErEffFreq);
64 : 0 : C2 = ErEffFreq / C0 / ZlEffFreq;
65 : 0 : }
66 : :
67 : 0 : void cpwstep::initSP (void) {
68 : 0 : allocMatrixS ();
69 : 0 : checkProperties ();
70 : 0 : }
71 : :
72 : 0 : void cpwstep::calcSP (nr_double_t frequency) {
73 [ # # ][ # # ]: 0 : nr_complex_t z = 2.0 / calcY (frequency) / z0;
74 [ # # ]: 0 : nr_complex_t s11 = -1.0 / (z + 1.0);
75 [ # # ]: 0 : nr_complex_t s21 = +z / (z + 1.0);
76 [ # # ]: 0 : setS (NODE_1, NODE_1, s11);
77 [ # # ]: 0 : setS (NODE_2, NODE_2, s11);
78 [ # # ]: 0 : setS (NODE_1, NODE_2, s21);
79 [ # # ]: 0 : setS (NODE_2, NODE_1, s21);
80 : 0 : }
81 : :
82 : 0 : void cpwstep::checkProperties (void) {
83 : 0 : nr_double_t W1 = getPropertyDouble ("W1");
84 : 0 : nr_double_t W2 = getPropertyDouble ("W2");
85 : 0 : nr_double_t s = getPropertyDouble ("S");
86 [ # # ]: 0 : if (W1 == W2) {
87 : : logprint (LOG_ERROR, "ERROR: Strip widths of step discontinuity do not "
88 : 0 : "differ\n");
89 : : }
90 [ # # ][ # # ]: 0 : if (W1 >= s || W2 >= s) {
91 : : logprint (LOG_ERROR, "ERROR: Strip widths of step discontinuity larger "
92 : 0 : "than groundplane gap\n");
93 : : }
94 : 0 : substrate * subst = getSubstrate ();
95 : 0 : nr_double_t er = subst->getPropertyDouble ("er");
96 [ # # ][ # # ]: 0 : if (er < 2 || er > 14) {
97 : : logprint (LOG_ERROR, "WARNING: Model for coplanar step valid for "
98 : 0 : "2 < er < 14 (er = %g)\n", er);
99 : : }
100 : 0 : }
101 : :
102 : 0 : nr_complex_t cpwstep::calcY (nr_double_t frequency) {
103 [ # # ]: 0 : nr_double_t W1 = getPropertyDouble ("W1");
104 [ # # ]: 0 : nr_double_t W2 = getPropertyDouble ("W2");
105 [ # # ]: 0 : nr_double_t s = getPropertyDouble ("S");
106 : 0 : nr_double_t s1 = (s - W1) / 2;
107 : 0 : nr_double_t s2 = (s - W2) / 2;
108 : : nr_double_t a, c, c1, c2, x1, x2;
109 : 0 : nr_double_t o = 2 * M_PI * frequency;
110 [ # # ]: 0 : calcCends (frequency, c1, c2);
111 : 0 : x1 = c1 * s1;
112 : 0 : x2 = c2 * s2;
113 [ # # ]: 0 : a = s1 > s2 ? s2 / s1 : s1 / s2;
114 : 0 : c = M_1_PI * ((a * a + 1) / a * std::log ((1 + a) / (1 - a)) -
115 : 0 : 2 * std::log (4 * a / (1 - a * a)));
116 : 0 : c = c * (x1 + x2) / 2;
117 : 0 : return nr_complex_t (0, c * o);
118 : : }
119 : :
120 : 0 : void cpwstep::initDC (void) {
121 : 0 : setVoltageSources (1);
122 : 0 : setInternalVoltageSource (true);
123 : 0 : allocMatrixMNA ();
124 : 0 : voltageSource (VSRC_1, NODE_1, NODE_2);
125 : 0 : }
126 : :
127 : 0 : void cpwstep::initAC (void) {
128 : 0 : setVoltageSources (2);
129 : 0 : setInternalVoltageSource (true);
130 : 0 : allocMatrixMNA ();
131 [ # # ][ # # ]: 0 : setB (NODE_1, VSRC_1, +1.0); setB (NODE_1, VSRC_2, +0.0);
132 [ # # ][ # # ]: 0 : setB (NODE_2, VSRC_1, +0.0); setB (NODE_2, VSRC_2, +1.0);
133 [ # # ][ # # ]: 0 : setC (VSRC_1, NODE_1, -1.0); setC (VSRC_1, NODE_2, +0.0);
134 [ # # ][ # # ]: 0 : setC (VSRC_2, NODE_1, +0.0); setC (VSRC_2, NODE_2, -1.0);
135 [ # # ][ # # ]: 0 : setE (VSRC_1, +0.0); setE (VSRC_2, +0.0);
136 : 0 : checkProperties ();
137 : 0 : }
138 : :
139 : 0 : void cpwstep::calcAC (nr_double_t frequency) {
140 [ # # ][ # # ]: 0 : nr_complex_t z = 1.0 / calcY (frequency);
141 [ # # ][ # # ]: 0 : setD (VSRC_1, VSRC_1, z); setD (VSRC_2, VSRC_2, z);
142 [ # # ][ # # ]: 0 : setD (VSRC_1, VSRC_2, z); setD (VSRC_2, VSRC_1, z);
143 : 0 : }
144 : :
145 : : // properties
146 : : PROP_REQ [] = {
147 : : { "W1", PROP_REAL, { 1e-3, PROP_NO_STR }, PROP_POS_RANGE },
148 : : { "W2", PROP_REAL, { 2e-3, PROP_NO_STR }, PROP_POS_RANGE },
149 : : { "S", PROP_REAL, { 4e-3, PROP_NO_STR }, PROP_POS_RANGE },
150 : : { "Subst", PROP_STR, { PROP_NO_VAL, "Subst1" }, PROP_NO_RANGE },
151 : : PROP_NO_PROP };
152 : : PROP_OPT [] = {
153 : : { "Backside", PROP_STR, { PROP_NO_VAL, "Metal" },
154 : : PROP_RNG_STR2 ("Metal", "Air") },
155 : : PROP_NO_PROP };
156 : : struct define_t cpwstep::cirdef =
157 : : { "CSTEP", 2, PROP_COMPONENT, PROP_NO_SUBSTRATE, PROP_LINEAR, PROP_DEF };
|