Qucs-core  0.0.19
mutualx.cpp
Go to the documentation of this file.
00001 /*
00002  * mutualx.cpp - multiple mutual inductors 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 "mutualx.h"
00031 
00032 using namespace qucs;
00033 
00034 mutualx::mutualx () : circuit () {
00035   type = CIR_MUTUALX;
00036   setVariableSized (true);
00037 }
00038 
00039 void mutualx::calcSP (nr_double_t frequency) {
00040   setMatrixS (ytos (calcMatrixY (frequency)));
00041 }
00042 
00043 matrix mutualx::calcMatrixY (nr_double_t frequency) {
00044 #if 1
00045   matrix ts = ztos (calcMatrixZ (frequency));
00046   matrix ty = stoy (ts);
00047 #else
00048   matrix ty = ztoy (calcMatrixZ (frequency));
00049 #endif
00050   int r, c;
00051   int inductors = getSize () / 2;
00052   matrix y = matrix (inductors * 2);
00053 
00054   for (r = 0; r < inductors; r++) {
00055     for (c = 0; c < inductors; c++) {
00056       y.set (2 * r + 0, 2 * c + 0, +ty (r, c));
00057       y.set (2 * r + 1, 2 * c + 1, +ty (r, c));
00058       y.set (2 * r + 0, 2 * c + 1, -ty (r, c));
00059       y.set (2 * r + 1, 2 * c + 0, -ty (r, c));
00060     }
00061   }
00062   return y;
00063 }
00064 
00065 matrix mutualx::calcMatrixZ (nr_double_t frequency) {
00066   int inductors = getSize () / 2;
00067   int r, c, state;
00068   qucs::vector * L = getPropertyVector ("L");
00069   qucs::vector * C = getPropertyVector ("k");
00070   nr_double_t o = 2 * pi * frequency;
00071   matrix z = matrix (inductors);
00072 
00073   // fill Z-Matrix entries
00074   for (state = 0, r = 0; r < inductors; r++) {
00075     for (c = 0; c < inductors; c++, state++) {
00076       nr_double_t l1 = real (L->get (r));
00077       nr_double_t l2 = real (L->get (c));
00078       nr_double_t k = real (C->get (state)) * std::sqrt (l1 * l2);
00079       z.set (r, c, nr_complex_t (0.0, k * o));
00080     }
00081   }
00082   return z;
00083 }
00084 
00085 void mutualx::initAC (void) {
00086   initDC ();
00087 }
00088 
00089 void mutualx::calcAC (nr_double_t frequency) {
00090   int inductors = getSize () / 2;
00091   int r, c, state;
00092   qucs::vector * L = getPropertyVector ("L");
00093   qucs::vector * C = getPropertyVector ("k");
00094   nr_double_t o = 2 * pi * frequency;
00095 
00096   // fill D-Matrix
00097   for (state = 0, r = 0; r < inductors; r++) {
00098     for (c = 0; c < inductors; c++, state++) {
00099       nr_double_t l1 = real (L->get (r));
00100       nr_double_t l2 = real (L->get (c));
00101       nr_double_t k = real (C->get (state)) * std::sqrt (l1 * l2);
00102       setD (VSRC_1 + r, VSRC_1 + c, nr_complex_t (0.0, k * o));
00103     }
00104   }
00105 }
00106 
00107 void mutualx::initDC (void) {
00108   int inductors = getSize () / 2;
00109   setVoltageSources (inductors);
00110   allocMatrixMNA ();
00111   // fill C and B-Matrix entries
00112   for (int i = 0; i < inductors; i++)
00113     voltageSource (VSRC_1 + i, NODE_1 + i * 2, NODE_2 + i * 2);
00114 }
00115 
00116 void mutualx::initTR (void) {
00117   int inductors = getSize () / 2;
00118   initDC ();
00119   setStates (inductors * inductors * 2);
00120 }
00121 
00122 void mutualx::calcTR (nr_double_t) {
00123   int inductors = getSize () / 2;
00124   int r, c, state;
00125   qucs::vector * L = getPropertyVector ("L");
00126   qucs::vector * C = getPropertyVector ("k");
00127 
00128   nr_double_t * veq = new nr_double_t[inductors * inductors];
00129   nr_double_t * req = new nr_double_t[inductors * inductors];
00130 
00131   // integration for self and mutual inductances
00132   for (state = 0, r = 0; r < inductors; r++) {
00133     for (c = 0; c < inductors; c++, state++) {
00134       nr_double_t l1 = real (L->get (r));
00135       nr_double_t l2 = real (L->get (c));
00136       nr_double_t i = real (getJ (VSRC_1 + c));
00137       nr_double_t k = real (C->get (state)) * std::sqrt (l1 * l2);
00138       setState  (2 * state, i * k);
00139       integrate (2 * state, k, req[state], veq[state]);
00140     }
00141   }
00142 
00143   // fill D-Matrix entries and extended RHS
00144   for (state = 0, r = 0; r < inductors; r++) {
00145     nr_double_t v = 0;
00146     for (c = 0; c < inductors; c++, state++) {
00147       setD (VSRC_1 + r, VSRC_1 + c, -req[state]);
00148       v += veq[state];
00149     }
00150     setE (VSRC_1 + r, v);
00151   }
00152 
00153   delete[] veq;
00154   delete[] req;
00155 }
00156 
00157 // properties
00158 PROP_REQ [] = {
00159   { "L", PROP_LIST, { 1e-9, PROP_NO_STR }, PROP_POS_RANGE },
00160   { "k", PROP_LIST, { 0.9, PROP_NO_STR }, PROP_RNGII (-1, +1) },
00161   PROP_NO_PROP };
00162 PROP_OPT [] = {
00163   PROP_NO_PROP };
00164 struct define_t mutualx::cirdef =
00165   { "MUTX",
00166     PROP_NODES, PROP_COMPONENT, PROP_NO_SUBSTRATE, PROP_LINEAR, PROP_DEF };