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 <[email protected]>
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 <wx/colour.h>
29 #include <wx/settings.h>
30 
31 #include "transline.h"
32 #include "units.h"
33 
34 #ifndef INFINITY
35 #define INFINITY std::numeric_limits<double>::infinity()
36 #endif
37 
38 
39 #ifndef M_PI_2
40 #define M_PI_2 ( M_PI / 2 )
41 #endif
42 
43 
44 // Functions to Read/Write parameters in pcb_calculator main frame:
45 // They are wrapper to actual functions, so all transline functions do not
46 // depend on Graphic User Interface
47 void SetPropertyInDialog( enum PRMS_ID aPrmId, double value );
48 
49 /* Puts the text into the given result line.
50 */
51 void SetResultInDialog( int line, const char* text );
52 
53 /* print aValue into the given result line.
54 */
55 void SetResultInDialog( int aLineNumber, double aValue, const char* aText );
56 
57 /* Puts the text into the given result line.
58 */
59 void SetResultInDialog( int line, const wxString& aText );
60 
61 /* print aValue into the given result line.
62 */
63 void SetResultInDialog( int aLineNumber, double aValue, const wxString& aText );
64 
65 /* Returns a named property value. */
66 double GetPropertyInDialog( enum PRMS_ID aPrmId );
67 
68 // Returns true if the param aPrmId is selected
69 // Has meaning only for params that have a radio button
70 bool IsSelectedInDialog( enum PRMS_ID aPrmId );
71 
77 void SetPropertyBgColorInDialog( enum PRMS_ID aPrmId, const KIGFX::COLOR4D* aCol );
78 
79 
80 /* Constructor creates a transmission line instance. */
82 {
83  m_parameters[MURC_PRM] = 1.0;
84  m_Name = nullptr;
85  ang_l = 0.0; // Electrical length in angle
86  len = 0.0; // length of line
87  er_eff = 1.0; // effective dielectric constant
88  Init();
89 }
90 
91 
92 /* Destructor destroys a transmission line instance. */
94 {
95 }
96 
97 
99 {
100  wxColour wxcol = wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW );
101  okCol = KIGFX::COLOR4D( wxcol );
102  okCol.r = wxcol.Red() / 255.0;
103  okCol.g = wxcol.Green() / 255.0;
104  okCol.b = wxcol.Blue() / 255.0;
105  int i;
106  // Initialize these variables mainly to avoid warnings from a static analyzer
107  for( i = 0; i < EXTRA_PRMS_COUNT; ++i )
108  {
109  m_parameters[i] = 0;
110  }
111 }
112 
113 
114 /* Sets a named property to the given value, access through the
115  * application.
116  */
117 void TRANSLINE::setProperty( enum PRMS_ID aPrmId, double value )
118 {
119  SetPropertyInDialog( aPrmId, value );
120 }
121 
122 
123 /*
124  *Returns true if the param aPrmId is selected
125  * Has meaning only for params that have a radio button
126  */
127 bool TRANSLINE::isSelected( enum PRMS_ID aPrmId )
128 {
129  return IsSelectedInDialog( aPrmId );
130 }
131 
132 
133 /* Puts the text into the given result line.
134 */
135 void TRANSLINE::setResult( int line, const wxString& text )
136 {
137  SetResultInDialog( line, text );
138 }
139 
140 
141 void TRANSLINE::setResult( int line, double value, const wxString& text )
142 {
143  SetResultInDialog( line, value, text );
144 }
145 
146 
147 /* Returns a property value. */
148 double TRANSLINE::getProperty( enum PRMS_ID aPrmId )
149 {
150  return GetPropertyInDialog( aPrmId );
151 }
152 
153 
159 {
160  for( int i = 0; i < DUMMY_PRM; ++i )
161  {
162  m_parameters[i] = getProperty( (PRMS_ID) i );
164  }
165 
169 }
170 
171 
178 {
179  // Do not check for values that are results of analyzing / synthesizing
180  // Do not check for transline specific incompatibilities ( like " conductor height should be lesser than dielectric height")
181  if( !std::isfinite( m_parameters[EPSILONR_PRM] ) || m_parameters[EPSILONR_PRM] <= 0 )
183 
184  if( !std::isfinite( m_parameters[TAND_PRM] ) || m_parameters[TAND_PRM] < 0 )
186 
187  if( !std::isfinite( m_parameters[RHO_PRM] ) || m_parameters[RHO_PRM] < 0 )
189 
190  if( !std::isfinite( m_parameters[H_PRM] ) || m_parameters[H_PRM] < 0 )
192 
193  if( !std::isfinite( m_parameters[TWISTEDPAIR_TWIST_PRM] )
196 
197  if( !std::isfinite( m_parameters[STRIPLINE_A_PRM] ) || m_parameters[STRIPLINE_A_PRM] <= 0 )
199 
200  if( !std::isfinite( m_parameters[H_T_PRM] ) || m_parameters[H_T_PRM] <= 0 )
202 
203  // How can we check ROUGH_PRM ?
204 
205  if( !std::isfinite( m_parameters[MUR_PRM] ) || m_parameters[MUR_PRM] < 0 )
207 
208  if( !std::isfinite( m_parameters[TWISTEDPAIR_EPSILONR_ENV_PRM] )
211 
212  if( !std::isfinite( m_parameters[MURC_PRM] ) || m_parameters[MURC_PRM] < 0 )
214 
215  if( !std::isfinite( m_parameters[FREQUENCY_PRM] ) || m_parameters[FREQUENCY_PRM] <= 0 )
217 }
218 
220 {
221  getProperties();
222  checkProperties();
223  calcAnalyze();
224  showAnalyze();
225  show_results();
226 }
227 
229 {
230  getProperties();
231  checkProperties();
232  calcSynthesize();
233  showSynthesize();
234  show_results();
235 }
236 
237 
244 #include <cstdio>
246 {
247  double depth;
248  depth = 1.0
249  / sqrt( M_PI * m_parameters[FREQUENCY_PRM] * m_parameters[MURC_PRM] * MU0
250  * m_parameters[SIGMA_PRM] );
251  return depth;
252 }
253 
254 
255 /* *****************************************************************
256 ********** **********
257 ********** mathematical functions **********
258 ********** **********
259 ***************************************************************** */
260 
261 #define NR_EPSI 2.2204460492503131e-16
262 
263 /* The function computes the complete elliptic integral of first kind
264  * K() and the second kind E() using the arithmetic-geometric mean
265  * algorithm (AGM) by Abramowitz and Stegun.
266  */
267 void TRANSLINE::ellipke( double arg, double& k, double& e )
268 {
269  int iMax = 16;
270 
271  if( arg == 1.0 )
272  {
273  k = INFINITY; // infinite
274  e = 0;
275  }
276  else if( std::isinf( arg ) && arg < 0 )
277  {
278  k = 0;
279  e = INFINITY; // infinite
280  }
281  else
282  {
283  double a, b, c, fr, s, fk = 1, fe = 1, t, da = arg;
284  int i;
285 
286  if( arg < 0 )
287  {
288  fk = 1 / sqrt( 1 - arg );
289  fe = sqrt( 1 - arg );
290  da = -arg / ( 1 - arg );
291  }
292 
293  a = 1;
294  b = sqrt( 1 - da );
295  c = sqrt( da );
296  fr = 0.5;
297  s = fr * c * c;
298 
299  for( i = 0; i < iMax; i++ )
300  {
301  t = ( a + b ) / 2;
302  c = ( a - b ) / 2;
303  b = sqrt( a * b );
304  a = t;
305  fr *= 2;
306  s += fr * c * c;
307 
308  if( c / a < NR_EPSI )
309  break;
310  }
311 
312  if( i >= iMax )
313  {
314  k = 0;
315  e = 0;
316  }
317  else
318  {
319  k = M_PI_2 / a;
320  e = M_PI_2 * ( 1 - s ) / a;
321  if( arg < 0 )
322  {
323  k *= fk;
324  e *= fe;
325  }
326  }
327  }
328 }
329 
330 
331 /* We need to know only K(k), and if possible KISS. */
332 double TRANSLINE::ellipk( double k )
333 {
334  double r, lost;
335 
336  ellipke( k, r, lost );
337  return r;
338 }
339 
340 #define MAX_ERROR 0.000001
341 
357 bool TRANSLINE::minimizeZ0Error1D( double* aVar )
358 {
359  double Z0_dest, Z0_current, Z0_result, angl_l_dest, increment, slope, error;
360  int iteration;
361 
362  if( !std::isfinite( m_parameters[Z0_PRM] ) )
363  {
364  *aVar = NAN;
365  return false;
366  }
367 
368  if( ( !std::isfinite( *aVar ) ) || ( *aVar == 0 ) )
369  *aVar = 0.001;
370 
371  /* required value of Z0 */
372  Z0_dest = m_parameters[Z0_PRM];
373 
374  /* required value of angl_l */
375  angl_l_dest = m_parameters[ANG_L_PRM];
376 
377  /* Newton's method */
378  iteration = 0;
379 
380  /* compute parameters */
381  calcAnalyze();
382  Z0_current = m_parameters[Z0_PRM];
383 
384  error = fabs( Z0_dest - Z0_current );
385 
386  while( error > MAX_ERROR )
387  {
388  iteration++;
389  increment = *aVar / 100.0;
390  *aVar += increment;
391  /* compute parameters */
392  calcAnalyze();
393  Z0_result = m_parameters[Z0_PRM];
394  /* f(w(n)) = Z0 - Z0(w(n)) */
395  /* f'(w(n)) = -f'(Z0(w(n))) */
396  /* f'(Z0(w(n))) = (Z0(w(n)) - Z0(w(n+delw))/delw */
397  /* w(n+1) = w(n) - f(w(n))/f'(w(n)) */
398  slope = ( Z0_result - Z0_current ) / increment;
399  slope = ( Z0_dest - Z0_current ) / slope - increment;
400  *aVar += slope;
401 
402  if( *aVar <= 0.0 )
403  *aVar = increment;
404 
405  /* find new error */
406  /* compute parameters */
407  calcAnalyze();
408  Z0_current = m_parameters[Z0_PRM];
409  error = fabs( Z0_dest - Z0_current );
410 
411  if( iteration > 100 )
412  break;
413  }
414 
415  /* Compute one last time, but with correct length */
416  m_parameters[Z0_PRM] = Z0_dest;
417  m_parameters[ANG_L_PRM] = angl_l_dest;
420  / 2.0 / M_PI; /* in m */
421  calcAnalyze();
422 
423  /* Restore parameters */
424  m_parameters[Z0_PRM] = Z0_dest;
425  m_parameters[ANG_L_PRM] = angl_l_dest;
428  / 2.0 / M_PI; /* in m */
429  return error <= MAX_ERROR;
430 }
443 void TRANSLINE::setErrorLevel( PRMS_ID aP, char aErrorLevel )
444 {
445  switch( aErrorLevel )
446  {
449  default: SetPropertyBgColorInDialog( aP, &okCol ); break;
450  }
451 }
bool isSelected(enum PRMS_ID aPrmId)
Definition: transline.cpp:127
double GetPropertyInDialog(enum PRMS_ID aPrmId)
void setResult(int, const wxString &)
Definition: transline.cpp:135
virtual void calcAnalyze()
Computation for analysis.
Definition: transline.h:102
bool IsSelectedInDialog(enum PRMS_ID aPrmId)
bool minimizeZ0Error1D(double *)
@function minimizeZ0Error1D
Definition: transline.cpp:357
void SetResultInDialog(int line, const char *text)
void Init()
Definition: transline.cpp:98
#define MAX_ERROR
Definition: transline.cpp:340
double ang_l
Definition: transline.h:134
double er_eff
Definition: transline.h:133
#define MU0
Definition: units.h:60
virtual ~TRANSLINE()
Definition: transline.cpp:93
#define M_PI_2
Definition: transline.cpp:40
void setProperty(enum PRMS_ID aPrmId, double aValue)
Definition: transline.cpp:117
double g
Green component.
Definition: color4d.h:385
virtual void calcSynthesize()
Computation for synthesis.
Definition: transline.h:107
virtual void showSynthesize()
Shows analysis results and checks for errors / warnings.
Definition: transline.h:117
double b
Blue component.
Definition: color4d.h:386
double ellipk(double)
Definition: transline.cpp:332
#define NR_EPSI
Definition: transline.cpp:261
virtual void show_results()
Shows results.
Definition: transline.h:122
void SetPropertyInDialog(enum PRMS_ID aPrmId, double value)
void analyze()
Definition: transline.cpp:219
void SetPropertyBgColorInDialog(enum PRMS_ID aPrmId, const KIGFX::COLOR4D *aCol)
Function SetPropertyBgColorInDialog Set the background color of a parameter.
void checkProperties()
@function checkProperties
Definition: transline.cpp:177
double m_parameters[EXTRA_PRMS_COUNT]
Definition: transline.h:131
PRMS_ID
Definition: transline.h:36
void getProperties()
@function getProperties
Definition: transline.cpp:158
KIGFX::COLOR4D okCol
Definition: transline.h:128
virtual void showAnalyze()
Shows synthesis results and checks for errors / warnings.
Definition: transline.h:112
double getProperty(enum PRMS_ID aPrmId)
Definition: transline.cpp:148
KIGFX::COLOR4D errCol
Definition: transline.h:126
#define INFINITY
Definition: transline.cpp:35
double len
Definition: transline.h:132
E_SERIE r
Definition: eserie.cpp:41
const char * m_Name
Definition: transline.h:84
#define C0
Definition: units.h:61
#define TRANSLINE_ERROR
Definition: transline.h:31
KIGFX::COLOR4D warnCol
Definition: transline.h:127
#define TRANSLINE_OK
Definition: transline.h:29
virtual void synthesize()
Definition: transline.cpp:228
double r
Red component.
Definition: color4d.h:384
void ellipke(double, double &, double &)
Definition: transline.cpp:267
#define TRANSLINE_WARNING
Definition: transline.h:30
double skin_depth()
@function skin_depth calculate skin depth
Definition: transline.cpp:245
void setErrorLevel(PRMS_ID, char)
@function setErrorLevel
Definition: transline.cpp:443
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:103