KiCad PCB EDA Suite
Loading...
Searching...
No Matches
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 Init();
78}
79
80
81/* Destructor destroys a transmission line instance. */
83{
84}
85
86
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 */
106void 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 */
117{
118 return IsSelectedInDialog( aPrmId );
119}
120
121
122/* Puts the text into the given result line.
123*/
124void TRANSLINE::setResult( int line, const char* text )
125{
126 SetResultInDialog( line, text );
127}
128
129
130void TRANSLINE::setResult( int line, double value, const char* text )
131{
132 SetResultInDialog( line, value, text );
133}
134
135
136/* Returns a property value. */
137double TRANSLINE::getProperty( enum PRMS_ID aPrmId )
138{
139 return GetPropertyInDialog( aPrmId );
140}
141
142
148{
149 for( int i = 0; i < DUMMY_PRM; ++i )
150 {
151 m_parameters[i] = getProperty( (PRMS_ID) i );
153 }
154
158}
159
160
167{
168 // Do not check for values that are results of analyzing / synthesizing
169 // Do not check for transline specific incompatibilities ( like " conductor height should be lesser than dielectric height")
170 if( !std::isfinite( m_parameters[EPSILONR_PRM] ) || m_parameters[EPSILONR_PRM] <= 0 )
172
173 if( !std::isfinite( m_parameters[TAND_PRM] ) || m_parameters[TAND_PRM] < 0 )
175
176 if( !std::isfinite( m_parameters[RHO_PRM] ) || m_parameters[RHO_PRM] < 0 )
178
179 if( !std::isfinite( m_parameters[H_PRM] ) || m_parameters[H_PRM] < 0 )
181
182 if( !std::isfinite( m_parameters[TWISTEDPAIR_TWIST_PRM] )
185
186 if( !std::isfinite( m_parameters[STRIPLINE_A_PRM] ) || m_parameters[STRIPLINE_A_PRM] <= 0 )
188
189 if( !std::isfinite( m_parameters[H_T_PRM] ) || m_parameters[H_T_PRM] <= 0 )
191
192 // How can we check ROUGH_PRM ?
193
194 if( !std::isfinite( m_parameters[MUR_PRM] ) || m_parameters[MUR_PRM] < 0 )
196
197 if( !std::isfinite( m_parameters[TWISTEDPAIR_EPSILONR_ENV_PRM] )
200
201 if( !std::isfinite( m_parameters[MURC_PRM] ) || m_parameters[MURC_PRM] < 0 )
203
204 if( !std::isfinite( m_parameters[FREQUENCY_PRM] ) || m_parameters[FREQUENCY_PRM] <= 0 )
206}
207
209{
212 calcAnalyze();
213 showAnalyze();
214 show_results();
215}
216
218{
223 show_results();
224}
225
226
233#include <cstdio>
235{
236 double depth;
237 depth = 1.0
240 return depth;
241}
242
243
244/* *****************************************************************
245********** **********
246********** mathematical functions **********
247********** **********
248***************************************************************** */
249
250#define NR_EPSI 2.2204460492503131e-16
251
252/* The function computes the complete elliptic integral of first kind
253 * K() and the second kind E() using the arithmetic-geometric mean
254 * algorithm (AGM) by Abramowitz and Stegun.
255 */
256void TRANSLINE::ellipke( double arg, double& k, double& e )
257{
258 int iMax = 16;
259
260 if( arg == 1.0 )
261 {
262 k = INFINITY; // infinite
263 e = 0;
264 }
265 else if( std::isinf( arg ) && arg < 0 )
266 {
267 k = 0;
268 e = INFINITY; // infinite
269 }
270 else
271 {
272 double a, b, c, fr, s, fk = 1, fe = 1, t, da = arg;
273 int i;
274
275 if( arg < 0 )
276 {
277 fk = 1 / sqrt( 1 - arg );
278 fe = sqrt( 1 - arg );
279 da = -arg / ( 1 - arg );
280 }
281
282 a = 1;
283 b = sqrt( 1 - da );
284 c = sqrt( da );
285 fr = 0.5;
286 s = fr * c * c;
287
288 for( i = 0; i < iMax; i++ )
289 {
290 t = ( a + b ) / 2;
291 c = ( a - b ) / 2;
292 b = sqrt( a * b );
293 a = t;
294 fr *= 2;
295 s += fr * c * c;
296
297 if( c / a < NR_EPSI )
298 break;
299 }
300
301 if( i >= iMax )
302 {
303 k = 0;
304 e = 0;
305 }
306 else
307 {
308 k = M_PI_2 / a;
309 e = M_PI_2 * ( 1 - s ) / a;
310 if( arg < 0 )
311 {
312 k *= fk;
313 e *= fe;
314 }
315 }
316 }
317}
318
319
320/* We need to know only K(k), and if possible KISS. */
321double TRANSLINE::ellipk( double k )
322{
323 double r, lost;
324
325 ellipke( k, r, lost );
326 return r;
327}
328
329#define MAX_ERROR 0.000001
330
347{
348 double Z0_dest, Z0_current, Z0_result, angl_l_dest, increment, slope, error;
349 int iteration;
350
351 if( !std::isfinite( m_parameters[Z0_PRM] ) )
352 {
353 *aVar = NAN;
354 return false;
355 }
356
357 if( ( !std::isfinite( *aVar ) ) || ( *aVar == 0 ) )
358 *aVar = 0.001;
359
360 /* required value of Z0 */
361 Z0_dest = m_parameters[Z0_PRM];
362
363 /* required value of angl_l */
364 angl_l_dest = m_parameters[ANG_L_PRM];
365
366 /* Newton's method */
367 iteration = 0;
368
369 /* compute parameters */
370 calcAnalyze();
371 Z0_current = m_parameters[Z0_PRM];
372
373 error = fabs( Z0_dest - Z0_current );
374
375 while( error > MAX_ERROR )
376 {
377 iteration++;
378 increment = *aVar / 100.0;
379 *aVar += increment;
380 /* compute parameters */
381 calcAnalyze();
382 Z0_result = m_parameters[Z0_PRM];
383 /* f(w(n)) = Z0 - Z0(w(n)) */
384 /* f'(w(n)) = -f'(Z0(w(n))) */
385 /* f'(Z0(w(n))) = (Z0(w(n)) - Z0(w(n+delw))/delw */
386 /* w(n+1) = w(n) - f(w(n))/f'(w(n)) */
387 slope = ( Z0_result - Z0_current ) / increment;
388 slope = ( Z0_dest - Z0_current ) / slope - increment;
389 *aVar += slope;
390
391 if( *aVar <= 0.0 )
392 *aVar = increment;
393
394 /* find new error */
395 /* compute parameters */
396 calcAnalyze();
397 Z0_current = m_parameters[Z0_PRM];
398 error = fabs( Z0_dest - Z0_current );
399
400 if( iteration > 100 )
401 break;
402 }
403
404 /* Compute one last time, but with correct length */
405 m_parameters[Z0_PRM] = Z0_dest;
406 m_parameters[ANG_L_PRM] = angl_l_dest;
409 / 2.0 / M_PI; /* in m */
410 calcAnalyze();
411
412 /* Restore parameters */
413 m_parameters[Z0_PRM] = Z0_dest;
414 m_parameters[ANG_L_PRM] = angl_l_dest;
417 / 2.0 / M_PI; /* in m */
418 return error <= MAX_ERROR;
419}
432void TRANSLINE::setErrorLevel( PRMS_ID aP, char aErrorLevel )
433{
434 switch( aErrorLevel )
435 {
438 default: SetPropertyBgColorInDialog( aP, &okCol ); break;
439 }
440}
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:104
double r
Red component.
Definition: color4d.h:392
double g
Green component.
Definition: color4d.h:393
double b
Blue component.
Definition: color4d.h:394
virtual ~TRANSLINE()
Definition: transline.cpp:82
virtual void showSynthesize()
Shows analysis results and checks for errors / warnings.
Definition: transline.h:117
bool isSelected(enum PRMS_ID aPrmId)
Definition: transline.cpp:116
double ellipk(double)
Definition: transline.cpp:321
KIGFX::COLOR4D warnCol
Definition: transline.h:127
double getProperty(enum PRMS_ID aPrmId)
Definition: transline.cpp:137
void Init()
Definition: transline.cpp:87
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:130
bool minimizeZ0Error1D(double *)
@function minimizeZ0Error1D
Definition: transline.cpp:346
double m_parameters[EXTRA_PRMS_COUNT]
Definition: transline.h:131
KIGFX::COLOR4D errCol
Definition: transline.h:126
void getProperties()
@function getProperties
Definition: transline.cpp:147
void checkProperties()
@function checkProperties
Definition: transline.cpp:166
void analyze()
Definition: transline.cpp:208
virtual void synthesize()
Definition: transline.cpp:217
void ellipke(double, double &, double &)
Definition: transline.cpp:256
const char * m_Name
Definition: transline.h:84
void setProperty(enum PRMS_ID aPrmId, double aValue)
Definition: transline.cpp:106
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:234
virtual void show_results()
Shows results.
Definition: transline.h:122
virtual void calcAnalyze()
Computation for analysis.
Definition: transline.h:102
void setErrorLevel(PRMS_ID, char)
@function setErrorLevel
Definition: transline.cpp:432
#define MAX_ERROR
Definition: coplanar.cpp:190
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 *aText)
bool IsSelectedInDialog(enum PRMS_ID aPrmId)
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:250
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