Xyce  6.1
N_DEV_DopeInfo.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_DopeInfo.C,v $
27 //
28 // Purpose : This file contains the details of the dope info class.
29 //
30 // Special Notes :
31 //
32 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
33 //
34 // Creation Date : 03/04/08
35 //
36 // Revision Information:
37 // ---------------------
38 //
39 // Revision Number: $Revision: 1.28.2.1 $
40 //
41 // Revision Date : $Date: 2015/04/02 18:20:12 $
42 //
43 // Current Owner : $Author: tvrusso $
44 //-------------------------------------------------------------------------
45 #include <Xyce_config.h>
46 
47 // ---------- Standard Includes ----------
48 #include <iostream>
49 
50 // ---------- Xyce Includes ----------
52 #include <N_UTL_Expression.h>
53 #include <N_DEV_DeviceSupport.h>
54 
55 namespace Xyce {
56 namespace Device {
57 
58 template<>
60 {
61  addPar("NMAX", 1.0e+15, &DopeInfo::Nmax);
62  addPar("NMIN", 0.0, &DopeInfo::Nmin);
63  addPar("NMAXCHOP", 1.0e+20, &DopeInfo::Nmax_chop)
64  .setGivenMember(&DopeInfo::Nmax_chopGiven);
65  addPar("XLOC", 0.0, &DopeInfo::xloc);
66  addPar("XMIN", 0.0, &DopeInfo::xmin)
67  .setGivenMember(&DopeInfo::xminGiven);
68  addPar("XMAX", 0.0, &DopeInfo::xmax)
69  .setGivenMember(&DopeInfo::xmaxGiven);
70  addPar("XWIDTH", 1.0e-3, &DopeInfo::xwidth);
71  addPar("YLOC", 0.0, &DopeInfo::yloc);
72  addPar("YMIN", 0.0, &DopeInfo::ymin)
73  .setGivenMember(&DopeInfo::yminGiven);
74  addPar("YMAX", 0.0, &DopeInfo::ymax)
75  .setGivenMember(&DopeInfo::ymaxGiven);
76  addPar("YWIDTH", 1.0e-3, &DopeInfo::ywidth);
77 
78  // Set up map for non-double precision variables:
79  addPar("NAME", std::string("none"), &DopeInfo::name);
80  addPar("FUNCTION", std::string("uniform"), &DopeInfo::funcType);
81  addPar("TYPE", std::string("ntype"), &DopeInfo::type);
82  addPar("FLATX", 0, &DopeInfo::flatX);
83  addPar("FLATY", 0, &DopeInfo::flatY);
84  addPar("SPECIES", std::string("none"), &DopeInfo::speciesName);
85  addPar("FILE", std::string("none"), &DopeInfo::fileName);
86  addPar("EXPRESSION", std::string("none"), &DopeInfo::exprString);
87 }
88 
90  static ParametricData<DopeInfo> parMap;
91 
92  return parMap;
93 }
94 
95 // ----------------------------------------------------------------------------
96 // Function : DopeInfo::DopeInfo
97 // Purpose : constructor
98 // Special Notes :
99 // Scope : public
100 // Creator : Eric Keiter, SNL
101 // Creation Date : 05/07/05
102 // ----------------------------------------------------------------------------
104  : CompositeParam (getParametricData()),
105  name("reg0"),
106  type("ntype"),
107  funcType("uniform"),
108  speciesName("none"),
109  fileName("none"),
110 
111  xmin(0.0),
112  xmax(0.0),
113  xloc(0.0),
114  xwidth(0.0),
115 
116  ymin(0.0),
117  ymax(0.0),
118  yloc(0.0),
119  ywidth(0.0),
120 
121  Nmax(1.0e+15),
122  Nmin(1.0e+11),
123  Nmax_chop(1.0e+99),
124  Nmax_chopGiven(false),
125  flatX(0),
126  flatY(0)
127 {}
128 
129 // ----------------------------------------------------------------------------
130 // Function : DopeInfo::processParam
131 // Purpose :
132 // Special Notes :
133 // Scope : public
134 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
135 // Creation Date : 03/31/03
136 // ----------------------------------------------------------------------------
137 bool DopeInfo::processParam(Param & ndParam, std::string & param, DevicePDEInstance & di)
138 {
139  bool bsuccess = true;
140 
141  return bsuccess;
142 }
143 
144 // ----------------------------------------------------------------------------
145 // Function : DopeInfo::processParams
146 // Purpose :
147 // Special Notes :
148 // Scope : public
149 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
150 // Creation Date : 03/31/03
151 // ----------------------------------------------------------------------------
153 {
154  {
155  ParameterMap::const_iterator p_i = getParameterMap().find(std::string("FUNCTION"));
156  const Descriptor &p = *(*p_i).second;
157 
158  ExtendedString tmp = getValue<std::string, DopeInfo>(*this, p);
159  setValue<std::string, DopeInfo>(*this, p, static_cast<std::string>(tmp.toLower()));
160  }
161 
162  {
163  ParameterMap::const_iterator p_i = getParameterMap().find(std::string("TYPE"));
164  const Descriptor &p = *(*p_i).second;
165 
166  ExtendedString tmp = getValue<std::string, DopeInfo>(*this, p);
167  setValue<std::string, DopeInfo>(*this, p, static_cast<std::string>(tmp.toLower()));
168  }
169 }
170 
171 // ----------------------------------------------------------------------------
172 // Function : DopeInfo::setupInfo
173 // Purpose :
174 // Special Notes :
175 // Scope : public
176 // Creator : Eric Keiter, SNL
177 // Creation Date : 11/20/08
178 // ----------------------------------------------------------------------------
180  std::vector<double> & CVec,
181  std::vector<double> & CdonorVec,
182  std::vector<double> & CacceptorVec,
183  std::vector<double> & xVec,
184  DeviceSupport & devSupport)
185 {
186  int i(0);
187  int NX (CVec.size());
188  splintDopeVec.resize(NX,0.0);
189 
190  double sign = 0.0;
191  if (type == "ptype" || type == "acceptor")
192  {
193  sign = -1.0;
194  }
195  else if (type == "ntype" || type == "donor")
196  {
197  sign = 1.0;
198  }
199 
200  if (funcType == "uniform")
201  {
202  for (i=0;i<NX;++i)
203  {
204  if (xmaxGiven && xminGiven)
205  {
206  if (xVec[i] > xmax || xVec[i] < xmin) // if outside the range, skip
207  {
208  continue;
209  }
210  }
211 
212  CVec[i] += sign*Nmax;
213  splintDopeVec[i] = Nmax;
214  if (type == "ptype" || type == "acceptor")
215  {
216  CacceptorVec[i] += Nmax;
217  }
218  else if (type == "ntype" || type == "donor")
219  {
220  CdonorVec[i] += Nmax;
221  }
222  }
223  }
224  else if (funcType == "gaussian")
225  {
226  double deltaX = fabs(xwidth);
227 
228  double ax = log(Nmax/Nmin)/(deltaX*deltaX);
229  for (i=0;i<NX;++i)
230  {
231  double scalarX = 1.0;
232  double abs_dx;
233 
234  if (given("XLOC") && given("XWIDTH") && deltaX != 0.0)
235  {
236  abs_dx = fabs(xVec[i]-xloc);
237 
238  // if true gaussian, x-section:
239  if (flatX==0)
240  {
241  scalarX *= ngdep2(abs_dx, 0.0, ax, 1.0);
242  }
243  else if (flatX>0) // half-gaussian, x-section:
244  {
245  bool flatReg = (xVec[i] > xloc);
246 
247  if (!flatReg)
248  {
249  scalarX *= ngdep2(abs_dx, 0.0, ax, 1.0);
250  }
251  }
252  else if (flatX<0) // half-gaussian, x-section:
253  {
254  bool flatReg = (xVec[i] < xloc);
255 
256  if (!flatReg)
257  {
258  scalarX *= ngdep2(abs_dx, 0.0, ax, 1.0);
259  }
260  }
261  }
262 
263  CVec[i] += sign*Nmax*scalarX;
264  splintDopeVec[i] = Nmax*scalarX;
265  if (type == "ptype" || type == "acceptor")
266  {
267  CacceptorVec[i] += Nmax*scalarX;
268  }
269  else if (type == "ntype" || type == "donor")
270  {
271  CdonorVec[i] += Nmax*scalarX;
272  }
273  }
274  }
275  else if (funcType == "step")
276  {
277  for (i=0;i<NX;++i)
278  {
279  double x = xVec[i];
280  bool regOn = true;
281 
282  if (given("XLOC"))
283  {
284  if (flatX == 0) regOn = true;
285 
286  if (flatX == -1)
287  {
288  if (x > xloc) regOn = false;
289  else regOn = true;
290  }
291 
292  if (flatX == +1)
293  {
294  if (x < xloc) regOn = false;
295  else regOn = true;
296  }
297  }
298 
299  CVec[i] += (regOn)?(sign*Nmax):(sign*Nmin);
300  splintDopeVec[i] = (regOn)?(Nmax):(Nmin);
301  if (type == "ptype" || type == "acceptor")
302  {
303  CacceptorVec[i] += (regOn)?(Nmax):(sign*Nmin);
304  }
305  else if (type == "ntype" || type == "donor")
306  {
307  CdonorVec[i] += (regOn)?(Nmax):(sign*Nmin);
308  }
309  }
310  }
311  else if (funcType == "expression")
312  {
313  if (exprString == "none")
314  {
315  std::string msg = "Dope Region : ";
316  msg += name;
317  msg += " has specified the expression specification, but not provided an expression.";
318  msg += "\n";
319  N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
320  }
321  else
322  {
323  if (DEBUG_DEVICE)
324  {
325  Xyce::dout() << "DopeInfo::setupInfo: exprString = " << exprString << std::endl;
326  }
327  Util::Expression expr;
328  expr.set(exprString);
329 
330  for (i=0;i<NX;++i)
331  {
332  double dopeValue(0.0);
333 
334  expr.set_var(std::string("#X"), xVec[i]);
335  expr.evaluateFunction (dopeValue);
336  CVec[i] += sign*dopeValue;
337  splintDopeVec[i] = dopeValue;
338  if (type == "ptype" || type == "acceptor")
339  {
340  CacceptorVec[i] += dopeValue;
341  }
342  else if (type == "ntype" || type == "donor")
343  {
344  CdonorVec[i] += dopeValue;
345  }
346  }
347  }
348  }
349  else if (funcType == "file")
350  {
351  if (fileName == "none")
352  {
353  std::string msg = "Dope Region : ";
354  msg += name;
355  msg += " has specified the file specification, but not specified a file name.";
356  msg += "\n";
357  N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
358  }
359  else
360  {
361  readDopingFile (fileName, xlocVec, dopeVec, y2Vec, devSupport);
362 
363  // if the user has requested that this be truncated to a max value,
364  // do it here:
365  if (Nmax_chopGiven)
366  {
367  int dopeSize=dopeVec.size();
368  for (int id=0;id<dopeSize;++id)
369  {
370  if (dopeVec[id] > Nmax_chop)
371  {
372  dopeVec[id] = Nmax_chop;
373  }
374  }
375  }
376 
377  for (i=0;i<NX;++i)
378  {
379  double xtmp = xVec[i];
380  double dopeValue(0.0);
381  devSupport.splint(xlocVec, dopeVec, y2Vec, xtmp, dopeValue);
382  CVec[i] += sign*dopeValue;
383  splintDopeVec[i] = dopeValue;
384  if (type == "ptype" || type == "acceptor")
385  {
386  CacceptorVec[i] += dopeValue;
387  }
388  else if (type == "ntype" || type == "donor")
389  {
390  CdonorVec[i] += dopeValue;
391  }
392  }
393  }
394  }
395  else
396  {
397  std::string msg = "Unrecognized Dope Region function type: ";
398  msg += funcType;
399  msg += " for region: ";
400  msg += name;
401  msg += "\n";
402  N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
403  }
404 
405 }
406 
407 // ----------------------------------------------------------------------------
408 // Function : DopeInfo::setupInfo2d
409 // Purpose :
410 // Special Notes :
411 // Scope : public
412 // Creator : Eric Keiter, SNL
413 // Creation Date : 11/20/08
414 // ----------------------------------------------------------------------------
416  std::vector<double> & CVec,
417  std::vector<double> & CdonorVec,
418  std::vector<double> & CacceptorVec,
419  std::vector<double> & xVec,
420  std::vector<double> & yVec,
421  DeviceSupport & devSupport)
422 {
423  int i(0);
424  int numMeshPoints (CVec.size());
425 
426  double sign = 1.0;
427  if (type == "ptype" || type == "acceptor") sign = -1.0;
428 
429  if (funcType == "uniform")
430  {
431  for (i=0;i<numMeshPoints;++i)
432  {
433 
434  if (xmaxGiven && xminGiven)
435  {
436  if (xVec[i] > xmax || xVec[i] < xmin) // if outside the x-range, skip
437  {
438  continue;
439  }
440  }
441 
442  if (ymaxGiven && yminGiven)
443  {
444  if (yVec[i] > ymax || yVec[i] < ymin) // if outside the y-range, skip
445  {
446  continue;
447  }
448  }
449 
450  CVec[i] += sign*Nmax;
451  if (type == "ptype" || type == "acceptor")
452  {
453  CacceptorVec[i] += Nmax;
454  }
455  else
456  {
457  CdonorVec[i] += Nmax;
458  }
459  }
460  }
461  else if (funcType == "gaussian")
462  {
463  double deltaX = fabs(xwidth);
464  double deltaY = fabs(ywidth);
465 
466  double ax = 0.0;
467  double ay = 0.0;
468 
469  if (deltaX!=0.0)
470  {
471  ax = log(Nmax/Nmin)/(deltaX*deltaX);
472  }
473 
474  if (deltaY!=0.0)
475  {
476  ay = log(Nmax/Nmin)/(deltaY*deltaY);
477  }
478 
479  for (i=0;i<numMeshPoints;++i)
480  {
481  double scalarX = 1.0;
482  double scalarY = 1.0;
483  double abs_dx, abs_dy;
484 
485  if (given("XLOC") && given("XWIDTH") && deltaX != 0.0)
486  {
487  abs_dx = fabs(xVec[i]-xloc);
488 
489  // if true gaussian, x-section:
490  if (flatX==0)
491  {
492  scalarX *= ngdep2(abs_dx, 0.0, ax, 1.0);
493  }
494  else if (flatX>0) // half-guassian, x-section:
495  {
496  bool flatReg = (xVec[i] > xloc);
497 
498  if (!flatReg)
499  {
500  scalarX *= ngdep2(abs_dx, 0.0, ax, 1.0);
501  }
502  }
503  else if (flatX<0) // half-guassian, x-section:
504  {
505  bool flatReg = (xVec[i] < xloc);
506 
507  if (!flatReg)
508  {
509  scalarX *= ngdep2(abs_dx, 0.0, ax, 1.0);
510  }
511  }
512  }
513 
514  if (given("YLOC") && given("YWIDTH") && deltaY != 0.0)
515  {
516  abs_dy = fabs(yVec[i]-yloc);
517  // if true gaussian, y-section:
518  if (flatY==0)
519  {
520  scalarY *= ngdep2(0.0, abs_dy, 1.0, ay);
521  }
522  else if (flatY>0) // half-guassian, y-section:
523  {
524  bool flatReg = (yVec[i] > yloc);
525 
526  if (!flatReg)
527  {
528  scalarY *= ngdep2(0.0, abs_dy, 1.0, ay);
529  }
530  }
531  else if (flatY<0) // half-guassian, y-section:
532  {
533  bool flatReg = (yVec[i] < yloc);
534 
535  if (!flatReg)
536  {
537  scalarY *= ngdep2(0.0, abs_dy, 1.0, ay);
538  }
539  }
540  }
541 
542  CVec[i] += sign*Nmax*scalarX*scalarY;
543 
544  if (type == "ptype" || type == "acceptor")
545  {
546  CacceptorVec[i] += Nmax*scalarX*scalarY;
547  }
548  else
549  {
550  CdonorVec[i] += Nmax*scalarX*scalarY;
551  }
552  }
553  }
554  else if (funcType == "step")
555  {
556  for (i=0;i<numMeshPoints;++i)
557  {
558  double x = xVec[i];
559  double y = yVec[i];
560  bool regOnX = true;
561  bool regOnY = true;
562 
563  if (given("YLOC"))
564  {
565  if (flatY == 0) regOnY = true;
566 
567  if (flatY == -1)
568  {
569  if(y > yloc) regOnY = false;
570  else regOnY = true;
571  }
572 
573  if (flatY == +1)
574  {
575  if (y < yloc) regOnY = false;
576  else regOnY = true;
577  }
578  }
579 
580  if (given("XLOC"))
581  {
582  if (flatX == 0) regOnX = true;
583 
584  if (flatX == -1)
585  {
586  if(x > xloc) regOnX = false;
587  else regOnX = true;
588  }
589 
590  if (flatX == +1)
591  {
592  if (x < xloc) regOnX = false;
593  else regOnX = true;
594  }
595  }
596  bool regOn = (regOnX && regOnY);
597 
598  CVec[i] += (regOn)?(sign*Nmax):(sign*Nmin);
599  if (type == "ptype" || type == "acceptor")
600  {
601  CacceptorVec[i] += (regOn)?(Nmax):(sign*Nmin);
602  }
603  else
604  {
605  CdonorVec[i] += (regOn)?(Nmax):(sign*Nmin);
606  }
607  }
608  }
609  else
610  {
611  std::string msg = "Unrecognized Dope Region function type: ";
612  msg += funcType;
613  msg += " for region: ";
614  msg += name;
615  msg += "\n";
616  N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
617  }
618 
619 }
620 
621 // ----------------------------------------------------------------------------
622 // Function : DopeInfo::nsdep
623 // Purpose : This function returns an approximate deposition profile
624 // of a step implant driven in an inert environment.
625 // Special Notes :
626 // 1 W/2 + x W/2 - x
627 // nsdep(x,W,Dt) = - (erf(---------) + erf(----------))
628 // 2 2*sqrt(Dt) 2*sqrt(Dt)
629 //
630 //
631 // Scope : public
632 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
633 // Creation Date : 4/25/02
634 // ----------------------------------------------------------------------------
635 double DopeInfo::nsdep(double x, double W, double Dt)
636 {
637  double D = 2.0 * sqrt(Dt);
638  double Wh = W / 2.0;
639  return 0.5 * (erf((Wh + x)/D) + erf((Wh - x)/D));
640 }
641 
642 // ----------------------------------------------------------------------------
643 // Function : DopeInfo::ngdep
644 //
645 // Purpose : This function returns an approximate Gaussian deposition.
646 //
647 // Adapted from a similar function in SGF.
648 //
649 // Special Notes : This function is a little flakey, in that it assumes
650 // that we're using a cylindrical geomtry
651 // (x = radius, y = height.) It also assumes that the (0,0)
652 // origin is in the upper-left-hand corner of the mesh.
653 //
654 // So, y=0.0 is the upper surface of the device, and the
655 // implant is coming from the top (above y=0.0). Hence,
656 // the (y>0) conditional.
657 //
658 // Also, the width parameter (W), is set up to be a
659 // diameter about x=0, which is the reason for the 0.5*W -
660 // half of this diameter will impact this radius.
661 //
662 // The implant is completely flat and constant in the
663 // x-direction, as long as fabs(x) is less than W/2.0.
664 // Beyond W/2.0, the gaussian profile kicks in.
665 //
666 // The parameters ax and ay are scaling parameters, and
667 // correspond to how much you want the doping to vary with
668 // space. A typical value for either can be set up as:
669 //
670 // Ax = ln (Nhi / Nlo)/(Rx*Rx)
671 //
672 // where:
673 //
674 // Nhi = the max. level of doping
675 // Nlo = the min. level of doping
676 // Rx = distance over which this doping should vary.
677 //
678 // Nhi/Nlo = 10^N, where N = # of orders of magnitude
679 // that should vary between x=0 and x=Rx.
680 //
681 // Scope : public
682 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
683 // Creation Date : 4/25/02
684 // ----------------------------------------------------------------------------
685 double DopeInfo::ngdep(double x, double y, double W, double ax, double ay)
686 {
687  double xprime = fabs(x) - (0.5 * W);
688  return ((xprime <= 0.0) ? 1.0 : exp(-ax*xprime*xprime))*
689  ((y > 0.0) ? 0.0 : exp(-ay*y*y));
690 }
691 
692 // ----------------------------------------------------------------------------
693 // Function : DopeInfo::ngdep2
694 //
695 // Purpose : This function returns an approximate Gaussian deposition.
696 //
697 // Special Notes : This function is a modification of the original ngdep
698 // (see above), and I designed it to address some of the
699 // peculiarities of ngdep.
700 //
701 // (1) I've gotten rid of the width, W. I'm just
702 // going to assume that whoever is calling this function
703 // can set that(the constant region) up on their own.
704 //
705 // (2) I've removed the conditionals cause things to
706 // be set to zero, or one, or whatever, if you are on one
707 // side or another of the suface. I'm assuming that
708 // whoever calls this function can do that themselves, if
709 // they need to.
710 //
711 // (3) I've removed the stuff that sets the retVal to zero
712 // for y>0. Again, this is the user's problem.
713 //
714 // ax and ay mean the same as they did for the original
715 // ngdep. (see above).
716 //
717 // It is possible to use this for the 1D case, pretty
718 // easily. Set the xflag to false, hold y fixed at zero,
719 // and have x correspond to the 1D mesh locations. (or, set
720 // xflag to true, hold x fixed at zero, and let y
721 // correspond to 1D mesh locations - either way).
722 //
723 // Scope : public
724 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
725 // Creation Date : 03/28/03
726 // ----------------------------------------------------------------------------
727 double DopeInfo::ngdep2(double x, double y, double ax, double ay)
728 {
729  double retVal = exp(-ax*x*x)* exp(-ay*y*y);
730  return retVal;
731 }
732 
733 // ----------------------------------------------------------------------------
734 // Function : DopeInfo::erf
735 // Purpose : This function returns the error function.
736 // Special Notes :
737 // Scope : public
738 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
739 // Creation Date : 4/25/02
740 // ----------------------------------------------------------------------------
741 double DopeInfo::erf(double x)
742 {
743  double t1 = 1.0 / (1.0 + 0.3275911 * fabs(x));
744  double t2 = t1 * t1;
745  double t3 = t2 * t1;
746  double t4 = t3 * t1;
747  double t5 = t4 * t1;
748  double result = 1.0 - (0.254829592*t1 - 0.284496736*t2 + 1.421413741*t3 -
749  1.453152027*t4 + 1.061405429*t5) * exp(-x*x);
750  return (x < 0.0) ? -result : result;
751 }
752 
753 //-----------------------------------------------------------------------------
754 // Function : DopeInfo::readDopingFile
755 // Purpose :
756 // Special Notes :
757 // Scope : public
758 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
759 // Creation Date : 11/10/07
760 //-----------------------------------------------------------------------------
762  std::string & filename,
763  std::vector<double> & xloc,
764  std::vector<double> & nvec,
765  std::vector<double> & y2,
766  DeviceSupport & devSupport)
767 {
768  std::ifstream input;
769  double x_loc(0.0);
770  double value(0.0);
771  xloc.clear();
772  nvec.clear();
773  y2.clear();
774 
775  input.open( filename.c_str(), std::ios::in );
776  if ( input.good() )
777  {
778  bool endOfFile = input.eof();
779  while (!endOfFile)
780  {
781  endOfFile = input.eof();
782  if (!endOfFile)
783  {
784  input >> x_loc;
785  }
786  else
787  {
788  break;
789  }
790 
791  endOfFile = input.eof();
792  if (!endOfFile)
793  {
794  input >> value;
795  }
796  else
797  {
798  break;
799  }
800  xloc.push_back(x_loc);
801  nvec.push_back(value);
802  }
803  input.close();
804  y2.resize(xloc.size(),0.0);
805  devSupport.spline (xloc, nvec, y2);
806  }
807  else
808  {
809  std::string msg = "Error: Cannot open doping file: " + filename;
810  N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg);
811  }
812 }
813 
814 //-----------------------------------------------------------------------------
815 // Function : DopeInfo::readDopingFile
816 // Purpose :
817 // Special Notes : This version assumes 2 dopants are in the file, P and N.
818 // Scope : public
819 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
820 // Creation Date : 11/10/07
821 //-----------------------------------------------------------------------------
823  std::string & filename,
824  std::vector<double> & xloc,
825  std::vector<double> & nvec,
826  std::vector<double> & y2_n,
827  std::vector<double> & pvec,
828  std::vector<double> & y2_p,
829  DeviceSupport & devSupport)
830 {
831  std::ifstream input;
832  double x_loc(0.0);
833  double value1(0.0);
834  double value2(0.0);
835  xloc.clear();
836  nvec.clear();
837  pvec.clear();
838  y2_n.clear();
839  y2_p.clear();
840 
841  input.open( filename.c_str(), std::ios::in );
842  if ( input.good() )
843  {
844  bool endOfFile = input.eof();
845  while (!endOfFile)
846  {
847  endOfFile = input.eof();
848  if (!endOfFile)
849  {
850  input >> x_loc;
851  }
852  else
853  {
854  break;
855  }
856 
857  endOfFile = input.eof();
858  if (!endOfFile)
859  {
860  input >> value1;
861  }
862  else
863  {
864  break;
865  }
866  endOfFile = input.eof();
867  if (!endOfFile)
868  {
869  input >> value2;
870  }
871  else
872  {
873  break;
874  }
875 
876  xloc.push_back(x_loc);
877  nvec.push_back(value1);
878  pvec.push_back(value2);
879 
880  //Xyce::dout() << "x="<<x_loc<<" value1="<<value1<<" value2="<<value2<<std::endl;
881  }
882  input.close();
883  y2_n.resize(xloc.size(),0.0);
884  y2_p.resize(xloc.size(),0.0);
885  devSupport.spline (xloc, nvec, y2_n);
886  devSupport.spline (xloc, pvec, y2_p);
887  }
888  else
889  {
890  std::string msg = "Error: Cannot open doping file: " + filename;
891  N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg);
892  }
893 }
894 
895 } // namespace Device
896 } // namespace Xyce
std::vector< double > dopeVec
static double ngdep(double x, double y, double W, double ax, double ay)
static ParametricData< DopeInfo > & getParametricData()
static double ngdep2(double x, double y, double ax, double ay)
static double nsdep(double x, double W, double Dt)
Pure virtual class to augment a linear system.
static void readDopingFile(std::string &filename, std::vector< double > &xloc, std::vector< double > &nvec, std::vector< double > &y2, DeviceSupport &devSup)
const T & value(const ParameterBase &entity, const Descriptor &descriptor)
Returns the value of the parameter for the entity.
Definition: N_DEV_Pars.h:1224
void splint(std::vector< double > &xa, std::vector< double > &ya, std::vector< double > &y2a, double x_position, double &y_spline)
void spline(std::vector< double > &x, std::vector< double > &y, std::vector< double > &y2)
bool given(const std::string &parameter_name) const
given returns true if the value was specified in the netlist (not defaulted).
std::vector< double > xlocVec
void setupInfo(std::vector< double > &CVec, std::vector< double > &CdonorVec, std::vector< double > &CacceptorVec, std::vector< double > &xVec, DeviceSupport &devSup)
std::vector< double > y2Vec
void setupInfo2d(std::vector< double > &CVec, std::vector< double > &CdonorVec, std::vector< double > &CacceptorVec, std::vector< double > &xVec, std::vector< double > &yVec, DeviceSupport &devSup)
Class Descriptor describes the parameters stored in the ParametricData parameter map.
Definition: N_DEV_Pars.h:546
static double erf(double x)
bool processParam(Param &ndParam, std::string &param, DevicePDEInstance &di)
ParametricData()
Constructs the parameter data map.
Definition: N_DEV_Pars.h:1392
std::vector< double > splintDopeVec
#define W
Manages parameter binding for class C.
Definition: N_DEV_Pars.h:214
void processParams()
processParams post processes the parameters that have been set in the object of the derived class...
CompositeParam is the base class for classes that wish to only manage the processing of parameter dat...
const ParameterMap & getParameterMap() const
getParameterMap returns the parameter map which describes the parameters.