Qucs-core
0.0.19
|
00001 /* 00002 * msopen.cpp - microstrip open end class implementation 00003 * 00004 * Copyright (C) 2004, 2008 Stefan Jahn <stefan@lkcc.org> 00005 * Copyright (C) 2004 Michael Margraf <Michael.Margraf@alumni.TU-Berlin.DE> 00006 * 00007 * This is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation; either version 2, or (at your option) 00010 * any later version. 00011 * 00012 * This software is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with this package; see the file COPYING. If not, write to 00019 * the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, 00020 * Boston, MA 02110-1301, USA. 00021 * 00022 * $Id$ 00023 * 00024 */ 00025 00026 #if HAVE_CONFIG_H 00027 # include <config.h> 00028 #endif 00029 00030 #include "component.h" 00031 #include "substrate.h" 00032 #include "msline.h" 00033 #include "msopen.h" 00034 00035 using namespace qucs; 00036 00037 msopen::msopen () : circuit (1) { 00038 type = CIR_MSOPEN; 00039 } 00040 00041 // Returns the microstrip open end capacitance. 00042 nr_double_t msopen::calcCend (nr_double_t frequency, nr_double_t W, 00043 nr_double_t h, nr_double_t t, nr_double_t er, 00044 const char * const SModel, const char * const DModel, 00045 const char * const Model) { 00046 00047 nr_double_t ZlEff, ErEff, WEff, ZlEffFreq, ErEffFreq; 00048 msline::analyseQuasiStatic (W, h, t, er, SModel, ZlEff, ErEff, WEff); 00049 msline::analyseDispersion (WEff, h, er, ZlEff, ErEff, frequency, DModel, 00050 ZlEffFreq, ErEffFreq); 00051 00052 W /= h; 00053 nr_double_t dl = 0; 00054 /* Kirschning, Jansen and Koster */ 00055 if (!strcmp (Model, "Kirschning")) { 00056 nr_double_t Q6 = qucs::pow (ErEffFreq, 0.81); 00057 nr_double_t Q7 = qucs::pow (W, 0.8544); 00058 nr_double_t Q1 = 0.434907 * 00059 (Q6 + 0.26) / (Q6 - 0.189) * (Q7 + 0.236) / (Q7 + 0.87); 00060 nr_double_t Q2 = qucs::pow (W, 0.371) / (2.358 * er + 1.0) + 1.0; 00061 nr_double_t Q3 = qucs::atan (0.084 * qucs::pow (W, 1.9413 / Q2)) * 00062 0.5274 / qucs::pow (ErEffFreq, 0.9236) + 1.0; 00063 nr_double_t Q4 = 0.0377 * (6.0 - 5.0 * qucs::exp (0.036 * (1.0 - er))) * 00064 qucs::atan (0.067 * qucs::pow (W, 1.456)) + 1.0; 00065 nr_double_t Q5 = 1.0 - 0.218 * qucs::exp (-7.5 * W); 00066 dl = Q1 * Q3 * Q5 / Q4; 00067 } 00068 /* Hammerstad */ 00069 else if (!strcmp (Model, "Hammerstad")) { 00070 dl = 0.102 * (W + 0.106) / (W + 0.264) * 00071 (1.166 + (er + 1) / er * (0.9 + qucs::log (W + 2.475))); 00072 } 00073 return dl * h * qucs::sqrt (ErEffFreq) / C0 / ZlEffFreq; 00074 } 00075 00076 void msopen::calcSP (nr_double_t frequency) { 00077 setS (NODE_1, NODE_1, ztor (1.0 / calcY (frequency))); 00078 } 00079 00080 nr_complex_t msopen::calcY (nr_double_t frequency) { 00081 00082 /* how to get properties of this component, e.g. W */ 00083 nr_double_t W = getPropertyDouble ("W"); 00084 const char * SModel = getPropertyString ("MSModel"); 00085 const char * DModel = getPropertyString ("MSDispModel"); 00086 const char * Model = getPropertyString ("Model"); 00087 00088 /* how to get properties of the substrate, e.g. Er, H */ 00089 substrate * subst = getSubstrate (); 00090 nr_double_t er = subst->getPropertyDouble ("er"); 00091 nr_double_t h = subst->getPropertyDouble ("h"); 00092 nr_double_t t = subst->getPropertyDouble ("t"); 00093 00094 /* local variables */ 00095 nr_complex_t y; 00096 nr_double_t o = 2 * pi * frequency; 00097 00098 /* Alexopoulos and Wu */ 00099 if (!strcmp (Model, "Alexopoulos")) { 00100 nr_double_t ZlEff, ErEff, WEff, ZlEffFreq, ErEffFreq; 00101 msline::analyseQuasiStatic (W, h, t, er, SModel, ZlEff, ErEff, WEff); 00102 msline::analyseDispersion (WEff, h, er, ZlEff, ErEff, frequency, DModel, 00103 ZlEffFreq, ErEffFreq); 00104 00105 if (fabs (er - 9.9) > 0.2) { 00106 logprint (LOG_ERROR, "WARNING: Model for microstrip open end defined " 00107 "for er = 9.9 (er = %g)\n", er); 00108 } 00109 00110 nr_double_t c1, c2, l2, r2; 00111 c1 = (1.125 * qucs::tanh (1.358 * W / h) - 0.315) * 00112 h / 2.54e-5 / 25 / ZlEffFreq * 1e-12; 00113 c2 = (6.832 * qucs::tanh (0.0109 * W / h) + 0.919) * 00114 h / 2.54e-5 / 25 / ZlEffFreq * 1e-12; 00115 l2 = (0.008285 * qucs::tanh (0.5665 * W / h) + 0.0103) * 00116 h / 2.54e-5 / 25 * ZlEffFreq * 1e-9; 00117 r2 = (1.024 * qucs::tanh (2.025 * W / h)) * ZlEffFreq; 00118 y = nr_complex_t (0, c1 * o) + 1.0 / nr_complex_t (r2, l2 * o - 1 / c2 / o); 00119 } 00120 else { 00121 nr_double_t c = calcCend (frequency, W, h, t, er, SModel, DModel, Model); 00122 y = nr_complex_t (0, c * o); 00123 } 00124 return y; 00125 } 00126 00127 void msopen::initDC (void) { 00128 allocMatrixMNA (); 00129 setY (NODE_1, NODE_1, 0); 00130 } 00131 00132 void msopen::calcAC (nr_double_t frequency) { 00133 setY (NODE_1, NODE_1, calcY (frequency)); 00134 } 00135 00136 // properties 00137 PROP_REQ [] = { 00138 { "W", PROP_REAL, { 1e-3, PROP_NO_STR }, PROP_POS_RANGE }, 00139 { "Subst", PROP_STR, { PROP_NO_VAL, "Subst1" }, PROP_NO_RANGE }, 00140 { "MSDispModel", PROP_STR, { PROP_NO_VAL, "Kirschning" }, PROP_RNG_DIS }, 00141 { "MSModel", PROP_STR, { PROP_NO_VAL, "Hammerstad" }, PROP_RNG_MOD }, 00142 { "Model", PROP_STR, { PROP_NO_VAL, "Kirschning" }, 00143 PROP_RNG_STR3 ("Kirschning", "Hammerstad", "Alexopoulos") }, 00144 PROP_NO_PROP }; 00145 PROP_OPT [] = { 00146 PROP_NO_PROP }; 00147 struct define_t msopen::cirdef = 00148 { "MOPEN", 1, PROP_COMPONENT, PROP_NO_SUBSTRATE, PROP_LINEAR, PROP_DEF };