Xyce  6.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
N_DEV_Reaction.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_Reaction.C,v $
27 //
28 // Purpose : Provide a generic class for reactions using simple
29 // law-of-mass-action kinetics, i.e.:
30 // A+2B+C -> D + 3E + F
31 // implies that the reaction happens at a rate:
32 // reactionRate = k*[A][B]^2[C]
33 // where [X] means "concentration of species X"
34 //
35 //
36 // Special Notes :
37 //
38 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
39 //
40 // Creation Date : 03/20/06
41 //
42 // Revision Information:
43 // ---------------------
44 //
45 // Revision Number: $Revision: 1.11 $
46 //
47 // Revision Date : $Date: 2014/05/01 22:27:13 $
48 //
49 // Current Owner : $Author: lcmusso $
50 //-----------------------------------------------------------------------------
51 
52 #include <Xyce_config.h>
53 
54 // Standard includes
55 #include <N_UTL_Misc.h>
56 #include <N_UTL_fwd.h>
57 
58 #include <vector>
59 #include <cmath>
60 
61 #ifdef Xyce_DEBUG_DEVICE
62 #include <iostream>
63 
64 #endif
65 
66 // Xyce includes
67 #include <N_DEV_Reaction.h>
68 #include <N_ERH_ErrorMgr.h>
69 
70 #include <iostream>
71 
72 
73 namespace Xyce {
74 namespace Device {
75 
76 //-----------------------------------------------------------------------------
77 // Function : Reaction::Reaction
78 // Purpose : Default constructor
79 // Special Notes :
80 // Scope : public
81 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
82 // Creation Date : 3/20/06
83 //-----------------------------------------------------------------------------
85  : numconcs(0),
86  numconsts(0),
87  theRateConstant(0.0),
88  myRateCalc(0)
89 {
90  theReactants.resize(0);
91  theProducts.resize(0);
92  concDependency.resize(0);
93  constDependency.resize(0);
94 }
95 
96 //-----------------------------------------------------------------------------
97 // Function : Reaction::Reaction
98 // Purpose : constructor
99 // Special Notes : Used when vector of reactants, products, and rate constant
100 // are available at time of construction
101 // Scope : public
102 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
103 // Creation Date : 3/20/06
104 //-----------------------------------------------------------------------------
105 Reaction::Reaction(std::vector< std::pair<int,double> > & reactants,
106  std::vector< std::pair<int,double> > & products,
107  double rateConstant)
108  :
109  theReactants(reactants),
110  theProducts(products),
111  theRateConstant(rateConstant),
112  numconcs(0),
113  numconsts(0),
114  myRateCalc(0)
115 {
116  concDependency.resize(0);
117  constDependency.resize(0);
118 }
119 
120 //-----------------------------------------------------------------------------
121 // Function : Reaction::Reaction
122 // Purpose : copy constructor
123 // Special Notes : Needed because we keep STL vectors of these objects, and
124 // we keep a pointer to the rate constant calculator. Kills
125 // us during all the push_backs without this copy constructor,
126 // as soon as the push starts moving existing objects around.
127 // Scope : public
128 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
129 // Creation Date : 3/20/06
130 //-----------------------------------------------------------------------------
132  :theReactants(right.theReactants),
133  theProducts(right.theProducts),
134  concDependency(right.concDependency),
135  constDependency(right.constDependency),
136  theRateConstant(right.theRateConstant),
137  numconcs(right.numconcs),
138  numconsts(right.numconsts)
139 {
140 
141  if (right.myRateCalc) // Never, ever copy the pointer to the rate calculator!
142  {
143  myRateCalc = right.myRateCalc->Clone();
144  }
145  else
146  {
147  myRateCalc=0;
148  }
149 }
150 
151 
152 //-----------------------------------------------------------------------------
153 // Function : Reaction::operator=
154 // Purpose : assignment operator
155 // Special Notes : Needed because we keep STL vectors of these objects, and
156 // we keep a pointer to the rate constant calculator. Kills
157 // us during all the push_backs without this copy constructor,
158 // as soon as the push starts moving existing objects around.
159 // Scope : public
160 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
161 // Creation Date : 3/20/06
162 //-----------------------------------------------------------------------------
163 Reaction &
165 {
166 
167  if (this == &right) return *this; // assignment to self
168 
169 #ifdef Xyce_DEBUG_DEVICE
170  Xyce::dout() << "We're doing an assignment of reaction! " << std::endl;
171 #endif
172 
173  // otherwise:
174  theReactants = right.theReactants;
175  theProducts = right.theProducts;
179  numconcs = right.numconcs;
180  numconsts = right.numconsts;
181 
182  if (right.myRateCalc) // Never, ever copy the pointer to the rate calculator!
183  {
184 
185  if (myRateCalc) delete myRateCalc; // we already have one, kill it
186 
187  myRateCalc=right.myRateCalc->Clone();
188  }
189  else
190  {
191  myRateCalc=0;
192  }
193 
194  return *this;
195 
196 }
197 
198 //-----------------------------------------------------------------------------
199 // Function : Reaction::Reaction
200 // Purpose : constructor
201 // Special Notes : Used when vector of reactants, products, and rate constant
202 // are available at time of construction
203 // Scope : public
204 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
205 // Creation Date : 3/20/06
206 //-----------------------------------------------------------------------------
208 {
209  if (myRateCalc)
210  {
211  delete myRateCalc;
212  myRateCalc=0;
213  }
214 }
215 
216 //-----------------------------------------------------------------------------
217 // Function : Reaction::setReactants
218 // Purpose : copy reactant/stoichiometric coefficients into object
219 // Special Notes :
220 // Scope : public
221 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
222 // Creation Date : 3/20/06
223 //-----------------------------------------------------------------------------
224 void Reaction::setReactants(std::vector< std::pair<int,double> > & reactants)
225 {
226  theReactants=reactants;
227 }
228 
229 //-----------------------------------------------------------------------------
230 // Function : Reaction::addReactant
231 // Purpose : add reactant/stoichiometric coefficients to reactants vector
232 // Special Notes :
233 // Scope : public
234 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
235 // Creation Date : 3/20/06
236 //-----------------------------------------------------------------------------
237 void Reaction::addReactant(int species,double stoich)
238 {
239  std::vector<std::pair<int,double> >::iterator iter;
240  std::vector<std::pair<int,double> >::iterator iter_end=theReactants.end();
241  bool foundSpecies=false;
242 
243  // Make sure we only have each that appears on the LHS of a reaction
244  // listed only once. If the user has specified one twice, combine them
245  // into a single term with an augmented stoichiometric coefficient.
246  for (iter=theReactants.begin(); iter != iter_end; iter++)
247  {
248  if (iter->first == species)
249  {
250  iter->second += stoich;
251  foundSpecies=true;
252  break;
253  }
254  }
255  // Only if we didn't find the species in our existing list should we
256  // add a new entry to the vector.
257  if (!foundSpecies)
258  theReactants.push_back(std::pair<int,double>(species,stoich));
259 }
260 
261 
262 //-----------------------------------------------------------------------------
263 // Function : Reaction::addProduct
264 // Purpose : add reactant/stoichiometric coefficients to vector
265 // Special Notes :
266 // Scope : public
267 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
268 // Creation Date : 3/20/06
269 //-----------------------------------------------------------------------------
270 void Reaction::addProduct(int species,double stoich)
271 {
272  std::vector<std::pair<int,double> >::iterator iter;
273  std::vector<std::pair<int,double> >::iterator iter_end=theProducts.end();
274  bool foundSpecies=false;
275 
276  // Make sure we only have each that appears on the RHS of a reaction
277  // listed only once. If the user has specified one twice, combine them
278  // into a single term with an augmented stoichiometric coefficient.
279  for (iter=theProducts.begin(); iter != iter_end; iter++)
280  {
281  if (iter->first == species)
282  {
283  iter->second += stoich;
284  foundSpecies=true;
285  break;
286  }
287  }
288  // Only if we didn't find the species in our existing list should we
289  // add a new entry to the vector.
290  if (!foundSpecies)
291  theProducts.push_back(std::pair<int,double>(species,stoich));
292 }
293 
294 //-----------------------------------------------------------------------------
295 // Function : Reaction::setProducts
296 // Purpose : copy product/stoichiometric coefficients into object
297 // Special Notes :
298 // Scope : public
299 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
300 // Creation Date : 3/20/06
301 //-----------------------------------------------------------------------------
302 void Reaction::setProducts(std::vector< std::pair<int,double> > & products)
303 {
304  theProducts=products;
305 }
306 
307 //-----------------------------------------------------------------------------
308 // Function : Reaction::getRate
309 // Purpose : compute and return the reaction rate. This is normally the
310 // first step of getDdt, but we might need this for
311 // other purposes (e.g. a kludge for getting electron/hole
312 // recombination/regeneration rates even when electrons and
313 // holes are constant species)
314 // Special Notes : It is tacitly assumed that the concentrations and
315 // constants in the provided vector are in an order
316 // consistent with the labeling in the reactants and
317 // products vectors. The contributions to the species
318 // time derivatives are summed into the provided output
319 // vector because it is assumed that there will be a network
320 // of reactions, not just one.
321 // Scope : public
322 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
323 // Creation Date : 3/20/06
324 //-----------------------------------------------------------------------------
325 double Reaction::getRate(std::vector<double> &concentrations,
326  std::vector<double> &constants)
327 {
328  int rSize=theReactants.size();
329  int pSize=theProducts.size();
330  double reactionRate;
331  int i;
332  int species;
333  double stoich;
334  double c;
335 
336  // Reaction rate determined by law of mass action
337  reactionRate=theRateConstant;
338  // product of concentrations of reactants raised to the power of
339  // stoichiometric coefficient
340 
341  //if(rSize == 3)
342  //std::cout<<" rate constant = "<<theRateConstant<<std::endl;
343 
344 
345  double c0 = 1e16;
346  double t0 = 7.1428571428571427e-11;
347 
348  double conc=0.0,hconc;
349 
350  for (i=0;i<rSize;++i)
351  {
352  species=theReactants[i].first;
353  stoich=theReactants[i].second;
354 
355  if (species>=0)
356  {
357  c=concentrations[species];
358  }
359  else
360  {
361  c=constants[-(species+1)];
362  hconc = c;
363  }
364 
365  if (stoich != 1.0)
366  {
367  reactionRate *= pow(c,stoich);
368  }
369  else
370  {
371  reactionRate *= c;
372  }
373  }
374 
375 
376  return reactionRate;
377 }
378 
379 //-----------------------------------------------------------------------------
380 // Function : Reaction::getDRateDC
381 // Purpose : return a vector of the derivatives of this reaction's
382 // rate with respect to each species
383 // Special Notes :
384 //
385 // Scope : public
386 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
387 // Creation Date : 9/13/06
388 //-----------------------------------------------------------------------------
389 void Reaction::getDRateDC(std::vector<double> &concentrations,
390  std::vector<double> &constants,
391  std::vector<double> &dratedc)
392 {
393  int cSize=concentrations.size();
394  int rSize=theReactants.size();
395  int species;
396  double stoich,c;
397  int i,j;
398 
399  if (numconcs != cSize)
400  {
401  setDependency(cSize);
402  }
403 
404  // dratedc is the vector of derivatives of the reaction rate w.r.t.
405  // concentrations. Since the reaction rate is just a product of factors
406  // involving individual concentrations, we will just be multiplying in
407  // terms, so we initialize only those that are necessary to theRateConstant.
408  // Only those elements of dratedc that represent concentrations that the
409  // rate depends on will be initialized to non-zero.
410  for (i=0;i<cSize;++i)
411  {
412  if (concDependency[i]==1) // the rxn rate depends on this species
413  {
414  dratedc[i]=theRateConstant;
415  }
416  }
417 
418 
419  // The reaction rate is K*(product as i=0,rSize){[Xi]^{stoich[i]}}
420  // compute dR/dXj
421  for (i=0;i<rSize;++i) // loop over all species on left side of reaction
422  {
423  species=theReactants[i].first;
424  stoich=theReactants[i].second;
425  if (species>=0)
426  {
427  c=concentrations[species];
428  }
429  else
430  {
431  c=constants[-(species+1)];
432  }
433 
434 
435  // for each species in the network, if we depend on that species,
436  // update the product in the dR/dXj
437  if (stoich != 1.0)
438  {
439  for (j=0;j<cSize;++j)
440  {
441  if (concDependency[j] != 0)
442  {
443  if (j==species)
444  {
445  dratedc[j] *= stoich*pow(c,stoich-1.0);
446  }
447  else
448  {
449  dratedc[j] *= pow(c,stoich);
450  }
451  }
452  }
453  }
454  else
455  {
456  for (j=0;j<cSize;++j)
457  {
458  // when j==species we'd just multiply by 1.0
459  if (j!=species && concDependency[j] != 0)
460  {
461  dratedc[j] *= c;
462  }
463  }
464  }
465  }
466 }
467 
468 //-----------------------------------------------------------------------------
469 // Function : Reaction::getDRateDConst
470 // Purpose : return a vector of the derivatives of this reaction's
471 // rate with respect to each constant species
472 //
473 // Special Notes : Very much similar to getDRateDC, but computes
474 // derivative w.r.t. constants. Like getDRateDC, this
475 // will ultimately be used to compute jacobian elements,
476 // but unlike that routine, it will be used to pick out
477 // specific constants for special treatment, and unlike
478 // getDRateDC, it only computes the derivative with respect
479 // to a single constant, not all constants..
480 //
481 // Scope : public
482 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
483 // Creation Date : 10/17/06
484 //-----------------------------------------------------------------------------
485 void Reaction::getDRateDConst(int constNum,
486  std::vector<double> &concentrations,
487  std::vector<double> &constants,
488  double &dratedc)
489 {
490  int cSize=constants.size();
491  int rSize=theReactants.size();
492  int species;
493  double stoich,c;
494  int i,j;
495 
496  if (numconsts != cSize)
497  {
498  setConstDependency(cSize);
499  }
500 
501  if (constDependency[constNum]==0) // the rxn rate does not depend on this
502  //species
503  {
504  dratedc=0.0;
505  }
506  else
507  {
508  dratedc=theRateConstant;
509 
510  // The reaction rate is K*(product as i=0,rSize){[Xi]^{stoich[i]}}
511  // compute dR/dXj
512  for (i=0;i<rSize;++i) // loop over all species on left side of reaction
513  {
514  species=theReactants[i].first;
515  stoich=theReactants[i].second;
516  if (species>=0)
517  {
518  c=concentrations[species];
519  }
520  else
521  {
522  c=constants[-(species+1)];
523  }
524 
525 
526  // for each species in the network, if we depend on that species,
527  // update the product in the dR/dXj
528  if (stoich != 1.0)
529  {
530  if (species < 0 && constNum ==-(species+1)) // this specie is the one
531  // we're differntiating wrt
532  {
533  dratedc *= stoich*pow(c,stoich-1.0);
534  }
535  else
536  {
537  dratedc *= pow(c,stoich);
538  }
539  }
540  else
541  {
542  // when constNum is the specie under consideration we'd multiply by 1.0
543  if (constNum !=-(species+1))
544  {
545  dratedc *= c;
546  }
547  }
548  }
549  }
550 }
551 
552 //-----------------------------------------------------------------------------
553 // Function : Reaction::getDdt
554 // Purpose : sum time derivatives of species into provided vector
555 // Special Notes : It is tacitly assumed that the concentrations and
556 // constants in the provided vector are in an order
557 // consistent with the labeling in the reactants and
558 // products vectors. The contributions to the species
559 // time derivatives are summed into the provided output
560 // vector because it is assumed that there will be a network
561 // of reactions, not just one.
562 // Scope : public
563 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
564 // Creation Date : 3/20/06
565 //-----------------------------------------------------------------------------
566 void Reaction::getDdt(std::vector<double> &concentrations,
567  std::vector<double> &constants,
568  std::vector<double> &ddt)
569 {
570  int rSize=theReactants.size();
571  int pSize=theProducts.size();
572  double reactionRate;
573  int i;
574  int species;
575  double stoich;
576 
577  // Reaction rate determined by law of mass action
578  reactionRate=getRate(concentrations,constants);
579 
580  // Now update time derivatives:
581 
582  for (i=0;i<rSize;++i)
583  {
584  species=theReactants[i].first;
585  stoich=theReactants[i].second;
586  if (species>=0)
587  {
588  ddt[species] -= stoich*reactionRate;
589  }
590  }
591 
592  for (i=0;i<pSize;++i)
593  {
594  species=theProducts[i].first;
595  stoich=theProducts[i].second;
596  if (species>=0)
597  {
598  ddt[species] += stoich*reactionRate;
599  }
600  }
601 }
602 
603 //-----------------------------------------------------------------------------
604 // Function : Reaction::getJac
605 // Purpose : sum derivatives of time derivatives of species with
606 // respect to concentration into provided matrix
607 // Special Notes : It is tacitly assumed that the concentrations and
608 // constants in the provided vector are in an order
609 // consistent with the labeling in the reactants and
610 // products vectors. The contributions to the species
611 // second derivatives are summed into the provided output
612 // vector because it is assumed that there will be a network
613 // of reactions, not just one.
614 //
615 // An implicit assumption here is that the species numbering
616 // does not change through the run --- that is, once we
617 // call this routine with a vector of concentrations, it
618 // is assumed from that point forward that element i of the
619 // vector always refers to the same species in subsequent
620 // calls. If it is necessary to change that over time, the
621 // reaction network will probably have to be reconstructed
622 // and re-initialized.
623 //
624 // Scope : public
625 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
626 // Creation Date : 3/20/06
627 //-----------------------------------------------------------------------------
628 void Reaction::getJac(std::vector<double> &concentrations,
629  std::vector<double> &constants,
630  std::vector<std::vector<double> > &jac)
631 {
632  int cSize=concentrations.size();
633  int rSize=theReactants.size();
634  int pSize=theProducts.size();
635  int species;
636  double stoich,c;
637  std::vector<double> dratedc(cSize,0.0);
638  int i,j;
639 
640  // here is where the assumption of static species numbering is coded.
641  // Should it be necessary to change that assumption, here's where the work
642  // would be needed.
643  getDRateDC(concentrations, constants, dratedc);
644 
645  // we now know how the reaction rate depends on the various concentrations.
646  // Now we can assemble the jacobian, which is d^2[Xi]/(dt d[Xj])
647 
648  // species on the left of the reaction
649  for (i=0;i<rSize;++i)
650  {
651  species=theReactants[i].first;
652  stoich=theReactants[i].second;
653  if (species>=0)
654  {
655  for (j=0;j<cSize;++j)
656  {
657  if (concDependency[j]!=0)
658  {
659  jac[species][j] -= stoich*dratedc[j];
660  }
661  }
662  }
663  }
664  // species on the right
665  for (i=0;i<pSize;++i)
666  {
667  species=theProducts[i].first;
668  stoich=theProducts[i].second;
669  if (species>=0)
670  {
671  for (j=0;j<cSize;++j)
672  {
673  if (concDependency[j]!=0)
674  {
675  jac[species][j] += stoich*dratedc[j];
676  }
677  }
678  }
679  }
680 
681 }
682 
683 //-----------------------------------------------------------------------------
684 // Function : Reaction::getDFdConst
685 // Purpose : sum derivatives of time derivatives of species with
686 // respect to concentration into provided vector
687 // Special Notes : It is tacitly assumed that the concentrations and
688 // constants in the provided vector are in an order
689 // consistent with the labeling in the reactants and
690 // products vectors. The contributions to the species
691 // second derivatives are summed into the provided output
692 // vector because it is assumed that there will be a network
693 // of reactions, not just one.
694 //
695 // An implicit assumption here is that the species numbering
696 // does not change through the run --- that is, once we
697 // call this routine with a vector of concentrations, it
698 // is assumed from that point forward that element i of the
699 // vector always refers to the same species in subsequent
700 // calls. If it is necessary to change that over time, the
701 // reaction network will probably have to be reconstructed
702 // and re-initialized.
703 //
704 // This method sums into a vector containing the derivatives
705 // of variable species with respect to the specified constant
706 // specie. It'll be used as a fragment of a larger jacobian.
707 //
708 // Scope : public
709 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
710 // Creation Date : 3/20/06
711 //-----------------------------------------------------------------------------
712 void Reaction::getDFdConst(int constantNumber,
713  std::vector<double> &concentrations,
714  std::vector<double> &constants,
715  std::vector<double> &dFdConst)
716 {
717  int constSize=constants.size();
718  int rSize=theReactants.size();
719  int pSize=theProducts.size();
720  int species;
721  double stoich,c;
722  double dratedc;
723  int i;
724 
725  // here is where the assumption of static species numbering is coded.
726  // Should it be necessary to change that assumption, here's where the work
727  // would be needed.
728  getDRateDConst(constantNumber,concentrations, constants, dratedc);
729 
730  // no point going through these loops if this reaction doesn't depend
731  // on this constant!
732  if (constDependency[constantNumber] != 0)
733  {
734  // we now know how the reaction rate depends on the various constants
735  // we can assemble the derivatives we need.
736 
737  // species on the left of the reaction
738  for (i=0;i<rSize;++i)
739  {
740  species=theReactants[i].first;
741  stoich=theReactants[i].second;
742  if (species>=0)
743  {
744  dFdConst[species] -= stoich*dratedc;
745  }
746  }
747  // species on the right
748  for (i=0;i<pSize;++i)
749  {
750  species=theProducts[i].first;
751  stoich=theProducts[i].second;
752  if (species>=0)
753  {
754  dFdConst[species] += stoich*dratedc;
755  }
756  }
757  }
758 }
759 
760 
761 //-----------------------------------------------------------------------------
762 // Function : Reaction::setSimpleRateCalculator
763 // Purpose : set the rate calculator for this reaction to a simple one
764 // Special Notes :
765 // Scope : public
766 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
767 // Creation Date : 8/01/06
768 //-----------------------------------------------------------------------------
769 void Reaction::setSimpleRateCalculator(double k_in, double C0, double t0,
770  double x0)
771 {
772  if (myRateCalc) // we already have a calculator set
773  {
774  delete myRateCalc; // kill it
775  myRateCalc=0;
776  }
777 
778  myRateCalc = dynamic_cast<RateCalculator *> (new SimpleRateCalculator(k_in, C0, t0, x0));
779 }
780 
781 //-----------------------------------------------------------------------------
782 // Function : Reaction::setCaptureRateCalculator
783 // Purpose : set the rate calculator for this reaction to the
784 // capture rate type (A0+E->AM, for example)
785 // Special Notes :
786 // Scope : public
787 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
788 // Creation Date : 8/01/06
789 //-----------------------------------------------------------------------------
790 void Reaction::setCaptureRateCalculator(double sigma, double v,
791  double C0, double t0, double x0)
792 {
793  if (myRateCalc) // we already have a calculator set
794  {
795  delete myRateCalc; // kill it
796  myRateCalc=0;
797  }
798 
799  myRateCalc = dynamic_cast<RateCalculator *> (
800  new CaptureRateCalculator(sigma, v, C0, t0, x0));
801 }
802 
803 //-----------------------------------------------------------------------------
804 // Function : Reaction::setEmissionRateCalculator
805 // Purpose : set the rate calculator for this reaction to the
806 // emission rate type (AM->A0+E, for example)
807 // Special Notes :
808 // Scope : public
809 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
810 // Creation Date : 8/01/06
811 //-----------------------------------------------------------------------------
812 void Reaction::setEmissionRateCalculator(double sigma, double v,
813  double N, double Energy,
814  double C0, double t0, double x0)
815 {
816  if (myRateCalc) // we already have a calculator set
817  {
818  delete myRateCalc; // kill it
819  myRateCalc=0;
820  }
821 
822  myRateCalc = dynamic_cast<RateCalculator *> (
823  new EmissionRateCalculator(sigma, v, N, Energy, C0, t0, x0));
824 }
825 
826 //-----------------------------------------------------------------------------
827 // Function : Reaction::setComplexRateCalculator
828 // Purpose : set the rate calculator for this reaction to the
829 // complex rate type (A+B->AB, for example)
830 // Special Notes :
831 // Scope : public
832 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
833 // Creation Date : 8/01/06
834 //-----------------------------------------------------------------------------
835 void Reaction::setComplexRateCalculator(std::vector<Specie> &V,
836  std::vector<Specie> &C,
837  double C0, double t0, double x0)
838 {
839  if (myRateCalc) // we already have a calculator set
840  {
841  delete myRateCalc; // kill it
842  myRateCalc=0;
843  }
844 
845  myRateCalc = dynamic_cast<RateCalculator *> (
846  new ComplexRateCalculator(V,C,theReactants,C0, t0, x0));
847 }
848 
849 //-----------------------------------------------------------------------------
850 // Function : Reaction::setDecomplexRateCalculator
851 // Purpose : set the rate calculator for this reaction to the
852 // decomplex rate type (AB->A+B, for example)
853 // Special Notes :
854 // Scope : public
855 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
856 // Creation Date : 8/01/06
857 //-----------------------------------------------------------------------------
858 void Reaction::setDecomplexRateCalculator(std::vector<Specie> &V,
859  std::vector<Specie> &C,
860  double bindingEnergy,
861  double gammaAB, double gammaA,
862  double gammaB, double concSi,
863  double C0, double t0, double x0)
864 {
865  if (myRateCalc) // we already have a calculator set
866  {
867  delete myRateCalc; // kill it
868  myRateCalc=0;
869  }
870 
871  myRateCalc = dynamic_cast<RateCalculator *> (
873  bindingEnergy, gammaAB,gammaA,
874  gammaB, concSi,
875  C0, t0, x0));
876 }
877 
878 
879 //-----------------------------------------------------------------------------
880 // Function : Reaction::setDecomplexRateCalculator
881 // Purpose : set the rate calculator for this reaction to the
882 // decomplex rate type (AB->A+B, for example)
883 // Special Notes :
884 // Scope : public
885 // Creator : Lawrence C Musson
886 // Creation Date : 03/24/2014
887 //-----------------------------------------------------------------------------
889  std::vector<Specie> &C, double sigma,
890  double C0, double t0, double x0)
891 {
892  if (myRateCalc) // we already have a calculator set
893  {
894  delete myRateCalc; // kill it
895  myRateCalc=0;
896  }
897 
898  myRateCalc = dynamic_cast<RateCalculator *> (
900  C0, t0, x0));
901 }
902 
903 //-----------------------------------------------------------------------------
904 // Function : Reaction::setRateConstantFromCalculator
905 // Purpose : set the rate constant from the temperature using our rate
906 // calculator
907 // Special Notes :
908 // Scope : public
909 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
910 // Creation Date : 8/01/06
911 //-----------------------------------------------------------------------------
913 {
914  if (myRateCalc) // if we *have* a rate calculator
915  {
917  }
918  // otherwise just leave it where it is (which might be 0)
919 }
920 
921 
922 //-----------------------------------------------------------------------------
923 // Function : Reaction::setRateConstantFromCalculator
924 // Purpose : set the rate constant from the temperature using our rate
925 // calculator
926 // Special Notes :
927 // Scope : public
928 // Creator : Lawrence C Musson, SNL
929 // Creation Date : 04/17/2014
930 //-----------------------------------------------------------------------------
932  std::vector<double> &concs,
933  std::vector<double> &constant_vec)
934 {
935  if (myRateCalc) // if we *have* a rate calculator
936  {
937  setRateConstant(myRateCalc->computeRateConstant(T,concs,constant_vec));
938  }
939  // otherwise just leave it where it is (which might be 0)
940 }
941 
942 //-----------------------------------------------------------------------------
943 // Function : Reaction::scaleRateConstantFromCalculator()
944 // Purpose : scale the rate constant using values stored in our rate
945 // calculator
946 // Special Notes :
947 // Scope : public
948 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
949 // Creation Date : 8/01/06
950 //-----------------------------------------------------------------------------
952 {
953  if (myRateCalc) // if we *have* a rate calculator
954  {
956  }
957  // otherwise just leave it where it is
958 }
959 
960 //-----------------------------------------------------------------------------
961 // Function : Reaction::unscaleRateConstantFromCalculator()
962 // Purpose : unscale the rate constant using values stored in our rate
963 // calculator
964 // Special Notes :
965 // Scope : public
966 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
967 // Creation Date : 8/01/06
968 //-----------------------------------------------------------------------------
970 {
971  if (myRateCalc) // if we *have* a rate calculator
972  {
974  }
975  // otherwise just leave it where it is
976 }
977 
978 
979 //-----------------------------------------------------------------------------
980 // Function : Reaction::setDependency
981 // Purpose : Set the vector that denotes which of the cSize species
982 // that the network tracks are actually used in this one
983 // reaction as reactants, that is, the species that are
984 // used in computing the reaction rate.
985 // Special Notes :
986 // Scope : private
987 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
988 // Creation Date : 3/20/06
989 //-----------------------------------------------------------------------------
990 void Reaction::setDependency(int cSize)
991 {
992  int rSize=theReactants.size();
993  int i;
994  numconcs=cSize;
995  concDependency.resize(numconcs,0);
996 
997  for (i=0;i<rSize;++i)
998  {
999  if (theReactants[i].first >= 0)
1000  {
1001  concDependency[theReactants[i].first]=1;
1002  }
1003  }
1004 
1005 }
1006 
1007 //-----------------------------------------------------------------------------
1008 // Function : Reaction::setConstDependency
1009 // Purpose : Set the vector that denotes which of the cSize constant
1010 // species that the network contains are actually used in this
1011 // one reaction as reactants, that is, the species that are
1012 // used in computing the reaction rate.
1013 // Special Notes :
1014 // Scope : private
1015 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
1016 // Creation Date : 10/17/06
1017 //-----------------------------------------------------------------------------
1019 {
1020  int rSize=theReactants.size();
1021  int i;
1022  numconsts=cSize;
1023  constDependency.resize(numconsts,0);
1024 
1025  for (i=0;i<rSize;++i)
1026  {
1027  if (theReactants[i].first < 0)
1028  {
1029  constDependency[-(theReactants[i].first+1)]=1;
1030  }
1031  }
1032 }
1033 
1034 //-----------------------------------------------------------------------------
1035 // Function : Reaction::output
1036 // Purpose : Accessor function to set rate constant
1037 // Special Notes :
1038 // Scope : public
1039 // Creator : Eric Keiter, SNL, Electrical and Microsystems Modeling
1040 // Creation Date : 5/27/06
1041 //-----------------------------------------------------------------------------
1042 void Reaction::output
1043  ( const std::vector<Specie> & species, std::ostream & os ) const
1044 {
1045  int i=0;
1046  int isize = theReactants.size();
1047  os << " Rxn: ";
1048  bool firstPrintDone=false;
1049  for (i=0;i<isize;++i)
1050  {
1051  int speciesIndex = theReactants[i].first;
1052  if (speciesIndex >= 0)
1053  {
1054  if (firstPrintDone) os << " + ";
1055  double tmp = theReactants[i].second;
1056  if (tmp > 1.0)
1057  os << " "<<tmp<< " * ";
1058  os.setf(std::ios::right); os.width(3);
1059  os << species[speciesIndex].getName();
1060 
1061  firstPrintDone = true;
1062  }
1063  }
1064 
1065  os << " = ";
1066  isize = theProducts.size();
1067  firstPrintDone=false;
1068  for (i=0;i<isize;++i)
1069  {
1070  int speciesIndex = theProducts[i].first;
1071  if (speciesIndex >= 0)
1072  {
1073  if (firstPrintDone) os << " + ";
1074  double tmp = theProducts[i].second;
1075  if (tmp > 1.0)
1076  os << " " << tmp << " * ";
1077  os.setf(std::ios::right); os.width(3);
1078 
1079  os << species[speciesIndex].getName();
1080  firstPrintDone = true;
1081  }
1082  }
1083 
1084  os << " Rate Constant: ";
1085  os.precision(8); os.setf(std::ios::scientific);
1086  os << theRateConstant;
1087 
1088 #if 0
1089  os << "\n Dependencies:\n";
1090  for (int j=0;j<concDependency.size();++j)
1091  {
1092  os << " " << species[j].getName() << " = " << concDependency[j] << std::endl;
1093  }
1094 #endif
1095  os << std::endl;
1096 
1097 }
1098 
1099 } // namespace Device
1100 } // namespace Xyce