Qucs-core
0.0.19
|
00001 /* 00002 * twistedpair.cpp - twisted pair line class implementation 00003 * 00004 * Copyright (C) 2007, 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 "twistedpair.h" 00031 00032 using namespace qucs; 00033 00034 twistedpair::twistedpair () : circuit (4) { 00035 type = CIR_TWISTEDPAIR; 00036 } 00037 00038 void twistedpair::initSP (void) { 00039 allocMatrixS (); 00040 calcLength (); 00041 } 00042 00043 void twistedpair::calcSP (nr_double_t frequency) { 00044 calcPropagation (frequency); 00045 00046 nr_complex_t g = nr_complex_t (alpha, beta); 00047 nr_double_t p = 2 * z0 + zl; 00048 nr_double_t n = 2 * z0 - zl; 00049 nr_complex_t e = qucs::exp (2.0 * g * len); 00050 nr_complex_t d = p * p * e - n * n; 00051 00052 nr_complex_t s11 = zl * (p * e + n) / d; 00053 nr_complex_t s14 = 1.0 - s11; 00054 nr_complex_t s12 = 4.0 * zl * z0 * qucs::exp (g * len) / d; 00055 00056 setS (NODE_1, NODE_1, +s11); setS (NODE_2, NODE_2, +s11); 00057 setS (NODE_3, NODE_3, +s11); setS (NODE_4, NODE_4, +s11); 00058 setS (NODE_1, NODE_4, +s14); setS (NODE_4, NODE_1, +s14); 00059 setS (NODE_2, NODE_3, +s14); setS (NODE_3, NODE_2, +s14); 00060 setS (NODE_1, NODE_2, +s12); setS (NODE_2, NODE_1, +s12); 00061 setS (NODE_3, NODE_4, +s12); setS (NODE_4, NODE_3, +s12); 00062 setS (NODE_1, NODE_3, -s12); setS (NODE_3, NODE_1, -s12); 00063 setS (NODE_2, NODE_4, -s12); setS (NODE_4, NODE_2, -s12); 00064 } 00065 00066 void twistedpair::calcNoiseSP (nr_double_t) { 00067 if (len < 0) return; 00068 // calculate noise using Bosma's theorem 00069 nr_double_t T = getPropertyDouble ("Temp"); 00070 matrix s = getMatrixS (); 00071 matrix e = eye (getSize ()); 00072 setMatrixN (celsius2kelvin (T) / T0 * (e - s * transpose (conj (s)))); 00073 } 00074 00075 void twistedpair::initDC (void) { 00076 nr_double_t d = getPropertyDouble ("d"); 00077 nr_double_t rho = getPropertyDouble ("rho"); 00078 calcLength (); 00079 00080 if (d != 0.0 && rho != 0.0 && len != 0.0) { 00081 // tiny resistances 00082 nr_double_t g1 = pi * sqr (d / 2) / rho / len; 00083 nr_double_t g2 = g1; 00084 setVoltageSources (0); 00085 allocMatrixMNA (); 00086 setY (NODE_1, NODE_1, +g1); setY (NODE_2, NODE_2, +g1); 00087 setY (NODE_1, NODE_2, -g1); setY (NODE_2, NODE_1, -g1); 00088 setY (NODE_3, NODE_3, +g2); setY (NODE_4, NODE_4, +g2); 00089 setY (NODE_3, NODE_4, -g2); setY (NODE_4, NODE_3, -g2); 00090 } 00091 else { 00092 // DC shorts 00093 setVoltageSources (2); 00094 allocMatrixMNA (); 00095 voltageSource (VSRC_1, NODE_1, NODE_2); 00096 voltageSource (VSRC_2, NODE_3, NODE_4); 00097 } 00098 } 00099 00100 void twistedpair::initAC (void) { 00101 calcLength (); 00102 if (len != 0.0) { 00103 setVoltageSources (0); 00104 allocMatrixMNA (); 00105 } else { 00106 setVoltageSources (2); 00107 allocMatrixMNA (); 00108 voltageSource (VSRC_1, NODE_1, NODE_2); 00109 voltageSource (VSRC_2, NODE_3, NODE_4); 00110 } 00111 } 00112 00113 nr_double_t twistedpair::calcLoss (nr_double_t frequency) { 00114 nr_double_t d = getPropertyDouble ("d"); 00115 nr_double_t rho = getPropertyDouble ("rho"); 00116 nr_double_t mur = getPropertyDouble ("mur"); 00117 nr_double_t tand = getPropertyDouble ("tand"); 00118 00119 nr_double_t delta, rout, rin, ad, ac, l0; 00120 // calculate conductor losses 00121 rout = d / 2; 00122 if (frequency > 0.0) { 00123 delta = qucs::sqrt (rho / (pi * frequency * MU0 * mur)); 00124 rin = rout - delta; 00125 if (rin < 0.0) rin = 0.0; 00126 } 00127 else rin = 0.0; 00128 ac = (rho * one_over_pi) / (rout * rout - rin * rin) / zl; 00129 00130 // calculate dielectric losses 00131 l0 = C0 / frequency; 00132 ad = pi * tand * qucs::sqrt (ereff) / l0; 00133 00134 alpha = ac + ad; 00135 return alpha; 00136 } 00137 00138 nr_double_t twistedpair::calcLength (void) { 00139 nr_double_t l = getPropertyDouble ("L"); 00140 nr_double_t T = getPropertyDouble ("T"); 00141 nr_double_t D = getPropertyDouble ("D"); 00142 len = l * T * pi * D * qucs::sqrt (1 + 1 / sqr (T * pi * D)); 00143 return len; 00144 } 00145 00146 void twistedpair::calcPropagation (nr_double_t frequency) { 00147 nr_double_t d = getPropertyDouble ("d"); 00148 nr_double_t D = getPropertyDouble ("D"); 00149 nr_double_t er = getPropertyDouble ("er"); 00150 nr_double_t T = getPropertyDouble ("T"); 00151 00152 nr_double_t q, p; 00153 p = qucs::atan (T * pi * D); 00154 q = 0.25 + 0.001 * p * p; // soft PTFE 00155 q = 0.25 + 0.0004 * p * p; // usual 00156 ereff = 1.0 + q * (er - 1.0); 00157 zl = Z0 / pi / qucs::sqrt (ereff) * qucs::acosh (D / d); 00158 beta = 2 * pi * frequency / C0 * qucs::sqrt (ereff); 00159 angle = rad2deg (p); 00160 alpha = calcLoss (frequency); 00161 } 00162 00163 void twistedpair::saveCharacteristics (nr_double_t) { 00164 setCharacteristic ("Zl", zl); 00165 setCharacteristic ("Er", ereff); 00166 setCharacteristic ("Length", len); 00167 setCharacteristic ("Angle", angle); 00168 } 00169 00170 void twistedpair::calcAC (nr_double_t frequency) { 00171 if (len != 0.0) { 00172 calcPropagation (frequency); 00173 nr_complex_t g = nr_complex_t (alpha, beta); 00174 nr_complex_t y11 = coth (g * len) / zl; 00175 nr_complex_t y21 = -cosech (g * len) / zl; 00176 setY (NODE_1, NODE_1, +y11); setY (NODE_2, NODE_2, +y11); 00177 setY (NODE_3, NODE_3, +y11); setY (NODE_4, NODE_4, +y11); 00178 setY (NODE_1, NODE_4, -y11); setY (NODE_4, NODE_1, -y11); 00179 setY (NODE_2, NODE_3, -y11); setY (NODE_3, NODE_2, -y11); 00180 setY (NODE_1, NODE_2, +y21); setY (NODE_2, NODE_1, +y21); 00181 setY (NODE_3, NODE_4, +y21); setY (NODE_4, NODE_3, +y21); 00182 setY (NODE_1, NODE_3, -y21); setY (NODE_3, NODE_1, -y21); 00183 setY (NODE_2, NODE_4, -y21); setY (NODE_4, NODE_2, -y21); 00184 } 00185 } 00186 00187 void twistedpair::calcNoiseAC (nr_double_t) { 00188 if (len < 0) return; 00189 // calculate noise using Bosma's theorem 00190 nr_double_t T = getPropertyDouble ("Temp"); 00191 setMatrixN (4 * celsius2kelvin (T) / T0 * real (getMatrixY ())); 00192 } 00193 00194 void twistedpair::initTR (void) { 00195 initDC (); 00196 } 00197 00198 // properties 00199 PROP_REQ [] = { 00200 { "d", PROP_REAL, { 0.5e-3, PROP_NO_STR }, PROP_POS_RANGEX }, 00201 { "D", PROP_REAL, { 0.8e-3, PROP_NO_STR }, PROP_POS_RANGEX }, 00202 { "L", PROP_REAL, { 1500e-3, PROP_NO_STR }, PROP_NO_RANGE }, 00203 { "T", PROP_REAL, { 100, PROP_NO_STR }, PROP_POS_RANGE }, 00204 { "er", PROP_REAL, { 4, PROP_NO_STR }, PROP_RNGII (1, 100) }, 00205 { "mur", PROP_REAL, { 1, PROP_NO_STR }, PROP_RNGII (1, 100) }, 00206 { "tand", PROP_REAL, { 4e-4, PROP_NO_STR }, PROP_POS_RANGE }, 00207 { "rho", PROP_REAL, { 0.022e-6, PROP_NO_STR }, PROP_POS_RANGE }, 00208 PROP_NO_PROP }; 00209 PROP_OPT [] = { 00210 { "Temp", PROP_REAL, { 26.85, PROP_NO_STR }, PROP_MIN_VAL (K) }, 00211 PROP_NO_PROP }; 00212 struct define_t twistedpair::cirdef = 00213 { "TWIST", 4, PROP_COMPONENT, PROP_NO_SUBSTRATE, PROP_LINEAR, PROP_DEF };