Qucs-core  0.0.18
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
rfedd.cpp
Go to the documentation of this file.
1 /*
2  * rfedd.cpp - equation defined RF device class implementation
3  *
4  * Copyright (C) 2008 Stefan Jahn <stefan@lkcc.org>
5  *
6  * This is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2, or (at your option)
9  * any later version.
10  *
11  * This software is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this package; see the file COPYING. If not, write to
18  * the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  *
21  * $Id$
22  *
23  */
24 
25 #if HAVE_CONFIG_H
26 # include <config.h>
27 #endif
28 
29 #include "component.h"
30 #include "equation.h"
31 #include "environment.h"
32 #include "rfedd.h"
33 
34 using namespace qucs;
35 using namespace qucs::eqn;
36 
37 // Constructor for the equation defined RF device.
38 rfedd::rfedd () : circuit () {
39  type = CIR_RFEDD;
40  setVariableSized (true);
41  peqn = NULL;
42 }
43 
44 // Destructor deletes equation defined RF device object from memory.
46  if (peqn) free (peqn);
47 }
48 
49 // Callback for initializing the DC analysis.
50 void rfedd::initDC (void) {
51 
52  // get appropriate property value
53  char * dc = getPropertyString ("duringDC");
54 
55  // a short during DC
56  if (!strcmp (dc, "short")) {
57  int v, n, lastnode = getSize () - 1;
58  setVoltageSources (lastnode);
59  allocMatrixMNA ();
60  // place zero voltage sources
61  for (v = VSRC_1, n = NODE_1; n < lastnode; n++, v++) {
62  voltageSource (v, n, lastnode);
63  }
64  return;
65  }
66  // an open during DC
67  else if (!strcmp (dc, "open")) {
69  allocMatrixMNA ();
70  return;
71  }
72  // zero frequency evaluation
73  else if (!strcmp (dc, "zerofrequency")) {
74  prepareModel ();
75  initMNA ();
76  calcMNA (0);
77  return;
78  }
79  // none specified, DC value of IDFT ?
80  else {
82  allocMatrixMNA ();
83  }
84 }
85 
86 // Some help macros.
87 #define A(a) ((assignment *) (a))
88 
89 // Creates a parameter variable name from the given arguments.
90 char * rfedd::createVariable (const char * base, int r, int c, bool pfx) {
91  char * str = strchr (getName (), '.');
92  if (str != NULL)
93  str = strrchr (str, '.') + 1;
94  else
95  str = getName ();
96  char * txt = (char *) malloc (strlen (str) + strlen (base) + 4);
97  if (pfx)
98  sprintf (txt, "%s.%s%d%d", str, base, r, c);
99  else
100  sprintf (txt, "%s%d%d", base, r, c);
101  return txt;
102 }
103 
104 // Creates a variable name from the given arguments.
105 char * rfedd::createVariable (const char * base, bool pfx) {
106  char * str = strchr (getName (), '.');
107  if (str != NULL)
108  str = strrchr (str, '.') + 1;
109  else
110  str = getName ();
111  char * txt = (char *) malloc (strlen (str) + strlen (base) + 2);
112  if (pfx)
113  sprintf (txt, "%s.%s", str, base);
114  else
115  sprintf (txt, "%s", base);
116  return txt;
117 }
118 
119 // Saves the given real value into the equation result.
120 void rfedd::setResult (void * eqn, nr_double_t val) {
121  A(eqn)->evaluate ();
122  constant * c = A(eqn)->getResult ();
123  c->d = val;
124 }
125 
126 // Saves the given complex value into the equation result.
127 void rfedd::setResult (void * eqn, nr_complex_t val) {
128  A(eqn)->evaluate ();
129  constant * c = A(eqn)->getResult ();
130  *(c->c) = val;
131 }
132 
133 // Returns the result of the equation.
135  A(eqn)->evaluate ();
136  return A(eqn)->getResultComplex ();
137 }
138 
139 // Initializes the equation defined device.
140 void rfedd::initModel (void) {
141  int i, j, k, ports = getSize ();
142  char * type, * pn, * sn, * snold, * fn, * fnold, * vr;
143  eqn::node * pvalue;
144 
145  // allocate space for equation pointers
146  peqn = (void **) malloc (sizeof (assignment *) * ports * ports);
147 
148  // first create frequency variables
149  sn = createVariable ("S");
150  snold = createVariable ("S", false);
151  fn = createVariable ("F");
152  fnold = createVariable ("F", false);
153  seqn = getEnv()->getChecker()->addComplex ("#laplace", sn, nr_complex_t (0, 0));
154  feqn = getEnv()->getChecker()->addDouble ("#frequency", fn, 0);
155  A(seqn)->evalType (); A(seqn)->skip = 1;
156  A(feqn)->evalType (); A(feqn)->skip = 1;
157 
158  // obtain type of parameters
159  type = getPropertyString ("Type");
160 
161  // prepare device equations
162  for (k = 0, i = 0; i < ports; i++) {
163  for (j = 0; j < ports; j++, k++) {
164  // find equation referenced in property
165  pn = createVariable ("P", i + 1, j + 1, false);
166  vr = getPropertyReference (pn);
167  pvalue = getEnv()->getChecker()->findEquation (vr);
168  if (!pvalue) {
169  logprint (LOG_ERROR, "ERROR: %s-parameter equation `%s' not found for "
170  "RFEDD `%s'\n", type, vr, getName ());
171  }
172  else {
173  // replace references to S and F by local references
174  pvalue->replace (snold, sn);
175  pvalue->replace (fnold, fn);
176  // evaluate types of parameters
177  A(pvalue)->evalType ();
178  A(pvalue)->skip = 1;
179  }
180  // save equations for parameters
181  peqn[k] = pvalue;
182  free (pn);
183  }
184  }
185 
186  free (sn); free (snold);
187  free (fn); free (fnold);
188 }
189 
190 // Prepares model equations if necessary.
191 void rfedd::prepareModel (void) {
192  if (peqn == NULL) initModel ();
193 }
194 
195 // Update local variable equations.
196 void rfedd::updateLocals (nr_double_t frequency) {
197 
198  // update frequency variables for equations
199  setResult (seqn, nr_complex_t (0, 2 * M_PI * frequency));
200  setResult (feqn, frequency);
201 
202  // get local subcircuit values
203  getEnv()->passConstants ();
204  getEnv()->equationSolver ();
205 }
206 
207 // Callback for DC analysis.
208 void rfedd::calcDC (void) {
209 }
210 
211 // Initializes MNA representation depending on parameter type.
212 void rfedd::initMNA (void) {
213  int i, ports = getSize ();
214  char * type = getPropertyString ("Type");
215  switch (type[0]) {
216  case 'Y':
217  setVoltageSources (0);
218  allocMatrixMNA ();
219  break;
220  case 'Z':
221  setVoltageSources (ports);
222  allocMatrixMNA ();
223  for (i = 0; i < ports; i++) setC (i, i, -1);
224  for (i = 0; i < ports; i++) setB (i, i, +1);
225  break;
226  case 'S':
227  setVoltageSources (ports);
228  allocMatrixMNA ();
229  for (i = 0; i < ports; i++) setB (i, i, +1);
230  break;
231  case 'H':
232  setVoltageSources (1);
233  allocMatrixMNA ();
234  setB (0, 0, +1); setC (0, 0, -1);
235  break;
236  case 'G':
237  setVoltageSources (1);
238  allocMatrixMNA ();
239  setB (1, 0, +1); setC (0, 1, -1);
240  break;
241  case 'A':
242  setVoltageSources (1);
243  allocMatrixMNA ();
244  setB (1, 0, -1); setC (0, 0, -1);
245  break;
246  case 'T':
247  setVoltageSources (2);
248  allocMatrixMNA ();
249  setB (0, 0, +1); setB (1, 1, +1);
250  setC (0, 0, -1); setC (1, 0, -1);
251  break;
252  }
253 }
254 
255 // Calculates MNA representation depending on parameter type.
256 void rfedd::calcMNA (nr_double_t frequency) {
257  char * type = getPropertyString ("Type");
258  int r, c, ports = getSize ();
259  matrix p = calcMatrix (frequency);
260  switch (type[0]) {
261  case 'Y':
262  setMatrixY (p);
263  break;
264  case 'Z':
265  for (r = 0; r < ports; r++)
266  for (c = 0; c < ports; c++)
267  setD (r, c, p (r, c));
268  break;
269  case 'S':
270  for (r = 0; r < ports; r++)
271  for (c = 0; c < ports; c++) {
272  if (r == c) {
273  setC (r, c, p (r, c) - 1.0);
274  setD (r, c, z0 * (p (r, c) + 1.0));
275  }
276  else {
277  setC (r, c, p (r, c));
278  setD (r, c, z0 * p (r, c));
279  }
280  }
281  break;
282  case 'H':
283  setY (1, 1, p (1, 1)); setB (1, 0, p (1, 0));
284  setC (0, 1, p (0, 1)); setD (0, 0, p (0, 0));
285  break;
286  case 'G':
287  setY (0, 0, p (0, 0)); setB (0, 0, p (0, 1));
288  setC (0, 0, p (1, 0)); setD (0, 0, p (1, 1));
289  break;
290  case 'A':
291  setY (0, 1, p (1, 0)); setB (0, 0, p (1, 1));
292  setC (0, 1, p (0, 0)); setD (0, 0, p (0, 1));
293  break;
294  case 'T':
295  setC (0, 1, p (0, 1) + p (0, 0));
296  setC (1, 1, p (1, 1) + p (1, 0));
297  setD (0, 0, -z0);
298  setD (1, 0, +z0);
299  setD (0, 1, z0 * (p (0, 1) - p (0, 0)));
300  setD (1, 1, z0 * (p (1, 1) - p (1, 0)));
301  break;
302  }
303 }
304 
305 // Callback for initializing the AC analysis.
306 void rfedd::initAC (void) {
307  initMNA ();
308  prepareModel ();
309 }
310 
311 // Callback for AC analysis.
312 void rfedd::calcAC (nr_double_t frequency) {
313  calcMNA (frequency);
314 }
315 
316 // Computes parameter matrix.
317 matrix rfedd::calcMatrix (nr_double_t frequency) {
318  int i, j, k, ports = getSize ();
319  matrix p (ports);
320 
321  // update local equations
322  updateLocals (frequency);
323 
324  // calculate parameters and put into Jacobian
325  for (k = 0, i = 0; i < ports; i++) {
326  for (j = 0; j < ports; j++, k++) {
327  p (i, j) = getResult (peqn[k]);
328  }
329  }
330 
331  return p;
332 }
333 
334 // Callback for initializing the TR analysis.
335 void rfedd::initTR (void) {
336  initDC ();
337 }
338 
339 // Callback for the TR analysis.
340 void rfedd::calcTR (nr_double_t) {
341  calcDC ();
342 }
343 
344 // Callback for initializing the S-parameter analysis.
345 void rfedd::initSP (void) {
346  allocMatrixS ();
347  prepareModel ();
348 }
349 
350 // Callback for S-parameter analysis.
351 void rfedd::calcSP (nr_double_t frequency) {
352  char * type = getPropertyString ("Type");
353  matrix p = calcMatrix (frequency);
354  switch (type[0]) {
355  case 'Y':
356  setMatrixS (ytos (p));
357  break;
358  case 'Z':
359  setMatrixS (ztos (p));
360  break;
361  case 'S':
362  setMatrixS (p);
363  break;
364  case 'H':
365  setMatrixS (twoport (p, 'H', 'S'));
366  break;
367  case 'G':
368  setMatrixS (twoport (p, 'G', 'S'));
369  break;
370  case 'A':
371  setMatrixS (twoport (p, 'A', 'S'));
372  break;
373  case 'T':
374  setMatrixS (twoport (p, 'T', 'S'));
375  break;
376  }
377 }
378 
379 // properties
380 PROP_REQ [] = {
381  { "Type", PROP_STR, { PROP_NO_VAL, "Y" },
382  PROP_RNG_STR7 ("Y", "Z", "S", "H", "G", "A", "T") },
383  { "duringDC", PROP_STR, { PROP_NO_VAL, "open" },
384  PROP_RNG_STR4 ("open", "short", "unspecified", "zerofrequency") },
385  { "P11", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
386  PROP_NO_PROP };
387 PROP_OPT [] = {
388  { "P12", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
389  { "P13", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
390  { "P14", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
391  { "P15", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
392  { "P16", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
393  { "P17", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
394  { "P18", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
395  { "P21", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
396  { "P22", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
397  { "P23", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
398  { "P24", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
399  { "P25", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
400  { "P26", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
401  { "P27", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
402  { "P28", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
403  { "P31", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
404  { "P32", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
405  { "P33", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
406  { "P34", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
407  { "P35", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
408  { "P36", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
409  { "P37", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
410  { "P38", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
411  { "P41", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
412  { "P42", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
413  { "P43", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
414  { "P44", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
415  { "P45", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
416  { "P46", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
417  { "P47", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
418  { "P48", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
419  { "P51", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
420  { "P52", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
421  { "P53", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
422  { "P54", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
423  { "P55", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
424  { "P56", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
425  { "P57", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
426  { "P58", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
427  { "P61", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
428  { "P62", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
429  { "P63", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
430  { "P64", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
431  { "P65", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
432  { "P66", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
433  { "P67", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
434  { "P68", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
435  { "P71", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
436  { "P72", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
437  { "P73", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
438  { "P74", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
439  { "P75", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
440  { "P76", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
441  { "P77", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
442  { "P78", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
443  { "P81", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
444  { "P82", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
445  { "P83", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
446  { "P84", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
447  { "P85", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
448  { "P86", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
449  { "P87", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
450  { "P88", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE },
451  PROP_NO_PROP };
452 struct define_t rfedd::cirdef =
453  { "RFEDD",
std::complex< nr_double_t > nr_complex_t
Definition: complex.h:31
void * feqn
Definition: rfedd.h:58
matrix ytos(matrix y, qucs::vector z0)
Admittance matrix to scattering parameters.
Definition: matrix.cpp:1133
char * getPropertyReference(const char *)
Definition: object.cpp:167
~rfedd()
Definition: rfedd.cpp:45
#define PROP_DEF
Definition: netdefs.h:189
void ** peqn
Definition: rfedd.h:56
void calcSP(nr_double_t)
Definition: rfedd.cpp:351
void setD(int, int, nr_complex_t)
Definition: circuit.cpp:373
void prepareModel(void)
Definition: rfedd.cpp:191
#define PROP_REAL
Definition: netdefs.h:174
void calcTR(nr_double_t)
Definition: rfedd.cpp:340
qucs::matrix calcMatrix(nr_double_t)
Definition: rfedd.cpp:317
eqn::checker * getChecker(void)
Definition: environment.h:73
#define PROP_NO_PROP
Definition: netdefs.h:122
void setVoltageSources(int)
Definition: circuit.cpp:607
#define PROP_NO_RANGE
Definition: netdefs.h:126
matrix twoport(matrix m, char in, char out)
Generic conversion matrix.
Definition: matrix.cpp:1594
void initSP(void)
placehoder for S-Parameter initialisation function
Definition: rfedd.cpp:345
#define PROP_NO_STR
Definition: netdefs.h:125
void setB(int, int, nr_complex_t)
Definition: circuit.cpp:349
void allocMatrixS(void)
Definition: circuit.cpp:251
n
Definition: parse_citi.y:147
#define PROP_LINEAR
Definition: netdefs.h:120
char * createVariable(const char *, int, int, bool prefix=true)
Definition: rfedd.cpp:90
static const nr_double_t z0
Definition: circuit.h:320
r
Definition: parse_mdl.y:515
int equationSolver(dataset *)
int getSize(void)
Get the number of ports the circuit element has.
Definition: circuit.h:143
Definition: rfedd.cpp:452
#define PROP_NODES
Definition: netdefs.h:121
void initDC(void)
Definition: rfedd.cpp:50
#define VSRC_1
Definition: circuit.h:40
i
Definition: parse_mdl.y:516
void calcAC(nr_double_t)
Definition: rfedd.cpp:312
void * seqn
Definition: rfedd.h:57
#define PROP_COMPONENT
Definition: netdefs.h:116
matrix ztos(matrix z, qucs::vector z0)
Convert impedance matrix scattering parameters.
Definition: matrix.cpp:1018
free($1)
nr_double_t d
Definition: equation.h:169
environment * getEnv(void)
Definition: circuit.h:180
void setMatrixY(matrix)
Definition: circuit.cpp:685
void initAC(void)
Definition: rfedd.cpp:306
nr_complex_t * c
Definition: equation.h:170
#define M_PI
Archimedes' constant ( )
Definition: consts.h:47
#define PROP_RNG_STR4(s1, s2, s3, s4)
Definition: netdefs.h:149
void initTR(void)
Definition: rfedd.cpp:335
void initModel(void)
Definition: rfedd.cpp:140
void setMatrixS(matrix)
Definition: circuit.cpp:643
void setY(int, int, nr_complex_t)
Definition: circuit.cpp:452
void calcDC(void)
Definition: rfedd.cpp:208
v
Definition: parse_zvr.y:141
void allocMatrixMNA(void)
Definition: circuit.cpp:267
#define PROP_STR
Definition: netdefs.h:175
nr_complex_t getResult(void *)
Definition: rfedd.cpp:134
void setVariableSized(bool v)
Definition: circuit.h:169
The environment class definition.
#define NODE_1
Definition: circuit.h:34
void voltageSource(int, int, int, nr_double_t value=0.0)
Definition: circuit.cpp:748
void passConstants(void)
#define PROP_RNG_STR7(s1, s2, s3, s4, s5, s6, s7)
Definition: netdefs.h:155
#define strchr
Definition: compat.h:33
#define LOG_ERROR
Definition: logging.h:28
char * getName(void)
Definition: object.cpp:84
void updateLocals(nr_double_t)
Definition: rfedd.cpp:196
node
#define A(a)
Definition: rfedd.cpp:87
#define PROP_NO_VAL
Definition: netdefs.h:124
void setC(int, int, nr_complex_t)
Definition: circuit.cpp:361
void calcMNA(nr_double_t)
Definition: rfedd.cpp:256
char * getPropertyString(const char *)
Definition: object.cpp:159
void initMNA(void)
Definition: rfedd.cpp:212
void logprint(int level, const char *format,...)
Definition: logging.c:37
void setResult(void *, nr_double_t)
Definition: rfedd.cpp:120
PROP_OPT[]
Definition: rfedd.cpp:387
#define strrchr
Definition: compat.h:34
PROP_REQ[]
Definition: rfedd.cpp:380
#define PROP_NO_SUBSTRATE
Definition: netdefs.h:118