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