KiCad PCB EDA Suite
Loading...
Searching...
No Matches
transline_calculation_base.cpp
Go to the documentation of this file.
1/*
2 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this package; see the file COPYING. If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
22
23
25namespace TC = TRANSLINE_CALCULATIONS;
26
27
28void TRANSLINE_CALCULATION_BASE::InitProperties( const std::initializer_list<TRANSLINE_PARAMETERS>& aParams )
29{
30 for( const TRANSLINE_PARAMETERS& param : aParams )
31 m_parameters[param] = 0.0;
32}
33
34
35std::unordered_map<TRANSLINE_PARAMETERS, std::pair<double, TRANSLINE_STATUS>>&
37{
39 return m_analysisStatus;
40}
41
42
43std::unordered_map<TRANSLINE_PARAMETERS, std::pair<double, TRANSLINE_STATUS>>&
45{
47 return m_synthesisStatus;
48}
49
50
52 const TRANSLINE_STATUS aStatus )
53{
54 m_analysisStatus[aParam] = { aValue, aStatus };
55}
56
57
59 const TRANSLINE_STATUS aStatus )
60{
61 m_synthesisStatus[aParam] = { aValue, aStatus };
62}
63
64
66 const TRANSLINE_PARAMETERS aMeasure )
67{
68 double& var = GetParameterRef( aOptimise );
69 double& Z0_param = GetParameterRef( aMeasure );
70 double& ANG_L_param = GetParameterRef( TCP::ANG_L );
71
72 if( !std::isfinite( Z0_param ) )
73 {
74 var = NAN;
75 return false;
76 }
77
78 if( ( !std::isfinite( var ) ) || ( var == 0 ) )
79 var = 0.001;
80
81 /* required value of Z0 */
82 double Z0_dest = Z0_param;
83
84 /* required value of angl_l */
85 double angl_l_dest = ANG_L_param;
86
87 /* Newton's method */
88 int iteration = 0;
89
90 /* compute parameters */
91 Analyse();
92 double Z0_current = Z0_param;
93
94 double error = fabs( Z0_dest - Z0_current );
95
96 while( error > m_maxError )
97 {
98 iteration++;
99 double increment = var / 100.0;
100 var += increment;
101
102 /* compute parameters */
103 Analyse();
104 double Z0_result = Z0_param;
105
106 // f(w(n)) = Z0 - Z0(w(n))
107 // f'(w(n)) = -f'(Z0(w(n)))
108 // f'(Z0(w(n))) = (Z0(w(n)) - Z0(w(n+delw))/delw
109 // w(n+1) = w(n) - f(w(n))/f'(w(n))
110 double slope = ( Z0_result - Z0_current ) / increment;
111 slope = ( Z0_dest - Z0_current ) / slope - increment;
112 var += slope;
113
114 if( var <= 0.0 )
115 var = increment;
116
117 /* find new error */
118 /* compute parameters */
119 Analyse();
120 Z0_current = Z0_param;
121 error = fabs( Z0_dest - Z0_current );
122
123 if( iteration > 250 )
124 break;
125 }
126
127 /* Compute one last time, but with correct length */
128 Z0_param = Z0_dest;
129 ANG_L_param = angl_l_dest;
130 SetParameter( TCP::PHYS_LEN, TC::C0 / GetParameter( TCP::FREQUENCY ) / sqrt( GetParameter( TCP::EPSILON_EFF ) )
131 * ANG_L_param / 2.0 / M_PI ); /* in m */
132 Analyse();
133
134 /* Restore parameters */
135 Z0_param = Z0_dest;
136 ANG_L_param = angl_l_dest;
137 SetParameter( TCP::PHYS_LEN, TC::C0 / GetParameter( TCP::FREQUENCY ) / sqrt( GetParameter( TCP::EPSILON_EFF ) )
138 * ANG_L_param / 2.0 / M_PI ); /* in m */
139
140 return error <= m_maxError;
141}
142
143
145{
146 double depth = 1.0
147 / sqrt( M_PI * GetParameter( TCP::FREQUENCY ) * GetParameter( TCP::MURC )
148 * TRANSLINE_CALCULATIONS::MU0 * GetParameter( TCP::SIGMA ) );
149 return depth;
150}
151
152
153double TRANSLINE_CALCULATION_BASE::UnitPropagationDelay( const double aEpsilonEff )
154{
155 return std::sqrt( aEpsilonEff ) * ( 1.0e10 / 2.99e8 );
156}
157
158
159std::pair<double, double> TRANSLINE_CALCULATION_BASE::EllipticIntegral( const double arg )
160{
161 static constexpr double NR_EPSI = 2.2204460492503131e-16;
162 int iMax = 16;
163
164 double k = 0.0, e = 0.0;
165
166 if( arg == 1.0 )
167 {
168 k = INFINITY; // infinite
169 e = 0;
170 }
171 else if( std::isinf( arg ) && arg < 0 )
172 {
173 k = 0;
174 e = INFINITY; // infinite
175 }
176 else
177 {
178 double a, b, c, fr, s, fk = 1, fe = 1, t, da = arg;
179 int i;
180
181 if( arg < 0 )
182 {
183 fk = 1 / sqrt( 1 - arg );
184 fe = sqrt( 1 - arg );
185 da = -arg / ( 1 - arg );
186 }
187
188 a = 1;
189 b = sqrt( 1 - da );
190 c = sqrt( da );
191 fr = 0.5;
192 s = fr * c * c;
193
194 for( i = 0; i < iMax; i++ )
195 {
196 t = ( a + b ) / 2;
197 c = ( a - b ) / 2;
198 b = sqrt( a * b );
199 a = t;
200 fr *= 2;
201 s += fr * c * c;
202
203 if( c / a < NR_EPSI )
204 break;
205 }
206
207 if( i >= iMax )
208 {
209 k = 0;
210 e = 0;
211 }
212 else
213 {
214 k = M_PI_2 / a;
215 e = M_PI_2 * ( 1 - s ) / a;
216 if( arg < 0 )
217 {
218 k *= fk;
219 e *= fe;
220 }
221 }
222 }
223
224 return { k, e };
225}
std::unordered_map< TRANSLINE_PARAMETERS, std::pair< double, TRANSLINE_STATUS > > & GetSynthesisResults()
Gets the output parameters following synthesis.
virtual void SetAnalysisResults()=0
Sets values in the output analysis results structure.
virtual void SetSynthesisResults()=0
Sets values in the output synthesis results structure.
double GetParameter(const TRANSLINE_PARAMETERS aParam) const
Gets the given calculation property.
void InitProperties(const std::initializer_list< TRANSLINE_PARAMETERS > &aParams)
Initialises the properties used (as inputs or outputs) by the calculation.
static std::pair< double, double > EllipticIntegral(double arg)
Computes the complete elliptic integral of first kind K() and the second kind E() using the arithmeti...
void SetParameter(const TRANSLINE_PARAMETERS aParam, const double aValue)
Sets the given calculation property.
void SetSynthesisResult(TRANSLINE_PARAMETERS aParam, const double aValue, const TRANSLINE_STATUS aStatus=TRANSLINE_STATUS::OK)
Sets a synthesis result.
static constexpr double m_maxError
The maximum error for Z0 optimisations.
bool MinimiseZ0Error1D(TRANSLINE_PARAMETERS aOptimise, TRANSLINE_PARAMETERS aMeasure)
minimizeZ0Error1D
double SkinDepth() const
Calculate skin depth.
virtual void Analyse()=0
Analyses the transmission line using the current parameter set.
double & GetParameterRef(const TRANSLINE_PARAMETERS aParam)
Adds a constant to the given parameter.
std::unordered_map< TRANSLINE_PARAMETERS, double > m_parameters
All input and output properties used by the calculation.
void SetAnalysisResult(TRANSLINE_PARAMETERS aParam, const double aValue, const TRANSLINE_STATUS aStatus=TRANSLINE_STATUS::OK)
Sets an analysis result.
std::unordered_map< TRANSLINE_PARAMETERS, std::pair< double, TRANSLINE_STATUS > > m_synthesisStatus
Synthesis results.
static double UnitPropagationDelay(double aEpsilonEff)
Calculates the unit propagation delay (ps/cm) for the given effective permittivity.
std::unordered_map< TRANSLINE_PARAMETERS, std::pair< double, TRANSLINE_STATUS > > & GetAnalysisResults()
Gets the output parameters following analysis.
std::unordered_map< TRANSLINE_PARAMETERS, std::pair< double, TRANSLINE_STATUS > > m_analysisStatus
Analysis results.
#define NR_EPSI
Definition: transline.cpp:250
#define INFINITY
Definition: transline.cpp:35
#define M_PI_2
Definition: transline.cpp:40
TRANSLINE_STATUS
Parameter status values.
TRANSLINE_PARAMETERS
All possible parameters used (as inputs or outputs) by the transmission line calculations.