Qucs-core
0.0.19
|
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 };