Xyce  6.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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-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_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.27 $
40 //
41 // Revision Date : $Date: 2014/02/24 23:49:18 $
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 #ifdef Xyce_DEBUG_DEVICE
324  Xyce::dout() << "DopeInfo::setupInfo: exprString = " << exprString << std::endl;
325 #endif
326  Util::Expression expr;
327  expr.set(exprString);
328 
329  for (i=0;i<NX;++i)
330  {
331  double dopeValue(0.0);
332 
333  expr.set_var(std::string("#X"), xVec[i]);
334  expr.evaluateFunction (dopeValue);
335  CVec[i] += sign*dopeValue;
336  splintDopeVec[i] = dopeValue;
337  if (type == "ptype" || type == "acceptor")
338  {
339  CacceptorVec[i] += dopeValue;
340  }
341  else if (type == "ntype" || type == "donor")
342  {
343  CdonorVec[i] += dopeValue;
344  }
345  }
346  }
347  }
348  else if (funcType == "file")
349  {
350  if (fileName == "none")
351  {
352  std::string msg = "Dope Region : ";
353  msg += name;
354  msg += " has specified the file specification, but not specified a file name.";
355  msg += "\n";
356  N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
357  }
358  else
359  {
360  readDopingFile (fileName, xlocVec, dopeVec, y2Vec, devSupport);
361 
362  // if the user has requested that this be truncated to a max value,
363  // do it here:
364  if (Nmax_chopGiven)
365  {
366  int dopeSize=dopeVec.size();
367  for (int id=0;id<dopeSize;++id)
368  {
369  if (dopeVec[id] > Nmax_chop)
370  {
371  dopeVec[id] = Nmax_chop;
372  }
373  }
374  }
375 
376  for (i=0;i<NX;++i)
377  {
378  double xtmp = xVec[i];
379  double dopeValue(0.0);
380  devSupport.splint(xlocVec, dopeVec, y2Vec, xtmp, dopeValue);
381  CVec[i] += sign*dopeValue;
382  splintDopeVec[i] = dopeValue;
383  if (type == "ptype" || type == "acceptor")
384  {
385  CacceptorVec[i] += dopeValue;
386  }
387  else if (type == "ntype" || type == "donor")
388  {
389  CdonorVec[i] += dopeValue;
390  }
391  }
392  }
393  }
394  else
395  {
396  std::string msg = "Unrecognized Dope Region function type: ";
397  msg += funcType;
398  msg += " for region: ";
399  msg += name;
400  msg += "\n";
401  N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
402  }
403 
404 }
405 
406 // ----------------------------------------------------------------------------
407 // Function : DopeInfo::setupInfo2d
408 // Purpose :
409 // Special Notes :
410 // Scope : public
411 // Creator : Eric Keiter, SNL
412 // Creation Date : 11/20/08
413 // ----------------------------------------------------------------------------
415  std::vector<double> & CVec,
416  std::vector<double> & CdonorVec,
417  std::vector<double> & CacceptorVec,
418  std::vector<double> & xVec,
419  std::vector<double> & yVec,
420  DeviceSupport & devSupport)
421 {
422  int i(0);
423  int numMeshPoints (CVec.size());
424 
425  double sign = 1.0;
426  if (type == "ptype" || type == "acceptor") sign = -1.0;
427 
428  if (funcType == "uniform")
429  {
430  for (i=0;i<numMeshPoints;++i)
431  {
432 
433  if (xmaxGiven && xminGiven)
434  {
435  if (xVec[i] > xmax || xVec[i] < xmin) // if outside the x-range, skip
436  {
437  continue;
438  }
439  }
440 
441  if (ymaxGiven && yminGiven)
442  {
443  if (yVec[i] > ymax || yVec[i] < ymin) // if outside the y-range, skip
444  {
445  continue;
446  }
447  }
448 
449  CVec[i] += sign*Nmax;
450  if (type == "ptype" || type == "acceptor")
451  {
452  CacceptorVec[i] += Nmax;
453  }
454  else
455  {
456  CdonorVec[i] += Nmax;
457  }
458  }
459  }
460  else if (funcType == "gaussian")
461  {
462  double deltaX = fabs(xwidth);
463  double deltaY = fabs(ywidth);
464 
465  double ax = 0.0;
466  double ay = 0.0;
467 
468  if (deltaX!=0.0)
469  {
470  ax = log(Nmax/Nmin)/(deltaX*deltaX);
471  }
472 
473  if (deltaY!=0.0)
474  {
475  ay = log(Nmax/Nmin)/(deltaY*deltaY);
476  }
477 
478  for (i=0;i<numMeshPoints;++i)
479  {
480  double scalarX = 1.0;
481  double scalarY = 1.0;
482  double abs_dx, abs_dy;
483 
484  if (given("XLOC") && given("XWIDTH") && deltaX != 0.0)
485  {
486  abs_dx = fabs(xVec[i]-xloc);
487 
488  // if true gaussian, x-section:
489  if (flatX==0)
490  {
491  scalarX *= ngdep2(abs_dx, 0.0, ax, 1.0);
492  }
493  else if (flatX>0) // half-guassian, x-section:
494  {
495  bool flatReg = (xVec[i] > xloc);
496 
497  if (!flatReg)
498  {
499  scalarX *= ngdep2(abs_dx, 0.0, ax, 1.0);
500  }
501  }
502  else if (flatX<0) // half-guassian, x-section:
503  {
504  bool flatReg = (xVec[i] < xloc);
505 
506  if (!flatReg)
507  {
508  scalarX *= ngdep2(abs_dx, 0.0, ax, 1.0);
509  }
510  }
511  }
512 
513  if (given("YLOC") && given("YWIDTH") && deltaY != 0.0)
514  {
515  abs_dy = fabs(yVec[i]-yloc);
516  // if true gaussian, y-section:
517  if (flatY==0)
518  {
519  scalarY *= ngdep2(0.0, abs_dy, 1.0, ay);
520  }
521  else if (flatY>0) // half-guassian, y-section:
522  {
523  bool flatReg = (yVec[i] > yloc);
524 
525  if (!flatReg)
526  {
527  scalarY *= ngdep2(0.0, abs_dy, 1.0, ay);
528  }
529  }
530  else if (flatY<0) // half-guassian, y-section:
531  {
532  bool flatReg = (yVec[i] < yloc);
533 
534  if (!flatReg)
535  {
536  scalarY *= ngdep2(0.0, abs_dy, 1.0, ay);
537  }
538  }
539  }
540 
541  CVec[i] += sign*Nmax*scalarX*scalarY;
542 
543  if (type == "ptype" || type == "acceptor")
544  {
545  CacceptorVec[i] += Nmax*scalarX*scalarY;
546  }
547  else
548  {
549  CdonorVec[i] += Nmax*scalarX*scalarY;
550  }
551  }
552  }
553  else if (funcType == "step")
554  {
555  for (i=0;i<numMeshPoints;++i)
556  {
557  double x = xVec[i];
558  double y = yVec[i];
559  bool regOnX = true;
560  bool regOnY = true;
561 
562  if (given("YLOC"))
563  {
564  if (flatY == 0) regOnY = true;
565 
566  if (flatY == -1)
567  {
568  if(y > yloc) regOnY = false;
569  else regOnY = true;
570  }
571 
572  if (flatY == +1)
573  {
574  if (y < yloc) regOnY = false;
575  else regOnY = true;
576  }
577  }
578 
579  if (given("XLOC"))
580  {
581  if (flatX == 0) regOnX = true;
582 
583  if (flatX == -1)
584  {
585  if(x > xloc) regOnX = false;
586  else regOnX = true;
587  }
588 
589  if (flatX == +1)
590  {
591  if (x < xloc) regOnX = false;
592  else regOnX = true;
593  }
594  }
595  bool regOn = (regOnX && regOnY);
596 
597  CVec[i] += (regOn)?(sign*Nmax):(sign*Nmin);
598  if (type == "ptype" || type == "acceptor")
599  {
600  CacceptorVec[i] += (regOn)?(Nmax):(sign*Nmin);
601  }
602  else
603  {
604  CdonorVec[i] += (regOn)?(Nmax):(sign*Nmin);
605  }
606  }
607  }
608  else
609  {
610  std::string msg = "Unrecognized Dope Region function type: ";
611  msg += funcType;
612  msg += " for region: ";
613  msg += name;
614  msg += "\n";
615  N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
616  }
617 
618 }
619 
620 // ----------------------------------------------------------------------------
621 // Function : DopeInfo::nsdep
622 // Purpose : This function returns an approximate deposition profile
623 // of a step implant driven in an inert environment.
624 // Special Notes :
625 // 1 W/2 + x W/2 - x
626 // nsdep(x,W,Dt) = - (erf(---------) + erf(----------))
627 // 2 2*sqrt(Dt) 2*sqrt(Dt)
628 //
629 //
630 // Scope : public
631 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
632 // Creation Date : 4/25/02
633 // ----------------------------------------------------------------------------
634 double DopeInfo::nsdep(double x, double W, double Dt)
635 {
636  double D = 2.0 * sqrt(Dt);
637  double Wh = W / 2.0;
638  return 0.5 * (erf((Wh + x)/D) + erf((Wh - x)/D));
639 }
640 
641 // ----------------------------------------------------------------------------
642 // Function : DopeInfo::ngdep
643 //
644 // Purpose : This function returns an approximate Gaussian deposition.
645 //
646 // Adapted from a similar function in SGF.
647 //
648 // Special Notes : This function is a little flakey, in that it assumes
649 // that we're using a cylindrical geomtry
650 // (x = radius, y = height.) It also assumes that the (0,0)
651 // origin is in the upper-left-hand corner of the mesh.
652 //
653 // So, y=0.0 is the upper surface of the device, and the
654 // implant is coming from the top (above y=0.0). Hence,
655 // the (y>0) conditional.
656 //
657 // Also, the width parameter (W), is set up to be a
658 // diameter about x=0, which is the reason for the 0.5*W -
659 // half of this diameter will impact this radius.
660 //
661 // The implant is completely flat and constant in the
662 // x-direction, as long as fabs(x) is less than W/2.0.
663 // Beyond W/2.0, the gaussian profile kicks in.
664 //
665 // The parameters ax and ay are scaling parameters, and
666 // correspond to how much you want the doping to vary with
667 // space. A typical value for either can be set up as:
668 //
669 // Ax = ln (Nhi / Nlo)/(Rx*Rx)
670 //
671 // where:
672 //
673 // Nhi = the max. level of doping
674 // Nlo = the min. level of doping
675 // Rx = distance over which this doping should vary.
676 //
677 // Nhi/Nlo = 10^N, where N = # of orders of magnitude
678 // that should vary between x=0 and x=Rx.
679 //
680 // Scope : public
681 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
682 // Creation Date : 4/25/02
683 // ----------------------------------------------------------------------------
684 double DopeInfo::ngdep(double x, double y, double W, double ax, double ay)
685 {
686  double xprime = fabs(x) - (0.5 * W);
687  return ((xprime <= 0.0) ? 1.0 : exp(-ax*xprime*xprime))*
688  ((y > 0.0) ? 0.0 : exp(-ay*y*y));
689 }
690 
691 // ----------------------------------------------------------------------------
692 // Function : DopeInfo::ngdep2
693 //
694 // Purpose : This function returns an approximate Gaussian deposition.
695 //
696 // Special Notes : This function is a modification of the original ngdep
697 // (see above), and I designed it to address some of the
698 // peculiarities of ngdep.
699 //
700 // (1) I've gotten rid of the width, W. I'm just
701 // going to assume that whoever is calling this function
702 // can set that(the constant region) up on their own.
703 //
704 // (2) I've removed the conditionals cause things to
705 // be set to zero, or one, or whatever, if you are on one
706 // side or another of the suface. I'm assuming that
707 // whoever calls this function can do that themselves, if
708 // they need to.
709 //
710 // (3) I've removed the stuff that sets the retVal to zero
711 // for y>0. Again, this is the user's problem.
712 //
713 // ax and ay mean the same as they did for the original
714 // ngdep. (see above).
715 //
716 // It is possible to use this for the 1D case, pretty
717 // easily. Set the xflag to false, hold y fixed at zero,
718 // and have x correspond to the 1D mesh locations. (or, set
719 // xflag to true, hold x fixed at zero, and let y
720 // correspond to 1D mesh locations - either way).
721 //
722 // Scope : public
723 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
724 // Creation Date : 03/28/03
725 // ----------------------------------------------------------------------------
726 double DopeInfo::ngdep2(double x, double y, double ax, double ay)
727 {
728  double retVal = exp(-ax*x*x)* exp(-ay*y*y);
729  return retVal;
730 }
731 
732 // ----------------------------------------------------------------------------
733 // Function : DopeInfo::erf
734 // Purpose : This function returns the error function.
735 // Special Notes :
736 // Scope : public
737 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
738 // Creation Date : 4/25/02
739 // ----------------------------------------------------------------------------
740 double DopeInfo::erf(double x)
741 {
742  double t1 = 1.0 / (1.0 + 0.3275911 * fabs(x));
743  double t2 = t1 * t1;
744  double t3 = t2 * t1;
745  double t4 = t3 * t1;
746  double t5 = t4 * t1;
747  double result = 1.0 - (0.254829592*t1 - 0.284496736*t2 + 1.421413741*t3 -
748  1.453152027*t4 + 1.061405429*t5) * exp(-x*x);
749  return (x < 0.0) ? -result : result;
750 }
751 
752 //-----------------------------------------------------------------------------
753 // Function : DopeInfo::readDopingFile
754 // Purpose :
755 // Special Notes :
756 // Scope : public
757 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
758 // Creation Date : 11/10/07
759 //-----------------------------------------------------------------------------
761  std::string & filename,
762  std::vector<double> & xloc,
763  std::vector<double> & nvec,
764  std::vector<double> & y2,
765  DeviceSupport & devSupport)
766 {
767  std::ifstream input;
768  double x_loc(0.0);
769  double value(0.0);
770  xloc.clear();
771  nvec.clear();
772  y2.clear();
773 
774  input.open( filename.c_str(), std::ios::in );
775  if ( input.good() )
776  {
777  bool endOfFile = input.eof();
778  while (!endOfFile)
779  {
780  endOfFile = input.eof();
781  if (!endOfFile)
782  {
783  input >> x_loc;
784  }
785  else
786  {
787  break;
788  }
789 
790  endOfFile = input.eof();
791  if (!endOfFile)
792  {
793  input >> value;
794  }
795  else
796  {
797  break;
798  }
799  xloc.push_back(x_loc);
800  nvec.push_back(value);
801  }
802  input.close();
803  y2.resize(xloc.size(),0.0);
804  devSupport.spline (xloc, nvec, y2);
805  }
806  else
807  {
808  std::string msg = "Error: Cannot open doping file: " + filename;
809  N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg);
810  }
811 }
812 
813 //-----------------------------------------------------------------------------
814 // Function : DopeInfo::readDopingFile
815 // Purpose :
816 // Special Notes : This version assumes 2 dopants are in the file, P and N.
817 // Scope : public
818 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
819 // Creation Date : 11/10/07
820 //-----------------------------------------------------------------------------
822  std::string & filename,
823  std::vector<double> & xloc,
824  std::vector<double> & nvec,
825  std::vector<double> & y2_n,
826  std::vector<double> & pvec,
827  std::vector<double> & y2_p,
828  DeviceSupport & devSupport)
829 {
830  std::ifstream input;
831  double x_loc(0.0);
832  double value1(0.0);
833  double value2(0.0);
834  xloc.clear();
835  nvec.clear();
836  pvec.clear();
837  y2_n.clear();
838  y2_p.clear();
839 
840  input.open( filename.c_str(), std::ios::in );
841  if ( input.good() )
842  {
843  bool endOfFile = input.eof();
844  while (!endOfFile)
845  {
846  endOfFile = input.eof();
847  if (!endOfFile)
848  {
849  input >> x_loc;
850  }
851  else
852  {
853  break;
854  }
855 
856  endOfFile = input.eof();
857  if (!endOfFile)
858  {
859  input >> value1;
860  }
861  else
862  {
863  break;
864  }
865  endOfFile = input.eof();
866  if (!endOfFile)
867  {
868  input >> value2;
869  }
870  else
871  {
872  break;
873  }
874 
875  xloc.push_back(x_loc);
876  nvec.push_back(value1);
877  pvec.push_back(value2);
878 
879  //Xyce::dout() << "x="<<x_loc<<" value1="<<value1<<" value2="<<value2<<std::endl;
880  }
881  input.close();
882  y2_n.resize(xloc.size(),0.0);
883  y2_p.resize(xloc.size(),0.0);
884  devSupport.spline (xloc, nvec, y2_n);
885  devSupport.spline (xloc, pvec, y2_p);
886  }
887  else
888  {
889  std::string msg = "Error: Cannot open doping file: " + filename;
890  N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg);
891  }
892 }
893 
894 } // namespace Device
895 } // namespace Xyce