46 #include <Xyce_config.h>
55 #include <N_UTL_fwd.h>
56 #include <N_ERH_ErrorMgr.h>
57 #include <N_UTL_Expression.h>
58 #include <N_UTL_FeatureTest.h>
63 #ifdef Xyce_REACTION_PARSER
71 #include "N_DEV_ReactionParser.hxx"
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)
89 #include <FlexLexer.h>
93 #define yylex N_DEV_lex
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),
146 applySources(right.applySources),
147 material(right.material)
155 for (i=0;i<sourceSize;++i)
157 Util::Expression *newSource;
159 newSource =
new Util::Expression(*((right.
theSourceTerms[i]).second));
189 std::pair<int,Util::Expression *> tempPair =
theSourceTerms.back();
191 delete tempPair.second;
210 #ifdef Xyce_REACTION_PARSER
214 std::map<std::string,int> theSpeciesIDs;
217 std::ifstream reactionFile(fileName.c_str(),std::ios::in);
218 if (reactionFile.is_open())
220 ReactionLexer theLexer(netlist_location, fileName, &reactionFile);
221 XyceDevice::ReactionParser theParser(&theLexer, theSpeciesIDs, *
this);
223 if (theParser.parse() != 0)
227 Xyce::dout() << *
this << std::endl;
233 Report::UserError() <<
"Cannot open reaction specification file " << fileName;
256 int nspec=theSpeciesVect.size();
261 for (i=0;i<nspec;++i)
288 int nspec=theConstantsVect.size();
293 for (i=0;i<nspec;++i)
365 Report::DevelFatal() <<
" Attempt to add reaction duplicate name " << name;
382 if (name.find(
"_ELECTRON_CAPTURE",0) != std::string::npos)
386 else if (name.find(
"_HOLE_CAPTURE",0) != std::string::npos)
390 else if (name.find(
"_ELECTRON_EMISSION",0) != std::string::npos)
394 else if (name.find(
"_HOLE_EMISSION",0) != std::string::npos)
415 std::map<std::string,int>::iterator n_i;
419 if (reactionNum == -1)
421 Report::DevelFatal() <<
" Attempt to add reactant " << reactant
422 <<
" to non-existant reaction " << name;
436 Report::DevelFatal() <<
"attempt to add unknown reactant " << reactant
437 <<
" to reaction number " << reactionNum
442 speciesNum = -(n_i->second+1);
447 speciesNum = n_i->second;
470 std::map<std::string,int>::iterator n_i;
476 if (reactionNum == -1)
478 Report::DevelFatal() <<
" Attempt to add product " << product
479 <<
" to non-existant reaction " << name;
493 Report::DevelFatal() <<
"attempt to add unknown product " << product
494 <<
" to reaction number " << reactionNum
499 std::ostringstream ost;
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";
511 speciesNum = n_i->second;
533 if (reactionNum == -1)
535 Report::DevelFatal() <<
" Attempt to set rate constant of non-existant reaction "
558 if (reactionNum == -1)
560 Report::DevelFatal() <<
" Attempt to scale rate constant of non-existant reaction "
584 if (reactionNum == -1)
586 Report::DevelFatal() <<
" Attempt to scale rate constant of non-existant reaction "
606 std::vector<double> &concs,
607 std::vector<double> &constant_vec)
613 if (reactionNum == -1)
615 Report::DevelFatal() <<
" Attempt to scale rate constant of non-existant reaction "
639 if (reactionNum == -1)
641 Report::DevelFatal() <<
" Attempt to scale rate constant of non-existant reaction "
665 if (reactionNum == -1)
667 Report::DevelFatal() <<
" Attempt to scale rate constant of non-existant reaction "
690 for (i=0; i<numReacts; ++i)
708 std::vector<double> &concs,
709 std::vector<double> &constant_vec)
713 for (i=0; i<numReacts; ++i)
715 theReactions[i].setRateConstantFromCalculator(T,concs,constant_vec);
733 for (i=0; i<numReacts; ++i)
752 for (i=0; i<numReacts; ++i)
775 std::vector<Xyce::Device::Reaction>::iterator reactionIter=
theReactions.begin();
776 std::vector<Xyce::Device::Reaction>::iterator reactionIterEnd=
theReactions.end();
781 for (; reactionIter != reactionIterEnd; ++reactionIter)
783 reactionIter->setScaleFactors(
C0,
t0,
x0);
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);
806 for(
int i=0 ; i<
species.size() ; ++i)
808 if(
species[i].getBCCarrierCharge() == 1)
812 else if(
species[i].getBCCarrierCharge() == -1)
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);
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);
868 Util::Expression *foo=
new Util::Expression(expressionStr);
869 theSourceTerms.push_back( std::pair<int,Util::Expression *>(speciesNum, foo));
886 Util::Expression * ExpressionCopy=
new Util::Expression(*expression);
891 std::pair<int,Util::Expression *>(speciesNum,ExpressionCopy));
924 std::vector< std::pair<int,Util::Expression *> >::iterator iterSource=
926 std::vector< std::pair<int,Util::Expression *> >::iterator source_end=
929 for (;iterSource != source_end; ++iterSource)
931 (iterSource->second)->set_sim_time(time);
946 double breaktime=0, btime;
947 std::vector< std::pair<int,Util::Expression *> >::iterator iterSource=
949 std::vector< std::pair<int,Util::Expression *> >::iterator source_end=
952 for (;iterSource != source_end; ++iterSource)
954 btime=(iterSource->second)->get_break_time();
981 std::vector<double> &ddt)
985 for (i=0;i<rSize;++i)
991 std::vector< std::pair<int,Util::Expression *> >::iterator iterSource=
993 std::vector< std::pair<int,Util::Expression *> >::iterator source_end=
996 for (;iterSource != source_end; ++iterSource)
999 (iterSource->second)->evaluateFunction(return_val);
1007 for (; iterMasterSource!= masterSource_end; ++iterMasterSource)
1025 std::vector<std::vector<double> >&jac)
1030 for (i=0;i<rSize;++i)
1046 std::vector<double> &concs,
1047 std::vector<double> &constant_vec,
1048 std::vector<double> &dFdConst)
1051 int cSize=concs.size();
1055 dFdConst.resize(cSize);
1056 for (i=0;i<cSize;++i)
1059 for (i=0;i<rSize;++i)
1061 theReactions[i].getDFdConst(constNum,concs,constant_vec,dFdConst);
1077 std::vector<std::vector<double> >&jac, std::vector<double> &constVec)
1080 int cSize=concs.size();
1083 constVec.resize(2*cSize);
1084 for (i=0 ; i<constVec.size() ; ++i)
1087 for (i=0;i<rSize;++i)
1089 theReactions[i].getJacobianVC(concs,constant_vec,jac,constVec);
1114 std::vector<double> &constant_vec,
1115 std::vector<int> &captureVect,
1116 std::vector<int> &emissionVect)
1121 for (i=0;i<captureVect.size();++i)
1123 rate -=
theReactions[captureVect[i]].getRateVC(concs, constant_vec);
1126 for (i=0;i<emissionVect.size();++i)
1128 if(
theReactions[emissionVect[i]].getCarrierEmissionIndex() < 0)
1130 rate +=
theReactions[emissionVect[i]].getRateVC(concs,constant_vec);
1134 rate +=
theReactions[emissionVect[i]].getFDEmissionRate(concs,constant_vec);
1156 std::vector<double> &constant_vec,
1157 std::vector<int> &captureVect,
1158 double & concentration)
1163 for (i=0;i<captureVect.size();++i)
1165 rate +=
theReactions[captureVect[i]].getRateVC(concs, constant_vec);
1170 return concentration/rate;
1192 std::vector<double> &constant_vec,
1193 std::vector<int> &captureVect,
1194 double & concentration,
1195 std::vector<double> &lifetimes)
1198 lifetimes.resize(captureVect.size());
1200 for (i=0;i<captureVect.size();++i)
1202 lifetimes[i] =
theReactions[captureVect[i]].getRateVC(concs, constant_vec);
1204 if (lifetimes[i] > 0)
1205 lifetimes[i] = concentration/lifetimes[i];
1235 std::vector<double> &constant_vec,
1236 std::vector<int> &captureVect,
1237 std::vector<int> &emissionVect,
1238 std::vector<double> &dRatedC)
1241 int cSize=dRatedC.size();
1242 int const_size=constant_vec.size();
1243 std::vector<double> tempdRdC(cSize);
1244 int FADSize = cSize+const_size;
1246 for (i=0;i<cSize;++i)
1253 std::vector<FDFadType> defects(cSize);
1254 std::vector<FDFadType> carriers(const_size);
1255 for( i=0 ; i<const_size ; ++i)
1257 carriers[i] = constant_vec[i];
1260 for( i=0 ; i<cSize ; ++i)
1262 defects[i] = concs[i];
1263 defects[i].diff(i+const_size,FADSize);
1266 for (i=0;i<captureVect.size();++i)
1268 tempdRdCFD =
theReactions[captureVect[i]].getRateVC(defects, carriers);
1270 for (j=0;j<cSize;++j)
1272 dRatedC[j] -= tempdRdCFD.dx(j+const_size);
1276 for (i=0;i<emissionVect.size();++i)
1278 tempdRdC.assign(cSize,0.0);
1279 if(
theReactions[emissionVect[i]].getCarrierEmissionIndex()<0)
1281 tempdRdCFD =
theReactions[emissionVect[i]].getRateVC(defects, carriers);
1282 for(
int j=0 ; j<cSize ; ++j)
1284 tempdRdC[j] = tempdRdCFD.dx(j+const_size);
1290 tempdRdCFD =
theReactions[emissionVect[i]].getFDEmissionRate(defects, carriers);
1291 for(
int j=0 ; j<cSize ; ++j)
1293 tempdRdC[j] = tempdRdCFD.dx(j+const_size);
1298 for (j=0;j<cSize;++j)
1300 dRatedC[j] += tempdRdC[j];
1329 std::vector<double> &constant_vec,
1330 std::vector<int> &captureVect,
1331 std::vector<int> &emissionVect,
1332 std::vector<double> &dRatedConst)
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;
1341 for (i=0;i<cSize;++i)
1348 std::vector<FDFadType> defects(concs.size());
1349 std::vector<FDFadType> carriers(2);
1350 for( i=0 ; i<cSize ; ++i)
1352 carriers[i] = constant_vec[i];
1353 carriers[i].diff(i,FADSize);
1355 for( i=0 ; i<concs.size() ; ++i)
1357 defects[i] = concs[i];
1361 for (i=0;i<captureVect.size();++i)
1363 tempdRdConst.assign(cSize,0.0);
1365 tempdRdConstFD =
theReactions[captureVect[i]].getRateVC(defects, carriers);
1367 for (j=0;j<cSize;++j)
1369 dRatedConst[j] -= tempdRdConstFD.dx(j);
1374 for (i=0;i<emissionVect.size();++i)
1376 tempdRdConst.assign(cSize,0.0);
1378 if(
theReactions[emissionVect[i]].getCarrierEmissionIndex()<0)
1380 tempdRdConstFD =
theReactions[emissionVect[i]].getRateVC(defects, carriers);
1381 for(
int j=0 ; j<cSize ; ++j)
1383 tempdRdConst[j] = tempdRdConstFD.dx(j);
1388 tempdRdConstFD =
theReactions[emissionVect[i]].getFDEmissionRate(defects, carriers);
1389 for(
int j=0 ; j<cSize ; ++j)
1391 tempdRdConst[j] = tempdRdConstFD.dx(j);
1395 for (j=0;j<cSize;++j)
1396 dRatedConst[j] += tempdRdConst[j];
1413 double sigma,
double hopDistance)
1424 int carrierIndex=-1;
1426 double thermalVelocity=0.0;
1433 int BCCarrierCharge=0;
1435 if(carrierName ==
"E")
1437 BCCarrierCharge = -1;
1439 else if(carrierName ==
"H")
1441 BCCarrierCharge = 1;
1445 Report::DevelFatal() <<
"ReactionNetwork::setBourgoinCorbettCalc: Illegal carrier for BC enhancement: " << carrierName;
1448 species[speciesIndex].setBCEnhancedDiffusion(carrierIndex,sigma,BCCarrierCharge,hopDistance);
1462 int carrierIndex = 0;
1487 int carrierIndex = 1;
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 scaleRateConstantsFromCalc()
void unscaleRateConstantFromCalculator(const std::string &name)
const std::string & getName() const
std::vector< int > holeEmissionReactions
void getDdt(std::vector< double > &concs, std::vector< double > &constants, std::vector< double > &ddt)
void setCoefficients(double Temp)
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< int > holeCaptureReactions
std::vector< Reaction > theReactions
void setRateConstantsFromCalc(double T)
void setSimTime(double time)
virtual ~ReactionNetwork()
std::vector< Specie > constants
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 scaleRateConstantFromCalculator()
void setConstants(std::vector< Specie > &theConstantsVect)
void setRxnVariableCoeffs(bool variableCoeffs)
void scaleRateConstantFromCalculator(const std::string &name)
void setSpecies(std::vector< Specie > &theSpeciesVect)
double getBreakpointTime()
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)
std::vector< int > masterSourceSpecies
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)
void unscaleRateConstantsFromCalc()
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)
std::vector< Specie > species