/* -*- C++ -*- This file is part of ViPEC Copyright (C) 1991-2000 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 #include #include #include #include #include #include #include #include #include #include #include //-------------------------------------------------------------------------------- MicroStripCalcWindow::MicroStripCalcWindow( QWidget* parent, const char* name ) : QDialog( parent, name , FALSE ), topLayout_(0) { setCaption( name ); topLayout_ = new QVBoxLayout( this ); QGridLayout* gridLayout = new QGridLayout ( 0 ); QHBoxLayout* buttonLayout = new QHBoxLayout( 0 ); topLayout_->addSpacing( 10 ); topLayout_->addItem( gridLayout ); topLayout_->addSpacing( 10 ); topLayout_->addItem( buttonLayout ); gridLayout->expand( 7, 7 ); gridLayout->addColSpacing( 0, 20 ); gridLayout->addColSpacing( 1, 100 ); gridLayout->addColSpacing( 2, 10 ); gridLayout->addColSpacing( 3, 50 ); gridLayout->addColSpacing( 4, 10 ); gridLayout->addColSpacing( 5, 50 ); gridLayout->addColSpacing( 6, 20 ); erEdit_ = new QLineEdit( this, "er" ); erEdit_->setMaxLength(10); erEdit_->setText("4.5"); QLabel* erTitle = new QLabel( erEdit_, Strings::translate( Strings::CalcDielectricConstant ), this ); QLabel* erLabel = new QLabel( 0, "Er", this ); gridLayout->addWidget(erTitle,0,1); gridLayout->addWidget(erEdit_,0,3); gridLayout->addWidget(erLabel,0,5); hEdit_ = new QLineEdit( this, "height" ); hEdit_->setMaxLength(10); hEdit_->setText("1.5"); QLabel* hTitle = new QLabel( hEdit_, Strings::translate( Strings::CalcSubstraceHeight ), this ); QLabel * hLabel = new QLabel( 0, "mm", this ); gridLayout->addWidget(hTitle,1,1); gridLayout->addWidget(hEdit_,1,3); gridLayout->addWidget(hLabel,1,5); fEdit_ = new QLineEdit( this, "freq" ); fEdit_->setMaxLength(10); fEdit_->setText("10.0"); QLabel* fTitle = new QLabel( fEdit_, Strings::translate( Strings::CalcFrequency ), this ); QLabel * fLabel = new QLabel( 0, "GHz", this ); gridLayout->addWidget(fTitle,2,1); gridLayout->addWidget(fEdit_,2,3); gridLayout->addWidget(fLabel,2,5); // Physical parameters lEdit_ = new QLineEdit( this, "length" ); lEdit_->setMaxLength(10); lEdit_->setText("10.0"); QLabel* lTitle = new QLabel( lEdit_, Strings::translate( Strings::CalcLineLength ), this ); QLabel * lLabel = new QLabel( 0, "mm", this ); gridLayout->addWidget(lTitle,3,1); gridLayout->addWidget(lEdit_,3,3); gridLayout->addWidget(lLabel,3,5); wEdit_ = new QLineEdit( this, "width" ); wEdit_->setMaxLength(10); wEdit_->setText("2.0"); QLabel* wTitle = new QLabel( wEdit_, Strings::translate( Strings::CalcLineWidth ), this ); QLabel * wLabel = new QLabel( 0, "mm", this ); gridLayout->addWidget(wTitle,4,1); gridLayout->addWidget(wEdit_,4,3); gridLayout->addWidget(wLabel,4,5); // Electrical parameters elEdit_ = new QLineEdit( this, "elength" ); elEdit_->setMaxLength(10); QLabel* elTitle = new QLabel( elEdit_, Strings::translate( Strings::CalcElectricalLength ), this ); QLabel * elLabel = new QLabel( 0, Strings::translate( Strings::CalcDegrees ), this ); gridLayout->addWidget(elTitle,5,1); gridLayout->addWidget(elEdit_,5,3); gridLayout->addWidget(elLabel,5,5); zEdit_ = new QLineEdit( this, Strings::translate( Strings::CalcImpedance ) ); zEdit_->setMaxLength(10); QLabel* zTitle = new QLabel( zEdit_, Strings::translate( Strings::CalcLineImpedance ), this ); QLabel * zLabel = new QLabel( 0, "ohm", this ); gridLayout->addWidget(zTitle,6,1); gridLayout->addWidget(zEdit_,6,3); gridLayout->addWidget(zLabel,6,5); QPushButton* but = new QPushButton( Strings::translate( Strings::CalcElectrical ), this ); connect( but, SIGNAL(pressed()), SLOT(calcElectrical()) ); buttonLayout->addWidget(but); QPushButton* but2 = new QPushButton( Strings::translate( Strings::CalcPhysical ), this ); connect( but2, SIGNAL(pressed()), SLOT(calcPhysical()) ); buttonLayout->addWidget(but2); topLayout_->activate(); } //-------------------------------------------------------------------------------- MicroStripCalcWindow::~MicroStripCalcWindow() {} //-------------------------------------------------------------------------------- void MicroStripCalcWindow::errorMsg(QString msg) { QMessageBox::information( this, "LiNECALC message", msg); } //-------------------------------------------------------------------------------- void MicroStripCalcWindow::calcPhysical() { if (!getSubstrateValues()) return; bool convertOk; QString buffer; buffer = elEdit_->text(); el_ = buffer.toDouble(&convertOk); if (!convertOk) { errorMsg("Invalid electrical length value!"); return; } buffer = zEdit_->text(); z_ = buffer.toDouble(&convertOk); if (!convertOk) { errorMsg("Invalid line impedance value!"); return; } w_ = estimateW(z_,er_,h_); TReal ratio = w_/h_; TReal Ef = calcEf(ratio,er_); TReal temp = 3E8/(f_*sqrt(Ef)); l_ = el_ / 360 * temp; buffer.sprintf( "%3.3f", (w_/1E-3)); wEdit_->setText(buffer); buffer.sprintf( "%3.3f", (l_/1E-3)); lEdit_->setText(buffer); } //-------------------------------------------------------------------------------- void MicroStripCalcWindow::calcElectrical() { if (!getSubstrateValues()) return; bool convertOk; QString buffer; buffer = wEdit_->text(); w_ = buffer.toDouble(&convertOk); if (!convertOk) { errorMsg("Invalid line width value!"); return; } buffer = lEdit_->text(); l_ = buffer.toDouble(&convertOk); if (!convertOk) { errorMsg("Invalid substrate height value!"); return; } w_ = w_ * 1E-3; l_ = l_ * 1E-3; TReal ratio = w_/h_; z_ = calcZo(ratio); TReal Ef = calcEf(ratio,er_); z_ = z_/sqrt(Ef); TReal temp = 3E8/(f_*sqrt(Ef)); el_ = 360 * l_ / temp; buffer.sprintf( "%3.3f", z_); zEdit_->setText(buffer); buffer.sprintf( "%3.3f", el_); elEdit_->setText(buffer); } //-------------------------------------------------------------------------------- bool MicroStripCalcWindow::getSubstrateValues() { bool convertOk; QString buffer; buffer = erEdit_->text(); er_ = buffer.toDouble(&convertOk); if (!convertOk) errorMsg("Invalid Er value!"); if (convertOk) { buffer = hEdit_->text(); h_ = buffer.toDouble(&convertOk); if (!convertOk) errorMsg("Invalid substrate height value!"); h_ = h_ * 1E-3; } if (convertOk) { buffer = fEdit_->text(); f_ = buffer.toDouble(&convertOk); if (!convertOk) errorMsg("Invalid frequency value!"); f_ = f_ * 1E9; } return convertOk; } //-------------------------------------------------------------------------------- TReal MicroStripCalcWindow::calcEf(TReal ratio, TReal Er) { TReal a = 1 + 1/49*log((pow(ratio,4)+pow(ratio/54,2))/(pow(ratio,4)+0.432)) + 1/18.7*log(1+pow(ratio/18.1,3)); TReal b = 0.564*pow((Er-0.9)/(Er+3),0.053); TReal Ef = (Er+1)/2+(Er-1)/2*pow(1+10/ratio,-a*b); return Ef; } //-------------------------------------------------------------------------------- TReal MicroStripCalcWindow::calcZo(TReal ratio) { TReal Zo = 120*M_PI/(ratio + 1.98*pow(ratio,0.172)); return Zo; } //-------------------------------------------------------------------------------- TReal MicroStripCalcWindow::estimateW(TReal Z, TReal Er, TReal H) { TReal w = 8*sqrt((exp(Z*sqrt(Er+1)/42.4)-1)*((7+4/Er)/11)+ (1+1/Er)/0.81)/(exp(Z*sqrt(Er+1)/42.4)-1); w = w*H; return w; }