My Project  0.0.16
QUCS Mapping
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
thyristor.cpp
Go to the documentation of this file.
1 /*
2  * thyristor.cpp - thyristor class implementation
3  *
4  * Copyright (C) 2008 Stefan Jahn <stefan@lkcc.org>
5  * Copyright (C) 2008 Michael Margraf <Michael.Margraf@alumni.TU-Berlin.DE>
6  *
7  * This is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2, or (at your option)
10  * any later version.
11  *
12  * This software is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this package; see the file COPYING. If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  *
22  * $Id: thyristor.cpp 1825 2011-03-11 20:42:14Z ela $
23  *
24  */
25 
26 #if HAVE_CONFIG_H
27 # include <config.h>
28 #endif
29 
30 #include "component.h"
31 #include "device.h"
32 #include "devstates.h"
33 #include "thyristor.h"
34 
35 #define NODE_A1 0 /* anode 1 */
36 #define NODE_A2 1 /* anode 2 (cathode) */
37 #define NODE_GA 2 /* gate */
38 #define NODE_IN 3 /* internal node */
39 
40 using namespace device;
41 
42 // Constructor for the thyristor.
43 thyristor::thyristor () : circuit (4) {
44  type = CIR_THYRISTOR;
45 }
46 
47 // Callback for initializing the DC analysis.
48 void thyristor::initDC (void) {
49  Ud_last = 0.0;
50  // allocate MNA matrices
51  allocMatrixMNA ();
52  // create internal node
53  setInternalNode (NODE_IN, "int");
54 }
55 
56 // Callback for DC analysis.
57 void thyristor::calcDC (void) {
58  calcTheModel (false);
59 }
60 
61 void thyristor::calcTheModel (bool last) {
62  // get device properties
63  nr_double_t Ubo = getPropertyDouble ("Vbo");
64  nr_double_t Ibo = getPropertyDouble ("Igt");
65  nr_double_t Is = getPropertyDouble ("Is");
66  nr_double_t N = getPropertyDouble ("N");
67  nr_double_t Gg = 1.0 / getPropertyDouble ("Rg");
68  nr_double_t T = getPropertyDouble ("Temp");
69  gi = 1.0 / getPropertyDouble ("Ri");
70 
71  nr_double_t Ut, Ud_bo, Ieq, Vd;
72 
73  Ut = N * kelvin (T) * kBoverQ;
74  Ud_bo = log (Ibo / Is + 1.0);
75 
76  Vd = Ud = real (getV (NODE_IN) - getV (NODE_A2));
77  Id = Is;
78  Ud /= Ut;
79 
80  bool isOn;
81  if (last)
82  isOn = (Ud_last / Ut) > Ud_bo;
83  else
84  isOn = Ud > Ud_bo;
85 
86  if (Ud >= 80.0) {
87  Id *= exp (80.0) * (1.0 + Ud - 80.0) - 1.0;
88  Ud = 80.0;
89  }
90  else
91  Id *= exp (Ud) - 1.0;
92 
93  gd = Is / Ut * exp (Ud);
94  Ieq = Id - Vd * gd;
95 
96  // fill in I-Vector
97  setI (NODE_A2, +Ieq);
98  setI (NODE_IN, -Ieq);
99  setI (NODE_A1, +0.0);
100  setI (NODE_GA, +0.0);
101 
102  if (!isOn) {
103  Ut = Ubo / log (Ibo / Is);
104  Vd = Ud = real (getV (NODE_A1) - getV (NODE_IN));
105  Id = Is;
106  Ud /= Ut;
107 
108  if (Ud >= 80.0) {
109  Id *= exp (80.0) * (1.0 + Ud - 80.0) - 1.0;
110  Ud = 80.0;
111  }
112  else
113  Id *= exp (Ud) - 1.0;
114 
115  gi = Is / Ut * exp (Ud);
116  Ieq = Id - Vd * gi;
117  addI (NODE_A1, -Ieq);
118  addI (NODE_IN, +Ieq);
119  }
120 
121  // fill in G-Matrix
122  setY (NODE_A2, NODE_A2, +gd); setY (NODE_IN, NODE_IN, +gd);
123  setY (NODE_A2, NODE_IN, -gd); setY (NODE_IN, NODE_A2, -gd);
124  setY (NODE_A1, NODE_A1, +gi); addY (NODE_IN, NODE_IN, +gi);
125  setY (NODE_A1, NODE_IN, -gi); setY (NODE_IN, NODE_A1, -gi);
126  setY (NODE_GA, NODE_GA, +Gg); addY (NODE_IN, NODE_IN, +Gg);
127  setY (NODE_GA, NODE_IN, -Gg); setY (NODE_IN, NODE_GA, -Gg);
128 }
129 
130 // Saves operating points (voltages).
132  nr_double_t Vd = real (getV (NODE_IN) - getV (NODE_A2));
133  nr_double_t Vi = real (getV (NODE_A1) - getV (NODE_IN));
134  setOperatingPoint ("Vd", Vd);
135  setOperatingPoint ("Vi", Vi);
136 }
137 
138 // Loads operating points (voltages).
140  Ud = getOperatingPoint ("Vd");
141  Ui = getOperatingPoint ("Vi");
142 }
143 
144 // Calculates and saves operating points.
146  nr_double_t Cj0 = getPropertyDouble ("Cj0");
147  // calculate capacitances and charges
148  nr_double_t Ci;
149  Ci = Cj0;
150  Qi = Cj0 * Ui;
151  // save operating points
152  setOperatingPoint ("gi", gi);
153  setOperatingPoint ("gd", gd);
154  setOperatingPoint ("Id", Id);
155  setOperatingPoint ("Ci", Ci);
156 }
157 
158 // Callback for initializing the AC analysis.
159 void thyristor::initAC (void) {
160  initDC ();
161 }
162 
163 // Build admittance matrix for AC and SP analysis.
164 matrix thyristor::calcMatrixY (nr_double_t frequency) {
165  nr_double_t gd = getOperatingPoint ("gd");
166  nr_double_t gi = getOperatingPoint ("gi");
167  nr_double_t gg = 1.0 / getPropertyDouble ("Rg");
168  nr_double_t Ci = getOperatingPoint ("Ci");
169  nr_complex_t yi = rect (gi, Ci * 2.0 * M_PI * frequency);
170  matrix y (4);
171  y.set (NODE_A2, NODE_A2, +gd);
172  y.set (NODE_IN, NODE_IN, +gd +yi +gg);
173  y.set (NODE_A2, NODE_IN, -gd);
174  y.set (NODE_IN, NODE_A2, -gd);
175  y.set (NODE_A1, NODE_A1, +yi);
176  y.set (NODE_A1, NODE_IN, -yi);
177  y.set (NODE_IN, NODE_A1, -yi);
178  y.set (NODE_GA, NODE_GA, +gg);
179  y.set (NODE_GA, NODE_IN, -gg);
180  y.set (NODE_IN, NODE_GA, -gg);
181  return y;
182 }
183 
184 // Callback for the AC analysis.
185 void thyristor::calcAC (nr_double_t frequency) {
186  setMatrixY (calcMatrixY (frequency));
187 }
188 
189 // Callback for S-parameter analysis.
190 void thyristor::calcSP (nr_double_t frequency) {
191  setMatrixS (ytos (calcMatrixY (frequency)));
192 }
193 
194 #define qState 0 // charge state
195 #define cState 1 // current state
196 
197 // Callback for initializing the TR analysis.
198 void thyristor::initTR (void) {
199  setStates (2);
200  initDC ();
201  time_prev = -1.0;
202 }
203 
204 // Callback for the TR analysis.
205 void thyristor::calcTR (nr_double_t time) {
206  if (time_prev < time) {
207  time_prev = time;
208  Ud_last = fabs (real (getV (NODE_IN) - getV (NODE_A2)));
209  }
210  calcTheModel (true);
211 
215 
216  nr_double_t Ci = getOperatingPoint ("Ci");
217  transientCapacitance (qState, NODE_A1, NODE_IN, Ci, Ui, Qi);
218 }
219 
220 // properties
221 PROP_REQ [] = {
222  { "Igt", PROP_REAL, { 50e-6, PROP_NO_STR }, PROP_POS_RANGEX },
223  { "Vbo", PROP_REAL, { 30, PROP_NO_STR }, PROP_POS_RANGEX },
224  PROP_NO_PROP };
225 PROP_OPT [] = {
226  { "Cj0", PROP_REAL, { 10e-12, PROP_NO_STR }, PROP_POS_RANGE },
227  { "Is", PROP_REAL, { 1e-10, PROP_NO_STR }, PROP_POS_RANGE },
228  { "N", PROP_REAL, { 2.0, PROP_NO_STR }, PROP_RNGII (0.1, 100) },
229  { "Ri", PROP_REAL, { 10.0, PROP_NO_STR }, PROP_POS_RANGEX },
230  { "Rg", PROP_REAL, { 5.0, PROP_NO_STR }, PROP_POS_RANGEX },
231  { "Temp", PROP_REAL, { 26.85, PROP_NO_STR }, PROP_MIN_VAL (K) },
232  PROP_NO_PROP };
233 struct define_t thyristor::cirdef =