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
47void SetPropertyInDialog( enum PRMS_ID aPrmId, double value );
48
49/* Puts the text into the given result line.
50*/
51void SetResultInDialog( int line, const char* text );
52
53/* print aValue into the given result line.
54*/
55void SetResultInDialog( int aLineNumber, double aValue, const char* aText );
56
57/* Returns a named property value. */
58double 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
62bool IsSelectedInDialog( enum PRMS_ID aPrmId );
63
69void SetPropertyBgColorInDialog( enum PRMS_ID aPrmId, const KIGFX::COLOR4D* aCol );
70
71
72/* Constructor creates a transmission line instance. */
74{
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 */
109void 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 */
120{
121 return IsSelectedInDialog( aPrmId );
122}
123
124
125/* Puts the text into the given result line.
126*/
127void TRANSLINE::setResult( int line, const char* text )
128{
129 SetResultInDialog( line, text );
130}
131
132
133void TRANSLINE::setResult( int line, double value, const char* text )
134{
135 SetResultInDialog( line, value, text );
136}
137
138
139/* Returns a property value. */
140double 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{
215 calcAnalyze();
216 showAnalyze();
217 show_results();
218}
219
221{
226 show_results();
227}
228
229
236#include <cstdio>
238{
239 double depth;
240 depth = 1.0
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 */
259void 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. */
324double 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
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}
435void TRANSLINE::setErrorLevel( PRMS_ID aP, char aErrorLevel )
436{
437 switch( aErrorLevel )
438 {
441 default: SetPropertyBgColorInDialog( aP, &okCol ); break;
442 }
443}
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:104
double r
Red component.
Definition: color4d.h:384
double g
Green component.
Definition: color4d.h:385
double b
Blue component.
Definition: color4d.h:386
virtual ~TRANSLINE()
Definition: transline.cpp:85
virtual void showSynthesize()
Shows analysis results and checks for errors / warnings.
Definition: transline.h:117
bool isSelected(enum PRMS_ID aPrmId)
Definition: transline.cpp:119
double ellipk(double)
Definition: transline.cpp:324
KIGFX::COLOR4D warnCol
Definition: transline.h:127
double getProperty(enum PRMS_ID aPrmId)
Definition: transline.cpp:140
void Init()
Definition: transline.cpp:90
virtual void calcSynthesize()
Computation for synthesis.
Definition: transline.h:107
KIGFX::COLOR4D okCol
Definition: transline.h:128
void setResult(int, double, const char *)
Definition: transline.cpp:133
bool minimizeZ0Error1D(double *)
@function minimizeZ0Error1D
Definition: transline.cpp:349
double m_parameters[EXTRA_PRMS_COUNT]
Definition: transline.h:131
KIGFX::COLOR4D errCol
Definition: transline.h:126
void getProperties()
@function getProperties
Definition: transline.cpp:150
void checkProperties()
@function checkProperties
Definition: transline.cpp:169
void analyze()
Definition: transline.cpp:211
virtual void synthesize()
Definition: transline.cpp:220
double len
Definition: transline.h:132
void ellipke(double, double &, double &)
Definition: transline.cpp:259
const char * m_Name
Definition: transline.h:84
void setProperty(enum PRMS_ID aPrmId, double aValue)
Definition: transline.cpp:109
virtual void showAnalyze()
Shows synthesis results and checks for errors / warnings.
Definition: transline.h:112
double skin_depth()
@function skin_depth calculate skin depth
Definition: transline.cpp:237
double er_eff
Definition: transline.h:133
virtual void show_results()
Shows results.
Definition: transline.h:122
double ang_l
Definition: transline.h:134
virtual void calcAnalyze()
Computation for analysis.
Definition: transline.h:102
void setErrorLevel(PRMS_ID, char)
@function setErrorLevel
Definition: transline.cpp:435
E_SERIE r
Definition: eserie.cpp:41
void SetPropertyInDialog(enum PRMS_ID aPrmId, double value)
void SetPropertyBgColorInDialog(enum PRMS_ID aPrmId, const KIGFX::COLOR4D *aCol)
Function SetPropertyBgColorInDialog Set the background color of a parameter.
double GetPropertyInDialog(enum PRMS_ID aPrmId)
void SetResultInDialog(int line, const char *text)
#define NR_EPSI
Definition: transline.cpp:253
#define MAX_ERROR
Definition: transline.cpp:332
bool IsSelectedInDialog(enum PRMS_ID aPrmId)
#define INFINITY
Definition: transline.cpp:35
#define M_PI_2
Definition: transline.cpp:40
@ EPSILON_EFF_PRM
Definition: transline.h:74
@ SIGMA_PRM
Definition: transline.h:69
@ SKIN_DEPTH_PRM
Definition: transline.h:70
@ EXTRA_PRMS_COUNT
Definition: transline.h:75
PRMS_ID
Definition: transline.h:37
@ TWISTEDPAIR_EPSILONR_ENV_PRM
Definition: transline.h:49
@ FREQUENCY_PRM
Definition: transline.h:51
@ DUMMY_PRM
Definition: transline.h:61
@ RHO_PRM
Definition: transline.h:41
@ MURC_PRM
Definition: transline.h:50
@ MUR_PRM
Definition: transline.h:48
@ STRIPLINE_A_PRM
Definition: transline.h:45
@ 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
@ H_T_PRM
Definition: transline.h:44
@ TWISTEDPAIR_TWIST_PRM
Definition: transline.h:43
@ EPSILONR_PRM
Definition: transline.h:39
@ H_PRM
Definition: transline.h:42
#define TRANSLINE_OK
Definition: transline.h:29
#define TRANSLINE_WARNING
Definition: transline.h:30
#define TRANSLINE_ERROR
Definition: transline.h:31
#define MU0
Definition: units.h:60
#define C0
Definition: units.h:61