pcb_calculator : do not overwrite input parameters
Split the computing / displaying code into different functions Add coloured warnings when a value is not finite / illogical . Fixes https://gitlab.com/kicad/code/kicad/-/issues/1849
This commit is contained in:
parent
0ff5dcee69
commit
8de6aa161f
|
@ -19,11 +19,12 @@
|
|||
*/
|
||||
|
||||
#include <wx/app.h>
|
||||
#include <wx/msgdlg.h>
|
||||
#include <wx/colour.h>
|
||||
#include <wx/log.h>
|
||||
#include <wx/msgdlg.h>
|
||||
|
||||
#include <pcb_calculator_frame_base.h>
|
||||
#include <pcb_calculator.h>
|
||||
#include <pcb_calculator_frame_base.h>
|
||||
#include <transline.h>
|
||||
|
||||
/*
|
||||
|
@ -56,17 +57,25 @@ double DoubleFromString( const wxString& TextValue )
|
|||
while( brk_point < buf.Len() )
|
||||
{
|
||||
wxChar ch = buf[brk_point];
|
||||
if( !( (ch >= '0' && ch <='9') || (ch == decimal_point)
|
||||
|| (ch == '-') || (ch == '+') || (ch == 'e') || (ch == 'E') ) )
|
||||
if( !( ( ch >= '0' && ch <= '9' ) || ( ch == decimal_point ) || ( ch == '-' )
|
||||
|| ( ch == '+' ) || ( ch == 'e' ) || ( ch == 'E' ) ) )
|
||||
{
|
||||
break;
|
||||
}
|
||||
++brk_point;
|
||||
}
|
||||
|
||||
/* Extract the numeric part */
|
||||
buf.Left( brk_point ).ToDouble( &value );
|
||||
// Check for strings that cannot qualify as a number
|
||||
if( brk_point == 0 )
|
||||
{
|
||||
return std::nan( "" );
|
||||
}
|
||||
|
||||
/* Extract the numeric part */
|
||||
if( !buf.Left( brk_point ).ToDouble( &value ) )
|
||||
{
|
||||
return std::nan( "" );
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
|
@ -76,15 +85,21 @@ double DoubleFromString( const wxString& TextValue )
|
|||
// depend on Graphic User Interface
|
||||
void SetPropertyInDialog( enum PRMS_ID aPrmId, double value )
|
||||
{
|
||||
PCB_CALCULATOR_FRAME * frame = (PCB_CALCULATOR_FRAME *) wxTheApp->GetTopWindow();
|
||||
PCB_CALCULATOR_FRAME* frame = (PCB_CALCULATOR_FRAME*) wxTheApp->GetTopWindow();
|
||||
frame->SetPrmValue( aPrmId, value );
|
||||
}
|
||||
|
||||
void SetPropertyBgColorInDialog( enum PRMS_ID aPrmId, const KIGFX::COLOR4D* aCol )
|
||||
{
|
||||
PCB_CALCULATOR_FRAME* frame = (PCB_CALCULATOR_FRAME*) wxTheApp->GetTopWindow();
|
||||
frame->SetPrmBgColor( aPrmId, aCol );
|
||||
}
|
||||
|
||||
/* Puts the text into the given result line.
|
||||
*/
|
||||
void SetResultInDialog( int line, const char* aText )
|
||||
{
|
||||
PCB_CALCULATOR_FRAME * frame = (PCB_CALCULATOR_FRAME *) wxTheApp->GetTopWindow();
|
||||
PCB_CALCULATOR_FRAME* frame = (PCB_CALCULATOR_FRAME*) wxTheApp->GetTopWindow();
|
||||
wxString msg = wxString::FromUTF8( aText );
|
||||
frame->SetResult( line, msg );
|
||||
}
|
||||
|
@ -93,10 +108,10 @@ void SetResultInDialog( int line, const char* aText )
|
|||
*/
|
||||
void SetResultInDialog( int aLineNumber, double aValue, const char* aText )
|
||||
{
|
||||
PCB_CALCULATOR_FRAME * frame = (PCB_CALCULATOR_FRAME *) wxTheApp->GetTopWindow();
|
||||
PCB_CALCULATOR_FRAME* frame = (PCB_CALCULATOR_FRAME*) wxTheApp->GetTopWindow();
|
||||
wxString msg = wxString::FromUTF8( aText );
|
||||
wxString fullmsg;
|
||||
fullmsg.Printf( wxT("%g "), aValue );
|
||||
fullmsg.Printf( wxT( "%g " ), aValue );
|
||||
fullmsg += msg;
|
||||
frame->SetResult( aLineNumber, fullmsg );
|
||||
}
|
||||
|
@ -104,7 +119,7 @@ void SetResultInDialog( int aLineNumber, double aValue, const char* aText )
|
|||
/* Returns a named property value. */
|
||||
double GetPropertyInDialog( enum PRMS_ID aPrmId )
|
||||
{
|
||||
PCB_CALCULATOR_FRAME * frame = (PCB_CALCULATOR_FRAME *) wxTheApp->GetTopWindow();
|
||||
PCB_CALCULATOR_FRAME* frame = (PCB_CALCULATOR_FRAME*) wxTheApp->GetTopWindow();
|
||||
return frame->GetPrmValue( aPrmId );
|
||||
}
|
||||
|
||||
|
@ -112,7 +127,7 @@ double GetPropertyInDialog( enum PRMS_ID aPrmId )
|
|||
// Has meaning only for params that have a radio button
|
||||
bool IsSelectedInDialog( enum PRMS_ID aPrmId )
|
||||
{
|
||||
PCB_CALCULATOR_FRAME * frame = (PCB_CALCULATOR_FRAME *) wxTheApp->GetTopWindow();
|
||||
PCB_CALCULATOR_FRAME* frame = (PCB_CALCULATOR_FRAME*) wxTheApp->GetTopWindow();
|
||||
return frame->IsPrmSelected( aPrmId );
|
||||
}
|
||||
|
||||
|
@ -132,8 +147,6 @@ double PCB_CALCULATOR_FRAME::GetPrmValue( enum PRMS_ID aPrmId )
|
|||
if( aPrmId == prm->m_Id )
|
||||
return prm->m_NormalizedValue;
|
||||
}
|
||||
|
||||
wxLogMessage( wxT("GetPrmValue: prm %d not found"), (int) aPrmId );
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
|
@ -149,19 +162,52 @@ void PCB_CALCULATOR_FRAME::SetPrmValue( enum PRMS_ID aPrmId, double aValue )
|
|||
for( unsigned ii = 0; ii < tr_ident->GetPrmsCount(); ii++ )
|
||||
{
|
||||
TRANSLINE_PRM* prm = tr_ident->GetPrm( ii );
|
||||
|
||||
if( aPrmId == prm->m_Id )
|
||||
{
|
||||
prm->m_Value = prm->m_NormalizedValue = aValue;
|
||||
prm->m_NormalizedValue = aValue;
|
||||
prm->m_Value = prm->m_NormalizedValue * prm->ToUserUnit();
|
||||
wxString msg;
|
||||
msg.Printf( wxT("%g"), prm->m_Value);
|
||||
((wxTextCtrl*)prm->m_ValueCtrl )->SetValue( msg );
|
||||
msg.Printf( wxT( "%g" ), prm->m_Value );
|
||||
( (wxTextCtrl*) prm->m_ValueCtrl )->SetValue( msg );
|
||||
return;
|
||||
}
|
||||
}
|
||||
wxLogMessage( wxT( "GetPrmValue: prm %d not found" ), (int) aPrmId );
|
||||
}
|
||||
|
||||
wxLogMessage( wxT("GetPrmValue: prm %d not found"), (int) aPrmId );
|
||||
/**
|
||||
* Function SetPrmBgColor
|
||||
* Set the background color for a given parameter
|
||||
* @param aPrmId = @ref PRMS_ID of the parameter
|
||||
* @param aCol = color ( @ref KIGFX::COLOR4D * )
|
||||
*/
|
||||
void PCB_CALCULATOR_FRAME::SetPrmBgColor( enum PRMS_ID aPrmId, const KIGFX::COLOR4D* aCol )
|
||||
{
|
||||
wxColour wxcol = wxColour( static_cast<unsigned char>( aCol->r * 255 ),
|
||||
static_cast<unsigned char>( aCol->g * 255 ),
|
||||
static_cast<unsigned char>( aCol->b * 255 ) );
|
||||
|
||||
if( !wxcol.IsOk() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
TRANSLINE_IDENT* tr_ident = m_transline_list[m_currTransLineType];
|
||||
|
||||
for( unsigned ii = 0; ii < tr_ident->GetPrmsCount(); ii++ )
|
||||
{
|
||||
TRANSLINE_PRM* prm = tr_ident->GetPrm( ii );
|
||||
wxTextCtrl* ctl = static_cast<wxTextCtrl*>( prm->m_ValueCtrl );
|
||||
|
||||
if( aPrmId == prm->m_Id )
|
||||
{
|
||||
ctl->SetBackgroundColour( wxcol );
|
||||
ctl->SetStyle( 0, -1, ctl->GetDefaultStyle() );
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -170,10 +216,10 @@ void PCB_CALCULATOR_FRAME::SetPrmValue( enum PRMS_ID aPrmId, double aValue )
|
|||
* @param aLineNumber = the line (0 to MSG_CNT_MAX-1) wher to display the text
|
||||
* @param aText = the text to display
|
||||
*/
|
||||
void PCB_CALCULATOR_FRAME::SetResult( int aLineNumber, const wxString & aText )
|
||||
void PCB_CALCULATOR_FRAME::SetResult( int aLineNumber, const wxString& aText )
|
||||
{
|
||||
#define MSG_CNT_MAX 7
|
||||
wxStaticText * messages[MSG_CNT_MAX] =
|
||||
wxStaticText* messages[MSG_CNT_MAX] =
|
||||
{ m_Message1, m_Message2, m_Message3,
|
||||
m_Message4, m_Message5, m_Message6,
|
||||
m_Message7
|
||||
|
@ -184,7 +230,7 @@ void PCB_CALCULATOR_FRAME::SetResult( int aLineNumber, const wxString & aText )
|
|||
if( aLineNumber < 0 )
|
||||
aLineNumber = 0;
|
||||
if( aLineNumber >= MSG_CNT_MAX )
|
||||
aLineNumber = MSG_CNT_MAX-1;
|
||||
aLineNumber = MSG_CNT_MAX - 1;
|
||||
|
||||
messages[aLineNumber]->SetLabel( aText );
|
||||
}
|
||||
|
@ -199,7 +245,7 @@ bool PCB_CALCULATOR_FRAME::IsPrmSelected( enum PRMS_ID aPrmId )
|
|||
switch( aPrmId )
|
||||
{
|
||||
default:
|
||||
wxMessageBox( wxT("IsPrmSelected() error") );
|
||||
wxMessageBox( wxT( "IsPrmSelected() error" ) );
|
||||
break;
|
||||
|
||||
case PHYS_WIDTH_PRM:
|
||||
|
@ -214,4 +260,3 @@ bool PCB_CALCULATOR_FRAME::IsPrmSelected( enum PRMS_ID aPrmId )
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -26,10 +26,10 @@
|
|||
|
||||
#include <pcb_calculator_frame_base.h>
|
||||
|
||||
#include <transline.h> // Included for SUBST_PRMS_ID definition.
|
||||
#include <transline_ident.h>
|
||||
#include <attenuator_classes.h>
|
||||
#include <class_regulator_data.h>
|
||||
#include <transline.h> // Included for SUBST_PRMS_ID definition.
|
||||
#include <transline_ident.h>
|
||||
|
||||
extern const wxString PcbCalcDataFileExt;
|
||||
|
||||
|
@ -56,23 +56,21 @@ private:
|
|||
bool m_TWNested; // Used to stop events caused by setting the answers.
|
||||
|
||||
enum TRANSLINE_TYPE_ID m_currTransLineType;
|
||||
TRANSLINE * m_currTransLine; // a pointer to the active transline
|
||||
TRANSLINE* m_currTransLine; // a pointer to the active transline
|
||||
// List of translines: ordered like in dialog menu list
|
||||
std::vector <TRANSLINE_IDENT *> m_transline_list;
|
||||
std::vector<TRANSLINE_IDENT*> m_transline_list;
|
||||
|
||||
ATTENUATOR * m_currAttenuator;
|
||||
ATTENUATOR* m_currAttenuator;
|
||||
// List ofattenuators: ordered like in dialog menu list
|
||||
std::vector <ATTENUATOR *> m_attenuator_list;
|
||||
std::vector<ATTENUATOR*> m_attenuator_list;
|
||||
wxString m_lastSelectedRegulatorName; // last regulator name selected
|
||||
|
||||
|
||||
|
||||
public:
|
||||
PCB_CALCULATOR_FRAME( KIWAY* aKiway, wxWindow* aParent );
|
||||
~PCB_CALCULATOR_FRAME();
|
||||
|
||||
private:
|
||||
|
||||
// Event handlers
|
||||
void OnClosePcbCalc( wxCloseEvent& event ) override;
|
||||
|
||||
|
@ -99,7 +97,7 @@ private:
|
|||
* force the standard extension of the file (.pcbcalc)
|
||||
* @param aFilename = the full filename, with or without extension
|
||||
*/
|
||||
void SetDataFilename( const wxString & aFilename);
|
||||
void SetDataFilename( const wxString& aFilename );
|
||||
|
||||
// Trace width / maximum current capability calculations.
|
||||
|
||||
|
@ -154,23 +152,23 @@ private:
|
|||
* Function TWCalculateWidth
|
||||
* Calculate track width required based on given current and temperature rise.
|
||||
*/
|
||||
double TWCalculateWidth( double aCurrent, double aThickness, double aDeltaT_C,
|
||||
bool aUseInternalLayer );
|
||||
double TWCalculateWidth(
|
||||
double aCurrent, double aThickness, double aDeltaT_C, bool aUseInternalLayer );
|
||||
|
||||
/**
|
||||
* Function TWCalculateCurrent
|
||||
* Calculate maximum current based on given width and temperature rise.
|
||||
*/
|
||||
double TWCalculateCurrent( double aWidth, double aThickness, double aDeltaT_C,
|
||||
bool aUseInternalLayer );
|
||||
double TWCalculateCurrent(
|
||||
double aWidth, double aThickness, double aDeltaT_C, bool aUseInternalLayer );
|
||||
|
||||
/**
|
||||
* Function TWDisplayValues
|
||||
* Displays the results of a calculation (including resulting values such
|
||||
* as the resistance and power loss).
|
||||
*/
|
||||
void TWDisplayValues( double aCurrent, double aExtWidth, double aIntWidth,
|
||||
double aExtThickness, double aIntThickness );
|
||||
void TWDisplayValues( double aCurrent, double aExtWidth, double aIntWidth, double aExtThickness,
|
||||
double aIntThickness );
|
||||
|
||||
/**
|
||||
* Function TWUpdateModeDisplay
|
||||
|
@ -358,8 +356,14 @@ public:
|
|||
* @param aLineNumber = the line (0 to 5) wher to display the text
|
||||
* @param aText = the text to display
|
||||
*/
|
||||
void SetResult( int aLineNumber, const wxString & aText );
|
||||
void SetResult( int aLineNumber, const wxString& aText );
|
||||
|
||||
/** Function SetPrgmBgColor
|
||||
* Set the background color of a parameter
|
||||
* @param aPrmId = param id to set
|
||||
* @param aCol = new color
|
||||
*/
|
||||
void SetPrmBgColor( enum PRMS_ID aPrmId, const KIGFX::COLOR4D* aCol );
|
||||
/**
|
||||
* Function GetPrmValue
|
||||
* Returns a param value.
|
||||
|
@ -380,7 +384,10 @@ public:
|
|||
void BoardClassesUpdateData( double aUnitScale );
|
||||
|
||||
// Calculator doesn't host a tool framework
|
||||
wxWindow* GetToolCanvas() const override { return nullptr; }
|
||||
wxWindow* GetToolCanvas() const override
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -31,43 +31,16 @@
|
|||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
#include <units.h>
|
||||
#include <transline.h>
|
||||
#include <microstrip.h>
|
||||
#include <c_microstrip.h>
|
||||
#include <microstrip.h>
|
||||
#include <transline.h>
|
||||
#include <units.h>
|
||||
|
||||
C_MICROSTRIP::C_MICROSTRIP() : TRANSLINE()
|
||||
{
|
||||
m_Name = "Coupled_MicroStrip";
|
||||
aux_ms = NULL;
|
||||
|
||||
// Initialize these variables mainly to avoid warnings from a static analyzer
|
||||
h = 0.0; // height of substrate
|
||||
ht = 0.0; // height to the top of box
|
||||
t = 0.0; // thickness of top metal
|
||||
rough = 0.0; // Roughness of top metal
|
||||
w = 0.0; // width of lines
|
||||
w_t_e = 0.0; // even-mode thickness-corrected line width
|
||||
w_t_o = 0.0; // odd-mode thickness-corrected line width
|
||||
l = 0.0; // length of lines
|
||||
s = 0.0; // spacing of lines
|
||||
Z0_e_0 = 0.0; // static even-mode impedance
|
||||
Z0_o_0 = 0.0; // static odd-mode impedance
|
||||
Z0e = 0.0; // even-mode impedance
|
||||
Z0o = 0.0; // odd-mode impedance
|
||||
c_e = 0.0; // even-mode capacitance
|
||||
c_o = 0.0; // odd-mode capacitance
|
||||
ang_l_e = 0.0; // even-mode electrical length in angle
|
||||
ang_l_o = 0.0; // odd-mode electrical length in angle
|
||||
er_eff_e = 0.0; // even-mode effective dielectric constant
|
||||
er_eff_o = 0.0; // odd-mode effective dielectric constant
|
||||
er_eff_e_0 = 0.0; // static even-mode effective dielectric constant
|
||||
er_eff_o_0 = 0.0; // static odd-mode effective dielectric constant
|
||||
w_eff = 0.0; // Effective width of line
|
||||
atten_dielectric_e = 0.0; // even-mode dielectric losses (dB)
|
||||
atten_cond_e = 0.0; // even-mode conductors losses (dB)
|
||||
atten_dielectric_o = 0.0; // odd-mode conductors losses (dB)
|
||||
atten_cond_o = 0.0; // odd-mode conductors losses (dB)
|
||||
Init();
|
||||
}
|
||||
|
||||
|
||||
|
@ -99,6 +72,7 @@ double C_MICROSTRIP::delta_u_thickness_single( double u, double t_h )
|
|||
log( ( 2.0 +
|
||||
(4.0 * M_PI * u -
|
||||
2.0) / ( 1.0 + exp( -100.0 * ( u - 1.0 / (2.0 * M_PI) ) ) ) ) / t_h ) );
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -122,16 +96,16 @@ void C_MICROSTRIP::delta_u_thickness()
|
|||
double e_r, u, g, t_h;
|
||||
double delta_u, delta_t, delta_u_e, delta_u_o;
|
||||
|
||||
e_r = er;
|
||||
u = w / h; /* normalized line width */
|
||||
g = s / h; /* normalized line spacing */
|
||||
t_h = t / h; /* normalized strip thickness */
|
||||
e_r = m_parameters[EPSILONR_PRM];
|
||||
u = m_parameters[PHYS_WIDTH_PRM] / m_parameters[H_PRM]; /* normalized line width */
|
||||
g = m_parameters[PHYS_S_PRM] / m_parameters[H_PRM]; /* normalized line spacing */
|
||||
t_h = m_parameters[T_PRM] / m_parameters[H_PRM]; /* normalized strip thickness */
|
||||
|
||||
if( t_h > 0.0 )
|
||||
{
|
||||
/* single microstrip correction for finite strip thickness */
|
||||
delta_u = delta_u_thickness_single( u, t_h );
|
||||
delta_t = t_h / (g * e_r);
|
||||
delta_t = t_h / ( g * e_r );
|
||||
/* thickness correction for the even- and odd-mode */
|
||||
delta_u_e = delta_u * ( 1.0 - 0.5 * exp( -0.69 * delta_u / delta_t ) );
|
||||
delta_u_o = delta_u_e + delta_t;
|
||||
|
@ -141,8 +115,8 @@ void C_MICROSTRIP::delta_u_thickness()
|
|||
delta_u_e = delta_u_o = 0.0;
|
||||
}
|
||||
|
||||
w_t_e = w + delta_u_e * h;
|
||||
w_t_o = w + delta_u_o * h;
|
||||
w_t_e = m_parameters[PHYS_WIDTH_PRM] + delta_u_e * m_parameters[H_PRM];
|
||||
w_t_o = m_parameters[PHYS_WIDTH_PRM] + delta_u_o * m_parameters[H_PRM];
|
||||
}
|
||||
|
||||
|
||||
|
@ -155,15 +129,15 @@ void C_MICROSTRIP::compute_single_line()
|
|||
aux_ms = new MICROSTRIP();
|
||||
|
||||
/* prepare parameters for single microstrip computations */
|
||||
aux_ms->er = er;
|
||||
aux_ms->w = w;
|
||||
aux_ms->h = h;
|
||||
aux_ms->t = 0.0;
|
||||
aux_ms->m_parameters[EPSILONR_PRM] = m_parameters[EPSILONR_PRM];
|
||||
aux_ms->m_parameters[PHYS_WIDTH_PRM] = m_parameters[PHYS_WIDTH_PRM];
|
||||
aux_ms->m_parameters[H_PRM] = m_parameters[H_PRM];
|
||||
aux_ms->m_parameters[T_PRM] = 0.0;
|
||||
|
||||
//aux_ms->t = t;
|
||||
aux_ms->ht = 1e12; /* arbitrarily high */
|
||||
aux_ms->m_freq = m_freq;
|
||||
aux_ms->m_murC = m_murC;
|
||||
//aux_ms->m_parameters[H_T_PRM] = m_parameters[H_T_PRM];
|
||||
aux_ms->m_parameters[H_T_PRM] = 1e12; /* arbitrarily high */
|
||||
aux_ms->m_parameters[FREQUENCY_PRM] = m_parameters[FREQUENCY_PRM];
|
||||
aux_ms->m_parameters[MURC_PRM] = m_parameters[MURC_PRM];
|
||||
aux_ms->microstrip_Z0();
|
||||
aux_ms->dispersion();
|
||||
}
|
||||
|
@ -177,15 +151,15 @@ double C_MICROSTRIP::filling_factor_even( double u, double g, double e_r )
|
|||
{
|
||||
double v, v3, v4, a_e, b_e, q_inf;
|
||||
|
||||
v = u * (20.0 + g * g) / (10.0 + g * g) + g* exp( -g );
|
||||
v = u * ( 20.0 + g * g ) / ( 10.0 + g * g ) + g * exp( -g );
|
||||
v3 = v * v * v;
|
||||
v4 = v3 * v;
|
||||
a_e = 1.0 + log( (v4 + v * v / 2704.0) / (v4 + 0.432) ) / 49.0 + log( 1.0 + v3 / 5929.741 )
|
||||
/ 18.7;
|
||||
b_e = 0.564 * pow( ( (e_r - 0.9) / (e_r + 3.0) ), 0.053 );
|
||||
a_e = 1.0 + log( ( v4 + v * v / 2704.0 ) / ( v4 + 0.432 ) ) / 49.0
|
||||
+ log( 1.0 + v3 / 5929.741 ) / 18.7;
|
||||
b_e = 0.564 * pow( ( ( e_r - 0.9 ) / ( e_r + 3.0 ) ), 0.053 );
|
||||
|
||||
/* filling factor, with width corrected for thickness */
|
||||
q_inf = pow( (1.0 + 10.0 / v), -a_e * b_e );
|
||||
q_inf = pow( ( 1.0 + 10.0 / v ), -a_e * b_e );
|
||||
|
||||
return q_inf;
|
||||
}
|
||||
|
@ -197,8 +171,8 @@ double C_MICROSTRIP::filling_factor_even( double u, double g, double e_r )
|
|||
*/
|
||||
double C_MICROSTRIP::filling_factor_odd( double u, double g, double e_r )
|
||||
{
|
||||
double b_odd = 0.747 * e_r / (0.15 + e_r);
|
||||
double c_odd = b_odd - (b_odd - 0.207) * exp( -0.414 * u );
|
||||
double b_odd = 0.747 * e_r / ( 0.15 + e_r );
|
||||
double c_odd = b_odd - ( b_odd - 0.207 ) * exp( -0.414 * u );
|
||||
double d_odd = 0.593 + 0.694 * exp( -0.562 * u );
|
||||
|
||||
/* filling factor, with width corrected for thickness */
|
||||
|
@ -239,7 +213,7 @@ double C_MICROSTRIP::delta_q_cover_odd( double h2h )
|
|||
|
||||
if( h2h <= 7 )
|
||||
{
|
||||
q_c = tanh( 9.575 / (7.0 - h2h) - 2.965 + 1.68 * h2h - 0.311 * h2h * h2h );
|
||||
q_c = tanh( 9.575 / ( 7.0 - h2h ) - 2.965 + 1.68 * h2h - 0.311 * h2h * h2h );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -263,17 +237,20 @@ void C_MICROSTRIP::er_eff_static()
|
|||
double u_t_e, u_t_o, g, h2, h2h;
|
||||
double a_o, t_h, q, q_c, q_t, q_inf;
|
||||
double er_eff_single;
|
||||
double er;
|
||||
|
||||
er = m_parameters[EPSILONR_PRM];
|
||||
|
||||
/* compute zero-thickness single line parameters */
|
||||
compute_single_line();
|
||||
er_eff_single = aux_ms->er_eff_0;
|
||||
|
||||
h2 = ht;
|
||||
u_t_e = w_t_e / h; /* normalized even_mode line width */
|
||||
u_t_o = w_t_o / h; /* normalized odd_mode line width */
|
||||
g = s / h; /* normalized line spacing */
|
||||
h2h = h2 / h; /* normalized cover height */
|
||||
t_h = t / h; /* normalized strip thickness */
|
||||
h2 = m_parameters[H_T_PRM];
|
||||
u_t_e = w_t_e / m_parameters[H_PRM]; /* normalized even_mode line width */
|
||||
u_t_o = w_t_o / m_parameters[H_PRM]; /* normalized odd_mode line width */
|
||||
g = m_parameters[PHYS_S_PRM] / m_parameters[H_PRM]; /* normalized line spacing */
|
||||
h2h = h2 / m_parameters[H_PRM]; /* normalized cover height */
|
||||
t_h = m_parameters[T_PRM] / m_parameters[H_PRM]; /* normalized strip thickness */
|
||||
|
||||
/* filling factor, computed with thickness corrected width */
|
||||
q_inf = filling_factor_even( u_t_e, g, er );
|
||||
|
@ -282,9 +259,9 @@ void C_MICROSTRIP::er_eff_static()
|
|||
/* thickness effect */
|
||||
q_t = aux_ms->delta_q_thickness( u_t_e, t_h );
|
||||
/* resultant filling factor */
|
||||
q = (q_inf - q_t) * q_c;
|
||||
q = ( q_inf - q_t ) * q_c;
|
||||
/* static even-mode effective dielectric constant */
|
||||
er_eff_e_0 = 0.5 * (er + 1.0) + 0.5 * (er - 1.0) * q;
|
||||
er_eff_e_0 = 0.5 * ( er + 1.0 ) + 0.5 * ( er - 1.0 ) * q;
|
||||
|
||||
/* filling factor, with width corrected for thickness */
|
||||
q_inf = filling_factor_odd( u_t_o, g, er );
|
||||
|
@ -293,12 +270,12 @@ void C_MICROSTRIP::er_eff_static()
|
|||
/* thickness effect */
|
||||
q_t = aux_ms->delta_q_thickness( u_t_o, t_h );
|
||||
/* resultant filling factor */
|
||||
q = (q_inf - q_t) * q_c;
|
||||
q = ( q_inf - q_t ) * q_c;
|
||||
|
||||
a_o = 0.7287 * ( er_eff_single - 0.5 * (er + 1.0) ) * ( 1.0 - exp( -0.179 * u_t_o ) );
|
||||
a_o = 0.7287 * ( er_eff_single - 0.5 * ( er + 1.0 ) ) * ( 1.0 - exp( -0.179 * u_t_o ) );
|
||||
|
||||
/* static odd-mode effective dielectric constant */
|
||||
er_eff_o_0 = (0.5 * (er + 1.0) + a_o - er_eff_single) * q + er_eff_single;
|
||||
er_eff_o_0 = ( 0.5 * ( er + 1.0 ) + a_o - er_eff_single ) * q + er_eff_single;
|
||||
}
|
||||
|
||||
|
||||
|
@ -317,14 +294,14 @@ double C_MICROSTRIP::delta_Z0_even_cover( double g, double u, double h2h )
|
|||
A = -4.351 / pow( 1.0 + h2h, 1.842 );
|
||||
B = 6.639 / pow( 1.0 + h2h, 1.861 );
|
||||
C = -2.291 / pow( 1.0 + h2h, 1.90 );
|
||||
f_e = 1.0 - atanh( A + (B + C * u) * u );
|
||||
f_e = 1.0 - atanh( A + ( B + C * u ) * u );
|
||||
|
||||
x = pow( 10.0, 0.103 * g - 0.159 );
|
||||
y = pow( 10.0, 0.0492 * g - 0.073 );
|
||||
D = 0.747 / sin( 0.5 * M_PI * x );
|
||||
E = 0.725 * sin( 0.5 * M_PI * y );
|
||||
F = pow( 10.0, 0.11 - 0.0947 * g );
|
||||
g_e = 270.0 * ( 1.0 - tanh( D + E * sqrt( 1.0 + h2h ) - F / (1.0 + h2h) ) );
|
||||
g_e = 270.0 * ( 1.0 - tanh( D + E * sqrt( 1.0 + h2h ) - F / ( 1.0 + h2h ) ) );
|
||||
|
||||
delta_Z0_even = f_e * g_e;
|
||||
|
||||
|
@ -364,7 +341,7 @@ double C_MICROSTRIP::delta_Z0_odd_cover( double g, double u, double h2h )
|
|||
{
|
||||
L = 2.674;
|
||||
}
|
||||
g_o = 270.0 * ( 1.0 - tanh( G + K * sqrt( 1.0 + h2h ) - L / (1.0 + h2h) ) );
|
||||
g_o = 270.0 * ( 1.0 - tanh( G + K * sqrt( 1.0 + h2h ) - L / ( 1.0 + h2h ) ) );
|
||||
|
||||
delta_Z0_odd = f_o * g_o;
|
||||
|
||||
|
@ -387,11 +364,11 @@ void C_MICROSTRIP::Z0_even_odd()
|
|||
double Q_1, Q_2, Q_3, Q_4, Q_5, Q_6, Q_7, Q_8, Q_9, Q_10;
|
||||
double delta_Z0_e_0, delta_Z0_o_0, Z0_single, er_eff_single;
|
||||
|
||||
h2 = ht;
|
||||
u_t_e = w_t_e / h; /* normalized even-mode line width */
|
||||
u_t_o = w_t_o / h; /* normalized odd-mode line width */
|
||||
g = s / h; /* normalized line spacing */
|
||||
h2h = h2 / h; /* normalized cover height */
|
||||
h2 = m_parameters[H_T_PRM];
|
||||
u_t_e = w_t_e / m_parameters[H_PRM]; /* normalized even-mode line width */
|
||||
u_t_o = w_t_o / m_parameters[H_PRM]; /* normalized odd-mode line width */
|
||||
g = m_parameters[PHYS_S_PRM] / m_parameters[H_PRM]; /* normalized line spacing */
|
||||
h2h = h2 / m_parameters[H_PRM]; /* normalized cover height */
|
||||
|
||||
Z0_single = aux_ms->Z0_0;
|
||||
er_eff_single = aux_ms->er_eff_0;
|
||||
|
@ -400,16 +377,13 @@ void C_MICROSTRIP::Z0_even_odd()
|
|||
er_eff = er_eff_e_0;
|
||||
Q_1 = 0.8695 * pow( u_t_e, 0.194 );
|
||||
Q_2 = 1.0 + 0.7519 * g + 0.189 * pow( g, 2.31 );
|
||||
Q_3 = 0.1975 +
|
||||
pow( ( 16.6 +
|
||||
pow( (8.4 / g),
|
||||
6.0 ) ),
|
||||
-0.387 ) + log( pow( g, 10.0 ) / ( 1.0 + pow( g / 3.4, 10.0 ) ) ) / 241.0;
|
||||
Q_4 = 2.0 * Q_1 /
|
||||
( Q_2 * ( exp( -g ) * pow( u_t_e, Q_3 ) + ( 2.0 - exp( -g ) ) * pow( u_t_e, -Q_3 ) ) );
|
||||
Q_3 = 0.1975 + pow( ( 16.6 + pow( ( 8.4 / g ), 6.0 ) ), -0.387 )
|
||||
+ log( pow( g, 10.0 ) / ( 1.0 + pow( g / 3.4, 10.0 ) ) ) / 241.0;
|
||||
Q_4 = 2.0 * Q_1
|
||||
/ ( Q_2 * ( exp( -g ) * pow( u_t_e, Q_3 ) + ( 2.0 - exp( -g ) ) * pow( u_t_e, -Q_3 ) ) );
|
||||
/* static even-mode impedance */
|
||||
Z0_e_0 = Z0_single *
|
||||
sqrt( er_eff_single / er_eff ) / (1.0 - sqrt( er_eff_single ) * Q_4 * Z0_single / ZF0);
|
||||
Z0_e_0 = Z0_single * sqrt( er_eff_single / er_eff )
|
||||
/ ( 1.0 - sqrt( er_eff_single ) * Q_4 * Z0_single / ZF0 );
|
||||
/* correction for cover */
|
||||
delta_Z0_e_0 = delta_Z0_even_cover( g, u_t_e, h2h ) / sqrt( er_eff );
|
||||
|
||||
|
@ -418,17 +392,16 @@ void C_MICROSTRIP::Z0_even_odd()
|
|||
/* odd-mode */
|
||||
er_eff = er_eff_o_0;
|
||||
Q_5 = 1.794 + 1.14 * log( 1.0 + 0.638 / ( g + 0.517 * pow( g, 2.43 ) ) );
|
||||
Q_6 = 0.2305 + log( pow( g, 10.0 ) / ( 1.0 + pow( g / 5.8, 10.0 ) ) ) / 281.3 + log(
|
||||
1.0 + 0.598 * pow( g, 1.154 ) ) / 5.1;
|
||||
Q_7 = (10.0 + 190.0 * g * g) / (1.0 + 82.3 * g * g * g);
|
||||
Q_6 = 0.2305 + log( pow( g, 10.0 ) / ( 1.0 + pow( g / 5.8, 10.0 ) ) ) / 281.3
|
||||
+ log( 1.0 + 0.598 * pow( g, 1.154 ) ) / 5.1;
|
||||
Q_7 = ( 10.0 + 190.0 * g * g ) / ( 1.0 + 82.3 * g * g * g );
|
||||
Q_8 = exp( -6.5 - 0.95 * log( g ) - pow( g / 0.15, 5.0 ) );
|
||||
Q_9 = log( Q_7 ) * (Q_8 + 1.0 / 16.5);
|
||||
Q_9 = log( Q_7 ) * ( Q_8 + 1.0 / 16.5 );
|
||||
Q_10 = ( Q_2 * Q_4 - Q_5 * exp( log( u_t_o ) * Q_6 * pow( u_t_o, -Q_9 ) ) ) / Q_2;
|
||||
|
||||
/* static odd-mode impedance */
|
||||
Z0_o_0 = Z0_single *
|
||||
sqrt( er_eff_single /
|
||||
er_eff ) / (1.0 - sqrt( er_eff_single ) * Q_10 * Z0_single / ZF0);
|
||||
Z0_o_0 = Z0_single * sqrt( er_eff_single / er_eff )
|
||||
/ ( 1.0 - sqrt( er_eff_single ) * Q_10 * Z0_single / ZF0 );
|
||||
/* correction for cover */
|
||||
delta_Z0_o_0 = delta_Z0_odd_cover( g, u_t_o, h2h ) / sqrt( er_eff );
|
||||
|
||||
|
@ -446,41 +419,42 @@ void C_MICROSTRIP::er_eff_freq()
|
|||
double F_e, F_o;
|
||||
double er_eff, u, g, f_n;
|
||||
|
||||
u = w / h; /* normalize line width */
|
||||
g = s / h; /* normalize line spacing */
|
||||
u = m_parameters[PHYS_WIDTH_PRM] / m_parameters[H_PRM]; /* normalize line width */
|
||||
g = m_parameters[PHYS_S_PRM] / m_parameters[H_PRM]; /* normalize line spacing */
|
||||
|
||||
/* normalized frequency [GHz * mm] */
|
||||
f_n = m_freq * h / 1e06;
|
||||
f_n = m_parameters[FREQUENCY_PRM] * m_parameters[H_PRM] / 1e06;
|
||||
|
||||
er_eff = er_eff_e_0;
|
||||
P_1 = 0.27488 + ( 0.6315 + 0.525 / pow( 1.0 + 0.0157 * f_n, 20.0 ) ) * u - 0.065683 * exp(
|
||||
-8.7513 * u );
|
||||
P_2 = 0.33622 * ( 1.0 - exp( -0.03442 * er ) );
|
||||
P_1 = 0.27488 + ( 0.6315 + 0.525 / pow( 1.0 + 0.0157 * f_n, 20.0 ) ) * u
|
||||
- 0.065683 * exp( -8.7513 * u );
|
||||
P_2 = 0.33622 * ( 1.0 - exp( -0.03442 * m_parameters[EPSILONR_PRM] ) );
|
||||
P_3 = 0.0363 * exp( -4.6 * u ) * ( 1.0 - exp( -pow( f_n / 38.7, 4.97 ) ) );
|
||||
P_4 = 1.0 + 2.751 * ( 1.0 - exp( -pow( er / 15.916, 8.0 ) ) );
|
||||
P_5 = 0.334 * exp( -3.3 * pow( er / 15.0, 3.0 ) ) + 0.746;
|
||||
P_4 = 1.0 + 2.751 * ( 1.0 - exp( -pow( m_parameters[EPSILONR_PRM] / 15.916, 8.0 ) ) );
|
||||
P_5 = 0.334 * exp( -3.3 * pow( m_parameters[EPSILONR_PRM] / 15.0, 3.0 ) ) + 0.746;
|
||||
P_6 = P_5 * exp( -pow( f_n / 18.0, 0.368 ) );
|
||||
P_7 = 1.0 +
|
||||
4.069* P_6* pow( g, 0.479 ) * exp( -1.347 * pow( g, 0.595 ) - 0.17 * pow( g, 2.5 ) );
|
||||
P_7 = 1.0
|
||||
+ 4.069 * P_6 * pow( g, 0.479 ) * exp( -1.347 * pow( g, 0.595 ) - 0.17 * pow( g, 2.5 ) );
|
||||
|
||||
F_e = P_1 * P_2 * pow( (P_3 * P_4 + 0.1844 * P_7) * f_n, 1.5763 );
|
||||
F_e = P_1 * P_2 * pow( ( P_3 * P_4 + 0.1844 * P_7 ) * f_n, 1.5763 );
|
||||
/* even-mode effective dielectric constant */
|
||||
er_eff_e = er - (er - er_eff) / (1.0 + F_e);
|
||||
er_eff_e = m_parameters[EPSILONR_PRM] - ( m_parameters[EPSILONR_PRM] - er_eff ) / ( 1.0 + F_e );
|
||||
|
||||
er_eff = er_eff_o_0;
|
||||
P_8 = 0.7168 * ( 1.0 + 1.076 / ( 1.0 + 0.0576 * (er - 1.0) ) );
|
||||
P_9 = P_8 - 0.7913 *
|
||||
( 1.0 - exp( -pow( f_n / 20.0, 1.424 ) ) ) * atan( 2.481 * pow( er / 8.0, 0.946 ) );
|
||||
P_10 = 0.242 * pow( er - 1.0, 0.55 );
|
||||
P_11 = 0.6366 * (exp( -0.3401 * f_n ) - 1.0) * atan( 1.263 * pow( u / 3.0, 1.629 ) );
|
||||
P_12 = P_9 + (1.0 - P_9) / ( 1.0 + 1.183 * pow( u, 1.376 ) );
|
||||
P_13 = 1.695 * P_10 / (0.414 + 1.605 * P_10);
|
||||
P_8 = 0.7168 * ( 1.0 + 1.076 / ( 1.0 + 0.0576 * ( m_parameters[EPSILONR_PRM] - 1.0 ) ) );
|
||||
P_9 = P_8
|
||||
- 0.7913 * ( 1.0 - exp( -pow( f_n / 20.0, 1.424 ) ) )
|
||||
* atan( 2.481 * pow( m_parameters[EPSILONR_PRM] / 8.0, 0.946 ) );
|
||||
P_10 = 0.242 * pow( m_parameters[EPSILONR_PRM] - 1.0, 0.55 );
|
||||
P_11 = 0.6366 * ( exp( -0.3401 * f_n ) - 1.0 ) * atan( 1.263 * pow( u / 3.0, 1.629 ) );
|
||||
P_12 = P_9 + ( 1.0 - P_9 ) / ( 1.0 + 1.183 * pow( u, 1.376 ) );
|
||||
P_13 = 1.695 * P_10 / ( 0.414 + 1.605 * P_10 );
|
||||
P_14 = 0.8928 + 0.1072 * ( 1.0 - exp( -0.42 * pow( f_n / 20.0, 3.215 ) ) );
|
||||
P_15 = fabs( 1.0 - 0.8928 * (1.0 + P_11) * P_12 * exp( -P_13 * pow( g, 1.092 ) ) / P_14 );
|
||||
P_15 = fabs( 1.0 - 0.8928 * ( 1.0 + P_11 ) * P_12 * exp( -P_13 * pow( g, 1.092 ) ) / P_14 );
|
||||
|
||||
F_o = P_1 * P_2 * pow( (P_3 * P_4 + 0.1844) * f_n * P_15, 1.5763 );
|
||||
F_o = P_1 * P_2 * pow( ( P_3 * P_4 + 0.1844 ) * f_n * P_15, 1.5763 );
|
||||
/* odd-mode effective dielectric constant */
|
||||
er_eff_o = er - (er - er_eff) / (1.0 + F_o);
|
||||
er_eff_o = m_parameters[EPSILONR_PRM] - ( m_parameters[EPSILONR_PRM] - er_eff ) / ( 1.0 + F_o );
|
||||
}
|
||||
|
||||
|
||||
|
@ -497,34 +471,40 @@ void C_MICROSTRIP::conductor_losses()
|
|||
e_r_eff_o_0 = er_eff_o_0;
|
||||
Z0_h_e = Z0_e_0 * sqrt( e_r_eff_e_0 ); /* homogeneous stripline impedance */
|
||||
Z0_h_o = Z0_o_0 * sqrt( e_r_eff_o_0 ); /* homogeneous stripline impedance */
|
||||
delta = m_skindepth;
|
||||
delta = m_parameters[SKIN_DEPTH_PRM];
|
||||
|
||||
if( m_freq > 0.0 )
|
||||
if( m_parameters[FREQUENCY_PRM] > 0.0 )
|
||||
{
|
||||
/* current distribution factor (same for the two modes) */
|
||||
K = exp( -1.2 * pow( (Z0_h_e + Z0_h_o) / (2.0 * ZF0), 0.7 ) );
|
||||
K = exp( -1.2 * pow( ( Z0_h_e + Z0_h_o ) / ( 2.0 * ZF0 ), 0.7 ) );
|
||||
/* skin resistance */
|
||||
R_s = 1.0 / (m_sigma * delta);
|
||||
R_s = 1.0 / ( m_parameters[SIGMA_PRM] * delta );
|
||||
/* correction for surface roughness */
|
||||
R_s *= 1.0 + ( (2.0 / M_PI) * atan( 1.40 * pow( (rough / delta), 2.0 ) ) );
|
||||
R_s *= 1.0
|
||||
+ ( ( 2.0 / M_PI )
|
||||
* atan( 1.40 * pow( ( m_parameters[ROUGH_PRM] / delta ), 2.0 ) ) );
|
||||
|
||||
/* even-mode strip inductive quality factor */
|
||||
Q_c_e = (M_PI * Z0_h_e * w * m_freq) / (R_s * C0 * K);
|
||||
Q_c_e = ( M_PI * Z0_h_e * m_parameters[PHYS_WIDTH_PRM] * m_parameters[FREQUENCY_PRM] )
|
||||
/ ( R_s * C0 * K );
|
||||
/* even-mode losses per unith length */
|
||||
alpha_c_e = ( 20.0 * M_PI / log( 10.0 ) ) * m_freq * sqrt( e_r_eff_e_0 ) / (C0 * Q_c_e);
|
||||
alpha_c_e = ( 20.0 * M_PI / log( 10.0 ) ) * m_parameters[FREQUENCY_PRM]
|
||||
* sqrt( e_r_eff_e_0 ) / ( C0 * Q_c_e );
|
||||
|
||||
/* odd-mode strip inductive quality factor */
|
||||
Q_c_o = (M_PI * Z0_h_o * w * m_freq) / (R_s * C0 * K);
|
||||
Q_c_o = ( M_PI * Z0_h_o * m_parameters[PHYS_WIDTH_PRM] * m_parameters[FREQUENCY_PRM] )
|
||||
/ ( R_s * C0 * K );
|
||||
/* odd-mode losses per unith length */
|
||||
alpha_c_o = ( 20.0 * M_PI / log( 10.0 ) ) * m_freq * sqrt( e_r_eff_o_0 ) / (C0 * Q_c_o);
|
||||
alpha_c_o = ( 20.0 * M_PI / log( 10.0 ) ) * m_parameters[FREQUENCY_PRM]
|
||||
* sqrt( e_r_eff_o_0 ) / ( C0 * Q_c_o );
|
||||
}
|
||||
else
|
||||
{
|
||||
alpha_c_e = alpha_c_o = 0.0;
|
||||
}
|
||||
|
||||
atten_cond_e = alpha_c_e * l;
|
||||
atten_cond_o = alpha_c_o * l;
|
||||
atten_cond_e = alpha_c_e * m_parameters[PHYS_LEN_PRM];
|
||||
atten_cond_o = alpha_c_o * m_parameters[PHYS_LEN_PRM];
|
||||
}
|
||||
|
||||
|
||||
|
@ -537,21 +517,19 @@ void C_MICROSTRIP::dielectric_losses()
|
|||
double e_r, e_r_eff_e_0, e_r_eff_o_0;
|
||||
double alpha_d_e, alpha_d_o;
|
||||
|
||||
e_r = er;
|
||||
e_r = m_parameters[EPSILONR_PRM];
|
||||
e_r_eff_e_0 = er_eff_e_0;
|
||||
e_r_eff_o_0 = er_eff_o_0;
|
||||
|
||||
alpha_d_e =
|
||||
( 20.0 * M_PI /
|
||||
log( 10.0 ) ) *
|
||||
(m_freq / C0) * ( e_r / sqrt( e_r_eff_e_0 ) ) * ( (e_r_eff_e_0 - 1.0) / (e_r - 1.0) ) * m_tand;
|
||||
alpha_d_o =
|
||||
( 20.0 * M_PI /
|
||||
log( 10.0 ) ) *
|
||||
(m_freq / C0) * ( e_r / sqrt( e_r_eff_o_0 ) ) * ( (e_r_eff_o_0 - 1.0) / (e_r - 1.0) ) * m_tand;
|
||||
alpha_d_e = ( 20.0 * M_PI / log( 10.0 ) ) * ( m_parameters[FREQUENCY_PRM] / C0 )
|
||||
* ( e_r / sqrt( e_r_eff_e_0 ) ) * ( ( e_r_eff_e_0 - 1.0 ) / ( e_r - 1.0 ) )
|
||||
* m_parameters[TAND_PRM];
|
||||
alpha_d_o = ( 20.0 * M_PI / log( 10.0 ) ) * ( m_parameters[FREQUENCY_PRM] / C0 )
|
||||
* ( e_r / sqrt( e_r_eff_o_0 ) ) * ( ( e_r_eff_o_0 - 1.0 ) / ( e_r - 1.0 ) )
|
||||
* m_parameters[TAND_PRM];
|
||||
|
||||
atten_dielectric_e = alpha_d_e * l;
|
||||
atten_dielectric_o = alpha_d_o * l;
|
||||
atten_dielectric_e = alpha_d_e * m_parameters[PHYS_LEN_PRM];
|
||||
atten_dielectric_o = alpha_d_o * m_parameters[PHYS_LEN_PRM];
|
||||
}
|
||||
|
||||
|
||||
|
@ -561,7 +539,7 @@ void C_MICROSTRIP::dielectric_losses()
|
|||
*/
|
||||
void C_MICROSTRIP::attenuation()
|
||||
{
|
||||
m_skindepth = skin_depth();
|
||||
m_parameters[SKIN_DEPTH_PRM] = skin_depth();
|
||||
conductor_losses();
|
||||
dielectric_losses();
|
||||
}
|
||||
|
@ -583,38 +561,33 @@ void C_MICROSTRIP::line_angle()
|
|||
/* odd-mode velocity */
|
||||
v_o = C0 / sqrt( e_r_eff_o );
|
||||
/* even-mode wavelength */
|
||||
lambda_g_e = v_e / m_freq;
|
||||
lambda_g_e = v_e / m_parameters[FREQUENCY_PRM];
|
||||
/* odd-mode wavelength */
|
||||
lambda_g_o = v_o / m_freq;
|
||||
lambda_g_o = v_o / m_parameters[FREQUENCY_PRM];
|
||||
/* electrical angles */
|
||||
ang_l_e = 2.0 * M_PI * l / lambda_g_e; /* in radians */
|
||||
ang_l_o = 2.0 * M_PI * l / lambda_g_o; /* in radians */
|
||||
ang_l_e = 2.0 * M_PI * m_parameters[PHYS_LEN_PRM] / lambda_g_e; /* in radians */
|
||||
ang_l_o = 2.0 * M_PI * m_parameters[PHYS_LEN_PRM] / lambda_g_o; /* in radians */
|
||||
}
|
||||
|
||||
|
||||
void C_MICROSTRIP::syn_err_fun( double* f1,
|
||||
double* f2,
|
||||
double s_h,
|
||||
double w_h,
|
||||
double e_r,
|
||||
double w_h_se,
|
||||
double w_h_so )
|
||||
void C_MICROSTRIP::syn_err_fun(
|
||||
double* f1, double* f2, double s_h, double w_h, double e_r, double w_h_se, double w_h_so )
|
||||
{
|
||||
double g, he;
|
||||
|
||||
g = cosh( 0.5 * M_PI * s_h );
|
||||
he = cosh( M_PI * w_h + 0.5 * M_PI * s_h );
|
||||
|
||||
*f1 = (2.0 / M_PI) * acosh( (2.0 * he - g + 1.0) / (g + 1.0) );
|
||||
*f2 = (2.0 / M_PI) * acosh( (2.0 * he - g - 1.0) / (g - 1.0) );
|
||||
*f1 = ( 2.0 / M_PI ) * acosh( ( 2.0 * he - g + 1.0 ) / ( g + 1.0 ) );
|
||||
*f2 = ( 2.0 / M_PI ) * acosh( ( 2.0 * he - g - 1.0 ) / ( g - 1.0 ) );
|
||||
|
||||
if( e_r <= 6.0 )
|
||||
{
|
||||
*f2 += ( 4.0 / ( M_PI * (1.0 + e_r / 2.0) ) ) * acosh( 1.0 + 2.0 * w_h / s_h );
|
||||
*f2 += ( 4.0 / ( M_PI * ( 1.0 + e_r / 2.0 ) ) ) * acosh( 1.0 + 2.0 * w_h / s_h );
|
||||
}
|
||||
else
|
||||
{
|
||||
*f2 += (1.0 / M_PI) * acosh( 1.0 + 2.0 * w_h / s_h );
|
||||
*f2 += ( 1.0 / M_PI ) * acosh( 1.0 + 2.0 * w_h / s_h );
|
||||
}
|
||||
|
||||
*f1 -= w_h_se;
|
||||
|
@ -637,44 +610,45 @@ void C_MICROSTRIP::synth_width()
|
|||
double eps = 1e-04;
|
||||
|
||||
f1 = f2 = 0;
|
||||
e_r = er;
|
||||
e_r = m_parameters[EPSILONR_PRM];
|
||||
|
||||
Z0 = Z0e / 2.0;
|
||||
Z0 = m_parameters[Z0_E_PRM] / 2.0;
|
||||
/* Wheeler formula for single microstrip synthesis */
|
||||
a = exp( Z0 * sqrt( e_r + 1.0 ) / 42.4 ) - 1.0;
|
||||
w_h_se = 8.0 * sqrt( a * ( (7.0 + 4.0 / e_r) / 11.0 ) + ( (1.0 + 1.0 / e_r) / 0.81 ) ) / a;
|
||||
w_h_se = 8.0 * sqrt( a * ( ( 7.0 + 4.0 / e_r ) / 11.0 ) + ( ( 1.0 + 1.0 / e_r ) / 0.81 ) ) / a;
|
||||
|
||||
Z0 = Z0o / 2.0;
|
||||
Z0 = m_parameters[Z0_O_PRM] / 2.0;
|
||||
/* Wheeler formula for single microstrip synthesis */
|
||||
a = exp( Z0 * sqrt( e_r + 1.0 ) / 42.4 ) - 1.0;
|
||||
w_h_so = 8.0 * sqrt( a * ( (7.0 + 4.0 / e_r) / 11.0 ) + ( (1.0 + 1.0 / e_r) / 0.81 ) ) / a;
|
||||
w_h_so = 8.0 * sqrt( a * ( ( 7.0 + 4.0 / e_r ) / 11.0 ) + ( ( 1.0 + 1.0 / e_r ) / 0.81 ) ) / a;
|
||||
|
||||
ce = cosh( 0.5 * M_PI * w_h_se );
|
||||
co = cosh( 0.5 * M_PI * w_h_so );
|
||||
/* first guess at s/h */
|
||||
s_h = (2.0 / M_PI) * acosh( (ce + co - 2.0) / (co - ce) );
|
||||
/* first guess at m_parameters[PHYS_S_PRM]/h */
|
||||
s_h = ( 2.0 / M_PI ) * acosh( ( ce + co - 2.0 ) / ( co - ce ) );
|
||||
/* first guess at w/h */
|
||||
w_h = acosh( (ce * co - 1.0) / (co - ce) ) / M_PI - s_h / 2.0;
|
||||
w_h = acosh( ( ce * co - 1.0 ) / ( co - ce ) ) / M_PI - s_h / 2.0;
|
||||
|
||||
s = s_h * h;
|
||||
w = w_h * h;
|
||||
m_parameters[PHYS_S_PRM] = s_h * m_parameters[H_PRM];
|
||||
m_parameters[PHYS_WIDTH_PRM] = w_h * m_parameters[H_PRM];
|
||||
|
||||
syn_err_fun( &f1, &f2, s_h, w_h, e_r, w_h_se, w_h_so );
|
||||
|
||||
/* rather crude Newton-Rhapson; we need this beacuse the estimate of */
|
||||
/* w_h is often quite far from the true value (see Akhtarzad S. et al.) */
|
||||
do {
|
||||
do
|
||||
{
|
||||
/* compute Jacobian */
|
||||
syn_err_fun( &ft1, &ft2, s_h + eps, w_h, e_r, w_h_se, w_h_so );
|
||||
j11 = (ft1 - f1) / eps;
|
||||
j21 = (ft2 - f2) / eps;
|
||||
j11 = ( ft1 - f1 ) / eps;
|
||||
j21 = ( ft2 - f2 ) / eps;
|
||||
syn_err_fun( &ft1, &ft2, s_h, w_h + eps, e_r, w_h_se, w_h_so );
|
||||
j12 = (ft1 - f1) / eps;
|
||||
j22 = (ft2 - f2) / eps;
|
||||
j12 = ( ft1 - f1 ) / eps;
|
||||
j22 = ( ft2 - f2 ) / eps;
|
||||
|
||||
/* compute next step */
|
||||
d_s_h = (-f1 * j22 + f2 * j12) / (j11 * j22 - j21 * j12);
|
||||
d_w_h = (-f2 * j11 + f1 * j21) / (j11 * j22 - j21 * j12);
|
||||
d_s_h = ( -f1 * j22 + f2 * j12 ) / ( j11 * j22 - j21 * j12 );
|
||||
d_w_h = ( -f2 * j11 + f1 * j21 ) / ( j11 * j22 - j21 * j12 );
|
||||
|
||||
//g_print("j11 = %e\tj12 = %e\tj21 = %e\tj22 = %e\n", j11, j12, j21, j22);
|
||||
//g_print("det = %e\n", j11*j22 - j21*j22);
|
||||
|
@ -691,8 +665,8 @@ void C_MICROSTRIP::synth_width()
|
|||
} while( err > 1e-04 );
|
||||
|
||||
|
||||
s = s_h * h;
|
||||
w = w_h * h;
|
||||
m_parameters[PHYS_S_PRM] = s_h * m_parameters[H_PRM];
|
||||
m_parameters[PHYS_WIDTH_PRM] = w_h * m_parameters[H_PRM];
|
||||
}
|
||||
|
||||
|
||||
|
@ -711,62 +685,54 @@ void C_MICROSTRIP::Z0_dispersion()
|
|||
double f_n, g, u, e_r;
|
||||
double R_1, R_2, R_7, R_10, R_11, R_12, R_15, R_16, tmpf;
|
||||
|
||||
e_r = er;
|
||||
e_r = m_parameters[EPSILONR_PRM];
|
||||
|
||||
u = w / h; /* normalize line width */
|
||||
g = s / h; /* normalize line spacing */
|
||||
u = m_parameters[PHYS_WIDTH_PRM] / m_parameters[H_PRM]; /* normalize line width */
|
||||
g = m_parameters[PHYS_S_PRM] / m_parameters[H_PRM]; /* normalize line spacing */
|
||||
|
||||
/* normalized frequency [GHz * mm] */
|
||||
f_n = m_freq * h / 1e06;
|
||||
f_n = m_parameters[FREQUENCY_PRM] * m_parameters[H_PRM] / 1e06;
|
||||
|
||||
e_r_eff_single_f = aux_ms->er_eff;
|
||||
e_r_eff_single_0 = aux_ms->er_eff_0;
|
||||
Z0_single_f = aux_ms->Z0;
|
||||
Z0_single_f = aux_ms->m_parameters[Z0_PRM];
|
||||
|
||||
e_r_eff_o_f = er_eff_o;
|
||||
e_r_eff_o_0 = er_eff_o_0;
|
||||
|
||||
Q_11 = 0.893 * ( 1.0 - 0.3 / ( 1.0 + 0.7 * (e_r - 1.0) ) );
|
||||
Q_12 = 2.121 * ( pow( f_n / 20.0, 4.91 ) / ( 1.0 + Q_11 * pow( f_n / 20.0, 4.91 ) ) ) * exp(
|
||||
-2.87 * g ) * pow( g, 0.902 );
|
||||
Q_11 = 0.893 * ( 1.0 - 0.3 / ( 1.0 + 0.7 * ( e_r - 1.0 ) ) );
|
||||
Q_12 = 2.121 * ( pow( f_n / 20.0, 4.91 ) / ( 1.0 + Q_11 * pow( f_n / 20.0, 4.91 ) ) )
|
||||
* exp( -2.87 * g ) * pow( g, 0.902 );
|
||||
Q_13 = 1.0 + 0.038 * pow( e_r / 8.0, 5.1 );
|
||||
Q_14 = 1.0 + 1.203 * pow( e_r / 15.0, 4.0 ) / ( 1.0 + pow( e_r / 15.0, 4.0 ) );
|
||||
Q_15 = 1.887 *
|
||||
exp( -1.5 *
|
||||
pow( g,
|
||||
0.84 ) ) *
|
||||
pow( g,
|
||||
Q_14 ) /
|
||||
( 1.0 + 0.41 *
|
||||
pow( f_n / 15.0, 3.0 ) * pow( u, 2.0 / Q_13 ) / ( 0.125 + pow( u, 1.626 / Q_13 ) ) );
|
||||
Q_15 = 1.887 * exp( -1.5 * pow( g, 0.84 ) ) * pow( g, Q_14 )
|
||||
/ ( 1.0
|
||||
+ 0.41 * pow( f_n / 15.0, 3.0 ) * pow( u, 2.0 / Q_13 )
|
||||
/ ( 0.125 + pow( u, 1.626 / Q_13 ) ) );
|
||||
Q_16 = ( 1.0 + 9.0 / ( 1.0 + 0.403 * pow( e_r - 1.0, 2 ) ) ) * Q_15;
|
||||
Q_17 = 0.394 *
|
||||
( 1.0 -
|
||||
exp( -1.47 * pow( u / 7.0, 0.672 ) ) ) * ( 1.0 - exp( -4.25 * pow( f_n / 20.0, 1.87 ) ) );
|
||||
Q_17 = 0.394 * ( 1.0 - exp( -1.47 * pow( u / 7.0, 0.672 ) ) )
|
||||
* ( 1.0 - exp( -4.25 * pow( f_n / 20.0, 1.87 ) ) );
|
||||
Q_18 = 0.61 * ( 1.0 - exp( -2.13 * pow( u / 8.0, 1.593 ) ) ) / ( 1.0 + 6.544 * pow( g, 4.17 ) );
|
||||
Q_19 = 0.21 * g * g * g * g /
|
||||
( ( 1.0 + 0.18 * pow( g, 4.9 ) ) * (1.0 + 0.1 * u * u) * ( 1.0 + pow( f_n / 24.0, 3.0 ) ) );
|
||||
Q_19 = 0.21 * g * g * g * g
|
||||
/ ( ( 1.0 + 0.18 * pow( g, 4.9 ) ) * ( 1.0 + 0.1 * u * u )
|
||||
* ( 1.0 + pow( f_n / 24.0, 3.0 ) ) );
|
||||
Q_20 = ( 0.09 + 1.0 / ( 1.0 + 0.1 * pow( e_r - 1, 2.7 ) ) ) * Q_19;
|
||||
Q_21 =
|
||||
fabs( 1.0 - 42.54 *
|
||||
pow( g, 0.133 ) * exp( -0.812 * g ) * pow( u, 2.5 ) / ( 1.0 + 0.033 * pow( u, 2.5 ) ) );
|
||||
Q_21 = fabs( 1.0
|
||||
- 42.54 * pow( g, 0.133 ) * exp( -0.812 * g ) * pow( u, 2.5 )
|
||||
/ ( 1.0 + 0.033 * pow( u, 2.5 ) ) );
|
||||
|
||||
r_e = pow( f_n / 28.843, 12 );
|
||||
q_e = 0.016 + pow( 0.0514 * e_r * Q_21, 4.524 );
|
||||
p_e = 4.766 * exp( -3.228 * pow( u, 0.641 ) );
|
||||
d_e = 5.086 * q_e *
|
||||
( r_e /
|
||||
(0.3838 + 0.386 *
|
||||
q_e) ) *
|
||||
( exp( -22.2 *
|
||||
pow( u,
|
||||
1.92 ) ) /
|
||||
(1.0 + 1.2992 * r_e) ) * ( pow( e_r - 1.0, 6.0 ) / ( 1.0 + 10 * pow( e_r - 1.0, 6.0 ) ) );
|
||||
C_e = 1.0 + 1.275 *
|
||||
( 1.0 -
|
||||
exp( -0.004625 * p_e *
|
||||
pow( e_r,
|
||||
1.674 ) * pow( f_n / 18.365, 2.745 ) ) ) - Q_12 + Q_16 - Q_17 + Q_18 + Q_20;
|
||||
d_e = 5.086 * q_e * ( r_e / ( 0.3838 + 0.386 * q_e ) )
|
||||
* ( exp( -22.2 * pow( u, 1.92 ) ) / ( 1.0 + 1.2992 * r_e ) )
|
||||
* ( pow( e_r - 1.0, 6.0 ) / ( 1.0 + 10 * pow( e_r - 1.0, 6.0 ) ) );
|
||||
C_e = 1.0
|
||||
+ 1.275
|
||||
* ( 1.0
|
||||
- exp( -0.004625 * p_e * pow( e_r, 1.674 )
|
||||
* pow( f_n / 18.365, 2.745 ) ) )
|
||||
- Q_12 + Q_16 - Q_17 + Q_18 + Q_20;
|
||||
|
||||
|
||||
R_1 = 0.03891 * pow( e_r, 1.4 );
|
||||
|
@ -774,42 +740,41 @@ void C_MICROSTRIP::Z0_dispersion()
|
|||
R_7 = 1.206 - 0.3144 * exp( -R_1 ) * ( 1.0 - exp( -R_2 ) );
|
||||
R_10 = 0.00044 * pow( e_r, 2.136 ) + 0.0184;
|
||||
tmpf = pow( f_n / 19.47, 6.0 );
|
||||
R_11 = tmpf / (1.0 + 0.0962 * tmpf);
|
||||
R_12 = 1.0 / (1.0 + 0.00245 * u * u);
|
||||
R_15 = 0.707* R_10* pow( f_n / 12.3, 1.097 );
|
||||
R_11 = tmpf / ( 1.0 + 0.0962 * tmpf );
|
||||
R_12 = 1.0 / ( 1.0 + 0.00245 * u * u );
|
||||
R_15 = 0.707 * R_10 * pow( f_n / 12.3, 1.097 );
|
||||
R_16 = 1.0 + 0.0503 * e_r * e_r * R_11 * ( 1.0 - exp( -pow( u / 15.0, 6.0 ) ) );
|
||||
Q_0 = R_7 * ( 1.0 - 1.1241 * (R_12 / R_16) * exp( -0.026 * pow( f_n, 1.15656 ) - R_15 ) );
|
||||
Q_0 = R_7 * ( 1.0 - 1.1241 * ( R_12 / R_16 ) * exp( -0.026 * pow( f_n, 1.15656 ) - R_15 ) );
|
||||
|
||||
/* even-mode frequency-dependent characteristic impedances */
|
||||
Z0e = Z0_e_0 * pow( 0.9408 * pow( e_r_eff_single_f, C_e ) - 0.9603, Q_0 ) / pow(
|
||||
(0.9408 - d_e) * pow( e_r_eff_single_0, C_e ) - 0.9603, Q_0 );
|
||||
m_parameters[Z0_E_PRM] = Z0_e_0 * pow( 0.9408 * pow( e_r_eff_single_f, C_e ) - 0.9603, Q_0 )
|
||||
/ pow( ( 0.9408 - d_e ) * pow( e_r_eff_single_0, C_e ) - 0.9603, Q_0 );
|
||||
|
||||
Q_29 = 15.16 / ( 1.0 + 0.196 * pow( e_r - 1.0, 2.0 ) );
|
||||
tmpf = pow( e_r - 1.0, 3.0 );
|
||||
Q_28 = 0.149 * tmpf / (94.5 + 0.038 * tmpf);
|
||||
Q_28 = 0.149 * tmpf / ( 94.5 + 0.038 * tmpf );
|
||||
tmpf = pow( e_r - 1.0, 1.5 );
|
||||
Q_27 = 0.4 * pow( g, 0.84 ) * ( 1.0 + 2.5 * tmpf / (5.0 + tmpf) );
|
||||
tmpf = pow( (e_r - 1.0) / 13.0, 12.0 );
|
||||
Q_26 = 30.0 - 22.2 * ( tmpf / (1.0 + 3.0 * tmpf) ) - Q_29;
|
||||
tmpf = (e_r - 1.0) * (e_r - 1.0);
|
||||
Q_25 = ( 0.3 * f_n * f_n / (10.0 + f_n * f_n) ) * ( 1.0 + 2.333 * tmpf / (5.0 + tmpf) );
|
||||
Q_24 =
|
||||
2.506* Q_28* pow( u,
|
||||
0.894 ) *
|
||||
pow( (1.0 + 1.3 * u) * f_n / 99.25, 4.29 ) / ( 3.575 + pow( u, 0.894 ) );
|
||||
Q_23 = 1.0 + 0.005 * f_n * Q_27 /
|
||||
( ( 1.0 + 0.812 * pow( f_n / 15.0, 1.9 ) ) * (1.0 + 0.025 * u * u) );
|
||||
Q_27 = 0.4 * pow( g, 0.84 ) * ( 1.0 + 2.5 * tmpf / ( 5.0 + tmpf ) );
|
||||
tmpf = pow( ( e_r - 1.0 ) / 13.0, 12.0 );
|
||||
Q_26 = 30.0 - 22.2 * ( tmpf / ( 1.0 + 3.0 * tmpf ) ) - Q_29;
|
||||
tmpf = ( e_r - 1.0 ) * ( e_r - 1.0 );
|
||||
Q_25 = ( 0.3 * f_n * f_n / ( 10.0 + f_n * f_n ) ) * ( 1.0 + 2.333 * tmpf / ( 5.0 + tmpf ) );
|
||||
Q_24 = 2.506 * Q_28 * pow( u, 0.894 ) * pow( ( 1.0 + 1.3 * u ) * f_n / 99.25, 4.29 )
|
||||
/ ( 3.575 + pow( u, 0.894 ) );
|
||||
Q_23 = 1.0
|
||||
+ 0.005 * f_n * Q_27
|
||||
/ ( ( 1.0 + 0.812 * pow( f_n / 15.0, 1.9 ) ) * ( 1.0 + 0.025 * u * u ) );
|
||||
Q_22 = 0.925 * pow( f_n / Q_26, 1.536 ) / ( 1.0 + 0.3 * pow( f_n / 30.0, 1.536 ) );
|
||||
|
||||
/* odd-mode frequency-dependent characteristic impedances */
|
||||
Z0o = Z0_single_f +
|
||||
(Z0_o_0 *
|
||||
pow( e_r_eff_o_f / e_r_eff_o_0,
|
||||
Q_22 ) - Z0_single_f * Q_23) / (1.0 + Q_24 + pow( 0.46 * g, 2.2 ) * Q_25);
|
||||
m_parameters[Z0_O_PRM] =
|
||||
Z0_single_f
|
||||
+ ( Z0_o_0 * pow( e_r_eff_o_f / e_r_eff_o_0, Q_22 ) - Z0_single_f * Q_23 )
|
||||
/ ( 1.0 + Q_24 + pow( 0.46 * g, 2.2 ) * Q_25 );
|
||||
}
|
||||
|
||||
|
||||
void C_MICROSTRIP::calc()
|
||||
void C_MICROSTRIP::calcAnalyze()
|
||||
{
|
||||
/* compute thickness corrections */
|
||||
delta_u_thickness();
|
||||
|
@ -828,67 +793,62 @@ void C_MICROSTRIP::calc()
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* get_microstrip_sub
|
||||
* get and assign microstrip substrate parameters
|
||||
* into microstrip structure
|
||||
*/
|
||||
void C_MICROSTRIP::get_c_microstrip_sub()
|
||||
void C_MICROSTRIP::showAnalyze()
|
||||
{
|
||||
er = getProperty( EPSILONR_PRM );
|
||||
m_murC = getProperty( MURC_PRM );
|
||||
h = getProperty( H_PRM );
|
||||
ht = getProperty( H_T_PRM );
|
||||
t = getProperty( T_PRM );
|
||||
m_sigma = 1.0/getProperty( RHO_PRM );
|
||||
m_tand = getProperty( TAND_PRM );
|
||||
rough = getProperty( ROUGH_PRM );
|
||||
setProperty( Z0_E_PRM, m_parameters[Z0_E_PRM] );
|
||||
setProperty( Z0_O_PRM, m_parameters[Z0_O_PRM] );
|
||||
setProperty( ANG_L_PRM, sqrt( ang_l_e * ang_l_o ) );
|
||||
|
||||
//Check for errors
|
||||
if( !std::isfinite( m_parameters[Z0_O_PRM] ) || m_parameters[Z0_O_PRM] <= 0.0 )
|
||||
setErrorLevel( Z0_O_PRM, TRANSLINE_ERROR );
|
||||
|
||||
if( !std::isfinite( m_parameters[Z0_E_PRM] ) || m_parameters[Z0_E_PRM] <= 0.0 )
|
||||
setErrorLevel( Z0_E_PRM, TRANSLINE_ERROR );
|
||||
|
||||
if( !std::isfinite( m_parameters[ANG_L_PRM] ) || m_parameters[ANG_L_PRM] <= 0.0 )
|
||||
setErrorLevel( ANG_L_PRM, TRANSLINE_ERROR );
|
||||
|
||||
// Check for warnings
|
||||
if( !std::isfinite( m_parameters[PHYS_WIDTH_PRM] ) || m_parameters[PHYS_WIDTH_PRM] <= 0.0 )
|
||||
setErrorLevel( PHYS_WIDTH_PRM, TRANSLINE_WARNING );
|
||||
|
||||
if( !std::isfinite( m_parameters[PHYS_S_PRM] ) || m_parameters[PHYS_S_PRM] <= 0.0 )
|
||||
setErrorLevel( PHYS_S_PRM, TRANSLINE_WARNING );
|
||||
|
||||
if( !std::isfinite( m_parameters[PHYS_LEN_PRM] ) || m_parameters[PHYS_LEN_PRM] <= 0.0 )
|
||||
setErrorLevel( PHYS_LEN_PRM, TRANSLINE_WARNING );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* get_c_microstrip_comp
|
||||
* get and assign microstrip component parameters
|
||||
* into microstrip structure
|
||||
*/
|
||||
void C_MICROSTRIP::get_c_microstrip_comp()
|
||||
void C_MICROSTRIP::showSynthesize()
|
||||
{
|
||||
m_freq = getProperty( FREQUENCY_PRM );
|
||||
setProperty( PHYS_WIDTH_PRM, m_parameters[PHYS_WIDTH_PRM] );
|
||||
setProperty( PHYS_S_PRM, m_parameters[PHYS_S_PRM] );
|
||||
setProperty( PHYS_LEN_PRM, m_parameters[PHYS_LEN_PRM] );
|
||||
|
||||
//Check for errors
|
||||
if( !std::isfinite( m_parameters[PHYS_WIDTH_PRM] ) || m_parameters[PHYS_WIDTH_PRM] <= 0.0 )
|
||||
setErrorLevel( PHYS_WIDTH_PRM, TRANSLINE_ERROR );
|
||||
|
||||
if( !std::isfinite( m_parameters[PHYS_S_PRM] ) || m_parameters[PHYS_S_PRM] <= 0.0 )
|
||||
setErrorLevel( PHYS_S_PRM, TRANSLINE_ERROR );
|
||||
|
||||
if( !std::isfinite( m_parameters[PHYS_LEN_PRM] ) || m_parameters[PHYS_LEN_PRM] <= 0.0 )
|
||||
setErrorLevel( PHYS_LEN_PRM, TRANSLINE_ERROR );
|
||||
|
||||
// Check for warnings
|
||||
if( !std::isfinite( m_parameters[Z0_O_PRM] ) || m_parameters[Z0_O_PRM] <= 0.0 )
|
||||
setErrorLevel( Z0_O_PRM, TRANSLINE_WARNING );
|
||||
|
||||
if( !std::isfinite( m_parameters[Z0_E_PRM] ) || m_parameters[Z0_E_PRM] <= 0.0 )
|
||||
setErrorLevel( Z0_E_PRM, TRANSLINE_WARNING );
|
||||
|
||||
if( !std::isfinite( m_parameters[ANG_L_PRM] ) || m_parameters[ANG_L_PRM] <= 0.0 )
|
||||
setErrorLevel( ANG_L_PRM, TRANSLINE_WARNING );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* get_c_microstrip_elec
|
||||
* get and assign microstrip electrical parameters
|
||||
* into microstrip structure
|
||||
*/
|
||||
void C_MICROSTRIP::get_c_microstrip_elec()
|
||||
{
|
||||
Z0e = getProperty( Z0_E_PRM );
|
||||
Z0o = getProperty( Z0_O_PRM );
|
||||
ang_l_e = getProperty( ANG_L_PRM );
|
||||
ang_l_o = getProperty( ANG_L_PRM );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* get_c_microstrip_phys
|
||||
* get and assign microstrip physical parameters
|
||||
* into microstrip structure
|
||||
*/
|
||||
void C_MICROSTRIP::get_c_microstrip_phys()
|
||||
{
|
||||
w = getProperty( PHYS_WIDTH_PRM );
|
||||
s = getProperty( PHYS_S_PRM );
|
||||
l = getProperty( PHYS_LEN_PRM );
|
||||
}
|
||||
|
||||
|
||||
void C_MICROSTRIP::show_results()
|
||||
{
|
||||
setProperty( Z0_E_PRM, Z0e );
|
||||
setProperty( Z0_O_PRM , Z0o );
|
||||
setProperty( ANG_L_PRM, sqrt( ang_l_e * ang_l_o ) );
|
||||
|
||||
setResult( 0, er_eff_e, "" );
|
||||
setResult( 1, er_eff_o, "" );
|
||||
|
@ -897,94 +857,65 @@ void C_MICROSTRIP::show_results()
|
|||
setResult( 4, atten_dielectric_e, "dB" );
|
||||
setResult( 5, atten_dielectric_o, "dB" );
|
||||
|
||||
setResult( 6, m_skindepth / UNIT_MICRON, "µm" );
|
||||
setResult( 6, m_parameters[SKIN_DEPTH_PRM] / UNIT_MICRON, "µm" );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* analysis function
|
||||
*/
|
||||
void C_MICROSTRIP::analyze()
|
||||
void C_MICROSTRIP::syn_fun(
|
||||
double* f1, double* f2, double s_h, double w_h, double Z0_e, double Z0_o )
|
||||
{
|
||||
/* Get and assign substrate parameters */
|
||||
get_c_microstrip_sub();
|
||||
/* Get and assign component parameters */
|
||||
get_c_microstrip_comp();
|
||||
/* Get and assign physical parameters */
|
||||
get_c_microstrip_phys();
|
||||
m_parameters[PHYS_S_PRM] = s_h * m_parameters[H_PRM];
|
||||
m_parameters[PHYS_WIDTH_PRM] = w_h * m_parameters[H_PRM];
|
||||
|
||||
/* compute coupled microstrip parameters */
|
||||
calc();
|
||||
/* print results in the subwindow */
|
||||
show_results();
|
||||
}
|
||||
calcAnalyze();
|
||||
|
||||
|
||||
void C_MICROSTRIP::syn_fun( double* f1,
|
||||
double* f2,
|
||||
double s_h,
|
||||
double w_h,
|
||||
double Z0_e,
|
||||
double Z0_o )
|
||||
{
|
||||
s = s_h * h;
|
||||
w = w_h * h;
|
||||
|
||||
/* compute coupled microstrip parameters */
|
||||
calc();
|
||||
|
||||
*f1 = Z0e - Z0_e;
|
||||
*f2 = Z0o - Z0_o;
|
||||
*f1 = m_parameters[Z0_E_PRM] - Z0_e;
|
||||
*f2 = m_parameters[Z0_O_PRM] - Z0_o;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* synthesis function
|
||||
*/
|
||||
void C_MICROSTRIP::synthesize()
|
||||
void C_MICROSTRIP::calcSynthesize()
|
||||
{
|
||||
double Z0_e, Z0_o;
|
||||
double Z0_e, Z0_o, ang_l_dest;
|
||||
double f1, f2, ft1, ft2, j11, j12, j21, j22, d_s_h, d_w_h, err;
|
||||
double eps = 1e-04;
|
||||
double w_h, s_h, le, lo;
|
||||
|
||||
/* Get and assign substrate parameters */
|
||||
get_c_microstrip_sub();
|
||||
|
||||
/* Get and assign component parameters */
|
||||
get_c_microstrip_comp();
|
||||
|
||||
/* Get and assign electrical parameters */
|
||||
get_c_microstrip_elec();
|
||||
|
||||
/* Get and assign physical parameters */
|
||||
/* at present it is required only for getting strips length */
|
||||
get_c_microstrip_phys();
|
||||
|
||||
|
||||
/* required value of Z0_e and Z0_o */
|
||||
Z0_e = Z0e;
|
||||
Z0_o = Z0o;
|
||||
Z0_e = m_parameters[Z0_E_PRM];
|
||||
Z0_o = m_parameters[Z0_O_PRM];
|
||||
|
||||
|
||||
ang_l_e = m_parameters[ANG_L_PRM];
|
||||
ang_l_o = m_parameters[ANG_L_PRM];
|
||||
ang_l_dest = m_parameters[ANG_L_PRM];
|
||||
|
||||
|
||||
/* calculate width and use for initial value in Newton's method */
|
||||
synth_width();
|
||||
w_h = w / h;
|
||||
s_h = s / h;
|
||||
w_h = m_parameters[PHYS_WIDTH_PRM] / m_parameters[H_PRM];
|
||||
s_h = m_parameters[PHYS_S_PRM] / m_parameters[H_PRM];
|
||||
f1 = f2 = 0;
|
||||
|
||||
/* rather crude Newton-Rhapson */
|
||||
do {
|
||||
do
|
||||
{
|
||||
/* compute Jacobian */
|
||||
syn_fun( &ft1, &ft2, s_h + eps, w_h, Z0_e, Z0_o );
|
||||
j11 = (ft1 - f1) / eps;
|
||||
j21 = (ft2 - f2) / eps;
|
||||
j11 = ( ft1 - f1 ) / eps;
|
||||
j21 = ( ft2 - f2 ) / eps;
|
||||
syn_fun( &ft1, &ft2, s_h, w_h + eps, Z0_e, Z0_o );
|
||||
j12 = (ft1 - f1) / eps;
|
||||
j22 = (ft2 - f2) / eps;
|
||||
j12 = ( ft1 - f1 ) / eps;
|
||||
j22 = ( ft2 - f2 ) / eps;
|
||||
|
||||
/* compute next step; increments of s_h and w_h */
|
||||
d_s_h = (-f1 * j22 + f2 * j12) / (j11 * j22 - j21 * j12);
|
||||
d_w_h = (-f2 * j11 + f1 * j21) / (j11 * j22 - j21 * j12);
|
||||
d_s_h = ( -f1 * j22 + f2 * j12 ) / ( j11 * j22 - j21 * j12 );
|
||||
d_w_h = ( -f2 * j11 + f1 * j21 ) / ( j11 * j22 - j21 * j12 );
|
||||
|
||||
s_h += d_s_h;
|
||||
w_h += d_w_h;
|
||||
|
@ -997,21 +928,18 @@ void C_MICROSTRIP::synthesize()
|
|||
} while( err > 1e-04 );
|
||||
|
||||
/* denormalize computed width and spacing */
|
||||
s = s_h * h;
|
||||
w = w_h * h;
|
||||
m_parameters[PHYS_S_PRM] = s_h * m_parameters[H_PRM];
|
||||
m_parameters[PHYS_WIDTH_PRM] = w_h * m_parameters[H_PRM];
|
||||
|
||||
setProperty( PHYS_WIDTH_PRM, w );
|
||||
setProperty( PHYS_S_PRM, s );
|
||||
|
||||
/* calculate physical length */
|
||||
ang_l_e = getProperty( ANG_L_PRM );
|
||||
ang_l_o = getProperty( ANG_L_PRM );
|
||||
le = C0 / m_freq / sqrt( er_eff_e ) * ang_l_e / 2.0 / M_PI;
|
||||
lo = C0 / m_freq / sqrt( er_eff_o ) * ang_l_o / 2.0 / M_PI;
|
||||
l = sqrt( le * lo );
|
||||
setProperty( PHYS_LEN_PRM, l );
|
||||
le = C0 / m_parameters[FREQUENCY_PRM] / sqrt( er_eff_e ) * ang_l_dest / 2.0 / M_PI;
|
||||
lo = C0 / m_parameters[FREQUENCY_PRM] / sqrt( er_eff_o ) * ang_l_dest / 2.0 / M_PI;
|
||||
m_parameters[PHYS_LEN_PRM] = sqrt( le * lo );
|
||||
|
||||
calc();
|
||||
/* print results in the subwindow */
|
||||
show_results();
|
||||
calcAnalyze();
|
||||
|
||||
m_parameters[ANG_L_PRM] = ang_l_dest;
|
||||
m_parameters[Z0_E_PRM] = Z0_e;
|
||||
m_parameters[Z0_O_PRM] = Z0_o;
|
||||
}
|
||||
|
|
|
@ -25,9 +25,13 @@
|
|||
#ifndef _C_MICROSTRIP_H_
|
||||
#define _C_MICROSTRIP_H_
|
||||
|
||||
#include <microstrip.h>
|
||||
#include <transline.h>
|
||||
|
||||
class C_MICROSTRIP : public TRANSLINE
|
||||
{
|
||||
public: C_MICROSTRIP();
|
||||
public:
|
||||
C_MICROSTRIP();
|
||||
~C_MICROSTRIP();
|
||||
|
||||
private:
|
||||
|
@ -58,10 +62,6 @@ private:
|
|||
double atten_dielectric_o; // odd-mode dielectric losses (dB)
|
||||
double atten_cond_o; // odd-mode conductors losses (dB)
|
||||
|
||||
public:
|
||||
void analyze() override;
|
||||
void synthesize() override;
|
||||
|
||||
private:
|
||||
double delta_u_thickness_single( double, double );
|
||||
void delta_u_thickness();
|
||||
|
@ -82,12 +82,11 @@ private:
|
|||
void syn_err_fun( double*, double*, double, double, double, double, double );
|
||||
void synth_width();
|
||||
void Z0_dispersion();
|
||||
void calc();
|
||||
void get_c_microstrip_sub();
|
||||
void get_c_microstrip_comp();
|
||||
void get_c_microstrip_elec();
|
||||
void get_c_microstrip_phys();
|
||||
void show_results();
|
||||
void calcAnalyze() override;
|
||||
void calcSynthesize() override;
|
||||
void showAnalyze() override;
|
||||
void showSynthesize() override;
|
||||
void show_results() override;
|
||||
void syn_fun( double*, double*, double, double, double, double );
|
||||
|
||||
|
||||
|
|
|
@ -27,86 +27,26 @@
|
|||
* coax.c - Puts up window for microstrip and
|
||||
* performs the associated calculations
|
||||
*/
|
||||
|
||||
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
#include <units.h>
|
||||
#include <transline.h>
|
||||
#include <coax.h>
|
||||
#include <units.h>
|
||||
|
||||
COAX::COAX() : TRANSLINE()
|
||||
{
|
||||
m_Name = "Coax";
|
||||
|
||||
// Initialize these variables mainly to avoid warnings from a static analyzer
|
||||
mur = 0.0; // magnetic permeability of substrate
|
||||
din = 0.0; // Inner diameter of cable
|
||||
dout = 0.0; // Outer diameter of cable
|
||||
l = 0.0; // Length of cable
|
||||
Z0 = 0.0; // characteristic impedance
|
||||
ang_l = 0.0; // Electrical length in angle
|
||||
atten_dielectric = 0.0; // Loss in dielectric (dB)
|
||||
atten_cond = 0.0; // Loss in conductors (dB)
|
||||
fc = 0.0; // Cutoff frequency for higher order modes
|
||||
Init();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* get_coax_sub() - get and assign coax substrate parameters into coax
|
||||
* structure
|
||||
*/
|
||||
void COAX::get_coax_sub()
|
||||
{
|
||||
er = getProperty( EPSILONR_PRM );
|
||||
mur = getProperty( MUR_PRM );
|
||||
m_murC = getProperty( MURC_PRM );
|
||||
m_tand = getProperty( TAND_PRM );
|
||||
m_sigma = 1.0 / getProperty( RHO_PRM );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* get_coax_comp() - get and assign coax component parameters into
|
||||
* coax structure
|
||||
*/
|
||||
void COAX::get_coax_comp()
|
||||
{
|
||||
m_freq = getProperty( FREQUENCY_PRM );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* get_coax_elec() - get and assign coax electrical parameters into
|
||||
* coax structure
|
||||
*/
|
||||
void COAX::get_coax_elec()
|
||||
{
|
||||
Z0 = getProperty( Z0_PRM );
|
||||
ang_l = getProperty( ANG_L_PRM );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* get_coax_phys() - get and assign coax physical parameters into coax
|
||||
* structure
|
||||
*/
|
||||
void COAX::get_coax_phys()
|
||||
{
|
||||
din = getProperty( PHYS_DIAM_IN_PRM );
|
||||
dout = getProperty( PHYS_DIAM_OUT_PRM );
|
||||
l = getProperty( PHYS_LEN_PRM );
|
||||
}
|
||||
|
||||
|
||||
double COAX::alphad_coax()
|
||||
{
|
||||
double ad;
|
||||
|
||||
ad = (M_PI / C0) * m_freq * sqrt( er ) * m_tand;
|
||||
ad = ( M_PI / C0 ) * m_parameters[FREQUENCY_PRM] * sqrt( m_parameters[EPSILONR_PRM] )
|
||||
* m_parameters[TAND_PRM];
|
||||
ad = ad * 20.0 / log( 10.0 );
|
||||
return ad;
|
||||
}
|
||||
|
@ -116,86 +56,165 @@ double COAX::alphac_coax()
|
|||
{
|
||||
double ac, Rs;
|
||||
|
||||
Rs = sqrt( M_PI * m_freq * m_murC * MU0 / m_sigma );
|
||||
ac = sqrt( er ) * ( ( (1 / din) + (1 / dout) ) / log( dout / din ) ) * (Rs / ZF0);
|
||||
Rs = sqrt( M_PI * m_parameters[FREQUENCY_PRM] * m_parameters[MURC_PRM] * MU0
|
||||
/ m_parameters[SIGMA_PRM] );
|
||||
ac = sqrt( m_parameters[EPSILONR_PRM] )
|
||||
* ( ( ( 1 / m_parameters[PHYS_DIAM_IN_PRM] ) + ( 1 / m_parameters[PHYS_DIAM_OUT_PRM] ) )
|
||||
/ log( m_parameters[PHYS_DIAM_OUT_PRM] / m_parameters[PHYS_DIAM_IN_PRM] ) )
|
||||
* ( Rs / ZF0 );
|
||||
ac = ac * 20.0 / log( 10.0 );
|
||||
return ac;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* analyze() - analysis function
|
||||
*/
|
||||
void COAX::analyze()
|
||||
/**
|
||||
* \f$ Z_0 = \frac{Z_{0_{\mathrm{vaccum}}}}{\sqrt{\epsilon_r}}\log_{10}\left( \frac{D_{\mathrm{out}}}{D_{\mathrm{in}}}\right) \f$
|
||||
*
|
||||
* \f$ \lambda_g = \frac{c}{f \cdot \sqrt{ \epsilon_r \cdot \mu_r}} \f$
|
||||
*
|
||||
* \f$ L_{[\mathrm{rad}]} = \frac{ 2\pi\cdot L_{[\mathrm{m}]}}{\lambda_g} \f$
|
||||
* */
|
||||
void COAX::calcAnalyze()
|
||||
{
|
||||
double lambda_g;
|
||||
|
||||
/* Get and assign substrate parameters */
|
||||
get_coax_sub();
|
||||
|
||||
/* Get and assign component parameters */
|
||||
get_coax_comp();
|
||||
m_parameters[Z0_PRM] =
|
||||
( ZF0 / 2 / M_PI / sqrt( m_parameters[EPSILONR_PRM] ) )
|
||||
* log( m_parameters[PHYS_DIAM_OUT_PRM] / m_parameters[PHYS_DIAM_IN_PRM] );
|
||||
|
||||
/* Get and assign physical parameters */
|
||||
get_coax_phys();
|
||||
|
||||
if( din != 0.0 )
|
||||
{
|
||||
Z0 = ( ZF0 / 2 / M_PI / sqrt( er ) ) * log( dout / din );
|
||||
}
|
||||
|
||||
lambda_g = ( C0 / (m_freq) ) / sqrt( er * mur );
|
||||
lambda_g = ( C0 / ( m_parameters[FREQUENCY_PRM] ) )
|
||||
/ sqrt( m_parameters[EPSILONR_PRM] * m_parameters[MUR_PRM] );
|
||||
/* calculate electrical angle */
|
||||
ang_l = (2.0 * M_PI * l) / lambda_g; /* in radians */
|
||||
|
||||
setProperty( Z0_PRM, Z0 );
|
||||
setProperty( ANG_L_PRM, ang_l );
|
||||
|
||||
show_results();
|
||||
m_parameters[ANG_L_PRM] =
|
||||
( 2.0 * M_PI * m_parameters[PHYS_LEN_PRM] ) / lambda_g; /* in radians */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* synthesize() - synthesis function
|
||||
*/
|
||||
void COAX::synthesize()
|
||||
/**
|
||||
* \f$ D_{\mathrm{in}} = D_{\mathrm{out}} \cdot e^{-\frac{Z_0*\sqrt{\epsilon_r}}{2\pi \cdot Z_{0_{\mathrm{vaccum}}}}} \f$
|
||||
*
|
||||
* \f$ D_{\mathrm{out}} = D_{\mathrm{in}} \cdot e^{ \frac{Z_0*\sqrt{\epsilon_r}}{2\pi \cdot Z_{0_{\mathrm{vaccum}}}}} \f$
|
||||
*
|
||||
* \f$ \lambda_g = \frac{c}{f \cdot \sqrt{ \epsilon_r \cdot \mu_r}} \f$
|
||||
*
|
||||
* \f$ L_{[\mathrm{m}]} = \frac{ \lambda_g cdot L_{[\mathrm{m}]}}{2\pi} \f$
|
||||
* */
|
||||
void COAX::calcSynthesize()
|
||||
{
|
||||
double lambda_g;
|
||||
|
||||
/* Get and assign substrate parameters */
|
||||
get_coax_sub();
|
||||
|
||||
/* Get and assign component parameters */
|
||||
get_coax_comp();
|
||||
|
||||
/* Get and assign electrical parameters */
|
||||
get_coax_elec();
|
||||
|
||||
/* Get and assign physical parameters */
|
||||
get_coax_phys();
|
||||
|
||||
if( isSelected( PHYS_DIAM_IN_PRM ) )
|
||||
{
|
||||
/* solve for din */
|
||||
din = dout / exp( Z0 * sqrt( er ) / ZF0 * 2 * M_PI );
|
||||
setProperty( PHYS_DIAM_IN_PRM, din );
|
||||
m_parameters[PHYS_DIAM_IN_PRM] =
|
||||
m_parameters[PHYS_DIAM_OUT_PRM]
|
||||
/ exp( m_parameters[Z0_PRM] * sqrt( m_parameters[EPSILONR_PRM] ) / ZF0 * 2 * M_PI );
|
||||
}
|
||||
else if( isSelected( PHYS_DIAM_OUT_PRM ) )
|
||||
{
|
||||
/* solve for dout */
|
||||
dout = din * exp( Z0 * sqrt( er ) / ZF0 * 2 * M_PI );
|
||||
setProperty( PHYS_DIAM_OUT_PRM, dout );
|
||||
m_parameters[PHYS_DIAM_OUT_PRM] =
|
||||
m_parameters[PHYS_DIAM_IN_PRM]
|
||||
* exp( m_parameters[Z0_PRM] * sqrt( m_parameters[EPSILONR_PRM] ) / ZF0 * 2 * M_PI );
|
||||
}
|
||||
|
||||
lambda_g = ( C0 / (m_freq) ) / sqrt( er * mur );
|
||||
lambda_g = ( C0 / ( m_parameters[FREQUENCY_PRM] ) )
|
||||
/ sqrt( m_parameters[EPSILONR_PRM] * m_parameters[MUR_PRM] );
|
||||
/* calculate physical length */
|
||||
l = (lambda_g * ang_l) / (2.0 * M_PI); /* in m */
|
||||
setProperty( PHYS_LEN_PRM, l );
|
||||
|
||||
show_results();
|
||||
m_parameters[PHYS_LEN_PRM] = ( lambda_g * m_parameters[ANG_L_PRM] ) / ( 2.0 * M_PI ); /* in m */
|
||||
}
|
||||
|
||||
|
||||
void COAX::showAnalyze()
|
||||
{
|
||||
setProperty( Z0_PRM, m_parameters[Z0_PRM] );
|
||||
setProperty( ANG_L_PRM, m_parameters[ANG_L_PRM] );
|
||||
|
||||
// Check for errors
|
||||
if( !std::isfinite( m_parameters[Z0_PRM] ) || m_parameters[Z0_PRM] < 0 )
|
||||
{
|
||||
setErrorLevel( Z0_PRM, TRANSLINE_ERROR );
|
||||
}
|
||||
|
||||
if( !std::isfinite( m_parameters[ANG_L_PRM] ) || m_parameters[ANG_L_PRM] < 0 )
|
||||
{
|
||||
setErrorLevel( ANG_L_PRM, TRANSLINE_ERROR );
|
||||
}
|
||||
|
||||
// Find warnings to display - physical parameters
|
||||
if( !std::isfinite( m_parameters[PHYS_DIAM_IN_PRM] ) || m_parameters[PHYS_DIAM_IN_PRM] <= 0.0 )
|
||||
{
|
||||
setErrorLevel( PHYS_DIAM_IN_PRM, TRANSLINE_WARNING );
|
||||
}
|
||||
|
||||
if( !std::isfinite( m_parameters[PHYS_DIAM_OUT_PRM] )
|
||||
|| m_parameters[PHYS_DIAM_OUT_PRM] <= 0.0 )
|
||||
{
|
||||
setErrorLevel( PHYS_DIAM_OUT_PRM, TRANSLINE_WARNING );
|
||||
}
|
||||
|
||||
if( m_parameters[PHYS_DIAM_IN_PRM] > m_parameters[PHYS_DIAM_OUT_PRM] )
|
||||
{
|
||||
setErrorLevel( PHYS_DIAM_IN_PRM, TRANSLINE_WARNING );
|
||||
setErrorLevel( PHYS_DIAM_OUT_PRM, TRANSLINE_WARNING );
|
||||
}
|
||||
|
||||
if( !std::isfinite( m_parameters[PHYS_LEN_PRM] ) || m_parameters[PHYS_LEN_PRM] < 0.0 )
|
||||
{
|
||||
setErrorLevel( PHYS_LEN_PRM, TRANSLINE_WARNING );
|
||||
}
|
||||
}
|
||||
|
||||
void COAX::showSynthesize()
|
||||
{
|
||||
if( isSelected( PHYS_DIAM_IN_PRM ) )
|
||||
setProperty( PHYS_DIAM_IN_PRM, m_parameters[PHYS_DIAM_IN_PRM] );
|
||||
else if( isSelected( PHYS_DIAM_OUT_PRM ) )
|
||||
setProperty( PHYS_DIAM_OUT_PRM, m_parameters[PHYS_DIAM_OUT_PRM] );
|
||||
setProperty( PHYS_LEN_PRM, m_parameters[PHYS_LEN_PRM] );
|
||||
|
||||
// Check for errors
|
||||
if( !std::isfinite( m_parameters[PHYS_DIAM_IN_PRM] ) || m_parameters[PHYS_DIAM_IN_PRM] <= 0.0 )
|
||||
{
|
||||
if( isSelected( PHYS_DIAM_IN_PRM ) )
|
||||
setErrorLevel( PHYS_DIAM_IN_PRM, TRANSLINE_ERROR );
|
||||
else
|
||||
setErrorLevel( PHYS_DIAM_IN_PRM, TRANSLINE_WARNING );
|
||||
}
|
||||
|
||||
if( !std::isfinite( m_parameters[PHYS_DIAM_OUT_PRM] )
|
||||
|| m_parameters[PHYS_DIAM_OUT_PRM] <= 0.0 )
|
||||
{
|
||||
if( isSelected( PHYS_DIAM_OUT_PRM ) )
|
||||
setErrorLevel( PHYS_DIAM_OUT_PRM, TRANSLINE_ERROR );
|
||||
else
|
||||
setErrorLevel( PHYS_DIAM_OUT_PRM, TRANSLINE_WARNING );
|
||||
}
|
||||
|
||||
if( m_parameters[PHYS_DIAM_IN_PRM] > m_parameters[PHYS_DIAM_OUT_PRM] )
|
||||
{
|
||||
if( isSelected( PHYS_DIAM_IN_PRM ) )
|
||||
setErrorLevel( PHYS_DIAM_IN_PRM, TRANSLINE_ERROR );
|
||||
else if( isSelected( PHYS_DIAM_OUT_PRM ) )
|
||||
setErrorLevel( PHYS_DIAM_OUT_PRM, TRANSLINE_ERROR );
|
||||
}
|
||||
|
||||
if( !std::isfinite( m_parameters[PHYS_LEN_PRM] ) || m_parameters[PHYS_LEN_PRM] < 0.0 )
|
||||
{
|
||||
setErrorLevel( PHYS_LEN_PRM, TRANSLINE_ERROR );
|
||||
}
|
||||
// Check for warnings
|
||||
if( !std::isfinite( m_parameters[Z0_PRM] ) || m_parameters[Z0_PRM] < 0 )
|
||||
{
|
||||
setErrorLevel( Z0_PRM, TRANSLINE_WARNING );
|
||||
}
|
||||
|
||||
if( !std::isfinite( m_parameters[ANG_L_PRM] ) || m_parameters[ANG_L_PRM] < 0 )
|
||||
{
|
||||
setErrorLevel( ANG_L_PRM, TRANSLINE_WARNING );
|
||||
}
|
||||
}
|
||||
/*
|
||||
* show_results() - show results
|
||||
*/
|
||||
|
@ -204,45 +223,57 @@ void COAX::show_results()
|
|||
int m, n;
|
||||
char text[256], txt[256];
|
||||
|
||||
atten_dielectric = alphad_coax() * l;
|
||||
atten_cond = alphac_coax() * l;
|
||||
m_parameters[LOSS_DIELECTRIC_PRM] = alphad_coax() * m_parameters[PHYS_LEN_PRM];
|
||||
m_parameters[LOSS_CONDUCTOR_PRM] = alphac_coax() * m_parameters[PHYS_LEN_PRM];
|
||||
|
||||
setResult( 0, er, "" );
|
||||
setResult( 1, atten_cond, "dB" );
|
||||
setResult( 2, atten_dielectric, "dB" );
|
||||
setResult( 0, m_parameters[EPSILONR_PRM], "" );
|
||||
setResult( 1, m_parameters[LOSS_CONDUCTOR_PRM], "dB" );
|
||||
setResult( 2, m_parameters[LOSS_DIELECTRIC_PRM], "dB" );
|
||||
|
||||
n = 1;
|
||||
fc = C0 / (M_PI * (dout + din) / (double) n);
|
||||
if( fc > m_freq )
|
||||
m_parameters[CUTOFF_FREQUENCY_PRM] =
|
||||
C0
|
||||
/ ( M_PI * ( m_parameters[PHYS_DIAM_OUT_PRM] + m_parameters[MUR_PRM] ) / (double) n );
|
||||
if( m_parameters[CUTOFF_FREQUENCY_PRM] > m_parameters[FREQUENCY_PRM] )
|
||||
strcpy( text, "none" );
|
||||
else
|
||||
{
|
||||
strcpy( text, "H(1,1) " );
|
||||
m = 2;
|
||||
fc = C0 / ( 2 * (dout - din) / (double) (m - 1) );
|
||||
while( (fc <= m_freq) && ( m < 10 ) )
|
||||
m_parameters[CUTOFF_FREQUENCY_PRM] =
|
||||
C0
|
||||
/ ( 2 * ( m_parameters[PHYS_DIAM_OUT_PRM] - m_parameters[MUR_PRM] )
|
||||
/ (double) ( m - 1 ) );
|
||||
while( ( m_parameters[CUTOFF_FREQUENCY_PRM] <= m_parameters[FREQUENCY_PRM] ) && ( m < 10 ) )
|
||||
{
|
||||
sprintf( txt, "H(n,%d) ", m );
|
||||
strcat( text, txt );
|
||||
m++;
|
||||
fc = C0 / ( 2 * (dout - din) / (double) (m - 1) );
|
||||
m_parameters[CUTOFF_FREQUENCY_PRM] =
|
||||
C0
|
||||
/ ( 2 * ( m_parameters[PHYS_DIAM_OUT_PRM] - m_parameters[MUR_PRM] )
|
||||
/ (double) ( m - 1 ) );
|
||||
}
|
||||
}
|
||||
setResult( 3, text );
|
||||
|
||||
m = 1;
|
||||
fc = C0 / (2 * (dout - din) / (double) m);
|
||||
if( fc > m_freq )
|
||||
m_parameters[CUTOFF_FREQUENCY_PRM] =
|
||||
C0 / ( 2 * ( m_parameters[PHYS_DIAM_OUT_PRM] - m_parameters[MUR_PRM] ) / (double) m );
|
||||
if( m_parameters[CUTOFF_FREQUENCY_PRM] > m_parameters[FREQUENCY_PRM] )
|
||||
strcpy( text, "none" );
|
||||
else
|
||||
{
|
||||
strcpy( text, "" );
|
||||
while( (fc <= m_freq) && ( m < 10 ) )
|
||||
while( ( m_parameters[CUTOFF_FREQUENCY_PRM] <= m_parameters[FREQUENCY_PRM] ) && ( m < 10 ) )
|
||||
{
|
||||
sprintf( txt, "E(n,%d) ", m );
|
||||
strcat( text, txt );
|
||||
m++;
|
||||
fc = C0 / (2 * (dout - din) / (double) m);
|
||||
m_parameters[CUTOFF_FREQUENCY_PRM] =
|
||||
C0
|
||||
/ ( 2 * ( m_parameters[PHYS_DIAM_OUT_PRM] - m_parameters[MUR_PRM] )
|
||||
/ (double) m );
|
||||
}
|
||||
}
|
||||
setResult( 4, text );
|
||||
|
|
|
@ -25,35 +25,21 @@
|
|||
#ifndef __COAX_H
|
||||
#define __COAX_H
|
||||
|
||||
#include <transline.h>
|
||||
|
||||
class COAX : public TRANSLINE
|
||||
{
|
||||
public: COAX();
|
||||
|
||||
private:
|
||||
double mur; // magnetic permeability of substrate
|
||||
double din; // Inner diameter of cable
|
||||
double dout; // Outer diameter of cable
|
||||
double l; // Length of cable
|
||||
double Z0; // characteristic impedance
|
||||
double ang_l; // Electrical length in angle
|
||||
double atten_dielectric; // Loss in dielectric (dB)
|
||||
double atten_cond; // Loss in conductors (dB)
|
||||
double fc; // Cutoff frequency for higher order modes
|
||||
|
||||
public:
|
||||
void analyze() override;
|
||||
void synthesize() override;
|
||||
COAX();
|
||||
|
||||
private:
|
||||
void get_coax_sub();
|
||||
void get_coax_comp();
|
||||
void get_coax_phys();
|
||||
void get_coax_elec();
|
||||
void fixdin();
|
||||
void fixdout();
|
||||
void calcAnalyze() override;
|
||||
void calcSynthesize() override;
|
||||
void showAnalyze() override;
|
||||
void showSynthesize() override;
|
||||
double alphad_coax();
|
||||
double alphac_coax();
|
||||
void show_results();
|
||||
void show_results() override;
|
||||
};
|
||||
|
||||
#endif // __COAX_H
|
||||
|
|
|
@ -28,26 +28,14 @@
|
|||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
#include <units.h>
|
||||
#include <transline.h>
|
||||
#include <coplanar.h>
|
||||
#include <units.h>
|
||||
|
||||
COPLANAR::COPLANAR() : TRANSLINE()
|
||||
{
|
||||
m_Name = "CoPlanar";
|
||||
backMetal = false;
|
||||
|
||||
// Initialize these variables mainly to avoid warnings from a static analyzer
|
||||
h = 0.0; // height of substrate
|
||||
t = 0.0; // thickness of top metal
|
||||
w = 0.0; // width of line
|
||||
s = 0.0; // width of gap between line and ground
|
||||
len = 0.0; // length of line
|
||||
Z0 = 0.0; // characteristic impedance
|
||||
ang_l = 0.0; // Electrical length in angle
|
||||
atten_dielectric = 0.0; // Loss in dielectric (dB)
|
||||
atten_cond = 0.0; // Loss in conductors (dB)
|
||||
er_eff = 1.0; // Effective dielectric constant
|
||||
Init();
|
||||
}
|
||||
|
||||
|
||||
|
@ -59,74 +47,67 @@ GROUNDEDCOPLANAR::GROUNDEDCOPLANAR() : COPLANAR()
|
|||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
void COPLANAR::getProperties()
|
||||
void COPLANAR::calcAnalyze()
|
||||
{
|
||||
m_freq = getProperty( FREQUENCY_PRM );
|
||||
w = getProperty( PHYS_WIDTH_PRM );
|
||||
s = getProperty( PHYS_S_PRM );
|
||||
len = getProperty( PHYS_LEN_PRM );
|
||||
h = getProperty( H_PRM );
|
||||
t = getProperty( T_PRM );
|
||||
|
||||
er = getProperty( EPSILONR_PRM );
|
||||
m_murC = getProperty( MURC_PRM );
|
||||
m_tand = getProperty( TAND_PRM );
|
||||
m_sigma = 1.0 / getProperty( RHO_PRM );
|
||||
Z0 = getProperty( Z0_PRM );
|
||||
ang_l = getProperty( ANG_L_PRM );
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
void COPLANAR::calc()
|
||||
{
|
||||
m_skindepth = skin_depth();
|
||||
m_parameters[SKIN_DEPTH_PRM] = skin_depth();
|
||||
|
||||
// other local variables (quasi-static constants)
|
||||
double k1, kk1, kpk1, k2, k3, q1, q2, q3 = 0, qz, er0 = 0;
|
||||
double zl_factor;
|
||||
|
||||
// compute the necessary quasi-static approx. (K1, K3, er(0) and Z(0))
|
||||
k1 = w / (w + s + s);
|
||||
k1 = m_parameters[PHYS_WIDTH_PRM]
|
||||
/ ( m_parameters[PHYS_WIDTH_PRM] + m_parameters[PHYS_S_PRM] + m_parameters[PHYS_S_PRM] );
|
||||
kk1 = ellipk( k1 );
|
||||
kpk1 = ellipk( sqrt( 1 - k1 * k1 ) );
|
||||
q1 = kk1 / kpk1;
|
||||
|
||||
|
||||
// backside is metal
|
||||
if( backMetal )
|
||||
{
|
||||
k3 = tanh( (M_PI / 4) * (w / h) ) / tanh( (M_PI / 4) * (w + s + s) / h );
|
||||
k3 = tanh( ( M_PI / 4 ) * ( m_parameters[PHYS_WIDTH_PRM] / m_parameters[H_PRM] ) )
|
||||
/ tanh( ( M_PI / 4 )
|
||||
* ( m_parameters[PHYS_WIDTH_PRM] + m_parameters[PHYS_S_PRM]
|
||||
+ m_parameters[PHYS_S_PRM] )
|
||||
/ m_parameters[H_PRM] );
|
||||
q3 = ellipk( k3 ) / ellipk( sqrt( 1 - k3 * k3 ) );
|
||||
qz = 1 / (q1 + q3);
|
||||
er0 = 1 + q3 * qz * (er - 1);
|
||||
qz = 1 / ( q1 + q3 );
|
||||
er0 = 1 + q3 * qz * ( m_parameters[EPSILONR_PRM] - 1 );
|
||||
zl_factor = ZF0 / 2 * qz;
|
||||
}
|
||||
// backside is air
|
||||
else
|
||||
{
|
||||
k2 = sinh( (M_PI / 4) * (w / h) ) / sinh( (M_PI / 4) * (w + s + s) / h );
|
||||
k2 = sinh( ( M_PI / 4 ) * ( m_parameters[PHYS_WIDTH_PRM] / m_parameters[H_PRM] ) )
|
||||
/ sinh( ( M_PI / 4 )
|
||||
* ( m_parameters[PHYS_WIDTH_PRM] + m_parameters[PHYS_S_PRM]
|
||||
+ m_parameters[PHYS_S_PRM] )
|
||||
/ m_parameters[H_PRM] );
|
||||
q2 = ellipk( k2 ) / ellipk( sqrt( 1 - k2 * k2 ) );
|
||||
er0 = 1 + (er - 1) / 2 * q2 / q1;
|
||||
er0 = 1 + ( m_parameters[EPSILONR_PRM] - 1 ) / 2 * q2 / q1;
|
||||
zl_factor = ZF0 / 4 / q1;
|
||||
}
|
||||
|
||||
|
||||
// adds effect of strip thickness
|
||||
if( t > 0 )
|
||||
if( m_parameters[T_PRM] > 0 )
|
||||
{
|
||||
double d, se, We, ke, qe;
|
||||
d = (t * 1.25 / M_PI) * ( 1 + log( 4 * M_PI * w / t ) );
|
||||
se = s - d;
|
||||
We = w + d;
|
||||
d = ( m_parameters[T_PRM] * 1.25 / M_PI )
|
||||
* ( 1 + log( 4 * M_PI * m_parameters[PHYS_WIDTH_PRM] / m_parameters[T_PRM] ) );
|
||||
se = m_parameters[PHYS_S_PRM] - d;
|
||||
We = m_parameters[PHYS_WIDTH_PRM] + d;
|
||||
|
||||
// modifies k1 accordingly (k1 = ke)
|
||||
ke = We / (We + se + se); // ke = k1 + (1 - k1 * k1) * d / 2 / s;
|
||||
ke = We / ( We + se + se ); // ke = k1 + (1 - k1 * k1) * d / 2 / s;
|
||||
qe = ellipk( ke ) / ellipk( sqrt( 1 - ke * ke ) );
|
||||
|
||||
// backside is metal
|
||||
if( backMetal )
|
||||
{
|
||||
qz = 1 / (qe + q3);
|
||||
er0 = 1 + q3 * qz * (er - 1);
|
||||
qz = 1 / ( qe + q3 );
|
||||
er0 = 1 + q3 * qz * ( m_parameters[EPSILONR_PRM] - 1 );
|
||||
zl_factor = ZF0 / 2 * qz;
|
||||
}
|
||||
// backside is air
|
||||
|
@ -136,177 +117,147 @@ void COPLANAR::calc()
|
|||
}
|
||||
|
||||
// modifies er0 as well
|
||||
er0 = er0 - (0.7 * (er0 - 1) * t / s) / ( q1 + (0.7 * t / s) );
|
||||
er0 = er0
|
||||
- ( 0.7 * ( er0 - 1 ) * m_parameters[T_PRM] / m_parameters[PHYS_S_PRM] )
|
||||
/ ( q1 + ( 0.7 * m_parameters[T_PRM] / m_parameters[PHYS_S_PRM] ) );
|
||||
}
|
||||
|
||||
// pre-compute square roots
|
||||
double sr_er = sqrt( er );
|
||||
double sr_er = sqrt( m_parameters[EPSILONR_PRM] );
|
||||
double sr_er0 = sqrt( er0 );
|
||||
|
||||
// cut-off frequency of the TE0 mode
|
||||
double fte = (C0 / 4) / ( h * sqrt( er - 1 ) );
|
||||
double fte = ( C0 / 4 ) / ( m_parameters[H_PRM] * sqrt( m_parameters[EPSILONR_PRM] - 1 ) );
|
||||
|
||||
// dispersion factor G
|
||||
double p = log( w / h );
|
||||
double u = 0.54 - (0.64 - 0.015 * p) * p;
|
||||
double v = 0.43 - (0.86 - 0.54 * p) * p;
|
||||
double G = exp( u * log( w / s ) + v );
|
||||
double p = log( m_parameters[PHYS_WIDTH_PRM] / m_parameters[H_PRM] );
|
||||
double u = 0.54 - ( 0.64 - 0.015 * p ) * p;
|
||||
double v = 0.43 - ( 0.86 - 0.54 * p ) * p;
|
||||
double G = exp( u * log( m_parameters[PHYS_WIDTH_PRM] / m_parameters[PHYS_S_PRM] ) + v );
|
||||
|
||||
// loss constant factors (computed only once for efficiency's sake)
|
||||
double ac = 0;
|
||||
if( t > 0 )
|
||||
if( m_parameters[T_PRM] > 0 )
|
||||
{
|
||||
// equations by GHIONE
|
||||
double n = (1 - k1) * 8 * M_PI / ( t * (1 + k1) );
|
||||
double a = w / 2;
|
||||
double b = a + s;
|
||||
double n = ( 1 - k1 ) * 8 * M_PI / ( m_parameters[T_PRM] * ( 1 + k1 ) );
|
||||
double a = m_parameters[PHYS_WIDTH_PRM] / 2;
|
||||
double b = a + m_parameters[PHYS_S_PRM];
|
||||
ac = ( M_PI + log( n * a ) ) / a + ( M_PI + log( n * b ) ) / b;
|
||||
}
|
||||
double ac_factor = ac / ( 4 * ZF0 * kk1 * kpk1 * (1 - k1 * k1) );
|
||||
double ad_factor = ( er / (er - 1) ) * m_tand * M_PI / C0;
|
||||
double ac_factor = ac / ( 4 * ZF0 * kk1 * kpk1 * ( 1 - k1 * k1 ) );
|
||||
double ad_factor = ( m_parameters[EPSILONR_PRM] / ( m_parameters[EPSILONR_PRM] - 1 ) )
|
||||
* m_parameters[TAND_PRM] * M_PI / C0;
|
||||
|
||||
|
||||
// ....................................................
|
||||
double sr_er_f = sr_er0;
|
||||
|
||||
// add the dispersive effects to er0
|
||||
sr_er_f += (sr_er - sr_er0) / ( 1 + G * pow( m_freq / fte, -1.8 ) );
|
||||
sr_er_f += ( sr_er - sr_er0 ) / ( 1 + G * pow( m_parameters[FREQUENCY_PRM] / fte, -1.8 ) );
|
||||
|
||||
// for now, the loss are limited to strip losses (no radiation
|
||||
// losses yet) losses in neper/length
|
||||
atten_cond = 20.0 / log( 10.0 ) * len
|
||||
* ac_factor * sr_er0 * sqrt( M_PI * MU0 * m_freq / m_sigma );
|
||||
atten_dielectric = 20.0 / log( 10.0 ) * len
|
||||
* ad_factor * m_freq * (sr_er_f * sr_er_f - 1) / sr_er_f;
|
||||
m_parameters[LOSS_CONDUCTOR_PRM] =
|
||||
20.0 / log( 10.0 ) * m_parameters[PHYS_LEN_PRM] * ac_factor * sr_er0
|
||||
* sqrt( M_PI * MU0 * m_parameters[FREQUENCY_PRM] / m_parameters[SIGMA_PRM] );
|
||||
m_parameters[LOSS_DIELECTRIC_PRM] = 20.0 / log( 10.0 ) * m_parameters[PHYS_LEN_PRM] * ad_factor
|
||||
* m_parameters[FREQUENCY_PRM] * ( sr_er_f * sr_er_f - 1 )
|
||||
/ sr_er_f;
|
||||
|
||||
ang_l = 2.0 * M_PI * len * sr_er_f * m_freq / C0; /* in radians */
|
||||
m_parameters[ANG_L_PRM] = 2.0 * M_PI * m_parameters[PHYS_LEN_PRM] * sr_er_f
|
||||
* m_parameters[FREQUENCY_PRM] / C0; /* in radians */
|
||||
|
||||
er_eff = sr_er_f * sr_er_f;
|
||||
Z0 = zl_factor / sr_er_f;
|
||||
m_parameters[EPSILON_EFF_PRM] = sr_er_f * sr_er_f;
|
||||
m_parameters[Z0_PRM] = zl_factor / sr_er_f;
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
void COPLANAR::show_results()
|
||||
{
|
||||
setProperty( Z0_PRM, Z0 );
|
||||
setProperty( ANG_L_PRM, ang_l );
|
||||
|
||||
setResult( 0, er_eff, "" );
|
||||
setResult( 1, atten_cond, "dB" );
|
||||
setResult( 2, atten_dielectric, "dB" );
|
||||
setResult( 0, m_parameters[EPSILON_EFF_PRM], "" );
|
||||
setResult( 1, m_parameters[LOSS_CONDUCTOR_PRM], "dB" );
|
||||
setResult( 2, m_parameters[LOSS_DIELECTRIC_PRM], "dB" );
|
||||
|
||||
setResult( 3, m_skindepth / UNIT_MICRON, "µm" );
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
void COPLANAR::analyze()
|
||||
{
|
||||
getProperties();
|
||||
|
||||
/* compute coplanar parameters */
|
||||
calc();
|
||||
|
||||
/* print results in the subwindow */
|
||||
show_results();
|
||||
setResult( 3, m_parameters[SKIN_DEPTH_PRM] / UNIT_MICRON, "µm" );
|
||||
}
|
||||
|
||||
|
||||
#define MAX_ERROR 0.000001
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
void COPLANAR::synthesize()
|
||||
/* @function calcSynthesize
|
||||
*
|
||||
* @TODO Add a warning in case the synthetizin algorithm did not converge.
|
||||
* Add it for all transmission lines that uses @ref minimizeZ0Error1D .
|
||||
*/
|
||||
void COPLANAR::calcSynthesize()
|
||||
{
|
||||
double Z0_dest, Z0_current, Z0_result, increment, slope, error;
|
||||
int iteration;
|
||||
|
||||
getProperties();
|
||||
|
||||
/* required value of Z0 */
|
||||
Z0_dest = Z0;
|
||||
double ang_l_tmp = getProperty( ANG_L_PRM );
|
||||
|
||||
// compute inital coplanar parameters. This function modify Z0 and ang_l
|
||||
// (set to NaN in some cases)
|
||||
calc();
|
||||
|
||||
if( std::isnan( Z0 ) ) // cannot be synthesized with current parameters
|
||||
{
|
||||
Z0 = Z0_dest;
|
||||
ang_l= ang_l_tmp;
|
||||
|
||||
if( isSelected( PHYS_WIDTH_PRM ) )
|
||||
{
|
||||
setProperty( PHYS_WIDTH_PRM, NAN );
|
||||
minimizeZ0Error1D( &( m_parameters[PHYS_WIDTH_PRM] ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
setProperty( PHYS_S_PRM, NAN );
|
||||
minimizeZ0Error1D( &( m_parameters[PHYS_S_PRM] ) );
|
||||
}
|
||||
|
||||
setProperty( PHYS_LEN_PRM, NAN );
|
||||
|
||||
/* print results in the subwindow */
|
||||
show_results();
|
||||
return;
|
||||
}
|
||||
|
||||
/* Newton's method */
|
||||
iteration = 0;
|
||||
Z0_current = Z0;
|
||||
error = fabs( Z0_dest - Z0_current );
|
||||
|
||||
while( error > MAX_ERROR )
|
||||
{
|
||||
iteration++;
|
||||
if( isSelected( PHYS_WIDTH_PRM ) )
|
||||
{
|
||||
increment = w / 100.0;
|
||||
w += increment;
|
||||
}
|
||||
else
|
||||
{
|
||||
increment = s / 100.0;
|
||||
s += increment;
|
||||
}
|
||||
/* compute coplanar parameters */
|
||||
calc();
|
||||
Z0_result = Z0;
|
||||
/* f(w(n)) = Z0 - Z0(w(n)) */
|
||||
/* f'(w(n)) = -f'(Z0(w(n))) */
|
||||
/* f'(Z0(w(n))) = (Z0(w(n)) - Z0(w(n+delw))/delw */
|
||||
/* w(n+1) = w(n) - f(w(n))/f'(w(n)) */
|
||||
slope = (Z0_result - Z0_current) / increment;
|
||||
slope = (Z0_dest - Z0_current) / slope - increment;
|
||||
if( isSelected( PHYS_WIDTH_PRM ) )
|
||||
w += slope;
|
||||
else
|
||||
s += slope;
|
||||
if( w <= 0.0 )
|
||||
w = increment;
|
||||
if( s <= 0.0 )
|
||||
s = increment;
|
||||
/* find new error */
|
||||
/* compute coplanar parameters */
|
||||
calc();
|
||||
Z0_current = Z0;
|
||||
error = fabs( Z0_dest - Z0_current );
|
||||
|
||||
if( iteration > 100 )
|
||||
break;
|
||||
}
|
||||
|
||||
setProperty( PHYS_WIDTH_PRM, w );
|
||||
setProperty( PHYS_S_PRM, s );
|
||||
/* calculate physical length */
|
||||
ang_l = getProperty( ANG_L_PRM );
|
||||
len = C0 / m_freq / sqrt( er_eff ) * ang_l / 2.0 / M_PI; /* in m */
|
||||
setProperty( PHYS_LEN_PRM, len );
|
||||
|
||||
/* compute coplanar parameters */
|
||||
calc();
|
||||
|
||||
/* print results in the subwindow */
|
||||
show_results();
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
void COPLANAR::showSynthesize()
|
||||
{
|
||||
if( isSelected( PHYS_WIDTH_PRM ) )
|
||||
setProperty( PHYS_WIDTH_PRM, m_parameters[PHYS_WIDTH_PRM] );
|
||||
|
||||
if( isSelected( PHYS_S_PRM ) )
|
||||
setProperty( PHYS_S_PRM, m_parameters[PHYS_S_PRM] );
|
||||
|
||||
setProperty( PHYS_LEN_PRM, m_parameters[PHYS_LEN_PRM] );
|
||||
|
||||
if( !std::isfinite( m_parameters[PHYS_S_PRM] ) || m_parameters[PHYS_S_PRM] <= 0 )
|
||||
{
|
||||
if( isSelected( PHYS_S_PRM ) )
|
||||
setErrorLevel( PHYS_S_PRM, TRANSLINE_ERROR );
|
||||
else
|
||||
setErrorLevel( PHYS_S_PRM, TRANSLINE_WARNING );
|
||||
}
|
||||
if( !std::isfinite( m_parameters[PHYS_WIDTH_PRM] ) || m_parameters[PHYS_WIDTH_PRM] <= 0 )
|
||||
{
|
||||
if( isSelected( PHYS_WIDTH_PRM ) )
|
||||
setErrorLevel( PHYS_WIDTH_PRM, TRANSLINE_ERROR );
|
||||
else
|
||||
setErrorLevel( PHYS_WIDTH_PRM, TRANSLINE_WARNING );
|
||||
}
|
||||
if( !std::isfinite( m_parameters[PHYS_LEN_PRM] ) || m_parameters[PHYS_LEN_PRM] < 0 )
|
||||
setErrorLevel( PHYS_LEN_PRM, TRANSLINE_ERROR );
|
||||
|
||||
if( !std::isfinite( m_parameters[Z0_PRM] ) || m_parameters[Z0_PRM] < 0 )
|
||||
setErrorLevel( Z0_PRM, TRANSLINE_WARNING );
|
||||
|
||||
if( !std::isfinite( m_parameters[ANG_L_PRM] ) || m_parameters[ANG_L_PRM] < 0 )
|
||||
setErrorLevel( ANG_L_PRM, TRANSLINE_WARNING );
|
||||
}
|
||||
|
||||
|
||||
void COPLANAR::showAnalyze()
|
||||
{
|
||||
setProperty( Z0_PRM, m_parameters[Z0_PRM] );
|
||||
setProperty( ANG_L_PRM, m_parameters[ANG_L_PRM] );
|
||||
|
||||
if( !std::isfinite( m_parameters[PHYS_S_PRM] ) || m_parameters[PHYS_S_PRM] <= 0 )
|
||||
setErrorLevel( PHYS_S_PRM, TRANSLINE_WARNING );
|
||||
|
||||
if( !std::isfinite( m_parameters[PHYS_WIDTH_PRM] ) || m_parameters[PHYS_WIDTH_PRM] <= 0 )
|
||||
setErrorLevel( PHYS_WIDTH_PRM, TRANSLINE_WARNING );
|
||||
|
||||
if( !std::isfinite( m_parameters[PHYS_LEN_PRM] ) || m_parameters[PHYS_LEN_PRM] < 0 )
|
||||
setErrorLevel( PHYS_LEN_PRM, TRANSLINE_WARNING );
|
||||
|
||||
if( !std::isfinite( m_parameters[Z0_PRM] ) || m_parameters[Z0_PRM] < 0 )
|
||||
setErrorLevel( Z0_PRM, TRANSLINE_ERROR );
|
||||
|
||||
if( !std::isfinite( m_parameters[ANG_L_PRM] ) || m_parameters[ANG_L_PRM] < 0 )
|
||||
setErrorLevel( ANG_L_PRM, TRANSLINE_ERROR );
|
||||
}
|
||||
|
|
|
@ -25,39 +25,31 @@
|
|||
#ifndef __COPLANAR_H
|
||||
#define __COPLANAR_H
|
||||
|
||||
#include <transline.h>
|
||||
|
||||
class COPLANAR : public TRANSLINE
|
||||
{
|
||||
public: COPLANAR();
|
||||
|
||||
private:
|
||||
double h; // height of substrate
|
||||
double t; // thickness of top metal
|
||||
double w; // width of line
|
||||
double s; // width of gap between line and ground
|
||||
double len; // length of line
|
||||
double Z0; // characteristic impedance
|
||||
double er_eff; // effective dielectric constant
|
||||
double ang_l; // Electrical length in angle
|
||||
double atten_dielectric; // Loss in dielectric (dB)
|
||||
double atten_cond; // Loss in conductors (dB)
|
||||
public:
|
||||
COPLANAR();
|
||||
|
||||
public:
|
||||
void analyze() override;
|
||||
void synthesize() override;
|
||||
void calcSynthesize() override;
|
||||
|
||||
protected:
|
||||
bool backMetal;
|
||||
|
||||
private:
|
||||
void calc();
|
||||
void show_results();
|
||||
void getProperties();
|
||||
void calcAnalyze() override;
|
||||
void showSynthesize() override;
|
||||
void showAnalyze() override;
|
||||
void show_results() override;
|
||||
};
|
||||
|
||||
|
||||
class GROUNDEDCOPLANAR : public COPLANAR
|
||||
{
|
||||
public: GROUNDEDCOPLANAR();
|
||||
public:
|
||||
GROUNDEDCOPLANAR();
|
||||
};
|
||||
|
||||
#endif // __COPLANAR_H
|
||||
|
|
|
@ -34,32 +34,15 @@
|
|||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
#include <units.h>
|
||||
#include <transline.h>
|
||||
#include <microstrip.h>
|
||||
#include <transline.h>
|
||||
|
||||
#include <units.h>
|
||||
|
||||
MICROSTRIP::MICROSTRIP() : TRANSLINE()
|
||||
{
|
||||
m_Name = "MicroStrip";
|
||||
|
||||
// Initialize these variables mainly to avoid warnings from a static analyzer
|
||||
h = 0.0; // height of substrate
|
||||
ht = 0.0; // height to the top of box
|
||||
t = 0.0; // thickness of top metal
|
||||
rough = 0.0; // Roughness of top metal
|
||||
mur = 0.0; // magnetic permeability of substrate
|
||||
w = 0.0; // width of line
|
||||
l = 0.0; // length of line
|
||||
Z0_0 = 0.0; // static characteristic impedance
|
||||
Z0 = 0.0; // characteristic impedance
|
||||
ang_l = 0.0; // Electrical length in angle
|
||||
er_eff_0 = 0.0; // Static effective dielectric constant
|
||||
er_eff = 0.0; // Effective dielectric constant
|
||||
mur_eff = 0.0; // Effective mag. permeability
|
||||
w_eff = 0.0; // Effective width of line
|
||||
atten_dielectric = 0.0; // Loss in dielectric (dB)
|
||||
atten_cond = 0.0; // Loss in conductors (dB)
|
||||
Z0_h_1 = 0.0; // homogeneous stripline impedance
|
||||
Init();
|
||||
}
|
||||
|
||||
|
||||
|
@ -71,8 +54,8 @@ double MICROSTRIP::Z0_homogeneous( double u )
|
|||
{
|
||||
double freq, Z0_value;
|
||||
|
||||
freq = 6.0 + (2.0 * M_PI - 6.0) * exp( -pow( 30.666 / u, 0.7528 ) );
|
||||
Z0_value = ( ZF0 / (2.0 * M_PI) ) * log( freq / u + sqrt( 1.0 + 4.0 / (u * u) ) );
|
||||
freq = 6.0 + ( 2.0 * M_PI - 6.0 ) * exp( -pow( 30.666 / u, 0.7528 ) );
|
||||
Z0_value = ( ZF0 / ( 2.0 * M_PI ) ) * log( freq / u + sqrt( 1.0 + 4.0 / ( u * u ) ) );
|
||||
return Z0_value;
|
||||
}
|
||||
|
||||
|
@ -88,7 +71,7 @@ double MICROSTRIP::delta_Z0_cover( double u, double h2h )
|
|||
|
||||
h2hp1 = 1.0 + h2h;
|
||||
P = 270.0 * ( 1.0 - tanh( 1.192 + 0.706 * sqrt( h2hp1 ) - 1.389 / h2hp1 ) );
|
||||
Q = 1.0109 - atanh( (0.012 * u + 0.177 * u * u - 0.027 * u * u * u) / (h2hp1 * h2hp1) );
|
||||
Q = 1.0109 - atanh( ( 0.012 * u + 0.177 * u * u - 0.027 * u * u * u ) / ( h2hp1 * h2hp1 ) );
|
||||
return P * Q;
|
||||
}
|
||||
|
||||
|
@ -105,9 +88,8 @@ double MICROSTRIP::filling_factor( double u, double e_r )
|
|||
u2 = u * u;
|
||||
u3 = u2 * u;
|
||||
u4 = u3 * u;
|
||||
a = 1.0 +
|
||||
log( (u4 + u2 / 2704) / (u4 + 0.432) ) / 49.0 + log( 1.0 + u3 / 5929.741 ) / 18.7;
|
||||
b = 0.564 * pow( (e_r - 0.9) / (e_r + 3.0), 0.053 );
|
||||
a = 1.0 + log( ( u4 + u2 / 2704 ) / ( u4 + 0.432 ) ) / 49.0 + log( 1.0 + u3 / 5929.741 ) / 18.7;
|
||||
b = 0.564 * pow( ( e_r - 0.9 ) / ( e_r + 3.0 ), 0.053 );
|
||||
q_inf = pow( 1.0 + 10.0 / u, -a * b );
|
||||
return q_inf;
|
||||
}
|
||||
|
@ -132,7 +114,7 @@ double MICROSTRIP::delta_q_thickness( double u, double t_h )
|
|||
{
|
||||
double q_t;
|
||||
|
||||
q_t = (2.0 * log( 2.0 ) / M_PI) * ( t_h / sqrt( u ) );
|
||||
q_t = ( 2.0 * log( 2.0 ) / M_PI ) * ( t_h / sqrt( u ) );
|
||||
return q_t;
|
||||
}
|
||||
|
||||
|
@ -145,7 +127,7 @@ double MICROSTRIP::e_r_effective( double e_r, double q )
|
|||
{
|
||||
double e_r_eff;
|
||||
|
||||
e_r_eff = 0.5 * (e_r + 1.0) + 0.5 * q * (e_r - 1.0);
|
||||
e_r_eff = 0.5 * ( e_r + 1.0 ) + 0.5 * q * ( e_r - 1.0 );
|
||||
return e_r_eff;
|
||||
}
|
||||
|
||||
|
@ -160,8 +142,8 @@ double MICROSTRIP::delta_u_thickness( double u, double t_h, double e_r )
|
|||
if( t_h > 0.0 )
|
||||
{
|
||||
/* correction for thickness for a homogeneous microstrip */
|
||||
delta_u = (t_h / M_PI) * log( 1.0 + (4.0 * M_E) * pow( tanh( sqrt(
|
||||
6.517 * u ) ), 2.0 ) / t_h );
|
||||
delta_u = ( t_h / M_PI )
|
||||
* log( 1.0 + ( 4.0 * M_E ) * pow( tanh( sqrt( 6.517 * u ) ), 2.0 ) / t_h );
|
||||
/* correction for strip on a substrate with relative permettivity e_r */
|
||||
delta_u = 0.5 * delta_u * ( 1.0 + 1.0 / cosh( sqrt( e_r - 1.0 ) ) );
|
||||
}
|
||||
|
@ -182,11 +164,11 @@ void MICROSTRIP::microstrip_Z0()
|
|||
double Z0_h_r;
|
||||
double delta_u_1, delta_u_r, q_inf, q_c, q_t, e_r_eff, e_r_eff_t, q;
|
||||
|
||||
e_r = er;
|
||||
h2 = ht;
|
||||
h2h = h2 / h;
|
||||
u = w / h;
|
||||
t_h = t / h;
|
||||
e_r = m_parameters[EPSILONR_PRM];
|
||||
h2 = m_parameters[H_T_PRM];
|
||||
h2h = h2 / m_parameters[H_PRM];
|
||||
u = m_parameters[PHYS_WIDTH_PRM] / m_parameters[H_PRM];
|
||||
t_h = m_parameters[T_PRM] / m_parameters[H_PRM];
|
||||
|
||||
/* compute normalized width correction for e_r = 1.0 */
|
||||
delta_u_1 = delta_u_thickness( u, t_h, 1.0 );
|
||||
|
@ -205,7 +187,7 @@ void MICROSTRIP::microstrip_Z0()
|
|||
/* thickness effect */
|
||||
q_t = delta_q_thickness( u, t_h );
|
||||
/* resultant filling factor */
|
||||
q = (q_inf - q_t) * q_c;
|
||||
q = ( q_inf - q_t ) * q_c;
|
||||
|
||||
/* e_r corrected for thickness and non homogeneous material */
|
||||
e_r_eff_t = e_r_effective( e_r, q );
|
||||
|
@ -215,11 +197,11 @@ void MICROSTRIP::microstrip_Z0()
|
|||
|
||||
/* characteristic impedance, corrected for thickness, cover */
|
||||
/* and non homogeneous material */
|
||||
Z0 = Z0_h_r / sqrt( e_r_eff_t );
|
||||
m_parameters[Z0_PRM] = Z0_h_r / sqrt( e_r_eff_t );
|
||||
|
||||
w_eff = u * h;
|
||||
w_eff = u * m_parameters[H_PRM];
|
||||
er_eff_0 = e_r_eff;
|
||||
Z0_0 = Z0;
|
||||
Z0_0 = m_parameters[Z0_PRM];
|
||||
}
|
||||
|
||||
|
||||
|
@ -231,13 +213,13 @@ double MICROSTRIP::e_r_dispersion( double u, double e_r, double f_n )
|
|||
{
|
||||
double P_1, P_2, P_3, P_4, P;
|
||||
|
||||
P_1 = 0.27488 + u * ( 0.6315 + 0.525 / pow( 1.0 + 0.0157 * f_n, 20.0 ) ) - 0.065683 * exp(
|
||||
-8.7513 * u );
|
||||
P_1 = 0.27488 + u * ( 0.6315 + 0.525 / pow( 1.0 + 0.0157 * f_n, 20.0 ) )
|
||||
- 0.065683 * exp( -8.7513 * u );
|
||||
P_2 = 0.33622 * ( 1.0 - exp( -0.03442 * e_r ) );
|
||||
P_3 = 0.0363 * exp( -4.6 * u ) * ( 1.0 - exp( -pow( f_n / 38.7, 4.97 ) ) );
|
||||
P_4 = 1.0 + 2.751 * ( 1.0 - exp( -pow( e_r / 15.916, 8.0 ) ) );
|
||||
|
||||
P = P_1 * P_2 * pow( (P_3 * P_4 + 0.1844) * f_n, 1.5763 );
|
||||
P = P_1 * P_2 * pow( ( P_3 * P_4 + 0.1844 ) * f_n, 1.5763 );
|
||||
|
||||
return P;
|
||||
}
|
||||
|
@ -247,11 +229,8 @@ double MICROSTRIP::e_r_dispersion( double u, double e_r, double f_n )
|
|||
* Z0_dispersion() - computes the dispersion correction factor for the
|
||||
* characteristic impedance
|
||||
*/
|
||||
double MICROSTRIP::Z0_dispersion( double u,
|
||||
double e_r,
|
||||
double e_r_eff_0,
|
||||
double e_r_eff_f,
|
||||
double f_n )
|
||||
double MICROSTRIP::Z0_dispersion(
|
||||
double u, double e_r, double e_r_eff_0, double e_r_eff_f, double f_n )
|
||||
{
|
||||
double R_1, R_2, R_3, R_4, R_5, R_6, R_7, R_8, R_9, R_10, R_11, R_12, R_13, R_14, R_15, R_16,
|
||||
R_17, D, tmpf;
|
||||
|
@ -263,22 +242,23 @@ double MICROSTRIP::Z0_dispersion( double u,
|
|||
R_5 = pow( f_n / 28.843, 12.0 );
|
||||
R_6 = 22.2 * pow( u, 1.92 );
|
||||
R_7 = 1.206 - 0.3144 * exp( -R_1 ) * ( 1.0 - exp( -R_2 ) );
|
||||
R_8 = 1.0 + 1.275 *
|
||||
( 1.0 - exp( -0.004625 * R_3 * pow( e_r, 1.674 ) * pow( f_n / 18.365, 2.745 ) ) );
|
||||
R_8 = 1.0
|
||||
+ 1.275
|
||||
* ( 1.0
|
||||
- exp( -0.004625 * R_3 * pow( e_r, 1.674 )
|
||||
* pow( f_n / 18.365, 2.745 ) ) );
|
||||
tmpf = pow( e_r - 1.0, 6.0 );
|
||||
R_9 = 5.086 * R_4 *
|
||||
( R_5 /
|
||||
(0.3838 + 0.386 *
|
||||
R_4) ) * ( exp( -R_6 ) / (1.0 + 1.2992 * R_5) ) * ( tmpf / (1.0 + 10.0 * tmpf) );
|
||||
R_9 = 5.086 * R_4 * ( R_5 / ( 0.3838 + 0.386 * R_4 ) )
|
||||
* ( exp( -R_6 ) / ( 1.0 + 1.2992 * R_5 ) ) * ( tmpf / ( 1.0 + 10.0 * tmpf ) );
|
||||
R_10 = 0.00044 * pow( e_r, 2.136 ) + 0.0184;
|
||||
tmpf = pow( f_n / 19.47, 6.0 );
|
||||
R_11 = tmpf / (1.0 + 0.0962 * tmpf);
|
||||
R_12 = 1.0 / (1.0 + 0.00245 * u * u);
|
||||
R_11 = tmpf / ( 1.0 + 0.0962 * tmpf );
|
||||
R_12 = 1.0 / ( 1.0 + 0.00245 * u * u );
|
||||
R_13 = 0.9408 * pow( e_r_eff_f, R_8 ) - 0.9603;
|
||||
R_14 = (0.9408 - R_9) * pow( e_r_eff_0, R_8 ) - 0.9603;
|
||||
R_15 = 0.707* R_10* pow( f_n / 12.3, 1.097 );
|
||||
R_14 = ( 0.9408 - R_9 ) * pow( e_r_eff_0, R_8 ) - 0.9603;
|
||||
R_15 = 0.707 * R_10 * pow( f_n / 12.3, 1.097 );
|
||||
R_16 = 1.0 + 0.0503 * e_r * e_r * R_11 * ( 1.0 - exp( -pow( u / 15.0, 6.0 ) ) );
|
||||
R_17 = R_7 * ( 1.0 - 1.1241 * (R_12 / R_16) * exp( -0.026 * pow( f_n, 1.15656 ) - R_15 ) );
|
||||
R_17 = R_7 * ( 1.0 - 1.1241 * ( R_12 / R_16 ) * exp( -0.026 * pow( f_n, 1.15656 ) - R_15 ) );
|
||||
|
||||
D = pow( R_13 / R_14, R_17 );
|
||||
|
||||
|
@ -295,22 +275,22 @@ void MICROSTRIP::dispersion()
|
|||
double e_r, e_r_eff_0;
|
||||
double u, f_n, P, e_r_eff_f, D, Z0_f;
|
||||
|
||||
e_r = er;
|
||||
e_r = m_parameters[EPSILONR_PRM];
|
||||
e_r_eff_0 = er_eff_0;
|
||||
u = w / h;
|
||||
u = m_parameters[PHYS_WIDTH_PRM] / m_parameters[H_PRM];
|
||||
|
||||
/* normalized frequency [GHz * mm] */
|
||||
f_n = m_freq * h / 1e06;
|
||||
f_n = m_parameters[FREQUENCY_PRM] * m_parameters[H_PRM] / 1e06;
|
||||
|
||||
P = e_r_dispersion( u, e_r, f_n );
|
||||
/* effective dielectric constant corrected for dispersion */
|
||||
e_r_eff_f = e_r - (e_r - e_r_eff_0) / (1.0 + P);
|
||||
e_r_eff_f = e_r - ( e_r - e_r_eff_0 ) / ( 1.0 + P );
|
||||
|
||||
D = Z0_dispersion( u, e_r, e_r_eff_0, e_r_eff_f, f_n );
|
||||
Z0_f = Z0_0 * D;
|
||||
|
||||
er_eff = e_r_eff_f;
|
||||
Z0 = Z0_f;
|
||||
m_parameters[Z0_PRM] = Z0_f;
|
||||
}
|
||||
|
||||
|
||||
|
@ -324,20 +304,24 @@ double MICROSTRIP::conductor_losses()
|
|||
double K, R_s, Q_c, alpha_c;
|
||||
|
||||
e_r_eff_0 = er_eff_0;
|
||||
delta = m_skindepth;
|
||||
delta = m_parameters[SKIN_DEPTH_PRM];
|
||||
|
||||
if( m_freq > 0.0 )
|
||||
if( m_parameters[FREQUENCY_PRM] > 0.0 )
|
||||
{
|
||||
/* current distribution factor */
|
||||
K = exp( -1.2 * pow( Z0_h_1 / ZF0, 0.7 ) );
|
||||
/* skin resistance */
|
||||
R_s = 1.0 / (m_sigma * delta);
|
||||
R_s = 1.0 / ( m_parameters[SIGMA_PRM] * delta );
|
||||
|
||||
/* correction for surface roughness */
|
||||
R_s *= 1.0 + ( (2.0 / M_PI) * atan( 1.40 * pow( (rough / delta), 2.0 ) ) );
|
||||
R_s *= 1.0
|
||||
+ ( ( 2.0 / M_PI )
|
||||
* atan( 1.40 * pow( ( m_parameters[ROUGH_PRM] / delta ), 2.0 ) ) );
|
||||
/* strip inductive quality factor */
|
||||
Q_c = (M_PI * Z0_h_1 * w * m_freq) / (R_s * C0 * K);
|
||||
alpha_c = ( 20.0 * M_PI / log( 10.0 ) ) * m_freq * sqrt( e_r_eff_0 ) / (C0 * Q_c);
|
||||
Q_c = ( M_PI * Z0_h_1 * m_parameters[PHYS_WIDTH_PRM] * m_parameters[FREQUENCY_PRM] )
|
||||
/ ( R_s * C0 * K );
|
||||
alpha_c = ( 20.0 * M_PI / log( 10.0 ) ) * m_parameters[FREQUENCY_PRM] * sqrt( e_r_eff_0 )
|
||||
/ ( C0 * Q_c );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -357,13 +341,12 @@ double MICROSTRIP::dielectric_losses()
|
|||
double e_r, e_r_eff_0;
|
||||
double alpha_d;
|
||||
|
||||
e_r = er;
|
||||
e_r = m_parameters[EPSILONR_PRM];
|
||||
e_r_eff_0 = er_eff_0;
|
||||
|
||||
alpha_d =
|
||||
( 20.0 * M_PI /
|
||||
log( 10.0 ) ) *
|
||||
(m_freq / C0) * ( e_r / sqrt( e_r_eff_0 ) ) * ( (e_r_eff_0 - 1.0) / (e_r - 1.0) ) * m_tand;
|
||||
alpha_d = ( 20.0 * M_PI / log( 10.0 ) ) * ( m_parameters[FREQUENCY_PRM] / C0 )
|
||||
* ( e_r / sqrt( e_r_eff_0 ) ) * ( ( e_r_eff_0 - 1.0 ) / ( e_r - 1.0 ) )
|
||||
* m_parameters[TAND_PRM];
|
||||
|
||||
return alpha_d;
|
||||
}
|
||||
|
@ -374,10 +357,10 @@ double MICROSTRIP::dielectric_losses()
|
|||
*/
|
||||
void MICROSTRIP::attenuation()
|
||||
{
|
||||
m_skindepth = skin_depth();
|
||||
m_parameters[SKIN_DEPTH_PRM] = skin_depth();
|
||||
|
||||
atten_cond = conductor_losses() * l;
|
||||
atten_dielectric = dielectric_losses() * l;
|
||||
atten_cond = conductor_losses() * m_parameters[PHYS_LEN_PRM];
|
||||
atten_dielectric = dielectric_losses() * m_parameters[PHYS_LEN_PRM];
|
||||
}
|
||||
|
||||
|
||||
|
@ -386,7 +369,11 @@ void MICROSTRIP::attenuation()
|
|||
*/
|
||||
void MICROSTRIP::mur_eff_ms()
|
||||
{
|
||||
mur_eff = (2.0 * mur) / ( (1.0 + mur) + ( (1.0 - mur) * pow( ( 1.0 + (10.0 * h / w) ), -0.5 ) ) );
|
||||
double* mur = &m_parameters[MUR_PRM];
|
||||
double* h = &m_parameters[H_PRM];
|
||||
double* w = &m_parameters[PHYS_WIDTH_PRM];
|
||||
mur_eff = ( 2.0 * *mur )
|
||||
/ ( ( 1.0 + *mur ) + ( ( 1.0 - *mur ) * pow( ( 1.0 + ( 10.0 * *h / *w ) ), -0.5 ) ) );
|
||||
}
|
||||
|
||||
|
||||
|
@ -396,24 +383,25 @@ double MICROSTRIP::synth_width()
|
|||
double e_r, a, b;
|
||||
double w_h, width;
|
||||
|
||||
e_r = er;
|
||||
e_r = m_parameters[EPSILONR_PRM];
|
||||
|
||||
a = ( (Z0 / ZF0 / 2 /
|
||||
M_PI) * sqrt( (e_r + 1) / 2. ) ) + ( (e_r - 1) / (e_r + 1) * ( 0.23 + (0.11 / e_r) ) );
|
||||
b = ZF0 / 2 * M_PI / ( Z0 * sqrt( e_r ) );
|
||||
a = ( ( m_parameters[Z0_PRM] / ZF0 / 2 / M_PI ) * sqrt( ( e_r + 1 ) / 2. ) )
|
||||
+ ( ( e_r - 1 ) / ( e_r + 1 ) * ( 0.23 + ( 0.11 / e_r ) ) );
|
||||
b = ZF0 / 2 * M_PI / ( m_parameters[Z0_PRM] * sqrt( e_r ) );
|
||||
|
||||
if( a > 1.52 )
|
||||
{
|
||||
w_h = 8 * exp( a ) / (exp( 2. * a ) - 2);
|
||||
w_h = 8 * exp( a ) / ( exp( 2. * a ) - 2 );
|
||||
}
|
||||
else
|
||||
{
|
||||
w_h = (2. / M_PI) * ( b - 1. -
|
||||
log( (2 * b) - 1. ) + ( (e_r - 1) / (2 * e_r) ) * (log( b - 1. ) + 0.39 - 0.61 / e_r) );
|
||||
w_h = ( 2. / M_PI )
|
||||
* ( b - 1. - log( ( 2 * b ) - 1. )
|
||||
+ ( ( e_r - 1 ) / ( 2 * e_r ) ) * ( log( b - 1. ) + 0.39 - 0.61 / e_r ) );
|
||||
}
|
||||
|
||||
if( h > 0.0 )
|
||||
width = w_h * h;
|
||||
if( m_parameters[H_PRM] > 0.0 )
|
||||
width = w_h * m_parameters[H_PRM];
|
||||
else
|
||||
width = 0;
|
||||
|
||||
|
@ -434,13 +422,13 @@ void MICROSTRIP::line_angle()
|
|||
/* velocity */
|
||||
v = C0 / sqrt( e_r_eff * mur_eff );
|
||||
/* wavelength */
|
||||
lambda_g = v / m_freq;
|
||||
lambda_g = v / m_parameters[FREQUENCY_PRM];
|
||||
/* electrical angles */
|
||||
ang_l = 2.0 * M_PI * l / lambda_g; /* in radians */
|
||||
m_parameters[ANG_L_PRM] = 2.0 * M_PI * m_parameters[PHYS_LEN_PRM] / lambda_g; /* in radians */
|
||||
}
|
||||
|
||||
|
||||
void MICROSTRIP::calc()
|
||||
void MICROSTRIP::calcAnalyze()
|
||||
{
|
||||
/* effective permeability */
|
||||
mur_eff_ms();
|
||||
|
@ -455,167 +443,78 @@ void MICROSTRIP::calc()
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* get_microstrip_sub () - get and assign microstrip substrate
|
||||
* parameters into microstrip structure
|
||||
*/
|
||||
void MICROSTRIP::get_microstrip_sub()
|
||||
{
|
||||
er = getProperty( EPSILONR_PRM );
|
||||
mur = getProperty( MUR_PRM );
|
||||
h = getProperty( H_PRM );
|
||||
ht = getProperty( H_T_PRM );
|
||||
t = getProperty( T_PRM );
|
||||
m_sigma = 1.0 / getProperty( RHO_PRM );
|
||||
m_murC = getProperty( MURC_PRM );
|
||||
m_tand = getProperty( TAND_PRM );
|
||||
rough = getProperty( ROUGH_PRM );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* get_microstrip_comp() - get and assign microstrip component
|
||||
* parameters into microstrip structure
|
||||
*/
|
||||
void MICROSTRIP::get_microstrip_comp()
|
||||
{
|
||||
m_freq = getProperty( FREQUENCY_PRM );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* get_microstrip_elec() - get and assign microstrip electrical
|
||||
* parameters into microstrip structure
|
||||
*/
|
||||
void MICROSTRIP::get_microstrip_elec()
|
||||
{
|
||||
Z0 = getProperty( Z0_PRM );
|
||||
ang_l = getProperty( ANG_L_PRM );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* get_microstrip_phys() - get and assign microstrip physical
|
||||
* parameters into microstrip structure
|
||||
*/
|
||||
void MICROSTRIP::get_microstrip_phys()
|
||||
{
|
||||
w = getProperty( PHYS_WIDTH_PRM );
|
||||
l = getProperty( PHYS_LEN_PRM );
|
||||
}
|
||||
|
||||
|
||||
void MICROSTRIP::show_results()
|
||||
{
|
||||
setProperty( Z0_PRM, Z0 );
|
||||
setProperty( ANG_L_PRM, ang_l );
|
||||
setProperty( Z0_PRM, m_parameters[Z0_PRM] );
|
||||
setProperty( ANG_L_PRM, m_parameters[ANG_L_PRM] );
|
||||
|
||||
setResult( 0, er_eff, "" );
|
||||
setResult( 1, atten_cond, "dB" );
|
||||
setResult( 2, atten_dielectric, "dB" );
|
||||
|
||||
setResult( 3, m_skindepth/UNIT_MICRON, "µm" );
|
||||
setResult( 3, m_parameters[SKIN_DEPTH_PRM] / UNIT_MICRON, "µm" );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* analysis function
|
||||
*/
|
||||
void MICROSTRIP::analyze()
|
||||
void MICROSTRIP::showSynthesize()
|
||||
{
|
||||
/* Get and assign substrate parameters */
|
||||
get_microstrip_sub();
|
||||
setProperty( PHYS_WIDTH_PRM, m_parameters[PHYS_WIDTH_PRM] );
|
||||
setProperty( PHYS_LEN_PRM, m_parameters[PHYS_LEN_PRM] );
|
||||
|
||||
/* Get and assign component parameters */
|
||||
get_microstrip_comp();
|
||||
// Check for errors
|
||||
if( !std::isfinite( m_parameters[PHYS_LEN_PRM] ) || ( m_parameters[PHYS_LEN_PRM] < 0 ) )
|
||||
setErrorLevel( PHYS_LEN_PRM, TRANSLINE_ERROR );
|
||||
|
||||
/* Get and assign physical parameters */
|
||||
get_microstrip_phys();
|
||||
if( !std::isfinite( m_parameters[PHYS_WIDTH_PRM] ) || ( m_parameters[PHYS_WIDTH_PRM] <= 0 ) )
|
||||
setErrorLevel( PHYS_WIDTH_PRM, TRANSLINE_ERROR );
|
||||
|
||||
/* compute microstrip parameters */
|
||||
calc();
|
||||
// Check for warnings
|
||||
|
||||
/* print results in the subwindow */
|
||||
show_results();
|
||||
if( !std::isfinite( m_parameters[Z0_PRM] ) || ( m_parameters[Z0_PRM] < 0 ) )
|
||||
setErrorLevel( Z0_PRM, TRANSLINE_WARNING );
|
||||
|
||||
if( !std::isfinite( m_parameters[ANG_L_PRM] ) || ( m_parameters[ANG_L_PRM] < 0 ) )
|
||||
setErrorLevel( ANG_L_PRM, TRANSLINE_WARNING );
|
||||
}
|
||||
|
||||
void MICROSTRIP::showAnalyze()
|
||||
{
|
||||
setProperty( Z0_PRM, m_parameters[Z0_PRM] );
|
||||
setProperty( ANG_L_PRM, m_parameters[ANG_L_PRM] );
|
||||
|
||||
#define MAX_ERROR 0.000001
|
||||
// Check for errors
|
||||
if( !std::isfinite( m_parameters[Z0_PRM] ) || ( m_parameters[Z0_PRM] < 0 ) )
|
||||
setErrorLevel( Z0_PRM, TRANSLINE_ERROR );
|
||||
|
||||
if( !std::isfinite( m_parameters[ANG_L_PRM] ) || ( m_parameters[ANG_L_PRM] < 0 ) )
|
||||
setErrorLevel( ANG_L_PRM, TRANSLINE_ERROR );
|
||||
|
||||
// Check for warnings
|
||||
if( !std::isfinite( m_parameters[PHYS_LEN_PRM] ) || ( m_parameters[PHYS_LEN_PRM] < 0 ) )
|
||||
setErrorLevel( PHYS_LEN_PRM, TRANSLINE_WARNING );
|
||||
|
||||
if( !std::isfinite( m_parameters[PHYS_WIDTH_PRM] ) || ( m_parameters[PHYS_WIDTH_PRM] <= 0 ) )
|
||||
setErrorLevel( PHYS_WIDTH_PRM, TRANSLINE_WARNING );
|
||||
}
|
||||
|
||||
/*
|
||||
* synthesis function
|
||||
*/
|
||||
void MICROSTRIP::synthesize()
|
||||
void MICROSTRIP::calcSynthesize()
|
||||
{
|
||||
double Z0_dest, Z0_current, Z0_result, increment, slope, error;
|
||||
int iteration;
|
||||
|
||||
/* Get and assign substrate parameters */
|
||||
get_microstrip_sub();
|
||||
|
||||
/* Get and assign component parameters */
|
||||
get_microstrip_comp();
|
||||
|
||||
/* Get and assign electrical parameters */
|
||||
get_microstrip_elec();
|
||||
|
||||
/* Get and assign physical parameters */
|
||||
/* at present it is required only for getting strips length */
|
||||
get_microstrip_phys();
|
||||
|
||||
|
||||
double angl_dest, z0_dest;
|
||||
z0_dest = m_parameters[Z0_PRM];
|
||||
angl_dest = m_parameters[ANG_L_PRM];
|
||||
/* calculate width and use for initial value in Newton's method */
|
||||
w = synth_width();
|
||||
|
||||
/* required value of Z0 */
|
||||
Z0_dest = Z0;
|
||||
|
||||
/* Newton's method */
|
||||
iteration = 0;
|
||||
|
||||
/* compute microstrip parameters */
|
||||
calc();
|
||||
Z0_current = Z0;
|
||||
|
||||
error = fabs( Z0_dest - Z0_current );
|
||||
|
||||
while( error > MAX_ERROR )
|
||||
{
|
||||
iteration++;
|
||||
increment = (w / 100.0);
|
||||
w += increment;
|
||||
/* compute microstrip parameters */
|
||||
calc();
|
||||
Z0_result = Z0;
|
||||
/* f(w(n)) = Z0 - Z0(w(n)) */
|
||||
/* f'(w(n)) = -f'(Z0(w(n))) */
|
||||
/* f'(Z0(w(n))) = (Z0(w(n)) - Z0(w(n+delw))/delw */
|
||||
/* w(n+1) = w(n) - f(w(n))/f'(w(n)) */
|
||||
slope = (Z0_result - Z0_current) / increment;
|
||||
/* printf("%g\n",slope); */
|
||||
w += (Z0_dest - Z0_current) / slope - increment;
|
||||
/* printf("ms->w = %g\n", ms->w); */
|
||||
/* find new error */
|
||||
/* compute microstrip parameters */
|
||||
calc();
|
||||
Z0_current = Z0;
|
||||
error = fabs( Z0_dest - Z0_current );
|
||||
|
||||
/* printf("Iteration = %d\n",iteration);
|
||||
* printf("w = %g\t Z0 = %g\n",ms->w, Z0_current); */
|
||||
if( iteration > 100 )
|
||||
break;
|
||||
}
|
||||
|
||||
setProperty( PHYS_WIDTH_PRM, w );
|
||||
/* calculate physical length */
|
||||
ang_l = getProperty( ANG_L_PRM );
|
||||
l = C0 / m_freq / sqrt( er_eff * mur_eff ) * ang_l / 2.0 / M_PI; /* in m */
|
||||
setProperty( PHYS_LEN_PRM, l );
|
||||
|
||||
/* compute microstrip parameters */
|
||||
calc();
|
||||
|
||||
/* print results in the subwindow */
|
||||
show_results();
|
||||
m_parameters[PHYS_WIDTH_PRM] = synth_width();
|
||||
minimizeZ0Error1D( &( m_parameters[PHYS_WIDTH_PRM] ) );
|
||||
m_parameters[Z0_PRM] = z0_dest;
|
||||
m_parameters[ANG_L_PRM] = angl_dest;
|
||||
m_parameters[PHYS_LEN_PRM] = C0 / m_parameters[FREQUENCY_PRM] / sqrt( er_eff * mur_eff )
|
||||
* m_parameters[ANG_L_PRM] / 2.0 / M_PI; /* in m */
|
||||
calcAnalyze();
|
||||
m_parameters[Z0_PRM] = z0_dest;
|
||||
m_parameters[ANG_L_PRM] = angl_dest;
|
||||
m_parameters[PHYS_LEN_PRM] = C0 / m_parameters[FREQUENCY_PRM] / sqrt( er_eff * mur_eff )
|
||||
* m_parameters[ANG_L_PRM] / 2.0 / M_PI; /* in m */
|
||||
}
|
||||
|
|
|
@ -25,9 +25,12 @@
|
|||
#ifndef __MICROSTRIP_H
|
||||
#define __MICROSTRIP_H
|
||||
|
||||
#include <transline.h>
|
||||
|
||||
class MICROSTRIP : public TRANSLINE
|
||||
{
|
||||
public: MICROSTRIP();
|
||||
public:
|
||||
MICROSTRIP();
|
||||
|
||||
friend class C_MICROSTRIP;
|
||||
|
||||
|
@ -52,10 +55,6 @@ private:
|
|||
// private params
|
||||
double Z0_h_1; // homogeneous stripline impedance
|
||||
|
||||
public:
|
||||
void analyze() override;
|
||||
void synthesize() override;
|
||||
|
||||
private:
|
||||
double er_eff_freq();
|
||||
double alpha_c();
|
||||
|
@ -81,12 +80,11 @@ private:
|
|||
void attenuation();
|
||||
void mur_eff_ms();
|
||||
void line_angle();
|
||||
void calc();
|
||||
void get_microstrip_sub();
|
||||
void get_microstrip_comp();
|
||||
void get_microstrip_elec();
|
||||
void get_microstrip_phys();
|
||||
void show_results();
|
||||
void show_results() override;
|
||||
void showSynthesize() override;
|
||||
void showAnalyze() override;
|
||||
void calcAnalyze() override;
|
||||
void calcSynthesize() override;
|
||||
};
|
||||
|
||||
#endif // __MICROSTRIP_H
|
||||
|
|
|
@ -25,27 +25,13 @@
|
|||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
||||
#include <units.h>
|
||||
#include <transline.h>
|
||||
#include <rectwaveguide.h>
|
||||
#include <units.h>
|
||||
|
||||
RECTWAVEGUIDE::RECTWAVEGUIDE() : TRANSLINE()
|
||||
{
|
||||
m_Name = "RectWaveGuide";
|
||||
|
||||
// Initialize these here variables mainly to avoid warnings from a static analyzer
|
||||
mur = 0.0; // magnetic permeability of substrate
|
||||
a = 0.0; // width of waveguide
|
||||
b = 0.0; // height of waveguide
|
||||
l = 0.0; // length of waveguide
|
||||
Z0 = 0.0; // characteristic impedance
|
||||
Z0EH = 0.0; // characteristic impedance of field quantities*/
|
||||
ang_l = 0.0; // Electrical length in angle
|
||||
er_eff = 0.0; // Effective dielectric constant
|
||||
mur_eff = 0.0; // Effective mag. permeability
|
||||
atten_dielectric = 0.0; // Loss in dielectric (dB)
|
||||
atten_cond = 0.0; // Loss in conductors (dB)
|
||||
fc10 = 0.0; // Cutoff frequency for TE10 mode
|
||||
Init();
|
||||
}
|
||||
|
||||
|
||||
|
@ -56,7 +42,8 @@ double RECTWAVEGUIDE::kval_square()
|
|||
{
|
||||
double kval;
|
||||
|
||||
kval = 2.0* M_PI * m_freq * sqrt( mur * er ) / C0;
|
||||
kval = 2.0 * M_PI * m_parameters[FREQUENCY_PRM]
|
||||
* sqrt( m_parameters[MUR_PRM] * m_parameters[EPSILONR_PRM] ) / C0;
|
||||
|
||||
return kval * kval;
|
||||
}
|
||||
|
@ -68,7 +55,8 @@ double RECTWAVEGUIDE::kval_square()
|
|||
*/
|
||||
double RECTWAVEGUIDE::kc_square( int m, int n )
|
||||
{
|
||||
return pow( (m * M_PI / a), 2.0 ) + pow( (n * M_PI / b), 2.0 );
|
||||
return pow( ( m * M_PI / m_parameters[PHYS_A_PRM] ), 2.0 )
|
||||
+ pow( ( n * M_PI / m_parameters[PHYS_B_PRM] ), 2.0 );
|
||||
}
|
||||
|
||||
|
||||
|
@ -78,7 +66,8 @@ double RECTWAVEGUIDE::kc_square( int m, int n )
|
|||
*/
|
||||
double RECTWAVEGUIDE::fc( int m, int n )
|
||||
{
|
||||
return sqrt( kc_square( m, n ) / mur / er ) * C0 / 2.0 / M_PI;
|
||||
return sqrt( kc_square( m, n ) / m_parameters[MUR_PRM] / m_parameters[EPSILONR_PRM] ) * C0 / 2.0
|
||||
/ M_PI;
|
||||
}
|
||||
|
||||
|
||||
|
@ -91,10 +80,15 @@ double RECTWAVEGUIDE::alphac()
|
|||
double Rs, f_c;
|
||||
double ac;
|
||||
short m, n, mmax, nmax;
|
||||
double* a = &m_parameters[PHYS_A_PRM];
|
||||
double* b = &m_parameters[PHYS_B_PRM];
|
||||
double* f = &m_parameters[FREQUENCY_PRM];
|
||||
double* murc = &m_parameters[MURC_PRM];
|
||||
double* sigma = &m_parameters[SIGMA_PRM];
|
||||
|
||||
Rs = sqrt( M_PI * m_freq * m_murC * MU0 / m_sigma );
|
||||
Rs = sqrt( M_PI * *f * *murc * MU0 / *sigma );
|
||||
ac = 0.0;
|
||||
mmax = (int) floor( m_freq / fc( 1, 0 ) );
|
||||
mmax = (int) floor( *f / fc( 1, 0 ) );
|
||||
nmax = mmax;
|
||||
|
||||
/* below from Ramo, Whinnery & Van Duzer */
|
||||
|
@ -105,24 +99,24 @@ double RECTWAVEGUIDE::alphac()
|
|||
for( m = 1; m <= mmax; m++ )
|
||||
{
|
||||
f_c = fc( m, n );
|
||||
if( m_freq > f_c )
|
||||
if( *f > f_c )
|
||||
{
|
||||
switch( n )
|
||||
{
|
||||
case 0:
|
||||
ac += ( Rs / ( b * ZF0 * sqrt( 1.0 - pow( (f_c / m_freq), 2.0 ) ) ) ) *
|
||||
( 1.0 + ( (2 * b / a) * pow( (f_c / m_freq), 2.0 ) ) );
|
||||
ac += ( Rs / ( *b * ZF0 * sqrt( 1.0 - pow( ( f_c / *f ), 2.0 ) ) ) )
|
||||
* ( 1.0 + ( ( 2 * *b / *a ) * pow( ( f_c / *f ), 2.0 ) ) );
|
||||
break;
|
||||
|
||||
default:
|
||||
ac += ( (2. * Rs) / ( b * ZF0 * sqrt( 1.0 - pow( (f_c / m_freq), 2.0 ) ) ) ) *
|
||||
( ( ( 1. + (b / a) ) * pow( (f_c / m_freq), 2.0 ) ) +
|
||||
( ( 1. -
|
||||
pow( (f_c / m_freq),
|
||||
2.0 ) ) *
|
||||
( ( (b / a) * ( ( (b / a) * pow( m, 2. ) ) + pow( n, 2. ) ) ) /
|
||||
( pow( (b * m / a),
|
||||
2.0 ) + pow( n, 2.0 ) ) ) ) );
|
||||
ac += ( ( 2. * Rs ) / ( *b * ZF0 * sqrt( 1.0 - pow( ( f_c / *f ), 2.0 ) ) ) )
|
||||
* ( ( ( 1. + ( *b / *a ) ) * pow( ( f_c / *f ), 2.0 ) )
|
||||
+ ( ( 1. - pow( ( f_c / *f ), 2.0 ) )
|
||||
* ( ( ( *b / *a )
|
||||
* ( ( ( *b / *a ) * pow( m, 2. ) )
|
||||
+ pow( n, 2. ) ) )
|
||||
/ ( pow( ( *b * m / *a ), 2.0 )
|
||||
+ pow( n, 2.0 ) ) ) ) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -132,14 +126,14 @@ double RECTWAVEGUIDE::alphac()
|
|||
/* TM(m,n) modes */
|
||||
for( n = 1; n <= nmax; n++ )
|
||||
{
|
||||
for( m = 1; m<= mmax; m++ )
|
||||
for( m = 1; m <= mmax; m++ )
|
||||
{
|
||||
f_c = fc( m, n );
|
||||
if( m_freq > f_c )
|
||||
if( *f > f_c )
|
||||
{
|
||||
ac += ( (2. * Rs) / ( b * ZF0 * sqrt( 1.0 - pow( (f_c / m_freq), 2.0 ) ) ) ) *
|
||||
( ( ( pow( m, 2.0 ) * pow( (b / a), 3.0 ) ) + pow( n, 2. ) ) /
|
||||
( ( pow( (m * b / a), 2. ) ) + pow( n, 2.0 ) ) );
|
||||
ac += ( ( 2. * Rs ) / ( *b * ZF0 * sqrt( 1.0 - pow( ( f_c / *f ), 2.0 ) ) ) )
|
||||
* ( ( ( pow( m, 2.0 ) * pow( ( *b / *a ), 3.0 ) ) + pow( n, 2. ) )
|
||||
/ ( ( pow( ( m * *b / *a ), 2. ) ) + pow( n, 2.0 ) ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -173,7 +167,7 @@ double RECTWAVEGUIDE::alphad()
|
|||
k_square = kval_square();
|
||||
beta = sqrt( k_square - kc_square( 1, 0 ) );
|
||||
|
||||
ad = (k_square * m_tand) / (2.0 * beta);
|
||||
ad = ( k_square * m_parameters[TAND_PRM] ) / ( 2.0 * beta );
|
||||
ad = ad * 20.0 * log10( exp( 1. ) ); /* convert from Np/m to db/m */
|
||||
return ad;
|
||||
}
|
||||
|
@ -186,11 +180,11 @@ double RECTWAVEGUIDE::alphad()
|
|||
*/
|
||||
void RECTWAVEGUIDE::get_rectwaveguide_sub()
|
||||
{
|
||||
er = getProperty( EPSILONR_PRM );
|
||||
mur = getProperty( MUR_PRM );
|
||||
m_murC = getProperty( MURC_PRM );
|
||||
m_sigma = 1.0 / getProperty( RHO_PRM );
|
||||
m_tand = getProperty( TAND_PRM );
|
||||
m_parameters[EPSILONR_PRM] = getProperty( EPSILONR_PRM );
|
||||
m_parameters[MUR_PRM] = getProperty( MUR_PRM );
|
||||
m_parameters[MURC_PRM] = getProperty( MURC_PRM );
|
||||
m_parameters[SIGMA_PRM] = 1.0 / getProperty( RHO_PRM );
|
||||
m_parameters[TAND_PRM] = getProperty( TAND_PRM );
|
||||
}
|
||||
|
||||
|
||||
|
@ -201,7 +195,7 @@ void RECTWAVEGUIDE::get_rectwaveguide_sub()
|
|||
*/
|
||||
void RECTWAVEGUIDE::get_rectwaveguide_comp()
|
||||
{
|
||||
m_freq = getProperty( FREQUENCY_PRM );
|
||||
m_parameters[FREQUENCY_PRM] = getProperty( FREQUENCY_PRM );
|
||||
}
|
||||
|
||||
|
||||
|
@ -212,8 +206,8 @@ void RECTWAVEGUIDE::get_rectwaveguide_comp()
|
|||
*/
|
||||
void RECTWAVEGUIDE::get_rectwaveguide_elec()
|
||||
{
|
||||
Z0 = getProperty( Z0_PRM );
|
||||
ang_l = getProperty( ANG_L_PRM );
|
||||
m_parameters[Z0_PRM] = getProperty( Z0_PRM );
|
||||
m_parameters[ANG_L_PRM] = getProperty( ANG_L_PRM );
|
||||
}
|
||||
|
||||
|
||||
|
@ -224,29 +218,20 @@ void RECTWAVEGUIDE::get_rectwaveguide_elec()
|
|||
*/
|
||||
void RECTWAVEGUIDE::get_rectwaveguide_phys()
|
||||
{
|
||||
a = getProperty( PHYS_WIDTH_PRM );
|
||||
b = getProperty( PHYS_S_PRM );
|
||||
l = getProperty( PHYS_LEN_PRM );
|
||||
m_parameters[PHYS_A_PRM] = getProperty( PHYS_A_PRM );
|
||||
m_parameters[PHYS_B_PRM] = getProperty( PHYS_B_PRM );
|
||||
m_parameters[PHYS_LEN_PRM] = getProperty( PHYS_LEN_PRM );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* analyze - analysis function
|
||||
*/
|
||||
void RECTWAVEGUIDE::analyze()
|
||||
void RECTWAVEGUIDE::calcAnalyze()
|
||||
{
|
||||
double lambda_g;
|
||||
double k_square;
|
||||
|
||||
/* Get and assign substrate parameters */
|
||||
get_rectwaveguide_sub();
|
||||
|
||||
/* Get and assign component parameters */
|
||||
get_rectwaveguide_comp();
|
||||
|
||||
/* Get and assign physical parameters */
|
||||
get_rectwaveguide_phys();
|
||||
|
||||
k_square = kval_square();
|
||||
|
||||
if( kc_square( 1, 0 ) <= k_square )
|
||||
|
@ -254,92 +239,124 @@ void RECTWAVEGUIDE::analyze()
|
|||
/* propagating modes */
|
||||
|
||||
// Z0 definition using fictive voltages and currents
|
||||
Z0 = 2.0* ZF0* sqrt( mur / er ) * (b / a) / sqrt( 1.0 - pow( (fc( 1, 0 ) / m_freq), 2.0 ) );
|
||||
m_parameters[Z0_PRM] =
|
||||
2.0 * ZF0 * sqrt( m_parameters[MUR_PRM] / m_parameters[EPSILONR_PRM] )
|
||||
* ( m_parameters[PHYS_B_PRM] / m_parameters[PHYS_A_PRM] )
|
||||
/ sqrt( 1.0 - pow( ( fc( 1, 0 ) / m_parameters[FREQUENCY_PRM] ), 2.0 ) );
|
||||
|
||||
/* calculate electrical angle */
|
||||
lambda_g = 2.0 * M_PI / sqrt( k_square - kc_square( 1, 0 ) );
|
||||
ang_l = 2.0 * M_PI * l / lambda_g; /* in radians */
|
||||
atten_cond = alphac() * l;
|
||||
atten_dielectric = alphad() * l;
|
||||
er_eff = ( 1.0 - pow( fc( 1, 0 ) / m_freq, 2.0 ) );
|
||||
m_parameters[ANG_L_PRM] =
|
||||
2.0 * M_PI * m_parameters[PHYS_LEN_PRM] / lambda_g; /* in radians */
|
||||
m_parameters[LOSS_CONDUCTOR_PRM] = alphac() * m_parameters[PHYS_LEN_PRM];
|
||||
m_parameters[LOSS_DIELECTRIC_PRM] = alphad() * m_parameters[PHYS_LEN_PRM];
|
||||
m_parameters[EPSILON_EFF_PRM] =
|
||||
( 1.0 - pow( fc( 1, 0 ) / m_parameters[FREQUENCY_PRM], 2.0 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* evanascent modes */
|
||||
Z0 = 0;
|
||||
ang_l = 0;
|
||||
er_eff = 0;
|
||||
atten_dielectric = 0.0;
|
||||
atten_cond = alphac_cutoff() * l;
|
||||
m_parameters[Z0_PRM] = 0;
|
||||
m_parameters[ANG_L_PRM] = 0;
|
||||
m_parameters[EPSILON_EFF_PRM] = 0;
|
||||
m_parameters[LOSS_DIELECTRIC_PRM] = 0.0;
|
||||
m_parameters[LOSS_CONDUCTOR_PRM] = alphac_cutoff() * m_parameters[PHYS_LEN_PRM];
|
||||
}
|
||||
|
||||
setProperty( Z0_PRM, Z0 );
|
||||
setProperty( ANG_L_PRM, ang_l );
|
||||
|
||||
show_results();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* synthesize - synthesis function
|
||||
*/
|
||||
void RECTWAVEGUIDE::synthesize()
|
||||
void RECTWAVEGUIDE::calcSynthesize()
|
||||
{
|
||||
double lambda_g, k_square, beta;
|
||||
|
||||
/* Get and assign substrate parameters */
|
||||
get_rectwaveguide_sub();
|
||||
|
||||
/* Get and assign component parameters */
|
||||
get_rectwaveguide_comp();
|
||||
|
||||
/* Get and assign electrical parameters */
|
||||
get_rectwaveguide_elec();
|
||||
|
||||
/* Get and assign physical parameters */
|
||||
get_rectwaveguide_phys();
|
||||
|
||||
|
||||
if( isSelected( PHYS_S_PRM ) )
|
||||
if( isSelected( PHYS_B_PRM ) )
|
||||
{
|
||||
/* solve for b */
|
||||
b = Z0 * a * sqrt( 1.0 - pow( fc( 1, 0 ) / m_freq, 2.0 ) ) / ( 2.0 * ZF0 * sqrt( mur / er ) );
|
||||
setProperty( PHYS_S_PRM, b );
|
||||
m_parameters[PHYS_B_PRM] =
|
||||
m_parameters[Z0_PRM] * m_parameters[PHYS_A_PRM]
|
||||
* sqrt( 1.0 - pow( fc( 1, 0 ) / m_parameters[FREQUENCY_PRM], 2.0 ) )
|
||||
/ ( 2.0 * ZF0 * sqrt( m_parameters[MUR_PRM] / m_parameters[EPSILONR_PRM] ) );
|
||||
}
|
||||
else if( isSelected( PHYS_WIDTH_PRM ) )
|
||||
else if( isSelected( PHYS_A_PRM ) )
|
||||
{
|
||||
/* solve for a */
|
||||
a = sqrt( pow( 2.0 * ZF0 * b / Z0, 2.0 ) + pow( C0 / (2.0 * m_freq), 2.0 ) );
|
||||
setProperty( PHYS_WIDTH_PRM, a );
|
||||
m_parameters[PHYS_A_PRM] =
|
||||
sqrt( pow( 2.0 * ZF0 * m_parameters[PHYS_B_PRM] / m_parameters[Z0_PRM], 2.0 )
|
||||
+ pow( C0 / ( 2.0 * m_parameters[FREQUENCY_PRM] ), 2.0 ) );
|
||||
}
|
||||
|
||||
k_square = kval_square();
|
||||
beta = sqrt( k_square - kc_square( 1, 0 ) );
|
||||
lambda_g = 2.0 * M_PI / beta;
|
||||
l = (ang_l * lambda_g) / (2.0 * M_PI); /* in m */
|
||||
|
||||
setProperty( PHYS_LEN_PRM, l );
|
||||
m_parameters[PHYS_LEN_PRM] = ( m_parameters[ANG_L_PRM] * lambda_g ) / ( 2.0 * M_PI ); /* in m */
|
||||
|
||||
if( kc_square( 1, 0 ) <= k_square )
|
||||
{
|
||||
/*propagating modes */
|
||||
beta = sqrt( k_square - kc_square( 1, 0 ) );
|
||||
lambda_g = 2.0 * M_PI / beta;
|
||||
atten_cond = alphac() * l;
|
||||
atten_dielectric = alphad() * l;
|
||||
er_eff = ( 1.0 - pow( (fc( 1, 0 ) / m_freq), 2.0 ) );
|
||||
m_parameters[LOSS_CONDUCTOR_PRM] = alphac() * m_parameters[PHYS_LEN_PRM];
|
||||
m_parameters[LOSS_DIELECTRIC_PRM] = alphad() * m_parameters[PHYS_LEN_PRM];
|
||||
m_parameters[EPSILON_EFF_PRM] =
|
||||
( 1.0 - pow( ( fc( 1, 0 ) / m_parameters[FREQUENCY_PRM] ), 2.0 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
/*evanascent modes */
|
||||
Z0 = 0;
|
||||
ang_l = 0;
|
||||
er_eff = 0;
|
||||
atten_dielectric = 0.0;
|
||||
atten_cond = alphac_cutoff() * l;
|
||||
m_parameters[Z0_PRM] = 0;
|
||||
m_parameters[ANG_L_PRM] = 0;
|
||||
m_parameters[EPSILON_EFF_PRM] = 0;
|
||||
m_parameters[LOSS_DIELECTRIC_PRM] = 0.0;
|
||||
m_parameters[LOSS_CONDUCTOR_PRM] = alphac_cutoff() * m_parameters[PHYS_LEN_PRM];
|
||||
}
|
||||
}
|
||||
|
||||
show_results();
|
||||
void RECTWAVEGUIDE::showSynthesize()
|
||||
{
|
||||
if( isSelected( PHYS_A_PRM ) )
|
||||
setProperty( PHYS_A_PRM, m_parameters[PHYS_A_PRM] );
|
||||
|
||||
if( isSelected( PHYS_B_PRM ) )
|
||||
setProperty( PHYS_B_PRM, m_parameters[PHYS_B_PRM] );
|
||||
|
||||
setProperty( PHYS_LEN_PRM, m_parameters[PHYS_LEN_PRM] );
|
||||
|
||||
// Check for errors
|
||||
if( !std::isfinite( m_parameters[PHYS_A_PRM] ) || m_parameters[PHYS_A_PRM] <= 0 )
|
||||
setErrorLevel( PHYS_A_PRM, TRANSLINE_ERROR );
|
||||
|
||||
if( !std::isfinite( m_parameters[PHYS_B_PRM] ) || m_parameters[PHYS_B_PRM] <= 00 )
|
||||
setErrorLevel( PHYS_B_PRM, TRANSLINE_ERROR );
|
||||
|
||||
// Check for warnings
|
||||
if( !std::isfinite( m_parameters[Z0_PRM] ) || m_parameters[Z0_PRM] < 0 )
|
||||
setErrorLevel( Z0_PRM, TRANSLINE_WARNING );
|
||||
|
||||
if( !std::isfinite( m_parameters[ANG_L_PRM] ) || m_parameters[ANG_L_PRM] < 0 )
|
||||
setErrorLevel( ANG_L_PRM, TRANSLINE_WARNING );
|
||||
}
|
||||
|
||||
|
||||
void RECTWAVEGUIDE::showAnalyze()
|
||||
{
|
||||
setProperty( Z0_PRM, m_parameters[Z0_PRM] );
|
||||
setProperty( ANG_L_PRM, m_parameters[ANG_L_PRM] );
|
||||
|
||||
// Check for errors
|
||||
if( !std::isfinite( m_parameters[Z0_PRM] ) || m_parameters[Z0_PRM] < 0 )
|
||||
setErrorLevel( Z0_PRM, TRANSLINE_ERROR );
|
||||
|
||||
if( !std::isfinite( m_parameters[ANG_L_PRM] ) || m_parameters[ANG_L_PRM] < 0 )
|
||||
setErrorLevel( ANG_L_PRM, TRANSLINE_ERROR );
|
||||
|
||||
// Check for warnings
|
||||
if( !std::isfinite( m_parameters[PHYS_A_PRM] ) || m_parameters[PHYS_A_PRM] <= 0 )
|
||||
setErrorLevel( PHYS_A_PRM, TRANSLINE_WARNING );
|
||||
|
||||
if( !std::isfinite( m_parameters[PHYS_B_PRM] ) || m_parameters[PHYS_B_PRM] <= 00 )
|
||||
setErrorLevel( PHYS_B_PRM, TRANSLINE_WARNING );
|
||||
}
|
||||
|
||||
|
||||
|
@ -353,12 +370,12 @@ void RECTWAVEGUIDE::show_results()
|
|||
Z0EH = ZF0 * sqrt( kval_square() / ( kval_square() - kc_square( 1, 0 ) ) );
|
||||
setResult( 0, Z0EH, "Ohm" );
|
||||
|
||||
setResult( 1, er_eff, "" );
|
||||
setResult( 2, atten_cond, "dB" );
|
||||
setResult( 3, atten_dielectric, "dB" );
|
||||
setResult( 1, m_parameters[EPSILON_EFF_PRM], "" );
|
||||
setResult( 2, m_parameters[LOSS_CONDUCTOR_PRM], "dB" );
|
||||
setResult( 3, m_parameters[LOSS_DIELECTRIC_PRM], "dB" );
|
||||
|
||||
// show possible TE modes (H modes)
|
||||
if( m_freq < fc( 1, 0 ) )
|
||||
if( m_parameters[FREQUENCY_PRM] < fc( 1, 0 ) )
|
||||
strcpy( text, "none" );
|
||||
else
|
||||
{
|
||||
|
@ -367,12 +384,12 @@ void RECTWAVEGUIDE::show_results()
|
|||
{
|
||||
for( n = 0; n <= max; n++ )
|
||||
{
|
||||
if( (m == 0) && (n == 0) )
|
||||
if( ( m == 0 ) && ( n == 0 ) )
|
||||
continue;
|
||||
if( m_freq >= ( fc( m, n ) ) )
|
||||
if( m_parameters[FREQUENCY_PRM] >= ( fc( m, n ) ) )
|
||||
{
|
||||
sprintf( txt, "H(%d,%d) ", m, n );
|
||||
if( (strlen( text ) + strlen( txt ) + 5) < MAXSTRLEN )
|
||||
if( ( strlen( text ) + strlen( txt ) + 5 ) < MAXSTRLEN )
|
||||
strcat( text, txt );
|
||||
else
|
||||
{
|
||||
|
@ -386,19 +403,19 @@ void RECTWAVEGUIDE::show_results()
|
|||
setResult( 4, text );
|
||||
|
||||
// show possible TM modes (E modes)
|
||||
if( m_freq < fc( 1, 1 ) )
|
||||
if( m_parameters[FREQUENCY_PRM] < fc( 1, 1 ) )
|
||||
strcpy( text, "none" );
|
||||
else
|
||||
{
|
||||
strcpy( text, "" );
|
||||
for( m = 1; m<= max; m++ )
|
||||
for( m = 1; m <= max; m++ )
|
||||
{
|
||||
for( n = 1; n<= max; n++ )
|
||||
for( n = 1; n <= max; n++ )
|
||||
{
|
||||
if( m_freq >= fc( m, n ) )
|
||||
if( m_parameters[FREQUENCY_PRM] >= fc( m, n ) )
|
||||
{
|
||||
sprintf( txt, "E(%d,%d) ", m, n );
|
||||
if( (strlen( text ) + strlen( txt ) + 5) < MAXSTRLEN )
|
||||
if( ( strlen( text ) + strlen( txt ) + 5 ) < MAXSTRLEN )
|
||||
strcat( text, txt );
|
||||
else
|
||||
{
|
||||
|
|
|
@ -25,9 +25,16 @@
|
|||
#ifndef __RECTWAVEGUIDE_H
|
||||
#define __RECTWAVEGUIDE_H
|
||||
|
||||
#include <transline.h>
|
||||
|
||||
#define PHYS_A_PRM PHYS_WIDTH_PRM
|
||||
#define PHYS_B_PRM PHYS_S_PRM
|
||||
|
||||
class RECTWAVEGUIDE : public TRANSLINE
|
||||
{
|
||||
public: RECTWAVEGUIDE();
|
||||
public:
|
||||
RECTWAVEGUIDE();
|
||||
|
||||
|
||||
private:
|
||||
double mur; // magnetic permeability of substrate
|
||||
|
@ -44,9 +51,6 @@ private:
|
|||
double fc10; // Cutoff frequency for TE10 mode
|
||||
|
||||
public:
|
||||
void analyze() override;
|
||||
void synthesize() override;
|
||||
|
||||
private:
|
||||
double kval_square();
|
||||
double kc_square( int, int );
|
||||
|
@ -58,7 +62,11 @@ private:
|
|||
void get_rectwaveguide_comp();
|
||||
void get_rectwaveguide_phys();
|
||||
void get_rectwaveguide_elec();
|
||||
void show_results();
|
||||
void show_results() override;
|
||||
void calcAnalyze() override;
|
||||
void calcSynthesize() override;
|
||||
void showAnalyze() override;
|
||||
void showSynthesize() override;
|
||||
};
|
||||
|
||||
#endif // __RECTWAVEGUIDE_H
|
||||
|
|
|
@ -27,44 +27,13 @@
|
|||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
#include <units.h>
|
||||
#include <transline.h>
|
||||
#include <stripline.h>
|
||||
#include <units.h>
|
||||
|
||||
STRIPLINE::STRIPLINE() : TRANSLINE()
|
||||
{
|
||||
m_Name = "StripLine";
|
||||
|
||||
// Initialize these variables mainly to avoid warnings from a static analyzer
|
||||
h = 0.0; // height of substrate
|
||||
a = 0.0; // distance of strip to top metal
|
||||
t = 0.0; // thickness of top metal
|
||||
w = 0.0; // width of line
|
||||
len = 0.0; // length of line
|
||||
Z0 = 0.0; // characteristic impedance
|
||||
ang_l = 0.0; // Electrical length in angle
|
||||
er_eff = 0.0; // effective dielectric constant
|
||||
atten_dielectric = 0.0; // Loss in dielectric (dB)
|
||||
atten_cond = 0.0; // Loss in conductors (dB)
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
void STRIPLINE::getProperties()
|
||||
{
|
||||
m_freq = getProperty( FREQUENCY_PRM );
|
||||
w = getProperty( PHYS_WIDTH_PRM );
|
||||
len = getProperty( PHYS_LEN_PRM );
|
||||
h = getProperty( H_PRM);
|
||||
a = getProperty( STRIPLINE_A_PRM );
|
||||
t = getProperty( T_PRM );
|
||||
|
||||
er = getProperty( EPSILONR_PRM );
|
||||
m_murC = getProperty( MURC_PRM );
|
||||
m_tand = getProperty( TAND_PRM );
|
||||
m_sigma = 1.0 / getProperty( RHO_PRM );
|
||||
Z0 = getProperty( Z0_PRM );
|
||||
ang_l = getProperty( ANG_L_PRM );
|
||||
Init();
|
||||
}
|
||||
|
||||
|
||||
|
@ -73,33 +42,37 @@ void STRIPLINE::getProperties()
|
|||
double STRIPLINE::lineImpedance( double height, double& ac )
|
||||
{
|
||||
double ZL;
|
||||
double hmt = height - t;
|
||||
double hmt = height - m_parameters[T_PRM];
|
||||
|
||||
ac = sqrt( m_freq / m_sigma / 17.2 );
|
||||
if( w / hmt >= 0.35 )
|
||||
ac = sqrt( m_parameters[FREQUENCY_PRM] / m_parameters[SIGMA_PRM] / 17.2 );
|
||||
if( m_parameters[PHYS_WIDTH_PRM] / hmt >= 0.35 )
|
||||
{
|
||||
ZL = w +
|
||||
( 2.0 * height *
|
||||
log( (2.0 * height - t) / hmt ) - t * log( height * height / hmt / hmt - 1.0 ) ) / M_PI;
|
||||
ZL = ZF0 * hmt / sqrt( er ) / 4.0 / ZL;
|
||||
ZL = m_parameters[PHYS_WIDTH_PRM]
|
||||
+ ( 2.0 * height * log( ( 2.0 * height - m_parameters[T_PRM] ) / hmt )
|
||||
- m_parameters[T_PRM] * log( height * height / hmt / hmt - 1.0 ) )
|
||||
/ M_PI;
|
||||
ZL = ZF0 * hmt / sqrt( m_parameters[EPSILONR_PRM] ) / 4.0 / ZL;
|
||||
|
||||
ac *= 2.02e-6 * er * ZL / hmt;
|
||||
ac *= 1.0 + 2.0 * w / hmt + (height + t) / hmt / M_PI* log( 2.0 * height / t - 1.0 );
|
||||
ac *= 2.02e-6 * m_parameters[EPSILONR_PRM] * ZL / hmt;
|
||||
ac *= 1.0 + 2.0 * m_parameters[PHYS_WIDTH_PRM] / hmt
|
||||
+ ( height + m_parameters[T_PRM] ) / hmt / M_PI
|
||||
* log( 2.0 * height / m_parameters[T_PRM] - 1.0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
double tdw = t / w;
|
||||
if( t / w > 1.0 )
|
||||
tdw = w / t;
|
||||
double tdw = m_parameters[T_PRM] / m_parameters[PHYS_WIDTH_PRM];
|
||||
if( m_parameters[T_PRM] / m_parameters[PHYS_WIDTH_PRM] > 1.0 )
|
||||
tdw = m_parameters[PHYS_WIDTH_PRM] / m_parameters[T_PRM];
|
||||
double de = 1.0 + tdw / M_PI * ( 1.0 + log( 4.0 * M_PI / tdw ) ) + 0.236 * pow( tdw, 1.65 );
|
||||
if( t / w > 1.0 )
|
||||
de *= t / 2.0;
|
||||
if( m_parameters[T_PRM] / m_parameters[PHYS_WIDTH_PRM] > 1.0 )
|
||||
de *= m_parameters[T_PRM] / 2.0;
|
||||
else
|
||||
de *= w / 2.0;
|
||||
ZL = ZF0 / 2.0 / M_PI / sqrt( er ) * log( 4.0 * height / M_PI / de );
|
||||
de *= m_parameters[PHYS_WIDTH_PRM] / 2.0;
|
||||
ZL = ZF0 / 2.0 / M_PI / sqrt( m_parameters[EPSILONR_PRM] )
|
||||
* log( 4.0 * height / M_PI / de );
|
||||
|
||||
ac *= 0.01141 / ZL / de;
|
||||
ac *= de / height + 0.5 + tdw / 2.0 / M_PI + 0.5 / M_PI* log( 4.0 * M_PI / tdw )
|
||||
ac *= de / height + 0.5 + tdw / 2.0 / M_PI + 0.5 / M_PI * log( 4.0 * M_PI / tdw )
|
||||
+ 0.1947 * pow( tdw, 0.65 ) - 0.0767 * pow( tdw, 1.65 );
|
||||
}
|
||||
|
||||
|
@ -108,103 +81,110 @@ double STRIPLINE::lineImpedance( double height, double& ac )
|
|||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
void STRIPLINE::calc()
|
||||
void STRIPLINE::calcAnalyze()
|
||||
{
|
||||
m_skindepth = skin_depth();
|
||||
m_parameters[SKIN_DEPTH_PRM] = skin_depth();
|
||||
|
||||
er_eff = er; // no dispersion
|
||||
m_parameters[EPSILON_EFF_PRM] = m_parameters[EPSILONR_PRM]; // no dispersion
|
||||
|
||||
double ac1, ac2;
|
||||
Z0 = 2.0 /
|
||||
( 1.0 / lineImpedance( 2.0 * a + t, ac1 ) + 1.0 / lineImpedance( 2.0 * (h - a) - t, ac2 ) );
|
||||
double t = m_parameters[T_PRM];
|
||||
double a = m_parameters[STRIPLINE_A_PRM];
|
||||
double h = m_parameters[H_PRM];
|
||||
m_parameters[Z0_PRM] = 2.0
|
||||
/ ( 1.0 / lineImpedance( 2.0 * a + t, ac1 )
|
||||
+ 1.0 / lineImpedance( 2.0 * ( h - a ) - t, ac2 ) );
|
||||
m_parameters[LOSS_CONDUCTOR_PRM] = m_parameters[PHYS_LEN_PRM] * 0.5 * ( ac1 + ac2 );
|
||||
m_parameters[LOSS_DIELECTRIC_PRM] = 20.0 / log( 10.0 ) * m_parameters[PHYS_LEN_PRM]
|
||||
* ( M_PI / C0 ) * m_parameters[FREQUENCY_PRM]
|
||||
* sqrt( m_parameters[EPSILONR_PRM] )
|
||||
* m_parameters[TAND_PRM];
|
||||
|
||||
atten_cond = len * 0.5 * (ac1 + ac2);
|
||||
atten_dielectric = 20.0 / log( 10.0 ) * len * (M_PI / C0) * m_freq * sqrt( er ) * m_tand;
|
||||
|
||||
ang_l = 2.0* M_PI* len* sqrt( er ) * m_freq / C0; // in radians
|
||||
m_parameters[ANG_L_PRM] = 2.0 * M_PI * m_parameters[PHYS_LEN_PRM]
|
||||
* sqrt( m_parameters[EPSILONR_PRM] ) * m_parameters[FREQUENCY_PRM]
|
||||
/ C0; // in radians
|
||||
}
|
||||
|
||||
|
||||
void STRIPLINE::showAnalyze()
|
||||
{
|
||||
setProperty( Z0_PRM, m_parameters[Z0_PRM] );
|
||||
setProperty( ANG_L_PRM, m_parameters[ANG_L_PRM] );
|
||||
|
||||
if( !std::isfinite( m_parameters[Z0_PRM] ) || m_parameters[Z0_PRM] < 0 )
|
||||
{
|
||||
setErrorLevel( Z0_PRM, TRANSLINE_ERROR );
|
||||
}
|
||||
if( !std::isfinite( m_parameters[ANG_L_PRM] ) || m_parameters[ANG_L_PRM] < 0 )
|
||||
{
|
||||
setErrorLevel( ANG_L_PRM, TRANSLINE_ERROR );
|
||||
}
|
||||
|
||||
if( !std::isfinite( m_parameters[PHYS_LEN_PRM] ) || m_parameters[PHYS_LEN_PRM] < 0 )
|
||||
{
|
||||
setErrorLevel( PHYS_LEN_PRM, TRANSLINE_WARNING );
|
||||
}
|
||||
if( !std::isfinite( m_parameters[PHYS_WIDTH_PRM] ) || m_parameters[PHYS_WIDTH_PRM] < 0 )
|
||||
{
|
||||
setErrorLevel( PHYS_WIDTH_PRM, TRANSLINE_WARNING );
|
||||
}
|
||||
|
||||
if( m_parameters[STRIPLINE_A_PRM] + m_parameters[T_PRM] >= m_parameters[H_PRM] )
|
||||
{
|
||||
setErrorLevel( STRIPLINE_A_PRM, TRANSLINE_WARNING );
|
||||
setErrorLevel( T_PRM, TRANSLINE_WARNING );
|
||||
setErrorLevel( H_PRM, TRANSLINE_WARNING );
|
||||
setErrorLevel( Z0_PRM, TRANSLINE_ERROR );
|
||||
}
|
||||
}
|
||||
|
||||
void STRIPLINE::showSynthesize()
|
||||
{
|
||||
setProperty( PHYS_LEN_PRM, m_parameters[PHYS_LEN_PRM] );
|
||||
setProperty( PHYS_WIDTH_PRM, m_parameters[PHYS_WIDTH_PRM] );
|
||||
|
||||
if( !std::isfinite( m_parameters[PHYS_LEN_PRM] ) || m_parameters[PHYS_LEN_PRM] < 0 )
|
||||
{
|
||||
setErrorLevel( PHYS_LEN_PRM, TRANSLINE_ERROR );
|
||||
}
|
||||
if( !std::isfinite( m_parameters[PHYS_WIDTH_PRM] ) || m_parameters[PHYS_WIDTH_PRM] < 0 )
|
||||
{
|
||||
setErrorLevel( PHYS_WIDTH_PRM, TRANSLINE_ERROR );
|
||||
}
|
||||
|
||||
if( !std::isfinite( m_parameters[Z0_PRM] ) || m_parameters[Z0_PRM] < 0 )
|
||||
{
|
||||
setErrorLevel( Z0_PRM, TRANSLINE_WARNING );
|
||||
}
|
||||
if( !std::isfinite( m_parameters[ANG_L_PRM] ) || m_parameters[ANG_L_PRM] < 0 )
|
||||
{
|
||||
setErrorLevel( ANG_L_PRM, TRANSLINE_WARNING );
|
||||
}
|
||||
|
||||
if( m_parameters[STRIPLINE_A_PRM] + m_parameters[T_PRM] >= m_parameters[H_PRM] )
|
||||
{
|
||||
setErrorLevel( STRIPLINE_A_PRM, TRANSLINE_WARNING );
|
||||
setErrorLevel( T_PRM, TRANSLINE_WARNING );
|
||||
setErrorLevel( H_PRM, TRANSLINE_WARNING );
|
||||
setErrorLevel( PHYS_WIDTH_PRM, TRANSLINE_ERROR );
|
||||
}
|
||||
}
|
||||
// -------------------------------------------------------------------
|
||||
void STRIPLINE::show_results()
|
||||
{
|
||||
setProperty( Z0_PRM, Z0 );
|
||||
setProperty( ANG_L_PRM, ang_l );
|
||||
|
||||
setResult( 0, er_eff, "" );
|
||||
setResult( 1, atten_cond, "dB" );
|
||||
setResult( 2, atten_dielectric, "dB" );
|
||||
setResult( 0, m_parameters[EPSILON_EFF_PRM], "" );
|
||||
setResult( 1, m_parameters[LOSS_CONDUCTOR_PRM], "dB" );
|
||||
setResult( 2, m_parameters[LOSS_DIELECTRIC_PRM], "dB" );
|
||||
|
||||
setResult( 3, m_skindepth / UNIT_MICRON, "µm" );
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
void STRIPLINE::analyze()
|
||||
{
|
||||
getProperties();
|
||||
calc();
|
||||
show_results();
|
||||
setResult( 3, m_parameters[SKIN_DEPTH_PRM] / UNIT_MICRON, "µm" );
|
||||
}
|
||||
|
||||
|
||||
#define MAX_ERROR 0.000001
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
void STRIPLINE::synthesize()
|
||||
void STRIPLINE::calcSynthesize()
|
||||
{
|
||||
double Z0_dest, Z0_current, Z0_result, increment, slope, error;
|
||||
int iteration;
|
||||
|
||||
getProperties();
|
||||
|
||||
/* required value of Z0 */
|
||||
Z0_dest = Z0;
|
||||
|
||||
/* Newton's method */
|
||||
iteration = 0;
|
||||
|
||||
/* compute parameters */
|
||||
calc();
|
||||
Z0_current = Z0;
|
||||
|
||||
error = fabs( Z0_dest - Z0_current );
|
||||
|
||||
while( error > MAX_ERROR )
|
||||
{
|
||||
iteration++;
|
||||
increment = w / 100.0;
|
||||
w += increment;
|
||||
/* compute parameters */
|
||||
calc();
|
||||
Z0_result = Z0;
|
||||
/* f(w(n)) = Z0 - Z0(w(n)) */
|
||||
/* f'(w(n)) = -f'(Z0(w(n))) */
|
||||
/* f'(Z0(w(n))) = (Z0(w(n)) - Z0(w(n+delw))/delw */
|
||||
/* w(n+1) = w(n) - f(w(n))/f'(w(n)) */
|
||||
slope = (Z0_result - Z0_current) / increment;
|
||||
slope = (Z0_dest - Z0_current) / slope - increment;
|
||||
w += slope;
|
||||
if( w <= 0.0 )
|
||||
w = increment;
|
||||
/* find new error */
|
||||
/* compute parameters */
|
||||
calc();
|
||||
Z0_current = Z0;
|
||||
error = fabs( Z0_dest - Z0_current );
|
||||
if( iteration > 100 )
|
||||
break;
|
||||
}
|
||||
|
||||
setProperty( PHYS_WIDTH_PRM, w );
|
||||
/* calculate physical length */
|
||||
ang_l = getProperty( ANG_L_PRM );
|
||||
len = C0 / m_freq / sqrt( er_eff ) * ang_l / 2.0 / M_PI; /* in m */
|
||||
setProperty( PHYS_LEN_PRM, len );
|
||||
|
||||
/* compute parameters */
|
||||
calc();
|
||||
|
||||
/* print results in the subwindow */
|
||||
show_results();
|
||||
minimizeZ0Error1D( &( m_parameters[PHYS_WIDTH_PRM] ) );
|
||||
}
|
||||
|
|
|
@ -24,31 +24,21 @@
|
|||
#ifndef __STRIPLINE_H
|
||||
#define __STRIPLINE_H
|
||||
|
||||
|
||||
#include <transline.h>
|
||||
|
||||
class STRIPLINE : public TRANSLINE
|
||||
{
|
||||
public: STRIPLINE();
|
||||
|
||||
private:
|
||||
double h; // height of substrate
|
||||
double a; // distance of strip to top metal
|
||||
double t; // thickness of top metal
|
||||
double w; // width of line
|
||||
double len; // length of line
|
||||
double Z0; // characteristic impedance
|
||||
double ang_l; // electrical length in angle
|
||||
double er_eff; // effective dielectric constant
|
||||
double atten_dielectric; // loss in dielectric (dB)
|
||||
double atten_cond; // loss in conductors (dB)
|
||||
|
||||
public:
|
||||
void analyze() override;
|
||||
void synthesize() override;
|
||||
STRIPLINE();
|
||||
|
||||
private:
|
||||
void calcAnalyze() override;
|
||||
void calcSynthesize() override;
|
||||
void showSynthesize() override;
|
||||
void showAnalyze() override;
|
||||
double lineImpedance( double, double& );
|
||||
void calc();
|
||||
void show_results();
|
||||
void getProperties();
|
||||
void show_results() override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
|
||||
/*
|
||||
* TRANSLINE.cpp - base for a transmission line implementation
|
||||
*
|
||||
|
@ -33,7 +34,7 @@
|
|||
|
||||
|
||||
#ifndef M_PI_2
|
||||
#define M_PI_2 (M_PI/2)
|
||||
#define M_PI_2 ( M_PI / 2 )
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -57,19 +58,20 @@ double GetPropertyInDialog( enum PRMS_ID aPrmId );
|
|||
// Has meaning only for params that have a radio button
|
||||
bool IsSelectedInDialog( enum PRMS_ID aPrmId );
|
||||
|
||||
/** Function SetPropertyBgColorInDialog
|
||||
* Set the background color of a parameter
|
||||
* @param aPrmId = param id to set
|
||||
* @param aCol = new color
|
||||
*/
|
||||
void SetPropertyBgColorInDialog( enum PRMS_ID aPrmId, const KIGFX::COLOR4D* aCol );
|
||||
|
||||
|
||||
/* Constructor creates a transmission line instance. */
|
||||
TRANSLINE::TRANSLINE()
|
||||
{
|
||||
m_murC = 1.0;
|
||||
m_parameters[MURC_PRM] = 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
|
||||
Init();
|
||||
}
|
||||
|
||||
|
||||
|
@ -79,6 +81,22 @@ TRANSLINE::~TRANSLINE()
|
|||
}
|
||||
|
||||
|
||||
void TRANSLINE::Init( void )
|
||||
{
|
||||
wxColour wxcol = wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW );
|
||||
okCol = KIGFX::COLOR4D( wxcol );
|
||||
okCol.r = wxcol.Red() / 255.0;
|
||||
okCol.g = wxcol.Green() / 255.0;
|
||||
okCol.b = wxcol.Blue() / 255.0;
|
||||
int i;
|
||||
// Initialize these variables mainly to avoid warnings from a static analyzer
|
||||
for( i = 0; i < EXTRA_PRMS_COUNT; ++i )
|
||||
{
|
||||
m_parameters[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Sets a named property to the given value, access through the
|
||||
* application.
|
||||
*/
|
||||
|
@ -87,6 +105,7 @@ 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
|
||||
|
@ -115,14 +134,101 @@ double TRANSLINE::getProperty( enum PRMS_ID aPrmId )
|
|||
return GetPropertyInDialog( aPrmId );
|
||||
}
|
||||
|
||||
/*
|
||||
* skin_depth - calculate skin depth
|
||||
/** @function getProperties
|
||||
*
|
||||
* Get all properties from the UI. Computes some extra ones.
|
||||
**/
|
||||
void TRANSLINE::getProperties( void )
|
||||
{
|
||||
int i;
|
||||
for( i = 0; i < DUMMY_PRM; ++i )
|
||||
{
|
||||
m_parameters[i] = getProperty( (PRMS_ID) i );
|
||||
setErrorLevel( (PRMS_ID) i, TRANSLINE_OK );
|
||||
}
|
||||
m_parameters[SIGMA_PRM] = 1.0 / getProperty( RHO_PRM );
|
||||
m_parameters[EPSILON_EFF_PRM] = 1.0;
|
||||
m_parameters[SKIN_DEPTH_PRM] = skin_depth();
|
||||
}
|
||||
/** @function checkProperties
|
||||
*
|
||||
* Checks the input parameters (ie: negative length).
|
||||
* Does not check for incompatibility between values as this depends on the line shape.
|
||||
**/
|
||||
void TRANSLINE::checkProperties( void )
|
||||
{
|
||||
// Do not check for values that are results of anylzing / synthesizing
|
||||
// Do not check for transline specific incompatibilities ( like " conductor height sould be lesser than dielectric height")
|
||||
if( !std::isfinite( m_parameters[EPSILONR_PRM] ) || m_parameters[EPSILONR_PRM] <= 0 )
|
||||
setErrorLevel( EPSILONR_PRM, TRANSLINE_WARNING );
|
||||
|
||||
if( !std::isfinite( m_parameters[TAND_PRM] ) || m_parameters[TAND_PRM] < 0 )
|
||||
setErrorLevel( TAND_PRM, TRANSLINE_WARNING );
|
||||
|
||||
if( !std::isfinite( m_parameters[RHO_PRM] ) || m_parameters[RHO_PRM] < 0 )
|
||||
setErrorLevel( RHO_PRM, TRANSLINE_WARNING );
|
||||
|
||||
if( !std::isfinite( m_parameters[H_PRM] ) || m_parameters[H_PRM] < 0 )
|
||||
setErrorLevel( H_PRM, TRANSLINE_WARNING );
|
||||
|
||||
if( !std::isfinite( m_parameters[TWISTEDPAIR_TWIST_PRM] )
|
||||
|| m_parameters[TWISTEDPAIR_TWIST_PRM] < 0 )
|
||||
setErrorLevel( TWISTEDPAIR_TWIST_PRM, TRANSLINE_WARNING );
|
||||
|
||||
if( !std::isfinite( m_parameters[STRIPLINE_A_PRM] ) || m_parameters[STRIPLINE_A_PRM] <= 0 )
|
||||
setErrorLevel( STRIPLINE_A_PRM, TRANSLINE_WARNING );
|
||||
|
||||
if( !std::isfinite( m_parameters[H_T_PRM] ) || m_parameters[H_T_PRM] <= 0 )
|
||||
setErrorLevel( H_T_PRM, TRANSLINE_WARNING );
|
||||
|
||||
// How can we check ROUGH_PRM ?
|
||||
|
||||
if( !std::isfinite( m_parameters[MUR_PRM] ) || m_parameters[MUR_PRM] < 0 )
|
||||
setErrorLevel( MUR_PRM, TRANSLINE_WARNING );
|
||||
|
||||
if( !std::isfinite( m_parameters[TWISTEDPAIR_EPSILONR_ENV_PRM] )
|
||||
|| m_parameters[TWISTEDPAIR_EPSILONR_ENV_PRM] <= 0 )
|
||||
setErrorLevel( TWISTEDPAIR_EPSILONR_ENV_PRM, TRANSLINE_WARNING );
|
||||
|
||||
if( !std::isfinite( m_parameters[MURC_PRM] ) || m_parameters[MURC_PRM] < 0 )
|
||||
setErrorLevel( MURC_PRM, TRANSLINE_WARNING );
|
||||
|
||||
if( !std::isfinite( m_parameters[FREQUENCY_PRM] ) || m_parameters[FREQUENCY_PRM] <= 0 )
|
||||
setErrorLevel( FREQUENCY_PRM, TRANSLINE_WARNING );
|
||||
}
|
||||
|
||||
void TRANSLINE::analyze()
|
||||
{
|
||||
getProperties();
|
||||
checkProperties();
|
||||
calcAnalyze();
|
||||
showAnalyze();
|
||||
show_results();
|
||||
}
|
||||
|
||||
void TRANSLINE::synthesize()
|
||||
{
|
||||
getProperties();
|
||||
checkProperties();
|
||||
calcSynthesize();
|
||||
showSynthesize();
|
||||
show_results();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @function skin_depth
|
||||
* calculate skin depth
|
||||
*
|
||||
* \f$ \frac{1}{\sqrt{ \pi \cdot f \cdot \mu \cdot \sigma }} \f$
|
||||
*/
|
||||
#include <cstdio>
|
||||
double TRANSLINE::skin_depth()
|
||||
{
|
||||
double depth;
|
||||
depth = 1.0 / sqrt( M_PI * m_freq * m_murC * MU0 * m_sigma );
|
||||
depth = 1.0
|
||||
/ sqrt( M_PI * m_parameters[FREQUENCY_PRM] * m_parameters[MURC_PRM] * MU0
|
||||
* m_parameters[SIGMA_PRM] );
|
||||
return depth;
|
||||
}
|
||||
|
||||
|
@ -161,7 +267,7 @@ void TRANSLINE::ellipke( double arg, double& k, double& e )
|
|||
{
|
||||
fk = 1 / sqrt( 1 - arg );
|
||||
fe = sqrt( 1 - arg );
|
||||
da = -arg / (1 - arg);
|
||||
da = -arg / ( 1 - arg );
|
||||
}
|
||||
a = 1;
|
||||
b = sqrt( 1 - da );
|
||||
|
@ -170,8 +276,8 @@ void TRANSLINE::ellipke( double arg, double& k, double& e )
|
|||
s = fr * c * c;
|
||||
for( i = 0; i < iMax; i++ )
|
||||
{
|
||||
t = (a + b) / 2;
|
||||
c = (a - b) / 2;
|
||||
t = ( a + b ) / 2;
|
||||
c = ( a - b ) / 2;
|
||||
b = sqrt( a * b );
|
||||
a = t;
|
||||
fr *= 2;
|
||||
|
@ -182,12 +288,13 @@ void TRANSLINE::ellipke( double arg, double& k, double& e )
|
|||
|
||||
if( i >= iMax )
|
||||
{
|
||||
k = 0; e = 0;
|
||||
k = 0;
|
||||
e = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
k = M_PI_2 / a;
|
||||
e = M_PI_2 * (1 - s) / a;
|
||||
e = M_PI_2 * ( 1 - s ) / a;
|
||||
if( arg < 0 )
|
||||
{
|
||||
k *= fk;
|
||||
|
@ -206,3 +313,122 @@ double TRANSLINE::ellipk( double k )
|
|||
ellipke( k, r, lost );
|
||||
return r;
|
||||
}
|
||||
|
||||
#define MAX_ERROR 0.000001
|
||||
|
||||
/**
|
||||
* @function minimizeZ0Error1D
|
||||
*
|
||||
* Tries to find a parameter that minimizes the error ( on Z0 ).
|
||||
* This function only works with a single parameter.
|
||||
* Calls @ref calcAnalyze several times until the error is acceptable.
|
||||
* While the error is unnacceptable, changes slightly the parameter.
|
||||
*
|
||||
* This function does not change Z0 / Angl_L.
|
||||
*
|
||||
* @param avar Parameter to synthesize
|
||||
* @return 'true' if error < MAX_ERROR, else 'false'
|
||||
*/
|
||||
|
||||
|
||||
bool TRANSLINE::minimizeZ0Error1D( double* aVar )
|
||||
{
|
||||
double Z0_dest, Z0_current, Z0_result, angl_l_dest, increment, slope, error;
|
||||
int iteration;
|
||||
|
||||
if( !std::isfinite( m_parameters[Z0_PRM] ) )
|
||||
{
|
||||
*aVar = NAN;
|
||||
return false;
|
||||
}
|
||||
|
||||
if( ( !std::isfinite( *aVar ) ) || ( *aVar == 0 ) )
|
||||
{
|
||||
*aVar = 0.001;
|
||||
}
|
||||
|
||||
/* required value of Z0 */
|
||||
Z0_dest = m_parameters[Z0_PRM];
|
||||
|
||||
/* required value of angl_l */
|
||||
angl_l_dest = m_parameters[ANG_L_PRM];
|
||||
|
||||
/* Newton's method */
|
||||
iteration = 0;
|
||||
|
||||
/* compute parameters */
|
||||
calcAnalyze();
|
||||
Z0_current = m_parameters[Z0_PRM];
|
||||
|
||||
error = fabs( Z0_dest - Z0_current );
|
||||
|
||||
while( error > MAX_ERROR )
|
||||
{
|
||||
iteration++;
|
||||
increment = *aVar / 100.0;
|
||||
*aVar += increment;
|
||||
/* compute parameters */
|
||||
calcAnalyze();
|
||||
Z0_result = m_parameters[Z0_PRM];
|
||||
/* f(w(n)) = Z0 - Z0(w(n)) */
|
||||
/* f'(w(n)) = -f'(Z0(w(n))) */
|
||||
/* f'(Z0(w(n))) = (Z0(w(n)) - Z0(w(n+delw))/delw */
|
||||
/* w(n+1) = w(n) - f(w(n))/f'(w(n)) */
|
||||
slope = ( Z0_result - Z0_current ) / increment;
|
||||
slope = ( Z0_dest - Z0_current ) / slope - increment;
|
||||
*aVar += slope;
|
||||
if( *aVar <= 0.0 )
|
||||
*aVar = increment;
|
||||
/* find new error */
|
||||
/* compute parameters */
|
||||
calcAnalyze();
|
||||
Z0_current = m_parameters[Z0_PRM];
|
||||
error = fabs( Z0_dest - Z0_current );
|
||||
|
||||
if( iteration > 100 )
|
||||
break;
|
||||
}
|
||||
|
||||
/* Compute one last time, but with correct length */
|
||||
m_parameters[Z0_PRM] = Z0_dest;
|
||||
m_parameters[ANG_L_PRM] = angl_l_dest;
|
||||
m_parameters[PHYS_LEN_PRM] = C0 / m_parameters[FREQUENCY_PRM]
|
||||
/ sqrt( m_parameters[EPSILON_EFF_PRM] ) * m_parameters[ANG_L_PRM]
|
||||
/ 2.0 / M_PI; /* in m */
|
||||
calcAnalyze();
|
||||
|
||||
/* Restore parameters */
|
||||
m_parameters[Z0_PRM] = Z0_dest;
|
||||
m_parameters[ANG_L_PRM] = angl_l_dest;
|
||||
m_parameters[PHYS_LEN_PRM] = C0 / m_parameters[FREQUENCY_PRM]
|
||||
/ sqrt( m_parameters[EPSILON_EFF_PRM] ) * m_parameters[ANG_L_PRM]
|
||||
/ 2.0 / M_PI; /* in m */
|
||||
return error <= MAX_ERROR;
|
||||
}
|
||||
/**
|
||||
* @function setErrorLevel
|
||||
*
|
||||
* set an error / warning level for a given parameter.
|
||||
*
|
||||
* @see TRANSLINE_OK
|
||||
* @see TRANSLINE_WARNING
|
||||
* @see TRANSLINE_ERROR
|
||||
*
|
||||
* @param aP parameter
|
||||
* @param aErrorLevel Error level
|
||||
*/
|
||||
void TRANSLINE::setErrorLevel( PRMS_ID aP, char aErrorLevel )
|
||||
{
|
||||
switch( aErrorLevel )
|
||||
{
|
||||
case( TRANSLINE_WARNING ):
|
||||
SetPropertyBgColorInDialog( aP, &warnCol );
|
||||
break;
|
||||
case( TRANSLINE_ERROR ):
|
||||
SetPropertyBgColorInDialog( aP, &errCol );
|
||||
break;
|
||||
default:
|
||||
SetPropertyBgColorInDialog( aP, &okCol );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,63 +24,109 @@
|
|||
#ifndef __TRANSLINE_H
|
||||
#define __TRANSLINE_H
|
||||
|
||||
#include <gal/color4d.h>
|
||||
#include <wx/wx.h>
|
||||
|
||||
#define TRANSLINE_OK 0
|
||||
#define TRANSLINE_WARNING 1
|
||||
#define TRANSLINE_ERROR 2
|
||||
|
||||
// IDs for lines parameters used in calculation:
|
||||
// (Used to retrieve these parameters from UI.
|
||||
// DUMMY_PRM is used to skip a param line in dialogs. It is not really a parameter
|
||||
enum PRMS_ID
|
||||
{
|
||||
UNKNOWN_ID = 0,
|
||||
EPSILONR_PRM,
|
||||
TAND_PRM,
|
||||
RHO_PRM,
|
||||
H_PRM,
|
||||
TWISTEDPAIR_TWIST_PRM,
|
||||
UNKNOWN_ID = -1,
|
||||
EPSILONR_PRM, // dielectric constant
|
||||
TAND_PRM, // Dielectric Loss Tangent
|
||||
RHO_PRM, // Conductivity of conductor
|
||||
H_PRM, // height of substrate
|
||||
TWISTEDPAIR_TWIST_PRM, // Twists per length
|
||||
H_T_PRM,
|
||||
STRIPLINE_A_PRM,
|
||||
T_PRM,
|
||||
STRIPLINE_A_PRM, // Stripline : distance from line to top metal
|
||||
T_PRM, // thickness of top metal
|
||||
ROUGH_PRM,
|
||||
MUR_PRM,
|
||||
MUR_PRM, // magnetic permeability of substrate
|
||||
TWISTEDPAIR_EPSILONR_ENV_PRM,
|
||||
MURC_PRM,
|
||||
FREQUENCY_PRM,
|
||||
Z0_PRM,
|
||||
MURC_PRM, // magnetic permeability of conductor
|
||||
FREQUENCY_PRM, // Frequency of operation
|
||||
Z0_PRM, // characteristic impedance
|
||||
Z0_E_PRM,
|
||||
Z0_O_PRM,
|
||||
ANG_L_PRM,
|
||||
ANG_L_PRM, // Electrical length in angle
|
||||
PHYS_WIDTH_PRM,
|
||||
PHYS_DIAM_IN_PRM,
|
||||
PHYS_S_PRM,
|
||||
PHYS_DIAM_OUT_PRM,
|
||||
PHYS_LEN_PRM,
|
||||
PHYS_DIAM_IN_PRM, // Inner diameter of cable
|
||||
PHYS_S_PRM, // width of gap between line and ground
|
||||
PHYS_DIAM_OUT_PRM, // Outer diameter of cable
|
||||
PHYS_LEN_PRM, // Length of cable
|
||||
DUMMY_PRM
|
||||
};
|
||||
|
||||
|
||||
// IDs for lines parameters used in calculation that are not given by the UI
|
||||
enum EXTRA_PRMS_ID
|
||||
{
|
||||
EXTRA_PRMS_START = DUMMY_PRM - 1,
|
||||
SIGMA_PRM, // Conductivity of the metal
|
||||
SKIN_DEPTH_PRM, // Skin depth
|
||||
LOSS_DIELECTRIC_PRM, // Loss in dielectric (dB)
|
||||
LOSS_CONDUCTOR_PRM, // Loss in conductors (dB)
|
||||
CUTOFF_FREQUENCY_PRM, // Cutoff frequency for higher order modes
|
||||
EPSILON_EFF_PRM, // Effective dielectric constant
|
||||
EXTRA_PRMS_COUNT,
|
||||
};
|
||||
|
||||
class TRANSLINE
|
||||
{
|
||||
public: TRANSLINE();
|
||||
public:
|
||||
TRANSLINE();
|
||||
virtual ~TRANSLINE();
|
||||
|
||||
const char *m_Name;
|
||||
void setProperty( enum PRMS_ID aPrmId, double aValue);
|
||||
const char* m_Name;
|
||||
void setProperty( enum PRMS_ID aPrmId, double aValue );
|
||||
double getProperty( enum PRMS_ID aPrmId );
|
||||
|
||||
|
||||
void getProperties( void );
|
||||
void checkProperties( void );
|
||||
void setResult( int, double, const char* );
|
||||
void setResult( int, const char* );
|
||||
bool isSelected( enum PRMS_ID aPrmId );
|
||||
|
||||
virtual void synthesize() { };
|
||||
virtual void analyze() { };
|
||||
void Init();
|
||||
virtual void synthesize();
|
||||
virtual void calc(){};
|
||||
/** @brief Computation for analysis
|
||||
*/
|
||||
virtual void calcAnalyze(){};
|
||||
/** @brief Computation for synthesis
|
||||
**/
|
||||
virtual void calcSynthesize(){};
|
||||
/** @brief Shows synthesis results and checks for errors / warnings.
|
||||
**/
|
||||
virtual void showAnalyze(){};
|
||||
/** @brief Shows analysis results and checks for errors / warnings.
|
||||
**/
|
||||
virtual void showSynthesize(){};
|
||||
/** @brief Shows results
|
||||
**/
|
||||
virtual void show_results(){};
|
||||
void analyze();
|
||||
KIGFX::COLOR4D errCol = KIGFX::COLOR4D( 1, 0.63, 0.63, 1 );
|
||||
KIGFX::COLOR4D warnCol = KIGFX::COLOR4D( 1, 1, 0.57, 1 );
|
||||
KIGFX::COLOR4D okCol = KIGFX::COLOR4D( 1, 1, 1, 1 );
|
||||
|
||||
protected:
|
||||
double m_freq; // Frequency of operation
|
||||
double er; /* dielectric constant */
|
||||
double m_tand; // Dielectric Loss Tangent
|
||||
double m_sigma; // Conductivity of the metal
|
||||
double m_murC; // magnetic permeability of conductor
|
||||
double m_skindepth; // Skin depth
|
||||
double m_parameters[EXTRA_PRMS_COUNT];
|
||||
double len; // length of line
|
||||
double er_eff; // effective dielectric constant
|
||||
double ang_l; // Electrical length in angle
|
||||
|
||||
bool minimizeZ0Error1D( double* );
|
||||
double skin_depth();
|
||||
void ellipke( double, double&, double& );
|
||||
double ellipk( double );
|
||||
void setErrorLevel( PRMS_ID, char );
|
||||
};
|
||||
|
||||
#endif /* __TRANSLINE_H */
|
||||
|
|
|
@ -27,159 +27,181 @@
|
|||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
#include <units.h>
|
||||
#include <transline.h>
|
||||
#include <twistedpair.h>
|
||||
#include <units.h>
|
||||
|
||||
TWISTEDPAIR::TWISTEDPAIR() : TRANSLINE()
|
||||
{
|
||||
m_Name = "TwistedPair";
|
||||
|
||||
// Initialize these variables mainly to avoid warnings from a static analyzer
|
||||
din = 0.0; // Inner diameter of conductor
|
||||
dout = 0.0; // Outer diameter of insulator
|
||||
twists = 0.0; // Twists per length
|
||||
er_env = 0.0; // dielectric constant of environment*/
|
||||
len = 0.0; // Length of cable
|
||||
Z0 = 0.0; // characteristic impedance
|
||||
ang_l = 0.0; // Electrical length in angle
|
||||
atten_dielectric = 0.0; // Loss in dielectric (dB)
|
||||
atten_cond = 0.0; // Loss in conductors (dB)
|
||||
er_eff = 1.0; // Effective dielectric constant
|
||||
Init();
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
void TWISTEDPAIR::getProperties()
|
||||
/**
|
||||
* \f$ \theta = \arctan\left( T \cdot \pi \cdot D_{out} \right) \f$
|
||||
*
|
||||
* Where :
|
||||
* - \f$ \theta \f$ : pitch angle
|
||||
* - \f$ T \f$ : Number of twists per unit length
|
||||
* - \f$ D_{out} \f$ : Wire diameter with insulation
|
||||
*
|
||||
* \f$ e_{eff} = e_{env} \cdot \left( 0.25 + 0.0007 \cdot \theta^2 \right)\cdot\left(e_r-e_{env}\right) \f$
|
||||
*
|
||||
* Where :
|
||||
* - \f$ e_{env} \f$ : relative dielectric constant of air ( or some other surronding material ),
|
||||
* - \f$ e_r \f$ : relative dielectric constant of the film insulation,
|
||||
* - \f$ e_{eff} \f$ : effective relative dielectric constant
|
||||
*
|
||||
* \f$ Z_0 = \frac{Z_\mathrm{VACCUM}}{\pi \cdot \sqrt{e_{eff}}}\cosh^{-1}\left(\frac{D_{out}}{D_{in}}\right) \f$
|
||||
*
|
||||
* - \f$ Z_0 \f$ : line impedance
|
||||
* - \f$ Z_\mathrm{VACCUM} \f$ : vaccum impedance
|
||||
* - \f$ D_{in} \f$ : Wire diameter without insulation
|
||||
*
|
||||
* Reference for above equations :
|
||||
*
|
||||
* [1] : P. Lefferson, ``Twisted Magnet Wire Transmission Line,''
|
||||
* IEEE Transactions on Parts, Hybrids, and Packaging, vol. PHP-7, no. 4, pp. 148-154, Dec. 1971.
|
||||
*
|
||||
* The following URL can be used as reference : http://qucs.sourceforge.net/tech/node93.html
|
||||
**/
|
||||
void TWISTEDPAIR::calcAnalyze()
|
||||
{
|
||||
m_freq = getProperty( FREQUENCY_PRM );
|
||||
din = getProperty( PHYS_DIAM_IN_PRM );
|
||||
dout = getProperty( PHYS_DIAM_OUT_PRM );
|
||||
len = getProperty( PHYS_LEN_PRM );
|
||||
|
||||
er = getProperty( EPSILONR_PRM );
|
||||
m_murC = getProperty( MURC_PRM );
|
||||
m_tand = getProperty( TAND_PRM );
|
||||
m_sigma = 1.0 / getProperty( RHO_PRM );
|
||||
twists = getProperty( TWISTEDPAIR_TWIST_PRM );
|
||||
er_env = getProperty( TWISTEDPAIR_EPSILONR_ENV_PRM );
|
||||
Z0 = getProperty( Z0_PRM );
|
||||
ang_l = getProperty( ANG_L_PRM );
|
||||
}
|
||||
double tw = atan( m_parameters[TWISTEDPAIR_TWIST_PRM] * M_PI
|
||||
* m_parameters[PHYS_DIAM_OUT_PRM] ); // pitch angle
|
||||
m_parameters[EPSILON_EFF_PRM] =
|
||||
m_parameters[TWISTEDPAIR_EPSILONR_ENV_PRM]
|
||||
+ ( 0.25 + 0.0007 * tw * tw )
|
||||
* ( m_parameters[EPSILONR_PRM] - m_parameters[TWISTEDPAIR_EPSILONR_ENV_PRM] );
|
||||
|
||||
m_parameters[Z0_PRM] =
|
||||
ZF0 / M_PI / sqrt( m_parameters[EPSILON_EFF_PRM] )
|
||||
* acosh( m_parameters[PHYS_DIAM_OUT_PRM] / m_parameters[PHYS_DIAM_IN_PRM] );
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
void TWISTEDPAIR::calc()
|
||||
{
|
||||
m_skindepth = skin_depth();
|
||||
m_parameters[LOSS_CONDUCTOR_PRM] =
|
||||
10.0 / log( 10.0 ) * m_parameters[PHYS_LEN_PRM] / m_parameters[SKIN_DEPTH_PRM]
|
||||
/ m_parameters[SIGMA_PRM] / M_PI / m_parameters[Z0_PRM]
|
||||
/ ( m_parameters[PHYS_DIAM_IN_PRM] - m_parameters[SKIN_DEPTH_PRM] );
|
||||
|
||||
double tw = atan( twists * M_PI * dout ); // pitch angle
|
||||
er_eff = er_env + (0.25 + 0.0007 * tw * tw) * (er - er_env);
|
||||
m_parameters[LOSS_DIELECTRIC_PRM] = 20.0 / log( 10.0 ) * m_parameters[PHYS_LEN_PRM] * M_PI / C0
|
||||
* m_parameters[FREQUENCY_PRM]
|
||||
* sqrt( m_parameters[EPSILON_EFF_PRM] )
|
||||
* m_parameters[TAND_PRM];
|
||||
|
||||
Z0 = ZF0 / M_PI / sqrt( er_eff ) * acosh( dout / din );
|
||||
|
||||
atten_cond = 10.0 / log( 10.0 ) * len / m_skindepth / m_sigma / M_PI / Z0 / (din - m_skindepth);
|
||||
|
||||
atten_dielectric = 20.0 / log( 10.0 ) * len * M_PI / C0* m_freq * sqrt( er_eff ) * m_tand;
|
||||
|
||||
ang_l = 2.0* M_PI* len* sqrt( er_eff ) * m_freq / C0; // in radians
|
||||
m_parameters[ANG_L_PRM] = 2.0 * M_PI * m_parameters[PHYS_LEN_PRM]
|
||||
* sqrt( m_parameters[EPSILON_EFF_PRM] ) * m_parameters[FREQUENCY_PRM]
|
||||
/ C0; // in radians
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
void TWISTEDPAIR::show_results()
|
||||
{
|
||||
setProperty( Z0_PRM, Z0 );
|
||||
setProperty( ANG_L_PRM, ang_l );
|
||||
|
||||
setResult( 0, er_eff, "" );
|
||||
setResult( 1, atten_cond, "dB" );
|
||||
setResult( 2, atten_dielectric, "dB" );
|
||||
|
||||
setResult( 3, m_skindepth / UNIT_MICRON, "µm" );
|
||||
setResult( 0, m_parameters[EPSILON_EFF_PRM], "" );
|
||||
setResult( 1, m_parameters[LOSS_CONDUCTOR_PRM], "dB" );
|
||||
setResult( 2, m_parameters[LOSS_DIELECTRIC_PRM], "dB" );
|
||||
setResult( 3, m_parameters[SKIN_DEPTH_PRM] / UNIT_MICRON, "µm" );
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
void TWISTEDPAIR::analyze()
|
||||
void TWISTEDPAIR::showAnalyze()
|
||||
{
|
||||
getProperties();
|
||||
calc();
|
||||
show_results();
|
||||
setProperty( Z0_PRM, m_parameters[Z0_PRM] );
|
||||
setProperty( ANG_L_PRM, m_parameters[ANG_L_PRM] );
|
||||
|
||||
// Check for errors
|
||||
if( !std::isfinite( m_parameters[Z0_PRM] ) || m_parameters[Z0_PRM] < 0 )
|
||||
{
|
||||
setErrorLevel( Z0_PRM, TRANSLINE_ERROR );
|
||||
}
|
||||
|
||||
if( !std::isfinite( m_parameters[ANG_L_PRM] ) || m_parameters[ANG_L_PRM] < 0 )
|
||||
{
|
||||
setErrorLevel( ANG_L_PRM, TRANSLINE_ERROR );
|
||||
}
|
||||
|
||||
// Find warnings to display - physical parameters
|
||||
if( !std::isfinite( m_parameters[PHYS_DIAM_IN_PRM] ) || m_parameters[PHYS_DIAM_IN_PRM] <= 0.0 )
|
||||
{
|
||||
setErrorLevel( PHYS_DIAM_IN_PRM, TRANSLINE_WARNING );
|
||||
}
|
||||
|
||||
if( !std::isfinite( m_parameters[PHYS_DIAM_OUT_PRM] )
|
||||
|| m_parameters[PHYS_DIAM_OUT_PRM] <= 0.0 )
|
||||
{
|
||||
setErrorLevel( PHYS_DIAM_OUT_PRM, TRANSLINE_WARNING );
|
||||
}
|
||||
|
||||
if( m_parameters[PHYS_DIAM_IN_PRM] > m_parameters[PHYS_DIAM_OUT_PRM] )
|
||||
{
|
||||
setErrorLevel( PHYS_DIAM_IN_PRM, TRANSLINE_WARNING );
|
||||
setErrorLevel( PHYS_DIAM_OUT_PRM, TRANSLINE_WARNING );
|
||||
}
|
||||
|
||||
if( !std::isfinite( m_parameters[PHYS_LEN_PRM] ) || m_parameters[PHYS_LEN_PRM] < 0.0 )
|
||||
{
|
||||
setErrorLevel( PHYS_LEN_PRM, TRANSLINE_WARNING );
|
||||
}
|
||||
}
|
||||
|
||||
void TWISTEDPAIR::showSynthesize()
|
||||
{
|
||||
if( isSelected( PHYS_DIAM_IN_PRM ) )
|
||||
setProperty( PHYS_DIAM_IN_PRM, m_parameters[PHYS_DIAM_IN_PRM] );
|
||||
else if( isSelected( PHYS_DIAM_OUT_PRM ) )
|
||||
setProperty( PHYS_DIAM_OUT_PRM, m_parameters[PHYS_DIAM_OUT_PRM] );
|
||||
setProperty( PHYS_LEN_PRM, m_parameters[PHYS_LEN_PRM] );
|
||||
|
||||
// Check for errors
|
||||
if( !std::isfinite( m_parameters[PHYS_DIAM_IN_PRM] ) || m_parameters[PHYS_DIAM_IN_PRM] <= 0.0 )
|
||||
{
|
||||
if( isSelected( PHYS_DIAM_IN_PRM ) )
|
||||
setErrorLevel( PHYS_DIAM_IN_PRM, TRANSLINE_ERROR );
|
||||
else
|
||||
setErrorLevel( PHYS_DIAM_IN_PRM, TRANSLINE_WARNING );
|
||||
}
|
||||
|
||||
if( !std::isfinite( m_parameters[PHYS_DIAM_OUT_PRM] )
|
||||
|| m_parameters[PHYS_DIAM_OUT_PRM] <= 0.0 )
|
||||
{
|
||||
if( isSelected( PHYS_DIAM_OUT_PRM ) )
|
||||
setErrorLevel( PHYS_DIAM_OUT_PRM, TRANSLINE_ERROR );
|
||||
else
|
||||
setErrorLevel( PHYS_DIAM_OUT_PRM, TRANSLINE_WARNING );
|
||||
}
|
||||
|
||||
if( m_parameters[PHYS_DIAM_IN_PRM] > m_parameters[PHYS_DIAM_OUT_PRM] )
|
||||
{
|
||||
if( isSelected( PHYS_DIAM_IN_PRM ) )
|
||||
setErrorLevel( PHYS_DIAM_IN_PRM, TRANSLINE_ERROR );
|
||||
else if( isSelected( PHYS_DIAM_OUT_PRM ) )
|
||||
setErrorLevel( PHYS_DIAM_OUT_PRM, TRANSLINE_ERROR );
|
||||
}
|
||||
|
||||
if( !std::isfinite( m_parameters[PHYS_LEN_PRM] ) || m_parameters[PHYS_LEN_PRM] < 0.0 )
|
||||
{
|
||||
setErrorLevel( PHYS_LEN_PRM, TRANSLINE_ERROR );
|
||||
}
|
||||
// Check for warnings
|
||||
if( !std::isfinite( m_parameters[Z0_PRM] ) || m_parameters[Z0_PRM] < 0 )
|
||||
{
|
||||
setErrorLevel( Z0_PRM, TRANSLINE_WARNING );
|
||||
}
|
||||
|
||||
if( !std::isfinite( m_parameters[ANG_L_PRM] ) || m_parameters[ANG_L_PRM] < 0 )
|
||||
{
|
||||
setErrorLevel( ANG_L_PRM, TRANSLINE_WARNING );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define MAX_ERROR 0.000001
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
void TWISTEDPAIR::synthesize()
|
||||
void TWISTEDPAIR::calcSynthesize()
|
||||
{
|
||||
double Z0_dest, Z0_current, Z0_result, increment, slope, error;
|
||||
int iteration;
|
||||
|
||||
getProperties();
|
||||
|
||||
/* required value of Z0 */
|
||||
Z0_dest = Z0;
|
||||
|
||||
/* Newton's method */
|
||||
iteration = 0;
|
||||
|
||||
/* compute parameters */
|
||||
calc();
|
||||
Z0_current = Z0;
|
||||
|
||||
error = fabs( Z0_dest - Z0_current );
|
||||
|
||||
while( error > MAX_ERROR )
|
||||
{
|
||||
iteration++;
|
||||
if( isSelected( PHYS_DIAM_IN_PRM ) )
|
||||
{
|
||||
increment = din / 100.0;
|
||||
din += increment;
|
||||
}
|
||||
minimizeZ0Error1D( &( m_parameters[PHYS_DIAM_IN_PRM] ) );
|
||||
else
|
||||
{
|
||||
increment = dout / 100.0;
|
||||
dout += increment;
|
||||
}
|
||||
/* compute parameters */
|
||||
calc();
|
||||
Z0_result = Z0;
|
||||
/* f(w(n)) = Z0 - Z0(w(n)) */
|
||||
/* f'(w(n)) = -f'(Z0(w(n))) */
|
||||
/* f'(Z0(w(n))) = (Z0(w(n)) - Z0(w(n+delw))/delw */
|
||||
/* w(n+1) = w(n) - f(w(n))/f'(w(n)) */
|
||||
slope = (Z0_result - Z0_current) / increment;
|
||||
slope = (Z0_dest - Z0_current) / slope - increment;
|
||||
if( isSelected( PHYS_DIAM_IN_PRM ) )
|
||||
din += slope;
|
||||
else
|
||||
dout += slope;
|
||||
if( din <= 0.0 )
|
||||
din = increment;
|
||||
if( dout <= 0.0 )
|
||||
dout = increment;
|
||||
/* find new error */
|
||||
/* compute parameters */
|
||||
calc();
|
||||
Z0_current = Z0;
|
||||
error = fabs( Z0_dest - Z0_current );
|
||||
if( iteration > 100 )
|
||||
break;
|
||||
}
|
||||
|
||||
setProperty( PHYS_DIAM_IN_PRM, din );
|
||||
setProperty( PHYS_DIAM_OUT_PRM, dout );
|
||||
/* calculate physical length */
|
||||
ang_l = getProperty( ANG_L_PRM );
|
||||
len = C0 / m_freq / sqrt( er_eff ) * ang_l / 2.0 / M_PI; /* in m */
|
||||
setProperty( PHYS_LEN_PRM, len );
|
||||
|
||||
/* compute parameters */
|
||||
calc();
|
||||
|
||||
/* print results in the subwindow */
|
||||
show_results();
|
||||
minimizeZ0Error1D( &( m_parameters[PHYS_DIAM_OUT_PRM] ) );
|
||||
}
|
||||
|
|
|
@ -24,30 +24,19 @@
|
|||
#ifndef __TWISTEDPAIR_H
|
||||
#define __TWISTEDPAIR_H
|
||||
|
||||
#include <transline.h>
|
||||
|
||||
class TWISTEDPAIR : public TRANSLINE
|
||||
{
|
||||
public: TWISTEDPAIR();
|
||||
|
||||
private:
|
||||
double din; // Inner diameter of conductor
|
||||
double dout; // Outer diameter of insulator
|
||||
double twists; // Twists per length
|
||||
double er_env; // dielectric constant of environment*/
|
||||
double len; // Length of cable
|
||||
double Z0; // characteristic impedance
|
||||
double ang_l; // Electrical length in angle
|
||||
double er_eff; // Effective dielectric constant
|
||||
double atten_dielectric; // Loss in dielectric (dB)
|
||||
double atten_cond; // Loss in conductors (dB)
|
||||
|
||||
public:
|
||||
void analyze() override;
|
||||
void synthesize() override;
|
||||
TWISTEDPAIR();
|
||||
|
||||
private:
|
||||
void calc();
|
||||
void show_results();
|
||||
void getProperties();
|
||||
void calcAnalyze() override;
|
||||
void calcSynthesize() override;
|
||||
void showAnalyze() override;
|
||||
void showSynthesize() override;
|
||||
void show_results() override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -17,8 +17,9 @@
|
|||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <wx/wx.h>
|
||||
#include <wx/filename.h>
|
||||
#include <wx/settings.h>
|
||||
#include <wx/wx.h>
|
||||
|
||||
#include <pcb_calculator_frame_base.h>
|
||||
|
||||
|
@ -316,7 +317,7 @@ void PCB_CALCULATOR_FRAME::TranslineTypeSelection( enum TRANSLINE_TYPE_ID aType
|
|||
}
|
||||
wxASSERT ( data );
|
||||
data->name->SetToolTip( prm->m_ToolTip );
|
||||
data->name->SetLabel( prm->m_Label );
|
||||
data->name->SetLabel( prm->m_Label != "" ? prm->m_Label + ':' : "" );
|
||||
prm->m_ValueCtrl = data->value;
|
||||
if( prm->m_Id != DUMMY_PRM )
|
||||
{
|
||||
|
@ -436,6 +437,25 @@ void PCB_CALCULATOR_FRAME::OnTranslineSelection( wxCommandEvent& event )
|
|||
// The new size must be taken in account
|
||||
m_panelTransline->GetSizer()->Layout();
|
||||
m_panelTransline->Refresh();
|
||||
// Delete previous warnings / errors
|
||||
wxColour background = wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW );
|
||||
|
||||
m_Value_EpsilonR->SetBackgroundColour( background );
|
||||
m_Value_TanD->SetBackgroundColour( background );
|
||||
m_Value_Rho->SetBackgroundColour( background );
|
||||
m_Substrate_prm4_Value->SetBackgroundColour( background );
|
||||
m_Substrate_prm5_Value->SetBackgroundColour( background );
|
||||
m_Substrate_prm6_Value->SetBackgroundColour( background );
|
||||
m_Substrate_prm7_Value->SetBackgroundColour( background );
|
||||
m_Substrate_prm8_Value->SetBackgroundColour( background );
|
||||
m_Substrate_prm9_Value->SetBackgroundColour( background );
|
||||
m_Value_Frequency_Ctrl->SetBackgroundColour( background );
|
||||
m_Phys_prm1_Value->SetBackgroundColour( background );
|
||||
m_Phys_prm2_Value->SetBackgroundColour( background );
|
||||
m_Phys_prm3_Value->SetBackgroundColour( background );
|
||||
m_elec_prm1_label->SetBackgroundColour( background );
|
||||
m_elec_prm2_label->SetBackgroundColour( background );
|
||||
m_elec_prm3_label->SetBackgroundColour( background );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -107,21 +107,21 @@ TRANSLINE_IDENT::TRANSLINE_IDENT( enum TRANSLINE_TYPE_ID aType )
|
|||
// Add common prms:
|
||||
// Default values are for FR4
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_SUBS, EPSILONR_PRM,
|
||||
_( "Er:" ), _( "Epsilon R: substrate relative dielectric constant" ),
|
||||
_( "Er" ), _( "Epsilon R: substrate relative dielectric constant" ),
|
||||
4.6, false ) );
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_SUBS, TAND_PRM,
|
||||
_( "TanD:" ), _( "Tangent delta: dielectric loss factor." ), 2e-2,
|
||||
_( "TanD" ), _( "Tangent delta: dielectric loss factor." ), 2e-2,
|
||||
false ) );
|
||||
|
||||
// Default value is for copper
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_SUBS, RHO_PRM,
|
||||
_( "Rho:" ),
|
||||
_( "Rho" ),
|
||||
_( "Electrical resistivity or specific electrical resistance of conductor (Ohm*meter)" ),
|
||||
1.72e-8, false ) );
|
||||
|
||||
// Default value is in GHz
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_FREQUENCY, FREQUENCY_PRM,
|
||||
_( "Frequency:" ), _( "Frequency of the input signal" ), 1.0, true ) );
|
||||
_( "Frequency" ), _( "Frequency of the input signal" ), 1.0, true ) );
|
||||
|
||||
|
||||
switch( m_Type )
|
||||
|
@ -136,30 +136,30 @@ TRANSLINE_IDENT::TRANSLINE_IDENT( enum TRANSLINE_TYPE_ID aType )
|
|||
m_Messages.Add( _( "Skin Depth:" ) );
|
||||
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_SUBS, H_PRM,
|
||||
_( "H:" ), _( "Height of Substrate" ), 0.2, true ) );
|
||||
_( "H" ), _( "Height of Substrate" ), 0.2, true ) );
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_SUBS, H_T_PRM,
|
||||
_( "H_t:" ), _( "Height of Box Top" ), 1e20, true ) );
|
||||
_( "H_t" ), _( "Height of Box Top" ), 1e20, true ) );
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_SUBS, T_PRM,
|
||||
_( "T:" ), _( "Strip Thickness" ), 0.035, true ) );
|
||||
_( "T" ), _( "Strip Thickness" ), 0.035, true ) );
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_SUBS, ROUGH_PRM,
|
||||
_( "Rough:" ), _( "Conductor Roughness" ), 0.0, true ) );
|
||||
_( "Rough" ), _( "Conductor Roughness" ), 0.0, true ) );
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_SUBS, MUR_PRM,
|
||||
_( "mu Rel S:" ),
|
||||
_( "mu Rel S" ),
|
||||
_( "Relative Permeability (mu) of Substrate" ), 1, false ) );
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_SUBS, MURC_PRM,
|
||||
_( "mu Rel C:" ), _( "Relative Permeability (mu) of Conductor" ), 1,
|
||||
_( "mu Rel C" ), _( "Relative Permeability (mu) of Conductor" ), 1,
|
||||
false ) );
|
||||
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_PHYS, PHYS_WIDTH_PRM,
|
||||
_( "W:" ), _( "Line Width" ), 0.2, true ) );
|
||||
_( "W" ), _( "Line Width" ), 0.2, true ) );
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_PHYS, PHYS_LEN_PRM,
|
||||
_( "L:" ), _( "Line Length" ), 50.0, true ) );
|
||||
_( "L" ), _( "Line Length" ), 50.0, true ) );
|
||||
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_ELEC, Z0_PRM,
|
||||
_( "Z0:" ), _( "Characteristic Impedance" ), 50.0, true ) );
|
||||
_( "Z0" ), _( "Characteristic Impedance" ), 50.0, true ) );
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_ELEC, DUMMY_PRM ) );
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_ELEC, ANG_L_PRM,
|
||||
_( "Ang_l:" ), _( "Electrical Length" ), 0.0, true ) );
|
||||
_( "Ang_l" ), _( "Electrical Length" ), 0.0, true ) );
|
||||
break;
|
||||
|
||||
case CPW_TYPE: // coplanar waveguide
|
||||
|
@ -173,25 +173,25 @@ TRANSLINE_IDENT::TRANSLINE_IDENT( enum TRANSLINE_TYPE_ID aType )
|
|||
m_Messages.Add( _( "Skin Depth:" ) );
|
||||
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_SUBS, H_PRM,
|
||||
_( "H:" ), _( "Height of Substrate" ), 0.2, true ) );
|
||||
_( "H" ), _( "Height of Substrate" ), 0.2, true ) );
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_SUBS, T_PRM,
|
||||
_( "T:" ), _( "Strip Thickness" ), 0.035, true ) );
|
||||
_( "T" ), _( "Strip Thickness" ), 0.035, true ) );
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_SUBS, MURC_PRM,
|
||||
_( "mu Rel C:" ), _( "Relative Permeability (mu) of Conductor" ), 1,
|
||||
_( "mu Rel C" ), _( "Relative Permeability (mu) of Conductor" ), 1,
|
||||
false ) );
|
||||
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_PHYS, PHYS_WIDTH_PRM,
|
||||
_( "W:" ), _( "Line Width" ), 0.2, true ) );
|
||||
_( "W" ), _( "Line Width" ), 0.2, true ) );
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_PHYS, PHYS_S_PRM,
|
||||
_( "S:" ), _( "Gap Width" ), 0.2, true ) );
|
||||
_( "S" ), _( "Gap Width" ), 0.2, true ) );
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_PHYS, PHYS_LEN_PRM,
|
||||
_( "L:" ), _( "Line Length" ), 50.0, true ) );
|
||||
_( "L" ), _( "Line Length" ), 50.0, true ) );
|
||||
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_ELEC, Z0_PRM,
|
||||
_( "Z0:" ), _( "Characteristic Impedance" ), 50.0, true ) );
|
||||
_( "Z0" ), _( "Characteristic Impedance" ), 50.0, true ) );
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_ELEC, DUMMY_PRM ) );
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_ELEC, ANG_L_PRM,
|
||||
_( "Ang_l:" ), _( "Electrical Length" ), 0.0, true ) );
|
||||
_( "Ang_l" ), _( "Electrical Length" ), 0.0, true ) );
|
||||
break;
|
||||
|
||||
case GROUNDED_CPW_TYPE: // grounded coplanar waveguide
|
||||
|
@ -205,25 +205,25 @@ TRANSLINE_IDENT::TRANSLINE_IDENT( enum TRANSLINE_TYPE_ID aType )
|
|||
m_Messages.Add( _( "Skin Depth:" ) );
|
||||
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_SUBS, H_PRM,
|
||||
_( "H:" ), _( "Height of Substrate" ), 0.2, true ) );
|
||||
_( "H" ), _( "Height of Substrate" ), 0.2, true ) );
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_SUBS, T_PRM,
|
||||
_( "T:" ), _( "Strip Thickness" ), 0.035, true ) );
|
||||
_( "T" ), _( "Strip Thickness" ), 0.035, true ) );
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_SUBS, MURC_PRM,
|
||||
_( "mu Rel C:" ), _( "Relative Permeability (mu) of Conductor" ), 1,
|
||||
_( "mu Rel C" ), _( "Relative Permeability (mu) of Conductor" ), 1,
|
||||
false ) );
|
||||
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_PHYS, PHYS_WIDTH_PRM,
|
||||
_( "W:" ), _( "Line Width" ), 0.2, true ) );
|
||||
_( "W" ), _( "Line Width" ), 0.2, true ) );
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_PHYS, PHYS_S_PRM,
|
||||
_( "S:" ), _( "Gap Width" ), 0.2, true ) );
|
||||
_( "S" ), _( "Gap Width" ), 0.2, true ) );
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_PHYS, PHYS_LEN_PRM,
|
||||
_( "L:" ), _( "Line Length" ), 50.0, true ) );
|
||||
_( "L" ), _( "Line Length" ), 50.0, true ) );
|
||||
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_ELEC, Z0_PRM,
|
||||
_( "Z0:" ), _( "Characteristic Impedance" ), 50.0, true ) );
|
||||
_( "Z0" ), _( "Characteristic Impedance" ), 50.0, true ) );
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_ELEC, DUMMY_PRM ) );
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_ELEC, ANG_L_PRM,
|
||||
_( "Ang_l:" ), _( "Electrical Length" ), 0, true ) );
|
||||
_( "Ang_l" ), _( "Electrical Length" ), 0, true ) );
|
||||
break;
|
||||
|
||||
|
||||
|
@ -240,23 +240,23 @@ TRANSLINE_IDENT::TRANSLINE_IDENT( enum TRANSLINE_TYPE_ID aType )
|
|||
m_Messages.Add( _( "TM-Modes:" ) );
|
||||
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_SUBS, MUR_PRM,
|
||||
_( "mu Rel I:" ), _( "Relative Permeability (mu) of Insulator" ), 1, false ) );
|
||||
_( "mu Rel I" ), _( "Relative Permeability (mu) of Insulator" ), 1, false ) );
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_SUBS, MURC_PRM,
|
||||
_( "mu Rel C:" ), _( "Relative Permeability (mu) of Conductor" ), 1,
|
||||
_( "mu Rel C" ), _( "Relative Permeability (mu) of Conductor" ), 1,
|
||||
false ) );
|
||||
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_PHYS, PHYS_WIDTH_PRM,
|
||||
_( "a:" ), _( "Width of Waveguide" ), 10.0, true ) );
|
||||
_( "a" ), _( "Width of Waveguide" ), 10.0, true ) );
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_PHYS, PHYS_S_PRM,
|
||||
_( "b:" ), _( "Height of Waveguide" ), 5.0, true ) );
|
||||
_( "b" ), _( "Height of Waveguide" ), 5.0, true ) );
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_PHYS, PHYS_LEN_PRM,
|
||||
_( "L:" ), _( "Waveguide Length" ), 50.0, true ) );
|
||||
_( "L" ), _( "Waveguide Length" ), 50.0, true ) );
|
||||
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_ELEC, Z0_PRM,
|
||||
_( "Z0:" ), _( "Characteristic Impedance" ), 50.0, true ) );
|
||||
_( "Z0" ), _( "Characteristic Impedance" ), 50.0, true ) );
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_ELEC, DUMMY_PRM ) );
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_ELEC, ANG_L_PRM,
|
||||
_( "Ang_l:" ), _( "Electrical Length" ), 0, true ) );
|
||||
_( "Ang_l" ), _( "Electrical Length" ), 0, true ) );
|
||||
break;
|
||||
|
||||
case COAX_TYPE: // coaxial cable
|
||||
|
@ -271,23 +271,23 @@ TRANSLINE_IDENT::TRANSLINE_IDENT( enum TRANSLINE_TYPE_ID aType )
|
|||
m_Messages.Add( _( "TM-Modes:" ) );
|
||||
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_SUBS, MUR_PRM,
|
||||
_( "mu Rel I:" ), _( "Relative Permeability (mu) of Insulator" ), 1, false ) );
|
||||
_( "mu Rel I" ), _( "Relative Permeability (mu) of Insulator" ), 1, false ) );
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_SUBS, MURC_PRM,
|
||||
_( "mu Rel C:" ), _( "Relative Permeability (mu) of Conductor" ), 1,
|
||||
_( "mu Rel C" ), _( "Relative Permeability (mu) of Conductor" ), 1,
|
||||
false ) );
|
||||
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_PHYS, PHYS_DIAM_IN_PRM,
|
||||
_( "Din:" ), _( "Inner Diameter (conductor)" ), 1.0, true ) );
|
||||
_( "Din" ), _( "Inner Diameter (conductor)" ), 1.0, true ) );
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_PHYS, PHYS_DIAM_OUT_PRM,
|
||||
_( "Dout:" ), _( "Outer Diameter (insulator)" ), 8.0, true ) );
|
||||
_( "Dout" ), _( "Outer Diameter (insulator)" ), 8.0, true ) );
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_PHYS, PHYS_LEN_PRM,
|
||||
_( "L:" ), _( "Line Length" ), 50.0, true ) );
|
||||
_( "L" ), _( "Line Length" ), 50.0, true ) );
|
||||
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_ELEC, Z0_PRM,
|
||||
_( "Z0:" ), _( "Characteristic Impedance" ), 50.0, true ) );
|
||||
_( "Z0" ), _( "Characteristic Impedance" ), 50.0, true ) );
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_ELEC, DUMMY_PRM ) );
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_ELEC, ANG_L_PRM,
|
||||
_( "Ang_l:" ), _( "Electrical Length" ), 0.0, true ) );
|
||||
_( "Ang_l" ), _( "Electrical Length" ), 0.0, true ) );
|
||||
break;
|
||||
|
||||
case C_MICROSTRIP_TYPE: // coupled microstrip
|
||||
|
@ -304,30 +304,30 @@ TRANSLINE_IDENT::TRANSLINE_IDENT( enum TRANSLINE_TYPE_ID aType )
|
|||
m_Messages.Add( _( "Skin Depth:" ) );
|
||||
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_SUBS, H_PRM,
|
||||
_( "H:" ), _( "Height of Substrate" ), 0.2, true ) );
|
||||
_( "H" ), _( "Height of Substrate" ), 0.2, true ) );
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_SUBS, H_T_PRM,
|
||||
_( "H_t:" ), _( "Height of Box Top" ), 1e20, true ) );
|
||||
_( "H_t" ), _( "Height of Box Top" ), 1e20, true ) );
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_SUBS, T_PRM,
|
||||
_( "T:" ), _( "Strip Thickness" ), 0.035, true ) );
|
||||
_( "T" ), _( "Strip Thickness" ), 0.035, true ) );
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_SUBS, ROUGH_PRM,
|
||||
_( "Rough:" ), _( "Conductor Roughness" ), 0.0, true ) );
|
||||
_( "Rough" ), _( "Conductor Roughness" ), 0.0, true ) );
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_SUBS, MURC_PRM,
|
||||
_( "mu Rel C:" ), _( "Relative Permeability (mu) of Conductor" ), 1,
|
||||
_( "mu Rel C" ), _( "Relative Permeability (mu) of Conductor" ), 1,
|
||||
false ) );
|
||||
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_PHYS, PHYS_WIDTH_PRM,
|
||||
_( "W:" ), _( "Line Width" ), 0.2, true ) );
|
||||
_( "W" ), _( "Line Width" ), 0.2, true ) );
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_PHYS, PHYS_S_PRM,
|
||||
_( "S:" ), _( "Gap Width" ), 0.2, true ) );
|
||||
_( "S" ), _( "Gap Width" ), 0.2, true ) );
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_PHYS, PHYS_LEN_PRM,
|
||||
_( "L:" ), _( "Line Length" ), 50.0, true ) );
|
||||
_( "L" ), _( "Line Length" ), 50.0, true ) );
|
||||
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_ELEC, Z0_E_PRM,
|
||||
_( "Zeven:" ), _( "Even mode impedance (lines driven by common voltages)" ), 50.0, true ) );
|
||||
_( "Zeven" ), _( "Even mode impedance (lines driven by common voltages)" ), 50.0, true ) );
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_ELEC, Z0_O_PRM,
|
||||
_( "Zodd:" ), _( "Odd mode impedance (lines driven by opposite (differential) voltages)" ), 50.0, true ) );
|
||||
_( "Zodd" ), _( "Odd mode impedance (lines driven by opposite (differential) voltages)" ), 50.0, true ) );
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_ELEC, ANG_L_PRM,
|
||||
_( "Ang_l:" ), _( "Electrical Length" ), 0.0, true ) );
|
||||
_( "Ang_l" ), _( "Electrical Length" ), 0.0, true ) );
|
||||
break;
|
||||
|
||||
case STRIPLINE_TYPE: // stripline
|
||||
|
@ -340,26 +340,26 @@ TRANSLINE_IDENT::TRANSLINE_IDENT( enum TRANSLINE_TYPE_ID aType )
|
|||
m_Messages.Add( _( "Skin Depth:" ) );
|
||||
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_SUBS, H_PRM,
|
||||
_( "H:" ), _( "Height of Substrate" ), 0.2, true ) );
|
||||
_( "H" ), _( "Height of Substrate" ), 0.2, true ) );
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_SUBS, STRIPLINE_A_PRM,
|
||||
_( "a:" ), _( "distance between strip and top metal" ), 0.2,
|
||||
_( "a" ), _( "distance between strip and top metal" ), 0.2,
|
||||
true ) );
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_SUBS, T_PRM,
|
||||
_( "T:" ), _( "Strip Thickness" ), 0.035, true ) );
|
||||
_( "T" ), _( "Strip Thickness" ), 0.035, true ) );
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_SUBS, MURC_PRM,
|
||||
_( "mu Rel C:" ), _( "Relative Permeability (mu) of Conductor" ), 1,
|
||||
_( "mu Rel C" ), _( "Relative Permeability (mu) of Conductor" ), 1,
|
||||
false ) );
|
||||
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_PHYS, PHYS_WIDTH_PRM,
|
||||
_( "W:" ), _( "Line Width" ), 0.2, true ) );
|
||||
_( "W" ), _( "Line Width" ), 0.2, true ) );
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_PHYS, PHYS_LEN_PRM,
|
||||
_( "L:" ), _( "Line Length" ), 50.0, true ) );
|
||||
_( "L" ), _( "Line Length" ), 50.0, true ) );
|
||||
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_ELEC, Z0_PRM,
|
||||
_( "Z0:" ), _( "Characteristic Impedance" ), 50, true ) );
|
||||
_( "Z0" ), _( "Characteristic Impedance" ), 50, true ) );
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_ELEC, DUMMY_PRM ) );
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_ELEC, ANG_L_PRM,
|
||||
_( "Ang_l:" ), _( "Electrical Length" ), 0, true ) );
|
||||
_( "Ang_l" ), _( "Electrical Length" ), 0, true ) );
|
||||
break;
|
||||
|
||||
case TWISTEDPAIR_TYPE: // twisted pair
|
||||
|
@ -373,25 +373,25 @@ TRANSLINE_IDENT::TRANSLINE_IDENT( enum TRANSLINE_TYPE_ID aType )
|
|||
m_Messages.Add( _( "Skin Depth:" ) );
|
||||
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_SUBS, TWISTEDPAIR_TWIST_PRM,
|
||||
_( "Twists:" ), _( "Number of Twists per Length" ), 0.0, false ) );
|
||||
_( "Twists" ), _( "Number of Twists per Length" ), 0.0, false ) );
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_SUBS, MURC_PRM,
|
||||
_( "mu Rel C:" ), _( "Relative Permeability (mu) of Conductor" ), 1,
|
||||
_( "mu Rel C" ), _( "Relative Permeability (mu) of Conductor" ), 1,
|
||||
false ) );
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_SUBS, TWISTEDPAIR_EPSILONR_ENV_PRM,
|
||||
_( "ErEnv:" ), _( "Relative Permittivity of Environment" ), 1,
|
||||
_( "ErEnv" ), _( "Relative Permittivity of Environment" ), 1,
|
||||
false ) );
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_PHYS, PHYS_DIAM_IN_PRM,
|
||||
_( "Din:" ), _( "Inner Diameter (conductor)" ), 1.0, true ) );
|
||||
_( "Din" ), _( "Inner Diameter (conductor)" ), 1.0, true ) );
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_PHYS, PHYS_DIAM_OUT_PRM,
|
||||
_( "Dout:" ), _( "Outer Diameter (insulator)" ), 8.0, true ) );
|
||||
_( "Dout" ), _( "Outer Diameter (insulator)" ), 8.0, true ) );
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_PHYS, PHYS_LEN_PRM,
|
||||
_( "L:" ), _( "Cable Length" ), 50.0, true ) );
|
||||
_( "L" ), _( "Cable Length" ), 50.0, true ) );
|
||||
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_ELEC, Z0_PRM,
|
||||
_( "Z0:" ), _( "Characteristic Impedance" ), 50.0, true ) );
|
||||
_( "Z0" ), _( "Characteristic Impedance" ), 50.0, true ) );
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_ELEC, DUMMY_PRM ) );
|
||||
AddPrm( new TRANSLINE_PRM( PRM_TYPE_ELEC, ANG_L_PRM,
|
||||
_( "Ang_l:" ), _( "Electrical Length" ), 0.0, true ) );
|
||||
_( "Ang_l" ), _( "Electrical Length" ), 0.0, true ) );
|
||||
break;
|
||||
|
||||
case END_OF_LIST_TYPE: // Not really used
|
||||
|
@ -422,7 +422,7 @@ void TRANSLINE_IDENT::ReadConfig()
|
|||
|
||||
for( auto& param : m_prms_List )
|
||||
{
|
||||
std::string id = std::to_string( param->m_Id );
|
||||
std::string id = param->m_Label.ToStdString();
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -443,7 +443,13 @@ void TRANSLINE_IDENT::WriteConfig()
|
|||
|
||||
for( auto& param : m_prms_List )
|
||||
{
|
||||
std::string id = std::to_string( param->m_Id );
|
||||
std::string id = param->m_Label.ToStdString();
|
||||
|
||||
if( !std::isfinite( param->m_Value ) )
|
||||
{
|
||||
param->m_Value = 0;
|
||||
}
|
||||
|
||||
cfg->m_TransLine.param_values[ name ][ id ] = param->m_Value;
|
||||
cfg->m_TransLine.param_units[ name ][ id ] = param->m_UnitSelection;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue