209 lines
5.2 KiB
C++
209 lines
5.2 KiB
C++
/*
|
|
* TRANSLINE.cpp - base for a transmission line implementation
|
|
*
|
|
* Copyright (C) 2005 Stefan Jahn <stefan@lkcc.org>
|
|
* Modified for Kicad: 2018 jean-pierre.charras
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this package; see the file COPYING. If not, write to
|
|
* the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
|
|
* Boston, MA 02110-1301, USA.
|
|
*
|
|
*/
|
|
|
|
#include <cmath>
|
|
#include <limits>
|
|
#include <transline.h>
|
|
#include <units.h>
|
|
|
|
|
|
#ifndef INFINITY
|
|
#define INFINITY std::numeric_limits<double>::infinity()
|
|
#endif
|
|
|
|
|
|
#ifndef M_PI_2
|
|
#define M_PI_2 (M_PI/2)
|
|
#endif
|
|
|
|
|
|
// Functions to Read/Write parameters in pcb_calculator main frame:
|
|
// They are wrapper to actual functions, so all transline functions do not
|
|
// depend on Graphic User Interface
|
|
void SetPropertyInDialog( enum PRMS_ID aPrmId, double value );
|
|
|
|
/* Puts the text into the given result line.
|
|
*/
|
|
void SetResultInDialog( int line, const char* text );
|
|
|
|
/* print aValue into the given result line.
|
|
*/
|
|
void SetResultInDialog( int aLineNumber, double aValue, const char* aText );
|
|
|
|
/* Returns a named property value. */
|
|
double GetPropertyInDialog( enum PRMS_ID aPrmId );
|
|
|
|
// Returns true if the param aPrmId is selected
|
|
// Has meaning only for params that have a radio button
|
|
bool IsSelectedInDialog( enum PRMS_ID aPrmId );
|
|
|
|
|
|
/* Constructor creates a transmission line instance. */
|
|
TRANSLINE::TRANSLINE()
|
|
{
|
|
m_murC = 1.0;
|
|
m_Name = nullptr;
|
|
|
|
// Initialize these variables mainly to avoid warnings from a static analyzer
|
|
m_freq = 0.0; // Frequency of operation
|
|
er = 0.0; // dielectric constant
|
|
m_tand = 0.0; // Dielectric Loss Tangent
|
|
m_sigma = 0.0; // Conductivity of the metal
|
|
m_skindepth = 0.0; // Skin depth
|
|
}
|
|
|
|
|
|
/* Destructor destroys a transmission line instance. */
|
|
TRANSLINE::~TRANSLINE()
|
|
{
|
|
}
|
|
|
|
|
|
/* Sets a named property to the given value, access through the
|
|
* application.
|
|
*/
|
|
void TRANSLINE::setProperty( enum PRMS_ID aPrmId, double value )
|
|
{
|
|
SetPropertyInDialog( aPrmId, value );
|
|
}
|
|
|
|
/*
|
|
*Returns true if the param aPrmId is selected
|
|
* Has meaning only for params that have a radio button
|
|
*/
|
|
bool TRANSLINE::isSelected( enum PRMS_ID aPrmId )
|
|
{
|
|
return IsSelectedInDialog( aPrmId );
|
|
}
|
|
|
|
|
|
/* Puts the text into the given result line.
|
|
*/
|
|
void TRANSLINE::setResult( int line, const char* text )
|
|
{
|
|
SetResultInDialog( line, text );
|
|
}
|
|
void TRANSLINE::setResult( int line, double value, const char* text )
|
|
{
|
|
SetResultInDialog( line, value, text );
|
|
}
|
|
|
|
|
|
/* Returns a property value. */
|
|
double TRANSLINE::getProperty( enum PRMS_ID aPrmId )
|
|
{
|
|
return GetPropertyInDialog( aPrmId );
|
|
}
|
|
|
|
/*
|
|
* skin_depth - calculate skin depth
|
|
*/
|
|
#include <stdio.h>
|
|
double TRANSLINE::skin_depth()
|
|
{
|
|
double depth;
|
|
depth = 1.0 / sqrt( M_PI * m_freq * m_murC * MU0 * m_sigma );
|
|
return depth;
|
|
}
|
|
|
|
|
|
/* *****************************************************************
|
|
********** **********
|
|
********** mathematical functions **********
|
|
********** **********
|
|
***************************************************************** */
|
|
|
|
#define NR_EPSI 2.2204460492503131e-16
|
|
|
|
/* The function computes the complete elliptic integral of first kind
|
|
* K() and the second kind E() using the arithmetic-geometric mean
|
|
* algorithm (AGM) by Abramowitz and Stegun.
|
|
*/
|
|
void TRANSLINE::ellipke( double arg, double& k, double& e )
|
|
{
|
|
int iMax = 16;
|
|
|
|
if( arg == 1.0 )
|
|
{
|
|
k = INFINITY; // infinite
|
|
e = 0;
|
|
}
|
|
else if( std::isinf( arg ) && arg < 0 )
|
|
{
|
|
k = 0;
|
|
e = INFINITY; // infinite
|
|
}
|
|
else
|
|
{
|
|
double a, b, c, fr, s, fk = 1, fe = 1, t, da = arg;
|
|
int i;
|
|
if( arg < 0 )
|
|
{
|
|
fk = 1 / sqrt( 1 - arg );
|
|
fe = sqrt( 1 - arg );
|
|
da = -arg / (1 - arg);
|
|
}
|
|
a = 1;
|
|
b = sqrt( 1 - da );
|
|
c = sqrt( da );
|
|
fr = 0.5;
|
|
s = fr * c * c;
|
|
for( i = 0; i < iMax; i++ )
|
|
{
|
|
t = (a + b) / 2;
|
|
c = (a - b) / 2;
|
|
b = sqrt( a * b );
|
|
a = t;
|
|
fr *= 2;
|
|
s += fr * c * c;
|
|
if( c / a < NR_EPSI )
|
|
break;
|
|
}
|
|
|
|
if( i >= iMax )
|
|
{
|
|
k = 0; e = 0;
|
|
}
|
|
else
|
|
{
|
|
k = M_PI_2 / a;
|
|
e = M_PI_2 * (1 - s) / a;
|
|
if( arg < 0 )
|
|
{
|
|
k *= fk;
|
|
e *= fe;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* We need to know only K(k), and if possible KISS. */
|
|
double TRANSLINE::ellipk( double k )
|
|
{
|
|
double r, lost;
|
|
|
|
ellipke( k, r, lost );
|
|
return r;
|
|
}
|