Xyce  6.1
N_DEV_2DPDE_DAE.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_2DPDE_DAE.C,v $
27 //
28 // Purpose : This file contains a lot of the
29 // implementation of the instance class for the two
30 // dimensional PDE based semiconductor device.
31 //
32 // Functions pertaining to the initial setup are in other
33 // files, as are functions relating to mesh handling and
34 // parameter handling.
35 //
36 // Special Notes :
37 //
38 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
39 //
40 // Creation Date : 07/05/03
41 //
42 // Revision Information:
43 // ---------------------
44 //
45 // Revision Number: $Revision: 1.32.2.1 $
46 //
47 // Revision Date : $Date: 2015/04/02 18:20:12 $
48 //
49 // Current Owner : $Author: tvrusso $
50 //-------------------------------------------------------------------------
51 
52 #include <Xyce_config.h>
53 
54 // ---------- Standard Includes ----------
55 #include <iostream>
56 
57 // ---------- Xyce Includes ----------
58 #include <N_DEV_2DPDE.h>
59 #include <N_DEV_SolverState.h>
60 #include <N_DEV_ExternData.h>
61 #include <N_DEV_DeviceOptions.h>
62 #include <N_DEV_MatrixLoadData.h>
63 #include <N_DEV_PDE_2DMesh.h>
64 #include <N_DEV_SourceData.h>
65 
66 #include <N_LAS_Vector.h>
67 #include <N_LAS_Matrix.h>
68 #include <N_LAS_System.h>
69 #include <N_LAS_Builder.h>
70 
71 namespace Xyce {
72 namespace Device {
73 namespace TwoDPDE {
74 
75 //-----------------------------------------------------------------------------
76 // Function : Instance::loadDAEFVector
77 // Purpose :
78 // Special Notes :
79 // Scope : public
80 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
81 // Creation Date : 6/21/05
82 //-----------------------------------------------------------------------------
84 {
85  bool bsuccess = true;
86  bool bs1;
87 
88  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) && getSolverState().debugTimeFlag)
89  {
90  Xyce::dout() << "loadDAEFVector: doubleDCOPStep="<<getSolverState().doubleDCOPStep;
91  if (getSolverState().dcopFlag) Xyce::dout() << " DCOP load" <<std::endl;
92  else Xyce::dout() << " Transient load" <<std::endl;
93  }
94 
95  if ((getSolverState().dcopFlag) && getSolverState().doubleDCOPStep == 0)
96  {
97  equationSet = 0;
98  bs1 = loadDAEFNonlinPoisson ();
99  }
100  else
101  {
102  equationSet = 1;
103 
104  if (getSolverState().twoLevelNewtonCouplingMode==Nonlinear::INNER_PROBLEM ||
105  getSolverState().twoLevelNewtonCouplingMode==Nonlinear::FULL_PROBLEM)
106  {
107  bs1 = loadDAEFDDFormulation ();
108  }
109  else if (getSolverState().twoLevelNewtonCouplingMode==Nonlinear::OUTER_PROBLEM)
110  {
112  }
113  else
114  {
115  std::string msg = "Instance::loadDAEFVector."
116  "Invalid coupling Mode";
117  N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
118  }
119  }
120 
121  return (bsuccess && bs1);
122 }
123 
124 //-----------------------------------------------------------------------------
125 // Function : Instance::loadDAEFNonlinPoisson
126 // Purpose : Loads the F-vector the nonlinear poisson calculation.
127 //
128 // Special Notes : This should be identical to the original loadRHS function,
129 // for the nonlinear poisson. All of that goes into the
130 // FVector, but with the opposite sign.
131 //
132 // Scope : public
133 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
134 // Creation Date : 6/21/05
135 //-----------------------------------------------------------------------------
137 {
138  return loadVecNLPoisson ( -1.0, extData.daeFVectorPtr );
139 }
140 
141 //-----------------------------------------------------------------------------
142 // Function : Instance::loadDAEFDDFormulation
143 // Purpose : This function should be called from the loadDAEFVector
144 // function when solving the drift-diffusion equations.
145 // Special Notes :
146 //
147 // Scope : private
148 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
149 // Creation Date : 6/21/05
150 //-----------------------------------------------------------------------------
152 {
153  // calcTerminalCurrents needs to be here b/c it is otherwise
154  // called from updateSecondaryState
156  return loadVecDDForm (-1.0,0.0, extData.daeFVectorPtr);
157 }
158 
159 //-----------------------------------------------------------------------------
160 // Function : Instance::loadDAEFExtractedConductance
161 // Purpose :
162 // Special Notes :
163 // Scope : private
164 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
165 // Creation Date : 6/21/05
166 //-----------------------------------------------------------------------------
168 {
169  bool bsuccess = true;
170 
171  return bsuccess;
172 }
173 
174 //-----------------------------------------------------------------------------
175 // Function : Instance::loadDAEQVector
176 // Purpose :
177 // Special Notes :
178 // Scope : public
179 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
180 // Creation Date : 6/21/05
181 //-----------------------------------------------------------------------------
183 {
184  bool bsuccess = true;
185  bool bs1;
186 
187  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) && getSolverState().debugTimeFlag)
188  {
189  Xyce::dout() << "loadDAEQVector: doubleDCOPStep="<<getSolverState().doubleDCOPStep;
190  if (getSolverState().dcopFlag) Xyce::dout() << " DCOP load" <<std::endl;
191  else Xyce::dout() << " Transient load" <<std::endl;
192  }
193 
194  if ((getSolverState().dcopFlag) && getSolverState().doubleDCOPStep == 0)
195  {
196  equationSet = 0;
197  bs1 = true; // no-op
198  }
199  else
200  {
201  equationSet = 1;
202 
203  if (getSolverState().twoLevelNewtonCouplingMode==Nonlinear::INNER_PROBLEM ||
204  getSolverState().twoLevelNewtonCouplingMode==Nonlinear::FULL_PROBLEM)
205  {
206  bs1 = loadDAEQDDFormulation ();
207  }
208  else if (getSolverState().twoLevelNewtonCouplingMode==Nonlinear::OUTER_PROBLEM)
209  {
211  }
212  else
213  {
214  std::string msg = "Instance::loadDAEQVector."
215  "Invalid coupling Mode";
216  N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
217  }
218  }
219 
220  return (bsuccess && bs1);
221 }
222 
223 
224 //-----------------------------------------------------------------------------
225 // Function : Instance::loadDAEQDDFormulation
226 // Purpose :
227 // Special Notes :
228 // Scope : private
229 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
230 // Creation Date : 6/21/05
231 //-----------------------------------------------------------------------------
233 {
234  bool bsuccess = true;
235  bool bs1 = true;
236 
237  Linear::Vector * vecPtr = extData.daeQVectorPtr;
238 
239  int i;
240  int Nrow, Prow;
241 
242  // mesh points for the PDE problem:
243  for (i=0;i<numMeshPoints;++i)
244  {
245 
246  // skip boundary points, for both NEW_BC and old.
247  if (boundarySten[i]) continue;
248 
249  if( useVectorGIDFlag )
250  {
251  Nrow = Nrowarray[i];
252  Prow = Prowarray[i];
253 
254  bs1 = vecPtr->sumElementByGlobalIndex(Nrow, (-nnVec[i]*scalingVars.t0), 0);
255  bsuccess = bsuccess && bs1;
256 
257  bs1 = vecPtr->sumElementByGlobalIndex(Prow, (-npVec[i]*scalingVars.t0), 0);
258  bsuccess = bsuccess && bs1;
259  }
260  else
261  {
262  Nrow = li_Nrowarray[i];
263  Prow = li_Prowarray[i];
264  (*vecPtr)[Nrow] = -nnVec[i]*scalingVars.t0;
265  (*vecPtr)[Prow] = -npVec[i]*scalingVars.t0;
266  }
267 
268  }
269 
270  return bsuccess;
271 }
272 
273 //-----------------------------------------------------------------------------
274 // Function : Instance::loadDAEQExtractedConductance
275 // Purpose :
276 // Special Notes :
277 // Scope : private
278 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
279 // Creation Date : 6/21/05
280 //-----------------------------------------------------------------------------
282 {
283  bool bsuccess = true;
284 
285  return bsuccess;
286 }
287 
288 //-----------------------------------------------------------------------------
289 // Function : Instance::loadDAEdFdx
290 // Purpose : This function performs an analytic Jacobian matrix load for
291 // the diode-pde class, for the case of solving a nonlinear
292 // poisson equation.
293 // Special Notes :
294 //
295 // Scope : private
296 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
297 // Creation Date : 6/21/05
298 //-----------------------------------------------------------------------------
300 {
301  bool bsuccess;
302 
303  if ((getSolverState().dcopFlag) && getSolverState().doubleDCOPStep == 0)
304  {
305  bsuccess = loadDAEdFdxNonlinPoisson ();
306  }
307  else
308  {
309  if (getSolverState().twoLevelNewtonCouplingMode==Nonlinear::INNER_PROBLEM ||
310  getSolverState().twoLevelNewtonCouplingMode==Nonlinear::FULL_PROBLEM)
311  {
312  bsuccess = loadDAEdFdxDDFormulation ();
313  }
314  else if (getSolverState().twoLevelNewtonCouplingMode==Nonlinear::OUTER_PROBLEM)
315  {
316  bsuccess = loadDAEdFdxExtractedConductance ();
317  }
318  else
319  {
320  Report::DevelFatal().in("Instance::loadDAEdFdx") << "Invalid coupling Mode" << numElectrodes;
321  }
322  }
323 
324  return bsuccess;
325 }
326 
327 //-----------------------------------------------------------------------------
328 // Function : Instance::loadDAEdFdxNonlinPoisson
329 // Purpose : This function performs an analytic Jacobian matrix load for
330 // the diode-pde class, for the case of solving a nonlinear
331 // poisson equation.
332 // Special Notes :
333 //
334 // Scope : private
335 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
336 // Creation Date : 6/21/05
337 //-----------------------------------------------------------------------------
339 {
341 }
342 
343 //-----------------------------------------------------------------------------
344 // Function : Instance::loadDAEdFdxDDFormulation
345 // Purpose :
346 // Special Notes :
347 // Scope : private
348 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
349 // Creation Date : 6/21/05
350 //-----------------------------------------------------------------------------
352 {
353  bool bsuccess = true;
354  bool bs1 = true;
355  // set up some of the partial derivative arrays:
356  bs1 = pdRecombination (); bsuccess = bsuccess && bs1;
357  bs1 = pdElectronCurrent (); bsuccess = bsuccess && bs1;
358  bs1 = pdHoleCurrent (); bsuccess = bsuccess && bs1;
359  bs1 = pdTerminalCurrents ();bsuccess = bsuccess && bs1;
360 
361  if ( !(getSolverState().twoLevelNewtonCouplingMode==Nonlinear::INNER_PROBLEM))
362  {
364  bsuccess = bsuccess && bs1;
365  }
366  else
367  {
369  bsuccess = bsuccess && bs1;
370  }
371 
372  bs1 = loadMatDDForm ( 0.0, extData.dFdxMatrixPtr );
373  bsuccess = bsuccess && bs1;
374 
375  return bsuccess;
376 }
377 
378 //-----------------------------------------------------------------------------
379 // Function : Instance::loadDAEdFdxExtractedConductance
380 // Purpose :
381 // Special Notes :
382 // Scope : private
383 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
384 // Creation Date : 6/21/05
385 //-----------------------------------------------------------------------------
387 {
388  bool bsuccess = true;
389 
390  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) && getSolverState().debugTimeFlag)
391  {
392  Xyce::dout() << std::endl;
393  Xyce::dout() << section_divider << std::endl;
394  Xyce::dout() << "Instance::loadDAEdFdxExtractedConductance" << std::endl;
395  }
396 
397 
398 #if 0 // Not yet implemented -- commented out to remove warnings
399  int colsGID[10];
400  double valsGID[10];
401  int i;
402  for (i=0;i<10;++i)
403  {
404  colsGID[i] = -1;
405  valsGID[i] = 0.0;
406  }
407 
408  // first put 1's on the diagonals of all the mesh-rows:
409 #endif
410 
411  // now load the equivalent conductances.
412 
413  return bsuccess;
414 }
415 
416 //-----------------------------------------------------------------------------
417 // Function : Instance::loadDAEdQdx
418 // Purpose :
419 // Special Notes :
420 // Scope : private
421 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
422 // Creation Date : 6/21/05
423 //-----------------------------------------------------------------------------
425 {
426  bool bsuccess;
427 
428  if ((getSolverState().dcopFlag) && getSolverState().doubleDCOPStep == 0)
429  {
430  bsuccess = true; // no-op
431  }
432  else
433  {
434  if (getSolverState().twoLevelNewtonCouplingMode==Nonlinear::INNER_PROBLEM ||
435  getSolverState().twoLevelNewtonCouplingMode==Nonlinear::FULL_PROBLEM)
436  {
437  bsuccess = loadDAEdQdxDDFormulation ();
438  }
439  else if (getSolverState().twoLevelNewtonCouplingMode==Nonlinear::OUTER_PROBLEM)
440  {
441  bsuccess = loadDAEdQdxExtractedConductance ();
442  }
443  else
444  {
445  Report::DevelFatal().in("Instance::loadDAEdQdx") << "Invalid coupling Mode" << numElectrodes;
446  }
447  }
448 
449  return bsuccess;
450 }
451 
452 //-----------------------------------------------------------------------------
453 // Function : Instance::loadDAEdQdxDDFormulation
454 // Purpose :
455 // Special Notes :
456 // Scope : private
457 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
458 // Creation Date : 6/21/05
459 //-----------------------------------------------------------------------------
461 {
462  bool bsuccess = true;
463  bool bs1 = true;
464  int i,j,count;
465  int Nrow, Prow;
466 
467  int numCol = cols.size();
468  if (vals.size () < cols.size()) numCol = vals.size();
469 
470  Linear::Matrix & QMatrix = (*extData.dQdxMatrixPtr);
471 
472  // load the rows associated with the PDE mesh:
473  if( useMatrixGIDFlag )
474  {
475  for (i=0;i<numMeshPoints;++i)
476  {
477  if (boundarySten[i]) continue;
478 
479  Nrow = Nrowarray[i];
480  Prow = Prowarray[i];
481 
482  // electron continuity row:
483  for (j=0;j<numCol;++j) { cols[j] = -1; vals[j] = 0.0; }
484  count = 0;
485 
486  // center point
487  vals[count] = -scalingVars.t0;
488  cols[count] = Ncolarray[i][0];
489  ++count;
490 
491  if (Nrow != -1 && count > 0)
492  {
493  bs1 = QMatrix.sumIntoRow (Nrow,count,&vals[0],&cols[0]);
494  bsuccess = bsuccess && bs1;
495  }
496  else
497  {
498  Report::DevelFatal() << "OOOPS 1!";
499  }
500 
501  // hole continuity row:
502  for (j=0;j<numCol;++j) { cols[j] = -1; vals[j] = 0.0; }
503  count = 0;
504 
505  // center point
506  vals[count] = -scalingVars.t0;
507  cols[count] = Pcolarray[i][0];
508  ++count;
509 
510  if (Prow != -1 && count > 0)
511  {
512  bs1 = QMatrix.sumIntoRow (Prow,count,&vals[0],&cols[0]);
513  bsuccess = bsuccess && bs1;
514  }
515  else
516  {
517  Report::DevelFatal() << "OOOPS 2!";
518  }
519 
520  } // mesh loop.
521  }
522  else // direct matrix access:
523  {
524  for (i=0;i<numMeshPoints;++i)
525  {
526  if (boundarySten[i]) continue;
527 
528  Nrow = li_Nrowarray[i];
529  Prow = li_Prowarray[i];
530 
531  std::vector<int> & Noff = li_NoffsetArray[i];
532  std::vector<int> & Poff = li_PoffsetArray[i];
533 
534  QMatrix[Nrow][Noff[0]] += -scalingVars.t0;
535  QMatrix[Prow][Poff[0]] += -scalingVars.t0;
536 
537  } // mesh loop.
538  }
539 
540  return bsuccess;
541 }
542 
543 //-----------------------------------------------------------------------------
544 // Function : Instance::loadDAEdQdxExtractedConductance
545 // Purpose :
546 // Special Notes :
547 // Scope : private
548 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
549 // Creation Date : 6/21/05
550 //-----------------------------------------------------------------------------
552 {
553  bool bsuccess = true;
554  return bsuccess;
555 }
556 
557 } // namespace TwoDPDE
558 } // namespace Device
559 } // namespace Xyce
560 
std::vector< double > & vals
Linear::Vector * daeQVectorPtr
Pure virtual class to augment a linear system.
bool loadMatKCLDDForm(Linear::Matrix *matPtr)
std::vector< int > Nrowarray
Definition: N_DEV_2DPDE.h:461
std::vector< int > boundarySten
Definition: N_DEV_2DPDE.h:441
std::vector< std::vector< int > > li_PoffsetArray
Definition: N_DEV_2DPDE.h:480
std::vector< std::vector< int > > Ncolarray
Definition: N_DEV_2DPDE.h:462
std::vector< int > li_Nrowarray
Definition: N_DEV_2DPDE.h:475
std::vector< double > nnVec
Definition: N_DEV_2DPDE.h:391
bool loadVecNLPoisson(double scalar, Linear::Vector *vecPtr)
Linear::Matrix * dFdxMatrixPtr
bool loadVecDDForm(double scalar, double dndtScalar, Linear::Vector *vecPtr)
const SolverState & getSolverState() const
std::vector< std::vector< int > > Pcolarray
Definition: N_DEV_2DPDE.h:466
std::vector< double > npVec
Definition: N_DEV_2DPDE.h:392
Linear::Vector * daeFVectorPtr
bool loadMatNLPoisson(Linear::Matrix *matPtr)
bool loadMatCktTrivial(Linear::Matrix *matPtr)
std::vector< int > li_Prowarray
Definition: N_DEV_2DPDE.h:476
std::vector< int > Prowarray
Definition: N_DEV_2DPDE.h:465
bool loadMatDDForm(double dndtScalar, Linear::Matrix *matPtr)
Linear::Matrix * dQdxMatrixPtr
std::vector< std::vector< int > > li_NoffsetArray
Definition: N_DEV_2DPDE.h:479