Xyce  6.1
N_DEV_BJT.C
Go to the documentation of this file.
1 //-----------------------------------------------------------------------------
2 // Copyright Notice
3 //
4 // Copyright 2002 Sandia Corporation. Under the terms
5 // of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S.
6 // Government retains certain rights in this software.
7 //
8 // Xyce(TM) Parallel Electrical Simulator
9 // Copyright (C) 2002-2015 Sandia Corporation
10 //
11 // This program is free software: you can redistribute it and/or modify
12 // it under the terms of the GNU General Public License as published by
13 // the Free Software Foundation, either version 3 of the License, or
14 // (at your option) any later version.
15 //
16 // This program is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU General Public License for more details.
20 //
21 // You should have received a copy of the GNU General Public License
22 // along with this program. If not, see <http://www.gnu.org/licenses/>.
23 //-----------------------------------------------------------------------------
24 
25 //-------------------------------------------------------------------------
26 // Filename : $RCSfile: N_DEV_BJT.C,v $
27 //
28 // Purpose :
29 //
30 // Special Notes :
31 //
32 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
33 //
34 // Creation Date : 02/28/00
35 //
36 // Revision Information:
37 // ---------------------
38 //
39 // Revision Number: $Revision: 1.413 $
40 //
41 // Revision Date : $Date: 2015/09/25 21:19:47 $
42 //
43 // Current Owner : $Author: rlschie $
44 //-------------------------------------------------------------------------
45 #include <Xyce_config.h>
46 
47 // ---------- Standard Includes ----------
48 #include <cstdio>
49 
50 // ---------- Xyce Includes ----------
51 #include <N_DEV_BJT.h>
52 #include <N_DEV_Const.h>
53 #include <N_DEV_DeviceOptions.h>
54 #include <N_DEV_ExternData.h>
55 #include <N_DEV_MatrixLoadData.h>
56 #include <N_DEV_SolverState.h>
57 #include <N_DEV_Message.h>
58 #include <N_ERH_ErrorMgr.h>
59 
60 #include <N_LAS_Matrix.h>
61 #include <N_LAS_MultiVector.h>
62 #include <N_LAS_Vector.h>
63 #include <N_UTL_FeatureTest.h>
64 #include <N_UTL_Math.h>
65 #include <N_UTL_ExtendedString.h>
66 #include <N_ANP_NoiseData.h>
67 
68 namespace Xyce {
69 namespace Device {
70 
71 namespace BJT {
72 
74 {
75  p.addPar ("AREA",1.0,&BJT::Instance::AREA)
76  .setUnit(U_NONE)
77  .setCategory(CAT_GEOMETRY)
78  .setDescription("Relative device area")
79  .setAnalyticSensitivityAvailable(true)
80  .setSensitivityFunctor(&bjtInstanceSens);
81 
82  p.addPar ("IC1",0.0,&BJT::Instance::icVBE)
83  .setGivenMember(&BJT::Instance::IC_GIVEN)
84  .setUnit(U_VOLT)
85  .setCategory(CAT_VOLT)
86  .setDescription("Vector of initial values: Vbe,Vce. Vbe=IC1");
87 
88  p.addPar ("IC2",0.0,&BJT::Instance::icVCE)
89  .setGivenMember(&BJT::Instance::IC_GIVEN)
90  .setUnit(U_VOLT)
91  .setCategory(CAT_VOLT)
92  .setDescription("Vector of initial values: Vbe,Vce. Vce=IC2");
93 
94  p.addPar ("TEMP",0.0,&BJT::Instance::TEMP)
95  .setExpressionAccess(ParameterType::TIME_DEP)
96  .setUnit(STANDARD)
97  .setCategory(CAT_UNKNOWN)
98  .setDescription("Device temperature")
99  .setAnalyticSensitivityAvailable(true)
100  .setSensitivityFunctor(&bjtInstanceSens);
101 
102  // Set up non-double precision variables:
103  p.addPar ("OFF",false,&BJT::Instance::OFF)
104  .setUnit(U_LOGIC)
105  .setCategory(CAT_VOLT)
106  .setDescription("Initial condition of no voltage drops accross device");
107 
108  p.addPar ("LAMBERTW",false,&BJT::Instance::lambertWFlag)
109  .setUnit(U_LOGIC)
110  .setCategory(CAT_NONE)
111  .setDescription("Flag for toggling the use of the lambert-W function instead of exponentials.");
112 
113  p.makeVector ("IC",2);
114 }
115 
117 {
118  // Set up double precision variables:
119  p.addPar ("TNOM",0.0,&BJT::Model::TNOM)
120  .setUnit(U_DEGC)
121  .setCategory(CAT_UNKNOWN)
122  .setDescription("Parameter measurement temperature")
123  .setAnalyticSensitivityAvailable(true)
124  .setSensitivityFunctor(&bjtModelSens);
125 
126  p.addPar ("IS",1.e-16,&BJT::Model::satCur)
127  .setExpressionAccess(ParameterType::LOG_T_DEP)
128  .setUnit(U_AMP)
129  .setCategory(CAT_UNKNOWN)
130  .setDescription("Transport saturation current")
131  .setAnalyticSensitivityAvailable(true)
132  .setSensitivityFunctor(&bjtModelSens);
133 
134  p.addPar ("BF",100.0,&BJT::Model::betaF)
135  .setOriginalValueStored(true)
136  .setGivenMember(&BJT::Model::BFgiven)
137  .setUnit(U_NONE)
138  .setCategory(CAT_UNKNOWN)
139  .setDescription("Ideal maximum foward beta")
140  .setAnalyticSensitivityAvailable(true)
141  .setSensitivityFunctor(&bjtModelSens);
142 
143  // hspice
144  p.addPar ("BFM",100.0,&BJT::Model::betaF)
145  .setOriginalValueStored(true)
146  .setGivenMember(&BJT::Model::BFMgiven)
147  .setUnit(U_NONE)
148  .setCategory(CAT_UNKNOWN)
149  .setDescription("Ideal maximum foward beta")
150  .setAnalyticSensitivityAvailable(true)
151  .setSensitivityFunctor(&bjtModelSens);
152 
153  p.addPar ("NF",1.0,&BJT::Model::emissionCoeffF)
154  .setOriginalValueStored(true)
155  .setUnit(U_NONE)
156  .setCategory(CAT_UNKNOWN)
157  .setDescription("Foward current emission coefficient")
158  .setAnalyticSensitivityAvailable(true)
159  .setSensitivityFunctor(&bjtModelSens);
160 
161  // forward early voltage has aliases for different spice flavors.
162  // Hspice/Pspice
163  p.addPar ("VA",0.0,&BJT::Model::earlyVoltF)
164  .setGivenMember(&BJT::Model::VAgiven)
165  .setUnit(U_VOLT)
166  .setCategory(CAT_UNKNOWN)
167  .setDescription("Foward early voltage")
168  .setAnalyticSensitivityAvailable(true)
169  .setSensitivityFunctor(&bjtModelSens);
170 
171  // Hspice
172  p.addPar ("VBF",0.0,&BJT::Model::earlyVoltF)
173  .setGivenMember(&BJT::Model::VBFgiven)
174  .setUnit(U_VOLT)
175  .setCategory(CAT_UNKNOWN)
176  .setDescription("Foward early voltage")
177  .setAnalyticSensitivityAvailable(true)
178  .setSensitivityFunctor(&bjtModelSens);
179 
180  // spice3
181  p.addPar ("VAF",0.0,&BJT::Model::earlyVoltF)
182  .setGivenMember(&BJT::Model::VAFgiven)
183  .setUnit(U_VOLT)
184  .setCategory(CAT_UNKNOWN)
185  .setDescription("Foward early voltage")
186  .setAnalyticSensitivityAvailable(true)
187  .setSensitivityFunctor(&bjtModelSens);
188 
189  p.addPar ("IKF",0.0,&BJT::Model::rollOffF)
190  .setGivenMember(&BJT::Model::IKFgiven)
191  .setUnit(U_AMP)
192  .setCategory(CAT_UNKNOWN)
193  .setDescription("Corner for foward-beta high-current roll-off")
194  .setAnalyticSensitivityAvailable(true)
195  .setSensitivityFunctor(&bjtModelSens);
196 
197  p.addPar ("IK",0.0,&BJT::Model::rollOffF)
198  .setGivenMember(&BJT::Model::IKgiven)
199  .setUnit(U_AMP)
200  .setCategory(CAT_UNKNOWN)
201  .setDescription("Corner for foward-beta high-current roll-off")
202  .setAnalyticSensitivityAvailable(true)
203  .setSensitivityFunctor(&bjtModelSens);
204 
205  p.addPar ("JBF",0.0,&BJT::Model::rollOffF)
206  .setGivenMember(&BJT::Model::JBFgiven)
207  .setUnit(U_AMP)
208  .setCategory(CAT_UNKNOWN)
209  .setDescription("Corner for foward-beta high-current roll-off")
210  .setAnalyticSensitivityAvailable(true)
211  .setSensitivityFunctor(&bjtModelSens);
212 
213  // base-emitter leakage sat current has aliases for different spice flavors.
214  p.addPar ("ISE",0.0,&BJT::Model::leakBECurrent)
215  .setExpressionAccess(ParameterType::LOG_T_DEP)
216  .setGivenMember(&BJT::Model::leakBECurrentGiven)
217  .setUnit(U_AMP)
218  .setCategory(CAT_UNKNOWN)
219  .setDescription("Base-emitter leakage saturation current")
220  .setAnalyticSensitivityAvailable(true)
221  .setSensitivityFunctor(&bjtModelSens);
222 
223  // Hspice
224  p.addPar ("JLE",0.0,&BJT::Model::leakBECurrent)
225  .setExpressionAccess(ParameterType::LOG_T_DEP)
226  .setGivenMember(&BJT::Model::JLEgiven)
227  .setUnit(U_AMP)
228  .setCategory(CAT_UNKNOWN)
229  .setDescription("Base-emitter leakage saturation current")
230  .setAnalyticSensitivityAvailable(true)
231  .setSensitivityFunctor(&bjtModelSens);
232 
234  .setGivenMember(&BJT::Model::NEgiven)
235  .setUnit(U_NONE)
236  .setCategory(CAT_UNKNOWN)
237  .setDescription("Base-emitter leakage emission coefficient")
238  .setAnalyticSensitivityAvailable(true)
239  .setSensitivityFunctor(&bjtModelSens);
240 
242  .setGivenMember(&BJT::Model::NLEgiven)
243  .setUnit(U_NONE)
244  .setCategory(CAT_UNKNOWN)
245  .setDescription("Base-emitter leakage emission coefficient")
246  .setAnalyticSensitivityAvailable(true)
247  .setSensitivityFunctor(&bjtModelSens);
248 
249  // BR/BRM alias:
250  p.addPar ("BR",1.0,&BJT::Model::betaR)
251  .setGivenMember(&BJT::Model::BRgiven)
252  .setUnit(U_NONE)
253  .setCategory(CAT_UNKNOWN)
254  .setDescription("Ideal maximum reverse beta")
255  .setAnalyticSensitivityAvailable(true)
256  .setSensitivityFunctor(&bjtModelSens);
257 
258  p.addPar ("BRM",1.0,&BJT::Model::betaR)
259  .setGivenMember(&BJT::Model::BRMgiven)
260  .setUnit(U_NONE)
261  .setCategory(CAT_UNKNOWN)
262  .setDescription("Ideal maximum reverse beta")
263  .setAnalyticSensitivityAvailable(true)
264  .setSensitivityFunctor(&bjtModelSens);
265 
266  p.addPar ("NR",1.0,&BJT::Model::emissionCoeffR)
267  .setUnit(U_NONE)
268  .setCategory(CAT_UNKNOWN)
269  .setDescription("Reverse current emission coefficient")
270  .setAnalyticSensitivityAvailable(true)
271  .setSensitivityFunctor(&bjtModelSens);
272 
273  // reverse early voltage has several aliases:
274  // spice
275  p.addPar ("VAR",0.0,&BJT::Model::earlyVoltR)
276  .setGivenMember(&BJT::Model::VARgiven)
277  .setUnit(U_VOLT)
278  .setCategory(CAT_UNKNOWN)
279  .setDescription("Reverse early voltage")
280  .setAnalyticSensitivityAvailable(true)
281  .setSensitivityFunctor(&bjtModelSens);
282 
283  // pspice,hspice
284  p.addPar ("VB",0.0,&BJT::Model::earlyVoltR)
285  .setGivenMember(&BJT::Model::VBgiven)
286  .setUnit(U_VOLT)
287  .setCategory(CAT_UNKNOWN)
288  .setDescription("Reverse early voltage")
289  .setAnalyticSensitivityAvailable(true)
290  .setSensitivityFunctor(&bjtModelSens);
291 
292  // hspice
293  p.addPar ("VRB",0.0,&BJT::Model::earlyVoltR)
294  .setGivenMember(&BJT::Model::VRBgiven)
295  .setUnit(U_VOLT)
296  .setCategory(CAT_UNKNOWN)
297  .setDescription("Reverse early voltage")
298  .setAnalyticSensitivityAvailable(true)
299  .setSensitivityFunctor(&bjtModelSens);
300 
301  // hspice
302  p.addPar ("BV",0.0,&BJT::Model::earlyVoltR)
303  .setGivenMember(&BJT::Model::BVgiven)
304  .setUnit(U_VOLT)
305  .setCategory(CAT_UNKNOWN)
306  .setDescription("Reverse early voltage")
307  .setAnalyticSensitivityAvailable(true)
308  .setSensitivityFunctor(&bjtModelSens);
309 
310  // Corner for reverse-beta high-current roll-off has an alias:
311  p.addPar ("IKR",0.0,&BJT::Model::rollOffR)
312  .setGivenMember(&BJT::Model::IKRgiven)
313  .setUnit(U_AMP)
314  .setCategory(CAT_UNKNOWN)
315  .setDescription("Corner for reverse-beta high-current roll-off")
316  .setAnalyticSensitivityAvailable(true)
317  .setSensitivityFunctor(&bjtModelSens);
318 
319  // hspice
320  p.addPar ("JBR",0.0,&BJT::Model::rollOffR)
321  .setGivenMember(&BJT::Model::JBRgiven)
322  .setUnit(U_AMP)
323  .setCategory(CAT_UNKNOWN)
324  .setDescription("Corner for reverse-beta high-current roll-off")
325  .setAnalyticSensitivityAvailable(true)
326  .setSensitivityFunctor(&bjtModelSens);
327 
328  // Base-collector leakage saturation current has an alias:
329  //spice/pspice
330  p.addPar ("ISC",0.0,&BJT::Model::leakBCCurrent)
331  .setGivenMember(&BJT::Model::leakBCCurrentGiven)
332  .setUnit(U_AMP)
333  .setCategory(CAT_UNKNOWN)
334  .setDescription("Base-collector leakage saturation current")
335  .setAnalyticSensitivityAvailable(true)
336  .setSensitivityFunctor(&bjtModelSens);
337 
338  // hspice
339  p.addPar ("JLC",0.0,&BJT::Model::leakBCCurrent)
340  .setGivenMember(&BJT::Model::JLCgiven)
341  .setUnit(U_AMP)
342  .setCategory(CAT_UNKNOWN)
343  .setDescription("Base-collector leakage saturation current")
344  .setAnalyticSensitivityAvailable(true)
345  .setSensitivityFunctor(&bjtModelSens);
346 
348  .setUnit(U_NONE)
349  .setCategory(CAT_UNKNOWN)
350  .setDescription("Base-collector leakage emission coefficient")
351  .setAnalyticSensitivityAvailable(true)
352  .setSensitivityFunctor(&bjtModelSens);
353 
354  p.addPar ("RB",0.0,&BJT::Model::baseResist)
355  .setUnit(U_OHM)
356  .setCategory(CAT_UNKNOWN)
357  .setDescription("Zero-bias (maximum) base resistance")
358  .setAnalyticSensitivityAvailable(true)
359  .setSensitivityFunctor(&bjtModelSens);
360 
361  // IRB (Current at which RB falls off by half)") has an alias:
362  //spice/pspice
364  .setGivenMember(&BJT::Model::IRBgiven)
365  .setUnit(U_AMP)
366  .setCategory(CAT_UNKNOWN)
367  .setDescription("Current at which RB falls off by half")
368  .setAnalyticSensitivityAvailable(true)
369  .setSensitivityFunctor(&bjtModelSens);
370 
371  // hspice
373  .setGivenMember(&BJT::Model::JRBgiven)
374  .setUnit(U_AMP)
375  .setCategory(CAT_UNKNOWN)
376  .setDescription("Current at which RB falls off by half")
377  .setAnalyticSensitivityAvailable(true)
378  .setSensitivityFunctor(&bjtModelSens);
379 
380  // hspice
382  .setGivenMember(&BJT::Model::IOBgiven)
383  .setUnit(U_AMP)
384  .setCategory(CAT_UNKNOWN)
385  .setDescription("Current at which RB falls off by half")
386  .setAnalyticSensitivityAvailable(true)
387  .setSensitivityFunctor(&bjtModelSens);
388 
389  p.addPar ("RBM",0.0,&BJT::Model::minBaseResist)
390  .setGivenMember(&BJT::Model::minBaseResistGiven)
391  .setUnit(U_OHM)
392  .setCategory(CAT_UNKNOWN)
393  .setDescription("Maximum base resistance")
394  .setAnalyticSensitivityAvailable(true)
395  .setSensitivityFunctor(&bjtModelSens);
396 
397  p.addPar ("RE",0.0,&BJT::Model::emitterResist)
398  .setExpressionAccess(ParameterType::MIN_RES)
399  .setUnit(U_OHM)
400  .setCategory(CAT_UNKNOWN)
401  .setDescription("Emitter ohmic resistance")
402  .setAnalyticSensitivityAvailable(true)
403  .setSensitivityFunctor(&bjtModelSens);
404 
405  p.addPar ("RC",0.0,&BJT::Model::collectorResist)
406  .setExpressionAccess(ParameterType::MIN_RES)
407  .setUnit(U_OHM)
408  .setCategory(CAT_UNKNOWN)
409  .setDescription("Collector ohmic resistance")
410  .setAnalyticSensitivityAvailable(true)
411  .setSensitivityFunctor(&bjtModelSens);
412 
413  p.addPar ("CJE",0.0,&BJT::Model::depCapBE)
414  .setExpressionAccess(ParameterType::MIN_CAP)
415  .setUnit(U_FARAD)
416  .setCategory(CAT_UNKNOWN)
417  .setDescription("Base-emitter zero-bias p-n capacitance")
418  .setAnalyticSensitivityAvailable(true)
419  .setSensitivityFunctor(&bjtModelSens);
420 
421  // alias for VJE:
422  //spice
423  p.addPar ("VJE",0.75,&BJT::Model::potBE)
424  .setGivenMember(&BJT::Model::VJEgiven)
425  .setUnit(U_VOLT)
426  .setCategory(CAT_UNKNOWN)
427  .setDescription("Base-emitter built-in potential")
428  .setAnalyticSensitivityAvailable(true)
429  .setSensitivityFunctor(&bjtModelSens);
430 
431  //pspice/hspice
432  p.addPar ("PE",0.75,&BJT::Model::potBE)
433  .setGivenMember(&BJT::Model::PEgiven)
434  .setUnit(U_VOLT)
435  .setCategory(CAT_UNKNOWN)
436  .setDescription("Base-emitter built-in potential")
437  .setAnalyticSensitivityAvailable(true)
438  .setSensitivityFunctor(&bjtModelSens);
439 
440  // alias for MJE:
441  //spice
442  p.addPar ("MJE",0.33,&BJT::Model::juncExpBE)
443  .setGivenMember(&BJT::Model::MJEgiven)
444  .setUnit(U_NONE)
445  .setCategory(CAT_UNKNOWN)
446  .setDescription("Base-emitter p-n grading factor")
447  .setAnalyticSensitivityAvailable(true)
448  .setSensitivityFunctor(&bjtModelSens);
449 
450  //pspice/hspice
451  p.addPar ("ME",0.33,&BJT::Model::juncExpBE)
452  .setGivenMember(&BJT::Model::MEgiven)
453  .setUnit(U_NONE)
454  .setCategory(CAT_UNKNOWN)
455  .setDescription("Base-emitter p-n grading factor")
456  .setAnalyticSensitivityAvailable(true)
457  .setSensitivityFunctor(&bjtModelSens);
458 
459  p.addPar ("TF",0.0,&BJT::Model::transTimeF)
460  .setUnit(U_SECOND)
461  .setCategory(CAT_UNKNOWN)
462  .setDescription("Ideal foward transit time")
463  .setAnalyticSensitivityAvailable(true)
464  .setSensitivityFunctor(&bjtModelSens);
465 
467  .setUnit(U_NONE)
468  .setCategory(CAT_UNKNOWN)
469  .setDescription("Transit time bias dependence coefficient")
470  .setAnalyticSensitivityAvailable(true)
471  .setSensitivityFunctor(&bjtModelSens);
472 
473  p.addPar ("VTF",0.0,&BJT::Model::transTimeFVBC)
474  .setGivenMember(&BJT::Model::VTFgiven)
475  .setUnit(U_VOLT)
476  .setCategory(CAT_UNKNOWN)
477  .setDescription("Transit time dependancy on Vbc")
478  .setAnalyticSensitivityAvailable(true)
479  .setSensitivityFunctor(&bjtModelSens);
480 
481  // alias for ITF:
482  // spice
484  .setGivenMember(&BJT::Model::ITFgiven)
485  .setUnit(U_UNKNOWN)
486  .setCategory(CAT_UNKNOWN)
487  .setDescription("Transit time dependancy on IC")
488  .setAnalyticSensitivityAvailable(true)
489  .setSensitivityFunctor(&bjtModelSens);
490 
491  // hspice
493  .setGivenMember(&BJT::Model::JTFgiven)
494  .setUnit(U_UNKNOWN)
495  .setCategory(CAT_UNKNOWN)
496  .setDescription("Transit time dependancy on IC")
497  .setAnalyticSensitivityAvailable(true)
498  .setSensitivityFunctor(&bjtModelSens);
499 
500  p.addPar ("PTF",0.0,&BJT::Model::excessPhase)
501  .setUnit(U_DEGREE)
502  .setCategory(CAT_UNKNOWN)
503  .setDescription("Excess Phase at 1/(2pi*TF) Hz")
504  .setAnalyticSensitivityAvailable(true)
505  .setSensitivityFunctor(&bjtModelSens);
506 
507  p.addPar ("CJC",0.0,&BJT::Model::depCapBC)
508  .setExpressionAccess(ParameterType::MIN_CAP)
509  .setUnit(U_FARAD)
510  .setCategory(CAT_UNKNOWN)
511  .setDescription("Base-collector zero-bias p-n capacitance")
512  .setAnalyticSensitivityAvailable(true)
513  .setSensitivityFunctor(&bjtModelSens);
514 
515  // alias for VJC:
516  // spice
517  p.addPar ("VJC",0.75,&BJT::Model::potBC)
518  .setGivenMember(&BJT::Model::VJCgiven)
519  .setUnit(U_VOLT)
520  .setCategory(CAT_UNKNOWN)
521  .setDescription("Base-collector built-in potential")
522  .setAnalyticSensitivityAvailable(true)
523  .setSensitivityFunctor(&bjtModelSens);
524 
525  // pspice,hspice
526  p.addPar ("PC",0.75,&BJT::Model::potBC)
527  .setGivenMember(&BJT::Model::PCgiven)
528  .setUnit(U_VOLT)
529  .setCategory(CAT_UNKNOWN)
530  .setDescription("Base-collector built-in potential")
531  .setAnalyticSensitivityAvailable(true)
532  .setSensitivityFunctor(&bjtModelSens);
533 
534  // alias for MJC:
535  // spice
536  p.addPar ("MJC",0.33,&BJT::Model::juncExpBC)
537  .setGivenMember(&BJT::Model::MJCgiven)
538  .setUnit(U_NONE)
539  .setCategory(CAT_UNKNOWN)
540  .setDescription("Base-collector p-n grading factor")
541  .setAnalyticSensitivityAvailable(true)
542  .setSensitivityFunctor(&bjtModelSens);
543 
544  //pspice/hspice
545  p.addPar ("MC",0.33,&BJT::Model::juncExpBC)
546  .setGivenMember(&BJT::Model::MCgiven)
547  .setUnit(U_NONE)
548  .setCategory(CAT_UNKNOWN)
549  .setDescription("Base-collector p-n grading factor")
550  .setAnalyticSensitivityAvailable(true)
551  .setSensitivityFunctor(&bjtModelSens);
552 
553  // alias for XCJC:
554  p.addPar ("XCJC",1.0,&BJT::Model::baseFracBCCap)
555  .setGivenMember(&BJT::Model::XCJCgiven)
556  .setUnit(U_NONE)
557  .setCategory(CAT_UNKNOWN)
558  .setDescription("Fraction of CJC connected internally to RB")
559  .setAnalyticSensitivityAvailable(true)
560  .setSensitivityFunctor(&bjtModelSens);
561  p.addPar ("CDIS",1.0,&BJT::Model::baseFracBCCap)
562  .setGivenMember(&BJT::Model::CDISgiven)
563  .setUnit(U_NONE)
564  .setCategory(CAT_UNKNOWN)
565  .setDescription("Fraction of CJC connected internally to RB")
566  .setAnalyticSensitivityAvailable(true)
567  .setSensitivityFunctor(&bjtModelSens);
568 
569  p.addPar ("TR",0.0,&BJT::Model::transTimeR)
570  .setUnit(U_SECOND)
571  .setCategory(CAT_UNKNOWN)
572  .setDescription("Ideal reverse transit time")
573  .setAnalyticSensitivityAvailable(true)
574  .setSensitivityFunctor(&bjtModelSens);
575 
576  // substrate zero bias capacitance has several aliases for different spice flavors.
577  // spice
578  p.addPar ("CJS",0.0,&BJT::Model::CJS)
579  .setGivenMember(&BJT::Model::CJSgiven)
580  .setUnit(U_FARAD)
581  .setCategory(CAT_UNKNOWN)
582  .setDescription("Substrate zero-bias p-n capacitance")
583  .setAnalyticSensitivityAvailable(true)
584  .setSensitivityFunctor(&bjtModelSens);
585 
586  // Pspice/Hspice
587  p.addPar ("CCS",0.0,&BJT::Model::CJS)
588  .setGivenMember(&BJT::Model::CCSgiven)
589  .setUnit(U_FARAD)
590  .setCategory(CAT_UNKNOWN)
591  .setDescription("Substrate zero-bias p-n capacitance")
592  .setAnalyticSensitivityAvailable(true)
593  .setSensitivityFunctor(&bjtModelSens);
594 
595  // Hspice
596  p.addPar ("CSUB",0.0,&BJT::Model::CJS)
597  .setGivenMember(&BJT::Model::CSUBgiven)
598  .setUnit(U_FARAD)
599  .setCategory(CAT_UNKNOWN)
600  .setDescription("Substrate zero-bias p-n capacitance")
601  .setAnalyticSensitivityAvailable(true)
602  .setSensitivityFunctor(&bjtModelSens);
603 
604  // aliases for VJS:
605  // spice
606  p.addPar ("VJS",0.75,&BJT::Model::potSubst)
607  .setGivenMember(&BJT::Model::VJSgiven)
608  .setUnit(U_VOLT)
609  .setCategory(CAT_UNKNOWN)
610  .setDescription("Substrate built-in potential")
611  .setAnalyticSensitivityAvailable(true)
612  .setSensitivityFunctor(&bjtModelSens);
613 
614  // pspice
615  p.addPar ("PS",0.75,&BJT::Model::potSubst)
616  .setGivenMember(&BJT::Model::PSgiven)
617  .setUnit(U_VOLT)
618  .setCategory(CAT_UNKNOWN)
619  .setDescription("Substrate built-in potential")
620  .setAnalyticSensitivityAvailable(true)
621  .setSensitivityFunctor(&bjtModelSens);
622 
623  // hspice
624  p.addPar ("PSUB",0.75,&BJT::Model::potSubst)
625  .setGivenMember(&BJT::Model::PSUBgiven)
626  .setUnit(U_VOLT)
627  .setCategory(CAT_UNKNOWN)
628  .setDescription("Substrate built-in potential")
629  .setAnalyticSensitivityAvailable(true)
630  .setSensitivityFunctor(&bjtModelSens);
631 
632  // aliases for MJS:
633  p.addPar ("MJS",0.0,&BJT::Model::expSubst)
634  .setGivenMember(&BJT::Model::MJSgiven)
635  .setUnit(U_NONE)
636  .setCategory(CAT_UNKNOWN)
637  .setDescription("Substrate p-n grading factor")
638  .setAnalyticSensitivityAvailable(true)
639  .setSensitivityFunctor(&bjtModelSens);
640 
641  p.addPar ("MS",0.0,&BJT::Model::expSubst)
642  .setGivenMember(&BJT::Model::MSgiven)
643  .setUnit(U_NONE)
644  .setCategory(CAT_UNKNOWN)
645  .setDescription("Substrate p-n grading factor")
646  .setAnalyticSensitivityAvailable(true)
647  .setSensitivityFunctor(&bjtModelSens);
648 
649  p.addPar ("ESUB",0.0,&BJT::Model::expSubst)
650  .setGivenMember(&BJT::Model::ESUBgiven)
651  .setUnit(U_NONE)
652  .setCategory(CAT_UNKNOWN)
653  .setDescription("Substrate p-n grading factor")
654  .setAnalyticSensitivityAvailable(true)
655  .setSensitivityFunctor(&bjtModelSens);
656 
657  // alias for XTB:
658  //spice/pspice
659  p.addPar ("XTB",0.0,&BJT::Model::betaExp)
660  .setGivenMember(&BJT::Model::XTBgiven)
661  .setUnit(U_NONE)
662  .setCategory(CAT_UNKNOWN)
663  .setDescription("Foward and reverse beta temperature coefficient")
664  .setAnalyticSensitivityAvailable(true)
665  .setSensitivityFunctor(&bjtModelSens);
666 
667  // hspice
668  p.addPar ("TB",0.0,&BJT::Model::betaExp)
669  .setGivenMember(&BJT::Model::TBgiven)
670  .setUnit(U_NONE)
671  .setCategory(CAT_UNKNOWN)
672  .setDescription("Foward and reverse beta temperature coefficient")
673  .setAnalyticSensitivityAvailable(true)
674  .setSensitivityFunctor(&bjtModelSens);
675 
676  // hspice
677  p.addPar ("TCB",0.0,&BJT::Model::betaExp)
678  .setGivenMember(&BJT::Model::TCBgiven)
679  .setUnit(U_NONE)
680  .setCategory(CAT_UNKNOWN)
681  .setDescription("Foward and reverse beta temperature coefficient")
682  .setAnalyticSensitivityAvailable(true)
683  .setSensitivityFunctor(&bjtModelSens);
684 
685  p.addPar ("EG",1.11,&BJT::Model::energyGap)
686  .setUnit(U_EV)
687  .setCategory(CAT_UNKNOWN)
688  .setDescription("Bandgap voltage (barrier highth)")
689  .setAnalyticSensitivityAvailable(true)
690  .setSensitivityFunctor(&bjtModelSens);
691 
692  // alias for XTI:
693  // spice/hspice
694  p.addPar ("XTI",3.0,&BJT::Model::tempExpIS)
695  .setGivenMember(&BJT::Model::XTIgiven)
696  .setUnit(U_UNKNOWN)
697  .setCategory(CAT_UNKNOWN)
698  .setDescription("Temperature exponent for IS. (synonymous with PT)")
699  .setAnalyticSensitivityAvailable(true)
700  .setSensitivityFunctor(&bjtModelSens);
701 
702  // pspice
703  p.addPar ("PT",3.0,&BJT::Model::tempExpIS)
704  .setGivenMember(&BJT::Model::PTgiven)
705  .setUnit(U_UNKNOWN)
706  .setCategory(CAT_UNKNOWN)
707  .setDescription("Temperature exponent for IS. (synonymous with XTI)")
708  .setAnalyticSensitivityAvailable(true)
709  .setSensitivityFunctor(&bjtModelSens);
710 
711  p.addPar ("KF",0.0,&BJT::Model::fNCoeff)
712  .setUnit(U_NONE)
713  .setCategory(CAT_UNKNOWN)
714  .setDescription("Flicker noise coefficient");
715 
716  p.addPar ("AF",1.0,&BJT::Model::fNExp)
717  .setUnit(U_UNKNOWN)
718  .setCategory(CAT_UNKNOWN)
719  .setDescription("Flicker noise exponent");
720 
721  p.addPar ("FC",0.5,&BJT::Model::depCapCoeff)
722  .setGivenMember(&BJT::Model::FCgiven)
723  .setUnit(U_NONE)
724  .setCategory(CAT_UNKNOWN)
725  .setDescription("Foward-bias depletion capacitor coefficient")
726  .setAnalyticSensitivityAvailable(true)
727  .setSensitivityFunctor(&bjtModelSens);
728 
729  p.addPar ("C2",0.0,&BJT::Model::c2)
730  .setGivenMember(&BJT::Model::c2Given)
731  .setUnit(U_UNKNOWN)
732  .setCategory(CAT_UNKNOWN)
733  .setDescription("Coefficient for base-emitter leak current.")
734  .setAnalyticSensitivityAvailable(true)
735  .setSensitivityFunctor(&bjtModelSens);
736 
737  p.addPar ("C4",0.0,&BJT::Model::c4)
738  .setGivenMember(&BJT::Model::c4Given)
739  .setUnit(U_UNKNOWN)
740  .setCategory(CAT_UNKNOWN)
741  .setDescription("Coefficient for base-collector leak current.")
742  .setAnalyticSensitivityAvailable(true)
743  .setSensitivityFunctor(&bjtModelSens);
744 
745  // alias for NK/NKF:
746  p.addPar ("NK",0.5,&BJT::Model::rollOffExp)
747  .setGivenMember(&BJT::Model::NKgiven)
748  .setUnit(U_NONE)
749  .setCategory(CAT_UNKNOWN)
750  .setDescription("High current rolloff coefficient")
751  .setAnalyticSensitivityAvailable(true)
752  .setSensitivityFunctor(&bjtModelSens);
753 
754  p.addPar ("NKF",0.5,&BJT::Model::rollOffExp)
755  .setGivenMember(&BJT::Model::NKFgiven)
756  .setUnit(U_NONE)
757  .setCategory(CAT_UNKNOWN)
758  .setDescription("High current rolloff coefficient")
759  .setAnalyticSensitivityAvailable(true)
760  .setSensitivityFunctor(&bjtModelSens);
761 
762  // Set up non-double precision variables:
763 
764  // Thermal model setup:
766 }
767 
768 std::vector< std::vector<int> > Instance::jacStamp_RB_RC_RE_;
769 std::vector< std::vector<int> > Instance::jacStamp_RB_RC_;
770 std::vector< std::vector<int> > Instance::jacStamp_RB_RE_;
771 std::vector< std::vector<int> > Instance::jacStamp_RC_RE_;
772 std::vector< std::vector<int> > Instance::jacStamp_RB_;
773 std::vector< std::vector<int> > Instance::jacStamp_RC_;
774 std::vector< std::vector<int> > Instance::jacStamp_RE_;
775 std::vector< std::vector<int> > Instance::jacStamp_;
776 
777 std::vector<int> Instance::jacMap_RB_RC_RE_;
778 std::vector<int> Instance::jacMap_RB_RC_;
779 std::vector<int> Instance::jacMap_RB_RE_;
780 std::vector<int> Instance::jacMap_RC_RE_;
781 std::vector<int> Instance::jacMap_RB_;
782 std::vector<int> Instance::jacMap_RC_;
783 std::vector<int> Instance::jacMap_RE_;
784 std::vector<int> Instance::jacMap_;
785 
786 std::vector< std::vector<int> > Instance::jacMap2_RB_RC_RE_;
787 std::vector< std::vector<int> > Instance::jacMap2_RB_RC_;
788 std::vector< std::vector<int> > Instance::jacMap2_RB_RE_;
789 std::vector< std::vector<int> > Instance::jacMap2_RC_RE_;
790 std::vector< std::vector<int> > Instance::jacMap2_RB_;
791 std::vector< std::vector<int> > Instance::jacMap2_RC_;
792 std::vector< std::vector<int> > Instance::jacMap2_RE_;
793 std::vector< std::vector<int> > Instance::jacMap2_;
794 
795 //-----------------------------------------------------------------------------
796 // Function : Instance::processParams
797 // Purpose :
798 // Special Notes :
799 // Scope : public
800 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
801 // Creation Date : 6/03/02
802 //-----------------------------------------------------------------------------
804 {
805  // Set any non-constant parameter defaults:
806  if (!given("TEMP"))
807  TEMP = getDeviceOptions().temp.getImmutableValue<double>();
808 
810  return true;
811 }
812 
813 //----------------------------------------------------------------------------
814 // Function : Instance::Instance
815 // Purpose : instance block constructor
816 // Special Notes :
817 // Scope : public
818 // Creator : Robert Hoekstra
819 // Creation Date : 11/30/00
820 //----------------------------------------------------------------------------
821 
823  const Configuration & configuration,
824  const InstanceBlock & IB,
825  Model & model,
826  const FactoryBlock & factory_block)
827  : DeviceInstance(IB, configuration.getInstanceParameters(), factory_block),
828  model_(model),
829  AREA(1.0),
830  icVBE(0.0),
831  icVCE(0.0),
832  TEMP(300.0),
833  OFF(false),
834  lambertWFlag(false),
835  IC_GIVEN(false),
836  externalNodeMode(false),
837  offFlag(false),
838  vt (0.0),
839  tSatCur (0.0),
840  tBetaF (0.0),
841  tBetaR (0.0),
842  tBELeakCur (0.0),
843  tBCLeakCur (0.0),
844  tBECap (0.0),
845  tBCCap (0.0),
846  tBEPot (0.0),
847  tBCPot (0.0),
848  tDepCap (0.0),
849  tF1 (0.0),
850  tF4 (0.0),
851  tF5 (0.0),
852  tVCrit (0.0),
853  tleakBEEmissionCoeff(1.5),
854  tleakBCEmissionCoeff(2.0),
855  tRollOffExp (0.5),
856  tInvRollOffF(0.0),
857  tInvRollOffR(0.0),
858  tInvEarlyVoltF(0.0),
859  tInvEarlyVoltR(0.0),
860  vEEp (0.0),
861  vBBp (0.0),
862  vCCp (0.0),
863  vBE (0.0),
864  vBC (0.0),
865  vBX (0.0),
866  vCS (0.0),
867  vBE_old (0.0),
868  vBC_old (0.0),
869  vBE_orig (0.0),
870  vBC_orig (0.0),
871  qB (0.0),
872  invqB (0.0),
873  dqBdvEp (0.0),
874  dqBdvBp (0.0),
875  dqBdvCp (0.0),
876  iBE (0.0),
877  iBC (0.0),
878  iBEleak (0.0),
879  iBCleak (0.0),
880  iCE (0.0),
881  iB (0.0),
882  iC (0.0),
883  iE (0.0),
884  iBEhighCurr (0.0),
885  gBEhighCurr (0.0),
886  gBE (0.0),
887  gBC (0.0),
888  gBEleak (0.0),
889  gBCleak (0.0),
890  gEpr (0.0),
891  gCpr (0.0),
892  gX (0.0),
893  geqCB (0.0),
894  capeqCB (0.0),
895  diBrdvB (0.0),
896  diBrdvEp (0.0),
897  diBrdvCp (0.0),
898  diBrdvBp (0.0),
899  diCEdvEp (0.0),
900  diCEdvCp (0.0),
901  diCEdvBp (0.0),
902 
903  diBEdvEp (0.0),
904  diBEdvCp (0.0),
905  diBEdvBp (0.0),
906 
907  gBEtot (0.0),
908  gBCtot (0.0),
909  qBEdiff (0.0),
910  iBEdiff (0.0),
911  capBEdiff (0.0),
912  qBEdep (0.0),
913  iBEdep (0.0),
914  capBEdep (0.0),
915  qCS (0.0),
916  iCS (0.0),
917  capCS (0.0),
918  qBCdiff (0.0),
919  iBCdiff (0.0),
920  capBCdiff (0.0),
921  qBCdep (0.0),
922  iBCdep (0.0),
923  capBCdep (0.0),
924  qBX (0.0),
925  iBX (0.0),
926  capBX (0.0),
927 
928 
929  li_Coll(-1),
930  li_CollP(-1),
931  li_Base(-1),
932  li_BaseP(-1),
933  li_Emit(-1),
934  li_EmitP(-1),
935  li_Subst(-1),
936  li_Ifx(-1),
937  li_dIfx(-1),
938  li_qstateBEdiff(-1),
939  li_qstateBEdep(-1),
940  li_qstateCS(-1),
941  li_qstateBCdiff(-1),
942  li_qstateBCdep(-1),
943  li_qstateBX(-1),
944  li_istateCEXBC(-1),
945 
946  li_storevBE(-1),
947  li_storevBC(-1),
948  li_store_capeqCB(-1),
949  li_store_dev_ib(-1),
950  li_store_dev_ie(-1),
951  li_store_dev_ic(-1),
952  li_store_dev_is(-1),
953 
954  li_branch_dev_ib(-1),
955  li_branch_dev_ie(-1),
956  li_branch_dev_ic(-1),
957  li_branch_dev_is(-1),
958 
959  gcpr (0.0),
960  gepr (0.0),
961  gx (0.0),
962  gm (0.0),
963  go (0.0),
964  gmu (0.0),
965  gpi (0.0),
966  gccs (0.0),
967  geqbx (0.0),
968  geqbc (0.0),
969  nextCexbc(0.0),
970  currCexbc(0.0),
971  lastCexbc(0.0),
972  phaseScalar(0.0),
973  dt0 (0.0),
974  dt1 (0.0),
975  AEmitEquEmitPNodeOffset(-1),
976  AEmitPEquEmitNodeOffset(-1),
977  ABaseEquBasePNodeOffset(-1),
978  ABasePEquBaseNodeOffset(-1),
979  ACollEquCollPNodeOffset(-1),
980  ACollPEquCollNodeOffset(-1),
981  AEmitEquEmitNodeOffset(-1),
982  AEmitPEquEmitPNodeOffset(-1),
983  ABaseEquBaseNodeOffset(-1),
984  ABasePEquBasePNodeOffset(-1),
985  ACollEquCollNodeOffset(-1),
986  ACollPEquCollPNodeOffset(-1),
987  AEmitPEquBasePNodeOffset(-1),
988  ABasePEquEmitPNodeOffset(-1),
989  AEmitPEquCollPNodeOffset(-1),
990  ACollPEquEmitPNodeOffset(-1),
991  ABasePEquCollPNodeOffset(-1),
992  ACollPEquBasePNodeOffset(-1),
993  ABaseEquCollPNodeOffset(-1),
994  ACollPEquBaseNodeOffset(-1),
995  ASubstEquSubstNodeOffset(-1),
996  ASubstEquCollPNodeOffset(-1),
997  ACollPEquSubstNodeOffset(-1),
998  ABaseEquEmitPNodeOffset(-1) ,
999  ACollPEquIfxNodeOffset(-1),
1000  AEmitPEquIfxNodeOffset(-1),
1001  AIfxEquCollPNodeOffset(-1),
1002  AIfxEquBasePNodeOffset(-1),
1003  AIfxEquEmitPNodeOffset(-1),
1004  AIfxEquIfxNodeOffset(-1),
1005  AIfxEqudIfxNodeOffset(-1),
1006  AdIfxEquCollPNodeOffset(-1),
1007  AdIfxEquBasePNodeOffset(-1),
1008  AdIfxEquEmitPNodeOffset(-1),
1009  AdIfxEquIfxNodeOffset(-1),
1010  AdIfxEqudIfxNodeOffset(-1),
1011 
1013  // f-matrix pointers:
1014  f_EmitEquEmitPNodePtr(0),
1015  f_EmitPEquEmitNodePtr(0),
1016  f_BaseEquBasePNodePtr(0),
1017  f_BasePEquBaseNodePtr(0),
1018  f_CollEquCollPNodePtr(0),
1019  f_CollPEquCollNodePtr(0),
1020  f_EmitEquEmitNodePtr(0),
1021  f_EmitPEquEmitPNodePtr(0),
1022  f_BaseEquBaseNodePtr(0),
1023  f_BasePEquBasePNodePtr(0),
1024  f_CollEquCollNodePtr(0),
1025  f_CollPEquCollPNodePtr(0),
1026  f_EmitPEquBasePNodePtr(0),
1027  f_BasePEquEmitPNodePtr(0),
1028  f_EmitPEquCollPNodePtr(0),
1029  f_CollPEquEmitPNodePtr(0),
1030  f_BasePEquCollPNodePtr(0),
1031  f_CollPEquBasePNodePtr(0),
1032  f_BaseEquCollPNodePtr(0),
1033  f_CollPEquBaseNodePtr(0),
1034  f_SubstEquSubstNodePtr(0),
1035  f_SubstEquCollPNodePtr(0),
1036  f_CollPEquSubstNodePtr(0),
1037  f_BaseEquEmitPNodePtr(0),
1038 
1039  //new offsets for full integration of excess phase term
1040  f_CollPEquIfxNodePtr(0),
1041  f_EmitPEquIfxNodePtr(0),
1042 
1043  // ERK. These 3 are only needed for dcop.
1044  f_IfxEquCollPNodePtr(0),
1045  f_IfxEquBasePNodePtr(0),
1046  f_IfxEquEmitPNodePtr(0),
1047 
1048  f_IfxEquIfxNodePtr(0),
1049  f_IfxEqudIfxNodePtr(0),
1050 
1051  f_dIfxEquCollPNodePtr(0),
1052  f_dIfxEquBasePNodePtr(0),
1053  f_dIfxEquEmitPNodePtr(0),
1054  f_dIfxEquIfxNodePtr(0),
1055  f_dIfxEqudIfxNodePtr(0),
1056 
1057 
1058  // q-matrix pointers:
1059  q_EmitEquEmitPNodePtr(0),
1060  q_EmitPEquEmitNodePtr(0),
1061  q_BaseEquBasePNodePtr(0),
1062  q_BasePEquBaseNodePtr(0),
1063  q_CollEquCollPNodePtr(0),
1064  q_CollPEquCollNodePtr(0),
1065  q_EmitEquEmitNodePtr(0),
1066  q_EmitPEquEmitPNodePtr(0),
1067  q_BaseEquBaseNodePtr(0),
1068  q_BasePEquBasePNodePtr(0),
1069  q_CollEquCollNodePtr(0),
1070  q_CollPEquCollPNodePtr(0),
1071  q_EmitPEquBasePNodePtr(0),
1072  q_BasePEquEmitPNodePtr(0),
1073  q_EmitPEquCollPNodePtr(0),
1074  q_CollPEquEmitPNodePtr(0),
1075  q_BasePEquCollPNodePtr(0),
1076  q_CollPEquBasePNodePtr(0),
1077  q_BaseEquCollPNodePtr(0),
1078  q_CollPEquBaseNodePtr(0),
1079  q_SubstEquSubstNodePtr(0),
1080  q_SubstEquCollPNodePtr(0),
1081  q_CollPEquSubstNodePtr(0),
1082  q_BaseEquEmitPNodePtr(0),
1083 
1084  //new offsets for full integration of excess phase term
1085  q_CollPEquIfxNodePtr(0),
1086  q_EmitPEquIfxNodePtr(0),
1087 
1088  // ERK. These 3 are only needed for dcop.
1089  q_IfxEquCollPNodePtr(0),
1090  q_IfxEquBasePNodePtr(0),
1091  q_IfxEquEmitPNodePtr(0),
1092 
1093  q_IfxEquIfxNodePtr(0),
1094  q_IfxEqudIfxNodePtr(0),
1095 
1096  q_dIfxEquCollPNodePtr(0),
1097  q_dIfxEquBasePNodePtr(0),
1098  q_dIfxEquEmitPNodePtr(0),
1099  q_dIfxEquIfxNodePtr(0),
1100  q_dIfxEqudIfxNodePtr(0),
1101 #endif
1102 
1103  callsOutputPlot (0)
1104 
1105 {
1106  // This basically says, numExtVars = the number of vars specified
1107  // by the user on the netlist instance line.
1108  numExtVars = IB.numExtVars;
1109 
1110  numStateVars = 7;
1111  setNumStoreVars(3);
1112  numLeadCurrentStoreVars = 4; // lead current dev_ib, dev_ie, dev_ic and dev_is
1113 
1114  setNumBranchDataVars(0); // by default don't allocate space in branch vectors
1115  numBranchDataVarsIfAllocated = 4; // this is the space to allocate if lead current or power is needed.
1116 
1117  devConMap.resize(4);
1118  devConMap[0] = 1;
1119  devConMap[1] = 1;
1120  devConMap[2] = 1;
1121  devConMap[3] = 2;
1122 
1123  if (numExtVars > 4)
1124  {
1125  devConMap.resize(numExtVars);
1126  }
1127  for (int i1=4;i1<numExtVars;++i1)
1128  {
1129  devConMap[i1] = 1; // map all the extra ones to the base.
1130  // That way I don't have to figure out
1131  // which optional nodes have been set
1132  // by the user.
1133  }
1134 
1135  // set up the jacStamp:
1136  if( jacStamp_.empty() )
1137  {
1138  jacStamp_RB_RC_RE_.resize(7);
1139  jacStamp_RB_RC_RE_[0].resize(2); // Collector Row
1140  jacStamp_RB_RC_RE_[0][0] = 0; // C-C
1141  jacStamp_RB_RC_RE_[0][1] = 4; // C-C'
1142 
1143  jacStamp_RB_RC_RE_[1].resize(4); // Base row
1144  jacStamp_RB_RC_RE_[1][0] = 1; // B-B
1145  jacStamp_RB_RC_RE_[1][1] = 4; // B-C'
1146  jacStamp_RB_RC_RE_[1][2] = 5; // B-B'
1147  jacStamp_RB_RC_RE_[1][3] = 6; // B-E'
1148 
1149  jacStamp_RB_RC_RE_[2].resize(2); // Emitter row
1150  jacStamp_RB_RC_RE_[2][0] = 2; // E-E
1151  jacStamp_RB_RC_RE_[2][1] = 6; // E-E'
1152 
1153  jacStamp_RB_RC_RE_[3].resize(2); // Substrate row
1154  jacStamp_RB_RC_RE_[3][0] = 3; // S-S
1155  jacStamp_RB_RC_RE_[3][1] = 4; // S-C'
1156 
1157  jacStamp_RB_RC_RE_[4].resize(6); // Collector'
1158  jacStamp_RB_RC_RE_[4][0] = 0; // C'-C
1159  jacStamp_RB_RC_RE_[4][1] = 1; // C'-B
1160  jacStamp_RB_RC_RE_[4][2] = 3; // C'-S
1161  jacStamp_RB_RC_RE_[4][3] = 4; // C'-C'
1162  jacStamp_RB_RC_RE_[4][4] = 5; // C'-B'
1163  jacStamp_RB_RC_RE_[4][5] = 6; // C'-E'
1164 
1165  jacStamp_RB_RC_RE_[5].resize(4); // Base'
1166  jacStamp_RB_RC_RE_[5][0] = 1; // B'-B
1167  jacStamp_RB_RC_RE_[5][1] = 4; // B'-C'
1168  jacStamp_RB_RC_RE_[5][2] = 5; // B'-B'
1169  jacStamp_RB_RC_RE_[5][3] = 6; // B'-E'
1170 
1171  jacStamp_RB_RC_RE_[6].resize(4); // Emitter'
1172  jacStamp_RB_RC_RE_[6][0] = 2; // E'-E
1173  jacStamp_RB_RC_RE_[6][1] = 4; // E'-C'
1174  jacStamp_RB_RC_RE_[6][2] = 5; // E'-B'
1175  jacStamp_RB_RC_RE_[6][3] = 6; // E'-E'
1176 
1177  if (getDeviceOptions().newExcessPhase)
1178  {
1179  //Excess Phase Terms
1180  jacStamp_RB_RC_RE_.resize(9);
1181 
1182  jacStamp_RB_RC_RE_[4].resize(7); // Collector' row
1183  jacStamp_RB_RC_RE_[4][6] = 7; // C'-Ifx
1184 
1185  jacStamp_RB_RC_RE_[6].resize(5); // Emitter' row
1186  jacStamp_RB_RC_RE_[6][4] = 7; // E'-Ifx
1187 
1188  jacStamp_RB_RC_RE_[7].resize(5); // Ifx row
1189  jacStamp_RB_RC_RE_[7][0] = 4; // dIfx-C'
1190  jacStamp_RB_RC_RE_[7][1] = 5; // dIfx-B'
1191  jacStamp_RB_RC_RE_[7][2] = 6; // dIfx-E'
1192  jacStamp_RB_RC_RE_[7][3] = 7; // Ifx-Ifx
1193  jacStamp_RB_RC_RE_[7][4] = 8; // Ifx-dIfx
1194 
1195  jacStamp_RB_RC_RE_[8].resize(5); // dIfx row
1196  jacStamp_RB_RC_RE_[8][0] = 4; // dIfx-C'
1197  jacStamp_RB_RC_RE_[8][1] = 5; // dIfx-B'
1198  jacStamp_RB_RC_RE_[8][2] = 6; // dIfx-E'
1199  jacStamp_RB_RC_RE_[8][3] = 7; // dIfx-Ifx
1200  jacStamp_RB_RC_RE_[8][4] = 8; // dIfx-dIfx
1201  }
1202 
1203  jacMap_RB_RC_RE_.clear();
1204 
1205  int StampSize = 0;
1206  if (getDeviceOptions().newExcessPhase)
1207  {
1208  StampSize = 9;
1209  }
1210  else
1211  {
1212  StampSize = 7;
1213  }
1214 
1216  jacStamp_RB_RE_, jacMap_RB_RE_, jacMap2_RB_RE_, 4, 0, StampSize );
1217 
1219  jacStamp_RC_RE_, jacMap_RC_RE_, jacMap2_RC_RE_, 5, 1, StampSize );
1220 
1222  jacStamp_RB_RC_, jacMap_RB_RC_, jacMap2_RB_RC_, 6, 2, StampSize );
1223 
1225  jacStamp_RB_, jacMap_RB_, jacMap2_RB_, 4, 0, StampSize );
1226 
1228  jacStamp_RE_, jacMap_RE_, jacMap2_RE_, 4, 1, StampSize );
1229 
1231  jacStamp_RC_, jacMap_RC_, jacMap2_RC_, 5, 2, StampSize );
1232 
1234  jacStamp_, jacMap_, jacMap2_, 4, 0, StampSize );
1235  }
1236 
1237  // Set params to constant default values:
1238  setDefaultParams ();
1239 
1240  // Set params according to instance line and constant defaults from metadata:
1241  setParams (IB.params);
1242 
1243  // Calculate any parameters specified as expressions:
1245 
1246  // calculate dependent (ie computed) params and check for errors:
1247  processParams ();
1248 
1249  // This is tricky. The prime nodes have 2 issues:
1250  // 1) do they exist?
1251  // 2) are they internal or external?
1252  //
1253  // The default BJT behavior is for them to be internal,
1254  // if they exist.
1255  //
1256  // Also, node 4 is always "external" even if not specified
1257  // by the user! If the user doesn't specify it, it gets set
1258  // to gnd, as an external node.
1259  //
1260  // Nominal order in the netlist, after the original 4 nodes
1261  // is collector', base', emitter'.
1262  //
1263  // I've chosen to only allow 2 modes: all optional variables
1264  // are internal, or all optional nodes (that exist) are
1265  // external. No mixing and matching. This is toggled by the
1266  // flag, externalNodeMode.
1267 
1268  int cNode=0;
1269  int eNode=0;
1270  int bNode=0;
1271 
1272  cNode = ((model_.collectorResist==0.0)?0:1);
1273  eNode = ((model_.emitterResist==0.0)?0:1);
1274  bNode = ((model_.baseResist==0.0)?0:1);
1275 
1276  int numExist = cNode + eNode + bNode;
1277 
1278  if (numExtVars <= 4)
1279  {
1280  numExtVars = 4;
1281  externalNodeMode = false;
1282  numIntVars = cNode + eNode + bNode;
1283  }
1284  else
1285  {
1286  if (numExtVars != 4 + numExist)
1287  {
1288  UserError(*this) << "Wrong number of external nodes are set!" << std::endl
1289  << "Either set none of them, or set them all.";
1290  }
1291 
1292  externalNodeMode = true;
1293  //numExtVars += cNode + eNode + bNode; // This is already set in netlist.
1294  }
1295 
1296 
1297  if (getDeviceOptions().newExcessPhase)
1298  {
1299  //add in 2 variables for excess phase calc.
1300  numIntVars += 2;
1301  }
1302 
1303 }
1304 
1305 //-----------------------------------------------------------------------------
1306 // Function : Instance::~Instance
1307 // Purpose : destructor
1308 // Special Notes :
1309 // Scope : public
1310 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
1311 // Creation Date : 3/16/00
1312 //-----------------------------------------------------------------------------
1314 {
1315 
1316 }
1317 
1318 //-----------------------------------------------------------------------------
1319 // Function : Instance::registerLIDs
1320 // Purpose :
1321 // Special Notes :
1322 // Scope : public
1323 // Creator : Robert Hoekstra
1324 // Creation Date : 6/13/02
1325 //-----------------------------------------------------------------------------
1326 void Instance::registerLIDs( const std::vector<int> & intLIDVecRef,
1327  const std::vector<int> & extLIDVecRef )
1328 {
1329  AssertLIDs(intLIDVecRef.size() == numIntVars);
1330  AssertLIDs(extLIDVecRef.size() == numExtVars);
1331 
1332  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
1333  {
1334  Xyce::dout() << section_divider << std::endl;
1335  Xyce::dout() << " BJTInstance::registerLIDs" <<std::endl;
1336  Xyce::dout() << " name = " << getName() << std::endl;
1337  Xyce::dout() << " number of internal variables: " << numIntVars << std::endl;
1338  Xyce::dout() << " number of external variables: " << numExtVars << std::endl;
1339  Xyce::dout() << " numIntVars = " << numIntVars << std::endl;
1340  Xyce::dout() << " numExtVars = " << numExtVars << std::endl;
1341  }
1342 
1343  // Copy over the global ID lists.
1344  intLIDVec = intLIDVecRef;
1345  extLIDVec = extLIDVecRef;
1346 
1347  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
1348  {
1349  Xyce::dout() << " Internal LID List" << std::endl;
1350  for( int i = 0; i < intLIDVec.size(); ++i )
1351  Xyce::dout() << " " << intLIDVec[i] << std::endl;
1352  Xyce::dout() << " External LID List" << std::endl;
1353  for( int i = 0; i < extLIDVec.size(); ++i )
1354  Xyce::dout() << " " << extLIDVec[i] << std::endl;
1355  }
1356 
1357  // Now use these lists to obtain the indices into the linear algebra
1358  // entities. This assumes an order. For the matrix indices, first do the
1359  // rows.
1360 
1361  // First do external variables:
1362  // it1 at collector, it2 at collectorPrime
1363  int intIndex = 0;
1364  int extIndex = 0;
1365 
1366  li_Coll = extLIDVec[extIndex++];
1367  li_Base = extLIDVec[extIndex++];
1368  li_Emit = extLIDVec[extIndex++];
1369  li_Subst = extLIDVec[extIndex++];
1370 
1371  if( model_.collectorResist == 0.0 )
1372  {
1373  li_CollP = li_Coll;
1374  }
1375  else
1376  {
1377  if (externalNodeMode)
1378  li_CollP = extLIDVec[extIndex++];
1379  else
1380  li_CollP = intLIDVec[intIndex++];
1381  }
1382 
1383 
1384  if( model_.baseResist == 0.0 )
1385  {
1386  li_BaseP = li_Base;
1387  }
1388  else
1389  {
1390  if (externalNodeMode)
1391  li_BaseP = extLIDVec[extIndex++];
1392  else
1393  li_BaseP = intLIDVec[intIndex++];
1394  }
1395 
1396 
1397  if( model_.emitterResist == 0.0 )
1398  {
1399  li_EmitP = li_Emit;
1400  }
1401  else
1402  {
1403  if (externalNodeMode)
1404  li_EmitP = extLIDVec[extIndex++];
1405  else
1406  li_EmitP = intLIDVec[intIndex++];
1407  }
1408 
1409 
1411  {
1412  li_Ifx = intLIDVec[intIndex++];
1413  li_dIfx = intLIDVec[intIndex++];
1414  }
1415 
1416  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
1417  {
1418  Xyce::dout() << " li_Coll = " << li_Coll << std::endl;
1419  Xyce::dout() << " li_CollP = " << li_CollP << std::endl;
1420  Xyce::dout() << " li_Base = " << li_Base << std::endl;
1421  Xyce::dout() << " li_BaseP = " << li_BaseP << std::endl;
1422  Xyce::dout() << " li_Emit = " << li_Emit << std::endl;
1423  Xyce::dout() << " li_EmitP = " << li_EmitP << std::endl;
1424  Xyce::dout() << " li_Subst = " << li_Subst << std::endl;
1425 
1426  if (getDeviceOptions().newExcessPhase)
1427  {
1428  Xyce::dout() << " li_Ifx = " << li_Ifx << std::endl;
1429  Xyce::dout() << " li_dIfx = " << li_dIfx << std::endl;
1430  }
1431 
1432  Xyce::dout() << section_divider << std::endl;
1433  }
1434 
1435 }
1436 
1437 //-----------------------------------------------------------------------------
1438 // Function : Instance::loadNodeSymbols
1439 // Purpose :
1440 // Special Notes :
1441 // Scope : public
1442 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
1443 // Creation Date : 05/13/05
1444 //-----------------------------------------------------------------------------
1445 void Instance::loadNodeSymbols(Util::SymbolTable &symbol_table) const
1446 {
1447  if (!externalNodeMode)
1448  {
1449  if( model_.collectorResist != 0.0 )
1450  addInternalNode(symbol_table, li_CollP, getName(), "collectorprime");
1451 
1452  if( model_.baseResist != 0.0 )
1453  addInternalNode(symbol_table, li_BaseP, getName(), "baseprime");
1454 
1455  if( model_.emitterResist != 0.0 )
1456  addInternalNode(symbol_table, li_EmitP, getName(), "emitterprime");
1457  }
1458 
1459  if (getDeviceOptions().newExcessPhase)
1460  {
1461  addInternalNode(symbol_table, li_Ifx, getName(), "ExcessPhase_Ifx");
1462  addInternalNode(symbol_table, li_dIfx, getName(), "ExcessPhase_dIfx");
1463  }
1464 
1465  addStoreNode(symbol_table, li_storevBE, getName(), "VBE");
1466  addStoreNode(symbol_table, li_storevBC, getName(), "VBC");
1467  addStoreNode(symbol_table, li_store_capeqCB, getName(), "CAPEQCB");
1468 
1469  if (loadLeadCurrent)
1470  {
1471  /*
1472  addStoreNode(symbol_table, li_store_dev_ib, getName(), "DEV_IB");
1473  addStoreNode(symbol_table, li_store_dev_ie, getName(), "DEV_IE");
1474  addStoreNode(symbol_table, li_store_dev_ic, getName(), "DEV_IC");
1475  addStoreNode(symbol_table, li_store_dev_is, getName(), "DEV_IS");
1476  */
1477 
1478  addBranchDataNode( symbol_table, li_branch_dev_ib, getName(), "BRANCH_DB");
1479  addBranchDataNode( symbol_table, li_branch_dev_ie, getName(), "BRANCH_DE");
1480  addBranchDataNode( symbol_table, li_branch_dev_ic, getName(), "BRANCH_DC");
1481  addBranchDataNode( symbol_table, li_branch_dev_is, getName(), "BRANCH_DS");
1482  }
1483 }
1484 
1485 //-----------------------------------------------------------------------------
1486 // Function : Instance::registerStateLIDs
1487 // Purpose :
1488 // Special Notes :
1489 // Scope : public
1490 // Creator : Robert Hoekstra
1491 // Creation Date : 6/13/02
1492 //-----------------------------------------------------------------------------
1493 void Instance::registerStateLIDs( const std::vector<int> & staLIDVecRef )
1494 {
1495  AssertLIDs(staLIDVecRef.size() == numStateVars);
1496 
1497  // Copy over the global ID lists:
1498  staLIDVec = staLIDVecRef;
1499 
1500  int i=0;
1501  li_qstateBEdiff = staLIDVec[i++];
1502  li_qstateBEdep = staLIDVec[i++];
1503  li_qstateCS = staLIDVec[i++];
1504  li_qstateBCdiff = staLIDVec[i++];
1505  li_qstateBCdep = staLIDVec[i++];
1506  li_qstateBX = staLIDVec[i++];
1507  li_istateCEXBC = staLIDVec[i++];
1508 }
1509 
1510 
1511 //-----------------------------------------------------------------------------
1512 // Function : Instance::registerStoreLIDs
1513 // Purpose :
1514 // Special Notes :
1515 // Scope : public
1516 // Creator : Eric Keiter, SNL
1517 // Creation Date : 12/09/11
1518 //-----------------------------------------------------------------------------
1519 void Instance::registerStoreLIDs( const std::vector<int> & stoLIDVecRef )
1520 {
1521  AssertLIDs(stoLIDVecRef.size() == getNumStoreVars());
1522 
1523  // Copy over the global ID lists:
1524  stoLIDVec = stoLIDVecRef;
1525 
1526  int i=0;
1527  li_storevBE = stoLIDVec[i++];
1528  li_storevBC = stoLIDVec[i++];
1529  li_store_capeqCB = stoLIDVec[i++];
1530  if( loadLeadCurrent )
1531  {
1532  li_store_dev_ib = stoLIDVec[i++];
1533  li_store_dev_ie = stoLIDVec[i++];
1534  li_store_dev_ic = stoLIDVec[i++];
1535  li_store_dev_is = stoLIDVec[i++];
1536  }
1537 
1538 }
1539 
1540 
1541 //-----------------------------------------------------------------------------
1542 // Function : Instance::registerBranchDataLIDs
1543 // Purpose :
1544 // Special Notes :
1545 // Scope : public
1546 // Creator : Eric Keiter, SNL
1547 // Creation Date : 12/09/11
1548 //-----------------------------------------------------------------------------
1549 void Instance::registerBranchDataLIDs(const std::vector<int> & branchLIDVecRef)
1550 {
1551  AssertLIDs(branchLIDVecRef.size() == getNumBranchDataVars());
1552 
1553  if (loadLeadCurrent)
1554  {
1555  li_branch_dev_ib = branchLIDVecRef[0];
1556  li_branch_dev_ie = branchLIDVecRef[1];
1557  li_branch_dev_ic = branchLIDVecRef[2];
1558  li_branch_dev_is = branchLIDVecRef[3];
1559  }
1560 }
1561 
1562 //-----------------------------------------------------------------------------
1563 // Function : Instance::jacobianStamp
1564 // Purpose :
1565 // Special Notes :
1566 // Scope : public
1567 // Creator : Robert Hoekstra
1568 // Creation Date : 8/21/02
1569 //-----------------------------------------------------------------------------
1570 const std::vector< std::vector<int> > & Instance::jacobianStamp() const
1571 {
1572  if (model_.baseResist)
1573  {
1574  if (model_.collectorResist)
1575  {
1576  if (model_.emitterResist)
1577  return jacStamp_RB_RC_RE_;
1578  else
1579  return jacStamp_RB_RC_;
1580  }
1581  else
1582  {
1583  if (model_.emitterResist)
1584  return jacStamp_RB_RE_;
1585  else
1586  return jacStamp_RB_;
1587  }
1588  }
1589  else
1590  {
1591  if (model_.collectorResist)
1592  {
1593  if (model_.emitterResist)
1594  return jacStamp_RC_RE_;
1595  else
1596  return jacStamp_RC_;
1597  }
1598  else
1599  {
1600  if (model_.emitterResist)
1601  return jacStamp_RE_;
1602  else
1603  return jacStamp_;
1604  }
1605  }
1606 }
1607 
1608 //-----------------------------------------------------------------------------
1609 // Function : Instance::registerJacLIDs
1610 // Purpose :
1611 // Special Notes :
1612 // Scope : public
1613 // Creator : Robert Hoekstra
1614 // Creation Date : 8/27/02
1615 //-----------------------------------------------------------------------------
1616 void Instance::registerJacLIDs( const std::vector< std::vector<int> > & jacLIDVec )
1617 {
1618  DeviceInstance::registerJacLIDs( jacLIDVec );
1619 
1620  std::vector<int> map;
1621  std::vector< std::vector<int> > map2;
1622 
1623  if (model_.baseResist)
1624  {
1625  if (model_.collectorResist)
1626  {
1627  if (model_.emitterResist)
1628  {
1629  map = jacMap_RB_RC_RE_;
1630  map2 = jacMap2_RB_RC_RE_;
1631  }
1632  else
1633  {
1634  map = jacMap_RB_RC_;
1635  map2 = jacMap2_RB_RC_;
1636  }
1637  }
1638  else
1639  {
1640  if (model_.emitterResist)
1641  {
1642  map = jacMap_RB_RE_;
1643  map2 = jacMap2_RB_RE_;
1644  }
1645  else
1646  {
1647  map = jacMap_RB_;
1648  map2 = jacMap2_RB_;
1649  }
1650  }
1651  }
1652  else
1653  {
1654  if (model_.collectorResist)
1655  {
1656  if (model_.emitterResist)
1657  {
1658  map = jacMap_RC_RE_;
1659  map2 = jacMap2_RC_RE_;
1660  }
1661  else
1662  {
1663  map = jacMap_RC_;
1664  map2 = jacMap2_RC_;
1665  }
1666  }
1667  else
1668  {
1669  if (model_.emitterResist)
1670  {
1671  map = jacMap_RE_;
1672  map2 = jacMap2_RE_;
1673  }
1674  else
1675  {
1676  map = jacMap_;
1677  map2 = jacMap2_;
1678  }
1679  }
1680  }
1681 
1682  ACollEquCollNodeOffset = jacLIDVec[map[0]][map2[0][0]];
1683  ACollEquCollPNodeOffset = jacLIDVec[map[0]][map2[0][1]];
1684 
1685  ABaseEquBaseNodeOffset = jacLIDVec[map[1]][map2[1][0]];
1686  ABaseEquCollPNodeOffset = jacLIDVec[map[1]][map2[1][1]];
1687  ABaseEquBasePNodeOffset = jacLIDVec[map[1]][map2[1][2]];
1688  ABaseEquEmitPNodeOffset = jacLIDVec[map[1]][map2[1][3]];
1689 
1690  AEmitEquEmitNodeOffset = jacLIDVec[map[2]][map2[2][0]];
1691  AEmitEquEmitPNodeOffset = jacLIDVec[map[2]][map2[2][1]];
1692 
1693  ASubstEquSubstNodeOffset = jacLIDVec[map[3]][map2[3][0]];
1694  ASubstEquCollPNodeOffset = jacLIDVec[map[3]][map2[3][1]];
1695 
1696  ACollPEquCollNodeOffset = jacLIDVec[map[4]][map2[4][0]];
1697  ACollPEquBaseNodeOffset = jacLIDVec[map[4]][map2[4][1]];
1698  ACollPEquSubstNodeOffset = jacLIDVec[map[4]][map2[4][2]];
1699  ACollPEquCollPNodeOffset = jacLIDVec[map[4]][map2[4][3]];
1700  ACollPEquBasePNodeOffset = jacLIDVec[map[4]][map2[4][4]];
1701  ACollPEquEmitPNodeOffset = jacLIDVec[map[4]][map2[4][5]];
1702 
1703  ABasePEquBaseNodeOffset = jacLIDVec[map[5]][map2[5][0]];
1704  ABasePEquCollPNodeOffset = jacLIDVec[map[5]][map2[5][1]];
1705  ABasePEquBasePNodeOffset = jacLIDVec[map[5]][map2[5][2]];
1706  ABasePEquEmitPNodeOffset = jacLIDVec[map[5]][map2[5][3]];
1707 
1708  AEmitPEquEmitNodeOffset = jacLIDVec[map[6]][map2[6][0]];
1709  AEmitPEquCollPNodeOffset = jacLIDVec[map[6]][map2[6][1]];
1710  AEmitPEquBasePNodeOffset = jacLIDVec[map[6]][map2[6][2]];
1711  AEmitPEquEmitPNodeOffset = jacLIDVec[map[6]][map2[6][3]];
1712 
1713  if (getDeviceOptions().newExcessPhase)
1714  {
1715  //Excess Phase Terms
1716  ACollPEquIfxNodeOffset = jacLIDVec[map[4]][map2[4][6]];
1717 
1718  AEmitPEquIfxNodeOffset = jacLIDVec[map[6]][map2[6][4]];
1719 
1720  AIfxEquCollPNodeOffset = jacLIDVec[map[7]][map2[7][0]];
1721  AIfxEquBasePNodeOffset = jacLIDVec[map[7]][map2[7][1]];
1722  AIfxEquEmitPNodeOffset = jacLIDVec[map[7]][map2[7][2]];
1723  AIfxEquIfxNodeOffset = jacLIDVec[map[7]][map2[7][3]];
1724  AIfxEqudIfxNodeOffset = jacLIDVec[map[7]][map2[7][4]];
1725 
1726  AdIfxEquCollPNodeOffset = jacLIDVec[map[8]][map2[8][0]];
1727  AdIfxEquBasePNodeOffset = jacLIDVec[map[8]][map2[8][1]];
1728  AdIfxEquEmitPNodeOffset = jacLIDVec[map[8]][map2[8][2]];
1729  AdIfxEquIfxNodeOffset = jacLIDVec[map[8]][map2[8][3]];
1730  AdIfxEqudIfxNodeOffset = jacLIDVec[map[8]][map2[8][4]];
1731  }
1732 
1733 }
1734 
1735 //-----------------------------------------------------------------------------
1736 // Function : Instance::setupPointers
1737 // Purpose :
1738 // Special Notes :
1739 // Scope : public
1740 // Creator : Eric Keiter, SNL
1741 // Creation Date : 12/01/08
1742 //-----------------------------------------------------------------------------
1744 {
1745 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
1746  Linear::Matrix & dFdx = *(extData.dFdxMatrixPtr);
1747  Linear::Matrix & dQdx = *(extData.dQdxMatrixPtr);
1748 
1749  // F-matrix
1752 
1757 
1760 
1763 
1770 
1775 
1780 
1781 
1782  // Q-matrix:
1785 
1790 
1793 
1796 
1803 
1808 
1813 
1815  {
1816  //F-matrix excess phase Terms
1818 
1820 
1826 
1832 
1833 
1834  // Q-matrix excess phase terms
1836 
1838 
1844 
1850  }
1851 
1852 #endif
1853 }
1854 
1855 //-----------------------------------------------------------------------------
1856 // Function : Instance::updateTemperature
1857 // Purpose :
1858 // Special Notes :
1859 // Scope : public
1860 // Creator : Robert Hoekstra
1861 // Creation Date : 11/30/00
1862 //-----------------------------------------------------------------------------
1863 bool Instance::updateTemperature( const double & temp )
1864 {
1865 
1866  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) && getSolverState().debugTimeFlag)
1867  {
1868  Xyce::dout() << "Start BJTInst::updateTemperature" << std::endl;
1869  Xyce::dout() << "temp = "<<temp << std::endl;
1870  }
1871  if( temp != -999.0 ) TEMP = temp;
1873  {
1874  // make sure interpolation doesn't take any resistance negative
1875  if(model_.baseResist < 0) model_.baseResist = 0;
1878 
1879  // some params may have changed during interpolation
1881  }
1882 
1883  //Generation of temperature based factors
1884  vt = TEMP * CONSTKoverQ;
1885  double TNOM = model_.TNOM;
1886  double fact2 = TEMP / CONSTREFTEMP;
1887  double egfet = CONSTEg0 - ( CONSTalphaEg * TEMP * TEMP ) /
1888  ( TEMP + CONSTbetaEg );
1889  double arg = -egfet / ( 2.0 * CONSTboltz * TEMP ) +
1890  CONSTEg300 / ( CONSTboltz * ( 2.0 * CONSTREFTEMP ) );
1891  double pbfact = -2.0 * vt * ( 1.5 * log( fact2 ) + CONSTQ * arg );
1892  double ratlog = log( TEMP / model_.TNOM );
1893  double ratio1 = TEMP / model_.TNOM - 1.0;
1894  double factlog = ratio1 * model_.energyGap / vt
1895  + model_.tempExpIS * ratlog;
1896  double factor = exp( factlog );
1897  double bfactor = exp( ratlog * model_.betaExp );
1898 
1899  // Temp. adj. saturation current
1900  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) && getSolverState().debugTimeFlag)
1901  {
1902  Xyce::dout() << " Factor is " << factor << std::endl;
1903  Xyce::dout() << " Bfactor is " << bfactor << std::endl;
1904  Xyce::dout() << " factlog is " << factlog << std::endl;
1905  Xyce::dout() << " ratio1 is " << ratio1 << std::endl;
1906  Xyce::dout() << " TEMP is " << TEMP << std::endl;
1907  Xyce::dout() << " TNOM is " << model_.TNOM << std::endl;
1908  Xyce::dout() << " Energy gap is " << model_.energyGap << std::endl;
1909  Xyce::dout() << " tempExpIS is " << model_.tempExpIS << std::endl;
1910  }
1911 
1912  // Temp. adj. zero-bias junction capacitances and built-in potentials
1913  double fact1 = model_.TNOM / CONSTREFTEMP;
1914  double pbo = ( model_.potBE - pbfact ) / fact1;
1915  double gmaold = ( model_.potBE - pbo ) / pbo;
1916 
1917  tBECap = model_.depCapBE / ( 1.0 + model_.juncExpBE *
1918  ( 4.e-4 * ( model_.TNOM - CONSTREFTEMP ) - gmaold ) );
1919  tBEPot = fact2 * pbo + pbfact;
1920 
1921  double gmanew = ( tBEPot - pbo ) / pbo;
1922 
1923  tBECap *= 1.0 + model_.juncExpBE *
1924  ( 4.e-4 * ( TEMP - CONSTREFTEMP ) - gmanew );
1925 
1926  pbo = ( model_.potBC - pbfact ) / fact1;
1927  gmaold = ( model_.potBC - pbo ) / pbo;
1928 
1929  tBCCap = model_.depCapBC / ( 1.0 + model_.juncExpBC *
1930  ( 4.e-4 * ( model_.TNOM - CONSTREFTEMP ) - gmaold ) );
1931  tBCPot = fact2 * pbo + pbfact;
1932 
1933  gmanew = ( tBCPot - pbo ) / pbo;
1934 
1935  tBCCap *= 1.0 + model_.juncExpBC *
1936  ( 4.e-4 * ( TEMP - CONSTREFTEMP ) - gmanew );
1937 
1938  // Temp. adj. depletion capacitance
1940 
1941  // Temp. adj. polynomial factors
1942  double xfc = log( 1.0 - model_.depCapCoeff );
1943  tF1 = tBEPot * ( 1.0 - exp( ( 1.0 - model_.juncExpBE ) * xfc ) ) /
1944  ( 1.0 - model_.juncExpBE );
1945 
1947  tF5 = tBCPot * ( 1.0 - exp( ( 1.0 - model_.juncExpBC ) * xfc ) ) /
1948  ( 1.0 - model_.juncExpBC );
1949 
1950  // Temp. adj. critical voltage
1951  // tVCrit = vt * log( vt / ( 1.41414 * model_.satCur ) );
1952  tVCrit = vt * log( vt / ( CONSTroot2 * model_.satCur ) );
1953 
1954  tSatCur = model_.satCur * factor;
1955  // Temp. adj. beta's
1956  tBetaF = model_.betaF * bfactor;
1957  tBetaR = model_.betaR * bfactor;
1958  // Temp. adj. leakage currents
1963  tBELeakCur = model_.leakBECurrent * exp( factlog / model_.leakBEEmissionCoeff ) / bfactor;
1964  tBCLeakCur = model_.leakBCCurrent * exp( factlog / model_.leakBCEmissionCoeff ) / bfactor;
1965 
1972 
1973  if (model_.rollOffF != 0)
1975  else
1976  tInvRollOffF = 0;
1977  if (model_.rollOffR != 0)
1979  else
1980  tInvRollOffR = 0;
1981  if (model_.earlyVoltF != 0)
1983  else
1984  tInvEarlyVoltF = 0;
1985  if (model_.earlyVoltR != 0)
1987  else
1988  tInvEarlyVoltR = 0;
1989 
1990  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) && getSolverState().debugTimeFlag)
1991  {
1992 
1993  Xyce::dout() << section_divider << std::endl;
1994  Xyce::dout() << "In BJTInst::updateTemperature" << std::endl;
1995  Xyce::dout() << section_divider << std::endl;
1996  Xyce::dout() << "TEMP = " << TEMP << std::endl;
1997  Xyce::dout() << "TNOM = " << TNOM << std::endl;
1998  Xyce::dout() << "vt = " << vt << std::endl;
1999  Xyce::dout() << "tSatCur = " << tSatCur << std::endl;
2000  Xyce::dout() << "tBetaF = " << tBetaF << std::endl;
2001  Xyce::dout() << "tBetaR = " << tBetaR << std::endl;
2002  Xyce::dout() << "tBELeakCur = " << tBELeakCur << std::endl;
2003  Xyce::dout() << "tBCLeakCur = " << tBELeakCur << std::endl;
2004  Xyce::dout() << "tBEPot = " << tBEPot << std::endl;
2005  Xyce::dout() << "tBECap = " << tBECap << std::endl;
2006  Xyce::dout() << "tBCPot = " << tBCPot << std::endl;
2007  Xyce::dout() << "tBCCap = " << tBCCap << std::endl;
2008  Xyce::dout() << "tDepCap = " << tDepCap << std::endl;
2009  Xyce::dout() << "tF1 = " << tF1 << std::endl;
2010  Xyce::dout() << "tF4 = " << tF4 << std::endl;
2011  Xyce::dout() << "tF5 = " << tF5 << std::endl;
2012  Xyce::dout() << "tleakBEEmissionCoeff = " << tleakBEEmissionCoeff << std::endl;
2013  Xyce::dout() << "tleakBCEmissionCoeff = " << tleakBCEmissionCoeff << std::endl;
2014  Xyce::dout() << "tRollOffExp = " << tRollOffExp << std::endl;
2015  Xyce::dout() << "tInvRollOffF = " << tInvRollOffF << std::endl;
2016  Xyce::dout() << "tInvRollOffR = " << tInvRollOffR << std::endl;
2017  Xyce::dout() << "tInvEarlyVoltF = " << tInvEarlyVoltF << std::endl;
2018  Xyce::dout() << "tInvEarlyVoltR = " << tInvEarlyVoltR << std::endl;
2019  Xyce::dout() << "tBaseResist = " << tBaseResist << std::endl;
2020  Xyce::dout() << "tCollectorResist = " << tCollectorResist << std::endl;
2021  Xyce::dout() << "tEmitterResist = " << tEmitterResist << std::endl;
2022  Xyce::dout() << section_divider << std::endl;
2023  Xyce::dout() << std::endl;
2024  }
2025 
2026  return true;
2027 }
2028 
2029 
2030 //----------------------------------------------------------------------------
2031 // Function : Instance::lambertWCurrent
2032 // Purpose : Determine the current through an individual BJT
2033 // Special Notes :
2034 // Scope : public
2035 // Creator : Nick Johnson, Summer Intern
2036 // Creation Date : 7/30/02
2037 //---------------------------------------------------------------------------
2038 bool Instance::lambertWCurrent(double &Id, double &Gd, double Vd, double Vte, double Isat)
2039 {
2040  double RS = 1.0e-12;
2041  double arg1 = (Vd + Isat*RS)/Vte;
2042  arg1 = std::min(CONSTMAX_EXP_ARG, arg1);
2043  double evd = exp(arg1);
2044  double lambWArg = Isat*RS*evd/Vte;
2045  double lambWReturn;
2046  int ierr;
2047  double lambWError;
2048  devSupport.lambertw(lambWArg, lambWReturn, ierr, lambWError);
2049 
2050  Id = -Isat+Vte*(lambWReturn)/RS;
2051  Gd = lambWReturn / ((1 + lambWReturn)*RS);
2052 
2053  return true;
2054 }
2055 
2056 //-----------------------------------------------------------------------------
2057 // Function : Instance::loadErrorWeightMask
2058 //
2059 // Purpose : Loads the zero elements of the device mask
2060 //
2061 // Special Notes : elements of the error vector associated with zero
2062 // elements of the mask will not be included in weighted
2063 // norms by the time integrator.
2064 //
2065 // Scope : public
2066 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
2067 // Creation Date : 01/19/07
2068 //-----------------------------------------------------------------------------
2070 {
2071  if (getDeviceOptions().newExcessPhase)
2072  {
2073  Linear::Vector * maskVectorPtr = extData.deviceErrorWeightMask_;
2074 
2075  (*maskVectorPtr)[li_Ifx] = 0.0;
2076  (*maskVectorPtr)[li_dIfx] = 0.0;
2077  }
2078 }
2079 
2080 //-----------------------------------------------------------------------------
2081 // Function : Instance::loadDAEQVector
2082 //
2083 // Purpose : Loads the Q-vector contributions for a single
2084 // BJT instance.
2085 //
2086 // Special Notes : The "Q" vector is part of a standard DAE formalism in
2087 // which the system of equations is represented as:
2088 //
2089 // f(x) = dQ(x)/dt + F(x) - B(t) = 0
2090 //
2091 // Scope : public
2092 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
2093 // Creation Date : 01/26/03
2094 //-----------------------------------------------------------------------------
2096 {
2097  double td = model_.excessPhaseFac;
2098  double vbe_diff = vBE - vBE_orig;
2099  double vbc_diff = vBC - vBC_orig;
2100 
2101  double * solVec = extData.nextSolVectorRawPtr;
2102  double * qVec = extData.daeQVectorRawPtr;
2103 
2104  qVec[li_Base] -= - model_.TYPE * qBX;
2105  qVec[li_Subst] -= -model_.TYPE * qCS;
2106  qVec[li_CollP] -= model_.TYPE * ( qCS + qBX + qBCdep + qBCdiff );
2107  qVec[li_BaseP] -= -model_.TYPE * ( qBEdep + qBEdiff + qBCdep + qBCdiff );
2108  qVec[li_EmitP] -= model_.TYPE*( qBEdep + qBEdiff );
2109 
2110  // excess phase ERK-dcop
2111  if (td != 0 && getDeviceOptions().newExcessPhase)
2112  {
2113  qVec[li_Ifx] += solVec[li_Ifx];
2114 
2115  if (!(getSolverState().dcopFlag) )
2116  {
2117  qVec[li_dIfx] += solVec[li_dIfx]*td*td;
2118  }
2119  else
2120  {
2121  qVec[li_dIfx] = 0.0;
2122  }
2123  }
2124 
2125  // load up the jdxp terms
2127  {
2128  double Cp_Jdxp_q = 0.0;
2129  double Ep_Jdxp_q = 0.0;
2130  double Bp_Jdxp_q = 0.0;
2131 
2132  if (!origFlag)
2133  {
2134  Cp_Jdxp_q = -(capBCdep + capBCdiff)*vbc_diff;
2135  Cp_Jdxp_q *= model_.TYPE;
2136 
2137  Bp_Jdxp_q = (capBEdep + capBEdiff)*vbe_diff
2138  + (capBCdiff + capBCdep + capeqCB) *vbc_diff;
2139  Bp_Jdxp_q *= model_.TYPE;
2140 
2141  Ep_Jdxp_q = - capeqCB * vbc_diff - (capBEdiff + capBEdep)* vbe_diff;
2142  Ep_Jdxp_q *= model_.TYPE;
2143  }
2144 
2145  double * dQdxdVp = extData.dQdxdVpVectorRawPtr;
2146  dQdxdVp[li_CollP] += Cp_Jdxp_q;
2147  dQdxdVp[li_BaseP] += Bp_Jdxp_q;
2148  dQdxdVp[li_EmitP] += Ep_Jdxp_q;
2149  }
2150 
2151  if( loadLeadCurrent )
2152  {
2153  double * storeLeadQ = extData.storeLeadCurrQCompRawPtr;
2154 
2155  storeLeadQ[li_store_dev_ic] = -model_.TYPE * ( qCS + qBX + qBCdep + qBCdiff );
2156  storeLeadQ[li_store_dev_ib] = model_.TYPE * ( qBX + qBEdep + qBEdiff + qBCdep + qBCdiff );
2157  storeLeadQ[li_store_dev_ie] = -model_.TYPE*( qBEdep + qBEdiff );
2158  storeLeadQ[li_store_dev_is] = model_.TYPE * qCS;
2159 
2160  double * leadQ = extData.nextLeadCurrQCompRawPtr;
2161  leadQ[li_branch_dev_ic] = -model_.TYPE * ( qCS + qBX + qBCdep + qBCdiff );
2162  leadQ[li_branch_dev_ib] = model_.TYPE * ( qBX + qBEdep + qBEdiff + qBCdep + qBCdiff );
2163  leadQ[li_branch_dev_ie] = -model_.TYPE*( qBEdep + qBEdiff );
2164  leadQ[li_branch_dev_is] = model_.TYPE * qCS;
2165 
2166  }
2167 
2168  return true;
2169 }
2170 
2171 //-----------------------------------------------------------------------------
2172 // Function : Instance::auxDAECalculations
2173 //
2174 // Purpose : This function is supposed to handle a lot of the final
2175 // "cleanup" calculations that were done, in the old-DAE
2176 // formulation, at the end of updateSecondaryState.
2177 //
2178 // For the new-DAE form, they need to be done elsewhere, as
2179 // updateSecondaryState isn't called for new-DAE.
2180 //
2181 // Special Notes :
2182 // Scope : public
2183 // Creator : Eric Keiter, 9233, Computational Sciences.
2184 // Creation Date : 04/15/04
2185 //-----------------------------------------------------------------------------
2187 {
2188  double i_fx;
2189  double td = model_.excessPhaseFac;
2190  double * solVec = extData.nextSolVectorRawPtr;
2191 
2192  if ( td != 0 && !(getSolverState().dcopFlag) )
2193  {
2194  i_fx = solVec[li_Ifx];
2195  iCE = i_fx - iBC / qB;
2196  }
2197  else
2198  {
2199  iCE = (iBE - iBC)/ qB;
2200  }
2201 
2202  iC = iCE - iBC / tBetaR - iBCleak;
2203  iB = iBE / tBetaF + iBEleak + iBC / tBetaR + iBCleak;
2204  iE = -iC-iB;
2205 
2206  if (td != 0)
2207  {
2208  if (!(getSolverState().dcopFlag) )
2209  {
2210  diCEdvBp = invqB * (-invqB * iBC * dqBdvBp - gBC);
2211  diCEdvCp = invqB * (-invqB * iBC * dqBdvCp + gBC);
2212  diCEdvEp = -invqB * invqB * iBC * dqBdvEp;
2213  }
2214  else // ERK-dcop: if dcop, use the td=0 case (copied from below)
2215  {
2216  diCEdvBp = invqB * (iCE * dqBdvBp + gBE - gBC);
2217  diCEdvCp = invqB * (iCE * dqBdvCp + gBC);
2218  diCEdvEp = invqB * (iCE * dqBdvEp - gBE);
2219  }
2220 
2221  diBEdvBp = invqB *(invqB* iBE * dqBdvBp + gBE);
2222  diBEdvCp = invqB * invqB * iBE * dqBdvCp;
2223  diBEdvEp = invqB * (invqB * iBE * dqBdvEp - gBE);
2224  }
2225  else
2226  {
2227  diCEdvBp = invqB * (iCE * dqBdvBp + gBE - gBC);
2228  diCEdvCp = invqB * (iCE * dqBdvCp + gBC);
2229  diCEdvEp = invqB * (iCE * dqBdvEp - gBE);
2230  }
2231 
2232  return;
2233 }
2234 
2235 //-----------------------------------------------------------------------------
2236 // Function : Instance::loadDAEFVector
2237 //
2238 // Purpose : Loads the F-vector contributions for a single
2239 // BJT instance.
2240 //
2241 // Special Notes :
2242 //
2243 // Scope : public
2244 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
2245 // Creation Date : 01/26/03
2246 //-----------------------------------------------------------------------------
2248 {
2249  double coefC, coefB, coefE, coefCp, coefBp, coefEp;
2250 
2251  double td = model_.excessPhaseFac;
2252  double * solVec = extData.nextSolVectorRawPtr;
2253  double * fVec = extData.daeFVectorRawPtr;
2254 
2255  double vbe_diff = vBE - vBE_orig;
2256  double vbc_diff = vBC - vBC_orig;
2257  double vce_diff = vbe_diff - vbc_diff;
2258 
2259  fVec[li_Coll] -= -vCCp * gCpr;
2260  fVec[li_Base] -= -vBBp * gX;
2261  fVec[li_Emit] -= -vEEp * gEpr;
2262  fVec[li_CollP] -= vCCp * gCpr + model_.TYPE * ( - iC );
2263  fVec[li_BaseP] -= vBBp * gX - model_.TYPE * ( iB );
2264  fVec[li_EmitP] -= vEEp * gEpr + model_.TYPE * ( - iE );
2265 
2266  // excess phase ERK-dcop.
2267  double i_fx = 0.0;
2268  double di_fx = 0.0;
2269 
2271  //if (td != 0 && getDeviceOptions().newExcessPhase)
2272  {
2273  i_fx = solVec[li_Ifx];
2274  di_fx = solVec[li_dIfx];
2275 
2276  if (td != 0)
2277  {
2278  if (!(getSolverState().dcopFlag) )
2279  {
2280  // omega0 = 1/td;
2281  fVec[li_Ifx] += - di_fx;
2282  fVec[li_dIfx] += 3 * di_fx*td + 3*i_fx -3 * iBE / qB;
2283  }
2284  else
2285  {
2286  fVec[li_Ifx] += i_fx -iBE/qB;
2287  fVec[li_dIfx] = 0.0;
2288  }
2289  }
2290  else
2291  {
2292  fVec[li_Ifx] += i_fx;
2293  fVec[li_dIfx] += di_fx;
2294  }
2295  }
2296 
2297  double Cp_Jdxp_f=0.0;
2298  double Bp_Jdxp_f=0.0;
2299  double Ep_Jdxp_f=0.0;
2300  double dIfx_Jdxp_f=0.0 ;
2301  double Ifx_Jdxp_f=0.0 ;
2302 
2303  // Now for the jdxp terms
2305  {
2306  if (!origFlag)
2307  {
2308  Cp_Jdxp_f = + diCEdvBp * vbe_diff
2309  + diCEdvCp * vce_diff
2310  - gBCtot * vbc_diff;
2311 
2312  Cp_Jdxp_f *= model_.TYPE;
2313 
2314  Bp_Jdxp_f = gBEtot * vbe_diff + gBCtot * vbc_diff;
2315  Bp_Jdxp_f *= model_.TYPE;
2316 
2317  Ep_Jdxp_f = - diCEdvCp * vce_diff - (diCEdvBp + gBEtot) * vbe_diff;
2318  Ep_Jdxp_f *= model_.TYPE;
2319 
2320  // ERK-dcop.
2321  if ( td != 0 && getDeviceOptions().newExcessPhase )
2322  {
2323  if ( !(getSolverState().dcopFlag) )
2324  {
2325  dIfx_Jdxp_f = -3 *( diBEdvBp*vbe_diff + diBEdvCp * vce_diff);
2326  dIfx_Jdxp_f *= model_.TYPE;
2327  }
2328  else
2329  {
2330  Ifx_Jdxp_f = ( diBEdvBp*vbe_diff + diBEdvCp * vce_diff);
2331  Ifx_Jdxp_f *= model_.TYPE;
2332  }
2333  }
2334  }
2335 
2336  double * dFdxdVp = extData.dFdxdVpVectorRawPtr;
2337  dFdxdVp[li_CollP] += Cp_Jdxp_f;
2338  dFdxdVp[li_BaseP] += Bp_Jdxp_f;
2339  dFdxdVp[li_EmitP] += Ep_Jdxp_f;
2340 
2341  // ERK-dcop.
2342  if ( td != 0 && getDeviceOptions().newExcessPhase )
2343  {
2344  if ( !(getSolverState().dcopFlag) )
2345  {
2346  dFdxdVp[li_dIfx] += dIfx_Jdxp_f;
2347  }
2348  else
2349  {
2350  dFdxdVp[li_Ifx] += Ifx_Jdxp_f;
2351  }
2352  }
2353  }
2354 
2355  if( loadLeadCurrent )
2356  {
2357  double * storeLeadF = extData.nextStoVectorRawPtr;
2358 
2359  storeLeadF[li_store_dev_ic] = model_.TYPE * ( iC );
2360  storeLeadF[li_store_dev_is] = 0;
2361  storeLeadF[li_store_dev_ie] = model_.TYPE * ( iE );
2362  storeLeadF[li_store_dev_ib] = model_.TYPE * ( iB );
2363 
2364  double * leadF = extData.nextLeadCurrFCompRawPtr;
2365  double * junctionV = extData.nextJunctionVCompRawPtr;
2366  leadF[li_branch_dev_ic] = model_.TYPE * ( iC );
2367  leadF[li_branch_dev_is] = 0;
2368  leadF[li_branch_dev_ie] = model_.TYPE * ( iE );
2369  leadF[li_branch_dev_ib] = model_.TYPE * ( iB );
2370 
2371  junctionV[li_branch_dev_ic] = solVec[li_Coll] - solVec[li_Emit];
2372  junctionV[li_branch_dev_is] = 0.0; // solVec[li_Subst] - solVec[li_Subst];
2373  junctionV[li_branch_dev_ib] = solVec[li_Base] - solVec[li_Emit];
2374  junctionV[li_branch_dev_ie] = solVec[li_Emit] - solVec[li_Base];
2375 
2376  }
2377  return true;
2378 }
2379 
2380 //-----------------------------------------------------------------------------
2381 // Function : Instance::loadDAEdQdx
2382 //
2383 // Purpose : Loads the Q-vector contributions for a single
2384 // BJT instance.
2385 //
2386 // Special Notes : The "Q" vector is part of a standard DAE formalism in
2387 // which the system of equations is represented as:
2388 //
2389 // f(x) = dQ(x)/dt + F(x) - B(t) = 0
2390 //
2391 // The "Q" vector contains charges and fluxes. So, this
2392 // matrix will contain only the capacitance terms.
2393 //
2394 // Scope : public
2395 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
2396 // Creation Date : 03/05/04
2397 //-----------------------------------------------------------------------------
2399 {
2400  double td = model_.excessPhaseFac;
2401 
2402  Linear::Matrix & dQdx = *(extData.dQdxMatrixPtr);
2403 
2405 
2409 
2413  += capCS + capBX + capBCdep + capBCdiff;
2414 
2416  += -capBCdep - capBCdiff;
2417 
2419  += -capBCdiff - capBCdep - capeqCB;
2420 
2422  += capBEdiff + capBEdep + capBCdiff + capBCdep + capeqCB;
2423 
2425  += -capBEdiff - capBEdep;
2428  += -capBEdiff - capBEdep - capeqCB;
2430  += capBEdiff + capBEdep;
2431 
2432  // excess phase terms. ERK-dcop
2433  if ( td != 0 && getDeviceOptions().newExcessPhase )
2434  {
2435  if (!(getSolverState().dcopFlag) )
2436  {
2437  dQdx[li_Ifx][AIfxEquIfxNodeOffset] += 1;
2438  dQdx[li_dIfx][AdIfxEqudIfxNodeOffset] += 1*td*td;
2439  }
2440  }
2441 
2442  return true;
2443 }
2444 
2445 //-----------------------------------------------------------------------------
2446 // Function : Instance::loadDAEdFdx ()
2447 //
2448 // Purpose : Loads the F-vector contributions for a single
2449 // BJT instance.
2450 //
2451 // Special Notes : See the special notes for loadDAEFVector.
2452 //
2453 // This is an algebraic constaint.
2454 //
2455 // Scope : public
2456 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
2457 // Creation Date : 03/05/04
2458 //-----------------------------------------------------------------------------
2460 {
2461  double td = model_.excessPhaseFac;
2462 
2463  Linear::Matrix & dFdx = *(extData.dFdxMatrixPtr);
2464 
2471 
2473 
2475 
2476 
2480  += diCEdvBp - gBCtot;
2482 
2483  // excess phase terms. ERK-dcop
2484  if ( td != 0 && getDeviceOptions().newExcessPhase && !(getSolverState().dcopFlag) )
2485  dFdx[li_CollP][ACollPEquIfxNodeOffset] += 1.0 * model_.TYPE;
2486 
2489  += -diBrdvCp - gBCtot;
2490 
2492  += -diBrdvBp + gBEtot + gBCtot;
2493 
2495  += -diBrdvEp - gBEtot;
2496 
2500  += - diCEdvBp - gBEtot;
2501 
2502  // ERK Note: -diCEdvEp should equal + diCEdvBp + diCEdvCp. In the
2503  // original old-DAE form, + diCEdvBp + diCEdvCp is used. In
2504  // the more recent new-DAE form, we've used diCEdvEp, but it sometimes
2505  // results in subtle differences between old- and new-DAE jacobians.
2506  // This should matter, but .....
2508  //+= gBEtot + gEpr - diCEdvEp;
2509  += gBEtot + gEpr + diCEdvBp + diCEdvCp; // this is a test.
2510 
2511  // excess phase terms. ERK-dcop
2512  if ( td != 0 && getDeviceOptions().newExcessPhase && !(getSolverState().dcopFlag) )
2513  dFdx[li_EmitP][AEmitPEquIfxNodeOffset] += -1.0 * model_.TYPE;
2514 
2515  // excess phase terms. ERK-dcop
2517  {
2518  if ( td != 0 )
2519  {
2520  if ( !(getSolverState().dcopFlag) )
2521  {
2522  dFdx[li_Ifx][AIfxEqudIfxNodeOffset]+= -1;
2526  dFdx[li_dIfx][AdIfxEqudIfxNodeOffset] += 3* td;
2527  dFdx[li_dIfx][AdIfxEquIfxNodeOffset] += 3;
2528  }
2529  else
2530  {
2534  dFdx[li_Ifx][AIfxEquIfxNodeOffset]+= 1;
2535  dFdx[li_dIfx][AdIfxEqudIfxNodeOffset] += 1;
2536  }
2537  }
2538  else
2539  {
2540  dFdx[li_Ifx][AIfxEquIfxNodeOffset]+= 1;
2541  dFdx[li_dIfx][AdIfxEqudIfxNodeOffset] += 1;
2542  }
2543  }
2544 
2545  return true;
2546 }
2547 
2548 //-----------------------------------------------------------------------------
2549 // Function : Instance::updatePrimaryState
2550 // Purpose :
2551 // Special Notes :
2552 // Scope : public
2553 // Creator : Robert J. Hoekstra
2554 // Creation Date : 1/13/00
2555 //-----------------------------------------------------------------------------
2557 {
2558  // Do the bulk of the work in updateIntermediateVars:
2559  bool bsuccess = updateIntermediateVars();
2560 
2561  double * staVec = extData.nextStaVectorRawPtr;
2562  double * currStaVec = extData.currStaVectorRawPtr;
2563 
2564  // save voltage drops
2565 
2566  double * stoVec = extData.nextStoVectorRawPtr;
2567  stoVec[li_storevBE] = vBE;
2568  stoVec[li_storevBC] = vBC;
2569  stoVec[li_store_capeqCB] = capeqCB;
2570 
2571  staVec[li_qstateBEdiff] = qBEdiff;
2572  staVec[li_qstateBEdep] = qBEdep;
2573  staVec[li_qstateBCdiff] = qBCdiff;
2574  staVec[li_qstateBCdep] = qBCdep;
2575  staVec[li_qstateBX] = qBX;
2576  staVec[li_qstateCS] = qCS;
2577 
2578 
2579  // if this is the first newton step of the first time step
2580  // of the transient simulation, we need to enforce that the
2581  // time derivatives w.r.t. charge are zero. This is to maintain 3f5
2582  // compatibility. ERK.
2583 
2584  if (!(getSolverState().dcopFlag) && (getSolverState().initTranFlag_) && getSolverState().newtonIter==0)
2585  {
2586  currStaVec[li_qstateBEdiff] = qBEdiff;
2587  currStaVec[li_qstateBEdep] = qBEdep;
2588  currStaVec[li_qstateBCdiff] = qBCdiff;
2589  currStaVec[li_qstateBCdep] = qBCdep;
2590  currStaVec[li_qstateBX] = qBX;
2591  currStaVec[li_qstateCS] = qCS;
2592  }
2593 
2594  return bsuccess;
2595 }
2596 
2597 //-----------------------------------------------------------------------------
2598 // Function : Instance::updateSecondaryState
2599 // Purpose :
2600 // Special Notes :
2601 // Scope : public
2602 // Creator : Robert J. Hoekstra
2603 // Creation Date : 1/13/00
2604 //-----------------------------------------------------------------------------
2606 {
2607  double * staDerivVec = extData.nextStaDerivVectorRawPtr;
2608 
2609  // Now that the state vector for time=0 is up-to-date, get the derivative
2610  // with respect to time of the charge, to obtain the best estimate for
2611  // the current in the capacitor.
2612 
2613  iBEdiff = staDerivVec[li_qstateBEdiff];
2614  iBEdep = staDerivVec[li_qstateBEdep ];
2615  iCS = staDerivVec[li_qstateCS ];
2616  iBCdiff = staDerivVec[li_qstateBCdiff];
2617  iBCdep = staDerivVec[li_qstateBCdep ];
2618  iBX = staDerivVec[li_qstateBX ];
2619 
2620  return true;
2621 }
2622 
2623 
2624 //-----------------------------------------------------------------------------
2625 // Function : Xyce::Device::BJT::Instance::getNumNoiseSources
2626 // Purpose :
2627 // Special Notes :
2628 // Scope : public
2629 // Creator : Eric Keiter, SNL
2630 // Creation Date : 12/27/2014
2631 //-----------------------------------------------------------------------------
2633 {
2634  return 6;
2635 }
2636 
2637 //-----------------------------------------------------------------------------
2638 // Function : Xyce::Device::BJT::Instance::setupNoiseSources
2639 // Purpose :
2640 // Special Notes :
2641 // Scope : public
2642 // Creator : Eric Keiter
2643 // Creation Date :
2644 //-----------------------------------------------------------------------------
2646 {
2647  int numSources=6;
2648  noiseData.numSources = numSources;
2649  noiseData.resize(numSources);
2650 
2651  noiseData.deviceName = getName().getEncodedName();
2652 
2653  noiseData.noiseNames[0] = "onoise_" + getName().getEncodedName()+
2654  std::string("_rc"); // noise due to rc
2655  noiseData.noiseNames[1] = "onoise_" + getName().getEncodedName()+
2656  std::string("_rb"); // noise due to rb
2657  noiseData.noiseNames[2] = "onoise_" + getName().getEncodedName()+
2658  std::string("_re"); // noise due to re
2659  noiseData.noiseNames[3] = "onoise_" + getName().getEncodedName()+
2660  std::string("_ic"); // noise due to ic
2661  noiseData.noiseNames[4] = "onoise_" + getName().getEncodedName()+
2662  std::string("_ib"); // noise due to ib
2663  noiseData.noiseNames[5] = "onoise_" + getName().getEncodedName()+
2664  std::string("_1overf"); // flicker (1/f) noise
2665 
2666  // RC thermal:
2667  noiseData.li_Pos[0] = li_CollP;
2668  noiseData.li_Neg[0] = li_Coll;
2669 
2670  // RB thermal:
2671  noiseData.li_Pos[1] = li_BaseP;
2672  noiseData.li_Neg[1] = li_Base;
2673 
2674  // RE thermal:
2675  noiseData.li_Pos[2] = li_EmitP;
2676  noiseData.li_Neg[2] = li_Emit;
2677 
2678  // IC shot:
2679  noiseData.li_Pos[3] = li_CollP;
2680  noiseData.li_Neg[3] = li_EmitP;
2681 
2682  // IB shot:
2683  noiseData.li_Pos[4] = li_BaseP;
2684  noiseData.li_Neg[4] = li_EmitP;
2685 
2686  // flicker:
2687  noiseData.li_Pos[5] = li_BaseP;
2688  noiseData.li_Neg[5] = li_EmitP;
2689 
2690 }
2691 
2692 //-----------------------------------------------------------------------------
2693 // Function : Xyce::Device::BJT::Instance::getNoiseSources
2694 // Purpose :
2695 // Special Notes :
2696 // Scope : public
2697 // Creator : Eric Keiter
2698 // Creation Date :
2699 //-----------------------------------------------------------------------------
2701 {
2702  // thermal noise, RC:
2704  noiseData.noiseDens[0], noiseData.lnNoiseDens[0], THERMNOISE,
2706 
2707  // thermal noise, RB:
2709  noiseData.noiseDens[1], noiseData.lnNoiseDens[1], THERMNOISE,
2710  gX, TEMP);
2711 
2712  // thermal noise, RE:
2714  noiseData.noiseDens[2], noiseData.lnNoiseDens[2], THERMNOISE,
2716 
2717  // shot noise, IC:
2719  noiseData.noiseDens[3], noiseData.lnNoiseDens[3], SHOTNOISE,
2720  iC, TEMP );
2721 
2722  // shot noise, IB:
2724  noiseData.noiseDens[4], noiseData.lnNoiseDens[4], SHOTNOISE,
2725  iB, TEMP );
2726 
2727  // flicker noise
2728  noiseData.noiseDens[5] = model_.fNCoeff * std::exp(model_.fNExp *
2729  std::log(std::max(fabs( iB ),N_MINLOG))) / noiseData.freq;
2730  noiseData.lnNoiseDens[5] = std::log(std::max(noiseData.noiseDens[5],N_MINLOG));
2731 }
2732 
2733 //-----------------------------------------------------------------------------
2734 // Function : Instance::oldDAEExcessPhaseCalculation1
2735 //
2736 // Purpose : This handles the parts of the calculation of excess phase
2737 // terms that need to be done in the
2738 // updatePrimaryState function.
2739 //
2740 // Special Notes : The excess phase calculation is based on a second-order
2741 // time derivative.
2742 //
2743 // Most of the excess phase work is done in the companion
2744 // function, oldDAEExcessPhaseCalculation2.
2745 //
2746 // This function mainly enforces a constant history.
2747 //
2748 // Scope : public
2749 // Creator : Eric Keiter, 9233, Computational Sciences.
2750 // Creation Date : 04/11/04
2751 //-----------------------------------------------------------------------------
2753 {
2754  // do excess phase stuff if we are in transient mode and td is nonzero.
2755  double td = model_.excessPhaseFac;
2756 
2757  currCexbc = lastCexbc = 0.0;
2758 
2759  if (!(getSolverState().dcopFlag) && td != 0)
2760  {
2761  // If there is no cexbc history, create one and use it.
2762  if (getSolverState().beginIntegrationFlag_)
2763  {
2764  currCexbc = lastCexbc = iBE/qB;
2767  }
2768  }
2769 
2770  return;
2771 }
2772 
2773 //-----------------------------------------------------------------------------
2774 // Function : Instance::oldDAEExcessPhaseCalculation2
2775 //
2776 // Purpose : This handles the parts of the calculation of excess phase
2777 // terms that need to be done in the
2778 // updateSecondaryState function.
2779 //
2780 // Special Notes : This function has a companion function,
2781 // oldDAEExcessPhaseCalculation1. Most of the work is done
2782 // in this one.
2783 //
2784 // Scope : public
2785 // Creator : Eric Keiter, 9233, Computational Sciences.
2786 // Creation Date : 04/11/04
2787 //-----------------------------------------------------------------------------
2789  (double & iEX, double & gEX, double & iC_local)
2790 {
2791  ////////////////////////////////////////////////////////////////
2792  double td = model_.excessPhaseFac;
2793 
2794  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) && getSolverState().debugTimeFlag)
2795  {
2796  Xyce::dout() << std::endl;
2797  Xyce::dout() << " Excess Phase stuff:" <<std::endl;
2798  Xyce::dout() << " name = " << getName() <<std::endl;
2799  Xyce::dout() << " td = " << td <<std::endl;
2800  }
2801 
2802  ////////////////////////////////////////////////////////////////
2803  // ERK: 07/13/01
2804  //
2805  // weil's approx. for excess phase applied with backward-
2806  // euler integration
2807  // (copied over from spice).
2808  //
2809  ////////////////////////////////////////////////////////////////
2810 
2811  iEX=iBE;
2812  gEX=gBE;
2813 
2814  dt0 = getSolverState().currTimeStep_;
2815  dt1 = getSolverState().lastTimeStep_;
2816 
2817  iC_local = 0.0;
2818 
2819  // do excess phase stuff if we are in transient mode and td is nonzero.
2820  if (!(getSolverState().dcopFlag) && td != 0)
2821  {
2822  double arg1, arg2, denom;
2823 
2824  arg1 = dt0 / td;
2825  arg2 = 3.0 * arg1;
2826  arg1 = arg2 * arg1;
2827  denom = 1.0 + arg1 + arg2;
2828  phaseScalar = arg1 / denom;
2829 
2830  // Secondary state stuff:
2831  if (!getSolverState().beginIntegrationFlag_)
2832  {
2833  currCexbc = (*extData.currStaVectorPtr)[li_istateCEXBC];
2834  lastCexbc = (*extData.lastStaVectorPtr)[li_istateCEXBC];
2835  }
2836 
2837  iC_local = ((currCexbc) * (1 + dt0 / dt1 + arg2) - (lastCexbc) * dt0 / dt1) / denom;
2838  iEX = iBE * phaseScalar;
2839  gEX = gBE * phaseScalar;
2840 
2841  nextCexbc = iC_local + iEX / qB;
2842  (*extData.nextStaVectorPtr)[li_istateCEXBC] = nextCexbc;
2843  }
2844 
2845  return;
2846 }
2847 
2848 //-----------------------------------------------------------------------------
2849 // Function : Instance::updateIntermediateVars
2850 // Purpose :
2851 // Special Notes :
2852 // Scope : public
2853 // Creator : Robert J. Hoekstra
2854 // Creation Date : 1/13/00
2855 //-----------------------------------------------------------------------------
2857 {
2858  bool bsuccess = true;
2859 
2860  double v_emit, v_emitP;
2861  double v_base, v_baseP;
2862  double v_coll, v_collP;
2863  double v_subst;
2864 
2865  double q1, q2;
2866  double * solVec = extData.nextSolVectorRawPtr;
2867 
2868  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) && getSolverState().debugTimeFlag)
2869  {
2870  Xyce::dout() << Xyce::section_divider << std::endl;
2871  Xyce::dout() << "Instance::updateIntermediateVars " << getName() <<std::endl;
2872  }
2873 
2874  // obtain voltages:
2875  v_emit = solVec[li_Emit];
2876  v_emitP = solVec[li_EmitP];
2877  v_base = solVec[li_Base];
2878  v_baseP = solVec[li_BaseP];
2879  v_coll = solVec[li_Coll];
2880  v_collP = solVec[li_CollP];
2881  v_subst = solVec[li_Subst];
2882 
2883  vEEp = (v_emit - v_emitP);
2884  vBBp = (v_base - v_baseP);
2885  vCCp = (v_coll - v_collP);
2886 
2887  vBE = model_.TYPE * (v_baseP - v_emitP);
2888  vBC = model_.TYPE * (v_baseP - v_collP);
2889  vBX = model_.TYPE * (v_base - v_collP);
2890  //vCS = model_.TYPE * (v_collP - v_subst);
2891  vCS = model_.TYPE * (v_subst - v_collP);
2892 
2893  vBE_orig = vBE;
2894  vBC_orig = vBC;
2895 
2896  // Reset this to show we're starting from the originals
2897  origFlag = true;
2898  offFlag = false;
2899 
2901  {
2902  if( IC_GIVEN )
2903  {
2904  vBE = model_.TYPE * icVBE;
2905  double vCE = model_.TYPE * icVCE;
2906  vBC = vBE - vCE;
2907  vBX = vBC;
2908  origFlag = false;
2909  }
2910  else
2911  {
2913  {
2914  Linear::Vector * flagSolVectorPtr = extData.flagSolVectorPtr;
2915  if ((*flagSolVectorPtr)[li_Emit] == 0 || (*flagSolVectorPtr)[li_EmitP] == 0 ||
2916  (*flagSolVectorPtr)[li_Base] == 0 || (*flagSolVectorPtr)[li_BaseP] == 0 ||
2917  (*flagSolVectorPtr)[li_Coll] == 0 || (*flagSolVectorPtr)[li_CollP] == 0 ||
2918  (*flagSolVectorPtr)[li_Subst] == 0 )
2919  {
2920  vBC = 0;
2921  vBE = tVCrit;
2922  vBX = vBC;
2923  origFlag = false;
2924  }
2925  }
2926  else
2927  {
2928  vBE=tVCrit;
2929  vBX = vBC;
2930  origFlag = false;
2931  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) && getSolverState().debugTimeFlag)
2932  {
2933  Xyce::dout() << " Setting device initial condition to Base-Emitter drop=tVCrit (" << tVCrit << ")"<<std::endl;
2934  }
2935  }
2936  }
2937 
2938 
2939  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) && getSolverState().debugTimeFlag)
2940  {
2941  Xyce::dout().width(21); Xyce::dout().precision(13); Xyce::dout().setf(std::ios::scientific);
2942  Xyce::dout() << " " <<std::endl;
2943  Xyce::dout() << " using UIC.\n";
2944  Xyce::dout() << " vBE = " << vBE << std::endl;
2945  Xyce::dout() << " vBC = " << vBC << std::endl;
2946  Xyce::dout() << " vBX = " << vBX << std::endl;
2947  Xyce::dout() << " vCS = " << vCS << std::endl;
2948  }
2949  }
2950  else if ((getSolverState().initFixFlag || getSolverState().initJctFlag_) && OFF)
2951  {
2952  vBX = vBC = vBE = 0.0 ;
2953  // NOTE: Must not set "origFlag" here, because that flags "non-converged"
2954  // which causes initFixFlag always to be set, which causes this section
2955  // always to be executed. Bad!
2956  // instead, flag with "offFlag" that will not be used in convergence
2957  // testing, but WILL be used in the voltage limiting machinery to make
2958  // this work properly.
2959  offFlag = true;
2960 
2961  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) && getSolverState().debugTimeFlag)
2962  {
2963  Xyce::dout().width(21); Xyce::dout().precision(13); Xyce::dout().setf(std::ios::scientific);
2964  Xyce::dout() << " " <<std::endl;
2965  Xyce::dout() << " BJT explicitly set OFF, zeroing all junction drops.\n";
2966  }
2967  }
2968 
2969 
2970  if (getSolverState().newtonIter == 0)
2971  {
2972  if (!(getSolverState().dcopFlag)||(getSolverState().locaEnabledFlag && getSolverState().dcopFlag))
2973  {
2977  }
2978  else
2979  {
2980  vBE_old = vBE; // otherwise we have no history
2981  vBC_old = vBC;
2982  capeqCB = 0.0;
2983  }
2984  }
2985  else
2986  {
2990  }
2991 
2992  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) && getSolverState().debugTimeFlag)
2993  {
2994  Xyce::dout() << " tVCrit = " << tVCrit << std::endl;
2995  Xyce::dout().width(3);
2996  Xyce::dout() << getSolverState().newtonIter;
2997  Xyce::dout().width(5); Xyce::dout() << getName();
2998  Xyce::dout() << " Blim: ";
2999  Xyce::dout() << " vBE=";
3000  Xyce::dout().width(21); Xyce::dout().precision(13); Xyce::dout().setf(std::ios::scientific);
3001  Xyce::dout() << vBE;
3002  Xyce::dout() << " vBC=";
3003  Xyce::dout().width(21); Xyce::dout().precision(13); Xyce::dout().setf(std::ios::scientific);
3004  Xyce::dout() << vBC << std::endl;
3005  }
3006 
3007  // if we had bypass implemented, most of it would be here.
3008  // don't bother limiting voltages if we've already forced OFF.
3009 
3010  if (getDeviceOptions().voltageLimiterFlag && !(getSolverState().initFixFlag&&OFF))
3011  {
3012  // "reset" the junction voltages to keep them from changing too much.
3013  // only do this if this is not the first newton iteration, and not
3014  // a by pass step.
3015  int ichk1, icheck;
3016 
3017  if (getSolverState().newtonIter >= 0)
3018  {
3019  ichk1=1; // don't know what this is for...
3020 
3021  vBE = devSupport.pnjlim(vBE, vBE_old, vt, tVCrit, &icheck);
3022  vBC = devSupport.pnjlim(vBC, vBC_old, vt, tVCrit, &ichk1);
3023 
3024  if (ichk1 == 1) icheck=1;
3025 
3026  // set the origFlag to zero if things have changed.
3027  if (icheck==1) origFlag = false;
3028  }
3029 
3030  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) && getSolverState().debugTimeFlag)
3031  {
3032  Xyce::dout().width(3);
3033  Xyce::dout() << getSolverState().newtonIter;
3034  Xyce::dout().width(5); Xyce::dout() << getName() ;
3035  Xyce::dout() << " Alim: ";
3036  Xyce::dout() << " vBE=";
3037  Xyce::dout().width(21); Xyce::dout().precision(13); Xyce::dout().setf(std::ios::scientific);
3038  Xyce::dout() << vBE;
3039  Xyce::dout() << " vBC=";
3040  Xyce::dout().width(21); Xyce::dout().precision(13); Xyce::dout().setf(std::ios::scientific);
3041  Xyce::dout() << vBC;
3042 
3043  //cout << " vBE_orig = " << vBE_orig << std::endl;
3044  //cout << " vBC_orig = " << vBC_orig << std::endl <<std::endl;
3045  //cout << " origFlag = " << origFlag << std::endl;
3046 
3047  if (origFlag) Xyce::dout() << " SAME";
3048  else Xyce::dout() << " DIFF";
3049  Xyce::dout() << std::endl;
3050  }
3051  }
3052 
3053  //Junction Current Calculations
3054 
3055  double csat = tSatCur * AREA;
3056  double vtF = vt * model_.emissionCoeffF;
3057  double vtR = vt * model_.emissionCoeffR;
3058  double vtE = vt * tleakBEEmissionCoeff;
3059  double vtC = vt * tleakBCEmissionCoeff;
3060  double iLeakBE = tBELeakCur * AREA;
3061  double iLeakBC = tBCLeakCur * AREA;
3062 
3063  // determine currents using LambertW
3064  if (lambertWFlag)
3065  {
3066  if( vBE > -5.0 * vtF )
3067  {
3068  lambertWCurrent(iBE, gBE, vBE, vtF, csat);
3069 
3070  if( iLeakBE == 0.0 )
3071  iBEleak = gBEleak = 0.0;
3072  else
3073  {
3074  lambertWCurrent(iBEleak, gBEleak, vBE, vtE, iLeakBE);
3075  }
3076  }
3077  else
3078  {
3079  gBE = -csat / vBE + getDeviceOptions().gmin;
3080  iBE = gBE * vBE;
3081  gBEleak = -iLeakBE / vBE;
3082  iBEleak = gBEleak * vBE;
3083  }
3084 
3085  if( vBC > -5.0 * vtR )
3086  {
3087  lambertWCurrent(iBC, gBC, vBC, vtR, csat);
3088 
3089  if( iLeakBC == 0.0 )
3090  iBCleak = gBCleak = 0.0;
3091  else
3092  {
3093  lambertWCurrent(iBCleak, gBCleak, vBC, vtC, iLeakBC);
3094  }
3095  }
3096  else
3097  {
3098  gBC = -csat / vBC + getDeviceOptions().gmin;
3099  iBC = gBC * vBC;
3100  gBCleak = -iLeakBC / vBC;
3101  iBCleak = gBCleak * vBC;
3102  }
3103  }
3104 
3105  // determine currents using normal exponential
3106  else
3107  {
3108  if (vBE > -5.0 * vtF)
3109  {
3110  double arg1 = vBE / vtF ;
3111  arg1 = std::min(CONSTMAX_EXP_ARG, arg1);
3112  double devBE;
3113  double evBE;
3114  if (getSolverState().bjtArtParameterFlag_)
3115  {
3116  evBE = devSupport.Xexp( arg1 , devBE, getDeviceOptions().exp_order );
3117  }
3118  else
3119  {
3120  evBE = exp( arg1 );
3121  devBE=evBE;
3122  }
3123  iBE = csat * ( evBE - 1.0 ) + getDeviceOptions().gmin * vBE;
3124  gBE = csat * devBE / vtF + getDeviceOptions().gmin;
3125 
3126  if (iLeakBE == 0.0)
3127  iBEleak = gBEleak = 0.0;
3128  else
3129  {
3130  double arg1 = vBE / vtE ;
3131  arg1 = std::min(CONSTMAX_EXP_ARG, arg1);
3132  double devBEleak;
3133  double evBEleak;
3134  if (getSolverState().bjtArtParameterFlag_)
3135  {
3136  evBEleak =devSupport.Xexp(arg1,devBEleak,getDeviceOptions().exp_order );
3137  }
3138  else
3139  {
3140  evBEleak = exp(arg1);
3141  devBEleak=evBEleak;
3142  }
3143  iBEleak = iLeakBE * (evBEleak - 1.0);
3144  gBEleak = iLeakBE * devBEleak / vtE;
3145  }
3146  }
3147  else
3148  {
3149  gBE = -csat / vBE + getDeviceOptions().gmin;
3150  iBE = gBE * vBE;
3151  gBEleak = -iLeakBE / vBE;
3152  iBEleak = gBEleak * vBE;
3153  }
3154 
3155  if( vBC > -5.0 * vtR )
3156  {
3157  double arg1 = vBC / vtR ;
3158  arg1 = std::min(CONSTMAX_EXP_ARG, arg1);
3159  double devBC;
3160  double evBC;
3161  if (getSolverState().bjtArtParameterFlag_)
3162  {
3163  evBC = devSupport.Xexp( arg1 , devBC, getDeviceOptions().exp_order );
3164  }
3165  else
3166  {
3167  evBC = exp( arg1 );
3168  devBC=evBC;
3169  }
3170  iBC = csat * ( evBC - 1.0 ) + getDeviceOptions().gmin * vBC;
3171  gBC = csat * devBC / vtR + getDeviceOptions().gmin;
3172 
3173  if (iLeakBC == 0.0)
3174  iBCleak = gBCleak = 0.0;
3175  else
3176  {
3177  double arg1 = vBC / vtC ;
3178  arg1 = std::min(CONSTMAX_EXP_ARG, arg1);
3179  double devBCleak;
3180  double evBCleak;
3181  if (getSolverState().bjtArtParameterFlag_)
3182  {
3183  evBCleak= devSupport.Xexp(arg1,devBCleak,getDeviceOptions().exp_order);
3184  }
3185  else
3186  {
3187  evBCleak = exp(arg1);
3188  devBCleak=evBCleak;
3189  }
3190  iBCleak = iLeakBC * (evBCleak - 1.0);
3191  gBCleak = iLeakBC * devBCleak / vtC;
3192  }
3193  }
3194  else
3195  {
3196  gBC = -csat / vBC + getDeviceOptions().gmin;
3197  iBC = gBC * vBC;
3198  gBCleak = -iLeakBC / vBC;
3199  iBCleak = gBCleak * vBC;
3200  }
3201  }
3202 
3203  // base charge calculations:
3204  double rofF = tInvRollOffF / AREA;
3205  double rofR = tInvRollOffR / AREA;
3206 
3207  q1 = 1.0 / ( 1.0 - tInvEarlyVoltF * vBC - tInvEarlyVoltR * vBE );
3208 
3209  if (rofF == 0.0 && rofR == 0.0)
3210  {
3211  qB = q1;
3212  double q1_qB = q1 * qB;
3213 
3214  dqBdvEp = q1_qB * tInvEarlyVoltR;
3215  dqBdvCp = q1_qB * tInvEarlyVoltF;
3216 /* replaced with simpler expression after if block
3217  dqBdvBp = -q1_qB * (model_.invEarlyVoltR + model_.invEarlyVoltF);
3218 */
3219  }
3220  else
3221  {
3222  q2 = rofF * iBE + rofR * iBC;
3223 
3224  // Difference from SPICE: spice puts a max(0,) around the arg definition,
3225  // which means we use the square root expression all the way down to
3226  // q2= -1/4. This is not really good, because it means that the derivative
3227  // of the square root term goes to negative infinity at the break point
3228  // between the expressions, and qB will be very discontinuous.
3229  // This doesn't have a huge effect on the solutions, but can possibly
3230  // lead to convergence issues (see bug 1214). This fix hasn't yet
3231  // been shown to help anything, but it has not hurt anything either.
3232  if (q2 >= 0)
3233  {
3234 
3235  double arg = 1.0 + 4.0 * q2;
3236  double sqarg = 1.0;
3237 
3238  // if (fabs(arg) > 0.0) sqarg = sqrt(arg);
3239  // double rofF_gBE_invSqarg = rofF * gBE / sqarg;
3240  // double rofR_gBC_invSqarg = rofR * gBC / sqarg;
3241  // add Pspice compatible rolloff parameter NK = tRollOffExp
3242 
3243  if (fabs(arg) > 0.0) sqarg = pow(arg,tRollOffExp);
3244  double rofF_gBE_invSqarg = 0.0;
3245  double rofR_gBC_invSqarg = 0.0;
3246  if(arg != 0) rofF_gBE_invSqarg = rofF*gBE*2*tRollOffExp*sqarg/arg;
3247  if(arg != 0) rofR_gBC_invSqarg = rofR*gBC*2*tRollOffExp*sqarg/arg;
3248 
3249  qB = 0.5 * q1 * (1.0 + sqarg);
3250 
3251  dqBdvEp = q1 * (qB * tInvEarlyVoltR + rofF_gBE_invSqarg);
3252  dqBdvCp = q1 * (qB * tInvEarlyVoltF + rofR_gBC_invSqarg);
3253 
3254  /* replaced with simpler expression after if block
3255  dqBdvBp = -q1 * (qB * ( model_.invEarlyVoltF + model_.invEarlyVoltR) +
3256  rofF_gBE_invSqarg + rofR_gBC_invSqarg);
3257  */
3258  }
3259  else
3260  {
3261  qB = q1;
3262  dqBdvEp = q1*qB*tInvEarlyVoltR;
3263  dqBdvCp = q1*qB*tInvEarlyVoltF;
3264  }
3265  }
3266  dqBdvBp = - (dqBdvEp + dqBdvCp);
3267 
3268  invqB = 1.0 / qB;
3269 
3270 
3271  // NOTE: this is a block that (for some reason) was originally in the
3272  // updatePrimaryState function. It got moved as in general, the "state"
3273  // functions are only for manipulating the state vector.
3274  // NOTE: brackets are around this block of code to preserve variable scope.
3275 
3276  double arg, sarg;
3277  double ctot;
3278  double czBC;
3279  double czBX;
3280  double czBE;
3281  double czCS;
3282  double fcpc;
3283  double fcpe;
3284 
3285  // capacitance calculations and "current" charge value calculations:
3286  ctot = tBCCap * AREA;
3287  czBC = ctot * model_.baseFracBCCap;
3288  czBX = ctot - czBC;
3289  czBE = tBECap * AREA;
3290  czCS = model_.CJS * AREA;
3291  fcpc = model_.depCapCoeff * model_.potBC;
3292  fcpe = tDepCap;
3293 
3294  // High current perturbation to BE current
3295  // The high current perturbation to the BE current is only
3296  // used in determining capacitance values. It does not enter
3297  // directly into the RHS KCL equations, or the Jacobian.
3298  iBEhighCurr = iBE;
3299  gBEhighCurr = gBE;
3300 
3301  // geqCB is only calculated sometimes (based on the if-statement).
3302  // If it is not calculated, then the value used will be the one from
3303  // the state vector, that was pulled out already.
3304  bool geqCB_recalc(false);
3305  if (model_.transTimeF != 0.0 && vBE > 0.0 &&
3306  ((!getSolverState().dcopFlag)||getSolverState().tranopFlag||getSolverState().acopFlag))
3307  {
3308  double argtf = 0.0;
3309  double arg2 = 0.0;
3310  double arg3 = 0.0;
3311 
3312  if ( model_.transTimeBiasCoeffF != 0.0)
3313  {
3314  argtf = model_.transTimeBiasCoeffF;
3315 
3316  if (model_.transTimeVBCFac != 0.0)
3317  argtf *= exp(vBC * model_.transTimeVBCFac);
3318 
3319  arg2 = argtf;
3320 
3321  if (model_.transTimeHighCurrF != 0.0)
3322  {
3323  double tmp = iBEhighCurr /
3325 
3326  argtf *= tmp * tmp;
3327  arg2 = argtf * (3.0 - 2.0 * tmp);
3328  }
3329  arg3 = iBEhighCurr * argtf * model_.transTimeVBCFac;
3330  }
3331 
3332  iBEhighCurr *= (1.0 + argtf) / qB;
3333  gBEhighCurr = (gBEhighCurr * (1.0 + arg2) - iBEhighCurr * dqBdvEp) / qB;
3334 
3335  capeqCB = model_.transTimeF * (arg3 - iBEhighCurr * dqBdvCp) / qB;
3337  geqCB_recalc = true;
3338  }
3339 
3340  // baseP-emitP depletion capacitance
3341  if( czBE == 0.0 )
3342  {
3343  qBEdep = 0.0;
3344  capBEdep = 0.0;
3345  }
3346  else
3347  {
3348  if ( vBE < fcpe )
3349  {
3350  arg = 1.0 - vBE / tBEPot;
3351  sarg = exp( -model_.juncExpBE * log( arg ) );
3352 
3353  qBEdep = tBEPot * czBE * ( 1.0 - arg * sarg ) /
3354  ( 1.0 - model_.juncExpBE );
3355  capBEdep = czBE * sarg;
3356  }
3357  else
3358  {
3359  double czBEf2 = czBE / model_.f2;
3360 
3361  qBEdep = czBE * tF1 + czBEf2 * ( model_.f3 * ( vBE -
3362  fcpe ) + ( model_.juncExpBE / ( 2.0 *
3363  tBEPot ) ) * ( vBE * vBE - fcpe * fcpe ) );
3364  capBEdep = czBEf2 * ( model_.f3 + model_.juncExpBE * vBE /
3365  tBEPot );
3366  }
3367  }
3368 
3369  // baseP-emitP diffusion capacitance
3370  if (model_.transTimeF == 0.0)
3371  {
3372  qBEdiff = capBEdiff = 0.0;
3373  }
3374  else
3375  {
3378  }
3379 
3380  // baseP-collP depletion capacitance
3381  if( czBC == 0.0 )
3382  {
3383  qBCdep = 0.0;
3384  capBCdep = 0.0;
3385  }
3386  else
3387  {
3388  if ( vBC < fcpc )
3389  {
3390  arg = 1.0 - vBC / tBCPot;
3391  sarg = exp( -model_.juncExpBC * log( arg ) );
3392 
3393  qBCdep = tBCPot * czBC * ( 1.0 - arg * sarg ) /
3394  ( 1.0 - model_.juncExpBC );
3395  capBCdep = czBC * sarg;
3396  }
3397  else
3398  {
3399  double czBCf2 = czBC / model_.f6;
3400 
3401  qBCdep = czBC * tF5 + czBCf2 * ( model_.f7 * ( vBC -
3402  fcpc ) + ( model_.juncExpBC / ( 2.0 *
3403  tBCPot ) ) * ( vBC * vBC - fcpc * fcpc ) );
3404  capBCdep = czBCf2 * ( model_.f7 + model_.juncExpBC * vBC / tBCPot );
3405  }
3406  }
3407 
3408  // baseP-collP diffusion capacitance
3409  if (model_.transTimeR == 0.0)
3410  {
3411  qBCdiff = capBCdiff = 0.0;
3412  }
3413  else
3414  {
3417  }
3418 
3419  // base-collP depletion capacitance
3420  if( czBX == 0.0 )
3421  {
3422  qBX = 0.0;
3423  capBX = 0.0;
3424  }
3425  else
3426  {
3427  if (vBX < fcpc)
3428  {
3429  arg = 1.0 - vBX / tBCPot;
3430  sarg = exp( -model_.juncExpBC * log( arg ) );
3431 
3432  qBX = tBCPot * czBX * ( 1.0 - arg * sarg ) /
3433  ( 1.0 - model_.juncExpBC );
3434  capBX = czBX * sarg;
3435  }
3436  else
3437  {
3438  double czBXf2 = czBX / model_.f6;
3439 
3440  qBX = czBX * tF5 + czBXf2 * ( model_.f7 * ( vBX -
3441  fcpc ) + ( model_.juncExpBC / ( 2.0 *
3442  tBCPot ) ) * ( vBX * vBX - fcpc * fcpc ) );
3443  capBX = czBXf2 * ( model_.f7 + model_.juncExpBC * vBX /
3444  tBCPot );
3445  }
3446  }
3447 
3448  // collP-subst depletion capacitance
3449  if( czCS == 0.0 )
3450  {
3451  qCS = 0.0;
3452  capCS = 0.0;
3453  }
3454  else
3455  {
3456  if ( vCS < 0.0 )
3457  {
3458  arg = 1.0 - vCS / model_.potSubst;
3459  sarg = exp( -model_.expSubst * log( arg ) );
3460 
3461  qCS = model_.potSubst * czCS * ( 1.0 - arg * sarg ) /
3462  ( 1.0 - model_.expSubst );
3463  capCS = czCS * sarg;
3464  }
3465  else
3466  {
3467  qCS = vCS * czCS * ( 1.0 + model_.expSubst * vCS / ( 2.0 *
3468  model_.potSubst ) );
3469  capCS = czCS * ( 1.0 + model_.expSubst * vCS / model_.potSubst );
3470  }
3471  }
3472 
3473  // Here things get a little confusing. Generally, this is a logical place
3474  // to calculate iB, iC, and iE. iC and iE include the excess phase current.
3475 
3476  // Doing the old excess phase calculation, for both new and old-DAE, out
3477  // of curiousity to see that they match. However, if running new-DAE, these
3478  // calculations will only be used in diagnostics, not the actual loads.
3479  double iEX_tmp = 0.0; double gEX_tmp = 0.0; double iC_tmp = 0.0;
3481  oldDAEExcessPhaseCalculation2 (iEX_tmp,gEX_tmp,iC_tmp);
3482 
3483  if (getDeviceOptions().newExcessPhase)
3484  {
3485  auxDAECalculations (); // iB, iC and iE calculated here.
3486 
3487  }
3488  else
3489  {
3490  // Do the iB, iC, and iE calculations for the old-DAE case here.
3491  double iEX = 0.0;
3492  double gEX = 0.0;
3493 
3494  iC = iC_tmp;
3495  iEX = iEX_tmp;
3496  gEX = gEX_tmp;
3497 
3498  iCE = ( iEX - iBC ) / qB;
3499  iC += iCE - iBC / tBetaR - iBCleak;
3500 
3501  iB = iBE / tBetaF + iBEleak + iBC / tBetaR + iBCleak;
3502  iE = -iC-iB;
3503 
3504  // These 3 derivatives depend upon excess phase terms, old-DAE version, so
3505  // they have to be set up here.
3506  diCEdvEp = invqB * (iCE * dqBdvEp - gEX);
3507  diCEdvCp = invqB * (iCE * dqBdvCp + gBC);
3508  diCEdvBp = invqB * (iCE * dqBdvBp + gEX - gBC);
3509  }
3510 
3511  // Some derivatives setup:
3512  // Emitter and Conductor conductances
3515 
3516  // Generation of gX for b-b' resistance
3517  double rBpr = model_.minBaseResist / AREA;
3518  double rBpi = model_.baseResist / AREA - rBpr;
3519  double xjrB = model_.baseCurrHalfResist * AREA;
3520 
3521  gX = rBpr + rBpi / qB;
3522 
3523  if (fabs(xjrB) > 0.0)
3524  {
3525  double arg1 = std::max(iB / xjrB, 1.0e-09);
3526  double arg2 = (-1.0 + sqrt( 1.0 + 14.59025 * arg1)) / 2.4317 / sqrt(arg1);
3527  arg1 = tan(arg2);
3528  gX = rBpr + 3.0 * rBpi * (arg1 - arg2) / arg2 / arg1 / arg1;
3529  }
3530 
3531  if (fabs(gX) > 0.0) gX = 1.0 / gX;
3532 
3533  diBrdvB = gX;
3534  diBrdvCp = 0.0;
3535  diBrdvEp = 0.0;
3536  diBrdvBp = -gX;
3537 
3538  gBEtot = gBE / tBetaF + gBEleak;
3539  gBCtot = gBC / tBetaR + gBCleak;
3540 
3541  return bsuccess;
3542 }
3543 
3544 //-----------------------------------------------------------------------------
3545 // Function : Instance::outputPlotFiles
3546 // Purpose :
3547 // Special Notes :
3548 // Scope : public
3549 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
3550 // Creation Date : 9/01/06
3551 //-----------------------------------------------------------------------------
3552 bool Instance::outputPlotFiles(bool force_final_output)
3553 {
3554  bool bsuccess = true;
3555 
3556  int i;
3557  std::ostringstream oss;
3558  oss << "Q_" << getName() << ".dat";
3559  std::string filename = oss.str();
3560 
3561  double time = getSolverState().currTime_;
3562  FILE *fp1;
3563 
3564  if (callsOutputPlot <= 0)
3565  {
3566  fp1 = fopen(filename.c_str(),"w");
3567  }
3568  else
3569  {
3570  fp1 = fopen(filename.c_str(),"a");
3571  }
3572 
3573  if (callsOutputPlot <= 0)
3574  {
3575  fprintf(fp1,
3576  " TITLE = \"Debug Excess Phase data: %s \"\n", getName().getEncodedName().c_str());
3577  }
3578 
3579  if (callsOutputPlot <= 0)
3580  {
3581  fprintf(fp1,"%s","\tVARIABLES = \"TIME (S)\",\n");
3582 
3583  fprintf(fp1,"%s","\t \"iBE/qB \",\n");
3584  fprintf(fp1,"%s","\t \"currCexbc \",\n");
3585  fprintf(fp1,"%s","\t \"lastCexbc \",\n");
3586  if (getDeviceOptions().newExcessPhase)
3587  {
3588  fprintf(fp1,"%s","\t \"i_fx \",\n");
3589  fprintf(fp1,"%s","\t \"di_fx \",\n");
3590  }
3591 
3592  fprintf(fp1,"%s","\tZONE F=POINT T=\"Excess Phase Data\"\n");
3593  }
3594 
3595  fprintf(fp1," %12.4e",time);
3596  fprintf(fp1," %12.4e",(iBE/qB));
3597  fprintf(fp1," %12.4e",currCexbc);
3598  fprintf(fp1," %12.4e",nextCexbc);
3599 
3600  if (getDeviceOptions().newExcessPhase)
3601  {
3602  double * solVec = extData.nextSolVectorRawPtr;
3603  double i_fx = solVec[li_Ifx];
3604  double di_fx = solVec[li_dIfx];
3605  fprintf(fp1," %12.4e",i_fx);
3606  fprintf(fp1," %12.4e",di_fx);
3607  }
3608 
3609  fprintf(fp1,"%s","\n");
3610 
3611  ++callsOutputPlot;
3612  fclose(fp1);
3613 
3614  return bsuccess;
3615 }
3616 
3617 //-----------------------------------------------------------------------------
3618 // Function : Model::processParams
3619 // Purpose :
3620 // Special Notes :
3621 // Scope : public
3622 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
3623 // Creation Date : 6/03/02
3624 //-----------------------------------------------------------------------------
3626 {
3627 
3628  if (!leakBECurrentGiven && c2Given)
3629  leakBECurrent = c2 * satCur;
3630 
3631  if (!leakBCCurrentGiven && c4Given)
3632  leakBCCurrent = c4 * satCur;
3633 
3634  if (!minBaseResistGiven)
3636 
3637  if (VAFgiven && ( earlyVoltF != 0.0 ) )
3638  invEarlyVoltF = 1.0 / earlyVoltF;
3639  else
3640  invEarlyVoltF = 0.0;
3641 
3642  if( IKFgiven && ( rollOffF != 0.0 ) )
3643  invRollOffF = 1.0 / rollOffF;
3644  else
3645  invRollOffF = 0.0;
3646 
3647  if( VARgiven && ( earlyVoltR != 0.0 ) )
3648  invEarlyVoltR = 1.0 / earlyVoltR;
3649  else
3650  invEarlyVoltR = 0.0;
3651 
3652  if( IKRgiven && ( rollOffR != 0.0 ) )
3653  invRollOffR = 1.0 / rollOffR;
3654  else
3655  invRollOffR = 0.0;
3656 
3657  if( collectorResist != 0.0 )
3659  else
3660  collectorConduct = 0;
3661 
3662  if( emitterResist != 0.0 )
3663  emitterConduct = 1.0 / emitterResist;
3664  else
3665  emitterConduct = 0;
3666 
3667  if( VTFgiven && ( transTimeFVBC != 0.0 ) )
3668  transTimeVBCFac = 1.0 / ( transTimeFVBC * 1.44 );
3669  else
3670  transTimeVBCFac = 0.0;
3671 
3672  double mpi = M_PI;
3673  excessPhaseFac = ( excessPhase / ( 180.0 / mpi ) ) * transTimeF;
3674 
3675  if( FCgiven )
3676  {
3677  if( depCapCoeff > 0.9999 )
3678  {
3679  depCapCoeff = 0.9999;
3680  Xyce::dout() << "Bad Depletion Capacitance Coefficient" << std::endl;
3681  }
3682  }
3683  else
3684  {
3685  depCapCoeff = 0.5;
3686  }
3687 
3688  double xfc = log( 1.0 - depCapCoeff );
3689 
3690  f2 = exp( ( 1.0 + juncExpBE ) * xfc );
3691  f3 = 1.0 - depCapCoeff * ( 1.0 + juncExpBE );
3692  f6 = exp( ( 1.0 + juncExpBC ) * xfc );
3693  f7 = 1.0 - depCapCoeff * ( 1.0 + juncExpBC );
3694 
3695  return true;
3696 }
3697 
3698 //----------------------------------------------------------------------------
3699 // Function : Model::processInstanceParams
3700 // Purpose :
3701 // Special Notes :
3702 // Scope : public
3703 // Creator : Dave Shirely, PSSI
3704 // Creation Date : 03/23/06
3705 //----------------------------------------------------------------------------
3707 {
3708 
3709  std::vector<Instance*>::iterator iter;
3710  std::vector<Instance*>::iterator first = instanceContainer.begin();
3711  std::vector<Instance*>::iterator last = instanceContainer.end();
3712 
3713  for (iter=first; iter!=last; ++iter)
3714  {
3715  (*iter)->processParams();
3716  }
3717 
3718  return true;
3719 }
3720 
3721 //-----------------------------------------------------------------------------
3722 // Function : Model::Model
3723 // Purpose : modelblock constructor
3724 // Special Notes :
3725 // Scope : public
3726 // Creator : Laura Boucheron
3727 // Creation Date : 7/12/00
3728 //-----------------------------------------------------------------------------
3730  const Configuration & configuration,
3731  const ModelBlock & MB,
3732  const FactoryBlock & factory_block)
3733  : DeviceModel(MB, configuration.getModelParameters(), factory_block),
3734  TYPE(1),
3735  TNOM(300.0),
3736  satCur(1.0e-16),
3737  betaF(100.0),
3738  BFgiven(false),
3739  BFMgiven(false),
3740  emissionCoeffF(1.0),
3741  earlyVoltF(1e99),
3742  VAgiven(false),
3743  VAFgiven(false),
3744  VBFgiven(false),
3745  rollOffF(1e99),
3746  IKFgiven(false),
3747  IKgiven(false),
3748  JBFgiven(false),
3749  leakBECurrent(0.0),
3750  leakBEEmissionCoeff(1.5),
3751  NEgiven(false),
3752  NLEgiven(false),
3753  betaR(1.0),
3754  BRgiven(false),
3755  BRMgiven(false),
3756  emissionCoeffR(1.0),
3757  earlyVoltR(1e99),
3758  VARgiven(false),
3759  VBgiven(false),
3760  VRBgiven(false),
3761  BVgiven(false),
3762  rollOffR(1e99),
3763  IKRgiven(false),
3764  JBRgiven(false),
3765 
3766  leakBCCurrent(0.0),
3767  leakBCEmissionCoeff(2.0),
3768  baseResist(0.0),
3769  baseCurrHalfResist(0.0),
3770  IRBgiven(false),
3771  JRBgiven(false),
3772  IOBgiven(false),
3773  minBaseResist(baseResist),
3774  emitterResist(0.0),
3775  collectorResist(0.0),
3776  depCapBE(0.0),
3777  potBE(0.75),
3778  VJEgiven(false),
3779  PEgiven(false),
3780 
3781  juncExpBE(0.33),
3782  MJEgiven(false),
3783  MEgiven(false),
3784 
3785  transTimeF(0.0),
3786  transTimeBiasCoeffF(0.0),
3787  transTimeFVBC(1.e99),
3788  transTimeHighCurrF(0.0),
3789  ITFgiven(false),
3790  JTFgiven(false),
3791  VTFgiven(false),
3792 
3793  excessPhase(0.0),
3794  depCapBC(0.0),
3795  potBC(0.75),
3796  VJCgiven(false),
3797  PCgiven(false),
3798 
3799  juncExpBC(0.33),
3800  MJCgiven(false),
3801  MCgiven(false),
3802 
3803  baseFracBCCap(1.0),
3804  XCJCgiven(false),
3805  CDISgiven(false),
3806  transTimeR(0.0),
3807  CJS(0.0),
3808  CJSgiven(false),
3809  CCSgiven(false),
3810  CSUBgiven(false),
3811  potSubst(0.75),
3812  VJSgiven(false),
3813  PSgiven(false),
3814  PSUBgiven(false),
3815 
3816  expSubst(0.0),
3817  MJSgiven(false),
3818  MSgiven(false),
3819  ESUBgiven(false),
3820 
3821  betaExp(0.0),
3822  XTBgiven(false),
3823  TBgiven(false),
3824  TCBgiven(false),
3825 
3826  energyGap(1.11),
3827  tempExpIS(3.0),
3828  XTIgiven(false),
3829  PTgiven(false),
3830 
3831  depCapCoeff(0.5),
3832  fNCoeff(0.0),
3833  fNExp(1.0),
3834  c2(0.0),
3835  c4(0.0),
3836  rollOffExp(0.5),
3837  FCgiven(false),
3838  NKgiven(false),
3839  NKFgiven(false),
3840 
3841  leakBCCurrentGiven(false),
3842  JLCgiven(false),
3843  leakBECurrentGiven(false),
3844  JLEgiven(false),
3845  minBaseResistGiven(false),
3846  c2Given(false),
3847  c4Given(false)
3848 {
3849  // Default value is type=1 (NPN) so only check for pnp
3850  if (getType() == "pnp" || getType() == "PNP")
3851  {
3852  TYPE = -1;
3853  }
3854 
3855  ////////////////////////////////////////////////////////////////////////////////
3856  // trap for redunantly specified parameters (some can be specified by several different names)
3857  // forward beta (BF/BFM)
3858  if (BFgiven && BFMgiven)
3859  {
3860  UserError0(*this) << "Both BF and BFM are set, which is redundant.";
3861  }
3862  if (BFgiven || BFMgiven)
3863  {
3864  BFgiven = true; // this is the given flag that is actually used later.
3865  }
3866 
3867  // reverse beta (Re/BRM)
3868  if (BRgiven && BRMgiven)
3869  {
3870  UserError0(*this) << "Both BR and BRM are set, which is redundant.";
3871  }
3872  if (BRgiven || BRMgiven)
3873  {
3874  BRgiven = true; // this is the given flag that is actually used later.
3875  }
3876 
3877  // forward early voltage (VA/VAF/VBF)
3878  int VAFgivenCount = 0;
3879  VAFgivenCount += VAgiven?1:0;
3880  VAFgivenCount += VAFgiven?1:0;
3881  VAFgivenCount += VBFgiven?1:0;
3882  if (VAFgivenCount > 1)
3883  {
3884  UserError0(*this) << "The forward early voltage is set more than once. VA, VAF and VBF are aliases.";
3885  }
3886  if (VAFgivenCount > 0)
3887  {
3888  VAFgiven = true; // this is the given flag that is actually used later.
3889  }
3890 
3891  // reverse early voltage (VAR/VB/VRB/BV)
3892  int VARgivenCount = 0;
3893  VARgivenCount += VARgiven?1:0;
3894  VARgivenCount += VRBgiven?1:0;
3895  VARgivenCount += VBgiven?1:0;
3896  VARgivenCount += BVgiven?1:0;
3897  if (VARgivenCount > 1)
3898  {
3899  UserError0(*this) << "The reverse early voltage is set more than once. VAR,VB,VRB and BV are aliases.";
3900  }
3901  if (VARgivenCount > 0)
3902  {
3903  VARgiven = true; // this is the given flag that is actually used later.
3904  }
3905 
3906  // high current roll-off (IKF/IK/JBF)
3907  int IKFgivenCount = 0;
3908  IKFgivenCount += IKgiven?1:0;
3909  IKFgivenCount += IKFgiven?1:0;
3910  IKFgivenCount += JBFgiven?1:0;
3911  if (IKFgivenCount > 1)
3912  {
3913  UserError0(*this) << "High current roll-off is set more than once (IKF, JBF or IK).";
3914  }
3915  if (IKFgivenCount > 0)
3916  {
3917  IKFgiven = true; // this is the given flag that is actually used later.
3918  }
3919 
3920  // reverse high current roll-off (IKR/JBR)
3921  if (IKRgiven && JBRgiven)
3922  {
3923  UserError0(*this) << "Both IKR and JBRgiven are set, which is redundant.";
3924  }
3925  if (IKRgiven || JBRgiven)
3926  {
3927  IKRgiven = true; // this is the flag actually used later.
3928  }
3929 
3930  // BE leakage saturation current (ISE/JLE). C2 is sometimes thougt of as equivalent,
3931  // but it is not.
3933  {
3934  UserError0(*this) << "Both JLE and ISE are set, which is redundant.";
3935  }
3937  {
3938  leakBECurrentGiven = true; // this is the flag actually used later.
3939  }
3940 
3941  // BC leakage saturation current (ISC/JLC). C4 is sometimes thougt of as equivalent,
3942  // but it is not.
3944  {
3945  UserError0(*this) << "Both JLC and ISC are set, which is redundant.";
3946  }
3948  {
3949  leakBCCurrentGiven = true; // this is the flag actually used later.
3950  }
3951 
3952  // leakage emission coefficient (NE/NLE)
3953  if (NLEgiven && NEgiven)
3954  {
3955  UserError0(*this) << "Both NLE and NE are set, which is redundant.";
3956  }
3957  if (NLEgiven || NEgiven)
3958  {
3959  NEgiven = true; // this is the flag actually used later.
3960  }
3961 
3962  // BE exponential factor (MJE/ME)
3963  if (MJEgiven && MEgiven)
3964  {
3965  UserError0(*this) << " Both MJE and ME are set, which is redundant.";
3966  }
3967  if (MJEgiven || MEgiven)
3968  {
3969  MJEgiven = true; // this is the flag actually used later.
3970  }
3971 
3972  // BC exponential factor (MJC/MC)
3973  if (MJCgiven && MCgiven)
3974  {
3975  UserError0(*this) << "Both MJC and MC are set, which is redundant.";
3976  }
3977  if (MJCgiven || MCgiven)
3978  {
3979  MJCgiven = true; // this is the flag actually used later.
3980  }
3981 
3982  // zero-bias coll-subst capacitance (CJS/CCS/CSUB)
3983  int CJSgivenCount = 0;
3984  CJSgivenCount += CJSgiven?1:0;
3985  CJSgivenCount += CCSgiven?1:0;
3986  CJSgivenCount += CSUBgiven?1:0;
3987  if (CJSgivenCount > 1)
3988  {
3989  UserError0(*this) << "The zero-bias collector-substrate capacitance (CJS, CCS or CSUB) is set more than once.";
3990  }
3991  if (CJSgivenCount > 0)
3992  {
3993  CJSgiven = true; // this is the given flag that is actually used later.
3994  }
3995 
3996  // current for 1/2 base resist. (IRB/JRB/IOB)
3997  int IRBgivenCount = 0;
3998  IRBgivenCount += IRBgiven?1:0;
3999  IRBgivenCount += JRBgiven?1:0;
4000  IRBgivenCount += IOBgiven?1:0;
4001  if (IRBgivenCount > 1)
4002  {
4003  UserError0(*this) << "The current for 1/2 base resistance (IRB, JRB or IOB) is set more than once.";
4004  }
4005  if (IRBgivenCount > 0)
4006  {
4007  IRBgiven = true; // this is the given flag that is actually used later.
4008  }
4009 
4010  // BE built-in potential (VJE/PE)
4011  if (VJEgiven && PEgiven)
4012  {
4013  UserError0(*this) << "The BE built-in potential (VJE or PE) is set more than once.";
4014  }
4015  if (VJEgiven && PEgiven)
4016  {
4017  VJEgiven = true; // this is the given flag that is actually used later.
4018  }
4019 
4020  // BC built-in potential (VJC/PC)
4021  if (VJCgiven && PCgiven)
4022  {
4023  UserError0(*this) << "The BC built-in potential (VJC or PC) is set more than once.";
4024  }
4025  if (VJCgiven && PCgiven)
4026  {
4027  VJCgiven = true; // this is the given flag that is actually used later.
4028  }
4029 
4030  // fraction of BC capacitance to int. base node (XCJC/CDIS)
4031  if (XCJCgiven && CDISgiven)
4032  {
4033  UserError0(*this) << "XCJC and CDIS are both set (they are aliases).";
4034  }
4035  if (XCJCgiven && CDISgiven)
4036  {
4037  XCJCgiven = true; // this is the given flag that is actually used later.
4038  }
4039 
4040  // substrate junction built-in potential (VJS/PS/PSUB)
4041  int VJSgivenCount = 0;
4042  VJSgivenCount += PSgiven?1:0;
4043  VJSgivenCount += VJSgiven?1:0;
4044  VJSgivenCount += PSUBgiven?1:0;
4045  if (VJSgivenCount > 1)
4046  {
4047  UserError0(*this) << "The Substrate built-in potential is set more than once. PS, VJS and PSUB are aliases.";
4048  }
4049  if (VJSgivenCount > 0)
4050  {
4051  VJSgiven = true; // this is the given flag that is actually used later.
4052  }
4053 
4054  // substrate junction built-in potential (MJS/MS/ESUB)
4055  int MJSgivenCount = 0;
4056  MJSgivenCount += MSgiven?1:0;
4057  MJSgivenCount += MJSgiven?1:0;
4058  MJSgivenCount += ESUBgiven?1:0;
4059  if (MJSgivenCount > 1)
4060  {
4061  UserError0(*this) << "The Substrate p-n grading factor is set more than once. MS, MJS and ESUB are aliases.";
4062  }
4063  if (MJSgivenCount > 0)
4064  {
4065  MJSgiven = true; // this is the given flag that is actually used later.
4066  }
4067 
4068  // (ITF/JTF)
4069  if (ITFgiven && JTFgiven)
4070  {
4071  UserError0(*this) << "ITF and JTF are both set (they are aliases).";
4072  }
4073  if (ITFgiven && JTFgiven)
4074  {
4075  ITFgiven = true; // this is the given flag that is actually used later.
4076  }
4077 
4078  // (NK/NKF)
4079  if (NKgiven && NKFgiven)
4080  {
4081  UserError0(*this) << "NK and NKF are both set (they are aliases).";
4082  }
4083  if (NKgiven && NKFgiven)
4084  {
4085  NKgiven = true; // this is the given flag that is actually used later.
4086  }
4087 
4088  // beta temperature exponent (XTB/TB/TCB)
4089  int XTBgivenCount = 0;
4090  XTBgivenCount += TBgiven?1:0;
4091  XTBgivenCount += XTBgiven?1:0;
4092  XTBgivenCount += TCBgiven?1:0;
4093  if (XTBgivenCount > 1)
4094  {
4095  UserError0(*this) << "The beta temperature coefficient is set more than once. TB, XTB and TCB are aliases.";
4096  }
4097  if (XTBgivenCount > 0)
4098  {
4099  XTBgiven = true; // this is the given flag that is actually used later.
4100  }
4101 
4102 
4103  // (PT/XTI)
4104  if (PTgiven && XTIgiven)
4105  {
4106  UserError0(*this) << "PT and XTI are both set (they are aliases).";
4107  }
4108  if (PTgiven && XTIgiven)
4109  {
4110  XTIgiven = true; // this is the given flag that is actually used later.
4111  }
4112 
4113  // end of redundant parameter traps
4114  ////////////////////////////////////////////////////////////////////////////////
4115 
4116 
4117  // Set params to constant default values:
4118  setDefaultParams ();
4119 
4120  // Set params according to .model line and constant defaults from metadata:
4121  setModParams (MB.params);
4122 
4123  // Set any non-constant parameter defaults:
4124  if (!given("TNOM"))
4126 
4127  if( !NKgiven)
4128  rollOffExp = 0.5;
4129 
4130  // Calculate any parameters specified as expressions:
4132 
4133  // calculate dependent (ie computed) params and check for errors:
4134  processParams ();
4135 }
4136 
4137 //-----------------------------------------------------------------------------
4138 // Function : Model::~Model
4139 // Purpose : destructor
4140 // Special Notes :
4141 // Scope : public
4142 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
4143 // Creation Date : 3/16/00
4144 //-----------------------------------------------------------------------------
4146 {
4147  std::vector<Instance*>::iterator iterI;
4148  std::vector<Instance*>::iterator firstI = instanceContainer.begin ();
4149  std::vector<Instance*>::iterator lastI = instanceContainer.end ();
4150 
4151  // loop over instances:
4152  for (iterI = firstI; iterI != lastI; ++iterI)
4153  {
4154  delete (*iterI);
4155  }
4156 
4157 }
4158 
4159 //-----------------------------------------------------------------------------
4160 // Function : Model::printOutInstances
4161 // Purpose : debugging tool.
4162 // Special Notes :
4163 // Scope : public
4164 // Creator : Laura Boucheron
4165 // Creation Date : 7/11/00
4166 //-----------------------------------------------------------------------------
4167 std::ostream &Model::printOutInstances(std::ostream &os) const
4168 {
4169  std::vector<Instance*>::const_iterator iter;
4170  std::vector<Instance*>::const_iterator first = instanceContainer.begin();
4171  std::vector<Instance*>::const_iterator last = instanceContainer.end();
4172 
4173  int i;
4174  os << " name modelName Parameters" << std::endl;
4175  for (i = 0, iter = first; iter != last; ++iter, ++i)
4176  {
4177  os << " " << i << ": " << (*iter)->getName() << " ";
4178  os << getName();
4179 
4180  os << std::endl;
4181  os << " AREA = " << (*iter)->AREA << std::endl;
4182  os << " icVBE = " << (*iter)->icVBE << std::endl;
4183  os << " icVCE = " << (*iter)->icVCE << std::endl;
4184  os << " TEMP = " << (*iter)->TEMP << std::endl;
4185  os << " OFF = " << (*iter)->OFF << std::endl;
4186 
4187  os << std::endl;
4188  }
4189 
4190  os << std::endl;
4191 
4192  return os;
4193 }
4194 
4195 //-----------------------------------------------------------------------------
4196 // Function : Model::forEachInstance
4197 // Purpose :
4198 // Special Notes :
4199 // Scope : public
4200 // Creator : David Baur
4201 // Creation Date : 2/4/2014
4202 //-----------------------------------------------------------------------------
4203 /// Apply a device instance "op" to all instances associated with this
4204 /// model
4205 ///
4206 /// @param[in] op Operator to apply to all instances.
4207 ///
4208 ///
4209 void Model::forEachInstance(DeviceInstanceOp &op) const /* override */
4210 {
4211  for (std::vector<Instance *>::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
4212  op(*it);
4213 }
4214 
4215 
4216 //-----------------------------------------------------------------------------
4217 // BJT Master functions:
4218 //-----------------------------------------------------------------------------
4219 
4220 //-----------------------------------------------------------------------------
4221 // Function : Master::updateState
4222 // Purpose :
4223 // Special Notes :
4224 // Scope : public
4225 // Creator : Eric Keiter, SNL
4226 // Creation Date : 11/26/08
4227 //-----------------------------------------------------------------------------
4228 bool Master::updateState (double * solVec, double * staVec, double * stoVec)
4229 {
4230  bool bsuccess = true;
4231 
4232  for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it)
4233  {
4234  Instance & bi = *(*it);
4235 
4236  double * stoVec = bi.extData.nextStoVectorRawPtr;
4237 
4238  // Do the bulk of the work in updateIntermediateVars:
4239  bool btmp = bi.updateIntermediateVars ();
4240  bsuccess = bsuccess && btmp;
4241 
4242  // save voltage drops
4243  stoVec[bi.li_storevBE] = bi.vBE;
4244  stoVec[bi.li_storevBC] = bi.vBC;
4245  stoVec[bi.li_store_capeqCB] = bi.capeqCB;
4246 
4247  staVec[bi.li_qstateBEdiff] = bi.qBEdiff;
4248  staVec[bi.li_qstateBEdep] = bi.qBEdep;
4249  staVec[bi.li_qstateBCdiff] = bi.qBCdiff;
4250  staVec[bi.li_qstateBCdep] = bi.qBCdep;
4251  staVec[bi.li_qstateBX] = bi.qBX;
4252  staVec[bi.li_qstateCS] = bi.qCS;
4253 
4254 
4255  // if this is the first newton step of the first time step
4256  // of the transient simulation, we need to enforce that the
4257  // time derivatives w.r.t. charge are zero. This is to maintain 3f5
4258  // compatibility. ERK.
4259 
4260  if (!(getSolverState().dcopFlag) && (getSolverState().initTranFlag_) && getSolverState().newtonIter==0)
4261  {
4262  double * currStaVec = (bi.extData.currStaVectorRawPtr);
4263 
4264  currStaVec[bi.li_qstateBEdiff] = bi.qBEdiff;
4265  currStaVec[bi.li_qstateBEdep] = bi.qBEdep;
4266  currStaVec[bi.li_qstateBCdiff] = bi.qBCdiff;
4267  currStaVec[bi.li_qstateBCdep] = bi.qBCdep;
4268  currStaVec[bi.li_qstateBX] = bi.qBX;
4269  currStaVec[bi.li_qstateCS] = bi.qCS;
4270  }
4271  }
4272 
4273  return bsuccess;
4274 }
4275 
4276 //-----------------------------------------------------------------------------
4277 // Function : Master::updateSecondaryState
4278 // Purpose :
4279 // Special Notes :
4280 // Scope : public
4281 // Creator : Eric Keiter, SNL
4282 // Creation Date : 11/26/08
4283 //-----------------------------------------------------------------------------
4284 bool Master::updateSecondaryState ( double * staDerivVec, double * stoVec )
4285 {
4286  bool bsuccess = true;
4287 
4288  for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it)
4289  {
4290  Instance & bi = *(*it);
4291 
4292  // Now that the state vector for time=0 is up-to-date, get the derivative
4293  // with respect to time of the charge, to obtain the best estimate for
4294  // the current in the capacitor.
4295 
4296  bi.iBEdiff = staDerivVec[bi.li_qstateBEdiff];
4297  bi.iBEdep = staDerivVec[bi.li_qstateBEdep ];
4298  bi.iCS = staDerivVec[bi.li_qstateCS ];
4299  bi.iBCdiff = staDerivVec[bi.li_qstateBCdiff];
4300  bi.iBCdep = staDerivVec[bi.li_qstateBCdep ];
4301  bi.iBX = staDerivVec[bi.li_qstateBX ];
4302  }
4303 
4304  return bsuccess;
4305 }
4306 
4307 //-----------------------------------------------------------------------------
4308 // Function : Master::loadDAEVectors
4309 // Purpose :
4310 // Special Notes :
4311 // Scope : public
4312 // Creator : Eric Keiter, SNL
4313 // Creation Date : 11/26/08
4314 //-----------------------------------------------------------------------------
4315 bool Master::loadDAEVectors (double * solVec, double * fVec, double *qVec, double * bVec, double * storeLeadF, double * storeLeadQ, double * leadF, double * leadQ, double * junctionV)
4316 {
4317  for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it)
4318  {
4319  Instance & bi = *(*it);
4320 
4321  double td = bi.model_.excessPhaseFac;
4322  double vbe_diff = bi.vBE - bi.vBE_orig;
4323  double vbc_diff = bi.vBC - bi.vBC_orig;
4324  double vce_diff = vbe_diff - vbc_diff;
4325 
4326  // F-vector:
4327  fVec[bi.li_Coll] -= -bi.vCCp * bi.gCpr;
4328  fVec[bi.li_Base] -= -bi.vBBp * bi.gX;
4329  fVec[bi.li_Emit] -= -bi.vEEp * bi.gEpr;
4330  fVec[bi.li_CollP] -= bi.vCCp * bi.gCpr + bi.model_.TYPE * ( - bi.iC );
4331  fVec[bi.li_BaseP] -= bi.vBBp * bi.gX - bi.model_.TYPE * ( bi.iB );
4332  fVec[bi.li_EmitP] -= bi.vEEp * bi.gEpr + bi.model_.TYPE * ( - bi.iE );
4333 
4334  // excess phase ERK-dcop.
4335  double i_fx = 0.0;
4336  double di_fx = 0.0;
4337 
4339  //if (td != 0 && getDeviceOptions().newExcessPhase)
4340  {
4341  i_fx = solVec[bi.li_Ifx];
4342  di_fx = solVec[bi.li_dIfx];
4343 
4344  if (td != 0)
4345  {
4346  if (!(getSolverState().dcopFlag) )
4347  {
4348  // omega0 = 1/td;
4349  fVec[bi.li_Ifx] += - di_fx;
4350  fVec[bi.li_dIfx] += 3 * di_fx*td + 3*i_fx -3 * bi.iBE / bi.qB;
4351  }
4352  else
4353  {
4354  fVec[bi.li_Ifx] += i_fx -bi.iBE/bi.qB;
4355  fVec[bi.li_dIfx] = 0.0;
4356  }
4357  }
4358  else
4359  {
4360  fVec[bi.li_Ifx] += i_fx;
4361  fVec[bi.li_dIfx] += di_fx;
4362  }
4363  }
4364 
4365  // Q-vector:
4366  qVec[bi.li_Base] -= - bi.model_.TYPE * bi.qBX;
4367  qVec[bi.li_Subst] -= -bi.model_.TYPE * bi.qCS;
4368  qVec[bi.li_CollP] -= bi.model_.TYPE * ( bi.qCS + bi.qBX + bi.qBCdep + bi.qBCdiff );
4369  qVec[bi.li_BaseP] -= -bi.model_.TYPE * ( bi.qBEdep + bi.qBEdiff + bi.qBCdep + bi.qBCdiff );
4370  qVec[bi.li_EmitP] -= bi.model_.TYPE*( bi.qBEdep + bi.qBEdiff );
4371 
4372  // excess phase ERK-dcop
4373  if (td != 0 && getDeviceOptions().newExcessPhase)
4374  {
4375  qVec[bi.li_Ifx] += solVec[bi.li_Ifx];
4376 
4377  if (!(getSolverState().dcopFlag) )
4378  {
4379  qVec[bi.li_dIfx] += solVec[bi.li_dIfx]*td*td;
4380  }
4381  else
4382  {
4383  qVec[bi.li_dIfx] = 0.0;
4384  }
4385  }
4386 
4387  // voltage limiter terms:
4389  {
4390  double Cp_Jdxp_f(0.0), Bp_Jdxp_f(0.0), Ep_Jdxp_f(0.0),
4391  dIfx_Jdxp_f(0.0 ), Ifx_Jdxp_f(0.0 ),
4392  Cp_Jdxp_q ( 0.0), Ep_Jdxp_q ( 0.0), Bp_Jdxp_q ( 0.0);
4393 
4394  // F-limiters:
4395  if (!bi.origFlag || bi.offFlag)
4396  {
4397  Cp_Jdxp_f = + bi.diCEdvBp * vbe_diff
4398  + bi.diCEdvCp * vce_diff
4399  - bi.gBCtot * vbc_diff;
4400 
4401  Cp_Jdxp_f *= bi.model_.TYPE;
4402 
4403  Bp_Jdxp_f = bi.gBEtot * vbe_diff + bi.gBCtot * vbc_diff;
4404  Bp_Jdxp_f *= bi.model_.TYPE;
4405 
4406  Ep_Jdxp_f = - bi.diCEdvCp * vce_diff - (bi.diCEdvBp + bi.gBEtot) * vbe_diff;
4407  Ep_Jdxp_f *= bi.model_.TYPE;
4408 
4409  // ERK-dcop.
4410  if ( td != 0 && getDeviceOptions().newExcessPhase )
4411  {
4412  if ( !(getSolverState().dcopFlag) )
4413  {
4414  dIfx_Jdxp_f = -3 *( bi.diBEdvBp*vbe_diff + bi.diBEdvCp * vce_diff);
4415  dIfx_Jdxp_f *= bi.model_.TYPE;
4416  }
4417  else
4418  {
4419  Ifx_Jdxp_f = ( bi.diBEdvBp*vbe_diff + bi.diBEdvCp * vce_diff);
4420  Ifx_Jdxp_f *= bi.model_.TYPE;
4421  }
4422  }
4423  }
4424 
4425  double * dFdxdVp = bi.extData.dFdxdVpVectorRawPtr;
4426  dFdxdVp[bi.li_CollP] += Cp_Jdxp_f;
4427  dFdxdVp[bi.li_BaseP] += Bp_Jdxp_f;
4428  dFdxdVp[bi.li_EmitP] += Ep_Jdxp_f;
4429 
4430  // ERK-dcop.
4431  if ( td != 0 && getDeviceOptions().newExcessPhase )
4432  {
4433  if ( !(getSolverState().dcopFlag) )
4434  {
4435  dFdxdVp[bi.li_dIfx] += dIfx_Jdxp_f;
4436  }
4437  else
4438  {
4439  dFdxdVp[bi.li_Ifx] += Ifx_Jdxp_f;
4440  }
4441  }
4442 
4443  // Q-limiters:
4444  if (!bi.origFlag || bi.offFlag)
4445  {
4446  Cp_Jdxp_q = -(bi.capBCdep + bi.capBCdiff)*vbc_diff;
4447  Cp_Jdxp_q *= bi.model_.TYPE;
4448 
4449  Bp_Jdxp_q = (bi.capBEdep + bi.capBEdiff)*vbe_diff
4450  + (bi.capBCdiff + bi.capBCdep + bi.capeqCB) *vbc_diff;
4451  Bp_Jdxp_q *= bi.model_.TYPE;
4452 
4453  Ep_Jdxp_q = - bi.capeqCB * vbc_diff - (bi.capBEdiff + bi.capBEdep)* vbe_diff;
4454  Ep_Jdxp_q *= bi.model_.TYPE;
4455  }
4456 
4457  double * dQdxdVp = bi.extData.dQdxdVpVectorRawPtr;
4458  dQdxdVp[bi.li_CollP] += Cp_Jdxp_q;
4459  dQdxdVp[bi.li_BaseP] += Bp_Jdxp_q;
4460  dQdxdVp[bi.li_EmitP] += Ep_Jdxp_q;
4461  }
4462 
4463  if( bi.loadLeadCurrent )
4464  {
4465  storeLeadQ[bi.li_store_dev_ic] = -bi.model_.TYPE * ( bi.qCS + bi.qBX + bi.qBCdep + bi.qBCdiff );
4466  storeLeadQ[bi.li_store_dev_ib] = bi.model_.TYPE * ( bi.qBX + bi.qBEdep + bi.qBEdiff + bi.qBCdep + bi.qBCdiff );
4467  storeLeadQ[bi.li_store_dev_ie] = -bi.model_.TYPE*( bi.qBEdep + bi.qBEdiff );
4468  storeLeadQ[bi.li_store_dev_is] = bi.model_.TYPE * bi.qCS;
4469 
4470  storeLeadF[bi.li_store_dev_ic] = bi.model_.TYPE * ( bi.iC );
4471  storeLeadF[bi.li_store_dev_is] = 0;
4472  storeLeadF[bi.li_store_dev_ie] = bi.model_.TYPE * ( bi.iE );
4473  storeLeadF[bi.li_store_dev_ib] = bi.model_.TYPE * ( bi.iB );
4474 
4475 
4476  leadQ[bi.li_branch_dev_ic] = -bi.model_.TYPE * ( bi.qCS + bi.qBX + bi.qBCdep + bi.qBCdiff );
4477  leadQ[bi.li_branch_dev_ib] = bi.model_.TYPE * ( bi.qBX + bi.qBEdep + bi.qBEdiff + bi.qBCdep + bi.qBCdiff );
4478  leadQ[bi.li_branch_dev_ie] = -bi.model_.TYPE*( bi.qBEdep + bi.qBEdiff );
4479  leadQ[bi.li_branch_dev_is] = bi.model_.TYPE * bi.qCS;
4480 
4481  leadF[bi.li_branch_dev_ic] = bi.model_.TYPE * ( bi.iC );
4482  leadF[bi.li_branch_dev_is] = 0;
4483  leadF[bi.li_branch_dev_ie] = bi.model_.TYPE * ( bi.iE );
4484  leadF[bi.li_branch_dev_ib] = bi.model_.TYPE * ( bi.iB );
4485 
4486  junctionV[bi.li_branch_dev_ic] = solVec[bi.li_Coll] - solVec[bi.li_Emit];
4487  junctionV[bi.li_branch_dev_is] = 0.0 ; // solVec[bi.li_Subst] - solVec[bi.li_Base];
4488  junctionV[bi.li_branch_dev_ib] = solVec[bi.li_Base] - solVec[bi.li_Emit];
4489  junctionV[bi.li_branch_dev_ie] = 0.0 ; // solVec[bi.li_Emit] - solVec[bi.li_Base];
4490 
4491  }
4492 
4493  }
4494 
4495  return true;
4496 }
4497 
4498 //-----------------------------------------------------------------------------
4499 // Function : Master::loadDAEMatrices
4500 // Purpose :
4501 // Special Notes :
4502 // Scope : public
4503 // Creator : Eric Keiter, SNL
4504 // Creation Date : 11/26/08
4505 //-----------------------------------------------------------------------------
4506 bool Master::loadDAEMatrices (Linear::Matrix & dFdx, Linear::Matrix & dQdx)
4507 {
4508  for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it)
4509  {
4510  Instance & bi = *(*it);
4511 
4512  double td = bi.model_.excessPhaseFac;
4513 
4514 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
4515  // F-matrix:
4516 
4517  *bi.f_CollEquCollNodePtr += bi.gCpr;
4518  *bi.f_CollEquCollPNodePtr -= bi.gCpr;
4519  *bi.f_BaseEquBaseNodePtr += bi.diBrdvB;
4520  *bi.f_BaseEquCollPNodePtr += bi.diBrdvCp;
4521  *bi.f_BaseEquBasePNodePtr += bi.diBrdvBp;
4522  *bi.f_BaseEquEmitPNodePtr += bi.diBrdvEp;
4523  *bi.f_EmitEquEmitNodePtr += bi.gEpr;
4524  *bi.f_EmitEquEmitPNodePtr -= bi.gEpr;
4525  *bi.f_CollPEquCollNodePtr -= bi.gCpr;
4526  *bi.f_CollPEquCollPNodePtr +=bi.diCEdvCp + bi.gBCtot + bi.gCpr;
4527  *bi.f_CollPEquBasePNodePtr += bi.diCEdvBp - bi.gBCtot;
4528  *bi.f_CollPEquEmitPNodePtr += bi.diCEdvEp;
4529 
4530  // excess phase terms. ERK-dcop
4531  if ( td != 0 && getDeviceOptions().newExcessPhase && !(getSolverState().dcopFlag) )
4532  {
4533  *bi.f_CollPEquIfxNodePtr += 1.0 * bi.model_.TYPE;
4534  }
4535  *bi.f_BasePEquBaseNodePtr -= bi.diBrdvB;
4536  *bi.f_BasePEquCollPNodePtr += -bi.diBrdvCp - bi.gBCtot;
4537  *bi.f_BasePEquBasePNodePtr += -bi.diBrdvBp + bi.gBEtot + bi.gBCtot;
4538  *bi.f_BasePEquEmitPNodePtr += -bi.diBrdvEp - bi.gBEtot;
4539  *bi.f_EmitPEquEmitNodePtr -= bi.gEpr;
4540  *bi.f_EmitPEquCollPNodePtr += -bi.diCEdvCp;
4541  *bi.f_EmitPEquBasePNodePtr += - bi.diCEdvBp - bi.gBEtot;
4542 
4543  // ERK Note: -bi.diCEdvEp should equal + bi.diCEdvBp + bi.diCEdvCp. In the
4544  // original old-DAE form, + bi.diCEdvBp + bi.diCEdvCp is used. In
4545  // the more recent new-DAE form, we've used bi.diCEdvEp, but it sometimes
4546  // results in subtle differences between old- and new-DAE jacobians.
4547  // This should matter, but .....
4548  *bi.f_EmitPEquEmitPNodePtr += bi.gBEtot + bi.gEpr + bi.diCEdvBp + bi.diCEdvCp; // this is a test.
4549  //+= bi.gBEtot + bi.gEpr - bi.diCEdvEp;
4550 
4551  // excess phase terms. ERK-dcop
4552  if ( td != 0 && getDeviceOptions().newExcessPhase && !(getSolverState().dcopFlag) )
4553  {
4554  *bi.f_EmitPEquIfxNodePtr += -1.0 * bi.model_.TYPE;
4555  }
4556 
4557  // excess phase terms. ERK-dcop
4559  {
4560  if ( td != 0 )
4561  {
4562  if ( !(getSolverState().dcopFlag) )
4563  {
4564  *bi.f_IfxEqudIfxNodePtr += -1;
4565 
4566  *bi.f_dIfxEquCollPNodePtr += -3*bi.diBEdvCp * bi.model_.TYPE;
4567  *bi.f_dIfxEquBasePNodePtr += -3*bi.diBEdvBp * bi.model_.TYPE;
4568  *bi.f_dIfxEquEmitPNodePtr += -3*bi.diBEdvEp * bi.model_.TYPE;
4569  *bi.f_dIfxEqudIfxNodePtr += 3* td;
4570  *bi.f_dIfxEquIfxNodePtr += 3;
4571  }
4572  else
4573  {
4574  *bi.f_IfxEquCollPNodePtr += -bi.diBEdvCp * bi.model_.TYPE;
4575  *bi.f_IfxEquBasePNodePtr += -bi.diBEdvBp * bi.model_.TYPE;
4576  *bi.f_IfxEquEmitPNodePtr += -bi.diBEdvEp * bi.model_.TYPE;
4577 
4578  *bi.f_IfxEquIfxNodePtr+= 1;
4579  *bi.f_dIfxEqudIfxNodePtr += 1;
4580  }
4581  }
4582  else
4583  {
4584  *bi.f_IfxEquIfxNodePtr += 1;
4585  *bi.f_dIfxEqudIfxNodePtr += 1;
4586  }
4587  }
4588 
4589  // Q-matrix:
4590 
4591  *bi.q_BaseEquBaseNodePtr += bi.capBX;
4592  *bi.q_BaseEquCollPNodePtr += -bi.capBX;
4593  *bi.q_SubstEquSubstNodePtr += bi.capCS;
4594  *bi.q_SubstEquCollPNodePtr -= bi.capCS;
4595  *bi.q_CollPEquBaseNodePtr -= bi.capBX;
4596  *bi.q_CollPEquSubstNodePtr -= bi.capCS;
4597  *bi.q_CollPEquCollPNodePtr += bi.capCS + bi.capBX + bi.capBCdep + bi.capBCdiff;
4598  *bi.q_CollPEquBasePNodePtr += -bi.capBCdep - bi.capBCdiff;
4599  *bi.q_BasePEquCollPNodePtr += -bi.capBCdiff - bi.capBCdep - bi.capeqCB;
4600  *bi.q_BasePEquBasePNodePtr += bi.capBEdiff + bi.capBEdep + bi.capBCdiff + bi.capBCdep + bi.capeqCB;
4601  *bi.q_BasePEquEmitPNodePtr += -bi.capBEdiff - bi.capBEdep;
4602  *bi.q_EmitPEquCollPNodePtr += bi.capeqCB;
4603  *bi.q_EmitPEquBasePNodePtr += -bi.capBEdiff - bi.capBEdep - bi.capeqCB;
4604  *bi.q_EmitPEquEmitPNodePtr += bi.capBEdiff + bi.capBEdep;
4605 
4606  // excess phase terms. ERK-dcop
4607  if ( td != 0 && getDeviceOptions().newExcessPhase )
4608  {
4609  if (!(getSolverState().dcopFlag) )
4610  {
4611  *bi.q_IfxEquIfxNodePtr += 1;
4612  *bi.q_dIfxEqudIfxNodePtr += 1*td*td;
4613  }
4614  }
4615 
4616 #else
4617  // F-matrix:
4618 
4619  dFdx[bi.li_Coll][bi.ACollEquCollNodeOffset] += bi.gCpr;
4620  dFdx[bi.li_Coll][bi.ACollEquCollPNodeOffset] -= bi.gCpr;
4621  dFdx[bi.li_Base][bi.ABaseEquBaseNodeOffset] += bi.diBrdvB;
4622  dFdx[bi.li_Base][bi.ABaseEquCollPNodeOffset] += bi.diBrdvCp;
4623  dFdx[bi.li_Base][bi.ABaseEquBasePNodeOffset] += bi.diBrdvBp;
4624  dFdx[bi.li_Base][bi.ABaseEquEmitPNodeOffset] += bi.diBrdvEp;
4625  dFdx[bi.li_Emit][bi.AEmitEquEmitNodeOffset] += bi.gEpr;
4626  dFdx[bi.li_Emit][bi.AEmitEquEmitPNodeOffset] -= bi.gEpr;
4627  dFdx[bi.li_CollP][bi.ACollPEquCollNodeOffset] -= bi.gCpr;
4628  dFdx[bi.li_CollP][bi.ACollPEquCollPNodeOffset] +=bi.diCEdvCp + bi.gBCtot + bi.gCpr;
4629  dFdx[bi.li_CollP][bi.ACollPEquBasePNodeOffset] += bi.diCEdvBp - bi.gBCtot;
4630  dFdx[bi.li_CollP][bi.ACollPEquEmitPNodeOffset] += bi.diCEdvEp;
4631 
4632  // excess phase terms. ERK-dcop
4633  if ( td != 0 && getDeviceOptions().newExcessPhase && !(getSolverState().dcopFlag) )
4634  {
4635  dFdx[bi.li_CollP][bi.ACollPEquIfxNodeOffset] += 1.0 * bi.model_.TYPE;
4636  }
4637 
4638  dFdx[bi.li_BaseP][bi.ABasePEquBaseNodeOffset] -= bi.diBrdvB;
4639  dFdx[bi.li_BaseP][bi.ABasePEquCollPNodeOffset] += -bi.diBrdvCp - bi.gBCtot;
4640  dFdx[bi.li_BaseP][bi.ABasePEquBasePNodeOffset] += -bi.diBrdvBp + bi.gBEtot + bi.gBCtot;
4641  dFdx[bi.li_BaseP][bi.ABasePEquEmitPNodeOffset] += -bi.diBrdvEp - bi.gBEtot;
4642  dFdx[bi.li_EmitP][bi.AEmitPEquEmitNodeOffset] -= bi.gEpr;
4643  dFdx[bi.li_EmitP][bi.AEmitPEquCollPNodeOffset] += -bi.diCEdvCp;
4644  dFdx[bi.li_EmitP][bi.AEmitPEquBasePNodeOffset] += - bi.diCEdvBp - bi.gBEtot;
4645 
4646  // ERK Note: -bi.diCEdvEp should equal + bi.diCEdvBp + bi.diCEdvCp. In the
4647  // original old-DAE form, + bi.diCEdvBp + bi.diCEdvCp is used. In
4648  // the more recent new-DAE form, we've used bi.diCEdvEp, but it sometimes
4649  // results in subtle differences between old- and new-DAE jacobians.
4650  // This should matter, but .....
4651 
4652  dFdx[bi.li_EmitP][bi.AEmitPEquEmitPNodeOffset] += bi.gBEtot + bi.gEpr + bi.diCEdvBp + bi.diCEdvCp; // this is a test.
4653  //+= bi.gBEtot + bi.gEpr - bi.diCEdvEp;
4654 
4655  // excess phase terms. ERK-dcop
4656  if ( td != 0 && getDeviceOptions().newExcessPhase && !(getSolverState().dcopFlag) )
4657  {
4658  dFdx[bi.li_EmitP][bi.AEmitPEquIfxNodeOffset] += -1.0 * bi.model_.TYPE;
4659  }
4660 
4661  // excess phase terms. ERK-dcop
4663  {
4664  if ( td != 0 )
4665  {
4666  if ( !(getSolverState().dcopFlag) )
4667  {
4668  dFdx[bi.li_Ifx][bi.AIfxEqudIfxNodeOffset]+= -1;
4669  dFdx[bi.li_dIfx][bi.AdIfxEquCollPNodeOffset] += -3*bi.diBEdvCp * bi.model_.TYPE;
4670  dFdx[bi.li_dIfx][bi.AdIfxEquBasePNodeOffset] += -3*bi.diBEdvBp * bi.model_.TYPE;
4671  dFdx[bi.li_dIfx][bi.AdIfxEquEmitPNodeOffset] += -3*bi.diBEdvEp * bi.model_.TYPE;
4672  dFdx[bi.li_dIfx][bi.AdIfxEqudIfxNodeOffset] += 3* td;
4673  dFdx[bi.li_dIfx][bi.AdIfxEquIfxNodeOffset] += 3;
4674  }
4675  else
4676  {
4677  dFdx[bi.li_Ifx][bi.AIfxEquCollPNodeOffset] += -bi.diBEdvCp * bi.model_.TYPE;
4678  dFdx[bi.li_Ifx][bi.AIfxEquBasePNodeOffset] += -bi.diBEdvBp * bi.model_.TYPE;
4679  dFdx[bi.li_Ifx][bi.AIfxEquEmitPNodeOffset] += -bi.diBEdvEp * bi.model_.TYPE;
4680  dFdx[bi.li_Ifx][bi.AIfxEquIfxNodeOffset]+= 1;
4681  dFdx[bi.li_dIfx][bi.AdIfxEqudIfxNodeOffset] += 1;
4682  }
4683  }
4684  else
4685  {
4686  dFdx[bi.li_Ifx][bi.AIfxEquIfxNodeOffset]+= 1;
4687  dFdx[bi.li_dIfx][bi.AdIfxEqudIfxNodeOffset] += 1;
4688  }
4689  }
4690 
4691  // Q-matrix:
4692 
4693  dQdx[bi.li_Base][bi.ABaseEquBaseNodeOffset] += bi.capBX;
4694  dQdx[bi.li_Base][bi.ABaseEquCollPNodeOffset] += -bi.capBX;
4695  dQdx[bi.li_Subst][bi.ASubstEquSubstNodeOffset] += bi.capCS;
4696  dQdx[bi.li_Subst][bi.ASubstEquCollPNodeOffset] -= bi.capCS;
4697  dQdx[bi.li_CollP][bi.ACollPEquBaseNodeOffset] -= bi.capBX;
4698  dQdx[bi.li_CollP][bi.ACollPEquSubstNodeOffset] -= bi.capCS;
4699  dQdx[bi.li_CollP][bi.ACollPEquCollPNodeOffset] += bi.capCS + bi.capBX + bi.capBCdep + bi.capBCdiff;
4700  dQdx[bi.li_CollP][bi.ACollPEquBasePNodeOffset] += -bi.capBCdep - bi.capBCdiff;
4701  dQdx[bi.li_BaseP][bi.ABasePEquCollPNodeOffset] += -bi.capBCdiff - bi.capBCdep - bi.capeqCB;
4702  dQdx[bi.li_BaseP][bi.ABasePEquBasePNodeOffset] += bi.capBEdiff + bi.capBEdep + bi.capBCdiff + bi.capBCdep + bi.capeqCB;
4703  dQdx[bi.li_BaseP][bi.ABasePEquEmitPNodeOffset] += -bi.capBEdiff - bi.capBEdep;
4704  dQdx[bi.li_EmitP][bi.AEmitPEquCollPNodeOffset] += bi.capeqCB;
4705  dQdx[bi.li_EmitP][bi.AEmitPEquBasePNodeOffset] += -bi.capBEdiff - bi.capBEdep - bi.capeqCB;
4706  dQdx[bi.li_EmitP][bi.AEmitPEquEmitPNodeOffset] += bi.capBEdiff + bi.capBEdep;
4707 
4708  // excess phase terms. ERK-dcop
4709  if ( td != 0 && getDeviceOptions().newExcessPhase )
4710  {
4711  if (!(getSolverState().dcopFlag) )
4712  {
4713  dQdx[bi.li_Ifx][bi.AIfxEquIfxNodeOffset] += 1;
4714  dQdx[bi.li_dIfx][bi.AdIfxEqudIfxNodeOffset] += 1*td*td;
4715  }
4716  }
4717 #endif
4718  }
4719  return true;
4720 }
4721 
4722 Device *Traits::factory(const Configuration &configuration, const FactoryBlock &factory_block)
4723 {
4724 
4725  return new Master(configuration, factory_block, factory_block.solverState_, factory_block.deviceOptions_);
4726 }
4727 
4729 {
4731  .registerDevice("q", 1)
4732  .registerModelType("pnp", 1)
4733  .registerModelType("npn", 1);
4734 }
4735 
4736 
4737 //-----------------------------------------------------------------------------
4738 // sensitivity related code.
4739 //
4740 // This is not the final implementation, as it is too klunky. But, it works
4741 // for now as a preliminary experiment.
4742 
4743 template <typename ScalarT>
4745  // inputs
4746  // instance
4747  const ScalarT & TEMP,
4748 
4749  // model
4750  const ScalarT & TNOM,
4751  const ScalarT & energyGap,
4752  const ScalarT & tempExpIS,
4753  const ScalarT & betaExp,
4754  const ScalarT & potBE,
4755  const ScalarT & depCapBE,
4756  const ScalarT & juncExpBE,
4757  const ScalarT & depCapBC,
4758  const ScalarT & juncExpBC,
4759  const ScalarT & depCapCoeff,
4760  const ScalarT & satCur,
4761  const ScalarT & betaF,
4762  const ScalarT & betaR,
4763 
4764  const ScalarT & c2,
4765  const ScalarT & c4,
4766  bool c2Given,
4767  bool c4Given,
4768 
4769  bool leakBECurrentGiven,
4770  bool leakBCCurrentGiven,
4771 
4772  const ScalarT & leakBEEmissionCoeff,
4773  const ScalarT & leakBCEmissionCoeff,
4774 
4775  const ScalarT & rollOffExp,
4776  const ScalarT & baseResist,
4777  const ScalarT & collectorResist,
4778  const ScalarT & emitterResist,
4779  const ScalarT & potBC,
4780  const ScalarT & rollOffF,
4781  const ScalarT & rollOffR,
4782  const ScalarT & earlyVoltF,
4783  const ScalarT & earlyVoltR,
4784 
4785  // outputs
4786  ScalarT & vt,
4787  ScalarT & leakBECurrent,
4788  ScalarT & leakBCCurrent,
4789  ScalarT & tBELeakCur,
4790  ScalarT & tBCLeakCur,
4791  ScalarT & tleakBEEmissionCoeff,
4792  ScalarT & tleakBCEmissionCoeff,
4793 
4794  ScalarT & tRollOffExp,
4795  ScalarT & tInvRollOffF,
4796  ScalarT & tInvRollOffR,
4797  ScalarT & tBaseResist,
4798  ScalarT & tCollectorResist,
4799  ScalarT & tEmitterResist,
4800 
4801  ScalarT & tBECap,
4802  ScalarT & tBEPot,
4803  ScalarT & tBCCap,
4804  ScalarT & tBCPot,
4805  ScalarT & tDepCap,
4806  ScalarT & tF1,
4807  ScalarT & tF4,
4808  ScalarT & tF5,
4809  ScalarT & tVCrit,
4810  ScalarT & tSatCur,
4811  ScalarT & tBetaF,
4812  ScalarT & tBetaR,
4813  ScalarT & tInvEarlyVoltF,
4814  ScalarT & tInvEarlyVoltR
4815  )
4816 {
4817  //Generation of temperature based factors
4818  vt = TEMP * CONSTKoverQ;
4819 
4820  ScalarT fact2 = TEMP / CONSTREFTEMP;
4821  ScalarT egfet = CONSTEg0 - ( CONSTalphaEg * TEMP * TEMP ) /
4822  ( TEMP + CONSTbetaEg );
4823  ScalarT arg = -egfet / ( 2.0 * CONSTboltz * TEMP ) +
4824  CONSTEg300 / ( CONSTboltz * ( 2.0 * CONSTREFTEMP ) );
4825  ScalarT pbfact = -2.0 * vt * ( 1.5 * log( fact2 ) + CONSTQ * arg );
4826  ScalarT ratlog = log( TEMP / TNOM );
4827  ScalarT ratio1 = TEMP / TNOM - 1.0;
4828  ScalarT factlog = ratio1 * energyGap / vt
4829  + tempExpIS * ratlog;
4830  ScalarT factor = exp( factlog );
4831  ScalarT bfactor = exp( ratlog * betaExp );
4832 
4833  // Temp. adj. zero-bias junction capacitances and built-in potentials
4834  ScalarT fact1 = TNOM / CONSTREFTEMP;
4835  ScalarT pbo = ( potBE - pbfact ) / fact1;
4836  ScalarT gmaold = ( potBE - pbo ) / pbo;
4837 
4838  tBECap = depCapBE / ( 1.0 + juncExpBE *
4839  ( 4.e-4 * ( TNOM - CONSTREFTEMP ) - gmaold ) );
4840  tBEPot = fact2 * pbo + pbfact;
4841 
4842  ScalarT gmanew = ( tBEPot - pbo ) / pbo;
4843 
4844  tBECap *= 1.0 + juncExpBE *
4845  ( 4.e-4 * ( TEMP - CONSTREFTEMP ) - gmanew );
4846 
4847  pbo = ( potBC - pbfact ) / fact1;
4848  gmaold = ( potBC - pbo ) / pbo;
4849 
4850  tBCCap = depCapBC / ( 1.0 + juncExpBC *
4851  ( 4.e-4 * ( TNOM - CONSTREFTEMP ) - gmaold ) );
4852  tBCPot = fact2 * pbo + pbfact;
4853 
4854  gmanew = ( tBCPot - pbo ) / pbo;
4855 
4856  tBCCap *= 1.0 + juncExpBC *
4857  ( 4.e-4 * ( TEMP - CONSTREFTEMP ) - gmanew );
4858 
4859  // Temp. adj. depletion capacitance
4860  tDepCap = depCapCoeff * tBEPot;
4861 
4862  // Temp. adj. polynomial factors
4863  ScalarT xfc = log( 1.0 - depCapCoeff );
4864  tF1 = tBEPot * ( 1.0 - exp( ( 1.0 - juncExpBE ) * xfc ) ) /
4865  ( 1.0 - juncExpBE );
4866 
4867  tF4 = depCapCoeff * tBCPot;
4868  tF5 = tBCPot * ( 1.0 - exp( ( 1.0 - juncExpBC ) * xfc ) ) /
4869  ( 1.0 - juncExpBC );
4870 
4871  // Temp. adj. critical voltage
4872  tVCrit = vt * log( vt / ( CONSTroot2 * satCur ) );
4873 
4874  tSatCur = satCur * factor;
4875  // Temp. adj. beta's
4876  tBetaF = betaF * bfactor;
4877  tBetaR = betaR * bfactor;
4878 
4879  // Temp. adj. leakage currents
4880  if (!leakBECurrentGiven && c2Given)
4881  {
4882  leakBECurrent = c2 * satCur;
4883  }
4884 
4885  if (!leakBCCurrentGiven && c4Given)
4886  {
4887  leakBCCurrent = c4 * satCur;
4888  }
4889 
4890  tBELeakCur = leakBECurrent * exp( factlog / leakBEEmissionCoeff ) / bfactor;
4891 
4892  tBCLeakCur = leakBCCurrent * exp( factlog / leakBCEmissionCoeff ) / bfactor;
4893 
4894  tleakBEEmissionCoeff = leakBEEmissionCoeff;
4895  tleakBCEmissionCoeff = leakBCEmissionCoeff;
4896 
4897  tRollOffExp = rollOffExp;
4898  tBaseResist = baseResist;
4899  tCollectorResist = collectorResist;
4900  tEmitterResist = emitterResist;
4901 
4902  if (rollOffF != 0)
4903  tInvRollOffF = 1/rollOffF;
4904  else
4905  tInvRollOffF = 0;
4906  if (rollOffR != 0)
4907  tInvRollOffR = 1/rollOffR;
4908  else
4909  tInvRollOffR = 0;
4910  if (earlyVoltF != 0)
4911  tInvEarlyVoltF = 1/earlyVoltF;
4912  else
4913  tInvEarlyVoltF = 0;
4914  if (earlyVoltR != 0)
4915  tInvEarlyVoltR = 1/earlyVoltR;
4916  else
4917  tInvEarlyVoltR = 0;
4918 
4919  return true;
4920 }
4921 
4922 
4923 //-----------------------------------------------------------------------------
4924 template <typename ScalarT>
4926  // inputs
4927  bool leakBECurrentGiven,
4928  bool leakBCCurrentGiven,
4929  bool c2Given,
4930  bool c4Given,
4931  bool minBaseResistGiven,
4932  bool VAFgiven,
4933  bool IKFgiven,
4934  bool VARgiven,
4935  bool IKRgiven,
4936  bool VTFgiven,
4937  bool FCgiven,
4938 
4939  const ScalarT & c2,
4940  const ScalarT & c4,
4941  const ScalarT & satCur,
4942  const ScalarT & baseResist,
4943  const ScalarT & earlyVoltF,
4944  const ScalarT & rollOffF,
4945  const ScalarT & earlyVoltR,
4946  const ScalarT & rollOffR,
4947 
4948  const ScalarT & collectorResist,
4949  const ScalarT & emitterResist,
4950  const ScalarT & transTimeFVBC,
4951  const ScalarT & excessPhase,
4952  const ScalarT & transTimeF,
4953  const ScalarT & juncExpBE,
4954  const ScalarT & juncExpBC,
4955 
4956  //outputs
4957  ScalarT & leakBECurrent,
4958  ScalarT & leakBCCurrent,
4959  ScalarT & minBaseResist,
4960  ScalarT & invEarlyVoltF,
4961  ScalarT & invRollOffF,
4962  ScalarT & invEarlyVoltR,
4963  ScalarT & invRollOffR,
4964 
4965  ScalarT & collectorConduct,
4966  ScalarT & emitterConduct,
4967  ScalarT & transTimeVBCFac,
4968  ScalarT & excessPhaseFac,
4969  ScalarT & depCapCoeff,
4970 
4971  ScalarT & f2,
4972  ScalarT & f3,
4973  ScalarT & f6,
4974  ScalarT & f7
4975  )
4976 {
4977 
4978  if (!leakBECurrentGiven && c2Given)
4979  leakBECurrent = c2 * satCur;
4980 
4981  if (!leakBCCurrentGiven && c4Given)
4982  leakBCCurrent = c4 * satCur;
4983 
4984  if (!minBaseResistGiven)
4985  minBaseResist = baseResist;
4986 
4987  if (VAFgiven && ( earlyVoltF != 0.0 ) )
4988  invEarlyVoltF = 1.0 / earlyVoltF;
4989  else
4990  invEarlyVoltF = 0.0;
4991 
4992  if( IKFgiven && ( rollOffF != 0.0 ) )
4993  invRollOffF = 1.0 / rollOffF;
4994  else
4995  invRollOffF = 0.0;
4996 
4997  if( VARgiven && ( earlyVoltR != 0.0 ) )
4998  invEarlyVoltR = 1.0 / earlyVoltR;
4999  else
5000  invEarlyVoltR = 0.0;
5001 
5002  if( IKRgiven && ( rollOffR != 0.0 ) )
5003  invRollOffR = 1.0 / rollOffR;
5004  else
5005  invRollOffR = 0.0;
5006 
5007  if( collectorResist != 0.0 )
5008  collectorConduct = 1.0 / collectorResist;
5009  else
5010  collectorConduct = 0;
5011 
5012  if( emitterResist != 0.0 )
5013  emitterConduct = 1.0 / emitterResist;
5014  else
5015  emitterConduct = 0;
5016 
5017  if( VTFgiven && ( transTimeFVBC != 0.0 ) )
5018  transTimeVBCFac = 1.0 / ( transTimeFVBC * 1.44 );
5019  else
5020  transTimeVBCFac = 0.0;
5021 
5022  ScalarT mpi = M_PI;
5023  excessPhaseFac = ( excessPhase / ( 180.0 / mpi ) ) * transTimeF;
5024 
5025  if( FCgiven )
5026  {
5027  if( depCapCoeff > 0.9999 )
5028  {
5029  depCapCoeff = 0.9999;
5030  Xyce::dout() << "Bad Depletion Capacitance Coefficient" << std::endl;
5031  }
5032  }
5033  else
5034  {
5035  depCapCoeff = 0.5;
5036  }
5037 
5038  ScalarT xfc = log( 1.0 - depCapCoeff );
5039 
5040  f2 = exp( ( 1.0 + juncExpBE ) * xfc );
5041  f3 = 1.0 - depCapCoeff * ( 1.0 + juncExpBE );
5042  f6 = exp( ( 1.0 + juncExpBC ) * xfc );
5043  f7 = 1.0 - depCapCoeff * ( 1.0 + juncExpBC );
5044 
5045  return true;
5046 }
5047 
5048 
5049 //-----------------------------------------------------------------------------
5050 // Function : oldDAEExcessPhaseCalculation1
5051 //-----------------------------------------------------------------------------
5052 template <>
5054  const fadType & td,
5055  const fadType & qB,
5056  const fadType & iBE,
5057 
5058  bool dcopFlag,
5059  bool beginIntegrationFlag,
5060 
5061  double * currStaVec, // raw pointers fine here
5062  double * lastStaVec, // raw pointers fine here
5063 
5064  const int li_istateCEXBC
5065  )
5066 {
5067  // do excess phase stuff if we are in transient mode and td is nonzero.
5068  //double td = model_.excessPhaseFac;
5069 
5070  if (!dcopFlag && td != 0)
5071  {
5072  // If there is no cexbc history, create one and use it.
5073  if (beginIntegrationFlag)
5074  {
5075  fadType tmp = iBE/qB;
5076  currStaVec[li_istateCEXBC] = tmp.val();
5077  lastStaVec[li_istateCEXBC] = tmp.val();
5078  }
5079  }
5080 
5081  return;
5082 }
5083 
5084 template <>
5086  const double & td,
5087  const double & qB,
5088  const double & iBE,
5089 
5090  bool dcopFlag,
5091  bool beginIntegrationFlag,
5092 
5093  double * currStaVec, // raw pointers fine here
5094  double * lastStaVec, // raw pointers fine here
5095 
5096  const int li_istateCEXBC
5097  )
5098 {
5099  // do excess phase stuff if we are in transient mode and td is nonzero.
5100  //double td = model_.excessPhaseFac;
5101 
5102  if (!dcopFlag && td != 0)
5103  {
5104  // If there is no cexbc history, create one and use it.
5105  if (beginIntegrationFlag)
5106  {
5107  double tmp = iBE/qB;
5108  currStaVec[li_istateCEXBC] = tmp;
5109  lastStaVec[li_istateCEXBC] = tmp;
5110  }
5111  }
5112 
5113  return;
5114 }
5115 
5116 //-----------------------------------------------------------------------------
5117 // Function : oldDAEExcessPhaseCalculation2
5118 //-----------------------------------------------------------------------------
5119 template <>
5121  (const fadType & td,
5122  const fadType & qB,
5123  const fadType & iBE,
5124  const fadType & gBE,
5125 
5126  const double dt0, //dt0 = getSolverState().currTimeStep;
5127  const double dt1, //dt1 = getSolverState().lastTimeStep;
5128 
5129  bool dcopFlag,
5130  bool beginIntegrationFlag,
5131 
5132  double * nextStaVec, // raw pointers fine here
5133  const double * currStaVec, // raw pointers fine here
5134  const double * lastStaVec, // raw pointers fine here
5135 
5136  const int li_istateCEXBC,
5137 
5138  fadType & iEX,
5139  fadType & gEX,
5140  fadType & iC_local)
5141 {
5142  ////////////////////////////////////////////////////////////////
5143  //double td = model_.excessPhaseFac;
5144 
5145  ////////////////////////////////////////////////////////////////
5146  // ERK: 07/13/01
5147  //
5148  // weil's approx. for excess phase applied with backward-
5149  // euler integration
5150  // (copied over from spice).
5151  //
5152  ////////////////////////////////////////////////////////////////
5153 
5154  iEX=iBE;
5155  gEX=gBE;
5156 
5157 
5158  iC_local = 0.0;
5159 
5160  // do excess phase stuff if we are in transient mode and td is nonzero.
5161  if (!dcopFlag && td != 0)
5162  {
5163  fadType arg1, arg2, denom, phaseScalar;
5164 
5165  arg1 = dt0 / td;
5166  arg2 = 3.0 * arg1;
5167  arg1 = arg2 * arg1;
5168  denom = 1.0 + arg1 + arg2;
5169  phaseScalar = arg1 / denom;
5170 
5171  fadType currCexbc;
5172  fadType lastCexbc;
5173 
5174  // Secondary state stuff:
5175  if (!beginIntegrationFlag)
5176  {
5177  currCexbc = (currStaVec)[li_istateCEXBC];
5178  lastCexbc = (lastStaVec)[li_istateCEXBC];
5179  }
5180  else
5181  {
5182  currCexbc = iBE/qB;
5183  lastCexbc = iBE/qB;
5184  }
5185 
5186  iC_local = ((currCexbc) * (1 + dt0 / dt1 + arg2) - (lastCexbc) * dt0 / dt1) / denom;
5187  iEX = iBE * phaseScalar;
5188  gEX = gBE * phaseScalar;
5189 
5190  fadType nextCexbc = iC_local + iEX / qB;
5191  nextStaVec[li_istateCEXBC] = nextCexbc.val();
5192  }
5193 
5194  return;
5195 }
5196 
5197 //-----------------------------------------------------------------------------
5198 // Function : oldDAEExcessPhaseCalculation2
5199 //-----------------------------------------------------------------------------
5200 template <>
5202  (const double & td,
5203  const double & qB,
5204  const double & iBE,
5205  const double & gBE,
5206 
5207  const double dt0, //dt0 = getSolverState().currTimeStep;
5208  const double dt1, //dt1 = getSolverState().lastTimeStep;
5209 
5210  bool dcopFlag,
5211  bool beginIntegrationFlag,
5212 
5213  double * nextStaVec, // raw pointers fine here
5214  const double * currStaVec, // raw pointers fine here
5215  const double * lastStaVec, // raw pointers fine here
5216 
5217  const int li_istateCEXBC,
5218 
5219  double & iEX,
5220  double & gEX,
5221  double & iC_local)
5222 {
5223  ////////////////////////////////////////////////////////////////
5224  //double td = model_.excessPhaseFac;
5225 
5226  ////////////////////////////////////////////////////////////////
5227  // ERK: 07/13/01
5228  //
5229  // weil's approx. for excess phase applied with backward-
5230  // euler integration
5231  // (copied over from spice).
5232  //
5233  ////////////////////////////////////////////////////////////////
5234 
5235  iEX=iBE;
5236  gEX=gBE;
5237 
5238 
5239  iC_local = 0.0;
5240 
5241  // do excess phase stuff if we are in transient mode and td is nonzero.
5242  if (!dcopFlag && td != 0)
5243  {
5244  double arg1, arg2, denom, phaseScalar;
5245 
5246  arg1 = dt0 / td;
5247  arg2 = 3.0 * arg1;
5248  arg1 = arg2 * arg1;
5249  denom = 1.0 + arg1 + arg2;
5250  phaseScalar = arg1 / denom;
5251 
5252  double currCexbc;
5253  double lastCexbc;
5254 
5255  // Secondary state stuff:
5256  if (!beginIntegrationFlag)
5257  {
5258  currCexbc = (currStaVec)[li_istateCEXBC];
5259  lastCexbc = (lastStaVec)[li_istateCEXBC];
5260  }
5261  else
5262  {
5263  currCexbc = iBE/qB;
5264  lastCexbc = iBE/qB;
5265  }
5266 
5267  iC_local = ((currCexbc) * (1 + dt0 / dt1 + arg2) - (lastCexbc) * dt0 / dt1) / denom;
5268  iEX = iBE * phaseScalar;
5269  gEX = gBE * phaseScalar;
5270 
5271  double nextCexbc = iC_local + iEX / qB;
5272  nextStaVec[li_istateCEXBC] = nextCexbc;
5273  }
5274 
5275  return;
5276 }
5277 
5278 template <typename ScalarT>
5280  const ScalarT & i_fx,
5281  const ScalarT & td,
5282  const ScalarT & iBE,
5283  const ScalarT & iBEleak,
5284  const ScalarT & iBC,
5285  const ScalarT & iBCleak,
5286  const ScalarT & qB,
5287  const ScalarT & invqB,
5288  const ScalarT & tBetaF,
5289  const ScalarT & tBetaR,
5290 
5291  const ScalarT & gBC,
5292  const ScalarT & gBE,
5293 
5294  const ScalarT & dqBdvBp,
5295  const ScalarT & dqBdvCp,
5296  const ScalarT & dqBdvEp,
5297 
5298  bool dcopFlag,
5299 
5300  ScalarT & iCE,
5301  ScalarT & iC,
5302  ScalarT & iB,
5303  ScalarT & iE,
5304 
5305  ScalarT & diCEdvBp,
5306  ScalarT & diCEdvCp,
5307  ScalarT & diCEdvEp,
5308 
5309  ScalarT & diBEdvBp,
5310  ScalarT & diBEdvCp,
5311  ScalarT & diBEdvEp
5312  )
5313 {
5314  //ScalarT i_fx;
5315  //ScalarT td = model_.excessPhaseFac;
5316  //ScalarT * solVec = extData.nextSolVectorRawPtr;
5317 
5318  if ( td != 0 && !dcopFlag )
5319  {
5320  //i_fx = solVec[li_Ifx];
5321  iCE = i_fx - iBC / qB;
5322  }
5323  else
5324  {
5325  iCE = (iBE - iBC)/ qB;
5326  }
5327 
5328  iC = iCE - iBC / tBetaR - iBCleak;
5329  iB = iBE / tBetaF + iBEleak + iBC / tBetaR + iBCleak;
5330  iE = -iC-iB;
5331 
5332 #if 1
5333  std::cout << "auxDAECalculations: tBetaR = " << tBetaR << std::endl;
5334  std::cout << "auxDAECalculations: tBetaF = " << tBetaF << std::endl;
5335  std::cout << "auxDAECalculations: iCE = " << iCE << std::endl;
5336  std::cout << "auxDAECalculations: iBC = " << iBC << std::endl;
5337  std::cout << "auxDAECalculations: iBE = " << iBE << std::endl;
5338  std::cout << "auxDAECalculations: iBEleak = " << iBEleak << std::endl;
5339  std::cout << "auxDAECalculations: iC = " << iC << std::endl;
5340  std::cout << "auxDAECalculations: iC = " << iC << std::endl;
5341  std::cout << "auxDAECalculations: iB = " << iB << std::endl;
5342  std::cout << "auxDAECalculations: iE = " << iE << std::endl;
5343 #endif
5344 
5345  if (td != 0)
5346  {
5347  if (!dcopFlag )
5348  {
5349  diCEdvBp = invqB * (-invqB * iBC * dqBdvBp - gBC);
5350  diCEdvCp = invqB * (-invqB * iBC * dqBdvCp + gBC);
5351  diCEdvEp = -invqB * invqB * iBC * dqBdvEp;
5352  }
5353  else // ERK-dcop: if dcop, use the td=0 case (copied from below)
5354  {
5355  diCEdvBp = invqB * (iCE * dqBdvBp + gBE - gBC);
5356  diCEdvCp = invqB * (iCE * dqBdvCp + gBC);
5357  diCEdvEp = invqB * (iCE * dqBdvEp - gBE);
5358  }
5359 
5360  diBEdvBp = invqB *(invqB* iBE * dqBdvBp + gBE);
5361  diBEdvCp = invqB * invqB * iBE * dqBdvCp;
5362  diBEdvEp = invqB * (invqB * iBE * dqBdvEp - gBE);
5363  }
5364  else
5365  {
5366  diCEdvBp = invqB * (iCE * dqBdvBp + gBE - gBC);
5367  diCEdvCp = invqB * (iCE * dqBdvCp + gBC);
5368  diCEdvEp = invqB * (iCE * dqBdvEp - gBE);
5369  }
5370 
5371  return;
5372 }
5373 
5374 //-----------------------------------------------------------------------------
5375 // Function : updateIntermediateVars
5376 // Purpose : update intermediate variables for one diode instance
5377 // Special Notes :
5378 // Scope : public
5379 // Creator :
5380 // Creation Date :
5381 //-----------------------------------------------------------------------------
5382 template <typename ScalarT>
5384 
5385  // inputs:
5386  const ScalarT & vBE,
5387  const ScalarT & vBC,
5388  const ScalarT & vBX,
5389  const ScalarT & vCS,
5390 
5391  const ScalarT & i_fx,
5392 
5393  // instance params:
5394  const ScalarT & AREA,
5395 
5396  // instance variables:
5397  const ScalarT & tSatCur,
5398  const ScalarT & vt,
5399  const ScalarT & tleakBEEmissionCoeff,
5400  const ScalarT & tleakBCEmissionCoeff,
5401  const ScalarT & tBELeakCur,
5402  const ScalarT & tBCLeakCur,
5403  const ScalarT & tInvRollOffF,
5404  const ScalarT & tInvRollOffR,
5405  const ScalarT & tRollOffExp,
5406  const ScalarT & tInvEarlyVoltF,
5407  const ScalarT & tInvEarlyVoltR,
5408  const ScalarT & tBECap,
5409  const ScalarT & tBCCap,
5410  const ScalarT & tDepCap,
5411  const ScalarT & tBEPot,
5412  const ScalarT & tBCPot,
5413  const ScalarT & tF1,
5414  const ScalarT & tF4,
5415  const ScalarT & tF5,
5416 
5417  // from device options:
5418  const double & gmin,
5419  const bool newExcessPhase,
5420 
5421  // from solver state:
5422  const bool dcopFlag,
5423  const bool tranopFlag,
5424  const bool acopFlag,
5425  const bool initTranFlag,
5426  const bool beginIntegrationFlag,
5427  const int newtonIter,
5428  const double pdt,
5429 
5430  // model params:
5431  const ScalarT & emissionCoeffF,
5432  const ScalarT & emissionCoeffR,
5433  const ScalarT & baseFracBCCap,
5434  const ScalarT & CJS,
5435  const ScalarT & depCapCoeff,
5436  const ScalarT & potBC,
5437  const ScalarT & transTimeF,
5438  const ScalarT & transTimeR,
5439  const ScalarT & transTimeBiasCoeffF,
5440  const ScalarT & transTimeVBCFac,
5441  const ScalarT & transTimeHighCurrF,
5442  const ScalarT & juncExpBE,
5443  const ScalarT & juncExpBC,
5444  const ScalarT & potSubst,
5445  const ScalarT & expSubst,
5446 
5447  const ScalarT & emitterConduct,
5448  const ScalarT & collectorConduct,
5449  const ScalarT & minBaseResist,
5450  const ScalarT & baseResist,
5451  const ScalarT & baseCurrHalfResist,
5452  const ScalarT & excessPhaseFac,
5453 
5454  const ScalarT & f2,
5455  const ScalarT & f3,
5456  const ScalarT & f6,
5457  const ScalarT & f7,
5458 
5459  const int level,
5460 
5461  // these are here b/c of the excess phase old-DAE form
5462  double * nextStaVec,
5463  double * currStaVec,
5464  double * lastStaVec,
5465  const int li_istateCEXBC,
5466  const double dt0, // getSolverState().currTimeStep,
5467  const double dt1, // getSolverState().lastTimeStep,
5468 
5469  // outputs:
5470  ScalarT & iB,
5471  ScalarT & iC,
5472  ScalarT & iE,
5473 
5474  ScalarT & iBE,
5475  ScalarT & gBE,
5476  ScalarT & iBC,
5477  ScalarT & gBC,
5478  ScalarT & iCE,
5479 
5480  ScalarT & iBEleak,
5481  ScalarT & gBEleak,
5482  ScalarT & iBCleak,
5483  ScalarT & gBCleak,
5484  ScalarT & qB,
5485  ScalarT & invqB,
5486  ScalarT & iBEhighCurr,
5487  ScalarT & gBEhighCurr,
5488 
5489  ScalarT & capeqCB,
5490  ScalarT & geqCB,
5491 
5492  ScalarT & qBEdep,
5493  ScalarT & capBEdep,
5494  ScalarT & qBEdiff,
5495  ScalarT & capBEdiff,
5496 
5497  ScalarT & qBCdep,
5498  ScalarT & capBCdep,
5499  ScalarT & qBCdiff,
5500  ScalarT & capBCdiff,
5501 
5502  ScalarT & qBX,
5503  ScalarT & capBX,
5504  ScalarT & qCS,
5505  ScalarT & capCS,
5506 
5507  ScalarT & gEpr,
5508  ScalarT & gCpr,
5509  ScalarT & gX,
5510 
5511  ScalarT & diBrdvB,
5512  ScalarT & diBrdvCp,
5513  ScalarT & diBrdvEp,
5514  ScalarT & diBrdvBp,
5515 
5516  ScalarT & diCEdvEp,
5517  ScalarT & diCEdvCp,
5518  ScalarT & diCEdvBp,
5519 
5520  ScalarT & diBEdvBp,
5521  ScalarT & diBEdvCp,
5522  ScalarT & diBEdvEp,
5523 
5524  ScalarT & gBEtot,
5525  ScalarT & gBCtot,
5526  ScalarT & tBetaF,
5527  ScalarT & tBetaR
5528  )
5529 {
5530  bool bsuccess = true;
5531 
5532  ScalarT dqBdvEp, dqBdvCp, dqBdvBp;
5533  ScalarT q1, q2;
5534 
5535  //Junction Current Calculations
5536  ScalarT csat = tSatCur * AREA;
5537  ScalarT vtF = vt * emissionCoeffF;
5538  ScalarT vtR = vt * emissionCoeffR;
5539  ScalarT vtE = vt * tleakBEEmissionCoeff;
5540  ScalarT vtC = vt * tleakBCEmissionCoeff;
5541  ScalarT iLeakBE = tBELeakCur * AREA;
5542  ScalarT iLeakBC = tBCLeakCur * AREA;
5543 
5544  if (vBE > -5.0 * vtF)
5545  {
5546  ScalarT arg1 = vBE / vtF ;
5547  arg1 = std::min(CONSTMAX_EXP_ARG, arg1);
5548  ScalarT devBE;
5549  ScalarT evBE;
5550 
5551  evBE = exp( arg1 );
5552  devBE=evBE;
5553 
5554  iBE = csat * ( evBE - 1.0 ) + gmin * vBE;
5555  gBE = csat * devBE / vtF + gmin;
5556 
5557  if (iLeakBE == 0.0)
5558  iBEleak = gBEleak = 0.0;
5559  else
5560  {
5561  ScalarT arg1 = vBE / vtE ;
5562  arg1 = std::min(CONSTMAX_EXP_ARG, arg1);
5563  ScalarT devBEleak;
5564  ScalarT evBEleak;
5565  evBEleak = exp(arg1);
5566  devBEleak=evBEleak;
5567  iBEleak = iLeakBE * (evBEleak - 1.0);
5568  gBEleak = iLeakBE * devBEleak / vtE;
5569  }
5570  }
5571  else
5572  {
5573  gBE = -csat / vBE + gmin;
5574  iBE = gBE * vBE;
5575  gBEleak = -iLeakBE / vBE;
5576  iBEleak = gBEleak * vBE;
5577  }
5578 
5579  if( vBC > -5.0 * vtR )
5580  {
5581  ScalarT arg1 = vBC / vtR ;
5582  arg1 = std::min(CONSTMAX_EXP_ARG, arg1);
5583  ScalarT devBC;
5584  ScalarT evBC;
5585  evBC = exp( arg1 );
5586  devBC=evBC;
5587 
5588  iBC = csat * ( evBC - 1.0 ) + gmin * vBC;
5589  gBC = csat * devBC / vtR + gmin;
5590 
5591  if (iLeakBC == 0.0)
5592  iBCleak = gBCleak = 0.0;
5593  else
5594  {
5595  ScalarT arg1 = vBC / vtC ;
5596  arg1 = std::min(CONSTMAX_EXP_ARG, arg1);
5597  ScalarT devBCleak;
5598  ScalarT evBCleak;
5599  evBCleak = exp(arg1);
5600  devBCleak=evBCleak;
5601 
5602  iBCleak = iLeakBC * (evBCleak - 1.0);
5603  gBCleak = iLeakBC * devBCleak / vtC;
5604  }
5605  }
5606  else
5607  {
5608  gBC = -csat / vBC + gmin;
5609  iBC = gBC * vBC;
5610  gBCleak = -iLeakBC / vBC;
5611  iBCleak = gBCleak * vBC;
5612  }
5613 
5614  // base charge calculations:
5615  ScalarT rofF = tInvRollOffF / AREA;
5616  ScalarT rofR = tInvRollOffR / AREA;
5617 
5618  q1 = 1.0 / ( 1.0 - tInvEarlyVoltF * vBC - tInvEarlyVoltR * vBE );
5619 
5620  if (rofF == 0.0 && rofR == 0.0)
5621  {
5622  qB = q1;
5623  ScalarT q1_qB = q1 * qB;
5624 
5625  dqBdvEp = q1_qB * tInvEarlyVoltR;
5626  dqBdvCp = q1_qB * tInvEarlyVoltF;
5627 /* replaced with simpler expression after if block
5628  dqBdvBp = -q1_qB * (invEarlyVoltR + invEarlyVoltF);
5629 */
5630  }
5631  else
5632  {
5633  q2 = rofF * iBE + rofR * iBC;
5634 
5635  // Difference from SPICE: spice puts a max(0,) around the arg definition,
5636  // which means we use the square root expression all the way down to
5637  // q2= -1/4. This is not really good, because it means that the derivative
5638  // of the square root term goes to negative infinity at the break point
5639  // between the expressions, and qB will be very discontinuous.
5640  // This doesn't have a huge effect on the solutions, but can possibly
5641  // lead to convergence issues (see bug 1214). This fix hasn't yet
5642  // been shown to help anything, but it has not hurt anything either.
5643  if (q2 >= 0)
5644  {
5645 
5646  ScalarT arg = 1.0 + 4.0 * q2;
5647  ScalarT sqarg = 1.0;
5648 
5649  // if (fabs(arg) > 0.0) sqarg = sqrt(arg);
5650  // ScalarT rofF_gBE_invSqarg = rofF * gBE / sqarg;
5651  // ScalarT rofR_gBC_invSqarg = rofR * gBC / sqarg;
5652  // add Pspice compatible rolloff parameter NK = tRollOffExp
5653 
5654  if (fabs(arg) > 0.0) sqarg = pow(arg,tRollOffExp);
5655  ScalarT rofF_gBE_invSqarg = 0.0;
5656  ScalarT rofR_gBC_invSqarg = 0.0;
5657  if(arg != 0) rofF_gBE_invSqarg = rofF*gBE*2*tRollOffExp*sqarg/arg;
5658  if(arg != 0) rofR_gBC_invSqarg = rofR*gBC*2*tRollOffExp*sqarg/arg;
5659 
5660  qB = 0.5 * q1 * (1.0 + sqarg);
5661 
5662  dqBdvEp = q1 * (qB * tInvEarlyVoltR + rofF_gBE_invSqarg);
5663  dqBdvCp = q1 * (qB * tInvEarlyVoltF + rofR_gBC_invSqarg);
5664 
5665  /* replaced with simpler expression after if block
5666  dqBdvBp = -q1 * (qB * ( invEarlyVoltF + invEarlyVoltR) +
5667  rofF_gBE_invSqarg + rofR_gBC_invSqarg);
5668  */
5669  }
5670  else
5671  {
5672  qB = q1;
5673  dqBdvEp = q1*qB*tInvEarlyVoltR;
5674  dqBdvCp = q1*qB*tInvEarlyVoltF;
5675  }
5676  }
5677  dqBdvBp = - (dqBdvEp + dqBdvCp);
5678 
5679  invqB = 1.0 / qB;
5680 
5681 
5682  // NOTE: this is a block that (for some reason) was originally in the
5683  // updatePrimaryState function. It got moved as in general, the "state"
5684  // functions are only for manipulating the state vector.
5685  // NOTE: brackets are around this block of code to preserve variable scope.
5686 
5687  ScalarT arg, sarg;
5688  ScalarT ctot;
5689  ScalarT czBC;
5690  ScalarT czBX;
5691  ScalarT czBE;
5692  ScalarT czCS;
5693  ScalarT fcpc;
5694  ScalarT fcpe;
5695 
5696  // capacitance calculations and "current" charge value calculations:
5697  ctot = tBCCap * AREA;
5698  czBC = ctot * baseFracBCCap;
5699  czBX = ctot - czBC;
5700  czBE = tBECap * AREA;
5701  czCS = CJS * AREA;
5702  fcpc = depCapCoeff * potBC;
5703  fcpe = tDepCap;
5704 
5705  // High current perturbation to BE current
5706  // The high current perturbation to the BE current is only
5707  // used in determining capacitance values. It does not enter
5708  // directly into the RHS KCL equations, or the Jacobian.
5709  iBEhighCurr = iBE;
5710  gBEhighCurr = gBE;
5711 
5712  // geqCB is only calculated sometimes (based on the if-statement).
5713  // If it is not calculated, then the value used will be the one from
5714  // the state vector, that was pulled out already.
5715  bool geqCB_recalc(false);
5716  if (transTimeF != 0.0 && vBE > 0.0 &&
5717  ((!dcopFlag)|| tranopFlag|| acopFlag))
5718  {
5719  ScalarT argtf = 0.0;
5720  ScalarT arg2 = 0.0;
5721  ScalarT arg3 = 0.0;
5722 
5723  if ( transTimeBiasCoeffF != 0.0)
5724  {
5725  argtf = transTimeBiasCoeffF;
5726 
5727  if (transTimeVBCFac != 0.0)
5728  argtf *= exp(vBC * transTimeVBCFac);
5729 
5730  arg2 = argtf;
5731 
5732  if (transTimeHighCurrF != 0.0)
5733  {
5734  ScalarT tmp = iBEhighCurr /
5735  (iBEhighCurr + transTimeHighCurrF * AREA);
5736 
5737  argtf *= tmp * tmp;
5738  arg2 = argtf * (3.0 - 2.0 * tmp);
5739  }
5740  arg3 = iBEhighCurr * argtf * transTimeVBCFac;
5741  }
5742 
5743  iBEhighCurr *= (1.0 + argtf) / qB;
5744  gBEhighCurr = (gBEhighCurr * (1.0 + arg2) - iBEhighCurr * dqBdvEp) / qB;
5745 
5746  capeqCB = transTimeF * (arg3 - iBEhighCurr * dqBdvCp) / qB;
5747  geqCB = capeqCB*pdt;
5748  geqCB_recalc = true;
5749  }
5750 
5751  // baseP-emitP depletion capacitance
5752  if( czBE == 0.0 )
5753  {
5754  qBEdep = 0.0;
5755  capBEdep = 0.0;
5756  }
5757  else
5758  {
5759  if ( vBE < fcpe )
5760  {
5761  arg = 1.0 - vBE / tBEPot;
5762  sarg = exp( -juncExpBE * log( arg ) );
5763 
5764  qBEdep = tBEPot * czBE * ( 1.0 - arg * sarg ) /
5765  ( 1.0 - juncExpBE );
5766  capBEdep = czBE * sarg;
5767  }
5768  else
5769  {
5770  ScalarT czBEf2 = czBE / f2;
5771 
5772  qBEdep = czBE * tF1 + czBEf2 * ( f3 * ( vBE -
5773  fcpe ) + ( juncExpBE / ( 2.0 *
5774  tBEPot ) ) * ( vBE * vBE - fcpe * fcpe ) );
5775  capBEdep = czBEf2 * ( f3 + juncExpBE * vBE /
5776  tBEPot );
5777  }
5778  }
5779 
5780  // baseP-emitP diffusion capacitance
5781  if (transTimeF == 0.0)
5782  {
5783  qBEdiff = capBEdiff = 0.0;
5784  }
5785  else
5786  {
5787  qBEdiff = transTimeF * iBEhighCurr;
5788  capBEdiff = transTimeF * gBEhighCurr;
5789  }
5790 
5791  // baseP-collP depletion capacitance
5792  if( czBC == 0.0 )
5793  {
5794  qBCdep = 0.0;
5795  capBCdep = 0.0;
5796  }
5797  else
5798  {
5799  if ( vBC < fcpc )
5800  {
5801  arg = 1.0 - vBC / tBCPot;
5802  sarg = exp( -juncExpBC * log( arg ) );
5803 
5804  qBCdep = tBCPot * czBC * ( 1.0 - arg * sarg ) /
5805  ( 1.0 - juncExpBC );
5806  capBCdep = czBC * sarg;
5807  }
5808  else
5809  {
5810  ScalarT czBCf2 = czBC / f6;
5811 
5812  qBCdep = czBC * tF5 + czBCf2 * ( f7 * ( vBC -
5813  fcpc ) + ( juncExpBC / ( 2.0 *
5814  tBCPot ) ) * ( vBC * vBC - fcpc * fcpc ) );
5815  capBCdep = czBCf2 * ( f7 + juncExpBC * vBC / tBCPot );
5816  }
5817  }
5818 
5819  // baseP-collP diffusion capacitance
5820  if (transTimeR == 0.0)
5821  {
5822  qBCdiff = capBCdiff = 0.0;
5823  }
5824  else
5825  {
5826  qBCdiff = transTimeR * iBC;
5827  capBCdiff = transTimeR * gBC;
5828  }
5829 
5830  // base-collP depletion capacitance
5831  if( czBX == 0.0 )
5832  {
5833  qBX = 0.0;
5834  capBX = 0.0;
5835  }
5836  else
5837  {
5838  if (vBX < fcpc)
5839  {
5840  arg = 1.0 - vBX / tBCPot;
5841  sarg = exp( -juncExpBC * log( arg ) );
5842 
5843  qBX = tBCPot * czBX * ( 1.0 - arg * sarg ) /
5844  ( 1.0 - juncExpBC );
5845  capBX = czBX * sarg;
5846  }
5847  else
5848  {
5849  ScalarT czBXf2 = czBX / f6;
5850 
5851  qBX = czBX * tF5 + czBXf2 * ( f7 * ( vBX -
5852  fcpc ) + ( juncExpBC / ( 2.0 *
5853  tBCPot ) ) * ( vBX * vBX - fcpc * fcpc ) );
5854  capBX = czBXf2 * ( f7 + juncExpBC * vBX /
5855  tBCPot );
5856  }
5857  }
5858 
5859  // collP-subst depletion capacitance
5860  if( czCS == 0.0 )
5861  {
5862  qCS = 0.0;
5863  capCS = 0.0;
5864  }
5865  else
5866  {
5867  if ( vCS < 0.0 )
5868  {
5869  arg = 1.0 - vCS / potSubst;
5870  sarg = exp( -expSubst * log( arg ) );
5871 
5872  qCS = potSubst * czCS * ( 1.0 - arg * sarg ) /
5873  ( 1.0 - expSubst );
5874  capCS = czCS * sarg;
5875  }
5876  else
5877  {
5878  qCS = vCS * czCS * ( 1.0 + expSubst * vCS / ( 2.0 *
5879  potSubst ) );
5880  capCS = czCS * ( 1.0 + expSubst * vCS / potSubst );
5881  }
5882  }
5883 
5884  // Here things get a little confusing. Generally, this is a logical place
5885  // to calculate iB, iC, and iE. iC and iE include the excess phase current.
5886 
5887  // Doing the old excess phase calculation, for both new and old-DAE, out
5888  // of curiousity to see that they match. However, if running new-DAE, these
5889  // calculations will only be used in diagnostics, not the actual loads.
5890  ScalarT iEX_tmp = 0.0; ScalarT gEX_tmp = 0.0; ScalarT iC_tmp = 0.0;
5891 
5893  excessPhaseFac, //td,
5894  qB, iBE,
5895  dcopFlag, beginIntegrationFlag,
5896  currStaVec, // raw pointers fine here
5897  lastStaVec, // raw pointers fine here
5898  li_istateCEXBC
5899  );
5900 
5902  (excessPhaseFac, //td,
5903  qB,
5904  iBE, gBE,
5905  dt0, //dt0 = getSolverState().currTimeStep;
5906  dt1, //dt1 = getSolverState().lastTimeStep;
5907  dcopFlag,
5908  beginIntegrationFlag,
5909  nextStaVec, // raw pointers fine here
5910  currStaVec, // raw pointers fine here
5911  lastStaVec, // raw pointers fine here
5912  li_istateCEXBC,
5913  iEX_tmp,gEX_tmp,iC_tmp);
5914 
5915  //if (getDeviceOptions().newExcessPhase)
5916  if (newExcessPhase)
5917  {
5919  i_fx, // solVec[li_Ifx];
5920  excessPhaseFac, //td,
5921  iBE, iBEleak, iBC, iBCleak,
5922  qB, invqB,
5923  tBetaF, tBetaR,
5924  gBC, gBE,
5925  dqBdvBp, dqBdvCp, dqBdvEp,
5926  dcopFlag,
5927  iCE, iC, iB, iE,
5928  diCEdvBp, diCEdvCp, diCEdvEp,
5929  diBEdvBp, diBEdvCp, diBEdvEp
5930  ); // iB, iC and iE calculated here.
5931  }
5932  else
5933  {
5934  // Do the iB, iC, and iE calculations for the old-DAE case here.
5935  ScalarT iEX = 0.0;
5936  ScalarT gEX = 0.0;
5937 
5938  iC = iC_tmp;
5939  iEX = iEX_tmp;
5940  gEX = gEX_tmp;
5941 
5942  iCE = ( iEX - iBC ) / qB;
5943  iC += iCE - iBC / tBetaR - iBCleak;
5944 
5945  iB = iBE / tBetaF + iBEleak + iBC / tBetaR + iBCleak;
5946  iE = -iC-iB;
5947 
5948  // These 3 derivatives depend upon excess phase terms, old-DAE version, so
5949  // they have to be set up here.
5950  diCEdvEp = invqB * (iCE * dqBdvEp - gEX);
5951  diCEdvCp = invqB * (iCE * dqBdvCp + gBC);
5952  diCEdvBp = invqB * (iCE * dqBdvBp + gEX - gBC);
5953  }
5954 
5955  // Some derivatives setup:
5956  // Emitter and Conductor conductances
5957  gEpr = emitterConduct * AREA;
5958  gCpr = collectorConduct * AREA;
5959 
5960  // Generation of gX for b-b' resistance
5961  ScalarT rBpr = minBaseResist / AREA;
5962  ScalarT rBpi = baseResist / AREA - rBpr;
5963  ScalarT xjrB = baseCurrHalfResist * AREA;
5964 
5965  gX = rBpr + rBpi / qB;
5966 
5967  if (fabs(xjrB) > 0.0)
5968  {
5969  ScalarT arg1 = std::max(iB / xjrB, 1.0e-09);
5970  ScalarT arg2 = (-1.0 + sqrt( 1.0 + 14.59025 * arg1)) / 2.4317 / sqrt(arg1);
5971  arg1 = tan(arg2);
5972  gX = rBpr + 3.0 * rBpi * (arg1 - arg2) / arg2 / arg1 / arg1;
5973  }
5974 
5975  if (fabs(gX) > 0.0) gX = 1.0 / gX;
5976 
5977  diBrdvB = gX;
5978  diBrdvCp = 0.0;
5979  diBrdvEp = 0.0;
5980  diBrdvBp = -gX;
5981 
5982  gBEtot = gBE / tBetaF + gBEleak;
5983  gBCtot = gBC / tBetaR + gBCleak;
5984 
5985  return bsuccess;
5986 }
5987 
5988 //-----------------------------------------------------------------------------
5989 // Function : bjtInstanceSensitivity::operator
5990 // Purpose : produces df/dp and dq/dp, where p= any bjt instance parameter.
5991 // Special Notes :
5992 // Scope : public
5993 // Creator : Eric Keiter, SNL
5994 // Creation Date : 7/18/2014
5995 //-----------------------------------------------------------------------------
5997  const ParameterBase &entity,
5998  const std::string &name,
5999  std::vector<double> & dfdp,
6000  std::vector<double> & dqdp,
6001  std::vector<double> & dbdp,
6002  std::vector<int> & Findices,
6003  std::vector<int> & Qindices,
6004  std::vector<int> & Bindices
6005  ) const
6006 {
6007  const ParameterBase * e1 = &entity;
6008  const Instance & inst = *(dynamic_cast<const Instance *> (e1));
6009 
6010  if (inst.getDeviceOptions().newExcessPhase)
6011  {
6012  dfdp.resize(9);
6013  dqdp.resize(9);
6014  Findices.resize(9);
6015  Qindices.resize(9);
6016  }
6017  else
6018  {
6019  dfdp.resize(7);
6020  dqdp.resize(7);
6021  Findices.resize(7);
6022  Qindices.resize(7);
6023  }
6024 
6025  // instance params:
6026  fadType AREA = inst.AREA;
6027  fadType TEMP = inst.TEMP;
6028 
6029  std::string paramName = ExtendedString( name ).toUpper();
6030  if (paramName=="AREA") { AREA.diff(0,1); }
6031  else if (paramName=="TEMP") { TEMP.diff(0,1); }
6032 
6033  // model params:
6034  fadType TNOM = inst.model_.TNOM;
6035  fadType energyGap = inst.model_.energyGap;
6036  fadType tempExpIS = inst.model_.tempExpIS;
6037  fadType betaExp = inst.model_.betaExp;
6038 
6039  fadType emissionCoeffF = inst.model_.emissionCoeffF;
6040  fadType emissionCoeffR = inst.model_.emissionCoeffR;
6041  fadType baseFracBCCap = inst.model_.baseFracBCCap;
6042  fadType CJS = inst.model_.CJS;
6043  fadType depCapCoeff = inst.model_.depCapCoeff;
6044  fadType potBE = inst.model_.potBE;
6045  fadType potBC = inst.model_.potBC;
6046 
6047  fadType depCapBE = inst.model_.depCapBE;
6048  fadType depCapBC = inst.model_.depCapBC;
6049  fadType betaF = inst.model_.betaF;
6050  fadType betaR = inst.model_.betaR;
6051 
6052  fadType transTimeF = inst.model_.transTimeF;
6053  fadType transTimeR = inst.model_.transTimeR;
6054  fadType transTimeBiasCoeffF = inst.model_.transTimeBiasCoeffF;
6055  fadType transTimeVBCFac = inst.model_.transTimeVBCFac;
6056  fadType transTimeHighCurrF = inst.model_.transTimeHighCurrF;
6057  fadType juncExpBE = inst.model_.juncExpBE;
6058  fadType juncExpBC = inst.model_.juncExpBC;
6059  fadType potSubst = inst.model_.potSubst;
6060  fadType expSubst = inst.model_.expSubst;
6061  fadType excessPhase = inst.model_.excessPhase;
6062 
6063  fadType c2 = inst.model_.c2;
6064  fadType c4 = inst.model_.c4;
6065  fadType satCur = inst.model_.satCur;
6066  fadType earlyVoltF = inst.model_.earlyVoltF;
6067  fadType rollOffF = inst.model_.rollOffF;
6068  fadType earlyVoltR = inst.model_.earlyVoltR;
6069  fadType rollOffR = inst.model_.rollOffR;
6070  fadType transTimeFVBC = inst.model_.transTimeFVBC;
6071 
6072  fadType emitterConduct = inst.model_.emitterConduct;
6073  fadType collectorConduct = inst.model_.collectorConduct;
6074  fadType minBaseResist = inst.model_.minBaseResist;
6075  fadType baseResist = inst.model_.baseResist;
6076  fadType baseCurrHalfResist = inst.model_.baseCurrHalfResist;
6077  fadType collectorResist = inst.model_.collectorResist;
6078  fadType emitterResist = inst.model_.emitterResist;
6079 
6080  fadType leakBECurrent = inst.model_.leakBECurrent;
6081  fadType leakBCCurrent = inst.model_.leakBCCurrent;
6082  fadType invEarlyVoltF = inst.model_.invEarlyVoltF;
6083  fadType invRollOffF = inst.model_.invRollOffF;
6084  fadType invEarlyVoltR = inst.model_.invEarlyVoltR;
6085  fadType invRollOffR = inst.model_.invRollOffR;
6086  fadType excessPhaseFac = inst.model_.excessPhaseFac;
6087 
6088  fadType leakBEEmissionCoeff = inst.model_.leakBEEmissionCoeff;
6089  fadType leakBCEmissionCoeff = inst.model_.leakBCEmissionCoeff;
6090  fadType rollOffExp = inst.model_.rollOffExp;
6091 
6092  // model params from processParams:
6093  fadType f2 = inst.model_.f2;
6094  fadType f3 = inst.model_.f3;
6095  fadType f6 = inst.model_.f6;
6096  fadType f7 = inst.model_.f7;
6097 
6098  processParams(
6099  // inputs
6100  inst.model_.leakBECurrentGiven,
6102  inst.model_.c2Given, inst.model_.c4Given,
6104  inst.model_.VAFgiven, inst.model_.IKFgiven,
6105  inst.model_.VARgiven, inst.model_.IKRgiven,
6106  inst.model_.VTFgiven, inst.model_.FCgiven,
6107 
6108  c2, c4, satCur, baseResist,
6109  earlyVoltF, rollOffF,
6110  earlyVoltR, rollOffR,
6111  collectorResist, emitterResist,
6112  transTimeFVBC,
6113  excessPhase, transTimeF,
6114  juncExpBE, juncExpBC,
6115 
6116  //outputs
6117  leakBECurrent, leakBCCurrent,
6118  minBaseResist,
6119  invEarlyVoltF, invRollOffF,
6120  invEarlyVoltR, invRollOffR,
6121 
6122  collectorConduct, emitterConduct,
6123  transTimeVBCFac,
6124  excessPhaseFac,
6125  depCapCoeff,
6126 
6127  f2, f3, f6, f7
6128  );
6129 
6130  // instance variables:
6131  fadType vt = inst.vt;
6132  fadType tSatCur = inst.tSatCur;
6133  fadType tleakBEEmissionCoeff = inst.tleakBEEmissionCoeff;
6134  fadType tleakBCEmissionCoeff = inst.tleakBCEmissionCoeff;
6135  fadType tBELeakCur = inst.tBELeakCur;
6136  fadType tBCLeakCur = inst.tBCLeakCur;
6137  fadType tInvRollOffF = inst.tInvRollOffF;
6138  fadType tInvRollOffR = inst.tInvRollOffR;
6139  fadType tRollOffExp = inst.tRollOffExp;
6140  fadType tInvEarlyVoltF = inst.tInvEarlyVoltF;
6141  fadType tInvEarlyVoltR = inst.tInvEarlyVoltR;
6142  fadType tBECap = inst.tBECap;
6143  fadType tBCCap = inst.tBCCap;
6144  fadType tDepCap = inst.tDepCap;
6145  fadType tBEPot = inst.tBEPot;
6146  fadType tBCPot = inst.tBCPot;
6147  fadType tF1 = inst.tF1;
6148  fadType tF4 = inst.tF4;
6149  fadType tF5 = inst.tF5;
6150 
6151  fadType tBaseResist = inst.tBaseResist;
6152  fadType tCollectorResist = inst.tCollectorResist;
6153  fadType tEmitterResist = inst.tEmitterResist;
6154  fadType tVCrit = inst.tVCrit;
6155  fadType tBetaF = inst.tBetaF;
6156  fadType tBetaR = inst.tBetaR;
6157 
6159  // inputs
6160  // instance
6161  TEMP,
6162  // model
6163  TNOM,
6164  energyGap,
6165  tempExpIS,
6166  betaExp,
6167  potBE,
6168  depCapBE,
6169  juncExpBE,
6170  depCapBC,
6171  juncExpBC,
6172  depCapCoeff,
6173  satCur,
6174  betaF,
6175  betaR,
6176 
6177  c2,
6178  c4,
6179  inst.model_.c2Given,
6180  inst.model_.c4Given,
6181 
6182  inst.model_.leakBECurrentGiven,
6184 
6185  leakBEEmissionCoeff,
6186  leakBCEmissionCoeff,
6187 
6188  rollOffExp,
6189  baseResist,
6190  collectorResist,
6191  emitterResist,
6192  potBC,
6193  rollOffF,
6194  rollOffR,
6195  earlyVoltF,
6196  earlyVoltR,
6197 
6198  // outputs
6199  vt,
6200  leakBECurrent,
6201  leakBCCurrent,
6202  tBELeakCur,
6203  tBCLeakCur,
6204  tleakBEEmissionCoeff,
6205  tleakBCEmissionCoeff,
6206 
6207  tRollOffExp,
6208  tInvRollOffF,
6209  tInvRollOffR,
6210  tBaseResist,
6211  tCollectorResist,
6212  tEmitterResist,
6213 
6214  tBECap,
6215  tBEPot,
6216  tBCCap,
6217  tBCPot,
6218  tDepCap,
6219  tF1,
6220  tF4,
6221  tF5,
6222  tVCrit,
6223  tSatCur,
6224  tBetaF,
6225  tBetaR,
6226  tInvEarlyVoltF,
6227  tInvEarlyVoltR
6228  );
6229 
6230  // updateIntermediateVars outputs
6231  fadType gCpr;
6232  fadType gX;
6233  fadType gEpr;
6234  fadType iC;
6235  fadType iB;
6236  fadType iE;
6237  fadType qBX;
6238  fadType qCS;
6239 
6240  fadType qBCdep;
6241  fadType qBCdiff;
6242  fadType qBEdep;
6243  fadType qBEdiff;
6244 
6245  fadType iBE;
6246  fadType gBE;
6247  fadType iBEleak;
6248  fadType gBEleak;
6249  fadType iBC;
6250  fadType gBC;
6251  fadType iBCleak;
6252  fadType gBCleak;
6253  fadType iCE;
6254  fadType qB;
6255  fadType invqB;
6256  fadType iBEhighCurr;
6257  fadType gBEhighCurr;
6258 
6259  fadType capeqCB;
6260  fadType geqCB;
6261 
6262  fadType capBEdep;
6263  fadType capBEdiff;
6264  fadType capBCdep;
6265  fadType capBCdiff;
6266 
6267  fadType capBX;
6268  fadType capCS;
6269 
6270  fadType diBrdvB;
6271  fadType diBrdvCp;
6272  fadType diBrdvEp;
6273  fadType diBrdvBp;
6274  fadType diCEdvEp;
6275  fadType diCEdvCp;
6276  fadType diCEdvBp;
6277  fadType diBEdvBp, diBEdvCp, diBEdvEp;
6278 
6279  fadType gBEtot;
6280  fadType gBCtot;
6281 
6282  ///////////////////////////////////////////
6283  // obtain voltages:
6284  double * solVec = inst.extData.nextSolVectorRawPtr;
6285  fadType v_emit = solVec[inst.li_Emit];
6286  fadType v_emitP = solVec[inst.li_EmitP];
6287  fadType v_base = solVec[inst.li_Base];
6288  fadType v_baseP = solVec[inst.li_BaseP];
6289  fadType v_coll = solVec[inst.li_Coll];
6290  fadType v_collP = solVec[inst.li_CollP];
6291  fadType v_subst = solVec[inst.li_Subst];
6292 
6293  fadType i_fx = 0.0;
6294  if (inst.getDeviceOptions().newExcessPhase)
6295  {
6296  i_fx = solVec[inst.li_Ifx];
6297  }
6298 
6299  fadType vEEp = (v_emit - v_emitP);
6300  fadType vBBp = (v_base - v_baseP);
6301  fadType vCCp = (v_coll - v_collP);
6302 
6303  fadType vBE = inst.model_.TYPE * (v_baseP - v_emitP);
6304  fadType vBC = inst.model_.TYPE * (v_baseP - v_collP);
6305  fadType vBX = inst.model_.TYPE * (v_base - v_collP);
6306  fadType vCS = inst.model_.TYPE * (v_subst - v_collP);
6307 
6308  fadType vBE_orig = vBE;
6309  fadType vBC_orig = vBC;
6310 
6311  ///////////////////////////////////////////
6313  (
6314  // inputs:
6315  vBE, vBC, vBX, vCS, i_fx,
6316  // instance params:
6317  AREA,
6318  // instance variables:
6319  tSatCur, vt,
6320  tleakBEEmissionCoeff, tleakBCEmissionCoeff,
6321  tBELeakCur, tBCLeakCur,
6322  tInvRollOffF, tInvRollOffR,
6323  tRollOffExp,
6324  tInvEarlyVoltF, tInvEarlyVoltR,
6325  tBECap, tBCCap,
6326  tDepCap,
6327  tBEPot, tBCPot,
6328  tF1, tF4, tF5,
6329  // from device options:
6330  inst.getDeviceOptions().gmin,
6332  // from solver state:
6333  inst.getSolverState().dcopFlag,
6334  inst.getSolverState().tranopFlag,
6335  inst.getSolverState().acopFlag,
6338  inst.getSolverState().newtonIter,
6339  inst.getSolverState().pdt_,
6340  // model params:
6341  emissionCoeffF, emissionCoeffR,
6342  baseFracBCCap, CJS,
6343  depCapCoeff, potBC,
6344  transTimeF, transTimeR,
6345  transTimeBiasCoeffF, transTimeVBCFac,
6346  transTimeHighCurrF,
6347  juncExpBE, juncExpBC,
6348  potSubst, expSubst,
6349  emitterConduct, collectorConduct, minBaseResist,
6350  baseResist, baseCurrHalfResist,
6351  excessPhaseFac,
6352  f2, f3, f6, f7,
6353  inst.model_.getLevel(),
6354  // these are here b/c of the excess phase old-DAE form
6358  inst.li_istateCEXBC,
6359  inst.getSolverState().currTimeStep_, // dt0
6360  inst.getSolverState().lastTimeStep_, // dt1
6361 
6362  // outputs:
6363  iB, iC, iE, iBE, gBE, iBC, gBC, iCE,
6364  iBEleak, gBEleak, iBCleak, gBCleak,
6365  qB, invqB, iBEhighCurr, gBEhighCurr,
6366  capeqCB, geqCB,
6367  qBEdep, capBEdep,
6368  qBEdiff, capBEdiff,
6369  qBCdep, capBCdep,
6370  qBCdiff, capBCdiff,
6371  qBX, capBX, qCS, capCS,
6372  gEpr, gCpr, gX,
6373  diBrdvB, diBrdvCp, diBrdvEp, diBrdvBp,
6374  diCEdvEp, diCEdvCp, diCEdvBp,
6375  diBEdvBp, diBEdvCp, diBEdvEp,
6376  gBEtot, gBCtot,
6377  tBetaF, tBetaR
6378  );
6379 
6380  int iColl=0;
6381  int iBase=1;
6382  int iEmit=2;
6383  int iCollP=3;
6384  int iBaseP=4;
6385  int iEmitP=5;
6386  int iSubst=6;
6387  int i_Ifx=7;
6388  int i_dIfx=8;
6389 
6390  fadType fColl = -vCCp * gCpr;
6391  fadType fBase = -vBBp * gX;
6392  fadType fEmit = -vEEp * gEpr;
6393  fadType fCollP = vCCp * gCpr + inst.model_.TYPE * ( - iC );
6394  fadType fBaseP = vBBp * gX - inst.model_.TYPE * ( iB );
6395  fadType fEmitP = vEEp * gEpr + inst.model_.TYPE * ( - iE );
6396 
6397  fadType qBase = -inst.model_.TYPE * qBX;
6398  fadType qSubst = -inst.model_.TYPE * qCS;
6399  fadType qCollP = inst.model_.TYPE * ( qCS + qBX + qBCdep + qBCdiff );
6400  fadType qBaseP = -inst.model_.TYPE * ( qBEdep + qBEdiff + qBCdep + qBCdiff );
6401  fadType qEmitP = inst.model_.TYPE*( qBEdep + qBEdiff );
6402 
6403  dfdp[iColl] -= fColl.dx(0);
6404  dfdp[iBase] -= fBase.dx(0);
6405  dfdp[iEmit] -= fEmit.dx(0);
6406  dfdp[iCollP] -= fCollP.dx(0);
6407  dfdp[iBaseP] -= fBaseP.dx(0);
6408  dfdp[iEmitP] -= fEmitP.dx(0);
6409 
6410  // excess phase ERK-dcop.
6411  fadType di_fx = 0.0;
6412  fadType td = excessPhaseFac;
6413 
6414  if (inst.getDeviceOptions().newExcessPhase)
6415  {
6416  //i_fx = solVec[i_Ifx]; (this was computed above)
6417  di_fx = solVec[i_dIfx];
6418 
6419  if (td != 0)
6420  {
6421  if (!(inst.getSolverState().dcopFlag) )
6422  {
6423  // omega0 = 1/td;
6424  fadType term = 3 * di_fx*td + 3*i_fx -3 * iBE / qB;
6425  dfdp[i_Ifx] += - di_fx.dx(0);
6426  dfdp[i_dIfx] += term.dx(0);
6427  }
6428  else
6429  {
6430  fadType term = i_fx -iBE/qB;
6431  dfdp[i_Ifx] += term.dx(0);
6432  dfdp[i_dIfx] = 0.0;
6433  }
6434  }
6435  else
6436  {
6437  dfdp[i_Ifx] += i_fx.dx(0);
6438  dfdp[i_dIfx] += di_fx.dx(0);
6439  }
6440  }
6441 
6442  dqdp[iBase] -= qBase.dx(0);
6443  dqdp[iSubst] -= qSubst.dx(0);
6444  dqdp[iCollP] -= qCollP.dx(0);
6445  dqdp[iBaseP] -= qBaseP.dx(0);
6446  dqdp[iEmitP] -= qEmitP.dx(0);
6447 
6448  // excess phase ERK-dcop
6449  if (td != 0 && inst.getDeviceOptions().newExcessPhase)
6450  {
6451  dqdp[i_Ifx] += solVec[i_Ifx];
6452 
6453  if (!(inst.getSolverState().dcopFlag) )
6454  {
6455  fadType term = solVec[i_dIfx]*td*td;
6456  dqdp[i_dIfx] += term.dx(0);
6457  }
6458  else
6459  {
6460  dqdp[i_dIfx] = 0.0;
6461  }
6462  }
6463 
6464  Findices[iColl] = inst.li_Coll;
6465  Findices[iBase] = inst.li_Base;
6466  Findices[iEmit] = inst.li_Emit;
6467  Findices[iCollP] = inst.li_CollP;
6468  Findices[iBaseP] = inst.li_BaseP;
6469  Findices[iEmitP] = inst.li_EmitP;
6470  Findices[iSubst] = inst.li_Subst;
6471  if (inst.getDeviceOptions().newExcessPhase)
6472  {
6473  Findices[i_Ifx] = inst.li_Ifx;
6474  Findices[i_dIfx] = inst.li_dIfx;
6475  }
6476 
6477  Qindices[iColl] = inst.li_Coll;
6478  Qindices[iBase] = inst.li_Base;
6479  Qindices[iEmit] = inst.li_Emit;
6480  Qindices[iCollP] = inst.li_CollP;
6481  Qindices[iBaseP] = inst.li_BaseP;
6482  Qindices[iEmitP] = inst.li_EmitP;
6483  Qindices[iSubst] = inst.li_Subst;
6484  if (inst.getDeviceOptions().newExcessPhase)
6485  {
6486  Qindices[i_Ifx] = inst.li_Ifx;
6487  Qindices[i_dIfx] = inst.li_dIfx;
6488  }
6489 }
6490 
6491 //-----------------------------------------------------------------------------
6492 // Function : bjtModelSensitivity::operator
6493 // Purpose : produces df/dp and dq/dp, where p= any bjt instance parameter.
6494 // Special Notes :
6495 // Scope : public
6496 // Creator : Eric Keiter, SNL
6497 // Creation Date : 7/18/2014
6498 //-----------------------------------------------------------------------------
6500  const ParameterBase &entity,
6501  const std::string &name,
6502  std::vector<double> & dfdp,
6503  std::vector<double> & dqdp,
6504  std::vector<double> & dbdp,
6505  std::vector<int> & Findices,
6506  std::vector<int> & Qindices,
6507  std::vector<int> & Bindices
6508  ) const
6509 {
6510  const ParameterBase * e1 = &entity;
6511  const Model & mod = *(dynamic_cast<const Model *> (e1));
6512 
6513  int sizeInstance = mod.instanceContainer.size();
6514 
6515  std::vector<Instance *>::const_iterator inTmp = mod.instanceContainer.begin();
6516  const Instance & instTmp = *((*inTmp));
6517 
6518  if (instTmp.getDeviceOptions().newExcessPhase)
6519  {
6520  dfdp.resize(9*sizeInstance);
6521  dqdp.resize(9*sizeInstance);
6522  Findices.resize(9*sizeInstance);
6523  Qindices.resize(9*sizeInstance);
6524  }
6525  else
6526  {
6527  dfdp.resize(7*sizeInstance);
6528  dqdp.resize(7*sizeInstance);
6529  Findices.resize(7*sizeInstance);
6530  Qindices.resize(7*sizeInstance);
6531  }
6532 
6533  // model params:
6534  fadType TNOM = mod.TNOM;
6535  fadType energyGap = mod.energyGap;
6536  fadType tempExpIS = mod.tempExpIS;
6537  fadType betaExp = mod.betaExp;
6538 
6539  fadType emissionCoeffF = mod.emissionCoeffF;
6540  fadType emissionCoeffR = mod.emissionCoeffR;
6541  fadType baseFracBCCap = mod.baseFracBCCap;
6542  fadType CJS = mod.CJS;
6543  fadType depCapCoeff = mod.depCapCoeff;
6544  fadType potBE = mod.potBE;
6545  fadType potBC = mod.potBC;
6546 
6547  fadType depCapBE = mod.depCapBE;
6548  fadType depCapBC = mod.depCapBC;
6549  fadType betaF = mod.betaF;
6550  fadType betaR = mod.betaR;
6551 
6552  fadType transTimeF = mod.transTimeF;
6553  fadType transTimeR = mod.transTimeR;
6554  fadType transTimeBiasCoeffF = mod.transTimeBiasCoeffF;
6555  fadType transTimeVBCFac = mod.transTimeVBCFac;
6556  fadType transTimeHighCurrF = mod.transTimeHighCurrF;
6557  fadType juncExpBE = mod.juncExpBE;
6558  fadType juncExpBC = mod.juncExpBC;
6559  fadType potSubst = mod.potSubst;
6560  fadType expSubst = mod.expSubst;
6561  fadType excessPhase = mod.excessPhase;
6562 
6563  fadType c2 = mod.c2;
6564  fadType c4 = mod.c4;
6565  fadType satCur = mod.satCur;
6566  fadType earlyVoltF = mod.earlyVoltF;
6567  fadType rollOffF = mod.rollOffF;
6568  fadType earlyVoltR = mod.earlyVoltR;
6569  fadType rollOffR = mod.rollOffR;
6570  fadType transTimeFVBC = mod.transTimeFVBC;
6571 
6572  fadType emitterConduct = mod.emitterConduct;
6573  fadType collectorConduct = mod.collectorConduct;
6574  fadType minBaseResist = mod.minBaseResist;
6575  fadType baseResist = mod.baseResist;
6576  fadType baseCurrHalfResist = mod.baseCurrHalfResist;
6577  fadType collectorResist = mod.collectorResist;
6578  fadType emitterResist = mod.emitterResist;
6579 
6580  fadType leakBECurrent = mod.leakBECurrent;
6581  fadType leakBCCurrent = mod.leakBCCurrent;
6582  fadType invEarlyVoltF = mod.invEarlyVoltF;
6583  fadType invRollOffF = mod.invRollOffF;
6584  fadType invEarlyVoltR = mod.invEarlyVoltR;
6585  fadType invRollOffR = mod.invRollOffR;
6586  fadType excessPhaseFac = mod.excessPhaseFac;
6587 
6588  fadType leakBEEmissionCoeff = mod.leakBEEmissionCoeff;
6589  fadType leakBCEmissionCoeff = mod.leakBCEmissionCoeff;
6590  fadType rollOffExp = mod.rollOffExp;
6591 
6592  // model params from processParams:
6593  fadType f2 = mod.f2;
6594  fadType f3 = mod.f3;
6595  fadType f6 = mod.f6;
6596  fadType f7 = mod.f7;
6597 
6598 #if 0
6599  // noise params. These aren't used in dc or transient sim, so commented out.
6600  fadType fNCoeff = mod.fNCoeff;
6601  fadType fNExp = mod.fNExp;
6602 #endif
6603 
6604  // assign derivative for specified param:
6605  std::string paramName = ExtendedString( name ).toUpper();
6606 
6607 
6608  if (paramName=="TNOM") { TNOM.diff(0,1); }
6609  else if (paramName=="IS") { satCur.diff(0,1); }
6610  else if (paramName=="BF") { betaF.diff(0,1); }
6611  else if (paramName=="BFM") { betaF.diff(0,1); }
6612  else if (paramName=="NF") { emissionCoeffF.diff(0,1); }
6613  else if (paramName=="VA") { earlyVoltF.diff(0,1); }
6614  else if (paramName=="VBF") { earlyVoltF.diff(0,1); }
6615  else if (paramName=="VAF") { earlyVoltF.diff(0,1); }
6616  else if (paramName=="IKF") { rollOffF.diff(0,1); }
6617  else if (paramName=="IK") { rollOffF.diff(0,1); }
6618  else if (paramName=="JBF") { rollOffF.diff(0,1); }
6619  else if (paramName=="ISE") { leakBECurrent.diff(0,1); }
6620  else if (paramName=="JLE") { leakBECurrent.diff(0,1); }
6621  else if (paramName=="NE") { leakBEEmissionCoeff.diff(0,1); }
6622  else if (paramName=="NLE") { leakBEEmissionCoeff.diff(0,1); }
6623  else if (paramName=="BR") { betaR.diff(0,1); }
6624  else if (paramName=="BRM") { betaR.diff(0,1); }
6625  else if (paramName=="NR") { emissionCoeffR.diff(0,1); }
6626  else if (paramName=="VAR") { earlyVoltR.diff(0,1); }
6627  else if (paramName=="VB") { earlyVoltR.diff(0,1); }
6628  else if (paramName=="VRB") { earlyVoltR.diff(0,1); }
6629  else if (paramName=="BV") { earlyVoltR.diff(0,1); }
6630 
6631  else if (paramName=="IKR") { rollOffR.diff(0,1); }
6632  else if (paramName=="JBR") { rollOffR.diff(0,1); }
6633  else if (paramName=="ISC") { leakBCCurrent.diff(0,1); }
6634  else if (paramName=="JLC") { leakBCCurrent.diff(0,1); }
6635  else if (paramName=="NC") { leakBCEmissionCoeff.diff(0,1); }
6636  else if (paramName=="RB") { baseResist.diff(0,1); }
6637  else if (paramName=="IRB") { baseCurrHalfResist.diff(0,1); }
6638  else if (paramName=="JRB") { baseCurrHalfResist.diff(0,1); }
6639  else if (paramName=="IOB") { baseCurrHalfResist.diff(0,1); }
6640 
6641  // next: RBM
6642  else if (paramName=="RBM") { minBaseResist.diff(0,1); }
6643  else if (paramName=="RE") { emitterResist.diff(0,1); }
6644  else if (paramName=="RC") { collectorResist.diff(0,1); }
6645  else if (paramName=="CJE") { depCapBE.diff(0,1); }
6646  else if (paramName=="VJE") { potBE.diff(0,1); }
6647  else if (paramName=="PE") { potBE.diff(0,1); }
6648  else if (paramName=="MJE") { juncExpBE.diff(0,1); }
6649  else if (paramName=="ME") { juncExpBE.diff(0,1); }
6650  else if (paramName=="TF") { transTimeF.diff(0,1); }
6651  else if (paramName=="XTF") { transTimeBiasCoeffF.diff(0,1); }
6652  else if (paramName=="VTF") { transTimeFVBC.diff(0,1); }
6653  else if (paramName=="ITF") { transTimeHighCurrF.diff(0,1); }
6654  else if (paramName=="JTF") { transTimeHighCurrF.diff(0,1); }
6655  else if (paramName=="PTF") { excessPhase.diff(0,1); }
6656  else if (paramName=="CJC") { depCapBC.diff(0,1); }
6657  else if (paramName=="VJC") { potBC.diff(0,1); }
6658  else if (paramName=="PC") { potBC.diff(0,1); }
6659  else if (paramName=="MJC") { juncExpBC.diff(0,1); }
6660  else if (paramName=="MC") { juncExpBC.diff(0,1); }
6661  else if (paramName=="XCJC") { baseFracBCCap.diff(0,1); }
6662  else if (paramName=="CDIS") { baseFracBCCap.diff(0,1); }
6663  else if (paramName=="TR") { transTimeR.diff(0,1); }
6664  else if (paramName=="CJS") { CJS.diff(0,1); }
6665  else if (paramName=="CCS") { CJS.diff(0,1); }
6666  else if (paramName=="CSUB") { CJS.diff(0,1); }
6667  else if (paramName=="VJS") { potSubst.diff(0,1); }
6668  else if (paramName=="PS") { potSubst.diff(0,1); }
6669  else if (paramName=="PSUB") { potSubst.diff(0,1); }
6670  else if (paramName=="MJS") { expSubst.diff(0,1); }
6671  else if (paramName=="MS") { expSubst.diff(0,1); }
6672  else if (paramName=="ESUB") { expSubst.diff(0,1); }
6673  else if (paramName=="XTB") { betaExp.diff(0,1); }
6674  else if (paramName=="TB") { betaExp.diff(0,1); }
6675  else if (paramName=="TCB") { betaExp.diff(0,1); }
6676  else if (paramName=="EG") { energyGap.diff(0,1); }
6677  else if (paramName=="XTI") { tempExpIS.diff(0,1); }
6678  else if (paramName=="PT") { tempExpIS.diff(0,1); }
6679 #if 0
6680  else if (paramName=="KF") { fNCoeff.diff(0,1); }
6681  else if (paramName=="AF") { fNExp.diff(0,1); }
6682 #endif
6683  else if (paramName=="FC") { depCapCoeff.diff(0,1); }
6684  else if (paramName=="C2") { c2.diff(0,1); }
6685  else if (paramName=="C4") { c4.diff(0,1); }
6686  else if (paramName=="NK") { rollOffExp.diff(0,1); }
6687  else if (paramName=="NKF") { rollOffExp.diff(0,1); }
6688 
6689  processParams(
6690  // inputs
6691  mod.leakBECurrentGiven,
6692  mod.leakBCCurrentGiven,
6693  mod.c2Given, mod.c4Given,
6694  mod.minBaseResistGiven,
6695  mod.VAFgiven, mod.IKFgiven,
6696  mod.VARgiven, mod.IKRgiven,
6697  mod.VTFgiven, mod.FCgiven,
6698 
6699  c2, c4, satCur, baseResist,
6700  earlyVoltF, rollOffF,
6701  earlyVoltR, rollOffR,
6702  collectorResist, emitterResist,
6703  transTimeFVBC,
6704  excessPhase, transTimeF,
6705  juncExpBE, juncExpBC,
6706 
6707  //outputs
6708  leakBECurrent, leakBCCurrent,
6709  minBaseResist,
6710  invEarlyVoltF, invRollOffF,
6711  invEarlyVoltR, invRollOffR,
6712 
6713  collectorConduct, emitterConduct,
6714  transTimeVBCFac,
6715  excessPhaseFac,
6716  depCapCoeff,
6717 
6718  f2, f3, f6, f7
6719  );
6720 
6721  int instIndex=0;
6722 
6723  for (std::vector<Instance *>::const_iterator in = mod.instanceContainer.begin();
6724  in != mod.instanceContainer.end(); ++in, ++instIndex)
6725  {
6726  const Instance & inst = *((*in));
6727 
6728  // instance variables:
6729  fadType TEMP = inst.TEMP;
6730  fadType AREA = inst.AREA;
6731 
6732  fadType vt = inst.vt;
6733  fadType tSatCur = inst.tSatCur;
6734  fadType tleakBEEmissionCoeff = inst.tleakBEEmissionCoeff;
6735  fadType tleakBCEmissionCoeff = inst.tleakBCEmissionCoeff;
6736  fadType tBELeakCur = inst.tBELeakCur;
6737  fadType tBCLeakCur = inst.tBCLeakCur;
6738  fadType tInvRollOffF = inst.tInvRollOffF;
6739  fadType tInvRollOffR = inst.tInvRollOffR;
6740  fadType tRollOffExp = inst.tRollOffExp;
6741  fadType tInvEarlyVoltF = inst.tInvEarlyVoltF;
6742  fadType tInvEarlyVoltR = inst.tInvEarlyVoltR;
6743  fadType tBECap = inst.tBECap;
6744  fadType tBCCap = inst.tBCCap;
6745  fadType tDepCap = inst.tDepCap;
6746  fadType tBEPot = inst.tBEPot;
6747  fadType tBCPot = inst.tBCPot;
6748  fadType tF1 = inst.tF1;
6749  fadType tF4 = inst.tF4;
6750  fadType tF5 = inst.tF5;
6751 
6752  fadType tBaseResist = inst.tBaseResist;
6753  fadType tCollectorResist = inst.tCollectorResist;
6754  fadType tEmitterResist = inst.tEmitterResist;
6755  fadType tVCrit = inst.tVCrit;
6756  fadType tBetaF = inst.tBetaF;
6757  fadType tBetaR = inst.tBetaR;
6758 
6760  // inputs
6761  // instance
6762  TEMP,
6763  // model
6764  TNOM,
6765  energyGap, tempExpIS,
6766  betaExp, potBE,
6767  depCapBE, juncExpBE,
6768  depCapBC, juncExpBC,
6769  depCapCoeff,
6770  satCur, betaF, betaR,
6771  c2, c4,
6772  inst.model_.c2Given,
6773  inst.model_.c4Given,
6774 
6775  inst.model_.leakBECurrentGiven,
6777 
6778  leakBEEmissionCoeff,
6779  leakBCEmissionCoeff,
6780 
6781  rollOffExp,
6782  baseResist,
6783  collectorResist,
6784  emitterResist,
6785  potBC,
6786  rollOffF, rollOffR,
6787  earlyVoltF, earlyVoltR,
6788 
6789  // outputs
6790  vt,
6791  leakBECurrent, leakBCCurrent,
6792  tBELeakCur, tBCLeakCur,
6793  tleakBEEmissionCoeff,
6794  tleakBCEmissionCoeff,
6795 
6796  tRollOffExp,
6797  tInvRollOffF,
6798  tInvRollOffR,
6799  tBaseResist,
6800  tCollectorResist,
6801  tEmitterResist,
6802 
6803  tBECap, tBEPot,
6804  tBCCap, tBCPot,
6805  tDepCap,
6806  tF1, tF4, tF5,
6807  tVCrit,
6808  tSatCur,
6809  tBetaF, tBetaR,
6810  tInvEarlyVoltF, tInvEarlyVoltR
6811  );
6812 
6813  // updateIntermediateVars outputs
6814  fadType gCpr;
6815  fadType gX;
6816  fadType gEpr;
6817  fadType iC;
6818  fadType iB;
6819  fadType iE;
6820  fadType qBX;
6821  fadType qCS;
6822 
6823  fadType qBCdep;
6824  fadType qBCdiff;
6825  fadType qBEdep;
6826  fadType qBEdiff;
6827 
6828  fadType iBE;
6829  fadType gBE;
6830  fadType iBEleak;
6831  fadType gBEleak;
6832  fadType iBC;
6833  fadType gBC;
6834  fadType iBCleak;
6835  fadType gBCleak;
6836  fadType iCE;
6837  fadType qB;
6838  fadType invqB;
6839  fadType iBEhighCurr;
6840  fadType gBEhighCurr;
6841 
6842  fadType capeqCB;
6843  fadType geqCB;
6844 
6845  fadType capBEdep;
6846  fadType capBEdiff;
6847  fadType capBCdep;
6848  fadType capBCdiff;
6849 
6850  fadType capBX;
6851  fadType capCS;
6852 
6853  fadType diBrdvB;
6854  fadType diBrdvCp;
6855  fadType diBrdvEp;
6856  fadType diBrdvBp;
6857  fadType diCEdvEp;
6858  fadType diCEdvCp;
6859  fadType diCEdvBp;
6860  fadType diBEdvBp, diBEdvCp, diBEdvEp;
6861 
6862  fadType gBEtot;
6863  fadType gBCtot;
6864 
6865  ///////////////////////////////////////////
6866  // obtain voltages:
6867  double * solVec = inst.extData.nextSolVectorRawPtr;
6868  fadType v_emit = solVec[inst.li_Emit];
6869  fadType v_emitP = solVec[inst.li_EmitP];
6870  fadType v_base = solVec[inst.li_Base];
6871  fadType v_baseP = solVec[inst.li_BaseP];
6872  fadType v_coll = solVec[inst.li_Coll];
6873  fadType v_collP = solVec[inst.li_CollP];
6874  fadType v_subst = solVec[inst.li_Subst];
6875 
6876  fadType i_fx = 0.0;
6877  if (inst.getDeviceOptions().newExcessPhase)
6878  {
6879  i_fx = solVec[inst.li_Ifx];
6880  }
6881 
6882  fadType vEEp = (v_emit - v_emitP);
6883  fadType vBBp = (v_base - v_baseP);
6884  fadType vCCp = (v_coll - v_collP);
6885 
6886  fadType vBE = inst.model_.TYPE * (v_baseP - v_emitP);
6887  fadType vBC = inst.model_.TYPE * (v_baseP - v_collP);
6888  fadType vBX = inst.model_.TYPE * (v_base - v_collP);
6889  fadType vCS = inst.model_.TYPE * (v_subst - v_collP);
6890 
6891  fadType vBE_orig = vBE;
6892  fadType vBC_orig = vBC;
6893 
6894  ///////////////////////////////////////////
6896  (
6897  // inputs:
6898  vBE, vBC, vBX, vCS, i_fx,
6899  // instance params:
6900  AREA,
6901  // instance variables:
6902  tSatCur, vt,
6903  tleakBEEmissionCoeff, tleakBCEmissionCoeff,
6904  tBELeakCur, tBCLeakCur,
6905  tInvRollOffF, tInvRollOffR,
6906  tRollOffExp,
6907  tInvEarlyVoltF, tInvEarlyVoltR,
6908  tBECap, tBCCap,
6909  tDepCap,
6910  tBEPot, tBCPot,
6911  tF1, tF4, tF5,
6912  // from device options:
6913  inst.getDeviceOptions().gmin,
6915  // from solver state:
6916  inst.getSolverState().dcopFlag,
6917  inst.getSolverState().tranopFlag,
6918  inst.getSolverState().acopFlag,
6921  inst.getSolverState().newtonIter,
6922  inst.getSolverState().pdt_,
6923  // model params:
6924  emissionCoeffF, emissionCoeffR,
6925  baseFracBCCap, CJS,
6926  depCapCoeff, potBC,
6927  transTimeF, transTimeR,
6928  transTimeBiasCoeffF, transTimeVBCFac,
6929  transTimeHighCurrF,
6930  juncExpBE, juncExpBC,
6931  potSubst, expSubst,
6932  emitterConduct, collectorConduct, minBaseResist,
6933  baseResist, baseCurrHalfResist,
6934  excessPhaseFac,
6935  f2, f3, f6, f7,
6936  inst.model_.getLevel(),
6937 
6938  // these are here b/c of the excess phase old-DAE form
6942  inst.li_istateCEXBC,
6943  inst.getSolverState().currTimeStep_, // dt0
6944  inst.getSolverState().lastTimeStep_, // dt1
6945 
6946  // outputs:
6947  iB, iC, iE, iBE, gBE, iBC, gBC, iCE,
6948  iBEleak, gBEleak, iBCleak, gBCleak,
6949  qB, invqB, iBEhighCurr, gBEhighCurr,
6950  capeqCB, geqCB,
6951  qBEdep, capBEdep,
6952  qBEdiff, capBEdiff,
6953  qBCdep, capBCdep,
6954  qBCdiff, capBCdiff,
6955  qBX, capBX, qCS, capCS,
6956  gEpr, gCpr, gX,
6957  diBrdvB, diBrdvCp, diBrdvEp, diBrdvBp,
6958  diCEdvEp, diCEdvCp, diCEdvBp,
6959  diBEdvBp, diBEdvCp, diBEdvEp,
6960  gBEtot, gBCtot,
6961  tBetaF, tBetaR
6962  );
6963 
6964  int iColl=0+instIndex*7;
6965  int iBase=1+instIndex*7;
6966  int iEmit=2+instIndex*7;
6967  int iCollP=3+instIndex*7;
6968  int iBaseP=4+instIndex*7;
6969  int iEmitP=5+instIndex*7;
6970  int iSubst=6+instIndex*7;
6971 
6972  int i_Ifx=7+instIndex*7;
6973  int i_dIfx=8+instIndex*7;
6974 
6975  fadType fColl = -vCCp * gCpr;
6976  fadType fBase = -vBBp * gX;
6977  fadType fEmit = -vEEp * gEpr;
6978  fadType fCollP = vCCp * gCpr + inst.model_.TYPE * ( - iC );
6979  fadType fBaseP = vBBp * gX - inst.model_.TYPE * ( iB );
6980  fadType fEmitP = vEEp * gEpr + inst.model_.TYPE * ( - iE );
6981 
6982  fadType qBase = -inst.model_.TYPE * qBX;
6983  fadType qSubst = -inst.model_.TYPE * qCS;
6984  fadType qCollP = inst.model_.TYPE * ( qCS + qBX + qBCdep + qBCdiff );
6985  fadType qBaseP = -inst.model_.TYPE * ( qBEdep + qBEdiff + qBCdep + qBCdiff );
6986  fadType qEmitP = inst.model_.TYPE*( qBEdep + qBEdiff );
6987 
6988  dfdp[iColl] -= fColl.dx(0);
6989  dfdp[iBase] -= fBase.dx(0);
6990  dfdp[iEmit] -= fEmit.dx(0);
6991  dfdp[iCollP] -= fCollP.dx(0);
6992  dfdp[iBaseP] -= fBaseP.dx(0);
6993  dfdp[iEmitP] -= fEmitP.dx(0);
6994 
6995  // excess phase ERK-dcop.
6996  fadType di_fx = 0.0;
6997  fadType td = excessPhaseFac;
6998 
6999  if (inst.getDeviceOptions().newExcessPhase)
7000  {
7001  //i_fx = solVec[i_Ifx]; (this was computed above)
7002  di_fx = solVec[i_dIfx];
7003 
7004  if (td != 0)
7005  {
7006  if (!(inst.getSolverState().dcopFlag) )
7007  {
7008  // omega0 = 1/td;
7009  fadType term = 3 * di_fx*td + 3*i_fx -3 * iBE / qB;
7010  dfdp[i_Ifx] += - di_fx.dx(0);
7011  dfdp[i_dIfx] += term.dx(0);
7012  }
7013  else
7014  {
7015  fadType term = i_fx -iBE/qB;
7016  dfdp[i_Ifx] += term.dx(0);
7017  dfdp[i_dIfx] = 0.0;
7018  }
7019  }
7020  else
7021  {
7022  dfdp[i_Ifx] += i_fx.dx(0);
7023  dfdp[i_dIfx] += di_fx.dx(0);
7024  }
7025  }
7026 
7027  dqdp[iBase] -= qBase.dx(0);
7028  dqdp[iSubst] -= qSubst.dx(0);
7029  dqdp[iCollP] -= qCollP.dx(0);
7030  dqdp[iBaseP] -= qBaseP.dx(0);
7031  dqdp[iEmitP] -= qEmitP.dx(0);
7032 
7033  // excess phase ERK-dcop
7034  if (td != 0 && inst.getDeviceOptions().newExcessPhase)
7035  {
7036  dqdp[i_Ifx] += solVec[i_Ifx];
7037 
7038  if (!(inst.getSolverState().dcopFlag) )
7039  {
7040  fadType term = solVec[i_dIfx]*td*td;
7041  dqdp[i_dIfx] += term.dx(0);
7042  }
7043  else
7044  {
7045  dqdp[i_dIfx] = 0.0;
7046  }
7047  }
7048 
7049  Findices[iColl] = inst.li_Coll;
7050  Findices[iBase] = inst.li_Base;
7051  Findices[iEmit] = inst.li_Emit;
7052  Findices[iCollP] = inst.li_CollP;
7053  Findices[iBaseP] = inst.li_BaseP;
7054  Findices[iEmitP] = inst.li_EmitP;
7055  Findices[iSubst] = inst.li_Subst;
7056  if (inst.getDeviceOptions().newExcessPhase)
7057  {
7058  Findices[i_Ifx] = inst.li_Ifx;
7059  Findices[i_dIfx] = inst.li_dIfx;
7060  }
7061 
7062  Qindices[iColl] = inst.li_Coll;
7063  Qindices[iBase] = inst.li_Base;
7064  Qindices[iEmit] = inst.li_Emit;
7065  Qindices[iCollP] = inst.li_CollP;
7066  Qindices[iBaseP] = inst.li_BaseP;
7067  Qindices[iEmitP] = inst.li_EmitP;
7068  Qindices[iSubst] = inst.li_Subst;
7069  if (inst.getDeviceOptions().newExcessPhase)
7070  {
7071  Qindices[i_Ifx] = inst.li_Ifx;
7072  Qindices[i_dIfx] = inst.li_dIfx;
7073  }
7074  }
7075 }
7076 
7077 
7078 } // namespace BJT
7079 } // namespace Device
7080 } // namespace Xyce
const InstanceName & getName() const
Linear::Vector * lastStaVectorPtr
static void initThermalModel(ParametricData< T > &parametric_data)
Add the parameter "TEMPMODEL" to the parametric_data.
static std::vector< std::vector< int > > jacMap2_RB_RC_RE_
Definition: N_DEV_BJT.h:1001
const DeviceOptions & deviceOptions_
const std::vector< std::vector< int > > & jacobianStamp() const
Definition: N_DEV_BJT.C:1570
Descriptor & addPar(const char *parName, T default_value, T U::*varPtr)
Adds the parameter description to the parameter map.
Definition: N_DEV_Pars.h:1429
#define CONSTEg0
Definition: N_DEV_Const.h:73
Instance(const Configuration &configuration, const InstanceBlock &IB, Model &it_MB, const FactoryBlock &factory_block)
Definition: N_DEV_BJT.C:822
static std::vector< int > jacMap_RB_RE_
Definition: N_DEV_BJT.h:994
double pdt_
Previous delta time alpha/dt (Many devices)
double currTimeStep_
Region, BJT, Digital, ThermalResistor, ROM, Charon, Others.
#define CONSTQ
Definition: N_DEV_Const.h:51
#define CONSTREFTEMP
Definition: N_DEV_Const.h:56
double pnjlim(double vnew, double vold, double vt, double vcrit, int *icheck)
bool initTranFlag_
RxnSet, TRA, LTRA, ACC, MOSFET, BJT, true only on very first(t=0) time step.
bool given(const std::string &parameter_name) const
Pure virtual class to augment a linear system.
Parameter may be specified as time dependent expression from netlist.
Definition: N_DEV_Pars.h:67
virtual bool updateSecondaryState(double *staDeriv, double *stoVec)
Updates the devices secondary state information.
Definition: N_DEV_BJT.C:4284
void addInternalNode(Util::SymbolTable &symbol_table, int index, const InstanceName &instance_name, const std::string &lead_name)
const std::string & getEncodedName() const
Return the instance name encoded as: [s:]*xname [s:]*Ytype!name [s:]*Utype!name!count.
bool updateIntermediateVars(const ScalarT &vBE, const ScalarT &vBC, const ScalarT &vBX, const ScalarT &vCS, const ScalarT &i_fx, const ScalarT &AREA, const ScalarT &tSatCur, const ScalarT &vt, const ScalarT &tleakBEEmissionCoeff, const ScalarT &tleakBCEmissionCoeff, const ScalarT &tBELeakCur, const ScalarT &tBCLeakCur, const ScalarT &tInvRollOffF, const ScalarT &tInvRollOffR, const ScalarT &tRollOffExp, const ScalarT &tInvEarlyVoltF, const ScalarT &tInvEarlyVoltR, const ScalarT &tBECap, const ScalarT &tBCCap, const ScalarT &tDepCap, const ScalarT &tBEPot, const ScalarT &tBCPot, const ScalarT &tF1, const ScalarT &tF4, const ScalarT &tF5, const double &gmin, const bool newExcessPhase, const bool dcopFlag, const bool tranopFlag, const bool acopFlag, const bool initTranFlag, const bool beginIntegrationFlag, const int newtonIter, const double pdt, const ScalarT &emissionCoeffF, const ScalarT &emissionCoeffR, const ScalarT &baseFracBCCap, const ScalarT &CJS, const ScalarT &depCapCoeff, const ScalarT &potBC, const ScalarT &transTimeF, const ScalarT &transTimeR, const ScalarT &transTimeBiasCoeffF, const ScalarT &transTimeVBCFac, const ScalarT &transTimeHighCurrF, const ScalarT &juncExpBE, const ScalarT &juncExpBC, const ScalarT &potSubst, const ScalarT &expSubst, const ScalarT &emitterConduct, const ScalarT &collectorConduct, const ScalarT &minBaseResist, const ScalarT &baseResist, const ScalarT &baseCurrHalfResist, const ScalarT &excessPhaseFac, const ScalarT &f2, const ScalarT &f3, const ScalarT &f6, const ScalarT &f7, const int level, double *nextStaVec, double *currStaVec, double *lastStaVec, const int li_istateCEXBC, const double dt0, const double dt1, ScalarT &iB, ScalarT &iC, ScalarT &iE, ScalarT &iBE, ScalarT &gBE, ScalarT &iBC, ScalarT &gBC, ScalarT &iCE, ScalarT &iBEleak, ScalarT &gBEleak, ScalarT &iBCleak, ScalarT &gBCleak, ScalarT &qB, ScalarT &invqB, ScalarT &iBEhighCurr, ScalarT &gBEhighCurr, ScalarT &capeqCB, ScalarT &geqCB, ScalarT &qBEdep, ScalarT &capBEdep, ScalarT &qBEdiff, ScalarT &capBEdiff, ScalarT &qBCdep, ScalarT &capBCdep, ScalarT &qBCdiff, ScalarT &capBCdiff, ScalarT &qBX, ScalarT &capBX, ScalarT &qCS, ScalarT &capCS, ScalarT &gEpr, ScalarT &gCpr, ScalarT &gX, ScalarT &diBrdvB, ScalarT &diBrdvCp, ScalarT &diBrdvEp, ScalarT &diBrdvBp, ScalarT &diCEdvEp, ScalarT &diCEdvCp, ScalarT &diCEdvBp, ScalarT &diBEdvBp, ScalarT &diBEdvCp, ScalarT &diBEdvEp, ScalarT &gBEtot, ScalarT &gBCtot, ScalarT &tBetaF, ScalarT &tBetaR)
Definition: N_DEV_BJT.C:5383
void registerDevice()
Definition: N_DEV_BJT.C:4728
static std::vector< std::vector< int > > jacStamp_RB_RC_
Definition: N_DEV_BJT.h:984
double lastTimeStep_
BJT, Others.
#define CONSTMAX_EXP_ARG
Definition: N_DEV_Const.h:110
void setNumStoreVars(int num_store_vars)
void addBranchDataNode(Util::SymbolTable &symbol_table, int index, const InstanceName &instance_name, const std::string &lead_name)
void makeVector(const std::string &cname, int len)
Allows the parameter to be specified as a vector.
Definition: N_DEV_Pars.h:1597
std::vector< int > li_Neg
InstanceVector::const_iterator getInstanceEnd() const
Returns an iterator to the ending of the vector of all instances created for this device...
Base class for all parameters.
Definition: N_DEV_Pars.h:169
static std::vector< std::vector< int > > jacStamp_RB_RC_RE_
Definition: N_DEV_BJT.h:983
#define AssertLIDs(cmp)
std::vector< int > li_Pos
void registerJacLIDs(const std::vector< std::vector< int > > &jacLIDVec)
Definition: N_DEV_BJT.C:1616
Parameter is subject to being set to minimum junction capacitance.
Definition: N_DEV_Pars.h:71
static std::vector< int > jacMap_RE_
Definition: N_DEV_BJT.h:998
virtual void registerJacLIDs(const JacobianStamp &jacLIDVec)
static std::vector< int > jacMap_RB_RC_
Definition: N_DEV_BJT.h:993
Parameter is subject to being set to minimum lead resistance.
Definition: N_DEV_Pars.h:70
static Device * factory(const Configuration &configuration, const FactoryBlock &factory_block)
Definition: N_DEV_BJT.C:4722
void loadNodeSymbols(Util::SymbolTable &symbol_table) const
Populates and returns the store name map.
Definition: N_DEV_BJT.C:1445
void registerLIDs(const std::vector< int > &intLIDVecRef, const std::vector< int > &extLIDVecRef)
Definition: N_DEV_BJT.C:1326
double tnom
nominal temperature for device params.
static std::vector< std::vector< int > > jacStamp_RB_RE_
Definition: N_DEV_BJT.h:985
static std::vector< std::vector< int > > jacStamp_RE_
Definition: N_DEV_BJT.h:989
InstanceVector::const_iterator getInstanceBegin() const
Returns an iterator to the beginning of the vector of all instances created for this device...
#define N_MINLOG
Definition: N_ANP_NOISE.C:108
std::vector< Param > params
Parameters from the line.
const std::string & getName(const C *c)
Returns the name of the specified object.
std::vector< double > noiseDens
std::vector< std::string > noiseNames
void auxDAECalculations(const ScalarT &i_fx, const ScalarT &td, const ScalarT &iBE, const ScalarT &iBEleak, const ScalarT &iBC, const ScalarT &iBCleak, const ScalarT &qB, const ScalarT &invqB, const ScalarT &tBetaF, const ScalarT &tBetaR, const ScalarT &gBC, const ScalarT &gBE, const ScalarT &dqBdvBp, const ScalarT &dqBdvCp, const ScalarT &dqBdvEp, bool dcopFlag, ScalarT &iCE, ScalarT &iC, ScalarT &iB, ScalarT &iE, ScalarT &diCEdvBp, ScalarT &diCEdvCp, ScalarT &diCEdvEp, ScalarT &diBEdvBp, ScalarT &diBEdvCp, ScalarT &diBEdvEp)
Definition: N_DEV_BJT.C:5279
void setParams(const std::vector< Param > &params)
void registerStoreLIDs(const std::vector< int > &stoLIDVecRef)
Definition: N_DEV_BJT.C:1519
const std::string & getName() const
The FactoryBlock contains parameters needed by the device, instance and model creation functions...
static std::vector< int > jacMap_RC_
Definition: N_DEV_BJT.h:997
bool beginIntegrationFlag_
BJT, true if 1st time step out of breakpoint (incl. t=0)
static std::vector< std::vector< int > > jacMap2_RE_
Definition: N_DEV_BJT.h:1007
const DeviceOptions & getDeviceOptions() const
void setupNoiseSources(Xyce::Analysis::NoiseData &noiseData)
Definition: N_DEV_BJT.C:2645
#define CONSTroot2
Definition: N_DEV_Const.h:50
virtual void operator()(const ParameterBase &entity, const std::string &param, std::vector< double > &dfdp, std::vector< double > &dqdp, std::vector< double > &dbdp, std::vector< int > &Findices, std::vector< int > &Qindices, std::vector< int > &Bindices) const
Definition: N_DEV_BJT.C:5996
static std::vector< int > jacMap_
Definition: N_DEV_BJT.h:999
static std::vector< std::vector< int > > jacStamp_RB_
Definition: N_DEV_BJT.h:987
double Xexp(double, double &, double)
static std::vector< std::vector< int > > jacStamp_RC_RE_
Definition: N_DEV_BJT.h:986
virtual void registerBranchDataLIDs(const std::vector< int > &branchLIDVecRef)
Definition: N_DEV_BJT.C:1549
Linear::Vector * deviceErrorWeightMask_
bool processParams(bool leakBECurrentGiven, bool leakBCCurrentGiven, bool c2Given, bool c4Given, bool minBaseResistGiven, bool VAFgiven, bool IKFgiven, bool VARgiven, bool IKRgiven, bool VTFgiven, bool FCgiven, const ScalarT &c2, const ScalarT &c4, const ScalarT &satCur, const ScalarT &baseResist, const ScalarT &earlyVoltF, const ScalarT &rollOffF, const ScalarT &earlyVoltR, const ScalarT &rollOffR, const ScalarT &collectorResist, const ScalarT &emitterResist, const ScalarT &transTimeFVBC, const ScalarT &excessPhase, const ScalarT &transTimeF, const ScalarT &juncExpBE, const ScalarT &juncExpBC, ScalarT &leakBECurrent, ScalarT &leakBCCurrent, ScalarT &minBaseResist, ScalarT &invEarlyVoltF, ScalarT &invRollOffF, ScalarT &invEarlyVoltR, ScalarT &invRollOffR, ScalarT &collectorConduct, ScalarT &emitterConduct, ScalarT &transTimeVBCFac, ScalarT &excessPhaseFac, ScalarT &depCapCoeff, ScalarT &f2, ScalarT &f3, ScalarT &f6, ScalarT &f7)
Definition: N_DEV_BJT.C:4925
static Config< T > & addConfiguration()
Adds the device to the Xyce device configuration.
static std::vector< std::vector< int > > jacMap2_RB_RE_
Definition: N_DEV_BJT.h:1003
Sacado::Fad::SFad< double, 1 > fadType
Definition: N_DEV_BJT.h:65
static std::vector< std::vector< int > > jacMap2_RB_
Definition: N_DEV_BJT.h:1005
Parameter uses temperature interpolation based on log of value.
Definition: N_DEV_Pars.h:69
Linear::Matrix * dFdxMatrixPtr
void oldDAEExcessPhaseCalculation1(const ScalarT &td, const ScalarT &qB, const ScalarT &iBE, bool dcopFlag, bool beginIntegrationFlag, double *currStaVec, double *lastStaVec, const int li_istateCEXBC)
Definition: N_DEV_BJT.h:263
const DeviceOptions & getDeviceOptions() const
Returns the device options given during device construction.
static std::vector< int > jacMap_RB_
Definition: N_DEV_BJT.h:996
The Device class is an interface for device implementations.
Definition: N_DEV_Device.h:101
bool processInstanceParams()
processInstanceParams
Definition: N_DEV_BJT.C:3706
void addStoreNode(Util::SymbolTable &symbol_table, int index, const InstanceName &instance_name, const std::string &lead_name)
virtual std::ostream & printOutInstances(std::ostream &os) const
Definition: N_DEV_BJT.C:4167
virtual void forEachInstance(DeviceInstanceOp &op) const
Apply a device instance "op" to all instances associated with this model.
Definition: N_DEV_BJT.C:4209
virtual bool loadDAEMatrices(Linear::Matrix &dFdx, Linear::Matrix &dQdx)
Populates the device's Jacobian object with these pointers.
Definition: N_DEV_BJT.C:4506
static bjtModelSensitivity bjtModelSens
Definition: N_DEV_BJT.h:118
virtual bool updateState(double *solVec, double *staVec, double *stoVec)
Updates the devices state information.
Definition: N_DEV_BJT.C:4228
const SolverState & solverState_
bool updateTemperature(const double &temp=-999.0)
Definition: N_DEV_BJT.C:1863
Class Configuration contains device configuration data.
std::vector< double > lnNoiseDens
virtual bool loadDAEVectors(double *solVec, double *fVec, double *qVec, double *bVec, double *storeLeadF, double *storeLeadQ, double *leadF, double *leadQ, double *junctionV)
Populates the device's ExternData object with these pointers.
Definition: N_DEV_BJT.C:4315
static std::vector< std::vector< int > > jacStamp_RC_
Definition: N_DEV_BJT.h:988
virtual void operator()(const ParameterBase &entity, const std::string &param, std::vector< double > &dfdp, std::vector< double > &dqdp, std::vector< double > &dbdp, std::vector< int > &Findices, std::vector< int > &Qindices, std::vector< int > &Bindices) const
Definition: N_DEV_BJT.C:6499
void getNoiseSources(Xyce::Analysis::NoiseData &noiseData)
Definition: N_DEV_BJT.C:2700
void jacStampMap(const JacobianStamp &stamp_parent, IdVector &map_parent, JacobianStamp &map2_parent, JacobianStamp &stamp, IdVector &map, JacobianStamp &map2, int from, int to, int original_size)
static void loadInstanceParameters(ParametricData< Instance > &instance_parameters)
Definition: N_DEV_BJT.C:73
bool updateTemperature( const ScalarT &TEMP, const ScalarT &TNOM, const ScalarT &energyGap, const ScalarT &tempExpIS, const ScalarT &betaExp, const ScalarT &potBE, const ScalarT &depCapBE, const ScalarT &juncExpBE, const ScalarT &depCapBC, const ScalarT &juncExpBC, const ScalarT &depCapCoeff, const ScalarT &satCur, const ScalarT &betaF, const ScalarT &betaR, const ScalarT &c2, const ScalarT &c4, bool c2Given, bool c4Given, bool leakBECurrentGiven, bool leakBCCurrentGiven, const ScalarT &leakBEEmissionCoeff, const ScalarT &leakBCEmissionCoeff, const ScalarT &rollOffExp, const ScalarT &baseResist, const ScalarT &collectorResist, const ScalarT &emitterResist, const ScalarT &potBC, const ScalarT &rollOffF, const ScalarT &rollOffR, const ScalarT &earlyVoltF, const ScalarT &earlyVoltR, ScalarT &vt, ScalarT &leakBECurrent, ScalarT &leakBCCurrent, ScalarT &tBELeakCur, ScalarT &tBCLeakCur, ScalarT &tleakBEEmissionCoeff, ScalarT &tleakBCEmissionCoeff, ScalarT &tRollOffExp, ScalarT &tInvRollOffF, ScalarT &tInvRollOffR, ScalarT &tBaseResist, ScalarT &tCollectorResist, ScalarT &tEmitterResist, ScalarT &tBECap, ScalarT &tBEPot, ScalarT &tBCCap, ScalarT &tBCPot, ScalarT &tDepCap, ScalarT &tF1, ScalarT &tF4, ScalarT &tF5, ScalarT &tVCrit, ScalarT &tSatCur, ScalarT &tBetaF, ScalarT &tBetaR, ScalarT &tInvEarlyVoltF, ScalarT &tInvEarlyVoltR)
Definition: N_DEV_BJT.C:4744
std::vector< Instance * > instanceContainer
Definition: N_DEV_BJT.h:1062
static std::vector< std::vector< int > > jacMap2_
Definition: N_DEV_BJT.h:1008
const SolverState & getSolverState() const
void lambertw(double x, double &w, int &ierr, double &xi)
#define M_PI
static std::vector< int > jacMap_RB_RC_RE_
Definition: N_DEV_BJT.h:992
Linear::Vector * nextStoVectorPtr
#define CONSTbetaEg
Definition: N_DEV_Const.h:75
bool lambertWCurrent(double &Id, double &Gd, double Vd, double Vte, double Isat)
Definition: N_DEV_BJT.C:2038
void setNumBranchDataVars(int num_branch_data_vars)
Linear::Vector * currStaVectorPtr
void registerStateLIDs(const std::vector< int > &stateLIDVecRef)
Definition: N_DEV_BJT.C:1493
#define Xyce_NONPOINTER_MATRIX_LOAD
Definition: N_DEV_Bsrc.C:97
void oldDAEExcessPhaseCalculation2(double &iEX, double &gEX, double &iC_local)
Definition: N_DEV_BJT.C:2789
void noiseSupport(double &noise, double &lnNoise, const int type, const double param, const double temp)
const std::string & getType() const
void oldDAEExcessPhaseCalculation2(const ScalarT &td, const ScalarT &qB, const ScalarT &iBE, const ScalarT &gBE, const double dt0, const double dt1, bool dcopFlag, bool beginIntegrationFlag, double *nextStaVec, const double *currStaVec, const double *lastStaVec, const int li_istateCEXBC, ScalarT &iEX, ScalarT &gEX, ScalarT &iC_local)
Definition: N_DEV_BJT.h:302
double gmin
minimum allowed conductance.
#define RS
static std::vector< int > jacMap_RC_RE_
Definition: N_DEV_BJT.h:995
#define CONSTKoverQ
Definition: N_DEV_Const.h:58
Linear::Vector * currStoVectorPtr
bool processParams()
processParams
Definition: N_DEV_BJT.C:3625
ModelBlock represents a .MODEL line from the netlist.
bool outputPlotFiles(bool force_final_output)
Definition: N_DEV_BJT.C:3552
#define CONSTalphaEg
Definition: N_DEV_Const.h:74
Manages parameter binding for class C.
Definition: N_DEV_Pars.h:214
InstanceBlock represent a device instance line from the netlist.
double currTime_
DeviceEntity for expression time, breakpoints DeviceMgr for dependent parameters, breakpoints...
static std::vector< std::vector< int > > jacStamp_
Definition: N_DEV_BJT.h:990
bool initJctFlag_
true if on the first newton step of the first dcop solve of the first .STEP iteration. BJT, JFET, Diode, MOSFET, SW, Extern
int getNumNoiseSources() const
Definition: N_DEV_BJT.C:2632
Util::Param temp
operating temperature of ckt.
std::vector< Param > params
Linear::Matrix * dQdxMatrixPtr
#define CONSTEg300
Definition: N_DEV_Const.h:72
static std::vector< std::vector< int > > jacMap2_RB_RC_
Definition: N_DEV_BJT.h:1002
static std::vector< std::vector< int > > jacMap2_RC_
Definition: N_DEV_BJT.h:1006
Linear::Vector * flagSolVectorPtr
static std::vector< std::vector< int > > jacMap2_RC_RE_
Definition: N_DEV_BJT.h:1004
const SolverState & getSolverState() const
Returns the solver state given during device construction.
void setModParams(const std::vector< Param > &params)
static bjtInstanceSensitivity bjtInstanceSens
Definition: N_DEV_BJT.h:117
static void loadModelParameters(ParametricData< Model > &model_parameters)
Definition: N_DEV_BJT.C:116
#define CONSTboltz
Definition: N_DEV_Const.h:53