Qucs-core  0.0.19
msvia.cpp
Go to the documentation of this file.
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 };