Qucs-core
0.0.19
|
00001 /* 00002 * msgap.cpp - microstrip gap class implementation 00003 * 00004 * Copyright (C) 2004, 2008, 2009 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 "msopen.h" 00033 #include "msgap.h" 00034 00035 using namespace qucs; 00036 00037 msgap::msgap () : circuit (2) { 00038 type = CIR_MSGAP; 00039 } 00040 00041 void msgap::calcSP (nr_double_t frequency) { 00042 setMatrixS (ytos (calcMatrixY (frequency))); 00043 } 00044 00045 matrix msgap::calcMatrixY (nr_double_t frequency) { 00046 00047 /* how to get properties of this component, e.g. W */ 00048 nr_double_t W1 = getPropertyDouble ("W1"); 00049 nr_double_t W2 = getPropertyDouble ("W2"); 00050 nr_double_t s = getPropertyDouble ("S"); 00051 const char * SModel = getPropertyString ("MSModel"); 00052 const char * DModel = getPropertyString ("MSDispModel"); 00053 00054 /* how to get properties of the substrate, e.g. Er, H */ 00055 substrate * subst = getSubstrate (); 00056 nr_double_t er = subst->getPropertyDouble ("er"); 00057 nr_double_t h = subst->getPropertyDouble ("h"); 00058 nr_double_t t = subst->getPropertyDouble ("t"); 00059 00060 nr_double_t Q1, Q2, Q3, Q4, Q5; 00061 bool flip = false; 00062 if (W2 < W1) { // equations are valid for 1 <= W2/W1 <= 3 00063 Q1 = W1; 00064 W1 = W2; 00065 W2 = Q1; 00066 flip = true; 00067 } 00068 00069 // calculate parallel open end capacitances 00070 nr_double_t C1 = msopen::calcCend (frequency, W1, h, t, er, 00071 SModel, DModel, "Kirschning"); 00072 nr_double_t C2 = msopen::calcCend (frequency, W2, h, t, er, 00073 SModel, DModel, "Kirschning"); 00074 00075 W2 /= W1; 00076 W1 /= h; 00077 s /= h; 00078 00079 // local variables 00080 Q5 = 1.23 / (1.0 + 0.12 * qucs::pow (W2 - 1.0, 0.9)); 00081 Q1 = 0.04598 * (0.03 + qucs::pow (W1, Q5)) * (0.272 + 0.07 * er); 00082 Q2 = 0.107 * (W1 + 9.0) * qucs::pow (s, 3.23) + 00083 2.09 * qucs::pow (s, 1.05) * (1.5 + 0.3 * W1) / (1.0 + 0.6 * W1); 00084 Q3 = qucs::exp (-0.5978 * qucs::pow (W2, +1.35)) - 0.55; 00085 Q4 = qucs::exp (-0.5978 * qucs::pow (W2, -1.35)) - 0.55; 00086 00087 nr_double_t Cs = 5e-10 * h * qucs::exp (-1.86 * s) * Q1 * 00088 (1.0 + 4.19 * (1.0 - qucs::exp (-0.785 * qucs::sqrt (1.0 / W1) * W2))); 00089 C1 *= (Q2 + Q3) / (Q2 + 1.0); 00090 C2 *= (Q2 + Q4) / (Q2 + 1.0); 00091 00092 if (flip) { // if necessary flip ports back 00093 Q1 = C1; 00094 C1 = C2; 00095 C2 = Q1; 00096 } 00097 00098 // build Y-parameter matrix 00099 nr_complex_t y21 = nr_complex_t (0.0, -2.0 * pi * frequency * Cs); 00100 nr_complex_t y11 = nr_complex_t (0.0, 2.0 * pi * frequency * (C1 + Cs)); 00101 nr_complex_t y22 = nr_complex_t (0.0, 2.0 * pi * frequency * (C2 + Cs)); 00102 matrix y (2); 00103 y.set (0, 0, y11); 00104 y.set (0, 1, y21); 00105 y.set (1, 0, y21); 00106 y.set (1, 1, y22); 00107 return y; 00108 } 00109 00110 void msgap::initDC (void) { 00111 allocMatrixMNA (); 00112 clearY (); 00113 } 00114 00115 void msgap::calcAC (nr_double_t frequency) { 00116 setMatrixY (calcMatrixY (frequency)); 00117 } 00118 00119 // properties 00120 PROP_REQ [] = { 00121 { "W1", PROP_REAL, { 1e-3, PROP_NO_STR }, PROP_POS_RANGE }, 00122 { "W2", PROP_REAL, { 1e-3, PROP_NO_STR }, PROP_POS_RANGE }, 00123 { "S" , PROP_REAL, { 1e-3, PROP_NO_STR }, PROP_POS_RANGE }, 00124 { "Subst", PROP_STR, { PROP_NO_VAL, "Subst1" }, PROP_NO_RANGE }, 00125 { "MSDispModel", PROP_STR, { PROP_NO_VAL, "Kirschning" }, PROP_RNG_DIS }, 00126 { "MSModel", PROP_STR, { PROP_NO_VAL, "Hammerstad" }, PROP_RNG_MOD }, 00127 PROP_NO_PROP }; 00128 PROP_OPT [] = { 00129 PROP_NO_PROP }; 00130 struct define_t msgap::cirdef = 00131 { "MGAP", 2, PROP_COMPONENT, PROP_NO_SUBSTRATE, PROP_LINEAR, PROP_DEF };