KiCad PCB EDA Suite
transline.cpp
Go to the documentation of this file.
1 
2 /*
3  * TRANSLINE.cpp - base for a transmission line implementation
4  *
5  * Copyright (C) 2005 Stefan Jahn <stefan@lkcc.org>
6  * Modified for Kicad: 2018 jean-pierre.charras
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this package; see the file COPYING. If not, write to
20  * the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
21  * Boston, MA 02110-1301, USA.
22  *
23  */
24 
25 #include <cmath>
26 #include <limits>
27 
28 #include "transline.h"
29 #include "units.h"
30 
31 #ifndef INFINITY
32 #define INFINITY std::numeric_limits<double>::infinity()
33 #endif
34 
35 
36 #ifndef M_PI_2
37 #define M_PI_2 ( M_PI / 2 )
38 #endif
39 
40 
41 // Functions to Read/Write parameters in pcb_calculator main frame:
42 // They are wrapper to actual functions, so all transline functions do not
43 // depend on Graphic User Interface
44 void SetPropertyInDialog( enum PRMS_ID aPrmId, double value );
45 
46 /* Puts the text into the given result line.
47 */
48 void SetResultInDialog( int line, const char* text );
49 
50 /* print aValue into the given result line.
51 */
52 void SetResultInDialog( int aLineNumber, double aValue, const char* aText );
53 
54 /* Returns a named property value. */
55 double GetPropertyInDialog( enum PRMS_ID aPrmId );
56 
57 // Returns true if the param aPrmId is selected
58 // Has meaning only for params that have a radio button
59 bool IsSelectedInDialog( enum PRMS_ID aPrmId );
60 
66 void SetPropertyBgColorInDialog( enum PRMS_ID aPrmId, const KIGFX::COLOR4D* aCol );
67 
68 
69 /* Constructor creates a transmission line instance. */
71 {
72  m_parameters[MURC_PRM] = 1.0;
73  m_Name = nullptr;
74  ang_l = 0.0; // Electrical length in angle
75  len = 0.0; // length of line
76  er_eff = 1.0; // effective dielectric constant
77  Init();
78 }
79 
80 
81 /* Destructor destroys a transmission line instance. */
83 {
84 }
85 
86 
87 void TRANSLINE::Init( void )
88 {
89  wxColour wxcol = wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW );
90  okCol = KIGFX::COLOR4D( wxcol );
91  okCol.r = wxcol.Red() / 255.0;
92  okCol.g = wxcol.Green() / 255.0;
93  okCol.b = wxcol.Blue() / 255.0;
94  int i;
95  // Initialize these variables mainly to avoid warnings from a static analyzer
96  for( i = 0; i < EXTRA_PRMS_COUNT; ++i )
97  {
98  m_parameters[i] = 0;
99  }
100 }
101 
102 
103 /* Sets a named property to the given value, access through the
104  * application.
105  */
106 void TRANSLINE::setProperty( enum PRMS_ID aPrmId, double value )
107 {
108  SetPropertyInDialog( aPrmId, value );
109 }
110 
111 
112 /*
113  *Returns true if the param aPrmId is selected
114  * Has meaning only for params that have a radio button
115  */
116 bool TRANSLINE::isSelected( enum PRMS_ID aPrmId )
117 {
118  return IsSelectedInDialog( aPrmId );
119 }
120 
121 
122 /* Puts the text into the given result line.
123 */
124 void TRANSLINE::setResult( int line, const char* text )
125 {
126  SetResultInDialog( line, text );
127 }
128 void TRANSLINE::setResult( int line, double value, const char* text )
129 {
130  SetResultInDialog( line, value, text );
131 }
132 
133 
134 /* Returns a property value. */
135 double TRANSLINE::getProperty( enum PRMS_ID aPrmId )
136 {
137  return GetPropertyInDialog( aPrmId );
138 }
139 
145 {
146  int i;
147  for( i = 0; i < DUMMY_PRM; ++i )
148  {
149  m_parameters[i] = getProperty( (PRMS_ID) i );
151  }
155 }
162 {
163  // Do not check for values that are results of anylzing / synthesizing
164  // Do not check for transline specific incompatibilities ( like " conductor height sould be lesser than dielectric height")
165  if( !std::isfinite( m_parameters[EPSILONR_PRM] ) || m_parameters[EPSILONR_PRM] <= 0 )
167 
168  if( !std::isfinite( m_parameters[TAND_PRM] ) || m_parameters[TAND_PRM] < 0 )
170 
171  if( !std::isfinite( m_parameters[RHO_PRM] ) || m_parameters[RHO_PRM] < 0 )
173 
174  if( !std::isfinite( m_parameters[H_PRM] ) || m_parameters[H_PRM] < 0 )
176 
177  if( !std::isfinite( m_parameters[TWISTEDPAIR_TWIST_PRM] )
180 
181  if( !std::isfinite( m_parameters[STRIPLINE_A_PRM] ) || m_parameters[STRIPLINE_A_PRM] <= 0 )
183 
184  if( !std::isfinite( m_parameters[H_T_PRM] ) || m_parameters[H_T_PRM] <= 0 )
186 
187  // How can we check ROUGH_PRM ?
188 
189  if( !std::isfinite( m_parameters[MUR_PRM] ) || m_parameters[MUR_PRM] < 0 )
191 
192  if( !std::isfinite( m_parameters[TWISTEDPAIR_EPSILONR_ENV_PRM] )
195 
196  if( !std::isfinite( m_parameters[MURC_PRM] ) || m_parameters[MURC_PRM] < 0 )
198 
199  if( !std::isfinite( m_parameters[FREQUENCY_PRM] ) || m_parameters[FREQUENCY_PRM] <= 0 )
201 }
202 
204 {
205  getProperties();
206  checkProperties();
207  calcAnalyze();
208  showAnalyze();
209  show_results();
210 }
211 
213 {
214  getProperties();
215  checkProperties();
216  calcSynthesize();
217  showSynthesize();
218  show_results();
219 }
220 
221 
228 #include <cstdio>
230 {
231  double depth;
232  depth = 1.0
233  / sqrt( M_PI * m_parameters[FREQUENCY_PRM] * m_parameters[MURC_PRM] * MU0
234  * m_parameters[SIGMA_PRM] );
235  return depth;
236 }
237 
238 
239 /* *****************************************************************
240 ********** **********
241 ********** mathematical functions **********
242 ********** **********
243 ***************************************************************** */
244 
245 #define NR_EPSI 2.2204460492503131e-16
246 
247 /* The function computes the complete elliptic integral of first kind
248  * K() and the second kind E() using the arithmetic-geometric mean
249  * algorithm (AGM) by Abramowitz and Stegun.
250  */
251 void TRANSLINE::ellipke( double arg, double& k, double& e )
252 {
253  int iMax = 16;
254 
255  if( arg == 1.0 )
256  {
257  k = INFINITY; // infinite
258  e = 0;
259  }
260  else if( std::isinf( arg ) && arg < 0 )
261  {
262  k = 0;
263  e = INFINITY; // infinite
264  }
265  else
266  {
267  double a, b, c, fr, s, fk = 1, fe = 1, t, da = arg;
268  int i;
269  if( arg < 0 )
270  {
271  fk = 1 / sqrt( 1 - arg );
272  fe = sqrt( 1 - arg );
273  da = -arg / ( 1 - arg );
274  }
275  a = 1;
276  b = sqrt( 1 - da );
277  c = sqrt( da );
278  fr = 0.5;
279  s = fr * c * c;
280  for( i = 0; i < iMax; i++ )
281  {
282  t = ( a + b ) / 2;
283  c = ( a - b ) / 2;
284  b = sqrt( a * b );
285  a = t;
286  fr *= 2;
287  s += fr * c * c;
288  if( c / a < NR_EPSI )
289  break;
290  }
291 
292  if( i >= iMax )
293  {
294  k = 0;
295  e = 0;
296  }
297  else
298  {
299  k = M_PI_2 / a;
300  e = M_PI_2 * ( 1 - s ) / a;
301  if( arg < 0 )
302  {
303  k *= fk;
304  e *= fe;
305  }
306  }
307  }
308 }
309 
310 
311 /* We need to know only K(k), and if possible KISS. */
312 double TRANSLINE::ellipk( double k )
313 {
314  double r, lost;
315 
316  ellipke( k, r, lost );
317  return r;
318 }
319 
320 #define MAX_ERROR 0.000001
321 
337 bool TRANSLINE::minimizeZ0Error1D( double* aVar )
338 {
339  double Z0_dest, Z0_current, Z0_result, angl_l_dest, increment, slope, error;
340  int iteration;
341 
342  if( !std::isfinite( m_parameters[Z0_PRM] ) )
343  {
344  *aVar = NAN;
345  return false;
346  }
347 
348  if( ( !std::isfinite( *aVar ) ) || ( *aVar == 0 ) )
349  {
350  *aVar = 0.001;
351  }
352 
353  /* required value of Z0 */
354  Z0_dest = m_parameters[Z0_PRM];
355 
356  /* required value of angl_l */
357  angl_l_dest = m_parameters[ANG_L_PRM];
358 
359  /* Newton's method */
360  iteration = 0;
361 
362  /* compute parameters */
363  calcAnalyze();
364  Z0_current = m_parameters[Z0_PRM];
365 
366  error = fabs( Z0_dest - Z0_current );
367 
368  while( error > MAX_ERROR )
369  {
370  iteration++;
371  increment = *aVar / 100.0;
372  *aVar += increment;
373  /* compute parameters */
374  calcAnalyze();
375  Z0_result = m_parameters[Z0_PRM];
376  /* f(w(n)) = Z0 - Z0(w(n)) */
377  /* f'(w(n)) = -f'(Z0(w(n))) */
378  /* f'(Z0(w(n))) = (Z0(w(n)) - Z0(w(n+delw))/delw */
379  /* w(n+1) = w(n) - f(w(n))/f'(w(n)) */
380  slope = ( Z0_result - Z0_current ) / increment;
381  slope = ( Z0_dest - Z0_current ) / slope - increment;
382  *aVar += slope;
383  if( *aVar <= 0.0 )
384  *aVar = increment;
385  /* find new error */
386  /* compute parameters */
387  calcAnalyze();
388  Z0_current = m_parameters[Z0_PRM];
389  error = fabs( Z0_dest - Z0_current );
390 
391  if( iteration > 100 )
392  break;
393  }
394 
395  /* Compute one last time, but with correct length */
396  m_parameters[Z0_PRM] = Z0_dest;
397  m_parameters[ANG_L_PRM] = angl_l_dest;
400  / 2.0 / M_PI; /* in m */
401  calcAnalyze();
402 
403  /* Restore parameters */
404  m_parameters[Z0_PRM] = Z0_dest;
405  m_parameters[ANG_L_PRM] = angl_l_dest;
408  / 2.0 / M_PI; /* in m */
409  return error <= MAX_ERROR;
410 }
423 void TRANSLINE::setErrorLevel( PRMS_ID aP, char aErrorLevel )
424 {
425  switch( aErrorLevel )
426  {
427  case( TRANSLINE_WARNING ):
429  break;
430  case( TRANSLINE_ERROR ):
432  break;
433  default:
435  break;
436  }
437 }
bool isSelected(enum PRMS_ID aPrmId)
Definition: transline.cpp:116
double GetPropertyInDialog(enum PRMS_ID aPrmId)
virtual void calcAnalyze()
Computation for analysis.
Definition: transline.h:101
bool IsSelectedInDialog(enum PRMS_ID aPrmId)
bool minimizeZ0Error1D(double *)
@function minimizeZ0Error1D
Definition: transline.cpp:337
void SetResultInDialog(int line, const char *text)
void Init()
Definition: transline.cpp:87
#define MAX_ERROR
Definition: transline.cpp:320
double ang_l
Definition: transline.h:123
double er_eff
Definition: transline.h:122
#define MU0
Definition: units.h:62
virtual ~TRANSLINE()
Definition: transline.cpp:82
#define M_PI_2
Definition: transline.cpp:37
void setResult(int, double, const char *)
Definition: transline.cpp:128
void setProperty(enum PRMS_ID aPrmId, double aValue)
Definition: transline.cpp:106
double g
Green component.
Definition: color4d.h:359
virtual void calcSynthesize()
Computation for synthesis.
Definition: transline.h:104
void checkProperties(void)
@function checkProperties
Definition: transline.cpp:161
virtual void showSynthesize()
Shows analysis results and checks for errors / warnings.
Definition: transline.h:110
double b
Blue component.
Definition: color4d.h:360
double ellipk(double)
Definition: transline.cpp:312
#define NR_EPSI
Definition: transline.cpp:245
virtual void show_results()
Shows results.
Definition: transline.h:113
void SetPropertyInDialog(enum PRMS_ID aPrmId, double value)
void analyze()
Definition: transline.cpp:203
void SetPropertyBgColorInDialog(enum PRMS_ID aPrmId, const KIGFX::COLOR4D *aCol)
Function SetPropertyBgColorInDialog Set the background color of a parameter.
double m_parameters[EXTRA_PRMS_COUNT]
Definition: transline.h:120
PRMS_ID
Definition: transline.h:37
KIGFX::COLOR4D okCol
Definition: transline.h:117
virtual void showAnalyze()
Shows synthesis results and checks for errors / warnings.
Definition: transline.h:107
double getProperty(enum PRMS_ID aPrmId)
Definition: transline.cpp:135
void getProperties(void)
@function getProperties
Definition: transline.cpp:144
KIGFX::COLOR4D errCol
Definition: transline.h:115
#define INFINITY
Definition: transline.cpp:32
double len
Definition: transline.h:121
const char * m_Name
Definition: transline.h:85
#define C0
Definition: units.h:63
#define TRANSLINE_ERROR
Definition: transline.h:32
KIGFX::COLOR4D warnCol
Definition: transline.h:116
#define TRANSLINE_OK
Definition: transline.h:30
virtual void synthesize()
Definition: transline.cpp:212
double r
Red component.
Definition: color4d.h:358
void ellipke(double, double &, double &)
Definition: transline.cpp:251
#define TRANSLINE_WARNING
Definition: transline.h:31
double skin_depth()
@function skin_depth calculate skin depth
Definition: transline.cpp:229
void setErrorLevel(PRMS_ID, char)
@function setErrorLevel
Definition: transline.cpp:423
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:98