Qucs-core
0.0.19
|
00001 /* 00002 * mscorner.cpp - microstrip corner class implementation 00003 * 00004 * Copyright (C) 2004, 2006, 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 "mscorner.h" 00033 00034 using namespace qucs; 00035 00036 mscorner::mscorner () : circuit (2) { 00037 type = CIR_MSCORNER; 00038 } 00039 00040 void mscorner::initCheck (void) { 00041 // get properties of substrate and corner 00042 nr_double_t W = getPropertyDouble ("W"); 00043 substrate * subst = getSubstrate (); 00044 nr_double_t er = subst->getPropertyDouble ("er"); 00045 h = subst->getPropertyDouble ("h"); 00046 00047 // local variables 00048 nr_double_t Wh = W/h; 00049 00050 // check validity 00051 if (Wh < 0.2 || Wh > 6.0) { 00052 logprint (LOG_ERROR, "WARNING: Model for microstrip corner defined for " 00053 "0.2 <= W/h <= 6.0 (W/h = %g)\n", Wh); 00054 } 00055 if (er < 2.36 || er > 10.4) { 00056 logprint (LOG_ERROR, "WARNING: Model for microstrip corner defined for " 00057 "2.36 <= er <= 10.4 (er = %g)\n", er); 00058 } 00059 00060 // capacitance in pF 00061 C = W * ((10.35 * er + 2.5) * Wh + (2.6 * er + 5.64)); 00062 // inductivity in nH 00063 L = 220.0 * h * (1.0 - 1.35 * qucs::exp (-0.18 * qucs::pow (Wh, 1.39))); 00064 } 00065 00066 void mscorner::initSP (void) { 00067 // allocate S-parameter matrix 00068 allocMatrixS (); 00069 initCheck (); 00070 } 00071 00072 void mscorner::calcSP (nr_double_t frequency) { 00073 setMatrixS (ztos (calcMatrixZ (frequency))); 00074 } 00075 00076 matrix mscorner::calcMatrixZ (nr_double_t frequency) { 00077 // check frequency validity 00078 if (frequency * h > 12e6) { 00079 logprint (LOG_ERROR, "WARNING: Model for microstrip corner defined for " 00080 "freq*h <= 12MHz (is %g)\n", frequency * h); 00081 } 00082 00083 // create Z-parameter matrix 00084 matrix z (2); 00085 nr_complex_t z21 = nr_complex_t (0.0, -0.5e12 / (pi * frequency * C)); 00086 nr_complex_t z11 = nr_complex_t (0.0, 2e-9 * pi * frequency * L) + z21; 00087 z.set (0, 0, z11); 00088 z.set (0, 1, z21); 00089 z.set (1, 0, z21); 00090 z.set (1, 1, z11); 00091 return z; 00092 } 00093 00094 void mscorner::initDC (void) { 00095 // a DC short (voltage source V = 0 volts) 00096 setVoltageSources (1); 00097 setInternalVoltageSource (1); 00098 allocMatrixMNA (); 00099 voltageSource (VSRC_1, NODE_1, NODE_2); 00100 } 00101 00102 void mscorner::initAC (void) { 00103 setVoltageSources (0); 00104 allocMatrixMNA (); 00105 initCheck (); 00106 } 00107 00108 void mscorner::calcAC (nr_double_t frequency) { 00109 setMatrixY (ztoy (calcMatrixZ (frequency))); 00110 } 00111 00112 // properties 00113 PROP_REQ [] = { 00114 { "W", PROP_REAL, { 1e-3, PROP_NO_STR }, PROP_POS_RANGE }, 00115 { "Subst", PROP_STR, { PROP_NO_VAL, "Subst1" }, PROP_NO_RANGE }, 00116 PROP_NO_PROP }; 00117 PROP_OPT [] = { 00118 PROP_NO_PROP }; 00119 struct define_t mscorner::cirdef = 00120 { "MCORN", 2, PROP_COMPONENT, PROP_NO_SUBSTRATE, PROP_LINEAR, PROP_DEF };