You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

225 lines
6.0 KiB

  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. #include <transline_calculations/units.h>
  20. #include <transline_calculations/transline_calculation_base.h>
  21. using TCP = TRANSLINE_PARAMETERS;
  22. namespace TC = TRANSLINE_CALCULATIONS;
  23. void TRANSLINE_CALCULATION_BASE::InitProperties( const std::initializer_list<TRANSLINE_PARAMETERS>& aParams )
  24. {
  25. for( const TRANSLINE_PARAMETERS& param : aParams )
  26. m_parameters[param] = 0.0;
  27. }
  28. std::unordered_map<TRANSLINE_PARAMETERS, std::pair<double, TRANSLINE_STATUS>>&
  29. TRANSLINE_CALCULATION_BASE::GetAnalysisResults()
  30. {
  31. SetAnalysisResults();
  32. return m_analysisStatus;
  33. }
  34. std::unordered_map<TRANSLINE_PARAMETERS, std::pair<double, TRANSLINE_STATUS>>&
  35. TRANSLINE_CALCULATION_BASE::GetSynthesisResults()
  36. {
  37. SetSynthesisResults();
  38. return m_synthesisStatus;
  39. }
  40. void TRANSLINE_CALCULATION_BASE::SetAnalysisResult( const TRANSLINE_PARAMETERS aParam, const double aValue,
  41. const TRANSLINE_STATUS aStatus )
  42. {
  43. m_analysisStatus[aParam] = { aValue, aStatus };
  44. }
  45. void TRANSLINE_CALCULATION_BASE::SetSynthesisResult( const TRANSLINE_PARAMETERS aParam, const double aValue,
  46. const TRANSLINE_STATUS aStatus )
  47. {
  48. m_synthesisStatus[aParam] = { aValue, aStatus };
  49. }
  50. bool TRANSLINE_CALCULATION_BASE::MinimiseZ0Error1D( const TRANSLINE_PARAMETERS aOptimise,
  51. const TRANSLINE_PARAMETERS aMeasure )
  52. {
  53. double& var = GetParameterRef( aOptimise );
  54. double& Z0_param = GetParameterRef( aMeasure );
  55. double& ANG_L_param = GetParameterRef( TCP::ANG_L );
  56. if( !std::isfinite( Z0_param ) )
  57. {
  58. var = NAN;
  59. return false;
  60. }
  61. if( ( !std::isfinite( var ) ) || ( var == 0 ) )
  62. var = 0.001;
  63. /* required value of Z0 */
  64. double Z0_dest = Z0_param;
  65. /* required value of angl_l */
  66. double angl_l_dest = ANG_L_param;
  67. /* Newton's method */
  68. int iteration = 0;
  69. /* compute parameters */
  70. Analyse();
  71. double Z0_current = Z0_param;
  72. double error = fabs( Z0_dest - Z0_current );
  73. while( error > m_maxError )
  74. {
  75. iteration++;
  76. double increment = var / 100.0;
  77. var += increment;
  78. /* compute parameters */
  79. Analyse();
  80. double Z0_result = Z0_param;
  81. // f(w(n)) = Z0 - Z0(w(n))
  82. // f'(w(n)) = -f'(Z0(w(n)))
  83. // f'(Z0(w(n))) = (Z0(w(n)) - Z0(w(n+delw))/delw
  84. // w(n+1) = w(n) - f(w(n))/f'(w(n))
  85. double slope = ( Z0_result - Z0_current ) / increment;
  86. slope = ( Z0_dest - Z0_current ) / slope - increment;
  87. var += slope;
  88. if( var <= 0.0 )
  89. var = increment;
  90. /* find new error */
  91. /* compute parameters */
  92. Analyse();
  93. Z0_current = Z0_param;
  94. error = fabs( Z0_dest - Z0_current );
  95. if( iteration > 250 )
  96. break;
  97. }
  98. /* Compute one last time, but with correct length */
  99. Z0_param = Z0_dest;
  100. ANG_L_param = angl_l_dest;
  101. SetParameter( TCP::PHYS_LEN, TC::C0 / GetParameter( TCP::FREQUENCY ) / sqrt( GetParameter( TCP::EPSILON_EFF ) )
  102. * ANG_L_param / 2.0 / M_PI ); /* in m */
  103. Analyse();
  104. /* Restore parameters */
  105. Z0_param = Z0_dest;
  106. ANG_L_param = angl_l_dest;
  107. SetParameter( TCP::PHYS_LEN, TC::C0 / GetParameter( TCP::FREQUENCY ) / sqrt( GetParameter( TCP::EPSILON_EFF ) )
  108. * ANG_L_param / 2.0 / M_PI ); /* in m */
  109. return error <= m_maxError;
  110. }
  111. double TRANSLINE_CALCULATION_BASE::SkinDepth() const
  112. {
  113. double depth = 1.0
  114. / sqrt( M_PI * GetParameter( TCP::FREQUENCY ) * GetParameter( TCP::MURC )
  115. * TRANSLINE_CALCULATIONS::MU0 * GetParameter( TCP::SIGMA ) );
  116. return depth;
  117. }
  118. double TRANSLINE_CALCULATION_BASE::UnitPropagationDelay( const double aEpsilonEff )
  119. {
  120. return std::sqrt( aEpsilonEff ) * ( 1.0e10 / 2.99e8 );
  121. }
  122. std::pair<double, double> TRANSLINE_CALCULATION_BASE::EllipticIntegral( const double arg )
  123. {
  124. static constexpr double NR_EPSI = 2.2204460492503131e-16;
  125. int iMax = 16;
  126. double k = 0.0, e = 0.0;
  127. if( arg == 1.0 )
  128. {
  129. k = INFINITY; // infinite
  130. e = 0;
  131. }
  132. else if( std::isinf( arg ) && arg < 0 )
  133. {
  134. k = 0;
  135. e = INFINITY; // infinite
  136. }
  137. else
  138. {
  139. double a, b, c, fr, s, fk = 1, fe = 1, t, da = arg;
  140. int i;
  141. if( arg < 0 )
  142. {
  143. fk = 1 / sqrt( 1 - arg );
  144. fe = sqrt( 1 - arg );
  145. da = -arg / ( 1 - arg );
  146. }
  147. a = 1;
  148. b = sqrt( 1 - da );
  149. c = sqrt( da );
  150. fr = 0.5;
  151. s = fr * c * c;
  152. for( i = 0; i < iMax; i++ )
  153. {
  154. t = ( a + b ) / 2;
  155. c = ( a - b ) / 2;
  156. b = sqrt( a * b );
  157. a = t;
  158. fr *= 2;
  159. s += fr * c * c;
  160. if( c / a < NR_EPSI )
  161. break;
  162. }
  163. if( i >= iMax )
  164. {
  165. k = 0;
  166. e = 0;
  167. }
  168. else
  169. {
  170. k = M_PI_2 / a;
  171. e = M_PI_2 * ( 1 - s ) / a;
  172. if( arg < 0 )
  173. {
  174. k *= fk;
  175. e *= fe;
  176. }
  177. }
  178. }
  179. return { k, e };
  180. }