My Project  0.0.16
QUCS Mapping
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
rectline.cpp
Go to the documentation of this file.
1 /*
2  * rectline.cpp - rectangular waveguide class implementation
3  *
4  * Copyright (C) 2008 Bastien ROUCARIES <roucaries.bastien@gmail.com>
5  * Copyright (C) 2008 Andrea Zonca <andrea.zonca@gmail.com>
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: rectline.cpp 1825 2011-03-11 20:42:14Z ela $
23  *
24  */
25 
26 #if HAVE_CONFIG_H
27 # include <config.h>
28 #endif
29 
30 #include "component.h"
31 #include "rectline.h"
32 
54 rectline::rectline () : circuit (2) {
55  alpha = beta = fc_low = fc_high = 0.0;
56  zl = 0.0;
57  type = CIR_RECTANGULAR;
58 }
59 
60 void rectline::calcResistivity (char * Mat, nr_double_t T) {
61  if (!strcmp (Mat, "Copper")) {
62  if (T < 7) {
63  rho = 2e-11;
64  }
65  else if (T < 15) {
66  rho = 6.66667e-17 * pow (T, 5) - 3.88549e-15 * pow (T, 4) +
67  9.82267e-14 * pow (T, 3) - 1.29684e-12 * pow (T, 2) +
68  8.68341e-12 * T - 2.72120e-12;
69  }
70  else if (T < 45) {
71  rho = 6.60731e-15 * pow (T, 3) - 1.14812e-13 * pow (T, 2) -
72  1.11681e-12 * T + 4.23709e-11;
73  }
74  else if (T < 100) {
75  rho = -6.53059e-15 * pow (T, 3) + 1.73783e-12 * pow (T, 2) -
76  8.73888e-11 * T + 1.37016e-9;
77  }
78  else if (T < 350) {
79  rho = 1.00018e-17 * pow (T, 3) - 8.72408e-15 * pow (T, 2) +
80  7.06020e-11 * T - 3.51125e-9;
81  }
82  else {
83  rho = 0.000000020628;
84  }
85  // in ADS iT_K is forced T_Ko Cu_300K:
86  //rho = 1.7e-8;
87  }
88  else if (!strcmp (Mat, "StainlessSteel")) {
89  rho = 7.4121e-17 * pow (T, 4) - 5.3504e-14 * pow (T, 3) +
90  1.2902e-11 * pow (T, 2) - 2.9186e-10 * T +4.9320e-7;
91  }
92  else if (!strcmp (Mat, "Gold")) {
93  if (T < 20) {
94  rho = 0.00000000024;
95  }
96  else if (T < 65) {
97  rho = 2e-12 * pow (T, 2) - 8e-11 * T + 1e-9;
98  }
99  else if (T < 80) {
100  rho = 5e-13 * pow (T, 3) - 1e-10 * pow (T, 2) + 9e-9 * T - 2e-7;
101  }
102  else if (T < 300) {
103  rho = 8e-11 * T - 1e-10;
104  }
105  else {
106  rho = 2.4e-8;
107  }
108  }
109 }
110 
150 void rectline::calcPropagation (nr_double_t frequency) {
151  nr_double_t er = getPropertyDouble ("er");
152  nr_double_t mur = getPropertyDouble ("mur");
153  nr_double_t tand = getPropertyDouble ("tand");
154  nr_double_t a = getPropertyDouble ("a");
155  nr_double_t b = getPropertyDouble ("b");
156 
157  /* wave number */
158  nr_double_t k0;
159  nr_double_t kc;
160  /* dielectric loss */
161  nr_double_t ad, ac, rs;
162 
163  // check cutoff frequency
164  if (frequency >= fc_high) {
165  logprint (LOG_ERROR, "WARNING: Operating frequency (%g) outside TE10 "
166  "band (%g <= TE10 <= %g) or outside non propagative mode "
167  "<= %g\n", frequency, fc_low, fc_high, fc_low);
168  }
169  // calculate wave number
170  k0 = (2.0 * M_PI * frequency * sqrt (er * mur)) / C0;
171  kc = M_PI / a;
172 
173  // calculate losses only for propagative mode
174  if (frequency >= fc_low) {
175  // calculate beta
176  beta = sqrt (sqr (k0) - sqr (kc));
177 
178  // dielectric
179  ad = (sqr(k0) * tand) / (2.0 * beta);
180  // resistive
181  rs = sqrt (M_PI * frequency * mur * MU0 * rho);
182  ac = rs * (2.0 * b * sqr (M_PI) + cubic (a) * sqr (k0)) /
183  (cubic (a) * b * beta * k0 * Z0);
184  alpha = (ad + ac);
185 
186  // wave impedance
187  zl = (k0 * Z0) / beta;
188 
189  } else {
190  /* according to [2] eq 3.207 */
191  beta = 0;
192  alpha = -sqrt (- (sqr (k0) - sqr (kc)));
193  // wave impedance
194  zl = (k0 * Z0) / rect (0, -alpha) ;
195  }
196 }
197 
199 void rectline::calcNoiseSP (nr_double_t) {
200  nr_double_t l = getPropertyDouble ("L");
201  if (l < 0) return;
202  // calculate noise using Bosma's theorem
203  nr_double_t T = getPropertyDouble ("Temp");
204  matrix s = getMatrixS ();
205  matrix e = eye (getSize ());
206  setMatrixN (kelvin (T) / T0 * (e - s * transpose (conj (s))));
207 }
208 
212 void rectline::initCheck (void) {
213  nr_double_t a = getPropertyDouble ("a");
214  nr_double_t b = getPropertyDouble ("b");
215  nr_double_t epsr = getPropertyDouble ("er");
216  nr_double_t mur = getPropertyDouble ("mur");
217  // check validity
218  if (a < b) {
219  logprint (LOG_ERROR, "ERROR: a < b should be a >= b.\n");
220  }
221  nr_double_t c = sqrt (epsr * mur);
222  fc_low = C0 / (2.0 * a * c);
223  /* min of second TE mode and first TM mode */
224  fc_high = MIN (C0 / (a * c), C0 / (2.0 * b * c));
225  // calculation of resistivity
226  rho = getPropertyDouble ("rho");
227  nr_double_t T = getPropertyDouble ("Temp");
228  calcResistivity (getPropertyString ("Material"), kelvin (T));
229 }
230 
232  setCharacteristic ("Zl", real (zl));
233 }
234 
236 void rectline::initSP (void) {
237  // allocate S-parameter matrix
238  allocMatrixS ();
239  initCheck ();
240 }
241 
243 void rectline::calcSP (nr_double_t frequency) {
244  nr_double_t l = getPropertyDouble ("L");
245 
246  // calculate propagation constants
247  calcPropagation (frequency);
248 
249  // calculate S-parameters
250  nr_complex_t z = zl / z0;
251  nr_complex_t y = 1.0 / z;
252  nr_complex_t g = rect (alpha, beta);
253  nr_complex_t n = 2.0 * cosh (g * l) + (z + y) * sinh (g * l);
254  nr_complex_t s11 = (z - y) * sinh (g * l) / n;
255  nr_complex_t s21 = 2.0 / n;
256  setS (NODE_1, NODE_1, s11); setS (NODE_2, NODE_2, s11);
257  setS (NODE_1, NODE_2, s21); setS (NODE_2, NODE_1, s21);
258 }
259 
260 /* ! Compute DC
261  \note below cut off it is an open circuit
262 */
263 void rectline::initDC (void) {
264  allocMatrixMNA ();
265  // open circuit
266  clearY ();
267 }
268 
270 void rectline::initAC (void) {
271  setVoltageSources (0);
272  allocMatrixMNA ();
273  initCheck ();
274 }
275 
277 void rectline::calcAC (nr_double_t frequency) {
278  nr_double_t l = getPropertyDouble ("L");
279 
280  // calculate propagation constants
281  calcPropagation (frequency);
282 
283  // calculate Y-parameters
284  nr_complex_t g = rect (alpha, beta);
285  nr_complex_t y11 = coth (g * l) / zl;
286  nr_complex_t y21 = -cosech (g * l) / zl;
287  setY (NODE_1, NODE_1, y11); setY (NODE_2, NODE_2, y11);
288  setY (NODE_1, NODE_2, y21); setY (NODE_2, NODE_1, y21);
289 }
290 
292 void rectline::calcNoiseAC (nr_double_t) {
293  nr_double_t l = getPropertyDouble ("L");
294  if (l < 0) return;
295  // calculate noise using Bosma's theorem
296  nr_double_t T = getPropertyDouble ("Temp");
297  setMatrixN (4.0 * kelvin (T) / T0 * real (getMatrixY ()));
298 }
299 
300 // properties
301 PROP_REQ [] = {
302  { "a", PROP_REAL, { 2.86e-2, PROP_NO_STR }, PROP_POS_RANGEX },
303  { "b", PROP_REAL, { 1.016e-2, PROP_NO_STR }, PROP_POS_RANGEX },
304  { "L", PROP_REAL, { 1500e-3, PROP_NO_STR }, PROP_NO_RANGE },
305  { "er", PROP_REAL, { 1, PROP_NO_STR }, PROP_RNGII (1, 100) },
306  { "mur", PROP_REAL, { 1, PROP_NO_STR }, PROP_RNGII (1, 100) },
307  { "tand", PROP_REAL, { 4e-4, PROP_NO_STR }, PROP_POS_RANGE },
308  { "rho", PROP_REAL, { 0.022e-6, PROP_NO_STR }, PROP_POS_RANGE },
309  PROP_NO_PROP };
310 PROP_OPT [] = {
311  { "Temp", PROP_REAL, { 26.85, PROP_NO_STR }, PROP_MIN_VAL (K) },
312  { "Material", PROP_STR, { PROP_NO_VAL, "unspecified" },
313  PROP_RNG_STR4 ("unspecified", "Copper", "StainlessSteel", "Gold") },
314  PROP_NO_PROP };
315 struct define_t rectline::cirdef =