Xyce  6.1
N_DEV_ReactionNetwork.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_ReactionNetwork.C,v $
27 //
28 // Purpose :
29 //
30 // Special Notes :
31 //
32 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
33 //
34 // Creation Date : 03/20/2006
35 //
36 // Revision Information:
37 // ---------------------
38 //
39 // Revision Number: $Revision: 1.23.2.1 $
40 //
41 // Revision Date : $Date: 2015/04/02 18:20:09 $
42 //
43 // Current Owner : $Author: tvrusso $
44 //-----------------------------------------------------------------------------
45 
46 #include <Xyce_config.h>
47 
48 
49 //Standard includes
50 
51 #include <iostream>
52 #include <sstream>
53 
54 // Xyce Includes
55 #include <N_UTL_fwd.h>
56 #include <N_ERH_ErrorMgr.h>
57 #include <N_UTL_Expression.h>
58 #include <N_UTL_FeatureTest.h>
59 #include <N_DEV_ReactionNetwork.h>
60 #include <N_DEV_MaterialLayer.h>
61 
62 
63 #ifdef Xyce_REACTION_PARSER
64 // Grrrr. Stupid bison 2.4 stopped putting the pre-prologue into the header.
65 // need this forward declaration
66 namespace Xyce {
67 namespace Device {
68 class ReactionLexer;
69 }}
70 
71 #include "N_DEV_ReactionParser.hxx"
72 // BLEAH! This is here DUPLICATED from N_DEV_ReactionParser.yxx
73 // because of STUPID choice in Bison 2.3 to put the post-prologue into the
74 // .cxx file instead of the .hxx file that Bison 2.1 used to put it in.
75 #undef yyFlexLexer
76  /* CAREFUL watch continuations! */
77 #define YY_DECL \
78  int N_DEV_ReactionLexer::getToken(Xyce::Device::N_DEV_ReactionParser::semantic_value *lvalp, \
79  Xyce::Device::location *llocp, \
80  map<std::string,int> &theSpeciesIDs)
81 
82  // YECH! Work around very stupid way that multiple parsers/lexers are
83  // handled.
84  // Bison's "%name-prefix" is implemented as a #define yylex "prefix"lex
85  // which BREAKS flex's C++ lexer: it contains a method "yylex" in the
86  // yyFlexLexer class. Unless we do this kludge, that method gets renamed
87  // with the define as well, and the result is a broken set of classes
88 #undef yylex
89 #include <FlexLexer.h>
90 #include <N_DEV_ReactionLexer.h>
91  // undo that kludge. Note that because of this stupidity, if the
92  // "%name-prefix" is changed, this line needs to be changed, too.
93 #define yylex N_DEV_lex
94 
95 #endif
96 
97 namespace Xyce {
98 namespace Device {
99 
100 //-----------------------------------------------------------------------------
101 // Function : ReactionNetwork::ReactionNetwork
102 // Purpose : Constructor
103 // Special Notes :
104 // Scope : public
105 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
106 // Creation Date : 03/20/06
107 //-----------------------------------------------------------------------------
108 ReactionNetwork::ReactionNetwork(const std::string &name)
109  : myName(name),
110  sourceScaleFac(1.0),
111  C0(1.0),
112  t0(1.0),
113  x0(1.0),
114  applySources(true)
115 {
116  theReactions.reserve(10); // try to cut down on copies
117 }
118 
119 //-----------------------------------------------------------------------------
120 // Function : ReactionNetwork::ReactionNetwork
121 // Purpose : Copy constructor
122 // Special Notes :
123 // Scope : public
124 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
125 // Creation Date : 03/20/06
126 //-----------------------------------------------------------------------------
128  const ReactionNetwork &right)
129  : speciesMap(right.speciesMap),
130  species(right.species),
131  constantsMap(right.constantsMap),
132  constants(right.constants),
133  initialConditions(right.initialConditions),
134  theReactions(right.theReactions),
135  reactionNamesMap(right.reactionNamesMap),
136  reactionNames(right.reactionNames),
137  myName(right.myName),
138  electronCaptureReactions(right.electronCaptureReactions),
139  holeCaptureReactions(right.holeCaptureReactions),
140  electronEmissionReactions(right.electronEmissionReactions),
141  holeEmissionReactions(right.holeEmissionReactions),
142  sourceScaleFac(right.sourceScaleFac),
143  C0(right.C0),
144  t0(right.t0),
145  x0(right.x0),
146  applySources(right.applySources),
147  material(right.material)
148 {
149 
150  // Can't just copy the vector of source terms, coz those are pointers.
151  // Need to do deep copy:
152  int i,sourceSize;
153  sourceSize=right.theSourceTerms.size();
154  theSourceTerms.reserve(sourceSize);
155  for (i=0;i<sourceSize;++i)
156  {
157  Util::Expression *newSource;
158  // make a new one as a copy of the right one
159  newSource = new Util::Expression(*((right.theSourceTerms[i]).second));
160  theSourceTerms.push_back(std::pair<int,Util::Expression *>(
161  (right.theSourceTerms[i]).first,
162  newSource) );
163  }
164 
165 }
166 
167 //-----------------------------------------------------------------------------
168 // Function : ReactionNetwork::~ReactionNetwork
169 // Purpose : Destructor
170 // Special Notes :
171 // Scope : public
172 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
173 // Creation Date : 03/20/06
174 //-----------------------------------------------------------------------------
176 {
177 
178  // It is no longer the case that we store only copies of expression
179  // pointers allocated from other classes. We now *must* destroy expressions
180  // we have created in parsing. Since it is difficult to keep track of
181  // which expression pointers were passed in to us and which we created
182  // ourselves, we no longer store those passed-in pointers, but rather
183  // pointers to copies of the pointed-to expression.
184 
185  // Walk backwards through the sourceTerms vector, deleting the expression
186  // and removing the pair from the vector.
187  while (!theSourceTerms.empty())
188  {
189  std::pair<int,Util::Expression *> tempPair = theSourceTerms.back();
190  theSourceTerms.pop_back();
191  delete tempPair.second;
192  }
193 }
194 
195 
196 //-----------------------------------------------------------------------------
197 // Function : ReactionNetwork::setReactionNetworkFromFile
198 // Purpose : Parse a reaction network specification file and set the
199 // network up.
200 //
201 // Special Notes :
202 //
203 // Scope : public
204 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
205 // Creation Date : 08/24/06
206 //-----------------------------------------------------------------------------
207 void
208 ReactionNetwork::setReactionNetworkFromFile(const NetlistLocation &netlist_location, const std::string &fileName)
209 {
210 #ifdef Xyce_REACTION_PARSER
211  if (fileName != "") // do nothing if no file specified
212  {
213  // Get the reaction set from a file
214  std::map<std::string,int> theSpeciesIDs;
215 
216  // temporary hard-coded filename
217  std::ifstream reactionFile(fileName.c_str(),std::ios::in);
218  if (reactionFile.is_open())
219  {
220  ReactionLexer theLexer(netlist_location, fileName, &reactionFile);
221  XyceDevice::ReactionParser theParser(&theLexer, theSpeciesIDs, *this);
222 
223  if (theParser.parse() != 0)
224  {
225  if (DEBUG_DEVICE)
226  {
227  Xyce::dout() << *this << std::endl;
228  }
229  }
230  }
231  else
232  {
233  Report::UserError() << "Cannot open reaction specification file " << fileName;
234  }
235  }
236 #endif
237 
238 }
239 
240 //-----------------------------------------------------------------------------
241 // Function : ReactionNetwork::setSpecies
242 // Purpose : register a list of species names used in reactions.
243 //
244 // Special Notes : Once registered this way, it is assumed that all vectors
245 // of species concentrations are ordered in the same way as
246 // the provided vector of species names.
247 //
248 // Scope : public
249 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
250 // Creation Date : 03/20/06
251 //-----------------------------------------------------------------------------
252 void ReactionNetwork::setSpecies(std::vector<Specie> &theSpeciesVect)
253 {
254 
255  int i;
256  int nspec=theSpeciesVect.size();
257 
258  speciesMap.clear();
259  species=theSpeciesVect;
260 
261  for (i=0;i<nspec;++i)
262  {
263  speciesMap[theSpeciesVect[i].getName()]=i;
264  }
265 
266 }
267 
268 //-----------------------------------------------------------------------------
269 // Function : ReactionNetwork::setConstants
270 // Purpose : register a list of constant species names used in reactions.
271 //
272 // Special Notes : Once registered this way, it is assumed that all
273 // vectors of constant species concentrations are ordered in
274 // the same way as the provided vector of species names.
275 //
276 // Constant species are those whose concentrations remain
277 // unaltered by the reaction network, e.g. those that are
278 // fed into the system at fixed rate as in a CSTR.
279 //
280 // Scope : public
281 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
282 // Creation Date : 03/20/06
283 //-----------------------------------------------------------------------------
284 void ReactionNetwork::setConstants(std::vector<Specie> &theConstantsVect)
285 {
286 
287  int i;
288  int nspec=theConstantsVect.size();
289 
290  constantsMap.clear();
291  constants = theConstantsVect;
292 
293  for (i=0;i<nspec;++i)
294  {
295  constantsMap[theConstantsVect[i].getName()]=i;
296  }
297 }
298 
299 
300 //-----------------------------------------------------------------------------
301 // Function : ReactionNetwork::addSpecie
302 // Purpose : add one to the list of species names used in reactions.
303 //
304 // Scope : public
305 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
306 // Creation Date : 03/20/06
307 //-----------------------------------------------------------------------------
308 void ReactionNetwork::addSpecie(const Specie &aSpecie)
309 {
310 
311  int i=species.size(); // get index of next one we add
312  species.push_back(aSpecie);
313  speciesMap[aSpecie.getName()]=i;
314 
315 }
316 
317 //-----------------------------------------------------------------------------
318 // Function : ReactionNetwork::addConstant
319 // Purpose : add one to the list of constant names used in reactions.
320 //
321 // Scope : public
322 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
323 // Creation Date : 03/20/06
324 //-----------------------------------------------------------------------------
325 void ReactionNetwork::addConstant(const Specie &aConstant)
326 {
327 
328  int i=constants.size(); // get index of next one we add
329  constants.push_back(aConstant);
330  constantsMap[aConstant.getName()]=i;
331 
332 }
333 
334 //-----------------------------------------------------------------------------
335 // Function : ReactionNetwork::addReaction
336 // Purpose : Create a new named reaction in the network
337 // Special Notes :
338 // Scope : public
339 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
340 // Creation Date : 03/20/06
341 //-----------------------------------------------------------------------------
342 void ReactionNetwork::addReaction(const std::string &name)
343 {
345  //Reaction dummy;
346 
347  addReaction(name, dummy);
348 }
349 
350 //-----------------------------------------------------------------------------
351 // Function : ReactionNetwork::addReaction
352 // Purpose : Add a reaction object into the network and give it a name
353 // Special Notes :
354 // Scope : public
355 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
356 // Creation Date : 03/20/06
357 //-----------------------------------------------------------------------------
358  void ReactionNetwork::addReaction(const std::string &name, Xyce::Device::Reaction &reaction)
359 {
360  // first check if there is already a reaction of that name in the
361  // reactions map:
362 
363  if (reactionNamesMap.find(name) != reactionNamesMap.end())
364  {
365  Report::DevelFatal() << " Attempt to add reaction duplicate name " << name;
366  }
367 
368  //try to cut down on calls to copy constructor
369  if (theReactions.capacity()<=theReactions.size())
370  {
371  theReactions.reserve(theReactions.size()+10);
372  }
373  theReactions.push_back(reaction);
374  reactionNames.push_back(name);
375  reactionNamesMap[name]=theReactions.size()-1;
376 
377  // Now check if the reaction has "_ELECTRON_CAPTURE",
378  // "_ELECTRON_EMISSION", "_HOLE_CAPTURE" or "_HOLE_EMISSION" in it.
379  // If so, keep track of it in a separate vector for such things.
380  // we do this so we can later get at them quickly without doing name
381  // searches.
382  if (name.find("_ELECTRON_CAPTURE",0) != std::string::npos)
383  {
384  electronCaptureReactions.push_back(theReactions.size()-1);
385  }
386  else if (name.find("_HOLE_CAPTURE",0) != std::string::npos)
387  {
388  holeCaptureReactions.push_back(theReactions.size()-1);
389  }
390  else if (name.find("_ELECTRON_EMISSION",0) != std::string::npos)
391  {
392  electronEmissionReactions.push_back(theReactions.size()-1);
393  }
394  else if (name.find("_HOLE_EMISSION",0) != std::string::npos)
395  {
396  holeEmissionReactions.push_back(theReactions.size()-1);
397  }
398 }
399 
400 //-----------------------------------------------------------------------------
401 // Function : ReactionNetwork::addReactant
402 // Purpose : add a species/stoichiometric coefficient pair to the
403 // reactant list of a specified named reaction
404 // The species is specified using its name, and can be either
405 // one of those in the list provided by setSpecies or
406 // setConstants.
407 // Special Notes :
408 // Scope : public
409 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
410 // Creation Date : 03/20/06
411 //-----------------------------------------------------------------------------
412 void ReactionNetwork::addReactant(const std::string &name, const std::string &reactant, double stoich)
413 {
414 
415  std::map<std::string,int>::iterator n_i;
416  // check that name exists in map
417  int reactionNum;
418  reactionNum=getReactionNum(name);
419  if (reactionNum == -1)
420  {
421  Report::DevelFatal() << " Attempt to add reactant " << reactant
422  << " to non-existant reaction " << name;
423  }
424  else
425  {
426  int speciesNum;
427  // now check if we know this reactant
428 
429  n_i = speciesMap.find(reactant);
430  if (n_i == speciesMap.end())
431  {
432  // not a solution species --- is it a constant?
433  n_i = constantsMap.find(reactant);
434  if (n_i == constantsMap.end())
435  { // nope
436  Report::DevelFatal() << "attempt to add unknown reactant " << reactant
437  << " to reaction number " << reactionNum
438  << "("<<name<<")";
439  }
440  else
441  {
442  speciesNum = -(n_i->second+1);
443  }
444  }
445  else
446  {
447  speciesNum = n_i->second;
448  }
449 
450 
451  getReaction(reactionNum).addReactant(speciesNum,stoich);
452  }
453 }
454 
455 //-----------------------------------------------------------------------------
456 // Function : ReactionNetwork::addProduct
457 // Purpose : add a species/stoichiometric coefficient pair to the
458 // product list of a specified named reaction
459 // The species is specified using its name, and must be
460 // one of those in the list provided by setSpecies
461 // (must not be one from the Constants list).
462 // Special Notes :
463 // Scope : public
464 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
465 // Creation Date : 03/20/06
466 //-----------------------------------------------------------------------------
467 void ReactionNetwork::addProduct(const std::string &name, const std::string &product, double stoich)
468 {
469 
470  std::map<std::string,int>::iterator n_i;
471 
472  // check that reaction name exists in map
473  // check that name exists in map
474  int reactionNum;
475  reactionNum=getReactionNum(name);
476  if (reactionNum == -1)
477  {
478  Report::DevelFatal() << " Attempt to add product " << product
479  << " to non-existant reaction " << name;
480  }
481  else
482  {
483  int speciesNum;
484  // now check if we know this product
485 
486  n_i = speciesMap.find(product);
487  if (n_i == speciesMap.end())
488  {
489  // not a solution species --- is it a constant?
490  n_i = constantsMap.find(product);
491  if (n_i == constantsMap.end())
492  { // nope
493  Report::DevelFatal() << "attempt to add unknown product " << product
494  << " to reaction number " << reactionNum
495  << "("<<name<<")";
496  }
497  else
498  {
499  std::ostringstream ost;
500 
501 #ifdef Xyce_RXN_WARNINGS
502  Report::UserWarning() << " Specified constant species " << product
503  << " as product of reaction number " << reactionNum
504  << "(" << name << ")"<<std::endl
505  << " IGNORING that product";
506 #endif
507  }
508  }
509  else
510  {
511  speciesNum = n_i->second;
512  getReaction(reactionNum).addProduct(speciesNum,stoich);
513  }
514 
515 
516  }
517 }
518 
519 
520 //-----------------------------------------------------------------------------
521 // Function : ReactionNetwork::setRateConstant
522 // Purpose : set the rate constant for the named reaction
523 // Special Notes :
524 // Scope : public
525 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
526 // Creation Date : 03/20/06
527 //-----------------------------------------------------------------------------
528 void ReactionNetwork::setRateConstant(const std::string &name, double k)
529 {
530  int reactionNum;
531  // check that reaction name exists in map
532  reactionNum=getReactionNum(name);
533  if (reactionNum == -1)
534  {
535  Report::DevelFatal() << " Attempt to set rate constant of non-existant reaction "
536  << name;
537  }
538  else
539  {
540  getReaction(reactionNum).setRateConstant(k);
541  }
542 }
543 
544 //-----------------------------------------------------------------------------
545 // Function : ReactionNetwork::scaleRateConstant
546 // Purpose : set the rate constant for the named reaction
547 // Special Notes :
548 // Scope : public
549 // Creator : Eric Keiter, SNL, Electrical and Microsystems Modeling
550 // Creation Date : 06/01/06
551 //-----------------------------------------------------------------------------
552 void ReactionNetwork::scaleRateConstant(const std::string &name, double kscale)
553 {
554 
555  int reactionNum;
556  // check that reaction name exists in map
557  reactionNum = getReactionNum(name);
558  if (reactionNum == -1)
559  {
560  Report::DevelFatal() << " Attempt to scale rate constant of non-existant reaction "
561  << name;
562  }
563  else
564  {
565  getReaction(reactionNum).scaleRateConstant(kscale);
566  }
567 }
568 
569 //-----------------------------------------------------------------------------
570 // Function : ReactionNetwork::setRateConstantFromCalculator
571 // Purpose : set the rate constant for the named reaction according
572 // to its saved method
573 // Special Notes :
574 // Scope : public
575 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
576 // Creation Date : 08/01/06
577 //-----------------------------------------------------------------------------
578 void ReactionNetwork::setRateConstantFromCalculator (const std::string &name, double T)
579 {
580 
581  int reactionNum;
582  // check that reaction name exists in map
583  reactionNum = getReactionNum(name);
584  if (reactionNum == -1)
585  {
586  Report::DevelFatal() << " Attempt to scale rate constant of non-existant reaction "
587  << name;
588  }
589  else
590  {
592  }
593 }
594 
595 
596 //-----------------------------------------------------------------------------
597 // Function : ReactionNetwork::setRateConstantFromCalculator
598 // Purpose : set the rate constant for the named reaction according
599 // to its saved method
600 // Special Notes :
601 // Scope : public
602 // Creator : Lawrence C Musson, SNL, Electrical and Microsystems Modeling
603 // Creation Date : 04/17/2014
604 //-----------------------------------------------------------------------------
605 void ReactionNetwork::setRateConstantFromCalculator (const std::string &name, double T,
606  std::vector<double> &concs,
607  std::vector<double> &constant_vec)
608 {
609 
610  int reactionNum;
611  // check that reaction name exists in map
612  reactionNum = getReactionNum(name);
613  if (reactionNum == -1)
614  {
615  Report::DevelFatal() << " Attempt to scale rate constant of non-existant reaction "
616  << name;
617  }
618  else
619  {
620  getReaction(reactionNum).setRateConstantFromCalculator(T,concs,constant_vec);
621  }
622 }
623 
624 //-----------------------------------------------------------------------------
625 // Function : ReactionNetwork::scaleRateConstantFromCalculator
626 // Purpose : scale the rate constant for the named reaction according
627 // to its saved method
628 // Special Notes :
629 // Scope : public
630 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
631 // Creation Date : 08/01/06
632 //-----------------------------------------------------------------------------
634 {
635 
636  int reactionNum;
637  // check that reaction name exists in map
638  reactionNum = getReactionNum(name);
639  if (reactionNum == -1)
640  {
641  Report::DevelFatal() << " Attempt to scale rate constant of non-existant reaction "
642  << name;
643  }
644  else
645  {
647  }
648 }
649 
650 //-----------------------------------------------------------------------------
651 // Function : ReactionNetwork::unscaleRateConstantFromCalculator
652 // Purpose : unscale the rate constant for the named reaction according
653 // to its saved method
654 // Special Notes :
655 // Scope : public
656 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
657 // Creation Date : 08/01/06
658 //-----------------------------------------------------------------------------
660 {
661 
662  int reactionNum;
663  // check that reaction name exists in map
664  reactionNum = getReactionNum(name);
665  if (reactionNum == -1)
666  {
667  Report::DevelFatal() << " Attempt to scale rate constant of non-existant reaction "
668  << name;
669  }
670  else
671  {
673  }
674 }
675 
676 //-----------------------------------------------------------------------------
677 // Function : ReactionNetwork::setRateConstantsFromCalc
678 // Purpose : set the rate constant for the all reaction according
679 // to their saved methods
680 // Special Notes :
681 // Scope : public
682 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
683 // Creation Date : 08/02/06
684 //-----------------------------------------------------------------------------
686 {
687  int numReacts=theReactions.size();
688  int i;
689 
690  for (i=0; i<numReacts; ++i)
691  {
692  theReactions[i].setRateConstantFromCalculator(T);
693  theReactions[i].setTemperature(T);
694  }
695 }
696 
697 
698 //-----------------------------------------------------------------------------
699 // Function : ReactionNetwork::setRateConstantsFromCalc
700 // Purpose : set the rate constant for the all reaction according
701 // to their saved methods
702 // Special Notes :
703 // Scope : public
704 // Creator : Lawrence C Musson, SNL, Electrical and Microsystems Modeling
705 // Creation Date : 08/02/06
706 //-----------------------------------------------------------------------------
708  std::vector<double> &concs,
709  std::vector<double> &constant_vec)
710 {
711  int numReacts=theReactions.size();
712  int i;
713  for (i=0; i<numReacts; ++i)
714  {
715  theReactions[i].setRateConstantFromCalculator(T,concs,constant_vec);
716  theReactions[i].setTemperature(T);
717  }
718 }
719 
720 //-----------------------------------------------------------------------------
721 // Function : ReactionNetwork::scaleRateConstantsFromCalc
722 // Purpose : scale the rate constant for the all reaction according
723 // to their saved methods
724 // Special Notes :
725 // Scope : public
726 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
727 // Creation Date : 08/02/06
728 //-----------------------------------------------------------------------------
730 {
731  int numReacts=theReactions.size();
732  int i;
733  for (i=0; i<numReacts; ++i)
734  {
735  theReactions[i].scaleRateConstantFromCalculator();
736  }
737 }
738 
739 //-----------------------------------------------------------------------------
740 // Function : ReactionNetwork::unscaleRateConstantsFromCalc
741 // Purpose : unscale the rate constant for the all reaction according
742 // to their saved methods
743 // Special Notes :
744 // Scope : public
745 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
746 // Creation Date : 08/02/06
747 //-----------------------------------------------------------------------------
749 {
750  int numReacts=theReactions.size();
751  int i;
752  for (i=0; i<numReacts; ++i)
753  {
754  theReactions[i].unscaleRateConstantFromCalculator();
755  }
756 }
757 
758 //-----------------------------------------------------------------------------
759 // Function : ReactionNetwork::setScaleParams
760 // Purpose : set the scale parameters and pass them down to any existing
761 // reactions. Done this way, we make sure that all reactions
762 // in the network are reset to the same set of scale
763 // parameters.
764 // Special Notes : If called before reactions defined, it's OK, because as
765 // each reaction's rate calculator is created, the stored
766 // C0, t0, and x0 are passed to it. This function does the
767 // calls down to existing reactions just in case they were
768 // previously defined.
769 // Scope : public
770 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
771 // Creation Date : 08/24/06
772 //-----------------------------------------------------------------------------
773 void ReactionNetwork::setScaleParams(double c,double t, double x)
774 {
775  std::vector<Xyce::Device::Reaction>::iterator reactionIter=theReactions.begin();
776  std::vector<Xyce::Device::Reaction>::iterator reactionIterEnd=theReactions.end();
777  C0=c;
778  t0=t;
779  x0=x;
780 
781  for (; reactionIter != reactionIterEnd; ++reactionIter)
782  {
783  reactionIter->setScaleFactors(C0,t0,x0);
784  }
785 }
786 
787 
788 //-----------------------------------------------------------------------------
789 // Function : ReactionNetwork::setmaterial
790 // Purpose : Set the bulk semiconductor material
791 // Scope : public
792 // Creator : Lawrence C Musson
793 // Creation Date : 08/19/14
794 //-----------------------------------------------------------------------------
796 {
797  material = mat;
798 
799  std::vector<Reaction>::iterator reactionIter=theReactions.begin();
800  std::vector<Reaction>::iterator reactionIterEnd=theReactions.end();
801  for (; reactionIter != reactionIterEnd; ++reactionIter)
802  reactionIter->setMaterial(material, Temp);
803 
804  //This is a good opportunity to check the species for bourgoin-corbett
805  //enhanced diffusion and then to set some parameters
806  for(int i=0 ; i<species.size() ; ++i)
807  {
808  if(species[i].getBCCarrierCharge() == 1)
809  {
810  species[i].setBCThermalVelocity(material->holeThermalV);
811  }
812  else if(species[i].getBCCarrierCharge() == -1)
813  {
814  species[i].setBCThermalVelocity(material->electronThermalV);
815  }
816  }
817 }
818 
819 
820 //-----------------------------------------------------------------------------
821 // Function : ReactionNetwork::setmaterial
822 // Purpose : Set the bulk semiconductor material
823 // Scope : public
824 // Creator : Lawrence C Musson
825 // Creation Date : 08/19/14
826 //-----------------------------------------------------------------------------
828 {
829  std::vector<Reaction>::iterator reactionIter=theReactions.begin();
830  std::vector<Reaction>::iterator reactionIterEnd=theReactions.end();
831  for (; reactionIter != reactionIterEnd; ++reactionIter)
832  reactionIter->setCoefficient(Temp);
833 }
834 
835 
836 //-----------------------------------------------------------------------------
837 // Function : ReactionNetwork::setmaterial
838 // Purpose : Set the bulk semiconductor material
839 // Scope : public
840 // Creator : Lawrence C Musson
841 // Creation Date : 08/19/14
842 //-----------------------------------------------------------------------------
843  void ReactionNetwork::setRxnVariableCoeffs(bool variableCoeffs)
844 {
845  variableRateCoeffs=variableCoeffs;
846 
847  std::vector<Reaction>::iterator reactionIter=theReactions.begin();
848  std::vector<Reaction>::iterator reactionIterEnd=theReactions.end();
849  for (; reactionIter != reactionIterEnd; ++reactionIter)
850  reactionIter->setRxnVariableCoeffs(variableCoeffs);
851 }
852 
853 //-----------------------------------------------------------------------------
854 // Function : ReactionNetwork::addSourceTerm
855 // Purpose : add an expression for a source term
856 // Special Notes :
857 // Scope : public
858 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
859 // Creation Date : 08/04/06
860 //-----------------------------------------------------------------------------
861 void ReactionNetwork::addSourceTerm(const std::string &speciesName, const std::string &expressionStr)
862 {
863  if (applySources)
864  {
865  int speciesNum=getSpeciesNum(speciesName);
866  if (speciesNum >= 0) // the species exists
867  {
868  Util::Expression *foo= new Util::Expression(expressionStr);
869  theSourceTerms.push_back( std::pair<int,Util::Expression *>(speciesNum, foo));
870  }
871  }
872 }
873 
874 //-----------------------------------------------------------------------------
875 // Function : ReactionNetwork::addSourceTerm
876 // Purpose : add an expression for a source term given
877 // already-constructed expression object.
878 // Special Notes :
879 // Scope : public
880 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
881 // Creation Date : 08/04/06
882 //-----------------------------------------------------------------------------
883 void ReactionNetwork::addSourceTerm(const std::string &speciesName, Util::Expression *expression)
884 {
885  int speciesNum=getSpeciesNum(speciesName);
886  Util::Expression * ExpressionCopy=new Util::Expression(*expression);
887 
888  if (speciesNum >= 0) // the species exists
889  {
890  theSourceTerms.push_back(
891  std::pair<int,Util::Expression *>(speciesNum,ExpressionCopy));
892  }
893 }
894 
895 //-----------------------------------------------------------------------------
896 // Function : ReactionNetwork::addMasterSourceTerm
897 // Purpose : add an expression for a source term that depends on a
898 // "master" source value.
899 // Special Notes :
900 // Scope : public
901 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
902 // Creation Date : 08/04/06
903 //-----------------------------------------------------------------------------
904 void ReactionNetwork::addMasterSourceTerm(const std::string &speciesName)
905 {
906  int speciesNum=getSpeciesNum(speciesName);
907 
908  if (speciesNum >= 0) // the species exists
909  {
910  masterSourceSpecies.push_back(speciesNum);
911  }
912 }
913 
914 //-----------------------------------------------------------------------------
915 // Function : ReactionNetwork::setSimTime
916 // Purpose : set internal "time" variable for all source terms
917 // Special Notes :
918 // Scope : public
919 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
920 // Creation Date : 08/04/06
921 //-----------------------------------------------------------------------------
923 {
924  std::vector< std::pair<int,Util::Expression *> >::iterator iterSource=
925  theSourceTerms.begin();
926  std::vector< std::pair<int,Util::Expression *> >::iterator source_end=
927  theSourceTerms.end();
928 
929  for (;iterSource != source_end; ++iterSource)
930  {
931  (iterSource->second)->set_sim_time(time);
932  }
933 }
934 
935 //-----------------------------------------------------------------------------
936 // Function : ReactionNetwork::getBreakpointTime
937 // Purpose : return the next time at which any source will have a
938 // breakpoint
939 // Special Notes :
940 // Scope : public
941 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
942 // Creation Date : 03/20/06
943 //-----------------------------------------------------------------------------
945 {
946  double breaktime=0, btime;
947  std::vector< std::pair<int,Util::Expression *> >::iterator iterSource=
948  theSourceTerms.begin();
949  std::vector< std::pair<int,Util::Expression *> >::iterator source_end=
950  theSourceTerms.end();
951 
952  for (;iterSource != source_end; ++iterSource)
953  {
954  btime=(iterSource->second)->get_break_time();
955  // pick smallest break time of all sources.
956  if (breaktime>0)
957  {
958  if (btime<breaktime)
959  {
960  breaktime=btime;
961  }
962  }
963  else
964  {
965  breaktime=btime;
966  }
967  }
968 
969  return (breaktime);
970 }
971 
972 //-----------------------------------------------------------------------------
973 // Function : ReactionNetwork::getDdt
974 // Purpose : compute the time derivative of all species concentrations
975 // Special Notes :
976 // Scope : public
977 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
978 // Creation Date : 03/20/06
979 //-----------------------------------------------------------------------------
980 void ReactionNetwork::getDdt(std::vector<double> &concs,std::vector<double> &constant_vec,
981  std::vector<double> &ddt)
982 {
983  int rSize=theReactions.size();
984  int i;
985  for (i=0;i<rSize;++i)
986  {
987  theReactions[i].getDdt(concs,constant_vec,ddt);
988  }
989 
990  // add in the source terms
991  std::vector< std::pair<int,Util::Expression *> >::iterator iterSource=
992  theSourceTerms.begin();
993  std::vector< std::pair<int,Util::Expression *> >::iterator source_end=
994  theSourceTerms.end();
995 
996  for (;iterSource != source_end; ++iterSource)
997  {
998  double return_val;
999  (iterSource->second)->evaluateFunction(return_val); // ignore return val? That's
1000  // what's done everywhere else
1001  ddt[(iterSource->first)] += sourceScaleFac*return_val;
1002  }
1003 
1004  // Add in the master source terms:
1005  std::vector<int>::iterator iterMasterSource=masterSourceSpecies.begin();
1006  std::vector<int>::iterator masterSource_end=masterSourceSpecies.end();
1007  for (; iterMasterSource!= masterSource_end; ++iterMasterSource)
1008  {
1009  ddt[*iterMasterSource] += masterSourceValue*sourceScaleFac;
1010  }
1011 
1012 }
1013 
1014 //-----------------------------------------------------------------------------
1015 // Function : ReactionNetwork::getJac
1016 // Purpose : compute the jacobian of the reaction network, the
1017 // derivatives of the time derivatives with respect to species
1018 // concentration.
1019 // Special Notes :
1020 // Scope : public
1021 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
1022 // Creation Date : 03/20/06
1023 //-----------------------------------------------------------------------------
1024 void ReactionNetwork::getJac(std::vector<double> &concs, std::vector<double> &constant_vec,
1025  std::vector<std::vector<double> >&jac)
1026 {
1027  int rSize=theReactions.size();
1028  int i;
1029 
1030  for (i=0;i<rSize;++i)
1031  {
1032  theReactions[i].getJac(concs,constant_vec,jac);
1033  }
1034 }
1035 
1036 //-----------------------------------------------------------------------------
1037 // Function : ReactionNetwork::getDFdConst
1038 // Purpose : compute the derivatives of the RHS with respect to
1039 // a specified constant concentration.
1040 // Special Notes :
1041 // Scope : public
1042 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
1043 // Creation Date : 10/17/06
1044 //-----------------------------------------------------------------------------
1045 void ReactionNetwork::getDFdConst( const std::string & constantName,
1046  std::vector<double> &concs,
1047  std::vector<double> &constant_vec,
1048  std::vector<double> &dFdConst)
1049 {
1050  int rSize=theReactions.size();
1051  int cSize=concs.size();
1052  int i;
1053  int constNum=getConstantNum(constantName);
1054 
1055  dFdConst.resize(cSize);
1056  for (i=0;i<cSize;++i)
1057  dFdConst[i]=0.0;
1058 
1059  for (i=0;i<rSize;++i)
1060  {
1061  theReactions[i].getDFdConst(constNum,concs,constant_vec,dFdConst);
1062  }
1063 }
1064 
1065 
1066 //-----------------------------------------------------------------------------
1067 // Function : ReactionNetwork::getJac
1068 // Purpose : compute the jacobian of the reaction network, the
1069 // derivatives of the time derivatives with respect to species
1070 // concentration.
1071 // Special Notes :
1072 // Scope : public
1073 // Creator : Lawrence C Musson, SNL, Electrical and Microsystems Modeling
1074 // Creation Date : 09/20/2014
1075 //-----------------------------------------------------------------------------
1076 void ReactionNetwork::getJacobianVC(std::vector<double> &concs, std::vector<double> &constant_vec,
1077  std::vector<std::vector<double> >&jac, std::vector<double> &constVec)
1078 {
1079  int rSize=theReactions.size();
1080  int cSize=concs.size();
1081  int i;
1082 
1083  constVec.resize(2*cSize);
1084  for (i=0 ; i<constVec.size() ; ++i)
1085  constVec[i]=0.0;
1086 
1087  for (i=0;i<rSize;++i)
1088  {
1089  theReactions[i].getJacobianVC(concs,constant_vec,jac,constVec);
1090  }
1091 
1092 }
1093 
1094 //-----------------------------------------------------------------------------
1095 // Function : ReactionNetwork::getRate
1096 // Purpose : Compute the total rate at which species are "consumed" or
1097 // "produced" by all the capture and emission reactions,
1098 // if there are any. This can be used even if the species
1099 // concentration is held fixed (it'll just be the sum of all
1100 // reaction rates involving electrons).
1101 // Special Notes : Assumes that all emission and capture reactions are
1102 // of the form B=>A+E or A+E=>B and will be incorrect if
1103 // the number of any reaction not of this form is listed in
1104 // the capture or emission vectors.
1105 //
1106 // Generic version in which the list of capture and emission
1107 // reactions are passed in
1108 //
1109 // Scope : public
1110 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
1111 // Creation Date : 09/13/06
1112 //-----------------------------------------------------------------------------
1113 double ReactionNetwork::getRate(std::vector<double> &concs,
1114  std::vector<double> &constant_vec,
1115  std::vector<int> &captureVect,
1116  std::vector<int> &emissionVect)
1117 {
1118  int i;
1119  double rate=0;
1120 
1121  for (i=0;i<captureVect.size();++i)
1122  {
1123  rate -= theReactions[captureVect[i]].getRateVC(concs, constant_vec);
1124  }
1125 
1126  for (i=0;i<emissionVect.size();++i)
1127  {
1128  if(theReactions[emissionVect[i]].getCarrierEmissionIndex() < 0)
1129  {
1130  rate += theReactions[emissionVect[i]].getRateVC(concs,constant_vec);
1131  }
1132  else
1133  {
1134  rate += theReactions[emissionVect[i]].getFDEmissionRate(concs,constant_vec);
1135  }
1136  }
1137 
1138 
1139  return rate;
1140 }
1141 
1142 //-----------------------------------------------------------------------------
1143 // Function : ReactionNetwork::getCaptureLifetime
1144 // Purpose : Given a list of capture reaction numbers and the
1145 // species number of the concentration consumed by those
1146 // reactions, return the lifetime.
1147 // Special Notes : Returns -1 if lifetime would be infinite (zero capture rate)
1148 // This is a kludge, but one that is easily tested by anyone
1149 // who uses this.
1150 //
1151 // Scope : public
1152 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
1153 // Creation Date : 09/20/06
1154 //-----------------------------------------------------------------------------
1155 double ReactionNetwork::getCaptureLifetime(std::vector<double> &concs,
1156  std::vector<double> &constant_vec,
1157  std::vector<int> &captureVect,
1158  double & concentration)
1159 {
1160  int i;
1161  double rate=0;
1162 
1163  for (i=0;i<captureVect.size();++i)
1164  {
1165  rate += theReactions[captureVect[i]].getRateVC(concs, constant_vec);
1166  }
1167 
1168  // inverse of lifetime = rate/concentration, so...
1169  if (rate > 0) // don't try to compute infinite lifetime!
1170  return concentration/rate;
1171  else
1172  return (-1.0); // bollocks, but let's not quibble. This is just as
1173  // invalid a lifetime as infinity would be!
1174 
1175 }
1176 
1177 //-----------------------------------------------------------------------------
1178 // Function : ReactionNetwork::getCaptureLifetimes
1179 // Purpose : Given a list of capture reaction numbers and the
1180 // species number of the concentration consumed by those
1181 // reactions, return a vector of lifetimes due to each
1182 // reaction.
1183 // Special Notes : Returns -1 if lifetime would be infinite (zero capture rate)
1184 // This is a kludge, but one that is easily tested by anyone
1185 // who uses this.
1186 //
1187 // Scope : public
1188 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
1189 // Creation Date : 09/20/06
1190 //-----------------------------------------------------------------------------
1191 void ReactionNetwork::getCaptureLifetimes(std::vector<double> &concs,
1192  std::vector<double> &constant_vec,
1193  std::vector<int> &captureVect,
1194  double & concentration,
1195  std::vector<double> &lifetimes)
1196 {
1197  int i;
1198  lifetimes.resize(captureVect.size());
1199 
1200  for (i=0;i<captureVect.size();++i)
1201  {
1202  lifetimes[i] = theReactions[captureVect[i]].getRateVC(concs, constant_vec);
1203  // inverse of lifetime = rate/concentration, so...
1204  if (lifetimes[i] > 0) // don't try to compute infinite lifetime!
1205  lifetimes[i] = concentration/lifetimes[i];
1206  else
1207  lifetimes[i]=-1.0; // bollocks, but let's not quibble. This is just as
1208  // invalid a lifetime as infinity would be!
1209  }
1210 
1211 }
1212 
1213 //-----------------------------------------------------------------------------
1214 // Function : ReactionNetwork::getDRateDC
1215 // Purpose : Compute the vector of derivatives of the Rate (as returned
1216 // by getRate) with respect to concentrations
1217 //
1218 // Special Notes : Assumes that all emission and capture reactions are
1219 // of the form B=>A+E or A+E=>B and will be incorrect if
1220 // the number of any reaction not of this form is listed in
1221 // the capture or emission vectors.
1222 //
1223 // Generic version in which the list of capture and emission
1224 // reactions are passed in
1225 //
1226 // Note that dRatedC is zeroed, so if you need to sum
1227 // terms from multiple species, you need to pass a temporary
1228 // to this routine and sum terms in to a different vector.
1229 //
1230 // Scope : public
1231 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
1232 // Creation Date : 09/13/06
1233 //-----------------------------------------------------------------------------
1234 void ReactionNetwork::getDRateDC(std::vector<double> &concs,
1235  std::vector<double> &constant_vec,
1236  std::vector<int> &captureVect,
1237  std::vector<int> &emissionVect,
1238  std::vector<double> &dRatedC)
1239 {
1240  int i,j;
1241  int cSize=dRatedC.size();
1242  int const_size=constant_vec.size();
1243  std::vector<double> tempdRdC(cSize);
1244  int FADSize = cSize+const_size;
1245 
1246  for (i=0;i<cSize;++i)
1247  {
1248  dRatedC[i]=0;
1249  }
1250 
1251  //The following sets up the FAD types in order to get sensitvities of the capture Rxns
1252  FDFadType tempdRdCFD;
1253  std::vector<FDFadType> defects(cSize);
1254  std::vector<FDFadType> carriers(const_size);
1255  for( i=0 ; i<const_size ; ++i)
1256  {
1257  carriers[i] = constant_vec[i];
1258  //carriers[i].diff(i,FADSize);
1259  }
1260  for( i=0 ; i<cSize ; ++i)
1261  {
1262  defects[i] = concs[i];
1263  defects[i].diff(i+const_size,FADSize);
1264  }
1265 
1266  for (i=0;i<captureVect.size();++i)
1267  {
1268  tempdRdCFD = theReactions[captureVect[i]].getRateVC(defects, carriers);
1269 
1270  for (j=0;j<cSize;++j)
1271  {
1272  dRatedC[j] -= tempdRdCFD.dx(j+const_size);
1273  }
1274  }
1275 
1276  for (i=0;i<emissionVect.size();++i)
1277  {
1278  tempdRdC.assign(cSize,0.0);
1279  if(theReactions[emissionVect[i]].getCarrierEmissionIndex()<0)
1280  {
1281  tempdRdCFD = theReactions[emissionVect[i]].getRateVC(defects, carriers);
1282  for(int j=0 ; j<cSize ; ++j)
1283  {
1284  tempdRdC[j] = tempdRdCFD.dx(j+const_size);
1285  }
1286  //theReactions[emissionVect[i]].getDRateDC(concs, constant_vec, tempdRdC);
1287  }
1288  else
1289  {
1290  tempdRdCFD = theReactions[emissionVect[i]].getFDEmissionRate(defects, carriers);
1291  for(int j=0 ; j<cSize ; ++j)
1292  {
1293  tempdRdC[j] = tempdRdCFD.dx(j+const_size);
1294  }
1295  }
1296 
1297 
1298  for (j=0;j<cSize;++j)
1299  {
1300  dRatedC[j] += tempdRdC[j];
1301  }
1302  }
1303 }
1304 
1305 
1306 //-----------------------------------------------------------------------------
1307 // Function : ReactionNetwork::getDRateDConst
1308 //
1309 // Purpose : Compute the vector of derivatives of the Rate (as returned
1310 // by getRate) with respect to constants, like E and H.
1311 //
1312 // Special Notes : Assumes that all emission and capture reactions are
1313 // of the form B=>A+E or A+E=>B and will be incorrect if
1314 // the number of any reaction not of this form is listed in
1315 // the capture or emission vectors.
1316 //
1317 // Generic version in which the list of capture and emission
1318 // reactions are passed in
1319 //
1320 // Note that dRatedConst is zeroed, so if you need to sum
1321 // terms from multiple species, you need to pass a temporary
1322 // to this routine and sum terms in to a different vector.
1323 //
1324 // Scope : public
1325 // Creator : Eric Keiter
1326 // Creation Date : 11/15/08
1327 //-----------------------------------------------------------------------------
1328 void ReactionNetwork::getDRateDConst(std::vector<double> &concs,
1329  std::vector<double> &constant_vec,
1330  std::vector<int> &captureVect,
1331  std::vector<int> &emissionVect,
1332  std::vector<double> &dRatedConst)
1333 {
1334  int i,j;
1335  int cSize=dRatedConst.size();
1336  int concSize=concs.size();
1337  int constSize=constant_vec.size();
1338  std::vector<double> tempdRdConst(cSize);
1339  int FADSize=concSize+constSize;
1340 
1341  for (i=0;i<cSize;++i)
1342  {
1343  dRatedConst[i]=0;
1344  }
1345 
1346  //The following sets up the FAD types in order to get sensitvities of the FD emission Rxns
1347  FDFadType tempdRdConstFD;
1348  std::vector<FDFadType> defects(concs.size());
1349  std::vector<FDFadType> carriers(2);
1350  for( i=0 ; i<cSize ; ++i)
1351  {
1352  carriers[i] = constant_vec[i];
1353  carriers[i].diff(i,FADSize);
1354  }
1355  for( i=0 ; i<concs.size() ; ++i)
1356  {
1357  defects[i] = concs[i];
1358  //defects[i].diff(i+2,FADSize);
1359  }
1360 
1361  for (i=0;i<captureVect.size();++i)
1362  {
1363  tempdRdConst.assign(cSize,0.0);
1364 
1365  tempdRdConstFD = theReactions[captureVect[i]].getRateVC(defects, carriers);
1366 
1367  for (j=0;j<cSize;++j)
1368  {
1369  dRatedConst[j] -= tempdRdConstFD.dx(j);
1370  }
1371  }
1372 
1373 
1374  for (i=0;i<emissionVect.size();++i)
1375  {
1376  tempdRdConst.assign(cSize,0.0);
1377 
1378  if(theReactions[emissionVect[i]].getCarrierEmissionIndex()<0)
1379  {
1380  tempdRdConstFD = theReactions[emissionVect[i]].getRateVC(defects, carriers);
1381  for(int j=0 ; j<cSize ; ++j)
1382  {
1383  tempdRdConst[j] = tempdRdConstFD.dx(j);
1384  }
1385  }
1386  else
1387  {
1388  tempdRdConstFD = theReactions[emissionVect[i]].getFDEmissionRate(defects, carriers);
1389  for(int j=0 ; j<cSize ; ++j)
1390  {
1391  tempdRdConst[j] = tempdRdConstFD.dx(j);
1392  }
1393  }
1394 
1395  for (j=0;j<cSize;++j)
1396  dRatedConst[j] += tempdRdConst[j];
1397  }
1398 
1399 }
1400 
1401 
1402 
1403 //-----------------------------------------------------------------------------
1404 // Function : ReactionNetwork::setBourgoinCorbettCalc
1405 // Purpose : set the named Bourgoin Corbett parameters in the species objects
1406 // Corbett enhanced diffusion
1407 // Special Notes :
1408 // Scope : public
1409 // Creator : Lawrence C Musson, SNL
1410 // Creation Date : 03/25/14
1411 //-----------------------------------------------------------------------------
1412  void ReactionNetwork::setBourgoinCorbettCalc(const std::string &speciesName,const std::string &carrierName,
1413  double sigma, double hopDistance)
1414  {
1415 
1416 
1417 
1418  //int i=species.size(); // get index of next one we add
1419  //species.push_back(aSpecie);
1420  //speciesMap[aSpecie.getName()]=i;
1421 
1422  int speciesIndex = speciesMap[speciesName];
1423 
1424  int carrierIndex=-1;
1425 
1426  double thermalVelocity=0.0;
1427 
1428 
1429  // for (int i=0 ; i<constantsMap.size() ; ++i)
1430  //if(carrierName == constants
1431  carrierIndex = constantsMap[carrierName];
1432 
1433  int BCCarrierCharge=0;
1434 
1435  if(carrierName == "E")
1436  {
1437  BCCarrierCharge = -1;
1438  }
1439  else if(carrierName == "H")
1440  {
1441  BCCarrierCharge = 1;
1442  }
1443  else
1444  {
1445  Report::DevelFatal() << "ReactionNetwork::setBourgoinCorbettCalc: Illegal carrier for BC enhancement: " << carrierName;
1446  }
1447 
1448  species[speciesIndex].setBCEnhancedDiffusion(carrierIndex,sigma,BCCarrierCharge,hopDistance);
1449 
1450  }
1451 
1452 //-----------------------------------------------------------------------------
1453 // Function : ReactionNetwork::setFDElectronEmissionCalc
1454 // Purpose : set the named reaction's rate calculator to type emission with Fermi-Dirac Stats
1455 // Scope : public
1456 // Creator : Lawrence C Musson
1457 // Creation Date : 06/30/2014
1458 //-----------------------------------------------------------------------------
1459 void ReactionNetwork::setFDElectronEmissionCalc(const std::string &name, double sigma, double E)
1460 {
1461 
1462  int carrierIndex = 0;
1463 
1464  carrierIndex = constantsMap["E"];
1465 
1466  //carrier velocities and DOS are a function of the bulk device material
1467  //The reaction network is set up prior to the device and so material
1468  //properties are unknown when this method is called. Instead of passing
1469  //through a velocity, I'm passing through a carrier charge so that
1470  //when the mulk material is known, this reaction can identify the carrier
1471  //that is being emitted and the velocity can be set appropriately for
1472  //the device material. --LCM
1473  double v = -1.0;
1474  getReaction(name).setFDEmissionRateCalculator(carrierIndex,sigma,E,v,1.0,t0,x0);
1475 }
1476 
1477 //-----------------------------------------------------------------------------
1478 // Function : ReactionNetwork::setFDHoleEmissionCalc
1479 // Purpose : set the named reaction's rate calculator to type emission with Fermi-Dirac Stats
1480 // Scope : public
1481 // Creator : Lawrence C Musson
1482 // Creation Date : 06/30/2014
1483 //-----------------------------------------------------------------------------
1484 void ReactionNetwork::setFDHoleEmissionCalc(const std::string &name, double sigma, double E)
1485 {
1486 
1487  int carrierIndex = 1;
1488 
1489  carrierIndex = constantsMap["H"];
1490 
1491  //carrier velocities and DOS are a function of the bulk device material
1492  //The reaction network is set up prior to the device and so material
1493  //properties are unknown when this method is called. Instead of passing
1494  //through a velocity, I'm passing through a carrier charge so that
1495  //when the mulk material is known, this reaction can identify the carrier
1496  //that is being emitted and the velocity can be set appropriately for
1497  //the device material. --LCM
1498  double v = +1.0;
1499  getReaction(name).setFDEmissionRateCalculator(carrierIndex,sigma,E,v,1.0,t0,x0);
1500 }
1501 
1502 
1503 } // namespace Device
1504 } // namespace Xyce
void setBourgoinCorbettCalc(const std::string &speciesName, const std::string &carrierName, double sigma, double hopDistance)
std::vector< std::pair< int, Util::Expression * > > theSourceTerms
void addConstant(const Specie &aConstant)
void scaleRateConstant(const std::string &name, double kscale)
Sacado::ELRFad::DFad< double > FDFadType
void setScaleParams(double c, double t, double x)
Pure virtual class to augment a linear system.
void getDRateDConst(std::vector< double > &concs, std::vector< double > &constants, std::vector< int > &captureVect, std::vector< int > &emissionVect, std::vector< double > &dratedc)
std::map< std::string, int > reactionNamesMap
double getCaptureLifetime(std::vector< double > &concs, std::vector< double > &constants, std::vector< int > &captureVect, double &concentration)
void unscaleRateConstantFromCalculator()
void getCaptureLifetimes(std::vector< double > &concs, std::vector< double > &constants, std::vector< int > &captureVect, double &concentration, std::vector< double > &lifetimes)
void unscaleRateConstantFromCalculator(const std::string &name)
const std::string & getName() const
Definition: N_DEV_Specie.h:83
void getDdt(std::vector< double > &concs, std::vector< double > &constants, std::vector< double > &ddt)
void scaleRateConstant(double)
void addReactant(const std::string &name, const std::string &reactant, double stoich)
void getJacobianVC(std::vector< double > &concs, std::vector< double > &constants, std::vector< std::vector< double > > &jac, std::vector< double > &constVec)
double getRate(std::vector< double > &concs, std::vector< double > &constants, std::vector< int > &captureVect, std::vector< int > &emissionVect)
void addMasterSourceTerm(const std::string &speciesName)
std::map< std::string, int > speciesMap
void addReactant(int species, double stoich)
void setFDElectronEmissionCalc(const std::string &name, double sigma, double E)
void addProduct(int species, double stoich)
Reaction & getReaction(const std::string &name)
void setRateConstantFromCalculator(double T)
std::vector< Reaction > theReactions
std::vector< int > electronEmissionReactions
void getJac(std::vector< double > &concs, std::vector< double > &constants, std::vector< std::vector< double > > &jac)
void getDFdConst(const std::string &constantName, std::vector< double > &concs, std::vector< double > &constants, std::vector< double > &dFdConst)
void setMaterial(MaterialLayer *material, double Temp)
void addReaction(const std::string &name)
void setConstants(std::vector< Specie > &theConstantsVect)
void setRxnVariableCoeffs(bool variableCoeffs)
void scaleRateConstantFromCalculator(const std::string &name)
void setSpecies(std::vector< Specie > &theSpeciesVect)
void setRateConstant(double)
std::vector< int > electronCaptureReactions
std::vector< std::string > reactionNames
int getSpeciesNum(const std::string &name)
void setFDHoleEmissionCalc(const std::string &name, double sigma, double E)
void setFDEmissionRateCalculator(int carrierIndex, double sigma, double Energy, double v, double C0, double t0, double x0)
void setRateConstantFromCalculator(const std::string &name, double T)
void addSpecie(const Specie &aSpecie)
int getConstantNum(const std::string &name)
std::map< std::string, int > constantsMap
void setRateConstant(const std::string &name, double k)
ReactionNetwork(const std::string &name="NoName")
void addProduct(const std::string &name, const std::string &reactant, double stoich)
int getReactionNum(const std::string name)
void setReactionNetworkFromFile(const NetlistLocation &netlist_location, const std::string &fileName)
void getDRateDC(std::vector< double > &concs, std::vector< double > &constants, std::vector< int > &captureVect, std::vector< int > &emissionVect, std::vector< double > &dratedc)
void addSourceTerm(const std::string &speciesName, const std::string &expressionStr)