Qucs-core
0.0.19
|
00001 /* 00002 * msvia.cpp - microstrip via hole class implementation 00003 * 00004 * Copyright (C) 2004, 2005, 2008 Stefan Jahn <stefan@lkcc.org> 00005 * 00006 * This is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2, or (at your option) 00009 * any later version. 00010 * 00011 * This software is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this package; see the file COPYING. If not, write to 00018 * the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, 00019 * Boston, MA 02110-1301, USA. 00020 * 00021 * $Id$ 00022 * 00023 */ 00024 00025 #if HAVE_CONFIG_H 00026 # include <config.h> 00027 #endif 00028 00029 #include "component.h" 00030 #include "substrate.h" 00031 #include "msvia.h" 00032 00033 using namespace qucs; 00034 00035 msvia::msvia () : circuit (2) { 00036 R = 0; 00037 Z = 0; 00038 type = CIR_MSVIA; 00039 } 00040 00041 void msvia::calcNoiseSP (nr_double_t) { 00042 // calculate noise correlation matrix 00043 nr_double_t T = getPropertyDouble ("Temp"); 00044 nr_double_t f = celsius2kelvin (T) * 4.0 * real (Z) * z0 / norm (4.0 * z0 + Z) / T0; 00045 setN (NODE_1, NODE_1, +f); setN (NODE_2, NODE_2, +f); 00046 setN (NODE_1, NODE_2, -f); setN (NODE_2, NODE_1, -f); 00047 } 00048 00049 void msvia::initSP (void) { 00050 allocMatrixS (); 00051 R = calcResistance (); 00052 } 00053 00054 void msvia::calcSP (nr_double_t frequency) { 00055 // calculate s-parameters 00056 Z = calcImpedance (frequency); 00057 nr_complex_t z = Z / z0; 00058 setS (NODE_1, NODE_1, z / (z + 2.0)); 00059 setS (NODE_2, NODE_2, z / (z + 2.0)); 00060 setS (NODE_1, NODE_2, 2.0 / (z + 2.0)); 00061 setS (NODE_2, NODE_1, 2.0 / (z + 2.0)); 00062 } 00063 00064 nr_complex_t msvia::calcImpedance (nr_double_t frequency) { 00065 // fetch substrate and component properties 00066 substrate * subst = getSubstrate (); 00067 nr_double_t h = subst->getPropertyDouble ("h"); 00068 nr_double_t t = subst->getPropertyDouble ("t"); 00069 nr_double_t rho = subst->getPropertyDouble ("rho"); 00070 nr_double_t r = getPropertyDouble ("D") / 2; 00071 00072 // check frequency validity 00073 if (frequency * h >= 0.03 * C0) { 00074 logprint (LOG_ERROR, "WARNING: Model for microstrip via hole defined for " 00075 "freq/C0*h < 0.03 (is %g)\n", frequency / C0 * h); 00076 } 00077 00078 // create Z-parameter 00079 nr_double_t fs = pi * MU0 * sqr (t) / rho; 00080 nr_double_t res = R * std::sqrt (1 + frequency * fs); 00081 nr_double_t a = std::sqrt (sqr (r) + sqr (h)); 00082 nr_double_t ind = MU0 * (h * std::log ((h + a) / r) + 1.5 * (r - a)); 00083 return Z = nr_complex_t (res, frequency * ind); 00084 } 00085 00086 nr_double_t msvia::calcResistance (void) { 00087 // fetch substrate and component properties 00088 substrate * subst = getSubstrate (); 00089 nr_double_t h = subst->getPropertyDouble ("h"); 00090 nr_double_t t = subst->getPropertyDouble ("t"); 00091 nr_double_t rho = subst->getPropertyDouble ("rho"); 00092 nr_double_t r = getPropertyDouble ("D") / 2; 00093 nr_double_t v = h / pi / (sqr (r) - sqr (r - t)); 00094 return R = rho * v; 00095 } 00096 00097 void msvia::initDC (void) { 00098 nr_double_t r = calcResistance (); 00099 00100 // for non-zero resistances usual MNA entries 00101 if (r != 0.0) { 00102 nr_double_t g = 1.0 / r; 00103 setVoltageSources (0); 00104 allocMatrixMNA (); 00105 setY (NODE_1, NODE_1, +g); setY (NODE_2, NODE_2, +g); 00106 setY (NODE_1, NODE_2, -g); setY (NODE_2, NODE_1, -g); 00107 } 00108 // for zero resistances create a zero voltage source 00109 else { 00110 setVoltageSources (1); 00111 setInternalVoltageSource (1); 00112 allocMatrixMNA (); 00113 clearY (); 00114 voltageSource (VSRC_1, NODE_1, NODE_2); 00115 } 00116 } 00117 00118 void msvia::initAC (void) { 00119 setVoltageSources (0); 00120 allocMatrixMNA (); 00121 R = calcResistance (); 00122 } 00123 00124 void msvia::calcAC (nr_double_t frequency) { 00125 nr_complex_t y = 1.0 / calcImpedance (frequency); 00126 setY (NODE_1, NODE_1, +y); setY (NODE_2, NODE_2, +y); 00127 setY (NODE_1, NODE_2, -y); setY (NODE_2, NODE_1, -y); 00128 } 00129 00130 void msvia::calcNoiseAC (nr_double_t) { 00131 // calculate noise current correlation matrix 00132 nr_double_t y = real (1.0 / Z); 00133 nr_double_t T = getPropertyDouble ("Temp"); 00134 nr_double_t f = celsius2kelvin (T) / T0 * 4.0 * y; 00135 setN (NODE_1, NODE_1, +f); setN (NODE_2, NODE_2, +f); 00136 setN (NODE_1, NODE_2, -f); setN (NODE_2, NODE_1, -f); 00137 } 00138 00139 // properties 00140 PROP_REQ [] = { 00141 { "D", PROP_REAL, { 100e-6, PROP_NO_STR }, PROP_POS_RANGE }, 00142 { "Subst", PROP_STR, { PROP_NO_VAL, "Subst1" }, PROP_NO_RANGE }, 00143 PROP_NO_PROP }; 00144 PROP_OPT [] = { 00145 { "Temp", PROP_REAL, { 26.85, PROP_NO_STR }, PROP_MIN_VAL (K) }, 00146 PROP_NO_PROP }; 00147 struct define_t msvia::cirdef = 00148 { "MVIA", 2, PROP_COMPONENT, PROP_NO_SUBSTRATE, PROP_LINEAR, PROP_DEF };