Qucs-core  0.0.18
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups 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$
23  *
24  */
25 
26 #if HAVE_CONFIG_H
27 # include <config.h>
28 #endif
29 
30 #include "component.h"
31 #include "rectline.h"
32 
55 using namespace qucs;
56 
57 rectline::rectline () : circuit (2) {
58  alpha = beta = fc_low = fc_high = 0.0;
59  zl = 0.0;
61 }
62 
63 void rectline::calcResistivity (char * Mat, nr_double_t T) {
64  if (!strcmp (Mat, "Copper")) {
65  if (T < 7) {
66  rho = 2e-11;
67  }
68  else if (T < 15) {
69  rho = 6.66667e-17 * qucs::pow (T, 5.0) - 3.88549e-15 * qucs::pow (T, 4.0) +
70  9.82267e-14 * qucs::pow (T, 3.0) - 1.29684e-12 * qucs::pow (T, 2.0) +
71  8.68341e-12 * T - 2.72120e-12;
72  }
73  else if (T < 45) {
74  rho = 6.60731e-15 * qucs::pow (T, 3.0) - 1.14812e-13 * qucs::pow (T, 2.0) -
75  1.11681e-12 * T + 4.23709e-11;
76  }
77  else if (T < 100) {
78  rho = -6.53059e-15 * qucs::pow (T, 3.0) + 1.73783e-12 * qucs::pow (T, 2.0) -
79  8.73888e-11 * T + 1.37016e-9;
80  }
81  else if (T < 350) {
82  rho = 1.00018e-17 * qucs::pow (T, 3.0) - 8.72408e-15 * qucs::pow (T, 2.0) +
83  7.06020e-11 * T - 3.51125e-9;
84  }
85  else {
86  rho = 0.000000020628;
87  }
88  // in ADS iT_K is forced T_Ko Cu_300K:
89  //rho = 1.7e-8;
90  }
91  else if (!strcmp (Mat, "StainlessSteel")) {
92  rho = 7.4121e-17 * qucs::pow (T, 4.0) - 5.3504e-14 * qucs::pow (T, 3.0) +
93  1.2902e-11 * qucs::pow (T, 2.0) - 2.9186e-10 * T +4.9320e-7;
94  }
95  else if (!strcmp (Mat, "Gold")) {
96  if (T < 20) {
97  rho = 0.00000000024;
98  }
99  else if (T < 65) {
100  rho = 2e-12 * qucs::pow (T, 2.0) - 8e-11 * T + 1e-9;
101  }
102  else if (T < 80) {
103  rho = 5e-13 * qucs::pow (T, 3.0) - 1e-10 * qucs::pow (T, 2.0) + 9e-9 * T - 2e-7;
104  }
105  else if (T < 300) {
106  rho = 8e-11 * T - 1e-10;
107  }
108  else {
109  rho = 2.4e-8;
110  }
111  }
112 }
113 
153 void rectline::calcPropagation (nr_double_t frequency) {
154  nr_double_t er = getPropertyDouble ("er");
155  nr_double_t mur = getPropertyDouble ("mur");
156  nr_double_t tand = getPropertyDouble ("tand");
157  nr_double_t a = getPropertyDouble ("a");
158  nr_double_t b = getPropertyDouble ("b");
159 
160  /* wave number */
161  nr_double_t k0;
162  nr_double_t kc;
163  /* dielectric loss */
164  nr_double_t ad, ac, rs;
165 
166  // check cutoff frequency
167  if (frequency >= fc_high) {
168  logprint (LOG_ERROR, "WARNING: Operating frequency (%g) outside TE10 "
169  "band (%g <= TE10 <= %g) or outside non propagative mode "
170  "<= %g\n", frequency, fc_low, fc_high, fc_low);
171  }
172  // calculate wave number
173  k0 = (2.0 * M_PI * frequency * std::sqrt (er * mur)) / C0;
174  kc = M_PI / a;
175 
176  // calculate losses only for propagative mode
177  if (frequency >= fc_low) {
178  // calculate beta
179  beta = std::sqrt (sqr (k0) - sqr (kc));
180 
181  // dielectric
182  ad = (sqr(k0) * tand) / (2.0 * beta);
183  // resistive
184  rs = std::sqrt (M_PI * frequency * mur * MU0 * rho);
185  ac = rs * (2.0 * b * sqr (M_PI) + cubic (a) * sqr (k0)) /
186  (cubic (a) * b * beta * k0 * Z0);
187  alpha = (ad + ac);
188 
189  // wave impedance
190  zl = (k0 * Z0) / beta;
191 
192  } else {
193  /* according to [2] eq 3.207 */
194  beta = 0;
195  alpha = -std::sqrt (- (sqr (k0) - sqr (kc)));
196  // wave impedance
197  zl = (k0 * Z0) / nr_complex_t (0, -alpha) ;
198  }
199 }
200 
202 void rectline::calcNoiseSP (nr_double_t) {
203  nr_double_t l = getPropertyDouble ("L");
204  if (l < 0) return;
205  // calculate noise using Bosma's theorem
206  nr_double_t T = getPropertyDouble ("Temp");
207  matrix s = getMatrixS ();
208  matrix e = eye (getSize ());
209  setMatrixN (kelvin (T) / T0 * (e - s * transpose (conj (s))));
210 }
211 
215 void rectline::initCheck (void) {
216  nr_double_t a = getPropertyDouble ("a");
217  nr_double_t b = getPropertyDouble ("b");
218  nr_double_t epsr = getPropertyDouble ("er");
219  nr_double_t mur = getPropertyDouble ("mur");
220  // check validity
221  if (a < b) {
222  logprint (LOG_ERROR, "ERROR: a < b should be a >= b.\n");
223  }
224  nr_double_t c = std::sqrt (epsr * mur);
225  fc_low = C0 / (2.0 * a * c);
226  /* min of second TE mode and first TM mode */
227  fc_high = MIN (C0 / (a * c), C0 / (2.0 * b * c));
228  // calculation of resistivity
229  rho = getPropertyDouble ("rho");
230  nr_double_t T = getPropertyDouble ("Temp");
231  calcResistivity (getPropertyString ("Material"), kelvin (T));
232 }
233 
235  setCharacteristic ("Zl", real (zl));
236 }
237 
239 void rectline::initSP (void) {
240  // allocate S-parameter matrix
241  allocMatrixS ();
242  initCheck ();
243 }
244 
246 void rectline::calcSP (nr_double_t frequency) {
247  nr_double_t l = getPropertyDouble ("L");
248 
249  // calculate propagation constants
250  calcPropagation (frequency);
251 
252  // calculate S-parameters
253  nr_complex_t z = zl / z0;
254  nr_complex_t y = 1.0 / z;
255  nr_complex_t g = nr_complex_t (alpha, beta);
256  nr_complex_t n = 2.0 * cosh (g * l) + (z + y) * sinh (g * l);
257  nr_complex_t s11 = (z - y) * sinh (g * l) / n;
258  nr_complex_t s21 = 2.0 / n;
259  setS (NODE_1, NODE_1, s11); setS (NODE_2, NODE_2, s11);
260  setS (NODE_1, NODE_2, s21); setS (NODE_2, NODE_1, s21);
261 }
262 
263 /* ! Compute DC
264  \note below cut off it is an open circuit
265 */
266 void rectline::initDC (void) {
267  allocMatrixMNA ();
268  // open circuit
269  clearY ();
270 }
271 
273 void rectline::initAC (void) {
274  setVoltageSources (0);
275  allocMatrixMNA ();
276  initCheck ();
277 }
278 
280 void rectline::calcAC (nr_double_t frequency) {
281  nr_double_t l = getPropertyDouble ("L");
282 
283  // calculate propagation constants
284  calcPropagation (frequency);
285 
286  // calculate Y-parameters
287  nr_complex_t g = nr_complex_t (alpha, beta);
288  nr_complex_t y11 = coth (g * l) / zl;
289  nr_complex_t y21 = -cosech (g * l) / zl;
290  setY (NODE_1, NODE_1, y11); setY (NODE_2, NODE_2, y11);
291  setY (NODE_1, NODE_2, y21); setY (NODE_2, NODE_1, y21);
292 }
293 
295 void rectline::calcNoiseAC (nr_double_t) {
296  nr_double_t l = getPropertyDouble ("L");
297  if (l < 0) return;
298  // calculate noise using Bosma's theorem
299  nr_double_t T = getPropertyDouble ("Temp");
300  setMatrixN (4.0 * kelvin (T) / T0 * real (getMatrixY ()));
301 }
302 
303 // properties
304 PROP_REQ [] = {
305  { "a", PROP_REAL, { 2.86e-2, PROP_NO_STR }, PROP_POS_RANGEX },
306  { "b", PROP_REAL, { 1.016e-2, PROP_NO_STR }, PROP_POS_RANGEX },
307  { "L", PROP_REAL, { 1500e-3, PROP_NO_STR }, PROP_NO_RANGE },
308  { "er", PROP_REAL, { 1, PROP_NO_STR }, PROP_RNGII (1, 100) },
309  { "mur", PROP_REAL, { 1, PROP_NO_STR }, PROP_RNGII (1, 100) },
310  { "tand", PROP_REAL, { 4e-4, PROP_NO_STR }, PROP_POS_RANGE },
311  { "rho", PROP_REAL, { 0.022e-6, PROP_NO_STR }, PROP_POS_RANGE },
312  PROP_NO_PROP };
313 PROP_OPT [] = {
314  { "Temp", PROP_REAL, { 26.85, PROP_NO_STR }, PROP_MIN_VAL (K) },
315  { "Material", PROP_STR, { PROP_NO_VAL, "unspecified" },
316  PROP_RNG_STR4 ("unspecified", "Copper", "StainlessSteel", "Gold") },
317  PROP_NO_PROP };
318 struct define_t rectline::cirdef =
std::complex< nr_double_t > nr_complex_t
Definition: complex.h:31
#define MU0
magnetic constant of vacuum ( )
Definition: constants.h:49
#define PROP_POS_RANGE
Definition: netdefs.h:129
l
Definition: parse_vcd.y:213
#define NODE_2
Definition: circuit.h:35
matrix real(matrix a)
Real part matrix.
Definition: matrix.cpp:568
#define T0
standard temperature
Definition: constants.h:61
#define PROP_RNGII(f, t)
Definition: netdefs.h:138
#define kelvin(x)
Definition: constants.h:108
#define PROP_DEF
Definition: netdefs.h:189
nr_complex_t coth(const nr_complex_t z)
Compute complex hyperbolic cotangent.
Definition: complex.cpp:320
PROP_OPT[]
Definition: acsolver.cpp:232
nr_complex_t pow(const nr_complex_t z, const nr_double_t d)
Compute power function with real exponent.
Definition: complex.cpp:238
#define PROP_REAL
Definition: netdefs.h:174
void initCheck(void)
Definition: rectline.cpp:215
#define PROP_NO_PROP
Definition: netdefs.h:122
#define K
Absolute 0 in centigrade.
Definition: constants.h:59
#define PROP_NO_RANGE
Definition: netdefs.h:126
#define PROP_NO_STR
Definition: netdefs.h:125
n
Definition: parse_citi.y:147
#define PROP_LINEAR
Definition: netdefs.h:120
nr_complex_t cosh(const nr_complex_t z)
Compute complex hyperbolic cosine.
Definition: complex.cpp:135
nr_complex_t sqr(const nr_complex_t z)
Square of complex number.
Definition: complex.cpp:673
nr_complex_t sqrt(const nr_complex_t z)
Compute principal value of square root.
Definition: complex.cpp:271
nr_complex_t cosech(const nr_complex_t z)
Compute complex argument hyperbolic cosec.
Definition: complex.cpp:364
#define PROP_COMPONENT
Definition: netdefs.h:116
void calcResistivity(char *, nr_double_t)
Definition: rectline.cpp:63
#define M_PI
Archimedes' constant ( )
Definition: consts.h:47
matrix transpose(matrix a)
Matrix transposition.
Definition: matrix.cpp:492
#define PROP_RNG_STR4(s1, s2, s3, s4)
Definition: netdefs.h:149
void calcPropagation(nr_double_t)
Definition: rectline.cpp:153
void calcNoiseAC(nr_double_t)
Definition: rectline.cpp:295
type
Definition: parse_vcd.y:164
#define PROP_MIN_VAL(k)
Definition: netdefs.h:133
void calcAC(nr_double_t)
Definition: rectline.cpp:280
#define MIN(x, y)
Minimum of x and y.
Definition: constants.h:132
void initAC(void)
Definition: rectline.cpp:273
nr_complex_t sinh(const nr_complex_t z)
Compute complex hyperbolic sine.
Definition: complex.cpp:144
#define PROP_POS_RANGEX
Definition: netdefs.h:131
#define PROP_STR
Definition: netdefs.h:175
void initDC(void)
Definition: rectline.cpp:266
void saveCharacteristics(nr_complex_t)
Definition: rectline.cpp:234
y
Definition: parse_mdl.y:499
#define NODE_1
Definition: circuit.h:34
#define C0
speed of light in vacuum ( )
Definition: constants.h:47
matrix eye(int rs, int cs)
Create identity matrix with specified number of rows and columns.
Definition: matrix.cpp:603
#define LOG_ERROR
Definition: logging.h:28
void calcSP(nr_double_t)
Definition: rectline.cpp:246
matrix conj(matrix a)
Conjugate complex matrix.
Definition: matrix.cpp:505
#define PROP_NO_VAL
Definition: netdefs.h:124
PROP_REQ[]
Definition: acsolver.cpp:229
void logprint(int level, const char *format,...)
Definition: logging.c:37
#define Z0
Wave impedance in vacuum ( )
Definition: constants.h:53
#define cubic(x)
Definition: constants.h:106
#define PROP_NO_SUBSTRATE
Definition: netdefs.h:118
void initSP(void)
Definition: rectline.cpp:239
void calcNoiseSP(nr_double_t)
Definition: rectline.cpp:202