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