KiCad PCB EDA Suite
c_microstrip.cpp
Go to the documentation of this file.
1 /*
2  * c_microstrip.cpp - coupled microstrip class implementation
3  *
4  * Copyright (C) 2002 Claudio Girardi <[email protected]>
5  * Copyright (C) 2005, 2006 Stefan Jahn <[email protected]>
6  *
7  * This program 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 of the License, or (at
10  * your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * 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 /* c_microstrip.c - Puts up window for coupled microstrips and
25  * performs the associated calculations
26  * Based on the original microstrip.c by Gopal Narayanan
27  */
28 
29 #include <cmath>
30 #include <cstdio>
31 #include <cstdlib>
32 #include <cstring>
33 
34 #include "c_microstrip.h"
35 #include "microstrip.h"
36 #include "transline.h"
37 #include "units.h"
38 
40  h( 0.0 ), // height of substrate
41  ht( 0.0 ), // height to the top of box
42  t( 0.0 ), // thickness of top metal
43  rough( 0.0 ), // Roughness of top metal
44  w( 0.0 ), // width of lines
45  w_t_e( 0.0 ), // even-mode thickness-corrected line width
46  w_t_o( 0.0 ), // odd-mode thickness-corrected line width
47  l( 0.0 ), // length of lines
48  s( 0.0 ), // spacing of lines
49  Z0_e_0( 0.0 ), // static even-mode impedance
50  Z0_o_0( 0.0 ), // static odd-mode impedance
51  Zdiff( 0.0), // differential impedance
52  Z0e( 0.0 ), // even-mode impedance
53  Z0o( 0.0 ), // odd-mode impedance
54  c_e( 0.0 ), // even-mode capacitance
55  c_o( 0.0 ), // odd-mode capacitance
56  ang_l_e( 0.0 ), // even-mode electrical length in angle
57  ang_l_o( 0.0 ), // odd-mode electrical length in angle
58  er_eff_e( 0.0 ), // even-mode effective dielectric constant
59  er_eff_o( 0.0 ), // odd-mode effective dielectric constant
60  er_eff_e_0( 0.0 ), // static even-mode effective dielectric constant
61  er_eff_o_0( 0.0 ), // static odd-mode effective dielectric constant
62  w_eff( 0.0 ), // Effective width of line
63  atten_dielectric_e( 0.0 ), // even-mode dielectric losses (dB)
64  atten_cond_e( 0.0 ), // even-mode conductors losses (dB)
65  atten_dielectric_o( 0.0 ), // odd-mode dielectric losses (dB)
66  atten_cond_o( 0.0 ), // odd-mode conductors losses (dB)
67  aux_ms( nullptr )
68 {
69  m_Name = "Coupled_MicroStrip";
70  Init();
71 }
72 
73 
75 {
76  delete aux_ms;
77 }
78 
79 
80 /*
81  * delta_u_thickness_single() computes the thickness effect on
82  * normalized width for a single microstrip line
83  *
84  * References: H. A. Atwater, "Simplified Design Equations for
85  * Microstrip Line Parameters", Microwave Journal, pp. 109-115,
86  * November 1989.
87  */
88 double C_MICROSTRIP::delta_u_thickness_single( double u, double t_h )
89 {
90  double delta_u;
91 
92  if( t_h > 0.0 )
93  {
94  delta_u =
95  (1.25 * t_h /
96  M_PI) *
97  ( 1.0 +
98  log( ( 2.0 +
99  (4.0 * M_PI * u -
100  2.0) / ( 1.0 + exp( -100.0 * ( u - 1.0 / (2.0 * M_PI) ) ) ) ) / t_h ) );
101 
102  }
103  else
104  {
105  delta_u = 0.0;
106  }
107  return delta_u;
108 }
109 
110 
111 /*
112  * delta_u_thickness() - compute the thickness effect on normalized
113  * width for coupled microstrips
114  *
115  * References: Rolf Jansen, "High-Speed Computation of Single and
116  * Coupled Microstrip Parameters Including Dispersion, High-Order
117  * Modes, Loss and Finite Strip Thickness", IEEE Trans. MTT, vol. 26,
118  * no. 2, pp. 75-82, Feb. 1978
119  */
121 {
122  double e_r, u, g, t_h;
123  double delta_u, delta_t, delta_u_e, delta_u_o;
124 
125  e_r = m_parameters[EPSILONR_PRM];
126  u = m_parameters[PHYS_WIDTH_PRM] / m_parameters[H_PRM]; /* normalized line width */
127  g = m_parameters[PHYS_S_PRM] / m_parameters[H_PRM]; /* normalized line spacing */
128  t_h = m_parameters[T_PRM] / m_parameters[H_PRM]; /* normalized strip thickness */
129 
130  if( t_h > 0.0 )
131  {
132  /* single microstrip correction for finite strip thickness */
133  delta_u = delta_u_thickness_single( u, t_h );
134  delta_t = t_h / ( g * e_r );
135  /* thickness correction for the even- and odd-mode */
136  delta_u_e = delta_u * ( 1.0 - 0.5 * exp( -0.69 * delta_u / delta_t ) );
137  delta_u_o = delta_u_e + delta_t;
138  }
139  else
140  {
141  delta_u_e = delta_u_o = 0.0;
142  }
143 
146 }
147 
148 
149 /*
150  * compute various parameters for a single line
151  */
153 {
154  if( aux_ms == NULL )
155  aux_ms = new MICROSTRIP();
156 
157  /* prepare parameters for single microstrip computations */
161  aux_ms->m_parameters[T_PRM] = 0.0;
162 
163  //aux_ms->m_parameters[H_T_PRM] = m_parameters[H_T_PRM];
164  aux_ms->m_parameters[H_T_PRM] = 1e12; /* arbitrarily high */
168  aux_ms->dispersion();
169 }
170 
171 
172 /*
173  * filling_factor_even() - compute the filling factor for the coupled
174  * microstrips even-mode without cover and zero conductor thickness
175  */
176 double C_MICROSTRIP::filling_factor_even( double u, double g, double e_r )
177 {
178  double v, v3, v4, a_e, b_e, q_inf;
179 
180  v = u * ( 20.0 + g * g ) / ( 10.0 + g * g ) + g * exp( -g );
181  v3 = v * v * v;
182  v4 = v3 * v;
183  a_e = 1.0 + log( ( v4 + v * v / 2704.0 ) / ( v4 + 0.432 ) ) / 49.0
184  + log( 1.0 + v3 / 5929.741 ) / 18.7;
185  b_e = 0.564 * pow( ( ( e_r - 0.9 ) / ( e_r + 3.0 ) ), 0.053 );
186 
187  /* filling factor, with width corrected for thickness */
188  q_inf = pow( ( 1.0 + 10.0 / v ), -a_e * b_e );
189 
190  return q_inf;
191 }
192 
193 
198 double C_MICROSTRIP::filling_factor_odd( double u, double g, double e_r )
199 {
200  double b_odd = 0.747 * e_r / ( 0.15 + e_r );
201  double c_odd = b_odd - ( b_odd - 0.207 ) * exp( -0.414 * u );
202  double d_odd = 0.593 + 0.694 * exp( -0.562 * u );
203 
204  /* filling factor, with width corrected for thickness */
205  double q_inf = exp( -c_odd * pow( g, d_odd ) );
206 
207  return q_inf;
208 }
209 
210 
211 /*
212  * delta_q_cover_even() - compute the cover effect on filling factor
213  * for the even-mode
214  */
216 {
217  double q_c;
218 
219  if( h2h <= 39 )
220  q_c = tanh( 1.626 + 0.107 * h2h - 1.733 / sqrt( h2h ) );
221  else
222  q_c = 1.0;
223 
224  return q_c;
225 }
226 
227 
228 /*
229  * delta_q_cover_odd() - compute the cover effect on filling factor
230  * for the odd-mode
231  */
233 {
234  double q_c;
235 
236  if( h2h <= 7 )
237  q_c = tanh( 9.575 / ( 7.0 - h2h ) - 2.965 + 1.68 * h2h - 0.311 * h2h * h2h );
238  else
239  q_c = 1.0;
240 
241  return q_c;
242 }
243 
244 
254 {
255  double u_t_e, u_t_o, g, h2, h2h;
256  double a_o, t_h, q, q_c, q_t, q_inf;
257  double er_eff_single;
258  double er;
259 
261 
262  /* compute zero-thickness single line parameters */
264  er_eff_single = aux_ms->er_eff_0;
265 
266  h2 = m_parameters[H_T_PRM];
267  u_t_e = w_t_e / m_parameters[H_PRM]; /* normalized even_mode line width */
268  u_t_o = w_t_o / m_parameters[H_PRM]; /* normalized odd_mode line width */
269  g = m_parameters[PHYS_S_PRM] / m_parameters[H_PRM]; /* normalized line spacing */
270  h2h = h2 / m_parameters[H_PRM]; /* normalized cover height */
271  t_h = m_parameters[T_PRM] / m_parameters[H_PRM]; /* normalized strip thickness */
272 
273  /* filling factor, computed with thickness corrected width */
274  q_inf = filling_factor_even( u_t_e, g, er );
275  /* cover effect */
276  q_c = delta_q_cover_even( h2h );
277  /* thickness effect */
278  q_t = aux_ms->delta_q_thickness( u_t_e, t_h );
279  /* resultant filling factor */
280  q = ( q_inf - q_t ) * q_c;
281  /* static even-mode effective dielectric constant */
282  er_eff_e_0 = 0.5 * ( er + 1.0 ) + 0.5 * ( er - 1.0 ) * q;
283 
284  /* filling factor, with width corrected for thickness */
285  q_inf = filling_factor_odd( u_t_o, g, er );
286  /* cover effect */
287  q_c = delta_q_cover_odd( h2h );
288  /* thickness effect */
289  q_t = aux_ms->delta_q_thickness( u_t_o, t_h );
290  /* resultant filling factor */
291  q = ( q_inf - q_t ) * q_c;
292 
293  a_o = 0.7287 * ( er_eff_single - 0.5 * ( er + 1.0 ) ) * ( 1.0 - exp( -0.179 * u_t_o ) );
294 
295  /* static odd-mode effective dielectric constant */
296  er_eff_o_0 = ( 0.5 * ( er + 1.0 ) + a_o - er_eff_single ) * q + er_eff_single;
297 }
298 
299 
307 double C_MICROSTRIP::delta_Z0_even_cover( double g, double u, double h2h )
308 {
309  double f_e, g_e, delta_Z0_even;
310  double x, y, A, B, C, D, E, F;
311 
312  A = -4.351 / pow( 1.0 + h2h, 1.842 );
313  B = 6.639 / pow( 1.0 + h2h, 1.861 );
314  C = -2.291 / pow( 1.0 + h2h, 1.90 );
315  f_e = 1.0 - atanh( A + ( B + C * u ) * u );
316 
317  x = pow( 10.0, 0.103 * g - 0.159 );
318  y = pow( 10.0, 0.0492 * g - 0.073 );
319  D = 0.747 / sin( 0.5 * M_PI * x );
320  E = 0.725 * sin( 0.5 * M_PI * y );
321  F = pow( 10.0, 0.11 - 0.0947 * g );
322  g_e = 270.0 * ( 1.0 - tanh( D + E * sqrt( 1.0 + h2h ) - F / ( 1.0 + h2h ) ) );
323 
324  delta_Z0_even = f_e * g_e;
325 
326  return delta_Z0_even;
327 }
328 
329 
337 double C_MICROSTRIP::delta_Z0_odd_cover( double g, double u, double h2h )
338 {
339  double f_o, g_o, delta_Z0_odd;
340  double G, J, K, L;
341 
342  J = tanh( pow( 1.0 + h2h, 1.585 ) / 6.0 );
343  f_o = pow( u, J );
344 
345  G = 2.178 - 0.796 * g;
346 
347  if( g > 0.858 )
348  K = log10( 20.492 * pow( g, 0.174 ) );
349  else
350  K = 1.30;
351 
352  if( g > 0.873 )
353  L = 2.51 * pow( g, -0.462 );
354  else
355  L = 2.674;
356 
357  g_o = 270.0 * ( 1.0 - tanh( G + K * sqrt( 1.0 + h2h ) - L / ( 1.0 + h2h ) ) );
358 
359  delta_Z0_odd = f_o * g_o;
360 
361  return delta_Z0_odd;
362 }
363 
364 
375 {
376  double er_eff, h2, u_t_e, u_t_o, g, h2h;
377  double Q_1, Q_2, Q_3, Q_4, Q_5, Q_6, Q_7, Q_8, Q_9, Q_10;
378  double delta_Z0_e_0, delta_Z0_o_0, Z0_single, er_eff_single;
379 
380  h2 = m_parameters[H_T_PRM];
381  u_t_e = w_t_e / m_parameters[H_PRM]; /* normalized even-mode line width */
382  u_t_o = w_t_o / m_parameters[H_PRM]; /* normalized odd-mode line width */
383  g = m_parameters[PHYS_S_PRM] / m_parameters[H_PRM]; /* normalized line spacing */
384  h2h = h2 / m_parameters[H_PRM]; /* normalized cover height */
385 
386  Z0_single = aux_ms->Z0_0;
387  er_eff_single = aux_ms->er_eff_0;
388 
389  /* even-mode */
390  er_eff = er_eff_e_0;
391  Q_1 = 0.8695 * pow( u_t_e, 0.194 );
392  Q_2 = 1.0 + 0.7519 * g + 0.189 * pow( g, 2.31 );
393  Q_3 = 0.1975 + pow( ( 16.6 + pow( ( 8.4 / g ), 6.0 ) ), -0.387 )
394  + log( pow( g, 10.0 ) / ( 1.0 + pow( g / 3.4, 10.0 ) ) ) / 241.0;
395  Q_4 = 2.0 * Q_1
396  / ( Q_2 * ( exp( -g ) * pow( u_t_e, Q_3 ) + ( 2.0 - exp( -g ) ) * pow( u_t_e, -Q_3 ) ) );
397  /* static even-mode impedance */
398  Z0_e_0 = Z0_single * sqrt( er_eff_single / er_eff )
399  / ( 1.0 - sqrt( er_eff_single ) * Q_4 * Z0_single / ZF0 );
400  /* correction for cover */
401  delta_Z0_e_0 = delta_Z0_even_cover( g, u_t_e, h2h ) / sqrt( er_eff );
402 
403  Z0_e_0 = Z0_e_0 - delta_Z0_e_0;
404 
405  /* odd-mode */
406  er_eff = er_eff_o_0;
407  Q_5 = 1.794 + 1.14 * log( 1.0 + 0.638 / ( g + 0.517 * pow( g, 2.43 ) ) );
408  Q_6 = 0.2305 + log( pow( g, 10.0 ) / ( 1.0 + pow( g / 5.8, 10.0 ) ) ) / 281.3
409  + log( 1.0 + 0.598 * pow( g, 1.154 ) ) / 5.1;
410  Q_7 = ( 10.0 + 190.0 * g * g ) / ( 1.0 + 82.3 * g * g * g );
411  Q_8 = exp( -6.5 - 0.95 * log( g ) - pow( g / 0.15, 5.0 ) );
412  Q_9 = log( Q_7 ) * ( Q_8 + 1.0 / 16.5 );
413  Q_10 = ( Q_2 * Q_4 - Q_5 * exp( log( u_t_o ) * Q_6 * pow( u_t_o, -Q_9 ) ) ) / Q_2;
414 
415  /* static odd-mode impedance */
416  Z0_o_0 = Z0_single * sqrt( er_eff_single / er_eff )
417  / ( 1.0 - sqrt( er_eff_single ) * Q_10 * Z0_single / ZF0 );
418  /* correction for cover */
419  delta_Z0_o_0 = delta_Z0_odd_cover( g, u_t_o, h2h ) / sqrt( er_eff );
420 
421  Z0_o_0 = Z0_o_0 - delta_Z0_o_0;
422 }
423 
424 
425 /*
426  * er_eff_freq() - compute er_eff as a function of frequency
427  */
429 {
430  double P_1, P_2, P_3, P_4, P_5, P_6, P_7;
431  double P_8, P_9, P_10, P_11, P_12, P_13, P_14, P_15;
432  double F_e, F_o;
433  double er_eff, u, g, f_n;
434 
435  u = m_parameters[PHYS_WIDTH_PRM] / m_parameters[H_PRM]; /* normalize line width */
436  g = m_parameters[PHYS_S_PRM] / m_parameters[H_PRM]; /* normalize line spacing */
437 
438  /* normalized frequency [GHz * mm] */
439  f_n = m_parameters[FREQUENCY_PRM] * m_parameters[H_PRM] / 1e06;
440 
441  er_eff = er_eff_e_0;
442  P_1 = 0.27488 + ( 0.6315 + 0.525 / pow( 1.0 + 0.0157 * f_n, 20.0 ) ) * u
443  - 0.065683 * exp( -8.7513 * u );
444  P_2 = 0.33622 * ( 1.0 - exp( -0.03442 * m_parameters[EPSILONR_PRM] ) );
445  P_3 = 0.0363 * exp( -4.6 * u ) * ( 1.0 - exp( -pow( f_n / 38.7, 4.97 ) ) );
446  P_4 = 1.0 + 2.751 * ( 1.0 - exp( -pow( m_parameters[EPSILONR_PRM] / 15.916, 8.0 ) ) );
447  P_5 = 0.334 * exp( -3.3 * pow( m_parameters[EPSILONR_PRM] / 15.0, 3.0 ) ) + 0.746;
448  P_6 = P_5 * exp( -pow( f_n / 18.0, 0.368 ) );
449  P_7 = 1.0
450  + 4.069 * P_6 * pow( g, 0.479 ) * exp( -1.347 * pow( g, 0.595 ) - 0.17 * pow( g, 2.5 ) );
451 
452  F_e = P_1 * P_2 * pow( ( P_3 * P_4 + 0.1844 * P_7 ) * f_n, 1.5763 );
453  /* even-mode effective dielectric constant */
455 
456  er_eff = er_eff_o_0;
457  P_8 = 0.7168 * ( 1.0 + 1.076 / ( 1.0 + 0.0576 * ( m_parameters[EPSILONR_PRM] - 1.0 ) ) );
458  P_9 = P_8
459  - 0.7913 * ( 1.0 - exp( -pow( f_n / 20.0, 1.424 ) ) )
460  * atan( 2.481 * pow( m_parameters[EPSILONR_PRM] / 8.0, 0.946 ) );
461  P_10 = 0.242 * pow( m_parameters[EPSILONR_PRM] - 1.0, 0.55 );
462  P_11 = 0.6366 * ( exp( -0.3401 * f_n ) - 1.0 ) * atan( 1.263 * pow( u / 3.0, 1.629 ) );
463  P_12 = P_9 + ( 1.0 - P_9 ) / ( 1.0 + 1.183 * pow( u, 1.376 ) );
464  P_13 = 1.695 * P_10 / ( 0.414 + 1.605 * P_10 );
465  P_14 = 0.8928 + 0.1072 * ( 1.0 - exp( -0.42 * pow( f_n / 20.0, 3.215 ) ) );
466  P_15 = fabs( 1.0 - 0.8928 * ( 1.0 + P_11 ) * P_12 * exp( -P_13 * pow( g, 1.092 ) ) / P_14 );
467 
468  F_o = P_1 * P_2 * pow( ( P_3 * P_4 + 0.1844 ) * f_n * P_15, 1.5763 );
469  /* odd-mode effective dielectric constant */
471 }
472 
473 
474 /*
475  * conductor_losses() - compute microstrips conductor losses per unit
476  * length
477  */
479 {
480  double e_r_eff_e_0, e_r_eff_o_0, Z0_h_e, Z0_h_o, delta;
481  double K, R_s, Q_c_e, Q_c_o, alpha_c_e, alpha_c_o;
482 
483  e_r_eff_e_0 = er_eff_e_0;
484  e_r_eff_o_0 = er_eff_o_0;
485  Z0_h_e = Z0_e_0 * sqrt( e_r_eff_e_0 ); /* homogeneous stripline impedance */
486  Z0_h_o = Z0_o_0 * sqrt( e_r_eff_o_0 ); /* homogeneous stripline impedance */
488 
489  if( m_parameters[FREQUENCY_PRM] > 0.0 )
490  {
491  /* current distribution factor (same for the two modes) */
492  K = exp( -1.2 * pow( ( Z0_h_e + Z0_h_o ) / ( 2.0 * ZF0 ), 0.7 ) );
493  /* skin resistance */
494  R_s = 1.0 / ( m_parameters[SIGMA_PRM] * delta );
495  /* correction for surface roughness */
496  R_s *= 1.0
497  + ( ( 2.0 / M_PI )
498  * atan( 1.40 * pow( ( m_parameters[ROUGH_PRM] / delta ), 2.0 ) ) );
499 
500  /* even-mode strip inductive quality factor */
501  Q_c_e = ( M_PI * Z0_h_e * m_parameters[PHYS_WIDTH_PRM] * m_parameters[FREQUENCY_PRM] )
502  / ( R_s * C0 * K );
503  /* even-mode losses per unith length */
504  alpha_c_e = ( 20.0 * M_PI / log( 10.0 ) ) * m_parameters[FREQUENCY_PRM]
505  * sqrt( e_r_eff_e_0 ) / ( C0 * Q_c_e );
506 
507  /* odd-mode strip inductive quality factor */
508  Q_c_o = ( M_PI * Z0_h_o * m_parameters[PHYS_WIDTH_PRM] * m_parameters[FREQUENCY_PRM] )
509  / ( R_s * C0 * K );
510  /* odd-mode losses per unith length */
511  alpha_c_o = ( 20.0 * M_PI / log( 10.0 ) ) * m_parameters[FREQUENCY_PRM]
512  * sqrt( e_r_eff_o_0 ) / ( C0 * Q_c_o );
513  }
514  else
515  {
516  alpha_c_e = alpha_c_o = 0.0;
517  }
518 
519  atten_cond_e = alpha_c_e * m_parameters[PHYS_LEN_PRM];
520  atten_cond_o = alpha_c_o * m_parameters[PHYS_LEN_PRM];
521 }
522 
523 
524 /*
525  * dielectric_losses() - compute microstrips dielectric losses per
526  * unit length
527  */
529 {
530  double e_r, e_r_eff_e_0, e_r_eff_o_0;
531  double alpha_d_e, alpha_d_o;
532 
533  e_r = m_parameters[EPSILONR_PRM];
534  e_r_eff_e_0 = er_eff_e_0;
535  e_r_eff_o_0 = er_eff_o_0;
536 
537  alpha_d_e = ( 20.0 * M_PI / log( 10.0 ) ) * ( m_parameters[FREQUENCY_PRM] / C0 )
538  * ( e_r / sqrt( e_r_eff_e_0 ) ) * ( ( e_r_eff_e_0 - 1.0 ) / ( e_r - 1.0 ) )
540  alpha_d_o = ( 20.0 * M_PI / log( 10.0 ) ) * ( m_parameters[FREQUENCY_PRM] / C0 )
541  * ( e_r / sqrt( e_r_eff_o_0 ) ) * ( ( e_r_eff_o_0 - 1.0 ) / ( e_r - 1.0 ) )
543 
546 }
547 
548 
549 /*
550  * c_microstrip_attenuation() - compute attenuation of coupled
551  * microstrips
552  */
554 {
558 }
559 
560 
561 /*
562  * line_angle() - calculate strips electrical lengths in radians
563  */
565 {
566  double e_r_eff_e, e_r_eff_o;
567  double v_e, v_o, lambda_g_e, lambda_g_o;
568 
569  e_r_eff_e = er_eff_e;
570  e_r_eff_o = er_eff_o;
571 
572  /* even-mode velocity */
573  v_e = C0 / sqrt( e_r_eff_e );
574  /* odd-mode velocity */
575  v_o = C0 / sqrt( e_r_eff_o );
576  /* even-mode wavelength */
577  lambda_g_e = v_e / m_parameters[FREQUENCY_PRM];
578  /* odd-mode wavelength */
579  lambda_g_o = v_o / m_parameters[FREQUENCY_PRM];
580  /* electrical angles */
581  ang_l_e = 2.0 * M_PI * m_parameters[PHYS_LEN_PRM] / lambda_g_e; /* in radians */
582  ang_l_o = 2.0 * M_PI * m_parameters[PHYS_LEN_PRM] / lambda_g_o; /* in radians */
583 }
584 
585 
592 {
593  Zdiff = 2 * Z0_o_0;
594 }
595 
596 
597 void C_MICROSTRIP::syn_err_fun( double* f1, double* f2, double s_h, double w_h, double e_r,
598  double w_h_se, double w_h_so )
599 {
600  double g, he;
601 
602  g = cosh( 0.5 * M_PI * s_h );
603  he = cosh( M_PI * w_h + 0.5 * M_PI * s_h );
604 
605  *f1 = ( 2.0 / M_PI ) * acosh( ( 2.0 * he - g + 1.0 ) / ( g + 1.0 ) );
606  *f2 = ( 2.0 / M_PI ) * acosh( ( 2.0 * he - g - 1.0 ) / ( g - 1.0 ) );
607 
608  if( e_r <= 6.0 )
609  *f2 += ( 4.0 / ( M_PI * ( 1.0 + e_r / 2.0 ) ) ) * acosh( 1.0 + 2.0 * w_h / s_h );
610  else
611  *f2 += ( 1.0 / M_PI ) * acosh( 1.0 + 2.0 * w_h / s_h );
612 
613  *f1 -= w_h_se;
614  *f2 -= w_h_so;
615 }
616 
617 
618 /*
619  * synth_width - calculate widths given Z0 and e_r
620  * from Akhtarzad S. et al., "The design of coupled microstrip lines",
621  * IEEE Trans. MTT-23, June 1975 and
622  * Hinton, J.H., "On design of coupled microstrip lines", IEEE Trans.
623  * MTT-28, March 1980
624  */
626 {
627  double Z0, e_r;
628  double w_h_se, w_h_so, w_h, a, ce, co, s_h;
629  double f1, f2, ft1, ft2, j11, j12, j21, j22, d_s_h, d_w_h, err;
630  double eps = 1e-04;
631 
632  f1 = f2 = 0;
633  e_r = m_parameters[EPSILONR_PRM];
634 
635  Z0 = m_parameters[Z0_E_PRM] / 2.0;
636  /* Wheeler formula for single microstrip synthesis */
637  a = exp( Z0 * sqrt( e_r + 1.0 ) / 42.4 ) - 1.0;
638  w_h_se = 8.0 * sqrt( a * ( ( 7.0 + 4.0 / e_r ) / 11.0 ) + ( ( 1.0 + 1.0 / e_r ) / 0.81 ) ) / a;
639 
640  Z0 = m_parameters[Z0_O_PRM] / 2.0;
641  /* Wheeler formula for single microstrip synthesis */
642  a = exp( Z0 * sqrt( e_r + 1.0 ) / 42.4 ) - 1.0;
643  w_h_so = 8.0 * sqrt( a * ( ( 7.0 + 4.0 / e_r ) / 11.0 ) + ( ( 1.0 + 1.0 / e_r ) / 0.81 ) ) / a;
644 
645  ce = cosh( 0.5 * M_PI * w_h_se );
646  co = cosh( 0.5 * M_PI * w_h_so );
647  /* first guess at m_parameters[PHYS_S_PRM]/h */
648  s_h = ( 2.0 / M_PI ) * acosh( ( ce + co - 2.0 ) / ( co - ce ) );
649  /* first guess at w/h */
650  w_h = acosh( ( ce * co - 1.0 ) / ( co - ce ) ) / M_PI - s_h / 2.0;
651 
654 
655  syn_err_fun( &f1, &f2, s_h, w_h, e_r, w_h_se, w_h_so );
656 
657  /* rather crude Newton-Rhapson; we need this because the estimate of */
658  /* w_h is often quite far from the true value (see Akhtarzad S. et al.) */
659  do
660  {
661  /* compute Jacobian */
662  syn_err_fun( &ft1, &ft2, s_h + eps, w_h, e_r, w_h_se, w_h_so );
663  j11 = ( ft1 - f1 ) / eps;
664  j21 = ( ft2 - f2 ) / eps;
665  syn_err_fun( &ft1, &ft2, s_h, w_h + eps, e_r, w_h_se, w_h_so );
666  j12 = ( ft1 - f1 ) / eps;
667  j22 = ( ft2 - f2 ) / eps;
668 
669  /* compute next step */
670  d_s_h = ( -f1 * j22 + f2 * j12 ) / ( j11 * j22 - j21 * j12 );
671  d_w_h = ( -f2 * j11 + f1 * j21 ) / ( j11 * j22 - j21 * j12 );
672 
673  //g_print("j11 = %e\tj12 = %e\tj21 = %e\tj22 = %e\n", j11, j12, j21, j22);
674  //g_print("det = %e\n", j11*j22 - j21*j22);
675  //g_print("d_s_h = %e\td_w_h = %e\n", d_s_h, d_w_h);
676 
677  s_h += d_s_h;
678  w_h += d_w_h;
679 
680  /* check the error */
681  syn_err_fun( &f1, &f2, s_h, w_h, e_r, w_h_se, w_h_so );
682 
683  err = sqrt( f1 * f1 + f2 * f2 );
684  /* converged ? */
685  } while( err > 1e-04 );
686 
687 
690 }
691 
692 
693 /*
694  * Z0_dispersion() - calculate frequency dependency of characteristic
695  * impedances
696  */
698 {
699  double Q_0;
700  double Q_11, Q_12, Q_13, Q_14, Q_15, Q_16, Q_17, Q_18, Q_19, Q_20, Q_21;
701  double Q_22, Q_23, Q_24, Q_25, Q_26, Q_27, Q_28, Q_29;
702  double r_e, q_e, p_e, d_e, C_e;
703  double e_r_eff_o_f, e_r_eff_o_0;
704  double e_r_eff_single_f, e_r_eff_single_0, Z0_single_f;
705  double f_n, g, u, e_r;
706  double R_1, R_2, R_7, R_10, R_11, R_12, R_15, R_16, tmpf;
707 
708  e_r = m_parameters[EPSILONR_PRM];
709 
710  u = m_parameters[PHYS_WIDTH_PRM] / m_parameters[H_PRM]; /* normalize line width */
711  g = m_parameters[PHYS_S_PRM] / m_parameters[H_PRM]; /* normalize line spacing */
712 
713  /* normalized frequency [GHz * mm] */
714  f_n = m_parameters[FREQUENCY_PRM] * m_parameters[H_PRM] / 1e06;
715 
716  e_r_eff_single_f = aux_ms->er_eff;
717  e_r_eff_single_0 = aux_ms->er_eff_0;
718  Z0_single_f = aux_ms->m_parameters[Z0_PRM];
719 
720  e_r_eff_o_f = er_eff_o;
721  e_r_eff_o_0 = er_eff_o_0;
722 
723  Q_11 = 0.893 * ( 1.0 - 0.3 / ( 1.0 + 0.7 * ( e_r - 1.0 ) ) );
724  Q_12 = 2.121 * ( pow( f_n / 20.0, 4.91 ) / ( 1.0 + Q_11 * pow( f_n / 20.0, 4.91 ) ) )
725  * exp( -2.87 * g ) * pow( g, 0.902 );
726  Q_13 = 1.0 + 0.038 * pow( e_r / 8.0, 5.1 );
727  Q_14 = 1.0 + 1.203 * pow( e_r / 15.0, 4.0 ) / ( 1.0 + pow( e_r / 15.0, 4.0 ) );
728  Q_15 = 1.887 * exp( -1.5 * pow( g, 0.84 ) ) * pow( g, Q_14 )
729  / ( 1.0
730  + 0.41 * pow( f_n / 15.0, 3.0 ) * pow( u, 2.0 / Q_13 )
731  / ( 0.125 + pow( u, 1.626 / Q_13 ) ) );
732  Q_16 = ( 1.0 + 9.0 / ( 1.0 + 0.403 * pow( e_r - 1.0, 2 ) ) ) * Q_15;
733  Q_17 = 0.394 * ( 1.0 - exp( -1.47 * pow( u / 7.0, 0.672 ) ) )
734  * ( 1.0 - exp( -4.25 * pow( f_n / 20.0, 1.87 ) ) );
735  Q_18 = 0.61 * ( 1.0 - exp( -2.13 * pow( u / 8.0, 1.593 ) ) ) / ( 1.0 + 6.544 * pow( g, 4.17 ) );
736  Q_19 = 0.21 * g * g * g * g
737  / ( ( 1.0 + 0.18 * pow( g, 4.9 ) ) * ( 1.0 + 0.1 * u * u )
738  * ( 1.0 + pow( f_n / 24.0, 3.0 ) ) );
739  Q_20 = ( 0.09 + 1.0 / ( 1.0 + 0.1 * pow( e_r - 1, 2.7 ) ) ) * Q_19;
740  Q_21 = fabs( 1.0
741  - 42.54 * pow( g, 0.133 ) * exp( -0.812 * g ) * pow( u, 2.5 )
742  / ( 1.0 + 0.033 * pow( u, 2.5 ) ) );
743 
744  r_e = pow( f_n / 28.843, 12 );
745  q_e = 0.016 + pow( 0.0514 * e_r * Q_21, 4.524 );
746  p_e = 4.766 * exp( -3.228 * pow( u, 0.641 ) );
747  d_e = 5.086 * q_e * ( r_e / ( 0.3838 + 0.386 * q_e ) )
748  * ( exp( -22.2 * pow( u, 1.92 ) ) / ( 1.0 + 1.2992 * r_e ) )
749  * ( pow( e_r - 1.0, 6.0 ) / ( 1.0 + 10 * pow( e_r - 1.0, 6.0 ) ) );
750  C_e = 1.0
751  + 1.275
752  * ( 1.0
753  - exp( -0.004625 * p_e * pow( e_r, 1.674 )
754  * pow( f_n / 18.365, 2.745 ) ) )
755  - Q_12 + Q_16 - Q_17 + Q_18 + Q_20;
756 
757 
758  R_1 = 0.03891 * pow( e_r, 1.4 );
759  R_2 = 0.267 * pow( u, 7.0 );
760  R_7 = 1.206 - 0.3144 * exp( -R_1 ) * ( 1.0 - exp( -R_2 ) );
761  R_10 = 0.00044 * pow( e_r, 2.136 ) + 0.0184;
762  tmpf = pow( f_n / 19.47, 6.0 );
763  R_11 = tmpf / ( 1.0 + 0.0962 * tmpf );
764  R_12 = 1.0 / ( 1.0 + 0.00245 * u * u );
765  R_15 = 0.707 * R_10 * pow( f_n / 12.3, 1.097 );
766  R_16 = 1.0 + 0.0503 * e_r * e_r * R_11 * ( 1.0 - exp( -pow( u / 15.0, 6.0 ) ) );
767  Q_0 = R_7 * ( 1.0 - 1.1241 * ( R_12 / R_16 ) * exp( -0.026 * pow( f_n, 1.15656 ) - R_15 ) );
768 
769  /* even-mode frequency-dependent characteristic impedances */
770  m_parameters[Z0_E_PRM] = Z0_e_0 * pow( 0.9408 * pow( e_r_eff_single_f, C_e ) - 0.9603, Q_0 )
771  / pow( ( 0.9408 - d_e ) * pow( e_r_eff_single_0, C_e ) - 0.9603, Q_0 );
772 
773  Q_29 = 15.16 / ( 1.0 + 0.196 * pow( e_r - 1.0, 2.0 ) );
774  tmpf = pow( e_r - 1.0, 3.0 );
775  Q_28 = 0.149 * tmpf / ( 94.5 + 0.038 * tmpf );
776  tmpf = pow( e_r - 1.0, 1.5 );
777  Q_27 = 0.4 * pow( g, 0.84 ) * ( 1.0 + 2.5 * tmpf / ( 5.0 + tmpf ) );
778  tmpf = pow( ( e_r - 1.0 ) / 13.0, 12.0 );
779  Q_26 = 30.0 - 22.2 * ( tmpf / ( 1.0 + 3.0 * tmpf ) ) - Q_29;
780  tmpf = ( e_r - 1.0 ) * ( e_r - 1.0 );
781  Q_25 = ( 0.3 * f_n * f_n / ( 10.0 + f_n * f_n ) ) * ( 1.0 + 2.333 * tmpf / ( 5.0 + tmpf ) );
782  Q_24 = 2.506 * Q_28 * pow( u, 0.894 ) * pow( ( 1.0 + 1.3 * u ) * f_n / 99.25, 4.29 )
783  / ( 3.575 + pow( u, 0.894 ) );
784  Q_23 = 1.0
785  + 0.005 * f_n * Q_27
786  / ( ( 1.0 + 0.812 * pow( f_n / 15.0, 1.9 ) ) * ( 1.0 + 0.025 * u * u ) );
787  Q_22 = 0.925 * pow( f_n / Q_26, 1.536 ) / ( 1.0 + 0.3 * pow( f_n / 30.0, 1.536 ) );
788 
789  /* odd-mode frequency-dependent characteristic impedances */
791  Z0_single_f
792  + ( Z0_o_0 * pow( e_r_eff_o_f / e_r_eff_o_0, Q_22 ) - Z0_single_f * Q_23 )
793  / ( 1.0 + Q_24 + pow( 0.46 * g, 2.2 ) * Q_25 );
794 }
795 
796 
798 {
799  /* compute thickness corrections */
801  /* get effective dielectric constants */
802  er_eff_static();
803  /* impedances for even- and odd-mode */
804  Z0_even_odd();
805  /* calculate freq dependence of er_eff_e, er_eff_o */
806  er_eff_freq();
807  /* calculate frequency dependence of Z0e, Z0o */
808  Z0_dispersion();
809  /* calculate losses */
810  attenuation();
811  /* calculate electrical lengths */
812  line_angle();
813  /* calculate diff impedance */
814  diff_impedance();
815 }
816 
817 
819 {
822  setProperty( ANG_L_PRM, sqrt( ang_l_e * ang_l_o ) );
823 
824  //Check for errors
825  if( !std::isfinite( m_parameters[Z0_O_PRM] ) || m_parameters[Z0_O_PRM] <= 0.0 )
827 
828  if( !std::isfinite( m_parameters[Z0_E_PRM] ) || m_parameters[Z0_E_PRM] <= 0.0 )
830 
831  if( !std::isfinite( m_parameters[ANG_L_PRM] ) || m_parameters[ANG_L_PRM] <= 0.0 )
833 
834  // Check for warnings
835  if( !std::isfinite( m_parameters[PHYS_WIDTH_PRM] ) || m_parameters[PHYS_WIDTH_PRM] <= 0.0 )
837 
838  if( !std::isfinite( m_parameters[PHYS_S_PRM] ) || m_parameters[PHYS_S_PRM] <= 0.0 )
840 
841  if( !std::isfinite( m_parameters[PHYS_LEN_PRM] ) || m_parameters[PHYS_LEN_PRM] <= 0.0 )
843 }
844 
846 {
850 
851  //Check for errors
852  if( !std::isfinite( m_parameters[PHYS_WIDTH_PRM] ) || m_parameters[PHYS_WIDTH_PRM] <= 0.0 )
854 
855  if( !std::isfinite( m_parameters[PHYS_S_PRM] ) || m_parameters[PHYS_S_PRM] <= 0.0 )
857 
858  if( !std::isfinite( m_parameters[PHYS_LEN_PRM] ) || m_parameters[PHYS_LEN_PRM] <= 0.0 )
860 
861  // Check for warnings
862  if( !std::isfinite( m_parameters[Z0_O_PRM] ) || m_parameters[Z0_O_PRM] <= 0.0 )
864 
865  if( !std::isfinite( m_parameters[Z0_E_PRM] ) || m_parameters[Z0_E_PRM] <= 0.0 )
867 
868  if( !std::isfinite( m_parameters[ANG_L_PRM] ) || m_parameters[ANG_L_PRM] <= 0.0 )
870 }
871 
873 {
874 
875  setResult( 0, er_eff_e, "" );
876  setResult( 1, er_eff_o, "" );
877  setResult( 2, atten_cond_e, wxT( "dB" ) );
878  setResult( 3, atten_cond_o, wxT( "dB" ) );
879  setResult( 4, atten_dielectric_e, wxT( "dB" ) );
880  setResult( 5, atten_dielectric_o, wxT( "dB" ) );
881 
882  setResult( 6, m_parameters[SKIN_DEPTH_PRM] / UNIT_MICRON, wxT( "µm" ) );
883  setResult( 7, Zdiff, wxT( "Ω" ) );
884 }
885 
886 
888  double* f1, double* f2, double s_h, double w_h, double Z0_e, double Z0_o )
889 {
892 
893  /* compute coupled microstrip parameters */
894  calcAnalyze();
895 
896  *f1 = m_parameters[Z0_E_PRM] - Z0_e;
897  *f2 = m_parameters[Z0_O_PRM] - Z0_o;
898 }
899 
900 
901 /*
902  * synthesis function
903  */
905 {
906  double Z0_e, Z0_o, ang_l_dest;
907  double f1, f2, ft1, ft2, j11, j12, j21, j22, d_s_h, d_w_h, err;
908  double eps = 1e-04;
909  double w_h, s_h, le, lo;
910 
911 
912  /* required value of Z0_e and Z0_o */
913  Z0_e = m_parameters[Z0_E_PRM];
914  Z0_o = m_parameters[Z0_O_PRM];
915 
916 
919  ang_l_dest = m_parameters[ANG_L_PRM];
920 
921 
922  /* calculate width and use for initial value in Newton's method */
923  synth_width();
926  f1 = f2 = 0;
927 
928  /* rather crude Newton-Rhapson */
929  do
930  {
931  /* compute Jacobian */
932  syn_fun( &ft1, &ft2, s_h + eps, w_h, Z0_e, Z0_o );
933  j11 = ( ft1 - f1 ) / eps;
934  j21 = ( ft2 - f2 ) / eps;
935  syn_fun( &ft1, &ft2, s_h, w_h + eps, Z0_e, Z0_o );
936  j12 = ( ft1 - f1 ) / eps;
937  j22 = ( ft2 - f2 ) / eps;
938 
939  /* compute next step; increments of s_h and w_h */
940  d_s_h = ( -f1 * j22 + f2 * j12 ) / ( j11 * j22 - j21 * j12 );
941  d_w_h = ( -f2 * j11 + f1 * j21 ) / ( j11 * j22 - j21 * j12 );
942 
943  s_h += d_s_h;
944  w_h += d_w_h;
945 
946  /* compute the error with the new values of s_h and w_h */
947  syn_fun( &f1, &f2, s_h, w_h, Z0_e, Z0_o );
948  err = sqrt( f1 * f1 + f2 * f2 );
949 
950  /* converged ? */
951  } while( err > 1e-04 );
952 
953  /* denormalize computed width and spacing */
956 
957 
958  /* calculate physical length */
959  le = C0 / m_parameters[FREQUENCY_PRM] / sqrt( er_eff_e ) * ang_l_dest / 2.0 / M_PI;
960  lo = C0 / m_parameters[FREQUENCY_PRM] / sqrt( er_eff_o ) * ang_l_dest / 2.0 / M_PI;
961  m_parameters[PHYS_LEN_PRM] = sqrt( le * lo );
962 
963  calcAnalyze();
964 
965  m_parameters[ANG_L_PRM] = ang_l_dest;
966  m_parameters[Z0_E_PRM] = Z0_e;
967  m_parameters[Z0_O_PRM] = Z0_o;
968 }
void setResult(int, const wxString &)
Definition: transline.cpp:135
void dielectric_losses()
void er_eff_freq()
double delta_q_thickness(double, double)
Definition: microstrip.cpp:128
double er_eff_o
Definition: c_microstrip.h:57
double er_eff_o_0
Definition: c_microstrip.h:59
double w_t_e
Definition: c_microstrip.h:43
void Init()
Definition: transline.cpp:98
void syn_fun(double *, double *, double, double, double, double)
double er_eff
Definition: transline.h:133
double er_eff_e
Definition: c_microstrip.h:56
#define G(x, y, z)
Definition: md5_hash.cpp:16
double atten_dielectric_e
Definition: c_microstrip.h:61
void setProperty(enum PRMS_ID aPrmId, double aValue)
Definition: transline.cpp:117
double ang_l_o
Definition: c_microstrip.h:55
double atanh(double x)
Definition: units.h:51
void show_results() override
Shows results.
double ang_l_e
Definition: c_microstrip.h:54
double Z0_0
Definition: microstrip.h:45
double Zdiff
Definition: c_microstrip.h:49
void synth_width()
#define ZF0
Definition: units.h:62
double er_eff_0
Definition: microstrip.h:48
void dispersion()
Definition: microstrip.cpp:288
double delta_q_cover_odd(double)
void compute_single_line()
void showAnalyze() override
Shows synthesis results and checks for errors / warnings.
void Z0_dispersion()
double m_parameters[EXTRA_PRMS_COUNT]
Definition: transline.h:131
void showSynthesize() override
Shows analysis results and checks for errors / warnings.
double atten_cond_o
Definition: c_microstrip.h:64
void er_eff_static()
er_eff_static() - compute the static effective dielectric constants
double filling_factor_even(double, double, double)
#define F(x, y, z)
Definition: md5_hash.cpp:15
MICROSTRIP * aux_ms
Definition: c_microstrip.h:96
double delta_Z0_odd_cover(double, double, double)
delta_Z0_odd_cover() - compute the odd-mode impedance correction for a homogeneous microstrip due to ...
double delta_Z0_even_cover(double, double, double)
delta_Z0_even_cover() - compute the even-mode impedance correction for a homogeneous microstrip due t...
const char * m_Name
Definition: transline.h:84
#define UNIT_MICRON
Definition: units_scales.h:33
double Z0_e_0
Definition: c_microstrip.h:47
double atten_dielectric_o
Definition: c_microstrip.h:63
#define C0
Definition: units.h:61
void calcAnalyze() override
Computation for analysis.
#define TRANSLINE_ERROR
Definition: transline.h:31
void microstrip_Z0()
Definition: microstrip.cpp:176
double er_eff_e_0
Definition: c_microstrip.h:58
double atten_cond_e
Definition: c_microstrip.h:62
void Z0_even_odd()
Z0_even_odd() - compute the static even- and odd-mode static impedances.
void delta_u_thickness()
double delta_u_thickness_single(double, double)
double filling_factor_odd(double, double, double)
filling_factor_odd() - compute the filling factor for the coupled microstrips odd-mode without cover ...
void calcSynthesize() override
Computation for synthesis.
constexpr int delta
void conductor_losses()
void diff_impedance()
Note that differential impedance is exactly twice the odd mode impedance.
void attenuation()
double delta_q_cover_even(double)
double acosh(double x)
Definition: units.h:40
void syn_err_fun(double *, double *, double, double, double, double, double)
#define TRANSLINE_WARNING
Definition: transline.h:30
double w_t_o
Definition: c_microstrip.h:44
double skin_depth()
@function skin_depth calculate skin depth
Definition: transline.cpp:245
void setErrorLevel(PRMS_ID, char)
@function setErrorLevel
Definition: transline.cpp:443
double Z0_o_0
Definition: c_microstrip.h:48