LCOV - code coverage report
Current view: top level - src - circuit.cpp (source / functions) Hit Total Coverage
Test: qucs-core-0.0.19 Code Coverage Lines: 268 507 52.9 %
Date: 2015-01-05 16:01:02 Functions: 65 105 61.9 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 145 402 36.1 %

           Branch data     Line data    Source code
       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.
      55 [ #  # ][ #  # ]:          0 : circuit::circuit () : object (), integrator () {
      56                 :          0 :   size = 0;
      57                 :          0 :   MatrixN = MatrixS = MatrixY = NULL;
      58                 :          0 :   MatrixB = MatrixC = MatrixD = NULL;
      59                 :          0 :   VectorQ = VectorE = VectorI = VectorV = VectorJ = NULL;
      60                 :          0 :   MatrixQV = NULL;
      61                 :          0 :   VectorCV = VectorGV = NULL;
      62                 :          0 :   nodes = NULL;
      63                 :          0 :   pacport = 0;
      64                 :          0 :   pol = 1;
      65                 :          0 :   flag = CIRCUIT_ORIGINAL | CIRCUIT_LINEAR;
      66                 :          0 :   subst = NULL;
      67                 :          0 :   vsource = -1;
      68                 :          0 :   vsources = 0;
      69                 :          0 :   nsources = 0;
      70                 :          0 :   inserted = -1;
      71                 :          0 :   subcircuit = NULL;
      72                 :          0 :   subnet = NULL;
      73                 :          0 :   deltas = NULL;
      74                 :          0 :   histories = NULL;
      75                 :          0 :   nHistories = 0;
      76                 :          0 :   type = CIR_UNKNOWN;
      77                 :          0 : }
      78                 :            : 
      79                 :            : /* Constructor creates an unnamed instance of the circuit class with a
      80                 :            :    certain number of ports. */
      81 [ +  - ][ +  - ]:     125988 : circuit::circuit (int s) : object (), integrator () {
      82 [ -  + ][ -  + ]:     125988 :   assert (s >= 0);
      83                 :     125988 :   size = s;
      84 [ +  - ][ +  - ]:     474473 :   if (size > 0) nodes = new node[s];
         [ +  - ][ +  + ]
           [ #  #  #  # ]
         [ +  - ][ +  - ]
         [ +  - ][ +  + ]
           [ #  #  #  # ]
      85                 :     125988 :   MatrixN = MatrixS = MatrixY = NULL;
      86                 :     125988 :   MatrixB = MatrixC = MatrixD = NULL;
      87                 :     125988 :   VectorQ = VectorE = VectorI = VectorV = VectorJ = NULL;
      88                 :     125988 :   MatrixQV = NULL;
      89                 :     125988 :   VectorCV = VectorGV = NULL;
      90                 :     125988 :   pacport = 0;
      91                 :     125988 :   pol = 1;
      92                 :     125988 :   flag = CIRCUIT_ORIGINAL | CIRCUIT_LINEAR;
      93                 :     125988 :   subst = NULL;
      94                 :     125988 :   vsource = -1;
      95                 :     125988 :   vsources = 0;
      96                 :     125988 :   nsources = 0;
      97                 :     125988 :   inserted = -1;
      98                 :     125988 :   subcircuit = NULL;
      99                 :     125988 :   subnet = NULL;
     100                 :     125988 :   deltas = NULL;
     101                 :     125988 :   histories = NULL;
     102                 :     125988 :   nHistories = 0;
     103                 :     125988 :   type = CIR_UNKNOWN;
     104                 :     125988 : }
     105                 :            : 
     106                 :            : /* The copy constructor creates a new instance based on the given
     107                 :            :    circuit object. */
     108 [ #  # ][ #  # ]:          0 : circuit::circuit (const circuit & c) : object (c), integrator (c) {
     109                 :          0 :   size = c.size;
     110                 :          0 :   pol = c.pol;
     111                 :          0 :   pacport = c.pacport;
     112                 :          0 :   flag = c.flag;
     113                 :          0 :   type = c.type;
     114                 :          0 :   subst = c.subst;
     115                 :          0 :   vsource = c.vsource;
     116                 :          0 :   vsources = c.vsources;
     117                 :          0 :   nsources = c.nsources;
     118                 :          0 :   inserted = c.inserted;
     119                 :          0 :   subnet = c.subnet;
     120                 :          0 :   deltas = c.deltas;
     121                 :          0 :   nHistories = c.nHistories;
     122                 :          0 :   histories = NULL;
     123 [ #  # ][ #  # ]:          0 :   subcircuit = c.subcircuit ? strdup (c.subcircuit) : NULL;
         [ #  # ][ #  # ]
     124                 :            : 
     125 [ #  # ][ #  # ]:          0 :   if (size > 0) {
     126                 :            :     // copy each node and set its circuit to the current circuit object
     127 [ #  # ][ #  # ]:          0 :     nodes = new node[size];
           [ #  #  #  #  
           #  # ][ #  # ]
         [ #  # ][ #  #  
             #  #  #  # ]
     128 [ #  # ][ #  # ]:          0 :     for (int i = 0; i < size; i++) {
     129 [ #  # ][ #  # ]:          0 :       nodes[i] = node (c.nodes[i]);;
         [ #  # ][ #  # ]
     130                 :          0 :       nodes[i].setCircuit (this);
     131                 :            :     }
     132                 :            :     // copy each s-parameter
     133 [ #  # ][ #  # ]:          0 :     if (c.MatrixS) {
     134 [ #  # ][ #  # ]:          0 :       allocMatrixS ();
     135                 :          0 :       memcpy (MatrixS, c.MatrixS, size * size * sizeof (nr_complex_t));
     136                 :            :     }
     137                 :            :     // copy each noise-correlation parameter
     138 [ #  # ][ #  # ]:          0 :     if (c.MatrixN) {
     139 [ #  # ][ #  # ]:          0 :       allocMatrixN (nsources);
     140                 :          0 :       int i = size + nsources;
     141                 :          0 :       memcpy (MatrixN, c.MatrixN, i * i * sizeof (nr_complex_t));
     142                 :            :     }
     143                 :            :     // copy each HB-matrix entry
     144 [ #  # ][ #  # ]:          0 :     if (c.MatrixQV) {
     145 [ #  # ][ #  # ]:          0 :       allocMatrixHB ();
     146                 :          0 :       memcpy (MatrixQV, c.MatrixQV, size * size * sizeof (nr_complex_t));
     147                 :          0 :       memcpy (VectorGV, c.VectorGV, size * sizeof (nr_complex_t));
     148                 :          0 :       memcpy (VectorCV, c.VectorCV, size * sizeof (nr_complex_t));
     149                 :          0 :       memcpy (VectorQ, c.VectorQ, size * sizeof (nr_complex_t));
     150                 :            :     }
     151                 :            :     // copy each G-MNA matrix entry
     152 [ #  # ][ #  # ]:          0 :     if (c.MatrixY) {
     153 [ #  # ][ #  # ]:          0 :       allocMatrixMNA ();
     154                 :          0 :       memcpy (MatrixY, c.MatrixY, size * size * sizeof (nr_complex_t));
     155                 :          0 :       memcpy (VectorI, c.VectorI, size * sizeof (nr_complex_t));
     156                 :          0 :       memcpy (VectorV, c.VectorV, size * sizeof (nr_complex_t));
     157 [ #  # ][ #  # ]:          0 :       if (vsources > 0) {
     158                 :          0 :         memcpy (MatrixB, c.MatrixB, vsources * size * sizeof (nr_complex_t));
     159                 :          0 :         memcpy (MatrixC, c.MatrixC, vsources * size * sizeof (nr_complex_t));
     160                 :          0 :         memcpy (MatrixD, c.MatrixD, vsources * vsources * sizeof (nr_complex_t));
     161                 :          0 :         memcpy (VectorE, c.VectorE, vsources * sizeof (nr_complex_t));
     162                 :          0 :         memcpy (VectorJ, c.VectorJ, vsources * sizeof (nr_complex_t));
     163                 :            :       }
     164                 :            :     }
     165                 :            :   }
     166                 :            :   else {
     167                 :          0 :     nodes = NULL;
     168                 :          0 :     MatrixS = MatrixN = MatrixY = NULL;
     169                 :          0 :     MatrixB = MatrixC = MatrixD = NULL;
     170                 :          0 :     VectorQ = VectorE = VectorI = VectorV = VectorJ = NULL;
     171                 :          0 :     MatrixQV = NULL;
     172                 :          0 :     VectorCV = VectorGV = NULL;
     173                 :            :   }
     174                 :            : 
     175                 :            :   // copy operating points
     176 [ #  # ][ #  # ]:          0 :   oper = valuelist<operatingpoint> (c.oper);
         [ #  # ][ #  # ]
     177                 :          0 : }
     178                 :            : 
     179                 :            : // Destructor deletes a circuit object.
     180 [ +  - ][ +  - ]:     125988 : circuit::~circuit () {
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     181 [ +  - ][ +  - ]:     125988 :   if (size > 0) {
     182 [ +  - ][ +  - ]:     125988 :     if (MatrixS) delete[] MatrixS;
         [ +  + ][ +  - ]
     183 [ +  + ][ +  - ]:     125988 :     if (MatrixN) delete[] MatrixN;
         [ +  + ][ +  - ]
     184                 :     125988 :     freeMatrixMNA ();
     185                 :     125988 :     freeMatrixHB ();
     186 [ +  - ][ +  + ]:     474473 :     delete[] nodes;
         [ +  - ][ +  - ]
         [ +  + ][ +  - ]
     187                 :            :   }
     188 [ -  + ][ +  + ]:     125988 :   if (subcircuit) free (subcircuit);
     189                 :     125988 :   deleteHistory ();
     190 [ -  + ][ -  + ]:     250663 : }
     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                 :          0 : void circuit::setSize (int s) {
     196                 :            :   // nothing to do here
     197         [ #  # ]:          0 :   if (size == s) return;
     198         [ #  # ]:          0 :   assert (s >= 0);
     199                 :            : 
     200         [ #  # ]:          0 :   if (size > 0) {
     201                 :            :     // destroy any matrix and node information
     202 [ #  # ][ #  # ]:          0 :     if (MatrixS) delete[] MatrixS;
     203 [ #  # ][ #  # ]:          0 :     if (MatrixN) delete[] MatrixN;
     204                 :          0 :     MatrixS = MatrixN = NULL;
     205                 :          0 :     freeMatrixMNA ();
     206 [ #  # ][ #  # ]:          0 :     delete[] nodes; nodes = NULL;
     207                 :            :   }
     208                 :            : 
     209         [ #  # ]:          0 :   if ((size = s) > 0) {
     210                 :            :     // re-create matrix and node information space
     211 [ #  # ][ #  #  :          0 :     nodes = new node[size];
             #  #  #  # ]
     212                 :          0 :     allocMatrixS ();
     213                 :          0 :     allocMatrixN (nsources);
     214                 :          0 :     allocMatrixMNA ();
     215                 :            :   }
     216                 :            : }
     217                 :            : 
     218                 :            : /* Destroys the HB-matrix memory. */
     219                 :     125988 : void circuit::freeMatrixHB (void) {
     220 [ +  + ][ +  - ]:     125988 :   if (VectorQ) { delete[] VectorQ; VectorQ = NULL; }
     221 [ +  + ][ +  - ]:     125988 :   if (MatrixQV) { delete[] MatrixQV; MatrixQV = NULL; }
     222 [ +  + ][ +  - ]:     125988 :   if (VectorCV) { delete[] VectorCV; VectorCV = NULL; }
     223 [ +  + ][ +  - ]:     125988 :   if (VectorGV) { delete[] VectorGV; VectorGV = NULL; }
     224                 :     125988 : }
     225                 :            : 
     226                 :            : /* Allocates the HB-matrix memory. */
     227                 :          1 : void circuit::allocMatrixHB (void) {
     228         [ -  + ]:          1 :   if (VectorQ) {
     229                 :          0 :     memset (VectorQ, 0, size * sizeof (nr_complex_t));
     230                 :            :   } else {
     231         [ +  + ]:          3 :     VectorQ = new nr_complex_t[size];
     232                 :            :   }
     233         [ -  + ]:          1 :   if (MatrixQV) {
     234                 :          0 :     memset (MatrixQV, 0, size * size * sizeof (nr_complex_t));
     235                 :            :   } else {
     236         [ +  + ]:          5 :     MatrixQV = new nr_complex_t[size * size];
     237                 :            :   }
     238         [ -  + ]:          1 :   if (VectorCV) {
     239                 :          0 :     memset (VectorCV, 0, size * sizeof (nr_complex_t));
     240                 :            :   } else {
     241         [ +  + ]:          3 :     VectorCV = new nr_complex_t[size];
     242                 :            :   }
     243         [ -  + ]:          1 :   if (VectorGV) {
     244                 :          0 :     memset (VectorGV, 0, size * sizeof (nr_complex_t));
     245                 :            :   } else {
     246         [ +  + ]:          3 :     VectorGV = new nr_complex_t[size];
     247                 :            :   }
     248                 :          1 : }
     249                 :            : 
     250                 :            : /* Allocates the S-parameter matrix memory. */
     251                 :     125097 : void circuit::allocMatrixS (void) {
     252         [ -  + ]:     125097 :   if (MatrixS) {
     253                 :          0 :     memset (MatrixS, 0, size * size * sizeof (nr_complex_t));
     254                 :            :   } else {
     255         [ +  + ]:    1304639 :     MatrixS = new nr_complex_t[size * size];
     256                 :            :   }
     257                 :     125097 : }
     258                 :            : 
     259                 :            : /* Allocates the noise correlation matrix memory. */
     260                 :       9452 : void circuit::allocMatrixN (int sources) {
     261                 :       9452 :   nsources = sources;
     262 [ +  + ][ +  - ]:       9452 :   if (MatrixN) delete[] MatrixN;
     263         [ +  + ]:     178148 :   MatrixN = new nr_complex_t[(size + sources) * (size + sources)];
     264                 :       9452 : }
     265                 :            : 
     266                 :            : /* Allocates the matrix memory for the MNA matrices. */
     267                 :     126752 : void circuit::allocMatrixMNA (void) {
     268                 :     126752 :   freeMatrixMNA ();
     269         [ +  - ]:     126752 :   if (size > 0) {
     270         [ +  + ]:    1116571 :     MatrixY = new nr_complex_t[size * size];
     271         [ +  + ]:     407347 :     VectorI = new nr_complex_t[size];
     272         [ +  + ]:     407347 :     VectorV = new nr_complex_t[size];
     273         [ +  + ]:     126752 :     if (vsources > 0) {
     274         [ +  + ]:      94285 :       MatrixB = new nr_complex_t[vsources * size];
     275         [ +  + ]:      94285 :       MatrixC = new nr_complex_t[vsources * size];
     276         [ +  + ]:      62400 :       MatrixD = new nr_complex_t[vsources * vsources];
     277         [ +  + ]:      62098 :       VectorE = new nr_complex_t[vsources];
     278         [ +  + ]:      62098 :       VectorJ = new nr_complex_t[vsources];
     279                 :            :     }
     280                 :            :   }
     281                 :     126752 : }
     282                 :            : 
     283                 :            : /* Free()'s all memory used by the MNA matrices. */
     284                 :     252740 : void circuit::freeMatrixMNA (void) {
     285 [ +  + ][ +  - ]:     252740 :   if (MatrixY) { delete[] MatrixY; MatrixY = NULL; }
     286 [ +  + ][ +  - ]:     252740 :   if (MatrixB) { delete[] MatrixB; MatrixB = NULL; }
     287 [ +  + ][ +  - ]:     252740 :   if (MatrixC) { delete[] MatrixC; MatrixC = NULL; }
     288 [ +  + ][ +  - ]:     252740 :   if (MatrixD) { delete[] MatrixD; MatrixD = NULL; }
     289 [ +  + ][ +  - ]:     252740 :   if (VectorE) { delete[] VectorE; VectorE = NULL; }
     290 [ +  + ][ +  - ]:     252740 :   if (VectorI) { delete[] VectorI; VectorI = NULL; }
     291 [ +  + ][ +  - ]:     252740 :   if (VectorV) { delete[] VectorV; VectorV = NULL; }
     292 [ +  + ][ +  - ]:     252740 :   if (VectorJ) { delete[] VectorJ; VectorJ = NULL; }
     293                 :     252740 : }
     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                 :     384274 : void circuit::setNode (int i, const char * n, int intern) {
     300                 :     384274 :   nodes[i].setName (n);
     301                 :     384274 :   nodes[i].setCircuit (this);
     302                 :     384274 :   nodes[i].setPort (i);
     303                 :     384274 :   nodes[i].setInternal (intern);
     304                 :     384274 : }
     305                 :            : 
     306                 :            : // Returns one of the circuit's nodes.
     307                 :    6970665 : node * circuit::getNode (int i) {
     308                 :    6970665 :   return &nodes[i];
     309                 :            : }
     310                 :            : 
     311                 :            : // Sets the subcircuit reference for the circuit object.
     312                 :        933 : void circuit::setSubcircuit (char * n) {
     313         [ -  + ]:        933 :   if (subcircuit) free (subcircuit);
     314         [ +  + ]:        933 :   subcircuit = n ? strdup (n) : NULL;
     315                 :        933 : }
     316                 :            : 
     317                 :            : #if DEBUG
     318                 :            : // DEBUG function:  Prints the S parameters of this circuit object.
     319                 :          0 : void circuit::print (void) {
     320         [ #  # ]:          0 :   for (int i = 0; i < getSize (); i++) {
     321         [ #  # ]:          0 :     for (int j = 0; j < getSize (); j++) {
     322                 :            :       logprint (LOG_STATUS, "%s S%d%d(%+.3e,%+.3e) ", getName (), i, j,
     323         [ #  # ]:          0 :                 (double) real (getS (i, j)), (double) imag (getS (i, j)));
     324                 :            :     }
     325                 :          0 :     logprint (LOG_STATUS, "\n");
     326                 :            :   }
     327                 :          0 : }
     328                 :            : #endif /* DEBUG */
     329                 :            : 
     330                 :            : /* Returns the current substrate of the circuit object.  Used for
     331                 :            :    microstrip components only. */
     332                 :       3344 : substrate * circuit::getSubstrate (void) {
     333                 :       3344 :   return subst;
     334                 :            : }
     335                 :            : 
     336                 :            : // Sets the substrate of the circuit object.
     337                 :         27 : void circuit::setSubstrate (substrate * s) {
     338                 :         27 :   subst = s;
     339                 :         27 : }
     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                 :    3726572 : nr_complex_t circuit::getB (int port, int nr) {
     344                 :    3726572 :   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                 :      63182 : void circuit::setB (int port, int nr, nr_complex_t z) {
     350                 :      63182 :   MatrixB[nr * size + port] = z;
     351                 :      63182 : }
     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                 :    3726572 : nr_complex_t circuit::getC (int nr, int port) {
     356                 :    3726572 :   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                 :     223692 : void circuit::setC (int nr, int port, nr_complex_t z) {
     362                 :     223692 :   MatrixC[nr * size + port] = z;
     363                 :     223692 : }
     364                 :            : 
     365                 :            : /* Returns the circuits D-MNA matrix value of the given voltage source
     366                 :            :    built in the circuit. */
     367                 :    2433343 : nr_complex_t circuit::getD (int r, int c) {
     368                 :    2433343 :   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                 :     376201 : void circuit::setD (int r, int c, nr_complex_t z) {
     374                 :     376201 :   MatrixD[r * vsources + c] = z;
     375                 :     376201 : }
     376                 :            : 
     377                 :            : /* Returns the circuits E-MNA matrix value of the given voltage source
     378                 :            :    built in the circuit. */
     379                 :    2049654 : nr_complex_t circuit::getE (int nr) {
     380                 :    2049654 :   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                 :     880080 : void circuit::setE (int nr, nr_complex_t z) {
     386                 :     880080 :   VectorE[nr] = z;
     387                 :     880080 : }
     388                 :            : 
     389                 :            : /* Returns the circuits I-MNA matrix value of the current source built
     390                 :            :    in the circuit. */
     391                 :    3202101 : nr_complex_t circuit::getI (int port) {
     392                 :    3202101 :   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                 :    2869379 : void circuit::setI (int port, nr_complex_t z) {
     398                 :    2869379 :   VectorI[port] = z;
     399                 :    2869379 : }
     400                 :            : 
     401                 :            : /* Modifies the circuits I-MNA matrix value of the current source
     402                 :            :    built in the circuit depending on the port number. */
     403                 :          0 : void circuit::addI (int port, nr_complex_t i) {
     404                 :          0 :   VectorI[port] += i;
     405                 :          0 : }
     406                 :            : 
     407                 :            : /* Same as above with different argument type. */
     408                 :    1967746 : void circuit::addI (int port, nr_double_t i) {
     409                 :    1967746 :   VectorI[port] += i;
     410                 :    1967746 : }
     411                 :            : 
     412                 :            : /* Returns the circuits Q-HB vector value. */
     413                 :        352 : nr_complex_t circuit::getQ (int port) {
     414                 :        352 :   return VectorQ[port];
     415                 :            : }
     416                 :            : 
     417                 :            : /* Sets the circuits Q-HB vector value. */
     418                 :        352 : void circuit::setQ (int port, nr_complex_t q) {
     419                 :        352 :   VectorQ[port] = q;
     420                 :        352 : }
     421                 :            : 
     422                 :            : /* Returns the circuits J-MNA matrix value of the given voltage source
     423                 :            :    built in the circuit. */
     424                 :     208702 : nr_complex_t circuit::getJ (int nr) {
     425                 :     208702 :   return VectorJ[nr];
     426                 :            : }
     427                 :            : 
     428                 :            : /* Sets the circuits J-MNA matrix value of the given voltage source
     429                 :            :    built in the circuit. */
     430                 :    2864758 : void circuit::setJ (int nr, nr_complex_t z) {
     431                 :    2864758 :   VectorJ[nr - vsource] = z;
     432                 :    2864758 : }
     433                 :            : 
     434                 :            : // Returns the circuits voltage value at the given port.
     435                 :    7406742 : nr_complex_t circuit::getV (int port) {
     436                 :    7406742 :   return VectorV[port];
     437                 :            : }
     438                 :            : 
     439                 :            : // Sets the circuits voltage value at the given port.
     440                 :   16448388 : void circuit::setV (int port, nr_complex_t z) {
     441                 :   16448388 :   VectorV[port] = z;
     442                 :   16448388 : }
     443                 :            : 
     444                 :            : /* Returns the circuits G-MNA matrix value depending on the port
     445                 :            :    numbers. */
     446                 :   18419856 : nr_complex_t circuit::getY (int r, int c) {
     447                 :   18419856 :   return MatrixY[r * size + c];
     448                 :            : }
     449                 :            : 
     450                 :            : /* Sets the circuits G-MNA matrix value depending on the port
     451                 :            :    numbers. */
     452                 :   15761029 : void circuit::setY (int r, int c, nr_complex_t y) {
     453                 :   15761029 :   MatrixY[r * size + c] = y;
     454                 :   15761029 : }
     455                 :            : 
     456                 :            : /* Modifies the circuits G-MNA matrix value depending on the port
     457                 :            :    numbers. */
     458                 :          0 : void circuit::addY (int r, int c, nr_complex_t y) {
     459                 :          0 :   MatrixY[r * size + c] += y;
     460                 :          0 : }
     461                 :            : 
     462                 :            : /* Same as above with different argument type. */
     463                 :    3935492 : void circuit::addY (int r, int c, nr_double_t y) {
     464                 :    3935492 :   MatrixY[r * size + c] += y;
     465                 :    3935492 : }
     466                 :            : 
     467                 :            : /* Returns the circuits G-MNA matrix value depending on the port
     468                 :            :    numbers. */
     469                 :          0 : nr_double_t circuit::getG (int r, int c) {
     470                 :          0 :   return real (MatrixY[r * size + c]);
     471                 :            : }
     472                 :            : 
     473                 :            : /* Sets the circuits G-MNA matrix value depending on the port
     474                 :            :    numbers. */
     475                 :          0 : void circuit::setG (int r, int c, nr_double_t y) {
     476                 :          0 :   MatrixY[r * size + c] = y;
     477                 :          0 : }
     478                 :            : 
     479                 :            : /* Returns the circuits C-HB matrix value depending on the port
     480                 :            :    numbers. */
     481                 :        176 : nr_complex_t circuit::getQV (int r, int c) {
     482                 :        176 :   return MatrixQV[r * size + c];
     483                 :            : }
     484                 :            : 
     485                 :            : /* Sets the circuits C-HB matrix value depending on the port
     486                 :            :    numbers. */
     487                 :        704 : void circuit::setQV (int r, int c, nr_complex_t qv) {
     488                 :        704 :   MatrixQV[r * size + c] = qv;
     489                 :        704 : }
     490                 :            : 
     491                 :            : /* Returns the circuits GV-HB vector value depending on the port
     492                 :            :    number. */
     493                 :        176 : nr_complex_t circuit::getGV (int port) {
     494                 :        176 :   return VectorGV[port];
     495                 :            : }
     496                 :            : 
     497                 :            : /* Sets the circuits GV-HB matrix value depending on the port
     498                 :            :    number. */
     499                 :        352 : void circuit::setGV (int port, nr_complex_t gv) {
     500                 :        352 :   VectorGV[port] = gv;
     501                 :        352 : }
     502                 :            : 
     503                 :            : /* Returns the circuits CV-HB vector value depending on the port
     504                 :            :    number. */
     505                 :        176 : nr_complex_t circuit::getCV (int port) {
     506                 :        176 :   return VectorCV[port];
     507                 :            : }
     508                 :            : 
     509                 :            : /* Sets the circuits CV-HB matrix value depending on the port
     510                 :            :    number. */
     511                 :        352 : void circuit::setCV (int port, nr_complex_t cv) {
     512                 :        352 :   VectorCV[port] = cv;
     513                 :        352 : }
     514                 :            : 
     515                 :            : /* This function adds a operating point consisting of a key and a
     516                 :            :    value to the circuit. */
     517                 :       1216 : void circuit::addOperatingPoint (const char * n, nr_double_t val) {
     518         [ +  - ]:       1216 :   operatingpoint * p = new operatingpoint (n, val);
     519                 :       1216 :   oper.add (n, p);
     520                 :       1216 : }
     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                 :    2154262 : nr_double_t circuit::getOperatingPoint (const char * n) {
     526                 :    2154262 :   operatingpoint * p = oper.get (n);
     527         [ +  - ]:    2154262 :   if (p != NULL) return p->getValue ();
     528                 :    2154262 :   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                 :    4187551 : void circuit::setOperatingPoint (const char * n, nr_double_t val) {
     534                 :    4187551 :   operatingpoint * p = oper.get (n);
     535         [ +  + ]:    4187551 :   if (p != NULL)
     536                 :    4186335 :     p->setValue (val);
     537                 :            :   else
     538                 :       1216 :     addOperatingPoint (n, val);
     539                 :    4187551 : }
     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. */
     544                 :          0 : int circuit::hasOperatingPoint (char * n) {
     545         [ #  # ]:          0 :   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                 :          0 : void circuit::addCharacteristic (const char * n, nr_double_t val) {
     551         [ #  # ]:          0 :   characteristic * p = new characteristic (n, val);
     552                 :          0 :   charac.add (n, p);
     553                 :          0 : }
     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                 :          0 : nr_double_t circuit::getCharacteristic (char * n) {
     559                 :          0 :   characteristic * p = charac.get (n);
     560         [ #  # ]:          0 :   if (p != NULL) return p->getValue ();
     561                 :          0 :   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                 :          0 : void circuit::setCharacteristic (const char * n, nr_double_t val) {
     567                 :          0 :   characteristic * p = charac.get (n);
     568         [ #  # ]:          0 :   if (p != NULL)
     569                 :          0 :     p->setValue (val);
     570                 :            :   else
     571                 :          0 :     addCharacteristic (n, val);
     572                 :          0 : }
     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. */
     577                 :          0 : int circuit::hasCharacteristic (char * n) {
     578         [ #  # ]:          0 :   return (charac.get (n)) ? 1 : 0;
     579                 :            : }
     580                 :            : 
     581                 :            : // Returns the S-parameter at the given matrix position.
     582                 :    6876468 : nr_complex_t circuit::getS (int x, int y) {
     583                 :    6876468 :   return MatrixS[y + x * size];
     584                 :            : }
     585                 :            : 
     586                 :            : // Sets the S-parameter at the given matrix position.
     587                 :    1395118 : void circuit::setS (int x, int y, nr_complex_t z) {
     588                 :    1395118 :   MatrixS[y + x * size] = z;
     589                 :    1395118 : }
     590                 :            : 
     591                 :            : // Returns the noise-correlation-parameter at the given matrix position.
     592                 :     718337 : nr_complex_t circuit::getN (int r, int c) {
     593                 :     718337 :   return MatrixN[c + r * (size + nsources)];
     594                 :            : }
     595                 :            : 
     596                 :            : // Sets the noise-correlation-parameter at the given matrix position.
     597                 :     216516 : void circuit::setN (int r, int c, nr_complex_t z) {
     598                 :     216516 :   MatrixN[c + r * (size + nsources)] = z;
     599                 :     216516 : }
     600                 :            : 
     601                 :            : // Returns the number of internal voltage sources for DC analysis.
     602                 :  156041497 : int circuit::getVoltageSources (void) {
     603                 :  156041497 :   return vsources;
     604                 :            : }
     605                 :            : 
     606                 :            : // Sets the number of internal voltage sources for DC analysis.
     607                 :      35488 : void circuit::setVoltageSources (int s) {
     608         [ -  + ]:      35488 :   assert (s >= 0);
     609                 :      35488 :   vsources = s;
     610                 :      35488 : }
     611                 :            : 
     612                 :            : // Returns the number of internal noise sources for AC analysis.
     613                 :          0 : int circuit::getNoiseSources (void) {
     614                 :          0 :   return nsources;
     615                 :            : }
     616                 :            : 
     617                 :            : // Sets the number of internal noise voltage sources for AC analysis.
     618                 :          0 : void circuit::setNoiseSources (int s) {
     619         [ #  # ]:          0 :   assert (s >= 0);
     620                 :          0 :   nsources = s;
     621                 :          0 : }
     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                 :      28151 : char * circuit::createInternal (const char * prefix, const char * obj) {
     627                 :      28151 :   char * n = (char *) malloc (strlen (prefix) + strlen (obj) + 3);
     628                 :      28151 :   sprintf (n, "_%s#%s", prefix, obj);
     629                 :      28151 :   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                 :      28005 : void circuit::setInternalNode (int node, const char * suffix) {
     636                 :      28005 :   char * n = createInternal (getName (), suffix);
     637                 :      28005 :   setNode (node, n, 1);
     638                 :      28005 :   free (n);
     639                 :      28005 : }
     640                 :            : 
     641                 :            : /* This function copies the matrix elements inside the given matrix to
     642                 :            :    the internal S-parameter matrix of the circuit. */
     643                 :       1070 : void circuit::setMatrixS (matrix s) {
     644                 :       1070 :   int r = s.getRows ();
     645                 :       1070 :   int c = s.getCols ();
     646                 :            :   // copy matrix elements
     647 [ +  - ][ +  - ]:       1070 :   if (r > 0 && c > 0 && r * c == size * size) {
                 [ +  - ]
     648                 :       1070 :     memcpy (MatrixS, s.getData (), sizeof (nr_complex_t) * r * c);
     649                 :            :   }
     650                 :       1070 : }
     651                 :            : 
     652                 :            : /* The function return a matrix containing the S-parameters of the
     653                 :            :    circuit. */
     654                 :         70 : matrix circuit::getMatrixS (void) {
     655                 :         70 :   matrix res (size);
     656         [ +  + ]:        770 :   for(unsigned int i=0; i < size; ++i)
     657         [ +  + ]:       7700 :     for(unsigned int j=0; j < size; ++j)
     658                 :       7000 :       res(i,j) = MatrixS[i*size + j];
     659                 :         70 :   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. */
     664                 :         70 : void circuit::setMatrixN (matrix n) {
     665                 :         70 :   int r = n.getRows ();
     666                 :         70 :   int c = n.getCols ();
     667                 :            :   // copy matrix elements
     668 [ +  - ][ +  - ]:         70 :   if (r > 0 && c > 0 && r * c == size * size) {
                 [ +  - ]
     669                 :         70 :     memcpy (MatrixN, n.getData (), sizeof (nr_complex_t) * r * c);
     670                 :            :   }
     671                 :         70 : }
     672                 :            : 
     673                 :            : /* The function return a matrix containing the noise correlation
     674                 :            :    matrix of the circuit. */
     675                 :          0 : matrix circuit::getMatrixN (void) {
     676                 :          0 :   matrix res (size);
     677         [ #  # ]:          0 :   for(unsigned int i=0; i < size; ++i)
     678         [ #  # ]:          0 :     for(unsigned int j=0; j < size; ++j)
     679                 :          0 :       res(i,j) = MatrixN[i*size + j];
     680                 :          0 :   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. */
     685                 :       2600 : void circuit::setMatrixY (matrix y) {
     686                 :       2600 :   int r = y.getRows ();
     687                 :       2600 :   int c = y.getCols ();
     688                 :            :   // copy matrix elements
     689 [ +  - ][ +  - ]:       2600 :   if (r > 0 && c > 0 && r * c == size * size) {
                 [ +  - ]
     690                 :       2600 :     memcpy (MatrixY, y.getData (), sizeof (nr_complex_t) * r * c);
     691                 :            :   }
     692                 :       2600 : }
     693                 :            : 
     694                 :            : /* The function return a matrix containing the G-MNA matrix of the
     695                 :            :    circuit. */
     696                 :          0 : matrix circuit::getMatrixY (void) {
     697                 :          0 :   matrix res (size);
     698         [ #  # ]:          0 :   for(unsigned int i=0; i < size; ++i)
     699         [ #  # ]:          0 :     for(unsigned int j=0; j < size; ++j)
     700                 :          0 :       res(i,j) = MatrixY[i*size + j];
     701                 :          0 :   return res;
     702                 :            : }
     703                 :            : 
     704                 :            : // The function cleans up the B-MNA matrix entries.
     705                 :          2 : void circuit::clearB (void) {
     706                 :          2 :   memset (MatrixB, 0, sizeof (nr_complex_t) * size * vsources);
     707                 :          2 : }
     708                 :            : 
     709                 :            : // The function cleans up the C-MNA matrix entries.
     710                 :          2 : void circuit::clearC (void) {
     711                 :          2 :   memset (MatrixC, 0, sizeof (nr_complex_t) * size * vsources);
     712                 :          2 : }
     713                 :            : 
     714                 :            : // The function cleans up the D-MNA matrix entries.
     715                 :          0 : void circuit::clearD (void) {
     716                 :          0 :   memset (MatrixD, 0, sizeof (nr_complex_t) * vsources * vsources);
     717                 :          0 : }
     718                 :            : 
     719                 :            : // The function cleans up the E-MNA matrix entries.
     720                 :          0 : void circuit::clearE (void) {
     721                 :          0 :   memset (VectorE, 0, sizeof (nr_complex_t) * vsources);
     722                 :          0 : }
     723                 :            : 
     724                 :            : // The function cleans up the J-MNA matrix entries.
     725                 :          0 : void circuit::clearJ (void) {
     726                 :          0 :   memset (VectorJ, 0, sizeof (nr_complex_t) * vsources);
     727                 :          0 : }
     728                 :            : 
     729                 :            : // The function cleans up the I-MNA matrix entries.
     730                 :        258 : void circuit::clearI (void) {
     731                 :        258 :   memset (VectorI, 0, sizeof (nr_complex_t) * size);
     732                 :        258 : }
     733                 :            : 
     734                 :            : // The function cleans up the V-MNA matrix entries.
     735                 :          0 : void circuit::clearV (void) {
     736                 :          0 :   memset (VectorV, 0, sizeof (nr_complex_t) * size);
     737                 :          0 : }
     738                 :            : 
     739                 :            : // The function cleans up the G-MNA matrix entries.
     740                 :       5156 : void circuit::clearY (void) {
     741                 :       5156 :   memset (MatrixY, 0, sizeof (nr_complex_t) * size * size);
     742                 :       5156 : }
     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                 :      30649 : void circuit::voltageSource (int n, int pos, int neg, nr_double_t value) {
     749                 :      30649 :   setC (n, pos, +1.0); setC (n, neg, -1.0);
     750                 :      30649 :   setB (pos, n, +1.0); setB (neg, n, -1.0);
     751                 :      30649 :   setD (n, n, 0.0);
     752                 :      30649 :   setE (n, value);
     753                 :      30649 : }
     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                 :     911023 : 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                 :     911023 :   int cstate = qstate + 1;
     764                 :     911023 :   setState (qstate, charge);
     765         [ +  - ]:     911023 :   integrate (qstate, cap, g, i);
     766                 :     911023 :   addY (pos, pos, +g); addY (neg, neg, +g);
     767                 :     911023 :   addY (pos, neg, -g); addY (neg, pos, -g);
     768                 :     911023 :   i = pol * (getState (cstate) - g * voltage);
     769                 :     911023 :   addI (pos , -i);
     770                 :     911023 :   addI (neg , +i);
     771                 :     911023 : }
     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                 :          0 : 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                 :          0 :   int cstate = qstate + 1;
     779                 :          0 :   setState (qstate, charge);
     780         [ #  # ]:          0 :   integrate (qstate, cap, g, i);
     781                 :          0 :   addY (node, node, +g);
     782                 :          0 :   i = pol * (getState (cstate) - g * voltage);
     783                 :          0 :   addI (node , -i);
     784                 :          0 : }
     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                 :          0 : void circuit::transientCapacitanceQ (int qstate, int qpos, int qneg,
     791                 :            :                                      nr_double_t charge) {
     792                 :            :   nr_double_t unused, i;
     793                 :          0 :   int cstate = qstate + 1;
     794                 :          0 :   setState (qstate, charge);
     795         [ #  # ]:          0 :   integrate (qstate, 0, unused, unused);
     796                 :          0 :   i = pol * getState (cstate);
     797                 :          0 :   addI (qpos , -i);
     798                 :          0 :   addI (qneg , +i);
     799                 :          0 : }
     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                 :          0 : void circuit::transientCapacitanceQ (int qstate, int qpos,
     804                 :            :                                      nr_double_t charge) {
     805                 :            :   nr_double_t unused, i;
     806                 :          0 :   int cstate = qstate + 1;
     807                 :          0 :   setState (qstate, charge);
     808         [ #  # ]:          0 :   integrate (qstate, 0, unused, unused);
     809                 :          0 :   i = pol * getState (cstate);
     810                 :          0 :   addI (qpos , -i);
     811                 :          0 : }
     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                 :      72850 : 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         [ +  - ]:      72850 :   conductor (cap, g);
     823                 :      72850 :   addY (qpos, vpos, +g); addY (qneg, vneg, +g);
     824                 :      72850 :   addY (qpos, vneg, -g); addY (qneg, vpos, -g);
     825                 :      72850 :   i = pol * (g * voltage);
     826                 :      72850 :   addI (qpos , +i);
     827                 :      72850 :   addI (qneg , -i);
     828                 :      72850 : }
     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                 :          0 : 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         [ #  # ]:          0 :   conductor (cap, g);
     837                 :          0 :   addY (qpos, vpos, +g);
     838                 :          0 :   addY (qpos, vneg, -g);
     839                 :          0 :   i = pol * (g * voltage);
     840                 :          0 :   addI (qpos , +i);
     841                 :          0 : }
     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                 :          0 : 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         [ #  # ]:          0 :   conductor (cap, g);
     850                 :          0 :   addY (qpos, vpos, +g); addY (qneg, vpos, -g);
     851                 :          0 :   i = pol * (g * voltage);
     852                 :          0 :   addI (qpos , +i);
     853                 :          0 :   addI (qneg , -i);
     854                 :          0 : }
     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                 :          0 : void circuit::transientCapacitanceC (int qpos, int vpos,
     860                 :            :                                      nr_double_t cap, nr_double_t voltage) {
     861                 :            :   nr_double_t g, i;
     862         [ #  # ]:          0 :   conductor (cap, g);
     863                 :          0 :   addY (qpos, vpos, +g);
     864                 :          0 :   i = pol * (g * voltage);
     865                 :          0 :   addI (qpos , +i);
     866                 :          0 : }
     867                 :            : 
     868                 :            : // The function initializes the histories of a circuit having the given age.
     869                 :          0 : void circuit::initHistory (nr_double_t age) {
     870                 :          0 :   nHistories = getSize () + getVoltageSources ();
     871 [ #  # ][ #  #  :          0 :   histories = new history[nHistories];
             #  #  #  # ]
     872                 :          0 :   setHistoryAge (age);
     873                 :          0 : }
     874                 :            : 
     875                 :            : // Sets the age of all circuit histories
     876                 :          0 : void circuit::setHistoryAge (nr_double_t age) {
     877         [ #  # ]:          0 :   for (int i = 0; i < nHistories; i++)
     878                 :            :   {
     879                 :          0 :     histories[i].setAge (age);
     880                 :            :   }
     881                 :          0 : }
     882                 :            : 
     883                 :            : 
     884                 :            : 
     885                 :            : // The function deletes the histories for the transient analysis.
     886                 :     126018 : void circuit::deleteHistory (void) {
     887         [ -  + ]:     126018 :   if (histories != NULL) {
     888 [ #  # ][ #  # ]:          0 :     delete[] histories;
     889                 :          0 :     histories = NULL;
     890                 :            :   }
     891                 :     126018 :   setHistory (false);
     892                 :     126018 : }
     893                 :            : 
     894                 :            : // Truncates the transient analysis history (i.e. removes values newer
     895                 :            : // newer than time tcut).
     896                 :          0 : void circuit::truncateHistory (nr_double_t tcut) {
     897         [ #  # ]:          0 :   if (histories != NULL) {
     898         [ #  # ]:          0 :     for (int i = 0; i < nHistories; i++)
     899                 :            :     {
     900                 :          0 :       histories[i].truncate (tcut);
     901                 :            :     }
     902                 :            :   }
     903                 :          0 : }
     904                 :            : 
     905                 :            : // Appends a history value.
     906                 :          0 : void circuit::appendHistory (int n, nr_double_t val) {
     907                 :          0 :   histories[n].append (val);
     908                 :          0 : }
     909                 :            : 
     910                 :            : // Returns the required age of the history.
     911                 :          0 : nr_double_t circuit::getHistoryAge (void) {
     912         [ #  # ]:          0 :   if (histories) return histories[0].getAge ();
     913                 :          0 :   return 0.0;
     914                 :            : }
     915                 :            : 
     916                 :            : // Returns size of the history
     917                 :          0 : int circuit::getHistorySize (void) {
     918                 :          0 :   return histories[0].getSize ();
     919                 :            : }
     920                 :            : 
     921                 :            : // Returns the time with the specified index
     922                 :          0 : nr_double_t circuit::getHistoryTFromIndex (int idx)
     923                 :            : {
     924                 :          0 :   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. */
     929                 :          0 : void circuit::applyHistory (history * h) {
     930         [ #  # ]:          0 :   for (int i = 0; i < nHistories; i++)
     931                 :            :   {
     932                 :          0 :     histories[i].apply(*h);
     933                 :            :   }
     934                 :            : 
     935                 :          0 : }
     936                 :            : 
     937                 :            : // Returns voltage at the given time for the given node.
     938                 :          0 : nr_double_t circuit::getV (int port, nr_double_t t) {
     939                 :          0 :   return histories[port].nearest (t);
     940                 :            : }
     941                 :            : 
     942                 :            : // Returns voltage at the given index from the history for the given node.
     943                 :          0 : nr_double_t circuit::getV (int port, int idx) {
     944                 :          0 :   return histories[port].getValfromidx (idx);
     945                 :            : }
     946                 :            : 
     947                 :            : // Returns current at the given time for the given voltage source.
     948                 :          0 : nr_double_t circuit::getJ (int nr, nr_double_t t) {
     949                 :          0 :   return histories[nr + getSize ()].nearest (t);
     950                 :            : }
     951                 :            : 
     952                 :            : } // namespace qucs

Generated by: LCOV version 1.11