Xyce  6.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
N_DEV_DiodePDE.h
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-2014 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 //-----------------------------------------------------------------------------
27 // Filename : $RCSfile: N_DEV_DiodePDE.h,v $
28 //
29 // Purpose : This file contains the classes neccessary for a PDE
30 // based diode simulation.
31 //
32 // Special Notes :
33 //
34 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
35 //
36 // Creation Date : 02/28/00
37 //
38 // Revision Information:
39 // ---------------------
40 //
41 // Revision Number: $Revision: 1.80.2.1 $
42 //
43 // Revision Date : $Date: 2014/02/26 20:16:31 $
44 //
45 // Current Owner : $Author: tvrusso $
46 //-----------------------------------------------------------------------------
47 
48 #ifndef Xyce_N_DEV_DiodePDE_h
49 #define Xyce_N_DEV_DiodePDE_h
50 
51 // ---------- Xyce Includes ----------
52 #include <N_DEV_Configuration.h>
53 #include <N_DEV_fwd.h>
54 #include <N_DEV_DeviceBlock.h>
55 #include <N_DEV_Configuration.h>
57 #include <N_DEV_DevicePDEModel.h>
58 #include <N_DEV_bcData.h>
59 #include <N_DEV_CompositeParam.h>
60 #include <N_DEV_PDE_Electrode.h>
61 
62 #include <N_DEV_Param.h>
63 #include <N_UTL_BreakPoint.h>
64 #include <N_UTL_Expression.h>
65 
66 namespace Xyce {
67 namespace Device {
68 namespace DiodePDE {
69 
70 class Model;
71 class Instance;
72 
73 struct Traits : public DeviceTraits<Model, Instance>
74 {
75  static const char *name() {return "1D PDE Device";}
76  static const char *deviceTypeName() {return "PDE level 3";}
77  static const int numNodes() {return 2;}
78  static const int numOptionalNodes() {return 100;}
79  static const bool modelRequired() {return true;}
80  static const bool isPDEDevice() {return true;}
81  static const bool isLinearDevice() {return false;}
82 
83  static Device *factory(const Configuration &configuration, const FactoryBlock &factory_block);
84  static void loadModelParameters(ParametricData<Model> &model_parameters);
85  static void loadInstanceParameters(ParametricData<Instance> &instance_parameters);
86 };
87 
88 //-----------------------------------------------------------------------------
89 // Class : Instance
90 // Purpose : Instance class for DiodePDE.
91 //
92 // Special Notes :6
93 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
94 // Creation Date : 6/29/00
95 //-----------------------------------------------------------------------------
97 {
98  friend class Model;
99  friend class ParametricData<Instance>;
100  friend class Traits;
101 
102 public:
103  Instance(
104  const Configuration & configuration,
105  const InstanceBlock & IB,
106  Model & model,
107  const FactoryBlock & factory_block);
108 
109  Instance(const Instance &right);
110  ~Instance();
111 
112  CompositeParam *constructComposite (const std::string & ccompositeName, const std::string & paramName);
113 
114  std::map<int,std::string> & getIntNameMap ();
115 
116  void registerLIDs( const std::vector<int> & intLIDVecRef,
117  const std::vector<int> & extLIDVecRef );
118  void registerStateLIDs( const std::vector<int> & staLIDVecRef );
119 
120  const std::vector< std::vector<int> > & jacobianStamp() const;
121  void registerJacLIDs( const std::vector< std::vector<int> > & jacLIDVec );
122 
123  void setupPointers();
124 
125  bool processParams ();
126 
127  bool doAllocations ();
128  bool setupNodes ();
129 
130  bool setupNumVars ();
131 
132  bool setupJacStamp ();
133  bool cleanupJacStamp ();
134 
135  bool updateIntermediateVars ();
136  bool updatePrimaryState ();
137  bool updateSecondaryState ();
138 
139  bool loadDeviceMask ();
140 
141  // functions that are used by both new-DAE and old-DAE:
142  bool loadVecNLPoisson (double * rhs);
143  bool loadMatNLPoisson (N_LAS_Matrix & mat);
144  bool loadMatKCLDDForm (N_LAS_Matrix & mat);
145  bool loadMatDDForm (N_LAS_Matrix & mat);
146  bool loadVecDDForm (double * rhs);
147  bool loadMatCktTrivial (N_LAS_Matrix & mat);
148  // end of the "both" DAE functions.
149 
150  bool setInitialGuess ();
151  bool loadRHSNonlinPoisson ();
152  bool loadRHSDDFormulation ();
154 
155  bool getInstanceBreakPoints( std::vector<N_UTL_BreakPoint> &breakPointTimes);
156 
157  bool plotfileFlag () {return true;}
158 
159  bool loadJacNonlinPoisson ();
160  bool loadJacKCLDDFormulation ();
161  bool loadJacDDFormulation ();
163 
164  // load functions, residual:
165  bool loadDAEQVector ();
166  bool loadDAEQDDFormulation ();
168 
169  bool loadDAEFVector ();
170  bool loadDAEFNonlinPoisson ();
171  bool loadDAEFDDFormulation ();
173 
174  // load functions, Jacobian:
175  bool loadDAEdQdx ();
176 
177  bool loadDAEdQdxDDFormulation ();
179 
180  bool loadDAEdFdx ();
181  bool loadDAEdFdxNonlinPoisson ();
182  bool loadDAEdFdxDDFormulation ();
184 
185  bool calcLifetimes ();
186  bool calcMobilities ();
187  bool updateTemperature(const double & temp_tmp);
188  bool calcVoltDepDensities ();
189 
190  bool setEH_inChemistry ();
191 
192  bool setupSourceProfile ();
193 
194  bool setupDopingProfile ();
195  bool calcDopingProfile ();
196 
197  bool setupMesh ();
198  bool calcInitialGuess ();
199  bool obtainSolution ();
200  bool obtainNodeVoltages ();
201  bool applyVoltageLimiting ();
202  bool calcVequBCs ();
203  bool calcDensityBCs ();
204  bool calcBoundaryConditions ();
205  bool setupMiscConstants ();
206  bool setupScalingVars ();
207  bool scaleVariables ();
208  bool unScaleVariables ();
209 
210  bool calcRecombination ();
211  bool calcElectronCurrent ();
212  bool calcHoleCurrent ();
213  bool calcEfield ();
214 
215  bool calcTerminalCurrents ();
216  bool calcConductance (int iElectrode, const N_LAS_Vector * dxdvPtr);
217  bool calcDXDV ();
218  bool loadDFDV (int ielectrode, N_LAS_Vector * dfdvPtr);
219 
220  bool pdRecombination ();
221  bool pdElectronCurrent ();
222  bool pdHoleCurrent ();
223  bool pdTerminalCurrents ();
224 
225  bool outputTecplot ();
226  bool outputSgplot ();
227 
228  bool enablePDEContinuation ();
229  bool disablePDEContinuation ();
230  void setPDEContinuationAlpha (double alpha);
231 
232  // bool continuationStatus();
233  // void changeContinuationStepSize(double scale);
234  // void updateOldContinuationParam();
235 
236  bool outputPlotFiles ();
237 
238 public:
239  // iterator reference to the resistor model which owns this instance.
240  // Getters and setters
242  {
243  return model_;
244  }
245 
246 private:
247 
248  Model & model_; //< Owning model
249 
256 
260 
261  // physical constants:
262 
263  double Emax; // maximum electric field (V/cm)
264 
265  double VminExp; // maximum potential (V), used in exponential expressions
266  double VmaxExp; // minimum potential (V), used in exponential expressions
267 
268  double diodeCap; // estimated diode capacitance (F)
269 
270  double LeadCurrent;
271 
272  // inputted doping profiles.
273  // pdope is often phosphorus
274  std::vector<double> xloc_pdope_vec;
275  std::vector<double> pdope_vec;
276  std::vector<double> y2_pdope_vec;
277 
278  // ndope is often boron.
279  std::vector<double> xloc_ndope_vec;
280  std::vector<double> ndope_vec;
281  std::vector<double> y2_ndope_vec;
282 
283  // source file arrays
284  std::vector<double> xloc_source_vec;
285  std::vector<double> source_vec;
286  std::vector<double> y2_source_vec;
287 
288  // temp spline arrays:
289  std::vector<double> xlocVec;
290  std::vector<double> specVec;
291  std::vector<double> y2Vec;
292 
293  // new doping/initial condition storage:
294  std::map<std::string, std::vector<double> > xlocMap;
295  std::map<std::string, std::vector<double> > specMap;
296 
297  // vector of electrode data:
298  std::map<std::string, PDE_1DElectrode*> electrodeMap;
299 
300  // boundary condition array. probably will be of size 2 or 3.
301  std::vector<bcData> bcVec;
302 
303  std::map<std::string,int> bcIndexMap;
304 
305  // doping profile constants:
306  double Na; // acceptor concentration on p-side (cm^-3)
307  double Nd; // donor concentration on n-side (cm^-3)
308  double Vbi; // built-in potential (V)
309  double WJ; // linearly graded junction width (cm)
310  double XC; // center of graded junction (cm)
311  double XL; // start of graded junction (cm)
312  double XR; // end of graded junction (cm)
313 
314  // boundary condition variables:
315  // These should eventually replace Nd and Na.
316  double NnMax; // maximum electron concentration
317  double NpMax; // maximum hole concentration.
318  double NnMin; // maximum electron concentration
319  double NpMin; // maximum hole concentration.
320 
321  // mesh constants:
322  int NX; // number of x mesh points
323  int LX; // index of last x point.
324 
325  // continuation parameters:
326  double maxVoltDelta;
328 
329  // option to use the old intrinsic calculation, to maintain backward compatibility.
330  bool useOldNi;
332 
333  // some 2D mesh stuff - mostly to catch netlist mistakes (as this is a 1D device model)
334  std::string meshFileName;
335 
336  // doping files.
337  std::string dopingFileName;
338  std::string ndopeFileName;
339  std::string pdopeFileName;
340 
341  // diode width:
342  double width;
343  double length;
344 
345  double basex; // location of base electrode, if running bjt mode.
346 
347  // diode cross sectional area:
348  double area;
349 
350  // boundary condition variables. These are superceded by
351  // the data in the bcVec and PDE_1DElectrode structures.
352  double anodebc;
353  double cathodebc;
354  double emitterbc;
355  double collectorbc;
356  double basebc;
357 
358  double anodeArea;
359  double cathodeArea;
360 
361  double emitterArea;
363  double baseArea;
364 
365  double baseLocation;
367 
372  int callsOSG;
373 
375 
377 
383 
388 
392 
393 #ifdef Xyce_DEBUG_DEVICE
394  int anodeIndex_user;
395  bool anodeIndex_userGiven;
396  int cathodeIndex_user;
397  bool cathodeIndex_userGiven;
398 #endif
399 
400  int NUMRC; // number of row-column pairs.
401 
402  std::vector<double> displCurrent;
403 
404  //*************************************
405  // Neutron reaction model stuff:
406  double junctionArea;
407 
408  std::vector<int> boundarySten;
409  std::vector<int> edgeBoundarySten;
410  std::vector<int> internalBoundarySten;
411 
412  std::vector<int> regBaseIndexVec;
413  std::vector<int> regNumSpecieVec;
414  std::vector<int> regElectronIndexVec;
415  std::vector<int> regHoleIndexVec;
416 
417  std::vector<double> dxVec; // mesh spacing.
418  std::vector<double> xVec; // mesh points.
419  std::vector<double> CVec; // doping
420  std::vector<double> CdonorVec; // doping
421  std::vector<double> CacceptorVec; // doping
422  std::vector<double> VVec; // electrostatic potential
423  std::vector<double> ExVec; // electric field, x-direction.
424 
425  std::vector<double> JnxVec; // electron current density
426  std::vector<double> JpxVec; // hole current density
427 
428  std::vector<double> RVec; // recombination.
429  std::vector<double> SVec; // radiation source term.
430 
431  std::vector<double> nnVec; // electron density
432  std::vector<double> npVec; // hole density
433 
434  //std::vector<double> unVec; // spatially dependent mobility, electron
435  //std::vector<double> upVec; // spatially dependent mobility, hole
436 #if 0
437  std::vector<double> unE_Vec; // mobility along edge, electron
438  std::vector<double> upE_Vec; // mobility along edge, hole
439 #else
440  std::vector<pdeFadType> unE_Vec; // mobility along edge, electron
441  std::vector<pdeFadType> upE_Vec; // mobility along edge, hole
442 #endif
443 
444  std::vector<double> tnVec; // spatially dependent lifetimes, electron
445  std::vector<double> tpVec; // spatially dependent lifetimes, hole
446 
447  // derivative arrays:
448 
449  std::vector<double> dRdpVec;
450  std::vector<double> dRdnVec;
451 
452  std::vector<double> dJndn1Vec;
453  std::vector<double> dJndn2Vec;
454  std::vector<double> dJndV1Vec;
455  std::vector<double> dJndV2Vec;
456  std::vector<double> dJndp1Vec;
457  std::vector<double> dJndp2Vec;
458 
459  std::vector<double> dJpdn1Vec;
460  std::vector<double> dJpdn2Vec;
461  std::vector<double> dJpdV1Vec;
462  std::vector<double> dJpdV2Vec;
463  std::vector<double> dJpdp1Vec;
464  std::vector<double> dJpdp2Vec;
465 
466  // LID indices.
467  std::vector<int> li_Vrowarray;
468  std::vector< std::vector<int> > li_Vcolarray;
469 
470  std::vector<int> li_Nrowarray;
471  std::vector< std::vector<int> > li_Ncolarray;
472 
473  std::vector<int> li_Prowarray;
474  std::vector< std::vector<int> > li_Pcolarray;
475 
476  // columns needed for coupledMode==2
477  std::vector< std::vector<int> > li_N_rxn_colarray;
478  std::vector< std::vector<int> > li_P_rxn_colarray;
479 
480  std::vector<int> li_stateDispl;
481 
482  // matrix pointers
483  std::vector< std::vector<double *> > fVmatPtr;
484  std::vector< std::vector<double *> > fNmatPtr;
485  std::vector< std::vector<double *> > fPmatPtr;
486  std::vector< std::vector<double *> > qVmatPtr;
487  std::vector< std::vector<double *> > qNmatPtr;
488  std::vector< std::vector<double *> > qPmatPtr;
489 
490  // map between a mesh point index and a list of nearest neighbors
491  // for that mesh point.
492  std::multimap< int, int* > meshNeighborMultiMap;
493 
494  // state variable arrays associated with displacement current.
495  std::vector<int> stateDispl;
496  std::vector<int> stateDispl_owned;
497  // this is an int array because I think bool arrays
498  // might be problematic for some compilers.
499 
500  int numMeshPoints; // this is probably redundant with NX.
503 
504  // 2d array of conductances, for 2-level "ckt phase" loads.
505  std::vector< std::vector<double> > condVec;
506 
507  // data related to DMA matrix loads.
508  std::vector<int> meshToLID;
509  std::vector< std::vector<int> > jacStamp;
510  std::vector<int> jacMap;
511  std::vector< std::vector<int> > jacMap2;
512 
513  // flags related to chemistry.
516 
518 };
519 
520 //-----------------------------------------------------------------------------
521 // Class : Model
522 // Purpose :
523 // Special Notes :
524 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
525 // Creation Date : 6/29/00
526 //-----------------------------------------------------------------------------
527 class Model : public DevicePDEModel
528 {
529  typedef std::vector<Instance *> InstanceVector;
530 
531  friend class Instance;
532  friend class ParametricData<Model>;
533  friend class Traits;
534 
535 public:
536  Model(
537  const Configuration & configuration,
538  const ModelBlock & MB,
539  const FactoryBlock & factory_block);
540  ~Model();
541 
542 private:
543  Model();
544  Model(const Model &);
545  Model &operator=(const Model &);
546 
547 public:
548  virtual void forEachInstance(DeviceInstanceOp &op) const /* override */;
549 
550  virtual std::ostream &printOutInstances(std::ostream &os) const;
551 
552  bool processParams ();
553  bool processInstanceParams ();
554 
555 private:
556 
557 
558 public:
559  void addInstance(Instance *instance)
560  {
561  instanceContainer.push_back(instance);
562  }
563 
565  {
566  return instanceContainer;
567  }
568 
570  {
571  return instanceContainer;
572  }
573 
574 private:
575  std::vector<Instance*> instanceContainer;
576 };
577 
578 void registerDevice();
579 
580 } // namespace DiodePDE
581 } // namespace Device
582 } // namespace Xyce
583 
586 
587 #endif