Qucs-core  0.0.18
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
circuit.cpp
Go to the documentation of this file.
1 /*
2  * circuit.cpp - circuit class implementation
3  *
4  * Copyright (C) 2003, 2004, 2005, 2006, 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 <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <assert.h>
33 
34 #include "logging.h"
35 #include "complex.h"
36 #include "object.h"
37 #include "matrix.h"
38 #include "node.h"
39 #include "property.h"
40 #include "valuelist.h"
41 #include "tvector.h"
42 #include "history.h"
43 #include "circuit.h"
44 #include "microstrip/substrate.h"
45 #include "operatingpoint.h"
46 #include "characteristic.h"
47 #include "component_id.h"
48 
49 namespace qucs {
50 
51 // normalising impedance
52 const nr_double_t circuit::z0 = 50.0;
53 
54 // Constructor creates an unnamed instance of the circuit class.
56  size = 0;
57  MatrixN = MatrixS = MatrixY = NULL;
58  MatrixB = MatrixC = MatrixD = NULL;
59  VectorQ = VectorE = VectorI = VectorV = VectorJ = NULL;
60  MatrixQV = NULL;
61  VectorCV = VectorGV = NULL;
62  nodes = NULL;
63  pacport = 0;
64  pol = 1;
66  subst = NULL;
67  vsource = -1;
68  vsources = 0;
69  nsources = 0;
70  inserted = -1;
71  subcircuit = NULL;
72  subnet = NULL;
73  deltas = NULL;
74  histories = NULL;
75  nHistories = 0;
76  type = CIR_UNKNOWN;
77 }
78 
79 /* Constructor creates an unnamed instance of the circuit class with a
80  certain number of ports. */
82  assert (s >= 0);
83  size = s;
84  if (size > 0) nodes = new node[s];
85  MatrixN = MatrixS = MatrixY = NULL;
86  MatrixB = MatrixC = MatrixD = NULL;
87  VectorQ = VectorE = VectorI = VectorV = VectorJ = NULL;
88  MatrixQV = NULL;
89  VectorCV = VectorGV = NULL;
90  pacport = 0;
91  pol = 1;
93  subst = NULL;
94  vsource = -1;
95  vsources = 0;
96  nsources = 0;
97  inserted = -1;
98  subcircuit = NULL;
99  subnet = NULL;
100  deltas = NULL;
101  histories = NULL;
102  nHistories = 0;
103  type = CIR_UNKNOWN;
104 }
105 
106 /* The copy constructor creates a new instance based on the given
107  circuit object. */
109  size = c.size;
110  pol = c.pol;
111  pacport = c.pacport;
112  flag = c.flag;
113  type = c.type;
114  subst = c.subst;
115  vsource = c.vsource;
116  vsources = c.vsources;
117  nsources = c.nsources;
118  inserted = c.inserted;
119  subnet = c.subnet;
120  deltas = c.deltas;
122  histories = NULL;
123  subcircuit = c.subcircuit ? strdup (c.subcircuit) : NULL;
124 
125  if (size > 0) {
126  // copy each node and set its circuit to the current circuit object
127  nodes = new node[size];
128  for (int i = 0; i < size; i++) {
129  nodes[i] = node (c.nodes[i]);;
130  nodes[i].setCircuit (this);
131  }
132  // copy each s-parameter
133  if (c.MatrixS) {
134  allocMatrixS ();
135  memcpy (MatrixS, c.MatrixS, size * size * sizeof (nr_complex_t));
136  }
137  // copy each noise-correlation parameter
138  if (c.MatrixN) {
140  int i = size + nsources;
141  memcpy (MatrixN, c.MatrixN, i * i * sizeof (nr_complex_t));
142  }
143  // copy each HB-matrix entry
144  if (c.MatrixQV) {
145  allocMatrixHB ();
146  memcpy (MatrixQV, c.MatrixQV, size * size * sizeof (nr_complex_t));
147  memcpy (VectorGV, c.VectorGV, size * sizeof (nr_complex_t));
148  memcpy (VectorCV, c.VectorCV, size * sizeof (nr_complex_t));
149  memcpy (VectorQ, c.VectorQ, size * sizeof (nr_complex_t));
150  }
151  // copy each G-MNA matrix entry
152  if (c.MatrixY) {
153  allocMatrixMNA ();
154  memcpy (MatrixY, c.MatrixY, size * size * sizeof (nr_complex_t));
155  memcpy (VectorI, c.VectorI, size * sizeof (nr_complex_t));
156  memcpy (VectorV, c.VectorV, size * sizeof (nr_complex_t));
157  if (vsources > 0) {
158  memcpy (MatrixB, c.MatrixB, vsources * size * sizeof (nr_complex_t));
159  memcpy (MatrixC, c.MatrixC, vsources * size * sizeof (nr_complex_t));
160  memcpy (MatrixD, c.MatrixD, vsources * vsources * sizeof (nr_complex_t));
161  memcpy (VectorE, c.VectorE, vsources * sizeof (nr_complex_t));
162  memcpy (VectorJ, c.VectorJ, vsources * sizeof (nr_complex_t));
163  }
164  }
165  }
166  else {
167  nodes = NULL;
168  MatrixS = MatrixN = MatrixY = NULL;
169  MatrixB = MatrixC = MatrixD = NULL;
170  VectorQ = VectorE = VectorI = VectorV = VectorJ = NULL;
171  MatrixQV = NULL;
172  VectorCV = VectorGV = NULL;
173  }
174 
175  // copy operating points
177 }
178 
179 // Destructor deletes a circuit object.
181  if (size > 0) {
182  if (MatrixS) delete[] MatrixS;
183  if (MatrixN) delete[] MatrixN;
184  freeMatrixMNA ();
185  freeMatrixHB ();
186  delete[] nodes;
187  }
188  if (subcircuit) free (subcircuit);
189  deleteHistory ();
190 }
191 
192 /* With this function the number of ports of the circuit object can be
193  changed. Previously stored node and matrix information gets
194  completely lost except the current size equals the given size. */
195 void circuit::setSize (int s) {
196  // nothing to do here
197  if (size == s) return;
198  assert (s >= 0);
199 
200  if (size > 0) {
201  // destroy any matrix and node information
202  if (MatrixS) delete[] MatrixS;
203  if (MatrixN) delete[] MatrixN;
204  MatrixS = MatrixN = NULL;
205  freeMatrixMNA ();
206  delete[] nodes; nodes = NULL;
207  }
208 
209  if ((size = s) > 0) {
210  // re-create matrix and node information space
211  nodes = new node[size];
212  allocMatrixS ();
214  allocMatrixMNA ();
215  }
216 }
217 
218 /* Destroys the HB-matrix memory. */
220  if (VectorQ) { delete[] VectorQ; VectorQ = NULL; }
221  if (MatrixQV) { delete[] MatrixQV; MatrixQV = NULL; }
222  if (VectorCV) { delete[] VectorCV; VectorCV = NULL; }
223  if (VectorGV) { delete[] VectorGV; VectorGV = NULL; }
224 }
225 
226 /* Allocates the HB-matrix memory. */
228  if (VectorQ) {
229  memset (VectorQ, 0, size * sizeof (nr_complex_t));
230  } else {
231  VectorQ = new nr_complex_t[size];
232  }
233  if (MatrixQV) {
234  memset (MatrixQV, 0, size * size * sizeof (nr_complex_t));
235  } else {
236  MatrixQV = new nr_complex_t[size * size];
237  }
238  if (VectorCV) {
239  memset (VectorCV, 0, size * sizeof (nr_complex_t));
240  } else {
241  VectorCV = new nr_complex_t[size];
242  }
243  if (VectorGV) {
244  memset (VectorGV, 0, size * sizeof (nr_complex_t));
245  } else {
246  VectorGV = new nr_complex_t[size];
247  }
248 }
249 
250 /* Allocates the S-parameter matrix memory. */
252  if (MatrixS) {
253  memset (MatrixS, 0, size * size * sizeof (nr_complex_t));
254  } else {
255  MatrixS = new nr_complex_t[size * size];
256  }
257 }
258 
259 /* Allocates the noise correlation matrix memory. */
260 void circuit::allocMatrixN (int sources) {
261  nsources = sources;
262  if (MatrixN) delete[] MatrixN;
263  MatrixN = new nr_complex_t[(size + sources) * (size + sources)];
264 }
265 
266 /* Allocates the matrix memory for the MNA matrices. */
268  freeMatrixMNA ();
269  if (size > 0) {
270  MatrixY = new nr_complex_t[size * size];
271  VectorI = new nr_complex_t[size];
272  VectorV = new nr_complex_t[size];
273  if (vsources > 0) {
279  }
280  }
281 }
282 
283 /* Free()'s all memory used by the MNA matrices. */
285  if (MatrixY) { delete[] MatrixY; MatrixY = NULL; }
286  if (MatrixB) { delete[] MatrixB; MatrixB = NULL; }
287  if (MatrixC) { delete[] MatrixC; MatrixC = NULL; }
288  if (MatrixD) { delete[] MatrixD; MatrixD = NULL; }
289  if (VectorE) { delete[] VectorE; VectorE = NULL; }
290  if (VectorI) { delete[] VectorI; VectorI = NULL; }
291  if (VectorV) { delete[] VectorV; VectorV = NULL; }
292  if (VectorJ) { delete[] VectorJ; VectorJ = NULL; }
293 }
294 
295 /* This function sets the name and port number of one of the circuit's
296  nodes. It also tells the appropriate node about the circuit it
297  belongs to. The optional 'intern' argument is used to mark a node
298  to be for internal use only. */
299 void circuit::setNode (int i, const char * n, int intern) {
300  nodes[i].setName (n);
301  nodes[i].setCircuit (this);
302  nodes[i].setPort (i);
303  nodes[i].setInternal (intern);
304 }
305 
306 // Returns one of the circuit's nodes.
308  return &nodes[i];
309 }
310 
311 // Sets the subcircuit reference for the circuit object.
312 void circuit::setSubcircuit (char * n) {
313  if (subcircuit) free (subcircuit);
314  subcircuit = n ? strdup (n) : NULL;
315 }
316 
317 #if DEBUG
318 // DEBUG function: Prints the S parameters of this circuit object.
319 void circuit::print (void) {
320  for (int i = 0; i < getSize (); i++) {
321  for (int j = 0; j < getSize (); j++) {
322  logprint (LOG_STATUS, "%s S%d%d(%+.3e,%+.3e) ", getName (), i, j,
323  (double) real (getS (i, j)), (double) imag (getS (i, j)));
324  }
325  logprint (LOG_STATUS, "\n");
326  }
327 }
328 #endif /* DEBUG */
329 
330 /* Returns the current substrate of the circuit object. Used for
331  microstrip components only. */
333  return subst;
334 }
335 
336 // Sets the substrate of the circuit object.
338  subst = s;
339 }
340 
341 /* Returns the circuits B-MNA matrix value of the given voltage source
342  built in the circuit depending on the port number. */
343 nr_complex_t circuit::getB (int port, int nr) {
344  return MatrixB[(nr - vsource) * size + port];
345 }
346 
347 /* Sets the circuits B-MNA matrix value of the given voltage source
348  built in the circuit depending on the port number. */
349 void circuit::setB (int port, int nr, nr_complex_t z) {
350  MatrixB[nr * size + port] = z;
351 }
352 
353 /* Returns the circuits C-MNA matrix value of the given voltage source
354  built in the circuit depending on the port number. */
355 nr_complex_t circuit::getC (int nr, int port) {
356  return MatrixC[(nr - vsource) * size + port];
357 }
358 
359 /* Sets the circuits C-MNA matrix value of the given voltage source
360  built in the circuit depending on the port number. */
361 void circuit::setC (int nr, int port, nr_complex_t z) {
362  MatrixC[nr * size + port] = z;
363 }
364 
365 /* Returns the circuits D-MNA matrix value of the given voltage source
366  built in the circuit. */
368  return MatrixD[(r - vsource) * vsources + c - vsource];
369 }
370 
371 /* Sets the circuits D-MNA matrix value of the given voltage source
372  built in the circuit. */
373 void circuit::setD (int r, int c, nr_complex_t z) {
374  MatrixD[r * vsources + c] = z;
375 }
376 
377 /* Returns the circuits E-MNA matrix value of the given voltage source
378  built in the circuit. */
380  return VectorE[nr - vsource];
381 }
382 
383 /* Sets the circuits E-MNA matrix value of the given voltage source
384  built in the circuit. */
385 void circuit::setE (int nr, nr_complex_t z) {
386  VectorE[nr] = z;
387 }
388 
389 /* Returns the circuits I-MNA matrix value of the current source built
390  in the circuit. */
392  return VectorI[port];
393 }
394 
395 /* Sets the circuits I-MNA matrix value of the current source built in
396  the circuit depending on the port number. */
397 void circuit::setI (int port, nr_complex_t z) {
398  VectorI[port] = z;
399 }
400 
401 /* Modifies the circuits I-MNA matrix value of the current source
402  built in the circuit depending on the port number. */
403 void circuit::addI (int port, nr_complex_t i) {
404  VectorI[port] += i;
405 }
406 
407 /* Same as above with different argument type. */
408 void circuit::addI (int port, nr_double_t i) {
409  VectorI[port] += i;
410 }
411 
412 /* Returns the circuits Q-HB vector value. */
414  return VectorQ[port];
415 }
416 
417 /* Sets the circuits Q-HB vector value. */
418 void circuit::setQ (int port, nr_complex_t q) {
419  VectorQ[port] = q;
420 }
421 
422 /* Returns the circuits J-MNA matrix value of the given voltage source
423  built in the circuit. */
425  return VectorJ[nr];
426 }
427 
428 /* Sets the circuits J-MNA matrix value of the given voltage source
429  built in the circuit. */
430 void circuit::setJ (int nr, nr_complex_t z) {
431  VectorJ[nr - vsource] = z;
432 }
433 
434 // Returns the circuits voltage value at the given port.
436  return VectorV[port];
437 }
438 
439 // Sets the circuits voltage value at the given port.
440 void circuit::setV (int port, nr_complex_t z) {
441  VectorV[port] = z;
442 }
443 
444 /* Returns the circuits G-MNA matrix value depending on the port
445  numbers. */
447  return MatrixY[r * size + c];
448 }
449 
450 /* Sets the circuits G-MNA matrix value depending on the port
451  numbers. */
452 void circuit::setY (int r, int c, nr_complex_t y) {
453  MatrixY[r * size + c] = y;
454 }
455 
456 /* Modifies the circuits G-MNA matrix value depending on the port
457  numbers. */
458 void circuit::addY (int r, int c, nr_complex_t y) {
459  MatrixY[r * size + c] += y;
460 }
461 
462 /* Same as above with different argument type. */
463 void circuit::addY (int r, int c, nr_double_t y) {
464  MatrixY[r * size + c] += y;
465 }
466 
467 /* Returns the circuits G-MNA matrix value depending on the port
468  numbers. */
469 nr_double_t circuit::getG (int r, int c) {
470  return real (MatrixY[r * size + c]);
471 }
472 
473 /* Sets the circuits G-MNA matrix value depending on the port
474  numbers. */
475 void circuit::setG (int r, int c, nr_double_t y) {
476  MatrixY[r * size + c] = y;
477 }
478 
479 /* Returns the circuits C-HB matrix value depending on the port
480  numbers. */
482  return MatrixQV[r * size + c];
483 }
484 
485 /* Sets the circuits C-HB matrix value depending on the port
486  numbers. */
487 void circuit::setQV (int r, int c, nr_complex_t qv) {
488  MatrixQV[r * size + c] = qv;
489 }
490 
491 /* Returns the circuits GV-HB vector value depending on the port
492  number. */
494  return VectorGV[port];
495 }
496 
497 /* Sets the circuits GV-HB matrix value depending on the port
498  number. */
499 void circuit::setGV (int port, nr_complex_t gv) {
500  VectorGV[port] = gv;
501 }
502 
503 /* Returns the circuits CV-HB vector value depending on the port
504  number. */
506  return VectorCV[port];
507 }
508 
509 /* Sets the circuits CV-HB matrix value depending on the port
510  number. */
511 void circuit::setCV (int port, nr_complex_t cv) {
512  VectorCV[port] = cv;
513 }
514 
515 /* This function adds a operating point consisting of a key and a
516  value to the circuit. */
517 void circuit::addOperatingPoint (const char * n, nr_double_t val) {
518  operatingpoint * p = new operatingpoint (n, val);
519  oper.add (n, p);
520 }
521 
522 /* Returns the requested operating point value which has been
523  previously added as its double representation. If there is no such
524  operating point the function returns zero. */
525 nr_double_t circuit::getOperatingPoint (const char * n) {
526  operatingpoint * p = oper.get (n);
527  if (p != NULL) return p->getValue ();
528  return 0.0;
529 }
530 
531 /* This function sets the operating point specified by the given name
532  to the value passed to the function. */
533 void circuit::setOperatingPoint (const char * n, nr_double_t val) {
534  operatingpoint * p = oper.get (n);
535  if (p != NULL)
536  p->setValue (val);
537  else
538  addOperatingPoint (n, val);
539 }
540 
541 /* The function checks whether the circuit has got a certain operating
542  point value. If so it returns non-zero, otherwise it returns
543  zero. */
545  return (oper.get (n)) ? 1 : 0;
546 }
547 
548 /* This function adds a characteristic point consisting of a key and a
549  value to the circuit. */
550 void circuit::addCharacteristic (const char * n, nr_double_t val) {
551  characteristic * p = new characteristic (n, val);
552  charac.add (n, p);
553 }
554 
555 /* Returns the requested characteristic value which has been
556  previously added as its double representation. If there is no such
557  characteristic value the function returns zero. */
558 nr_double_t circuit::getCharacteristic (char * n) {
559  characteristic * p = charac.get (n);
560  if (p != NULL) return p->getValue ();
561  return 0.0;
562 }
563 
564 /* This function sets the characteristic value specified by the given
565  name to the value passed to the function. */
566 void circuit::setCharacteristic (const char * n, nr_double_t val) {
567  characteristic * p = charac.get (n);
568  if (p != NULL)
569  p->setValue (val);
570  else
571  addCharacteristic (n, val);
572 }
573 
574 /* The function checks whether the circuit has got a certain
575  characteristic value. If so it returns non-zero, otherwise it
576  returns zero. */
578  return (charac.get (n)) ? 1 : 0;
579 }
580 
581 // Returns the S-parameter at the given matrix position.
583  return MatrixS[y + x * size];
584 }
585 
586 // Sets the S-parameter at the given matrix position.
587 void circuit::setS (int x, int y, nr_complex_t z) {
588  MatrixS[y + x * size] = z;
589 }
590 
591 // Returns the noise-correlation-parameter at the given matrix position.
593  return MatrixN[c + r * (size + nsources)];
594 }
595 
596 // Sets the noise-correlation-parameter at the given matrix position.
597 void circuit::setN (int r, int c, nr_complex_t z) {
598  MatrixN[c + r * (size + nsources)] = z;
599 }
600 
601 // Returns the number of internal voltage sources for DC analysis.
603  return vsources;
604 }
605 
606 // Sets the number of internal voltage sources for DC analysis.
608  assert (s >= 0);
609  vsources = s;
610 }
611 
612 // Returns the number of internal noise sources for AC analysis.
614  return nsources;
615 }
616 
617 // Sets the number of internal noise voltage sources for AC analysis.
619  assert (s >= 0);
620  nsources = s;
621 }
622 
623 /* The function returns an internal node or circuit name with the
624  given prefix and based on the given circuits name. The caller is
625  responsible to free() the returned string. */
626 char * circuit::createInternal (const char * prefix, const char * obj) {
627  char * n = (char *) malloc (strlen (prefix) + strlen (obj) + 3);
628  sprintf (n, "_%s#%s", prefix, obj);
629  return n;
630 }
631 
632 /* Creates an internal node given the node number as well as the name
633  suffix. An appropriate node name is constructed from the circuits
634  name and the suffix. */
635 void circuit::setInternalNode (int node, const char * suffix) {
636  char * n = createInternal (getName (), suffix);
637  setNode (node, n, 1);
638  free (n);
639 }
640 
641 /* This function copies the matrix elements inside the given matrix to
642  the internal S-parameter matrix of the circuit. */
644  int r = s.getRows ();
645  int c = s.getCols ();
646  // copy matrix elements
647  if (r > 0 && c > 0 && r * c == size * size) {
648  memcpy (MatrixS, s.getData (), sizeof (nr_complex_t) * r * c);
649  }
650 }
651 
652 /* The function return a matrix containing the S-parameters of the
653  circuit. */
655  matrix res (size);
656  for(unsigned int i=0; i < size; ++i)
657  for(unsigned int j=0; i < size; ++j)
658  res(i,j) = MatrixS[i*size + j];
659  return res;
660 }
661 
662 /* This function copies the matrix elements inside the given matrix to
663  the internal noise correlation matrix of the circuit. */
665  int r = n.getRows ();
666  int c = n.getCols ();
667  // copy matrix elements
668  if (r > 0 && c > 0 && r * c == size * size) {
669  memcpy (MatrixN, n.getData (), sizeof (nr_complex_t) * r * c);
670  }
671 }
672 
673 /* The function return a matrix containing the noise correlation
674  matrix of the circuit. */
676  matrix res (size);
677  for(unsigned int i=0; i < size; ++i)
678  for(unsigned int j=0; i < size; ++j)
679  res(i,j) = MatrixN[i*size + j];
680  return res;
681 }
682 
683 /* This function copies the matrix elements inside the given matrix to
684  the internal G-MNA matrix of the circuit. */
686  int r = y.getRows ();
687  int c = y.getCols ();
688  // copy matrix elements
689  if (r > 0 && c > 0 && r * c == size * size) {
690  memcpy (MatrixY, y.getData (), sizeof (nr_complex_t) * r * c);
691  }
692 }
693 
694 /* The function return a matrix containing the G-MNA matrix of the
695  circuit. */
697  matrix res (size);
698  for(unsigned int i=0; i < size; ++i)
699  for(unsigned int j=0; i < size; ++j)
700  res(i,j) = MatrixY[i*size + j];
701  return res;
702 }
703 
704 // The function cleans up the B-MNA matrix entries.
705 void circuit::clearB (void) {
706  memset (MatrixB, 0, sizeof (nr_complex_t) * size * vsources);
707 }
708 
709 // The function cleans up the C-MNA matrix entries.
710 void circuit::clearC (void) {
711  memset (MatrixC, 0, sizeof (nr_complex_t) * size * vsources);
712 }
713 
714 // The function cleans up the D-MNA matrix entries.
715 void circuit::clearD (void) {
716  memset (MatrixD, 0, sizeof (nr_complex_t) * vsources * vsources);
717 }
718 
719 // The function cleans up the E-MNA matrix entries.
720 void circuit::clearE (void) {
721  memset (VectorE, 0, sizeof (nr_complex_t) * vsources);
722 }
723 
724 // The function cleans up the J-MNA matrix entries.
725 void circuit::clearJ (void) {
726  memset (VectorJ, 0, sizeof (nr_complex_t) * vsources);
727 }
728 
729 // The function cleans up the I-MNA matrix entries.
730 void circuit::clearI (void) {
731  memset (VectorI, 0, sizeof (nr_complex_t) * size);
732 }
733 
734 // The function cleans up the V-MNA matrix entries.
735 void circuit::clearV (void) {
736  memset (VectorV, 0, sizeof (nr_complex_t) * size);
737 }
738 
739 // The function cleans up the G-MNA matrix entries.
740 void circuit::clearY (void) {
741  memset (MatrixY, 0, sizeof (nr_complex_t) * size * size);
742 }
743 
744 /* This function can be used by several components in order to place
745  the n-th voltage source between node 'pos' and node 'neg' with the
746  given value. Remember to indicate this voltage source using the
747  function setVoltageSources(). */
748 void circuit::voltageSource (int n, int pos, int neg, nr_double_t value) {
749  setC (n, pos, +1.0); setC (n, neg, -1.0);
750  setB (pos, n, +1.0); setB (neg, n, -1.0);
751  setD (n, n, 0.0);
752  setE (n, value);
753 }
754 
755 /* The function runs the necessary calculation in order to perform a
756  single integration step of a voltage controlled capacitance placed
757  in between the given nodes. It is assumed that the appropiate
758  charge only depends on the voltage between these nodes. */
759 void circuit::transientCapacitance (int qstate, int pos, int neg,
760  nr_double_t cap, nr_double_t voltage,
761  nr_double_t charge) {
762  nr_double_t g, i;
763  int cstate = qstate + 1;
764  setState (qstate, charge);
765  integrate (qstate, cap, g, i);
766  addY (pos, pos, +g); addY (neg, neg, +g);
767  addY (pos, neg, -g); addY (neg, pos, -g);
768  i = pol * (getState (cstate) - g * voltage);
769  addI (pos , -i);
770  addI (neg , +i);
771 }
772 
773 /* This is the one-node variant of the above function. It performs
774  the same steps for a single node related to ground. */
775 void circuit::transientCapacitance (int qstate, int node, nr_double_t cap,
776  nr_double_t voltage, nr_double_t charge) {
777  nr_double_t g, i;
778  int cstate = qstate + 1;
779  setState (qstate, charge);
780  integrate (qstate, cap, g, i);
781  addY (node, node, +g);
782  i = pol * (getState (cstate) - g * voltage);
783  addI (node , -i);
784 }
785 
786 /* The function performs a single integration step of the given charge
787  located between the given nodes. It saves the current
788  contributions of the charge itself and considers the polarity of
789  the circuit. */
790 void circuit::transientCapacitanceQ (int qstate, int qpos, int qneg,
791  nr_double_t charge) {
792  nr_double_t unused, i;
793  int cstate = qstate + 1;
794  setState (qstate, charge);
795  integrate (qstate, 0, unused, unused);
796  i = pol * getState (cstate);
797  addI (qpos , -i);
798  addI (qneg , +i);
799 }
800 
801 /* This is the one-node variant of the above function. It performs
802  the same steps for a single node related to ground. */
803 void circuit::transientCapacitanceQ (int qstate, int qpos,
804  nr_double_t charge) {
805  nr_double_t unused, i;
806  int cstate = qstate + 1;
807  setState (qstate, charge);
808  integrate (qstate, 0, unused, unused);
809  i = pol * getState (cstate);
810  addI (qpos , -i);
811 }
812 
813 /* This function stores the Jacobian entries due to the C = dQ/dV
814  value. The nodes where the charge is located as well as those of
815  the voltage dependency, the appropiate capacitance value and the
816  voltage across the the controlling branch must be given. It also
817  saves the current contributions which are necessary for the NR
818  iteration and considers the polarity of the circuit. */
819 void circuit::transientCapacitanceC (int qpos, int qneg, int vpos, int vneg,
820  nr_double_t cap, nr_double_t voltage) {
821  nr_double_t g, i;
822  conductor (cap, g);
823  addY (qpos, vpos, +g); addY (qneg, vneg, +g);
824  addY (qpos, vneg, -g); addY (qneg, vpos, -g);
825  i = pol * (g * voltage);
826  addI (qpos , +i);
827  addI (qneg , -i);
828 }
829 
830 /* This is the one-node variant of the transientCapacitanceC()
831  function. It performs the same steps for a single charge node
832  related to ground. */
833 void circuit::transientCapacitanceC2V (int qpos, int vpos, int vneg,
834  nr_double_t cap, nr_double_t voltage) {
835  nr_double_t g, i;
836  conductor (cap, g);
837  addY (qpos, vpos, +g);
838  addY (qpos, vneg, -g);
839  i = pol * (g * voltage);
840  addI (qpos , +i);
841 }
842 
843 /* This is the one-node variant of the transientCapacitanceC()
844  function. It performs the same steps for a single voltage node
845  related to ground. */
846 void circuit::transientCapacitanceC2Q (int qpos, int qneg, int vpos,
847  nr_double_t cap, nr_double_t voltage) {
848  nr_double_t g, i;
849  conductor (cap, g);
850  addY (qpos, vpos, +g); addY (qneg, vpos, -g);
851  i = pol * (g * voltage);
852  addI (qpos , +i);
853  addI (qneg , -i);
854 }
855 
856 /* This is the one-node variant of the transientCapacitanceC()
857  function. It performs the same steps for a single voltage node and
858  charge node related to ground. */
859 void circuit::transientCapacitanceC (int qpos, int vpos,
860  nr_double_t cap, nr_double_t voltage) {
861  nr_double_t g, i;
862  conductor (cap, g);
863  addY (qpos, vpos, +g);
864  i = pol * (g * voltage);
865  addI (qpos , +i);
866 }
867 
868 // The function initializes the histories of a circuit having the given age.
869 void circuit::initHistory (nr_double_t age) {
872  setHistoryAge (age);
873 }
874 
875 // Sets the age of all circuit histories
876 void circuit::setHistoryAge (nr_double_t age) {
877  for (int i = 0; i < nHistories; i++)
878  {
879  histories[i].setAge (age);
880  }
881 }
882 
883 
884 
885 // The function deletes the histories for the transient analysis.
887  if (histories != NULL) {
888  delete[] histories;
889  histories = NULL;
890  }
891  setHistory (false);
892 }
893 
894 // Truncates the transient analysis history (i.e. removes values newer
895 // newer than time tcut).
896 void circuit::truncateHistory (nr_double_t tcut) {
897  if (histories != NULL) {
898  for (int i = 0; i < nHistories; i++)
899  {
900  histories[i].truncate (tcut);
901  }
902  }
903 }
904 
905 // Appends a history value.
906 void circuit::appendHistory (int n, nr_double_t val) {
907  histories[n].append (val);
908 }
909 
910 // Returns the required age of the history.
911 nr_double_t circuit::getHistoryAge (void) {
912  if (histories) return histories[0].getAge ();
913  return 0.0;
914 }
915 
916 // Returns size of the history
918  return histories[0].getSize ();
919 }
920 
921 // Returns the time with the specified index
922 nr_double_t circuit::getHistoryTFromIndex (int idx)
923 {
924  return histories[0].getTfromidx (idx);
925 }
926 
927 /* This function should be used to apply the time vector history to
928  the value histories of a circuit. */
930 
932 
933  for (int i = 0; i < nHistories; i++)
934  {
935  histories[i].setTvector (t);
936  }
937 
938 }
939 
940 // Returns voltage at the given time for the given node.
941 nr_double_t circuit::getV (int port, nr_double_t t) {
942  return histories[port].nearest (t);
943 }
944 
945 // Returns voltage at the given index from the history for the given node.
946 nr_double_t circuit::getV (int port, int idx) {
947  return histories[port].getValfromidx (idx);
948 }
949 
950 // Returns current at the given time for the given voltage source.
951 nr_double_t circuit::getJ (int nr, nr_double_t t) {
952  return histories[nr + getSize ()].nearest (t);
953 }
954 
955 } // namespace qucs
nr_double_t getG(int, int)
Definition: circuit.cpp:469
std::complex< nr_double_t > nr_complex_t
Definition: complex.h:31
nr_double_t getOperatingPoint(const char *)
Definition: circuit.cpp:525
void addCharacteristic(const char *, nr_double_t)
Definition: circuit.cpp:550
void setHistory(bool h)
Definition: circuit.h:213
void clearY(void)
Definition: circuit.cpp:740
void freeMatrixMNA(void)
Definition: circuit.cpp:284
matrix real(matrix a)
Real part matrix.
Definition: matrix.cpp:568
nr_complex_t * MatrixC
Definition: circuit.h:338
char * subcircuit
Definition: circuit.h:348
void setSubcircuit(char *)
Definition: circuit.cpp:312
substrate * subst
Definition: circuit.h:350
void integrate(int, nr_double_t, nr_double_t &, nr_double_t &)
Definition: integrator.cpp:67
void allocMatrixN(int sources=0)
Definition: circuit.cpp:260
void setQ(int, nr_complex_t)
Definition: circuit.cpp:418
void clearC(void)
Definition: circuit.cpp:710
void conductor(nr_double_t, nr_double_t &)
Definition: integrator.cpp:76
void setD(int, int, nr_complex_t)
Definition: circuit.cpp:373
int hasOperatingPoint(char *)
Definition: circuit.cpp:544
substrate * getSubstrate(void)
Definition: circuit.cpp:332
void appendHistory(int, nr_double_t)
Definition: circuit.cpp:906
t
Definition: parse_vcd.y:290
nr_double_t getTfromidx(int)
Definition: history.cpp:206
tvector< nr_double_t > * getTvector(void)
Definition: history.h:53
nr_double_t * deltas
Definition: circuit.h:355
void setVoltageSources(int)
Definition: circuit.cpp:607
nr_complex_t * VectorI
Definition: circuit.h:341
int nsources
Definition: circuit.h:331
nr_complex_t * VectorJ
Definition: circuit.h:343
int getHistorySize(void)
Definition: circuit.cpp:917
void setB(int, int, nr_complex_t)
Definition: circuit.cpp:349
nr_complex_t * getData(void)
Definition: matrix.h:105
void clearE(void)
Definition: circuit.cpp:720
void allocMatrixS(void)
Definition: circuit.cpp:251
void setInternal(int i)
Definition: node.h:45
n
Definition: parse_citi.y:147
void transientCapacitanceQ(int, int, int, nr_double_t)
Definition: circuit.cpp:790
static const nr_double_t z0
Definition: circuit.h:320
void append(nr_double_t)
Definition: history.cpp:62
h
Definition: parse_vcd.y:214
r
Definition: parse_mdl.y:515
nr_complex_t getN(int, int)
Definition: circuit.cpp:592
void transientCapacitanceC2Q(int, int, int, nr_double_t, nr_double_t)
Definition: circuit.cpp:846
void clearD(void)
Definition: circuit.cpp:715
void setJ(int, nr_complex_t)
Definition: circuit.cpp:430
matrix getMatrixY(void)
Definition: circuit.cpp:696
void applyHistory(history *)
Definition: circuit.cpp:929
int getSize(void)
Get the number of ports the circuit element has.
Definition: circuit.h:143
void setPort(int)
Definition: node.cpp:76
void clearI(void)
Definition: circuit.cpp:730
void addY(int, int, nr_complex_t)
Definition: circuit.cpp:458
matrix getMatrixN(void)
Definition: circuit.cpp:675
nr_double_t getAge(void)
Definition: history.h:43
i
Definition: parse_mdl.y:516
void clearJ(void)
Definition: circuit.cpp:725
int getVoltageSources(void)
Definition: circuit.cpp:602
matrix imag(matrix a)
Imaginary part matrix.
Definition: matrix.cpp:581
nr_complex_t * MatrixY
Definition: circuit.h:336
void addOperatingPoint(const char *, nr_double_t)
Definition: circuit.cpp:517
nr_complex_t getC(int, int)
Definition: circuit.cpp:355
void setValue(nr_double_t val)
Definition: pair.h:42
void transientCapacitance(int, int, int, nr_double_t, nr_double_t, nr_double_t)
Definition: circuit.cpp:759
nr_double_t getHistoryAge(void)
Definition: circuit.cpp:911
void setName(const char *)
Definition: object.cpp:78
void clearB(void)
Definition: circuit.cpp:705
base class for qucs circuit elements.
Definition: circuit.h:92
nr_double_t getJ(int, nr_double_t)
Definition: circuit.cpp:951
void transientCapacitanceC2V(int, int, int, nr_double_t, nr_double_t)
Definition: circuit.cpp:833
nr_complex_t getI(int)
Definition: circuit.cpp:391
void setSize(int)
Set the number of ports the circuit element has.
Definition: circuit.cpp:195
void deleteHistory(void)
Definition: circuit.cpp:886
free($1)
void setCV(int, nr_complex_t)
Definition: circuit.cpp:511
void allocMatrixHB(void)
Definition: circuit.cpp:227
void truncate(int)
Definition: history.cpp:69
void setE(int, nr_complex_t)
Definition: circuit.cpp:385
void print(void)
valuelist< characteristic > charac
Definition: circuit.h:352
nr_complex_t * MatrixS
Definition: circuit.h:334
void addI(int, nr_complex_t)
Definition: circuit.cpp:403
x
Definition: parse_mdl.y:498
void setMatrixY(matrix)
Definition: circuit.cpp:685
int hasCharacteristic(char *)
Definition: circuit.cpp:577
nr_complex_t getE(int)
Definition: circuit.cpp:379
Declaration sizeof(struct vcd_scope))
void setAge(nr_double_t a)
Definition: history.h:42
nr_complex_t * MatrixB
Definition: circuit.h:337
value
Definition: parse_vcd.y:315
state_type_t getState(int, int n=0)
Definition: states.cpp:99
Dense matrix class header file.
The circuit class header file.
generic object class.
Definition: object.h:52
void setI(int, nr_complex_t)
Definition: circuit.cpp:397
nr_complex_t * MatrixQV
Definition: circuit.h:345
static char * createInternal(const char *, const char *)
Definition: circuit.cpp:626
nr_complex_t getD(int, int)
Definition: circuit.cpp:367
void truncateHistory(nr_double_t)
Definition: circuit.cpp:896
nr_complex_t getGV(int)
Definition: circuit.cpp:493
void setMatrixS(matrix)
Definition: circuit.cpp:643
Dense complex matrix class This class defines a matrix object with its methods, operators and operati...
Definition: matrix.h:92
matrix getMatrixS(void)
Definition: circuit.cpp:654
void setY(int, int, nr_complex_t)
Definition: circuit.cpp:452
name prefix
Definition: parse_spice.y:131
void setInternalNode(int, const char *)
Definition: circuit.cpp:635
int vsources
Definition: circuit.h:330
nr_double_t getCharacteristic(char *)
Definition: circuit.cpp:558
void allocMatrixMNA(void)
Definition: circuit.cpp:267
int getSize(void)
Definition: history.cpp:230
void transientCapacitanceC(int, int, int, int, nr_double_t, nr_double_t)
Definition: circuit.cpp:819
nr_complex_t getB(int, int)
Definition: circuit.cpp:343
nr_complex_t * MatrixN
Definition: circuit.h:335
void setTvector(tvector< nr_double_t > *v)
Definition: history.h:52
int getCols(void)
Definition: matrix.h:103
void setCircuit(circuit *)
Definition: node.cpp:86
valuelist< operatingpoint > oper
Definition: circuit.h:351
history * histories
Definition: circuit.h:357
void setNode(int, const char *, int intern=0)
Definition: circuit.cpp:299
y
Definition: parse_mdl.y:499
nr_double_t getV(int, nr_double_t)
Definition: circuit.cpp:941
nr_double_t getValue(void)
Definition: pair.h:41
nr_complex_t getQV(int, int)
Definition: circuit.cpp:481
nr_complex_t * VectorQ
Definition: circuit.h:344
nr_double_t getHistoryTFromIndex(int)
Definition: circuit.cpp:922
nr_double_t nearest(nr_double_t, bool interpolate=true)
Definition: history.cpp:160
node * nodes
Definition: circuit.h:349
void voltageSource(int, int, int, nr_double_t value=0.0)
Definition: circuit.cpp:748
void setMatrixN(matrix)
Definition: circuit.cpp:664
void setQV(int, int, nr_complex_t)
Definition: circuit.cpp:487
void setNoiseSources(int)
Definition: circuit.cpp:618
char * getName(void)
Definition: object.cpp:84
void setS(int, int, nr_complex_t)
Definition: circuit.cpp:587
node * getNode(int)
Definition: circuit.cpp:307
node
void setN(int, int, nr_complex_t)
Definition: circuit.cpp:597
void setOperatingPoint(const char *, nr_double_t)
Definition: circuit.cpp:533
#define LOG_STATUS
Definition: logging.h:29
net * subnet
Definition: circuit.h:353
void setC(int, int, nr_complex_t)
Definition: circuit.cpp:361
nr_complex_t * VectorGV
Definition: circuit.h:346
nr_complex_t getQ(int)
Definition: circuit.cpp:413
nr_complex_t getY(int, int)
Definition: circuit.cpp:446
nr_double_t getValfromidx(int)
Definition: history.cpp:218
void setCharacteristic(const char *, nr_double_t)
Definition: circuit.cpp:566
int getNoiseSources(void)
Definition: circuit.cpp:613
void setState(int, state_type_t, int n=0)
Definition: states.cpp:109
void initHistory(nr_double_t)
Definition: circuit.cpp:869
void logprint(int level, const char *format,...)
Definition: logging.c:37
nr_complex_t * VectorCV
Definition: circuit.h:347
void setHistoryAge(nr_double_t)
Definition: circuit.cpp:876
void setGV(int, nr_complex_t)
Definition: circuit.cpp:499
int inserted
Definition: circuit.h:332
int getRows(void)
Definition: matrix.h:104
nr_complex_t getS(int, int)
Definition: circuit.cpp:582
void setG(int, int, nr_double_t)
Definition: circuit.cpp:475
int nHistories
Definition: circuit.h:356
void setSubstrate(substrate *)
Definition: circuit.cpp:337
void clearV(void)
Definition: circuit.cpp:735
nr_complex_t * VectorV
Definition: circuit.h:342
void freeMatrixHB(void)
Definition: circuit.cpp:219
nr_complex_t * MatrixD
Definition: circuit.h:339
nr_complex_t * VectorE
Definition: circuit.h:340
void setV(int, nr_complex_t)
Definition: circuit.cpp:440
nr_complex_t getCV(int)
Definition: circuit.cpp:505