Qucs-core  0.0.18
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
tunneldiode.cpp
Go to the documentation of this file.
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 tunneldiode::tunneldiode () : circuit (2) {
42  type = CIR_TUNNELDIODE;
43 }
44 
45 // Callback for initializing the DC analysis.
46 void tunneldiode::initDC (void) {
47  // allocate MNA matrices
48  allocMatrixMNA ();
49 }
50 
51 // Calculate one branch of the tunnel current.
52 void tunneldiode::calcId (nr_double_t U, nr_double_t& I, nr_double_t& G) {
53  nr_double_t eta = getPropertyDouble ("eta");
54  nr_double_t Wr = getPropertyDouble ("Wr");
55  nr_double_t dv = getPropertyDouble ("dv");
56  nr_double_t de = getPropertyDouble ("de");
57  nr_double_t dW = getPropertyDouble ("dW");
58 
59  U = Wr - Q_e*U/dv;
60  de *= kB * kelvin (getPropertyDouble ("Temp"));
61 
62  nr_double_t a = M_PI_2 + qucs::atan ( U / dW );
63 
64  nr_double_t e = (eta - U) / de;
65  nr_double_t b = e;
66  if (e < 15.0) // avoid numerical overflow
67  b = qucs::log (1.0 + qucs::exp ( e ));
68 
69  // current
70  I = b * a;
71 
72  // derivative
73  G = Q_e / dv / de / (1.0 + qucs::exp(-e)) * a - b * Q_e / dv / dW / (1.0 + sqr (U/dW));
74 }
75 
76 // Callback for DC analysis.
77 void tunneldiode::calcDC (void) {
78  // get device properties
79  nr_double_t Ip = getPropertyDouble ("Ip");
80  nr_double_t A = getPropertyDouble ("Area");
81  nr_double_t Tmax = getPropertyDouble ("Tmax");
82  nr_double_t de = getPropertyDouble ("de");
83  nr_double_t eta = getPropertyDouble ("eta");
84  nr_double_t Iv = getPropertyDouble ("Iv");
85  nr_double_t Vv = getPropertyDouble ("Vv");
86  nr_double_t nv = getPropertyDouble ("nv");
87  nr_double_t T = kB * kelvin (getPropertyDouble ("Temp"));
88 
89  // diode voltage
90  Ud = real (getV (NODE_A1) - getV (NODE_A2));
91 
92  // bi-directional tunnel current
93  nr_double_t Ipos, Ineg, Gpos, Gneg;
94  gd = Id = A * Ip * Tmax * de * T / eta / M_PI_2;
95  calcId ( Ud, Ipos, Gpos);
96  calcId (-Ud, Ineg, Gneg);
97  Id *= Ipos - Ineg;
98  gd *= Gpos + Gneg;
99 
100  // thermal-ionic current
101  nv *= T / Q_e;
102  nr_double_t c = A * Iv / qucs::sinh (Vv / nv);
103  Id += c * qucs::sinh (Ud / nv);
104  gd += c * qucs::cosh (Ud / nv) / nv;
105 
106  nr_double_t Ieq = Id - Ud * gd;
107 
108  // fill in I-Vector
109  setI (NODE_A2, +Ieq);
110  setI (NODE_A1, -Ieq);
111 
112  // fill in G-Matrix
113  setY (NODE_A1, NODE_A1, +gd); setY (NODE_A2, NODE_A2, +gd);
114  setY (NODE_A1, NODE_A2, -gd); setY (NODE_A2, NODE_A1, -gd);
115 }
116 
117 // Saves operating points (voltages).
119  nr_double_t Vd = real (getV (NODE_A1) - getV (NODE_A2));
120  setOperatingPoint ("Vd", Vd);
121 }
122 
123 // Loads operating points (voltages).
125  Ud = getOperatingPoint ("Vd");
126 }
127 
128 // Calculates and saves operating points.
130  nr_double_t A = getPropertyDouble ("Area");
131  nr_double_t Cj0 = getPropertyDouble ("Cj0");
132  nr_double_t M = getScaledProperty ("M");
133  nr_double_t Vj = getScaledProperty ("Vj");
134  nr_double_t te = getScaledProperty ("te");
135 
136  // calculate capacitances and charges
137  nr_double_t Cd;
138 
139  // depletion capacitance
140  nr_double_t c = 1.0 + fabs(Ud) / Vj;
141  Cd = A * Cj0 / qucs::pow (c, M);
142  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  Cd -= te * gd;
146  Qd -= te * Id;
147 
148  // save operating points
149  setOperatingPoint ("gd", gd);
150  setOperatingPoint ("Id", Id);
151  setOperatingPoint ("Cd", Cd);
152 }
153 
154 // Callback for initializing the AC analysis.
155 void tunneldiode::initAC (void) {
156  initDC ();
157 }
158 
159 // Build admittance matrix for AC and SP analysis.
160 matrix tunneldiode::calcMatrixY (nr_double_t frequency) {
161  nr_double_t gd = getOperatingPoint ("gd");
162  nr_double_t Cd = getOperatingPoint ("Cd");
163  nr_complex_t yd = nr_complex_t (gd, Cd * 2.0 * M_PI * frequency);
164  matrix y (2);
165  y.set (NODE_A1, NODE_A1, +yd);
166  y.set (NODE_A2, NODE_A2, +yd);
167  y.set (NODE_A1, NODE_A2, -yd);
168  y.set (NODE_A2, NODE_A1, -yd);
169  return y;
170 }
171 
172 // Callback for the AC analysis.
173 void tunneldiode::calcAC (nr_double_t frequency) {
174  setMatrixY (calcMatrixY (frequency));
175 }
176 
177 // Callback for S-parameter analysis.
178 void tunneldiode::calcSP (nr_double_t frequency) {
179  setMatrixS (ytos (calcMatrixY (frequency)));
180 }
181 
182 #define qState 0 // charge state
183 #define cState 1 // current state
184 
185 // Callback for initializing the TR analysis.
186 void tunneldiode::initTR (void) {
187  setStates (2);
188  initDC ();
189 }
190 
191 // Callback for the TR analysis.
192 void tunneldiode::calcTR (nr_double_t) {
193  calcDC ();
194 
198 
199  nr_double_t Cd = getOperatingPoint ("Cd");
201 }
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 =
std::complex< nr_double_t > nr_complex_t
Definition: complex.h:31
nr_double_t getOperatingPoint(const char *)
Definition: circuit.cpp:525
#define PROP_POS_RANGE
Definition: netdefs.h:129
matrix ytos(matrix y, qucs::vector z0)
Admittance matrix to scattering parameters.
Definition: matrix.cpp:1133
matrix real(matrix a)
Real part matrix.
Definition: matrix.cpp:568
#define PROP_RNGII(f, t)
Definition: netdefs.h:138
#define kelvin(x)
Definition: constants.h:108
#define PROP_DEF
Definition: netdefs.h:189
nr_double_t getPropertyDouble(const char *)
Definition: object.cpp:176
nr_complex_t pow(const nr_complex_t z, const nr_double_t d)
Compute power function with real exponent.
Definition: complex.cpp:238
#define PROP_REAL
Definition: netdefs.h:174
void setStates(int n)
Definition: states.h:52
#define PROP_NO_PROP
Definition: netdefs.h:122
#define NODE_A2
Definition: tunneldiode.cpp:35
void initTR(void)
nr_complex_t atan(const nr_complex_t z)
Compute complex arc tangent.
Definition: complex.cpp:117
#define K
Absolute 0 in centigrade.
Definition: constants.h:59
void calcId(nr_double_t, nr_double_t &, nr_double_t &)
Definition: tunneldiode.cpp:52
#define PROP_NO_STR
Definition: netdefs.h:125
nr_double_t getScaledProperty(const char *)
Definition: object.cpp:185
void calcDC(void)
Definition: tunneldiode.cpp:77
nr_double_t Qd
Definition: tunneldiode.h:44
qucs::matrix calcMatrixY(nr_double_t)
nr_complex_t cosh(const nr_complex_t z)
Compute complex hyperbolic cosine.
Definition: complex.cpp:135
nr_complex_t sqr(const nr_complex_t z)
Square of complex number.
Definition: complex.cpp:673
#define M_PI_2
Half of Archimedes' constant ( )
Definition: consts.h:51
nr_double_t Ud
Definition: tunneldiode.h:44
void calcOperatingPoints(void)
void transientCapacitance(int, int, int, nr_double_t, nr_double_t, nr_double_t)
Definition: circuit.cpp:759
nr_double_t Id
Definition: tunneldiode.h:44
void calcAC(nr_double_t)
#define Q_e
Elementary charge ( )
Definition: constants.h:66
#define PROP_COMPONENT
Definition: netdefs.h:116
#define kB
Boltzmann constant ( )
Definition: constants.h:64
#define NODE_A1
Definition: tunneldiode.cpp:34
void setMatrixY(matrix)
Definition: circuit.cpp:685
#define M_PI
Archimedes' constant ( )
Definition: consts.h:47
void initAC(void)
void setI(int, nr_complex_t)
Definition: circuit.cpp:397
void setMatrixS(matrix)
Definition: circuit.cpp:643
type
Definition: parse_vcd.y:164
void setY(int, int, nr_complex_t)
Definition: circuit.cpp:452
#define PROP_MIN_VAL(k)
Definition: netdefs.h:133
void saveOperatingPoints(void)
#define qState
void calcTR(nr_double_t)
void allocMatrixMNA(void)
Definition: circuit.cpp:267
void initDC(void)
Definition: tunneldiode.cpp:46
nr_complex_t sinh(const nr_complex_t z)
Compute complex hyperbolic sine.
Definition: complex.cpp:144
#define PROP_POS_RANGEX
Definition: netdefs.h:131
#define A(a)
Definition: eqndefined.cpp:72
y
Definition: parse_mdl.y:499
nr_double_t getV(int, nr_double_t)
Definition: circuit.cpp:941
nr_complex_t exp(const nr_complex_t z)
Compute complex exponential.
Definition: complex.cpp:205
nr_double_t gd
Definition: tunneldiode.h:44
void setOperatingPoint(const char *, nr_double_t)
Definition: circuit.cpp:533
PROP_OPT[]
PROP_REQ[]
#define PROP_RNGXI(f, t)
Definition: netdefs.h:139
void calcSP(nr_double_t)
#define M(con)
Definition: evaluate.cpp:64
nr_complex_t log(const nr_complex_t z)
Compute principal value of natural logarithm of z.
Definition: complex.cpp:215
void loadOperatingPoints(void)
#define PROP_NONLINEAR
Definition: netdefs.h:119
#define PROP_NO_SUBSTRATE
Definition: netdefs.h:118