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>>&
41
42
43std::unordered_map<TRANSLINE_PARAMETERS, std::pair<double, TRANSLINE_STATUS>>&
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, bool aRecalculateLength )
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 if( aRecalculateLength )
129 {
130 Z0_param = Z0_dest;
131 ANG_L_param = angl_l_dest;
133 * ANG_L_param / 2.0 / M_PI ); /* in m */
134 Analyse();
135
136 /* Restore parameters */
137 Z0_param = Z0_dest;
138 ANG_L_param = angl_l_dest;
140 * ANG_L_param / 2.0 / M_PI ); /* in m */
141 }
142
143 return error <= m_maxError;
144}
145
146
148{
149 double depth = 1.0
152 return depth;
153}
154
155
156double TRANSLINE_CALCULATION_BASE::UnitPropagationDelay( const double aEpsilonEff )
157{
158 return std::sqrt( aEpsilonEff ) * ( 1.0e10 / 2.99e8 );
159}
160
161
162std::pair<double, double> TRANSLINE_CALCULATION_BASE::EllipticIntegral( const double arg )
163{
164 static constexpr double NR_EPSI = 2.2204460492503131e-16;
165 int iMax = 16;
166
167 double k = 0.0, e = 0.0;
168
169 if( arg == 1.0 )
170 {
171 k = INFINITY; // infinite
172 e = 0;
173 }
174 else if( std::isinf( arg ) && arg < 0 )
175 {
176 k = 0;
177 e = INFINITY; // infinite
178 }
179 else
180 {
181 double a, b, c, fr, s, fk = 1, fe = 1, t, da = arg;
182 int i;
183
184 if( arg < 0 )
185 {
186 fk = 1 / sqrt( 1 - arg );
187 fe = sqrt( 1 - arg );
188 da = -arg / ( 1 - arg );
189 }
190
191 a = 1;
192 b = sqrt( 1 - da );
193 c = sqrt( da );
194 fr = 0.5;
195 s = fr * c * c;
196
197 for( i = 0; i < iMax; i++ )
198 {
199 t = ( a + b ) / 2;
200 c = ( a - b ) / 2;
201 b = sqrt( a * b );
202 a = t;
203 fr *= 2;
204 s += fr * c * c;
205
206 if( c / a < NR_EPSI )
207 break;
208 }
209
210 if( i >= iMax )
211 {
212 k = 0;
213 e = 0;
214 }
215 else
216 {
217 k = M_PI_2 / a;
218 e = M_PI_2 * ( 1 - s ) / a;
219 if( arg < 0 )
220 {
221 k *= fk;
222 e *= fe;
223 }
224 }
225 }
226
227 return { k, e };
228}
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.
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.
bool MinimiseZ0Error1D(TRANSLINE_PARAMETERS aOptimise, TRANSLINE_PARAMETERS aMeasure, bool aRecalculateLength=false)
minimizeZ0Error1D
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.
TRANSLINE_PARAMETERS TCP
#define M_PI
#define NR_EPSI
#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.