LCOV - code coverage report
Current view: top level - src/components/devices - tunneldiode.cpp (source / functions) Hit Total Coverage
Test: qucs-core-0.0.19 Code Coverage Lines: 0 101 0.0 %
Date: 2015-01-05 16:01:02 Functions: 0 14 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 78 0.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * tunneldiode.cpp - resonance tunnel diode class implementation
       3                 :            :  *
       4                 :            :  * Copyright (C) 2011 Michael Margraf <michael.margraf@alumni.tu-berlin.de>
       5                 :            :  *
       6                 :            :  * This is free software; you can redistribute it and/or modify
       7                 :            :  * it under the terms of the GNU General Public License as published by
       8                 :            :  * the Free Software Foundation; either version 2, or (at your option)
       9                 :            :  * any later version.
      10                 :            :  *
      11                 :            :  * This software is distributed in the hope that it will be useful,
      12                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      13                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14                 :            :  * GNU General Public License for more details.
      15                 :            :  *
      16                 :            :  * You should have received a copy of the GNU General Public License
      17                 :            :  * along with this package; see the file COPYING.  If not, write to
      18                 :            :  * the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
      19                 :            :  * Boston, MA 02110-1301, USA.
      20                 :            :  *
      21                 :            :  * $Id$
      22                 :            :  *
      23                 :            :  */
      24                 :            : 
      25                 :            : #if HAVE_CONFIG_H
      26                 :            : # include <config.h>
      27                 :            : #endif
      28                 :            : 
      29                 :            : #include "component.h"
      30                 :            : #include "device.h"
      31                 :            : #include "devstates.h"
      32                 :            : #include "tunneldiode.h"
      33                 :            : 
      34                 :            : #define NODE_A1 0 /* cathode node */
      35                 :            : #define NODE_A2 1 /* anode node   */
      36                 :            : 
      37                 :            : using namespace qucs;
      38                 :            : using namespace qucs::device;
      39                 :            : 
      40                 :            : // Constructor for the diode.
      41                 :          0 : tunneldiode::tunneldiode () : circuit (2) {
      42                 :          0 :   type = CIR_TUNNELDIODE;
      43                 :          0 : }
      44                 :            : 
      45                 :            : // Callback for initializing the DC analysis.
      46                 :          0 : void tunneldiode::initDC (void) {
      47                 :            :   // allocate MNA matrices
      48                 :          0 :   allocMatrixMNA ();
      49                 :          0 : }
      50                 :            : 
      51                 :            : // Calculate one branch of the tunnel current.
      52                 :          0 : void tunneldiode::calcId (nr_double_t U, nr_double_t& I, nr_double_t& G) {
      53                 :          0 :   nr_double_t eta  = getPropertyDouble ("eta");
      54                 :          0 :   nr_double_t Wr   = getPropertyDouble ("Wr");
      55                 :          0 :   nr_double_t dv   = getPropertyDouble ("dv");
      56                 :          0 :   nr_double_t de   = getPropertyDouble ("de");
      57                 :          0 :   nr_double_t dW   = getPropertyDouble ("dW");
      58                 :            : 
      59                 :          0 :   U   = Wr - Q_e*U/dv;
      60                 :          0 :   de *= kB * kelvin (getPropertyDouble ("Temp"));
      61                 :            : 
      62                 :          0 :   nr_double_t a = M_PI_2 + qucs::atan ( U / dW );
      63                 :            : 
      64                 :          0 :   nr_double_t e = (eta - U) / de;
      65                 :          0 :   nr_double_t b = e;
      66         [ #  # ]:          0 :   if (e < 15.0)  // avoid numerical overflow
      67                 :          0 :     b = qucs::log (1.0 + qucs::exp ( e ));
      68                 :            : 
      69                 :            :   // current
      70                 :          0 :   I = b * a;
      71                 :            : 
      72                 :            :   // derivative
      73                 :          0 :   G = Q_e / dv / de / (1.0 + qucs::exp(-e)) * a - b * Q_e / dv / dW / (1.0 + sqr (U/dW));
      74                 :          0 : }
      75                 :            : 
      76                 :            : // Callback for DC analysis.
      77                 :          0 : void tunneldiode::calcDC (void) {
      78                 :            :   // get device properties
      79         [ #  # ]:          0 :   nr_double_t Ip   = getPropertyDouble ("Ip");
      80         [ #  # ]:          0 :   nr_double_t A    = getPropertyDouble ("Area");
      81         [ #  # ]:          0 :   nr_double_t Tmax = getPropertyDouble ("Tmax");
      82         [ #  # ]:          0 :   nr_double_t de   = getPropertyDouble ("de");
      83         [ #  # ]:          0 :   nr_double_t eta  = getPropertyDouble ("eta");
      84         [ #  # ]:          0 :   nr_double_t Iv   = getPropertyDouble ("Iv");
      85         [ #  # ]:          0 :   nr_double_t Vv   = getPropertyDouble ("Vv");
      86         [ #  # ]:          0 :   nr_double_t nv   = getPropertyDouble ("nv");
      87         [ #  # ]:          0 :   nr_double_t T    = kB * kelvin (getPropertyDouble ("Temp"));
      88                 :            : 
      89                 :            :   // diode voltage
      90 [ #  # ][ #  # ]:          0 :   Ud = real (getV (NODE_A1) - getV (NODE_A2));
                 [ #  # ]
      91                 :            : 
      92                 :            :   // bi-directional tunnel current
      93                 :            :   nr_double_t Ipos, Ineg, Gpos, Gneg;
      94                 :          0 :   gd = Id = A * Ip * Tmax * de * T / eta / M_PI_2;
      95         [ #  # ]:          0 :   calcId ( Ud, Ipos, Gpos);
      96         [ #  # ]:          0 :   calcId (-Ud, Ineg, Gneg);
      97                 :          0 :   Id *= Ipos - Ineg;
      98                 :          0 :   gd *= Gpos + Gneg;
      99                 :            : 
     100                 :            :   // thermal-ionic current
     101                 :          0 :   nv *= T / Q_e;
     102         [ #  # ]:          0 :   nr_double_t c = A * Iv / qucs::sinh (Vv / nv);
     103         [ #  # ]:          0 :   Id += c * qucs::sinh (Ud / nv);
     104         [ #  # ]:          0 :   gd += c * qucs::cosh (Ud / nv) / nv;
     105                 :            : 
     106                 :          0 :   nr_double_t Ieq = Id - Ud * gd;
     107                 :            : 
     108                 :            :   // fill in I-Vector
     109         [ #  # ]:          0 :   setI (NODE_A2, +Ieq);
     110         [ #  # ]:          0 :   setI (NODE_A1, -Ieq);
     111                 :            : 
     112                 :            :   // fill in G-Matrix
     113 [ #  # ][ #  # ]:          0 :   setY (NODE_A1, NODE_A1, +gd); setY (NODE_A2, NODE_A2, +gd);
     114 [ #  # ][ #  # ]:          0 :   setY (NODE_A1, NODE_A2, -gd); setY (NODE_A2, NODE_A1, -gd);
     115                 :          0 : }
     116                 :            : 
     117                 :            : // Saves operating points (voltages).
     118                 :          0 : void tunneldiode::saveOperatingPoints (void) {
     119 [ #  # ][ #  # ]:          0 :   nr_double_t Vd = real (getV (NODE_A1) - getV (NODE_A2));
     120                 :          0 :   setOperatingPoint ("Vd", Vd);
     121                 :          0 : }
     122                 :            : 
     123                 :            : // Loads operating points (voltages).
     124                 :          0 : void tunneldiode::loadOperatingPoints (void) {
     125                 :          0 :   Ud = getOperatingPoint ("Vd");
     126                 :          0 : }
     127                 :            : 
     128                 :            : // Calculates and saves operating points.
     129                 :          0 : void tunneldiode::calcOperatingPoints (void) {
     130                 :          0 :   nr_double_t A   = getPropertyDouble ("Area");
     131                 :          0 :   nr_double_t Cj0 = getPropertyDouble ("Cj0");
     132                 :          0 :   nr_double_t M   = getScaledProperty ("M");
     133                 :          0 :   nr_double_t Vj  = getScaledProperty ("Vj");
     134                 :          0 :   nr_double_t te  = getScaledProperty ("te");
     135                 :            : 
     136                 :            :   // calculate capacitances and charges
     137                 :            :   nr_double_t Cd;
     138                 :            : 
     139                 :            :   // depletion capacitance
     140                 :          0 :   nr_double_t c = 1.0 + fabs(Ud) / Vj;
     141                 :          0 :   Cd = A * Cj0 / qucs::pow (c, M);
     142                 :          0 :   Qd = A * Cj0 * Vj / (1.0-M) * (1.0 - qucs::pow (c, 1.0 - M));
     143                 :            : 
     144                 :            :   // quantum well (diffusion) capacitance (negative because of NDR region)
     145                 :          0 :   Cd -= te * gd;
     146                 :          0 :   Qd -= te * Id;
     147                 :            : 
     148                 :            :   // save operating points
     149                 :          0 :   setOperatingPoint ("gd", gd);
     150                 :          0 :   setOperatingPoint ("Id", Id);
     151                 :          0 :   setOperatingPoint ("Cd", Cd);
     152                 :          0 : }
     153                 :            : 
     154                 :            : // Callback for initializing the AC analysis.
     155                 :          0 : void tunneldiode::initAC (void) {
     156                 :          0 :   initDC ();
     157                 :          0 : }
     158                 :            : 
     159                 :            : // Build admittance matrix for AC and SP analysis.
     160                 :          0 : matrix tunneldiode::calcMatrixY (nr_double_t frequency) {
     161         [ #  # ]:          0 :   nr_double_t gd = getOperatingPoint ("gd");
     162         [ #  # ]:          0 :   nr_double_t Cd = getOperatingPoint ("Cd");
     163                 :          0 :   nr_complex_t yd = nr_complex_t (gd, Cd * 2.0 * M_PI * frequency);
     164         [ #  # ]:          0 :   matrix y (2);
     165         [ #  # ]:          0 :   y.set (NODE_A1, NODE_A1, +yd);
     166         [ #  # ]:          0 :   y.set (NODE_A2, NODE_A2, +yd);
     167         [ #  # ]:          0 :   y.set (NODE_A1, NODE_A2, -yd);
     168         [ #  # ]:          0 :   y.set (NODE_A2, NODE_A1, -yd);
     169                 :          0 :   return y;
     170                 :            : }
     171                 :            : 
     172                 :            : // Callback for the AC analysis.
     173                 :          0 : void tunneldiode::calcAC (nr_double_t frequency) {
     174         [ #  # ]:          0 :   setMatrixY (calcMatrixY (frequency));
     175                 :          0 : }
     176                 :            : 
     177                 :            : // Callback for S-parameter analysis.
     178                 :          0 : void tunneldiode::calcSP (nr_double_t frequency) {
     179 [ #  # ][ #  # ]:          0 :   setMatrixS (ytos (calcMatrixY (frequency)));
         [ #  # ][ #  # ]
                 [ #  # ]
     180                 :          0 : }
     181                 :            : 
     182                 :            : #define qState 0 // charge state
     183                 :            : #define cState 1 // current state
     184                 :            : 
     185                 :            : // Callback for initializing the TR analysis.
     186                 :          0 : void tunneldiode::initTR (void) {
     187                 :          0 :   setStates (2);
     188                 :          0 :   initDC ();
     189                 :          0 : }
     190                 :            : 
     191                 :            : // Callback for the TR analysis.
     192                 :          0 : void tunneldiode::calcTR (nr_double_t) {
     193                 :          0 :   calcDC ();
     194                 :            : 
     195                 :          0 :   saveOperatingPoints ();
     196                 :          0 :   loadOperatingPoints ();
     197                 :          0 :   calcOperatingPoints ();
     198                 :            : 
     199                 :          0 :   nr_double_t Cd = getOperatingPoint ("Cd");
     200                 :          0 :   transientCapacitance (qState, NODE_A1, NODE_A2, Cd, Ud, Qd);
     201                 :          0 : }
     202                 :            : 
     203                 :            : // properties
     204                 :            : PROP_REQ [] = {
     205                 :            :   { "Ip", PROP_REAL, { 4.0e-3, PROP_NO_STR }, PROP_POS_RANGE },
     206                 :            :   { "Iv", PROP_REAL, { 0.6e-3, PROP_NO_STR }, PROP_POS_RANGE },
     207                 :            :   { "Vv", PROP_REAL, { 0.8, PROP_NO_STR }, PROP_POS_RANGE },
     208                 :            : 
     209                 :            :   { "Cj0", PROP_REAL, { 80e-15, PROP_NO_STR }, PROP_POS_RANGE },
     210                 :            :   { "M", PROP_REAL, { 0.5, PROP_NO_STR }, PROP_RNGII (0, 2) },
     211                 :            :   { "Vj", PROP_REAL, { 0.5, PROP_NO_STR }, PROP_RNGXI (0, 10) },
     212                 :            :   PROP_NO_PROP };
     213                 :            : PROP_OPT [] = {
     214                 :            :   { "Wr", PROP_REAL, { 2.7e-20, PROP_NO_STR }, PROP_POS_RANGE },
     215                 :            :   { "eta", PROP_REAL, { 1e-20, PROP_NO_STR }, PROP_POS_RANGE },
     216                 :            :   { "dW", PROP_REAL, { 4.5e-21, PROP_NO_STR }, PROP_POS_RANGE },
     217                 :            :   { "Tmax", PROP_REAL, { 0.95, PROP_NO_STR }, PROP_POS_RANGE },
     218                 :            :   { "de", PROP_REAL, { 0.9, PROP_NO_STR }, PROP_POS_RANGE },
     219                 :            :   { "dv", PROP_REAL, { 2.0, PROP_NO_STR }, PROP_POS_RANGE },
     220                 :            :   { "nv", PROP_REAL, { 16, PROP_NO_STR }, PROP_POS_RANGE },
     221                 :            :   { "te", PROP_REAL, { 0.6e-12, PROP_NO_STR }, PROP_POS_RANGE },
     222                 :            :   { "Temp", PROP_REAL, { 26.85, PROP_NO_STR }, PROP_MIN_VAL (K) },
     223                 :            :   { "Area", PROP_REAL, { 1, PROP_NO_STR }, PROP_POS_RANGEX },
     224                 :            :   PROP_NO_PROP };
     225                 :            : struct define_t tunneldiode::cirdef =
     226                 :            :   { "RTD", 2, PROP_COMPONENT, PROP_NO_SUBSTRATE, PROP_NONLINEAR, PROP_DEF };

Generated by: LCOV version 1.11