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 <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 /* Returns a named property value. */
58 double GetPropertyInDialog( enum PRMS_ID aPrmId );
59 
60 // Returns true if the param aPrmId is selected
61 // Has meaning only for params that have a radio button
62 bool IsSelectedInDialog( enum PRMS_ID aPrmId );
63 
69 void SetPropertyBgColorInDialog( enum PRMS_ID aPrmId, const KIGFX::COLOR4D* aCol );
70 
71 
72 /* Constructor creates a transmission line instance. */
74 {
75  m_parameters[MURC_PRM] = 1.0;
76  m_Name = nullptr;
77  ang_l = 0.0; // Electrical length in angle
78  len = 0.0; // length of line
79  er_eff = 1.0; // effective dielectric constant
80  Init();
81 }
82 
83 
84 /* Destructor destroys a transmission line instance. */
86 {
87 }
88 
89 
91 {
92  wxColour wxcol = wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW );
93  okCol = KIGFX::COLOR4D( wxcol );
94  okCol.r = wxcol.Red() / 255.0;
95  okCol.g = wxcol.Green() / 255.0;
96  okCol.b = wxcol.Blue() / 255.0;
97  int i;
98  // Initialize these variables mainly to avoid warnings from a static analyzer
99  for( i = 0; i < EXTRA_PRMS_COUNT; ++i )
100  {
101  m_parameters[i] = 0;
102  }
103 }
104 
105 
106 /* Sets a named property to the given value, access through the
107  * application.
108  */
109 void TRANSLINE::setProperty( enum PRMS_ID aPrmId, double value )
110 {
111  SetPropertyInDialog( aPrmId, value );
112 }
113 
114 
115 /*
116  *Returns true if the param aPrmId is selected
117  * Has meaning only for params that have a radio button
118  */
119 bool TRANSLINE::isSelected( enum PRMS_ID aPrmId )
120 {
121  return IsSelectedInDialog( aPrmId );
122 }
123 
124 
125 /* Puts the text into the given result line.
126 */
127 void TRANSLINE::setResult( int line, const char* text )
128 {
129  SetResultInDialog( line, text );
130 }
131 
132 
133 void TRANSLINE::setResult( int line, double value, const char* text )
134 {
135  SetResultInDialog( line, value, text );
136 }
137 
138 
139 /* Returns a property value. */
140 double TRANSLINE::getProperty( enum PRMS_ID aPrmId )
141 {
142  return GetPropertyInDialog( aPrmId );
143 }
144 
145 
151 {
152  for( int i = 0; i < DUMMY_PRM; ++i )
153  {
154  m_parameters[i] = getProperty( (PRMS_ID) i );
156  }
157 
161 }
162 
163 
170 {
171  // Do not check for values that are results of analyzing / synthesizing
172  // Do not check for transline specific incompatibilities ( like " conductor height should be lesser than dielectric height")
173  if( !std::isfinite( m_parameters[EPSILONR_PRM] ) || m_parameters[EPSILONR_PRM] <= 0 )
175 
176  if( !std::isfinite( m_parameters[TAND_PRM] ) || m_parameters[TAND_PRM] < 0 )
178 
179  if( !std::isfinite( m_parameters[RHO_PRM] ) || m_parameters[RHO_PRM] < 0 )
181 
182  if( !std::isfinite( m_parameters[H_PRM] ) || m_parameters[H_PRM] < 0 )
184 
185  if( !std::isfinite( m_parameters[TWISTEDPAIR_TWIST_PRM] )
188 
189  if( !std::isfinite( m_parameters[STRIPLINE_A_PRM] ) || m_parameters[STRIPLINE_A_PRM] <= 0 )
191 
192  if( !std::isfinite( m_parameters[H_T_PRM] ) || m_parameters[H_T_PRM] <= 0 )
194 
195  // How can we check ROUGH_PRM ?
196 
197  if( !std::isfinite( m_parameters[MUR_PRM] ) || m_parameters[MUR_PRM] < 0 )
199 
200  if( !std::isfinite( m_parameters[TWISTEDPAIR_EPSILONR_ENV_PRM] )
203 
204  if( !std::isfinite( m_parameters[MURC_PRM] ) || m_parameters[MURC_PRM] < 0 )
206 
207  if( !std::isfinite( m_parameters[FREQUENCY_PRM] ) || m_parameters[FREQUENCY_PRM] <= 0 )
209 }
210 
212 {
213  getProperties();
214  checkProperties();
215  calcAnalyze();
216  showAnalyze();
217  show_results();
218 }
219 
221 {
222  getProperties();
223  checkProperties();
224  calcSynthesize();
225  showSynthesize();
226  show_results();
227 }
228 
229 
236 #include <cstdio>
238 {
239  double depth;
240  depth = 1.0
241  / sqrt( M_PI * m_parameters[FREQUENCY_PRM] * m_parameters[MURC_PRM] * MU0
242  * m_parameters[SIGMA_PRM] );
243  return depth;
244 }
245 
246 
247 /* *****************************************************************
248 ********** **********
249 ********** mathematical functions **********
250 ********** **********
251 ***************************************************************** */
252 
253 #define NR_EPSI 2.2204460492503131e-16
254 
255 /* The function computes the complete elliptic integral of first kind
256  * K() and the second kind E() using the arithmetic-geometric mean
257  * algorithm (AGM) by Abramowitz and Stegun.
258  */
259 void TRANSLINE::ellipke( double arg, double& k, double& e )
260 {
261  int iMax = 16;
262 
263  if( arg == 1.0 )
264  {
265  k = INFINITY; // infinite
266  e = 0;
267  }
268  else if( std::isinf( arg ) && arg < 0 )
269  {
270  k = 0;
271  e = INFINITY; // infinite
272  }
273  else
274  {
275  double a, b, c, fr, s, fk = 1, fe = 1, t, da = arg;
276  int i;
277 
278  if( arg < 0 )
279  {
280  fk = 1 / sqrt( 1 - arg );
281  fe = sqrt( 1 - arg );
282  da = -arg / ( 1 - arg );
283  }
284 
285  a = 1;
286  b = sqrt( 1 - da );
287  c = sqrt( da );
288  fr = 0.5;
289  s = fr * c * c;
290 
291  for( i = 0; i < iMax; i++ )
292  {
293  t = ( a + b ) / 2;
294  c = ( a - b ) / 2;
295  b = sqrt( a * b );
296  a = t;
297  fr *= 2;
298  s += fr * c * c;
299 
300  if( c / a < NR_EPSI )
301  break;
302  }
303 
304  if( i >= iMax )
305  {
306  k = 0;
307  e = 0;
308  }
309  else
310  {
311  k = M_PI_2 / a;
312  e = M_PI_2 * ( 1 - s ) / a;
313  if( arg < 0 )
314  {
315  k *= fk;
316  e *= fe;
317  }
318  }
319  }
320 }
321 
322 
323 /* We need to know only K(k), and if possible KISS. */
324 double TRANSLINE::ellipk( double k )
325 {
326  double r, lost;
327 
328  ellipke( k, r, lost );
329  return r;
330 }
331 
332 #define MAX_ERROR 0.000001
333 
349 bool TRANSLINE::minimizeZ0Error1D( double* aVar )
350 {
351  double Z0_dest, Z0_current, Z0_result, angl_l_dest, increment, slope, error;
352  int iteration;
353 
354  if( !std::isfinite( m_parameters[Z0_PRM] ) )
355  {
356  *aVar = NAN;
357  return false;
358  }
359 
360  if( ( !std::isfinite( *aVar ) ) || ( *aVar == 0 ) )
361  *aVar = 0.001;
362 
363  /* required value of Z0 */
364  Z0_dest = m_parameters[Z0_PRM];
365 
366  /* required value of angl_l */
367  angl_l_dest = m_parameters[ANG_L_PRM];
368 
369  /* Newton's method */
370  iteration = 0;
371 
372  /* compute parameters */
373  calcAnalyze();
374  Z0_current = m_parameters[Z0_PRM];
375 
376  error = fabs( Z0_dest - Z0_current );
377 
378  while( error > MAX_ERROR )
379  {
380  iteration++;
381  increment = *aVar / 100.0;
382  *aVar += increment;
383  /* compute parameters */
384  calcAnalyze();
385  Z0_result = m_parameters[Z0_PRM];
386  /* f(w(n)) = Z0 - Z0(w(n)) */
387  /* f'(w(n)) = -f'(Z0(w(n))) */
388  /* f'(Z0(w(n))) = (Z0(w(n)) - Z0(w(n+delw))/delw */
389  /* w(n+1) = w(n) - f(w(n))/f'(w(n)) */
390  slope = ( Z0_result - Z0_current ) / increment;
391  slope = ( Z0_dest - Z0_current ) / slope - increment;
392  *aVar += slope;
393 
394  if( *aVar <= 0.0 )
395  *aVar = increment;
396 
397  /* find new error */
398  /* compute parameters */
399  calcAnalyze();
400  Z0_current = m_parameters[Z0_PRM];
401  error = fabs( Z0_dest - Z0_current );
402 
403  if( iteration > 100 )
404  break;
405  }
406 
407  /* Compute one last time, but with correct length */
408  m_parameters[Z0_PRM] = Z0_dest;
409  m_parameters[ANG_L_PRM] = angl_l_dest;
412  / 2.0 / M_PI; /* in m */
413  calcAnalyze();
414 
415  /* Restore parameters */
416  m_parameters[Z0_PRM] = Z0_dest;
417  m_parameters[ANG_L_PRM] = angl_l_dest;
420  / 2.0 / M_PI; /* in m */
421  return error <= MAX_ERROR;
422 }
435 void TRANSLINE::setErrorLevel( PRMS_ID aP, char aErrorLevel )
436 {
437  switch( aErrorLevel )
438  {
441  default: SetPropertyBgColorInDialog( aP, &okCol ); break;
442  }
443 }
bool isSelected(enum PRMS_ID aPrmId)
Definition: transline.cpp:119
double GetPropertyInDialog(enum PRMS_ID aPrmId)
virtual void calcAnalyze()
Computation for analysis.
Definition: transline.h:102
bool IsSelectedInDialog(enum PRMS_ID aPrmId)
bool minimizeZ0Error1D(double *)
@function minimizeZ0Error1D
Definition: transline.cpp:349
void SetResultInDialog(int line, const char *text)
void Init()
Definition: transline.cpp:90
#define MAX_ERROR
Definition: transline.cpp:332
double ang_l
Definition: transline.h:134
double er_eff
Definition: transline.h:133
#define MU0
Definition: units.h:62
virtual ~TRANSLINE()
Definition: transline.cpp:85
#define M_PI_2
Definition: transline.cpp:40
void setResult(int, double, const char *)
Definition: transline.cpp:133
void setProperty(enum PRMS_ID aPrmId, double aValue)
Definition: transline.cpp:109
double g
Green component.
Definition: color4d.h:378
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:379
double ellipk(double)
Definition: transline.cpp:324
#define NR_EPSI
Definition: transline.cpp:253
virtual void show_results()
Shows results.
Definition: transline.h:122
void SetPropertyInDialog(enum PRMS_ID aPrmId, double value)
void analyze()
Definition: transline.cpp:211
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:169
double m_parameters[EXTRA_PRMS_COUNT]
Definition: transline.h:131
PRMS_ID
Definition: transline.h:36
void getProperties()
@function getProperties
Definition: transline.cpp:150
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:140
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:63
#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:220
double r
Red component.
Definition: color4d.h:377
void ellipke(double, double &, double &)
Definition: transline.cpp:259
#define TRANSLINE_WARNING
Definition: transline.h:30
double skin_depth()
@function skin_depth calculate skin depth
Definition: transline.cpp:237
void setErrorLevel(PRMS_ID, char)
@function setErrorLevel
Definition: transline.cpp:435
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:103