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