/* -*- C++ -*- This file is part of ViPEC Copyright (C) 1991-2001 Johan Rossouw (jrossouw@alcatel.altech.co.za) This program is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU Library General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include #include #include /* a few static constant variables used by the models */ #ifndef _WS_WIN_ static const TReal ZERO=1E-1000; static const TReal BIGNUM=1E1000; #else static const TReal ZERO=1E-200; static const TReal BIGNUM=1E200; #endif using namespace std; static const TReal C = 2.997925E8; // Speed of light (m/s) static const TReal muo =4*M_PI*1E-7; //permeabilitty of vacuum (V.s.A^{-1}.m^{-1}) static const TReal KapaC = 58E6; // conductivity of cooper (Ohm^{-1}.m^{-1}) //--------------------------------------------------------------------------- void TwoPorts::getTLIN(TReal Freq, TReal Z, TReal E, TReal Fo, Matrix& Y) { TReal Alpha = 0.00001; //LOSS FACTOR TReal Beta = (M_PI*E/180) * (Freq/Fo); TComplex Gamma = TComplex(Alpha, Beta); TComplex Yi = cosh(Gamma) / (sinh(Gamma) * TComplex(Z,0)); TComplex Yt = TComplex(1,0) / (sinh(Gamma) * TComplex(-Z,0)); Y.resize(2); Y(0,0) = Yi; Y(0,1) = Yt; Y(1,0) = Yt; Y(1,1) = Yi; } //--------------------------------------------------------------------------- void TwoPorts::getTLSC(TReal Freq, TReal Z, TReal E, TReal Fo, TComplex &Y) { TReal Alpha = 0.00001; //LOSS FACTOR TReal Beta = (M_PI*E/180) * (Freq/Fo); TComplex Gamma = TComplex(Alpha, Beta); Y = cosh(Gamma) / (sinh(Gamma) * TComplex(Z,0)); } //--------------------------------------------------------------------------- void TwoPorts::getTLOC(TReal Freq, TReal Z, TReal E, TReal Fo, TComplex &Y) { TReal Alpha = 0.00001; //LOSS FACTOR TReal Beta = (M_PI*E/180) * (Freq/Fo); TComplex Gamma = TComplex(Alpha, Beta); Y = sinh(Gamma) / (TComplex(Z,0) * cosh(Gamma)); } //--------------------------------------------------------------------------- void TwoPorts::getCLIN(TReal Freq, TReal Ze, TReal Zo, TReal E, TReal Fo, Matrix& Y) { TReal d = cos(Freq/Fo); TReal Ye = 1/Ze; TReal Yo = 1/Zo; /* calculate beta - actually this is beta*length */ TReal Beta = (M_PI*E/180) * (Freq/Fo); TComplex s,m; if (fabs(d)=ZERO && ke<=0.7) { keP = log(2*((1+sqrt(keP))/(1-sqrt(keP))))/M_PI; Zoe = Zoe*30.0*M_PI*keP; } else if (ke>0.7 && ke<=1) { ke = log(2*(1+sqrt(ke))/(1-sqrt(ke)))/M_PI; Zoe = Zoe*30.0*M_PI/ke; } else { throw Exception::LineDimensionsOutOfRange(); } /* odd mode impedance */ TReal Zoo = 1/sqrt(Er); if (ko>=ZERO && ko<=0.7) { koP = log(2*((1+sqrt(koP))/(1-sqrt(koP))))/M_PI; Zoo = Zoo*30.0*M_PI*koP; } else if (ko>0.7 && ko<=1) { ko = log(2*(1+sqrt(ko))/(1-sqrt(ko)))/M_PI; Zoo = Zoo*30.0*M_PI/ko; } else { throw Exception::LineDimensionsOutOfRange(); } /* Phase length at this freq computed by first getting beta=2*pi/wavelength (rad) with the freq in Hz!! - electrical length in rad just by multiplying with L */ TReal Beta = Freq*sqrt(Er)/(C); //2*pi above and below line cancelled /* losses contained in alpha */ //TReal Alpha = (27.3/2*M_PI)*Freq*tanRho*sqrt(Er)/C; //TComplex Gamma(Alpha, Beta); /* S = j*tan(beta*l) */ TComplex s = TComplex(0,tan(Beta*L)); //TComplex s = TComplex(0,tan(Gamma*L)); TComplex m = sqrt(TComplex(1,0) - pow(s,2)) / s; TReal Ye = 1/Zoe; TReal Yo = 1/Zoo; Y.resize(2); Y(0,0) = TComplex((Yo+Ye),0) / (TComplex(-2,0)*s); Y(0,1) = TComplex((Yo-Ye),0) / (TComplex(-2,0)*s); Y(1,0) = m*TComplex((Yo-Ye),0) / (TComplex(-2,0)); Y(1,1) = m*TComplex((Yo+Ye),0) / (TComplex(-2,0)); } //--------------------------------------------------------------------------- void TwoPorts::getGYR(TReal R, Matrix& Y) { Y.resize(2); Y(0,0) = TComplex(0,0); Y(0,1) = TComplex(1/R,0); Y(1,0) = TComplex(-1/R,0); Y(1,1) = TComplex(0,0); } //--------------------------------------------------------------------------- void TwoPorts::getTransformer(TReal f, TReal L1, TReal L2, TReal k, Matrix& Y) { Y.resize(2); // small case, to restrict the users possibility of getting a singular matrix if (k>=1) { k = 0.99999; } else if (k<0) { k = 0; } TReal L12 = sqrt(L1*L2); // Maximal mutual inductance TReal k2m1 = k*k-1; // k=M/L12, where M is the diagonal term of the impedance matrix Y(0,0) = TComplex(0, 1/(f*L1*k2m1)); Y(0,1) = TComplex(0, -k/(f*L12*k2m1)); Y(1,0) = Y(0,1); Y(1,1) = TComplex(0, 1/(f*L2*k2m1)); } //--------------------------------------------------------------------------- void TwoPorts::getBIPB(TReal Freq, TReal B, TReal Fo, TReal Re, TReal C, Matrix& Y) { // PARAMETER SEQUENCY B=beta F=frequency Re=resistance C=capac TComplex beta = TComplex(B,0) / TComplex(1,B*Freq/Fo); TComplex zr = (TComplex(1,0) + beta) * TComplex(Re,0); TComplex yc = TComplex(0,Freq*C); Y.resize(2); Y(0,0) = (TComplex(1,0) / zr) + yc; Y(1,0) = (beta / zr) - yc; Y(0,1) = TComplex(-1,0) * yc; Y(1,1) = yc; } //--------------------------------------------------------------------------- void TwoPorts::getSLIN(TReal Freq, TReal W, //Line width TReal L, //Line length TReal T, //Conductor thickness TReal H, //Substrate height TReal Er, //Relative permittivity TReal tanRho, //Loss Matrix& Y) { /* work with normalized Z for the rest of function */ TReal Z = 1.0/sqrt(Er); //normalized Z /* Phase length at this freq computed by first getting beta=2*pi/wavelength (rad) with the freq in Hz!! - electrical length in rad just by multiplying with L */ TReal Beta = Freq*sqrt(Er)/(C); //2*pi above and below line cancelled out /* k and kprime are functions of W and height */ TReal k = tanh(M_PI*W/(2*H)); TReal kPrime = sqrt(1-pow(k,2)); if (T<=ZERO) { //case for zero thickness conductor if (k>=ZERO && k<=0.7) { kPrime = log(2*((1+sqrt(kPrime))/(1-sqrt(kPrime))))/M_PI; Z = Z*30.0*M_PI*kPrime; } else if (k>0.7 && k<=1) { k = log(2*(1+sqrt(k))/(1-sqrt(k)))/M_PI; Z = Z*30.0*M_PI/k; } else { throw Exception::LineDimensionsOutOfRange(); } }//if T<=ZERO else { //case for finite thickness conductor TReal x = T/H; TReal m = 2/(1+(2/3)*x/(1-x)); TReal Wnorm = (x/M_PI*(1-x))*(1-0.5*log(pow(x/(2-x),2)+pow(0.0796*x/(W/H+1.1*x),m))); Wnorm = 1/(Wnorm + W/(H-T)); Z = Z*30*log(1+(Wnorm*4/M_PI)*(Wnorm*8/M_PI+sqrt(pow(Wnorm*8/M_PI,2)+6.27))); }//else /* alpha = pi*tan(rho)/wavelength - note that freq is radians in ALL functions */ //TReal Alpha = 0.5*Freq*tanRho*sqrt(Er)/C; /* another dielectric loss tangent is alpha = 27.3*sqrt(Er)*tanRho/(natural wavel) NOTE this one gives better results!! */ TReal Alpha = (27.3/2*M_PI)*Freq*tanRho*sqrt(Er)/C; /* before calculating input admittance, multiply alpha, beta with length to get angle */ Beta *= L; Alpha *= L; /* Now get gamma */ TComplex Gamma = TComplex(Alpha, Beta); TComplex Yi = cosh(Gamma) / (sinh(Gamma) * TComplex(Z,0)); TComplex Yt = TComplex(1,0) / (sinh(Gamma) * TComplex(-Z,0)); Y.resize(2); Y(0,0) = Yi; Y(0,1) = Yt; Y(1,0) = Yt; Y(1,1) = Yi; }//end of getSLIN() //--------------------------------------------------------------------------- void TwoPorts::getMLIN(TReal Freq, TReal W, //Line width TReal L, //Line length TReal T, //Line thickness TReal H, //Substrate height TReal Er, //Relative permittivity TReal tanRho, //Loss Matrix& Y) { const TReal ZETA = 120*M_PI; /* units of OHM */ TReal Z=0; /* variable used for line impedance */ TReal Ere=0; /* variable for the effective relabive permm */ /* We take strip thickness into account... */ if (T/H <=0.005) { //small enough to assume T==0 /* because the mode is not purely TEM but quasi-TEM the effective dielectric constant is lower than that given for the substrate and takes into account the fields external to the substrate */ Ere = 0.5*(Er+1) + 0.5*(Er-1)*pow((1+10*H/W),-0.5); /* Z computed differently for different ratios of W/H */ if (W/H <= 1) { Z = ZETA/(2*M_PI*sqrt(Ere)) * log( (8*H/W)+0.25*W/H ); } else if (W/H > 1) { Z = (ZETA/sqrt(Ere)) / (W/H + 1.393 + 0.667*log(W/H+1.444)); } else { throw Exception::LineDimensionsOutOfRange(); } }//if T/H<=0.005 else { Ere = 0.5*(Er+1) + 0.5*(Er-1)/sqrt(1+10*H/W) - (pow(W/H,-0.5)*T/H)*(Er-1)/4.6; /* ratio needed to calculate effective width */ TReal dWonH; if (W/H <= 1/(2*M_PI)) { dWonH = (1.25/M_PI)*(T/H)*(1 + log(4*M_PI*W/T)); } else { dWonH = (1.25/M_PI)*(T/H)*(1 + log(2*H/T)); } /* effective Width */ TReal We = W + dWonH*H; /* and now we can get Z - different for ratios of W/H */ if (W/H <= 1) { Z = (60/sqrt(Ere)) * log( (8*H/We)+0.25*We/H ); } else if (W/H > 1) { Z = (376.7/sqrt(Ere)) / (We/H + 1.393 + 0.667*log(We/H+1.444)); } else { throw Exception::LineDimensionsOutOfRange(); } }//if-else T/H /* Phase length at this freq computed by first getting beta=2*pi/wavelength (rad) with the freq in Hz!! - electrical length in rad just by multiplying with L */ TReal Beta = Freq*sqrt(Ere)/(C); //2*pi above and below line cancelled out /* alpha - note that freq is radians in ALL functions, therefore the 2*pi NOTE the mixture of effective and normal relative permm */ // 27/02/2001 - Bug in calculation of Alpha, the commented line was the original //TMyReal Alpha = (27.3/2*M_PI)*Er/(Er-1)*((Ere-1)/sqrt(Ere))*Freq*tanRho*sqrt(Ere)/C; TReal Alpha = 0.5*Er/(Er-1)*((Ere-1)/sqrt(Ere))*Freq*tanRho/C; /* before calculating input admittance, multiply alpha, beta with length to get angle */ Beta *= L; Alpha *= L; /* Now get gamma */ TComplex Gamma = TComplex(Alpha, Beta); TComplex Yi = cosh(Gamma) / (sinh(Gamma) * TComplex(Z,0)); TComplex Yt = TComplex(1,0) / (sinh(Gamma) * TComplex(-Z,0)); Y.resize(2); Y(0,0) = Yi; Y(0,1) = Yt; Y(1,0) = Yt; Y(1,1) = Yi; } //----------------------------------------------------------------------------------------- void TwoPorts::getCoaxLIN(TReal Freq, TReal W, //Outer Diameter of the inner conductor TReal L, //Line length TReal /*T*/, //Thickness of the inner conductor for further calculations (not used for the monent) TReal H, //Inner Diameter of the outer conductor (shield) TReal Er, //Relative permittivity beween the shield and the inner conductor TReal tanRho, //Loss Matrix& Y) { /* the theory behind this model is developped in the Book of Brian C.Wandell : Transmission Line Design Hadbook */ /* elements of this model are presented in efg, internal report plx2.doc 991202 */ const TReal Zo = 377; /* units of OHM */ TReal freal = Freq/(2*M_PI); /* note that freq is in radians in all functions, therefore we have to consider 2*pi each time*/ /* Caracteristic impedance (2.6) */ TReal Z = Zo/(2*M_PI*sqrt(Er))*log(H/W); /* Computing the losses along TL */ /* Conductive losses metal conductor */ TReal alphaL = 1/(2*H*Z)*pow((freal*muo/(M_PI*KapaC)),0.5)*(1+H/W); // the conductor is not paramagnetic mur=1 /* Dielectric losses */ TReal alphaD = M_PI*freal*(sqrt(Er)*(tanRho)/C); /*Total damping = conductor and dielectric (radiation damping is assumed negligible) */ TReal Alpha = alphaL+alphaD; /* We have defined Ere, as an electric permittivity with E'+jE'', */ /* In our range of materials Er is not linked to frequency */ /* and therefore the TL will resonate at equally spaced harmonics */ /* If tanRho is not always negligible, Ere is not real */ //TComplex Ere = TComplex(Er,Er*tanRho); TReal Ere = Er; /* in the full TEM case */ /*The propagation constant become */ //TComplex Beta=2*M_PI/C*freal*pow(Ere,0.5); TReal Beta=2*M_PI*freal*(pow(Ere,0.5)/C); /* before calculating input admittance, multiply alpha, beta with length to get angle */ // Beta = Beta*TComplex(L,0); Beta *= L; Alpha *= L; /* Now get gamma */ //TComplex Gamma = TComplex(Alpha,0)+Beta; TComplex Gamma = TComplex(Alpha,Beta); TComplex Yi = cosh(Gamma) / (sinh(Gamma) * TComplex(Z,0)); TComplex Yt = TComplex(1,0) / (sinh(Gamma) * TComplex(-Z,0)); Y.resize(2); Y(0,0) = Yi; Y(0,1) = Yt; Y(1,0) = Yt; Y(1,1) = Yi; }