Xyce  6.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
N_DEV_2DPDE.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 // Filename : $RCSfile: N_DEV_2DPDE.h,v $
27 //
28 // Purpose : This file contains the classes neccessary for a 2D PDE
29 // based simulation. MOSFETs, BJTs, Diodes, etc.
30 //
31 // Special Notes :
32 //
33 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
34 //
35 // Creation Date : 11/14/01
36 //
37 // Revision Information:
38 // ---------------------
39 //
40 // Revision Number: $Revision: 1.86.2.1 $
41 //
42 // Revision Date : $Date: 2014/02/26 20:16:31 $
43 //
44 // Current Owner : $Author: tvrusso $
45 //-----------------------------------------------------------------------------
46 
47 #ifndef Xyce_N_DEV_2DPDE_h
48 #define Xyce_N_DEV_2DPDE_h
49 
50 // ---------- Standard Includes ----------
51 
52 // ---------- Xyce Includes ----------
53 #include <N_DEV_Configuration.h>
54 #include <N_DEV_fwd.h>
55 #include <N_DEV_DeviceBlock.h>
57 #include <N_DEV_DevicePDEModel.h>
58 
60 #include <N_DEV_PDE_2DMesh.h>
61 
62 #include <N_DEV_DiodePDE.h>
63 
64 #include <N_UTL_BreakPoint.h>
65 
66 
67 // Have the "new" boundary conditions turned on by default.
68 #if 1
69 #define Xyce_NEW_BC 1
70 #endif
71 
72 namespace Xyce {
73 namespace Device {
74 namespace TwoDPDE {
75 
76 class Model;
77 class Instance;
78 
79 struct Traits : public DeviceTraits<Model, Instance, DiodePDE::Traits>
80 {
81  static const char *name() {return "2D PDE Device";}
82  static const char *deviceTypeName () {return "PDE level 2";}
83  static const int numNodes() {return 2;}
84  static const int numOptionalNodes() {return 100;}
85  static const int numFillNodes() {return 2;}
86  static const bool modelRequired() {return true;}
87  static const bool isPDEDevice() {return true;}
88  static const bool isLinearDevice() {return false;}
89 
90  static Device *factory(const Configuration &configuration, const FactoryBlock &factory_block);
91  static void loadModelParameters(ParametricData<Model> &model_parameters);
92  static void loadInstanceParameters(ParametricData<Instance> &instance_parameters);
93 };
94 
95 //-----------------------------------------------------------------------------
96 // Class : Instance
97 // Purpose : Instance class for .
98 //
99 // Special Notes :
100 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
101 // Creation Date : 11/14/01
102 //-----------------------------------------------------------------------------
104 {
105  friend class ParametricData<Instance>;
106  friend class Model;
107  friend class Traits;
108 
109  // functions
110 public:
111 
112  Instance(
113  const Configuration & configuration,
114  const InstanceBlock & IB,
115  Model & model,
116  const FactoryBlock &factory_block);
117  ~Instance();
118 
119 private:
120  Instance(const Instance &right);
121  Instance &operator=(const Instance &right);
122 
123 public:
124  void registerGIDs (const std::list<index_pair> & intGIDListRef,
125  const std::list<index_pair> & extGIDListRef );
126 
127  void setupIntNameMap ();
128  void setupRowColPairs ();
129 
130  void registerStateGIDs (const std::list<index_pair> & staGIDListRef);
131 
132  void registerLIDs( const std::vector<int> & intLIDVecRef,
133  const std::vector<int> & extLIDVecRef );
134  void registerStateLIDs( const std::vector<int> & staLIDVecRef );
135  std::map<int,std::string> & getIntNameMap ();
136 
137  const std::vector< std::vector<int> > & jacobianStamp() const;
138  void registerJacLIDs( const std::vector< std::vector<int> > & jacLIDVec );
139 
140  bool processParams ();
141 
142  bool processOneTimeParams( Param & ndParam );
143 
144  bool processDopingParams (Param & ndParam, std::string param);
145 
146  bool processElectrodeParams (Param & ndParam);
147 
148  bool setupJacStamp ();
149 
150  bool doSensMeshResize ();
151  bool undoSensMeshResize ();
152 
153  bool setupMesh ();
154  bool doAllocations ();
155 
156  bool setupDINodes ();
157  bool setupBCEdgeAreas ();
158 
159  bool setupBoundaryStencil ();
160  bool setupNumVars ();
161 
162  bool checkForElectrodeOverlap ();
163 
164  bool setupLabelIndex ();
165  bool setupMinDXVector ();
166 
167  bool updateIntermediateVars ();
168  bool updatePrimaryState ();
169  bool updateSecondaryState ();
170 
171  // functions that are used by both new-DAE and old-DAE:
172  bool loadVecNLPoisson (double scalar, N_LAS_Vector * vecPtr);
173  bool loadMatNLPoisson (N_LAS_Matrix * matPtr);
174  bool loadMatKCLDDForm (N_LAS_Matrix * matPtr);
175  bool loadMatDDForm (double dndtScalar, N_LAS_Matrix * matPtr);
176  bool loadVecDDForm (double scalar,double dndtScalar,N_LAS_Vector *vecPtr);
177  bool loadMatCktTrivial (N_LAS_Matrix * matPtr);
178  // end of the "both" DAE functions.
179 
180  bool setInitialGuess ();
181  bool loadRHSNonlinPoisson ();
182  bool loadRHSDDFormulation ();
184 
185  bool plotfileFlag () {return true;}
186 
187  // load functions, residual:
188  bool loadDAEQVector ();
189  bool loadDAEQDDFormulation ();
191 
192  bool loadDAEFVector ();
193  bool loadDAEFNonlinPoisson ();
194  bool loadDAEFDDFormulation ();
196 
197  // load functions, Jacobian:
198  bool loadDAEdQdx ();
199 
200  bool loadDAEdQdxDDFormulation ();
202 
203  bool loadDAEdFdx ();
204  bool loadDAEdFdxNonlinPoisson ();
205  bool loadDAEdFdxDDFormulation ();
207 
208  bool calcLifetimes ();
209  bool calcMobilities ();
210  bool updateTemperature(const double & temp_tmp);
211  bool calcVoltDepDensities ();
212 
213  bool calcDopingProfile ();
214  bool calcInitialGuess ();
215  bool obtainSolution ();
216  bool obtainNodeVoltages ();
217  bool applyVoltageLimiting ();
218  bool calcVequBCs ();
219  bool calcDensityBCs ();
220  bool calcBoundaryConditions ();
221 
222  bool setupMiscConstants ();
223  bool setupScalingVars ();
224  bool scaleVariables ();
225  bool unScaleVariables ();
226  bool scaleDopeVariables ();
227  bool unScaleDopeVariables ();
228 
229  bool calcRecombination ();
230 
231 
232  bool setupPhotogen ();
233  bool calcPhotogen ();
234  bool calcPenalty ();
236  bool sumSources ();
237 
238  bool calcElectronCurrent ();
239  bool calcHoleCurrent ();
240  bool calcEfield ();
241 
242  bool calcTerminalCharges ();
243  bool calcTerminalCurrents ();
244  bool calcConductance (int iElectrode, const N_LAS_Vector * dxdvPtr);
245  bool calcDXDV ();
246  bool loadDFDV (int ielectrode, N_LAS_Vector * dfdvPtr);
247 
248  bool pdRecombination ();
249  bool pdElectronCurrent ();
250  bool pdHoleCurrent ();
251  bool pdTerminalCurrents ();
252  bool pdTerminalCharges ();
253  bool allocatePDTerms ();
254 
255  bool pdPenalty ();
256 
257  bool outputTecplot ();
258  bool outputTecplotVectors ();
259  bool tecplotGeomOutput (FILE *fp1);
260  bool outputSgplot ();
261  bool outputGnuplot ();
262  bool outputTxtData ();
263 
264  bool enablePDEContinuation ();
265  bool disablePDEContinuation ();
266  void setPDEContinuationAlpha (double alpha);
267  void setPDEContinuationBeta (double beta);
268 
269  bool outputPlotFiles ();
270 
271  CompositeParam *constructComposite (const std::string & compositeName, const std::string & paramName);
272 
273 public:
274  // iterator reference to the resistor model which owns this instance.
275  // Getters and setters
277  {
278  return model_;
279  }
280 
281 private:
282 
283  Model & model_; //< Owning model
284 
285 protected:
286 private:
287 
288  // physical constants:
289  double Is; // saturation current
290  double Id; // diode current, analytic form
291 
292  double Emax; // maximum electric field (V/cm)
293 
294  double VminExp; // maximum potential (V), used in exponential expressions
295  double VmaxExp; // minimum potential (V), used in exponential expressions
296 
297  // device interface node vector:
298  std::vector<DeviceInterfaceNode> dIVec;
299 
302 
303  double LeadCurrent1;
304  double LeadCurrent2;
305  double LeadCurrent3;
306  double LeadCurrent4;
307  double LeadCurrent5;
308  double LeadCurrent6;
309  double LeadCurrent7;
310  double LeadCurrent8;
311 
312  // doping profile constants:
313  double Na; // acceptor concentration on p-side (cm^-3)
314  double Nd; // donor concentration on n-side (cm^-3)
315  double Vbi; // built-in potential (V)
316  double WJ; // linearly graded junction width (cm)
317  double XC; // center of graded junction (cm)
318  double XL; // start of graded junction (cm)
319  double XR; // end of graded junction (cm)
320 
321  // boundary condition variables:
322  double NnMax; // maximum electron concentration
323  double NpMax; // maximum hole concentration.
324  double NnMin; // maximum electron concentration
325  double NpMin; // maximum hole concentration.
326 
327  // option to use the old intrinsic calculation, to maintain backward compatibility.
328  bool useOldNi;
330 
331  std::string meshFileName;
332  std::string deviceType;
338 
339 
340  // meshing variables, if using internally generated mesh.
343  double deviceLength;
344  double deviceWidth;
345 
347 
350  double penaltyPow;
351  double PulseData;
352 
353 
354  // diode cross sectional area:
355  double area;
356 
357 #ifdef Xyce_OXIDE_ENABLED
358  bool allOxideFlag;
359 #endif
360 
363  int callsOSG;
368 
371 
372  bool calcConductanceFlag; // Set when calcConductance is
373  // called for the 1st time.
374 
376 
381 
386 
388 
390 
393 
394  // mesh container pointer:
397 
398  // array pointers:
399  std::vector<double> xVec; // x locations
400  std::vector<double> yVec; // y locations
401  std::vector<double> CVec; // doping
402  std::vector<double> CdonorVec; // doping
403  std::vector<double> CacceptorVec; // doping
404 
405  std::vector<double> minDXVec; // minimum mesh spacing connected to this node.
406 
407  std::vector<double> areaVec;
408 
409  std::vector<double> VVec; // electrostatic potential
410  std::vector<double> nnVec; // electron density
411  std::vector<double> npVec; // hole density
412 
413  std::vector<double> totSrcVec; // total source term.
414  std::vector<double> RVec; // recombination.
415  std::vector<double> SVec; // radiation source term.
416 
417  std::vector<double> elecPenalty; // penalty term for negative e- density.
418  std::vector<double> holePenalty; // penalty term for negative h+ density.
419  std::vector<double> pdElecPenalty; // penalty deriv. term for negative e- density.
420  std::vector<double> pdHolePenalty; // penalty deriv. term for negative h+ density.
421 
422  std::vector<double> unVec; // spatially dependent mobility, electron
423  std::vector<double> upVec; // spatially dependent mobility, hole
424  std::vector<double> unE_Vec; // mobility along edge, electron
425  std::vector<double> upE_Vec; // mobility along edge, hole
426  std::vector<double> tnVec; // spatially dependent lifetimes, electron
427  std::vector<double> tpVec; // spatially dependent lifetimes, hole
428 
429  std::vector<double> EfieldVec; // electric field along an edge.
430 
431  std::vector<double> JnVec; // electron current density, along an edge
432  std::vector<double> JpVec; // hole current density, along an edge
433 
434  std::vector<double> displPotential; // time derivative of potential at a node,
435  // used in calculating displacement current.
436 
437  std::vector<double> displCurrent; // displacement current along an edge.
438 
439  std::vector<double> outputVec;
440 
441  // derivative arrays:
442 
443  // derivatives of recombination terms:
444  std::vector<double> dRdpVec; // derivative of R w.r.t. np (at a node)
445  std::vector<double> dRdnVec; // derivative of R w.r.t. nn (at a node)
446 
447  // derivatives of current density terms:
448  std::vector<double> dJndn1Vec;
449  std::vector<double> dJndn2Vec;
450  std::vector<double> dJndV1Vec;
451  std::vector<double> dJndV2Vec;
452 
453  std::vector<double> dJpdn1Vec;
454  std::vector<double> dJpdn2Vec;
455  std::vector<double> dJpdV1Vec;
456  std::vector<double> dJpdV2Vec;
457 
458  // matrix index arrays:
459  // external variable information is in the dIVec data structure.
460 
461  // boundary "neighbor" stencil
462  // This array is set to 1 if we are on a mesh node which has a
463  // nearest neighbor node which is a boundary condition node.
464  // 0 if not.
465  std::vector<int> boundarySten;
466  std::vector<int> boundaryStenV;
467  std::vector<int> boundaryStenN;
468  std::vector<int> boundaryStenP;
469 
470  std::vector<int> boundaryTest;
471 
472  // boundary neighbor stencil
473  // This array is set to 1 if we are next to a boundary, but not on
474  // a boundary. 0 if not. A node directly on the boundary
475  // does should return a zero.
476  std::vector<int> boundaryNeighborSten;
477 
478  // internal variable index arrays:
479 
480  // index arrays for poisson's equation:
481  std::vector<int> Vrowarray;
482  std::vector< std::vector<int> > Vcolarray;
483 
484  // index arrays for electron continuity:
485  std::vector<int> Nrowarray;
486  std::vector< std::vector<int> > Ncolarray;
487 
488  // index arrays for hole continuity:
489  std::vector<int> Prowarray;
490  std::vector< std::vector<int> > Pcolarray;
491 
492  // variable ownership arrays.
493  std::vector<int> vOwnVec; // on processor tag, for voltage variables.
494  std::vector<int> nnOwnVec; // on processor tag, for elec. density variables.
495  std::vector<int> npOwnVec; // on processor tag, for hole density variables.
496 
497  //local id's (offsets)
498  std::vector<int> li_Vrowarray;
499  std::vector<int> li_Nrowarray;
500  std::vector<int> li_Prowarray;
501 
502  std::vector< std::vector<int> > li_VoffsetArray;
503  std::vector< std::vector<int> > li_NoffsetArray;
504  std::vector< std::vector<int> > li_PoffsetArray;
505 
506  std::vector<int> MESHtoLID_V;
507  std::vector<int> MESHtoLID_N;
508  std::vector<int> MESHtoLID_P;
509 
510 
511  // minor arrays used in tecplot output:
512  std::vector<UINT> aiEdge;
513  std::vector<UINT> aiEdge_nf;
514  //std::vector<UINT> electrodeEdge;
517 
518  // this map is mostly used for processing the netlist information
519  // regarding boundary conditions.
520  std::map<std::string,std::string> tmpBCmap;
521 
522  // label index array (of numMeshPoints length)
523  std::vector<int> labelIndex;
524  std::vector<std::string> labelNameVector;
525  std::map<std::string,int> labelDIMap;
526 
527  // map between a mesh point index and a list of nearest neighbors
528  // for that mesh point.
529  std::multimap < int, int* > meshNeighborMultiMap;
530 
531  // vector of electrode data:
532  std::map<std::string,PDE_2DElectrode*> electrodeMap;
533 
534  // displacement current state variable information:
535  std::vector<int> stateDispl;
536  std::vector<int> stateDispl_owned; // this is an int array because
537  // bool arrays are problematic,
538  // esp. with some STL implementations.
539 
540  //local id's (offsets)
541  std::vector<int> li_stateDispl;
542 
544  int numInterfaceMeshPoints; // number of mesh points that
545  // are along electrode boundaries
551 
552  // 2d array of conductances, for 2-level "ckt phase" loads.
553  std::vector< std::vector<double> > condVec;
554 
555  // 2d array of capacitances,
556  std::vector< std::vector<double> > capVec;
557 
559 
560  // data related to DMA matrix loads.
561  std::vector<int> meshToLID;
562  std::vector< std::vector<int> > jacStamp;
563 };
564 
565 //-----------------------------------------------------------------------------
566 // Class : Model
567 // Purpose :
568 // Special Notes :
569 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
570 // Creation Date : 11/14/01
571 //-----------------------------------------------------------------------------
572 class Model : public DevicePDEModel
573 {
574  typedef std::vector<Instance *> InstanceVector;
575 
576  friend class ParametricData<Model>;
577  friend class Instance;
578  friend class Traits;
579 
580 public:
581  Model(
582  const Configuration & configuration,
583  const ModelBlock & MB,
584  const FactoryBlock & factory_block);
585 
586  ~Model();
587 
588 private:
589  Model();
590  Model(const Model &);
591  Model &operator=(const Model &);
592 
593 public:
594  virtual void forEachInstance(DeviceInstanceOp &op) const /* override */;
595 
596  virtual std::ostream &printOutInstances(std::ostream &os) const;
597 
598  bool processParams ();
599  bool processInstanceParams ();
600 
601 
602 public:
603  void addInstance(Instance *instance)
604  {
605  instanceContainer.push_back(instance);
606  }
607 
609  {
610  return instanceContainer;
611  }
612 
614  {
615  return instanceContainer;
616  }
617 
618 private:
619  std::vector<Instance*> instanceContainer;
620 
621 private:
622 };
623 
624 void registerDevice();
625 
626 } // namespace TwoDPDE
627 } // namespace Device
628 } // namespace Xyce
629 
632 
633 #endif