Qucs-core
0.0.19
|
00001 /* 00002 * resistor.cpp - resistor class implementation 00003 * 00004 * Copyright (C) 2003, 2004, 2005, 2006, 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 "resistor.h" 00031 00032 using namespace qucs; 00033 00034 resistor::resistor () : circuit (2) { 00035 type = CIR_RESISTOR; 00036 } 00037 00038 void resistor::initSP (void) { 00039 initModel (); 00040 allocMatrixS (); 00041 } 00042 00043 void resistor::calcSP (nr_double_t) { 00044 // calculate S-parameters 00045 nr_double_t z = getScaledProperty ("R") / z0; 00046 setS (NODE_1, NODE_1, z / (z + 2)); 00047 setS (NODE_2, NODE_2, z / (z + 2)); 00048 setS (NODE_1, NODE_2, 2 / (z + 2)); 00049 setS (NODE_2, NODE_1, 2 / (z + 2)); 00050 } 00051 00052 void resistor::calcNoiseSP (nr_double_t) { 00053 // calculate noise correlation matrix 00054 nr_double_t r = getScaledProperty ("R"); 00055 nr_double_t T = getPropertyDouble ("Temp"); 00056 nr_double_t f = celsius2kelvin (T) * 4.0 * r * z0 / sqr (2.0 * z0 + r) / T0; 00057 setN (NODE_1, NODE_1, +f); setN (NODE_2, NODE_2, +f); 00058 setN (NODE_1, NODE_2, -f); setN (NODE_2, NODE_1, -f); 00059 } 00060 00061 void resistor::calcNoiseAC (nr_double_t) { 00062 // calculate noise current correlation matrix 00063 nr_double_t r = getScaledProperty ("R"); 00064 if (r > 0.0 || r < 0.0) { 00065 nr_double_t T = getPropertyDouble ("Temp"); 00066 nr_double_t f = celsius2kelvin (T) / T0 * 4.0 / r; 00067 setN (NODE_1, NODE_1, +f); setN (NODE_2, NODE_2, +f); 00068 setN (NODE_1, NODE_2, -f); setN (NODE_2, NODE_1, -f); 00069 } 00070 } 00071 00072 void resistor::initModel (void) { 00073 /* if this is a controlled resistor then do nothing here */ 00074 if (hasProperty ("Controlled")) return; 00075 00076 nr_double_t T = getPropertyDouble ("Temp"); 00077 nr_double_t Tn = getPropertyDouble ("Tnom"); 00078 nr_double_t R = getPropertyDouble ("R"); 00079 nr_double_t DT = T - Tn; 00080 00081 // compute R temperature dependency 00082 nr_double_t Tc1 = getPropertyDouble ("Tc1"); 00083 nr_double_t Tc2 = getPropertyDouble ("Tc2"); 00084 R = R * (1 + DT * (Tc1 + Tc2 * DT)); 00085 setScaledProperty ("R", R); 00086 } 00087 00088 void resistor::initDC (void) { 00089 initModel (); 00090 nr_double_t r = getScaledProperty ("R"); 00091 00092 // for non-zero resistances usual MNA entries 00093 if (r != 0.0) { 00094 nr_double_t g = 1.0 / r; 00095 setVoltageSources (0); 00096 allocMatrixMNA (); 00097 setY (NODE_1, NODE_1, +g); setY (NODE_2, NODE_2, +g); 00098 setY (NODE_1, NODE_2, -g); setY (NODE_2, NODE_1, -g); 00099 } 00100 // for zero resistances create a zero voltage source 00101 else { 00102 setVoltageSources (1); 00103 setInternalVoltageSource (1); 00104 allocMatrixMNA (); 00105 voltageSource (VSRC_1, NODE_1, NODE_2); 00106 } 00107 } 00108 00109 /* The calcDC() function is here partly implemented again because the 00110 circuit can be used to simulate controlled non-zero resistances. */ 00111 void resistor::calcDC (void) { 00112 nr_double_t r = getScaledProperty ("R"); 00113 00114 // for non-zero resistances usual MNA entries 00115 if (r != 0.0) { 00116 nr_double_t g = 1.0 / r; 00117 setY (NODE_1, NODE_1, +g); setY (NODE_2, NODE_2, +g); 00118 setY (NODE_1, NODE_2, -g); setY (NODE_2, NODE_1, -g); 00119 } 00120 } 00121 00122 void resistor::initAC (void) { 00123 initDC (); 00124 } 00125 00126 void resistor::calcAC (nr_double_t) { 00127 calcDC (); 00128 } 00129 00130 void resistor::initTR (void) { 00131 initDC (); 00132 } 00133 00134 void resistor::calcTR (nr_double_t) { 00135 calcDC (); 00136 } 00137 00138 // Initialize computation of MNA matrix entries for HB. 00139 void resistor::initHB (void) { 00140 initModel (); 00141 nr_double_t r = getScaledProperty ("R"); 00142 setVoltageSources (1); 00143 setInternalVoltageSource (1); 00144 allocMatrixMNA (); 00145 voltageSource (VSRC_1, NODE_1, NODE_2); 00146 setD (VSRC_1, VSRC_1, -r); 00147 } 00148 00149 // properties 00150 PROP_REQ [] = { 00151 { "R", PROP_REAL, { 50, PROP_NO_STR }, PROP_NO_RANGE }, PROP_NO_PROP }; 00152 PROP_OPT [] = { 00153 { "Temp", PROP_REAL, { 26.85, PROP_NO_STR }, PROP_MIN_VAL (K) }, 00154 { "Tc1", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE }, 00155 { "Tc2", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE }, 00156 { "Tnom", PROP_REAL, { 26.85, PROP_NO_STR }, PROP_MIN_VAL (K) }, 00157 PROP_NO_PROP }; 00158 struct define_t resistor::cirdef = 00159 { "R", 2, PROP_COMPONENT, PROP_NO_SUBSTRATE, PROP_LINEAR, PROP_DEF };