KiCad PCB EDA Suite
rectwaveguide.cpp
Go to the documentation of this file.
1/*
2 * rectwaveguide.cpp - rectangular waveguide class implementation
3 *
4 * Copyright (C) 2001 Gopal Narayanan <[email protected]>
5 * Copyright (C) 2005, 2006 Stefan Jahn <[email protected]>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program 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 */
23
24#include <cmath>
25#include <cstdio>
26#include <cstring>
27
28#include "rectwaveguide.h"
29#include "units.h"
30
32 mur( 0.0 ), // magnetic permeability of substrate
33 a( 0.0 ), // width of waveguide
34 b( 0.0 ), // height of waveguide
35 l( 0.0 ), // length of waveguide
36 Z0( 0.0 ), // characteristic impedance
37 Z0EH( 0.0 ), // characteristic impedance of field quantities*/
38 mur_eff( 0.0 ), // Effective mag. permeability
39 atten_dielectric( 0.0 ), // Loss in dielectric (dB)
40 atten_cond( 0.0 ), // Loss in conductors (dB)
41 fc10( 1.0 ) // Cutoff frequency for TE10 mode
42{
43 m_Name = "RectWaveGuide";
44 Init();
45}
46
47
48/*
49 * returns square of k
50 */
52{
53 double kval;
54
55 kval = 2.0 * M_PI * m_parameters[FREQUENCY_PRM]
57
58 return kval * kval;
59}
60
61
62/*
63 * given mode numbers m and n
64 * returns square of cutoff kc value
65 */
66double RECTWAVEGUIDE::kc_square( int m, int n )
67{
68 return pow( ( m * M_PI / m_parameters[PHYS_A_PRM] ), 2.0 )
69 + pow( ( n * M_PI / m_parameters[PHYS_B_PRM] ), 2.0 );
70}
71
72
73/*
74 * given mode numbers m and n
75 * returns cutoff fc value
76 */
77double RECTWAVEGUIDE::fc( int m, int n )
78{
79 return sqrt( kc_square( m, n ) / m_parameters[MUR_PRM] / m_parameters[EPSILONR_PRM] ) * C0 / 2.0
80 / M_PI;
81}
82
83
84/*
85 * alphac - returns attenuation due to conductor losses for all propagating
86 * modes in the waveguide
87 */
89{
90 double Rs, f_c;
91 double ac;
92 short m, n, mmax, nmax;
93 double* a = &m_parameters[PHYS_A_PRM];
94 double* b = &m_parameters[PHYS_B_PRM];
95 double* f = &m_parameters[FREQUENCY_PRM];
96 double* murc = &m_parameters[MURC_PRM];
97 double* sigma = &m_parameters[SIGMA_PRM];
98
99 Rs = sqrt( M_PI * *f * *murc * MU0 / *sigma );
100 ac = 0.0;
101 mmax = (int) floor( *f / fc( 1, 0 ) );
102 nmax = mmax;
103
104 /* below from Ramo, Whinnery & Van Duzer */
105
106 /* TE(m,n) modes */
107 for( n = 0; n <= nmax; n++ )
108 {
109 for( m = 1; m <= mmax; m++ )
110 {
111 f_c = fc( m, n );
112
113 if( *f > f_c )
114 {
115 switch( n )
116 {
117 case 0:
118 ac += ( Rs / ( *b * ZF0 * sqrt( 1.0 - pow( ( f_c / *f ), 2.0 ) ) ) )
119 * ( 1.0 + ( ( 2 * *b / *a ) * pow( ( f_c / *f ), 2.0 ) ) );
120 break;
121
122 default:
123 ac += ( ( 2. * Rs ) / ( *b * ZF0 * sqrt( 1.0 - pow( ( f_c / *f ), 2.0 ) ) ) )
124 * ( ( ( 1. + ( *b / *a ) ) * pow( ( f_c / *f ), 2.0 ) )
125 + ( ( 1. - pow( ( f_c / *f ), 2.0 ) )
126 * ( ( ( *b / *a )
127 * ( ( ( *b / *a ) * pow( m, 2. ) )
128 + pow( n, 2. ) ) )
129 / ( pow( ( *b * m / *a ), 2.0 )
130 + pow( n, 2.0 ) ) ) ) );
131 break;
132 }
133 }
134 }
135 }
136
137 /* TM(m,n) modes */
138 for( n = 1; n <= nmax; n++ )
139 {
140 for( m = 1; m <= mmax; m++ )
141 {
142 f_c = fc( m, n );
143
144 if( *f > f_c )
145 {
146 ac += ( ( 2. * Rs ) / ( *b * ZF0 * sqrt( 1.0 - pow( ( f_c / *f ), 2.0 ) ) ) )
147 * ( ( ( pow( m, 2.0 ) * pow( ( *b / *a ), 3.0 ) ) + pow( n, 2. ) )
148 / ( ( pow( ( m * *b / *a ), 2. ) ) + pow( n, 2.0 ) ) );
149 }
150 }
151 }
152
153 ac = ac * 20.0 * log10( exp( 1. ) ); /* convert from Np/m to db/m */
154 return ac;
155}
156
157
158/*
159 * alphac_cutoff - returns attenuation for a cutoff wg
160 */
162{
163 double acc;
164
165 acc = sqrt( kc_square( 1, 0 ) - kval_square() );
166 acc = 20 * log10( exp( 1.0 ) ) * acc;
167 return acc;
168}
169
170
171/*
172 * returns attenuation due to dielectric losses
173 */
175{
176 double k_square, beta;
177 double ad;
178
179 k_square = kval_square();
180 beta = sqrt( k_square - kc_square( 1, 0 ) );
181
182 ad = ( k_square * m_parameters[TAND_PRM] ) / ( 2.0 * beta );
183 ad = ad * 20.0 * log10( exp( 1. ) ); /* convert from Np/m to db/m */
184 return ad;
185}
186
187
188/*
189 * get_rectwaveguide_sub
190 * get and assign rectwaveguide substrate parameters
191 * into rectwaveguide structure
192 */
194{
200}
201
202
203/*
204 * get_rectwaveguide_comp
205 * get and assign rectwaveguide component parameters
206 * into rectwaveguide structure
207 */
209{
211}
212
213
214/*
215 * get_rectwaveguide_elec
216 * get and assign rectwaveguide electrical parameters
217 * into rectwaveguide structure
218 */
220{
223}
224
225
226/*
227 * get_rectwaveguide_phys
228 * get and assign rectwaveguide physical parameters
229 * into rectwaveguide structure
230 */
232{
236}
237
238
239/*
240 * analyze - analysis function
241 * source: https://empossible.net/wp-content/uploads/2018/03/Lecture-5c-Rectangular-waveguide.pdf
242 */
244{
245 double lambda_g;
246 double k_square;
247
248 k_square = kval_square();
249
250 if( kc_square( 1, 0 ) <= k_square )
251 {
252 /* propagating modes */
253
254 // Z0 definition using fictive voltages and currents
257 / sqrt( 1.0 - pow( ( fc( 1, 0 ) / m_parameters[FREQUENCY_PRM] ), 2.0 ) );
258
259 /* calculate electrical angle */
260 lambda_g = 2.0 * M_PI / sqrt( k_square - kc_square( 1, 0 ) );
262 2.0 * M_PI * m_parameters[PHYS_LEN_PRM] / lambda_g; /* in radians */
266 ( 1.0 - pow( fc( 1, 0 ) / m_parameters[FREQUENCY_PRM], 2.0 ) );
267 }
268 else
269 {
270 /* evanascent modes */
271 m_parameters[Z0_PRM] = 0;
276 }
277}
278
279/*
280 * synthesize - synthesis function
281 * source: re-arrangment of calcAnalyze equation
282 * TE10 (via fc(1,0) ) results in the b term not influencing the result, as long as
283 * 1) fc > f
284 * 2) a > b
285 */
287{
288 double lambda_g, k_square, beta;
289 /* solve for a */
291 C0
292 / ( sqrt( ( m_parameters[MUR_PRM] * m_parameters[EPSILONR_PRM] ) ) * 2
293 * m_parameters[FREQUENCY_PRM] * sqrt( 1
294 - pow( ( ZF0 * sqrt( m_parameters[MUR_PRM]
297 ,2.0 ) ) );
298
299 k_square = kval_square();
300 beta = sqrt( k_square - kc_square( 1, 0 ) );
301 lambda_g = 2.0 * M_PI / beta;
302 m_parameters[PHYS_LEN_PRM] = ( m_parameters[ANG_L_PRM] * lambda_g ) / ( 2.0 * M_PI ); /* in m */
303
304 if( kc_square( 1, 0 ) <= k_square )
305 {
306 /*propagating modes */
307 beta = sqrt( k_square - kc_square( 1, 0 ) );
308 lambda_g = 2.0 * M_PI / beta;
312 ( 1.0 - pow( ( fc( 1, 0 ) / m_parameters[FREQUENCY_PRM] ), 2.0 ) );
313 }
314 else
315 {
316 /*evanascent modes */
317 m_parameters[Z0_PRM] = 0;
322 }
323}
324
326{
327 if( isSelected( PHYS_A_PRM ) )
329
330 if( isSelected( PHYS_B_PRM ) )
332
334
335 // Check for errors
336 if( !std::isfinite( m_parameters[PHYS_A_PRM] ) || m_parameters[PHYS_A_PRM] <= 0 )
338
339 if( !std::isfinite( m_parameters[PHYS_B_PRM] ) || m_parameters[PHYS_B_PRM] <= 00 )
341
342 // Check for warnings
343 if( !std::isfinite( m_parameters[Z0_PRM] ) || m_parameters[Z0_PRM] < 0 )
345
346 if( !std::isfinite( m_parameters[ANG_L_PRM] ) || m_parameters[ANG_L_PRM] < 0 )
348}
349
350
352{
355
356 // Check for errors
357 if( !std::isfinite( m_parameters[Z0_PRM] ) || m_parameters[Z0_PRM] < 0 )
359
360 if( !std::isfinite( m_parameters[ANG_L_PRM] ) || m_parameters[ANG_L_PRM] < 0 )
362
363 // Check for warnings
364 if( !std::isfinite( m_parameters[PHYS_A_PRM] ) || m_parameters[PHYS_A_PRM] <= 0 )
366
367 if( !std::isfinite( m_parameters[PHYS_B_PRM] ) || m_parameters[PHYS_B_PRM] <= 00 )
369}
370
371
372#define MAXSTRLEN 128
374{
375 int m, n, max = 6;
376 char text[MAXSTRLEN], txt[32];
377
378 // Z0EH = Ey / Hx (definition with field quantities)
379 Z0EH = ZF0 * sqrt( kval_square() / ( kval_square() - kc_square( 1, 0 ) ) );
380 setResult( 0, Z0EH, "Ohm" );
381
385
386 // show possible TE modes (H modes)
387 if( m_parameters[FREQUENCY_PRM] < fc( 1, 0 ) )
388 {
389 strcpy( text, "none" );
390 }
391 else
392 {
393 strcpy( text, "" );
394 for( m = 0; m <= max; m++ )
395 {
396 for( n = 0; n <= max; n++ )
397 {
398 if( ( m == 0 ) && ( n == 0 ) )
399 continue;
400
401 if( m_parameters[FREQUENCY_PRM] >= ( fc( m, n ) ) )
402 {
403 sprintf( txt, "H(%d,%d) ", m, n );
404 if( ( strlen( text ) + strlen( txt ) + 5 ) < MAXSTRLEN )
405 {
406 strcat( text, txt );
407 }
408 else
409 {
410 strcat( text, "..." );
411 m = n = max + 1; // print no more modes
412 }
413 }
414 }
415 }
416 }
417 setResult( 4, text );
418
419 // show possible TM modes (E modes)
420 if( m_parameters[FREQUENCY_PRM] < fc( 1, 1 ) )
421 {
422 strcpy( text, "none" );
423 }
424 else
425 {
426 strcpy( text, "" );
427 for( m = 1; m <= max; m++ )
428 {
429 for( n = 1; n <= max; n++ )
430 {
431 if( m_parameters[FREQUENCY_PRM] >= fc( m, n ) )
432 {
433 sprintf( txt, "E(%d,%d) ", m, n );
434 if( ( strlen( text ) + strlen( txt ) + 5 ) < MAXSTRLEN )
435 {
436 strcat( text, txt );
437 }
438 else
439 {
440 strcat( text, "..." );
441 m = n = max + 1; // print no more modes
442 }
443 }
444 }
445 }
446 }
447 setResult( 5, text );
448}
double kc_square(int, int)
double kval_square()
double fc(int, int)
void get_rectwaveguide_comp()
void calcSynthesize() override
Computation for synthesis.
void get_rectwaveguide_phys()
double alphac_cutoff()
void get_rectwaveguide_sub()
void get_rectwaveguide_elec()
void show_results() override
Shows results.
void calcAnalyze() override
Computation for analysis.
void showSynthesize() override
Shows analysis results and checks for errors / warnings.
void showAnalyze() override
Shows synthesis results and checks for errors / warnings.
bool isSelected(enum PRMS_ID aPrmId)
Definition: transline.cpp:119
double getProperty(enum PRMS_ID aPrmId)
Definition: transline.cpp:140
void Init()
Definition: transline.cpp:90
void setResult(int, double, const char *)
Definition: transline.cpp:133
double m_parameters[EXTRA_PRMS_COUNT]
Definition: transline.h:131
const char * m_Name
Definition: transline.h:84
void setProperty(enum PRMS_ID aPrmId, double aValue)
Definition: transline.cpp:109
void setErrorLevel(PRMS_ID, char)
@function setErrorLevel
Definition: transline.cpp:435
#define MAXSTRLEN
#define PHYS_B_PRM
Definition: rectwaveguide.h:31
#define PHYS_A_PRM
Definition: rectwaveguide.h:30
@ LOSS_DIELECTRIC_PRM
Definition: transline.h:71
@ EPSILON_EFF_PRM
Definition: transline.h:74
@ LOSS_CONDUCTOR_PRM
Definition: transline.h:72
@ SIGMA_PRM
Definition: transline.h:69
@ FREQUENCY_PRM
Definition: transline.h:51
@ RHO_PRM
Definition: transline.h:41
@ MURC_PRM
Definition: transline.h:50
@ MUR_PRM
Definition: transline.h:48
@ Z0_PRM
Definition: transline.h:52
@ TAND_PRM
Definition: transline.h:40
@ PHYS_LEN_PRM
Definition: transline.h:60
@ ANG_L_PRM
Definition: transline.h:55
@ EPSILONR_PRM
Definition: transline.h:39
#define TRANSLINE_WARNING
Definition: transline.h:30
#define TRANSLINE_ERROR
Definition: transline.h:31
#define ZF0
Definition: units.h:62
#define MU0
Definition: units.h:60
#define C0
Definition: units.h:61