45 #include <Xyce_config.h>
50 #include <N_UTL_Math.h>
65 #include <N_LAS_Matrix.h>
66 #include <N_LAS_MultiVector.h>
67 #include <N_LAS_Vector.h>
72 #include <N_UTL_Expression.h>
73 #include <N_UTL_BreakPoint.h>
85 .setDescription(
"Temperature");
90 .setDescription(
"Length Scalar.");
95 .setDescription(
"Concentration Scalar.");
100 .setDescription(
"Time Scalar.");
105 .setDescription(
"Scalar for X axis in tecplot file (default unit is cm)");
110 .setDescription(
"Output Interval(sec)");
115 .setDescription(
"Flag for processing chemistry file only once,then copied to other mesh points.");
120 .setDescription(
"Flag for applying scaling to the reaction equations.");
126 .setDescription(
"Flag for enabling lattice defect diffusion.");
132 .setDescription(
"Flag for enabling lattice defect diffusion. Identical to DIFFUSION flag,above. Do not set both!");
138 .setDescription(
"Flag for excluding regions that are outside of source region from computing defect reaction equations. This is a speed optimization. Turning it on will NOT change the answer");
143 .setDescription(
"Debug Flag for turning on/off column reordering.");
150 .setDescription(
"Integer number to determine type of tecplot output. 0=no output. 1=single time-dependent file,with each time step in a different zone.");
155 .setDescription(
"Flag for using Dirichlet boundary conditions.");
163 .setDescription(
"Parameter measurement temperature");
169 .setDescription(
"Left edge of integration volume.");
174 .setDescription(
"Right edge of integration volume");
180 .setDescription(
"Left edge of source region");
186 .setDescription(
"Right edge of source region");
197 .setDescription(
"Name of the reaction file");
202 .setDescription(
"Number of mesh points.");
245 reactionFileCopyFlag(false),
246 haveAnyReactions(false),
247 useScaledVariablesFlag(true),
248 useDopingArrayData(false),
251 lastOutputTime(-10.0),
262 excludeNoSourceRegionsFlag(true),
263 excludeNoSourceRegionsFlagGiven(false),
264 transportFlagGiven(false),
265 transportFlag(false),
266 diffusionFlagGiven(false),
267 diffusionFlag(false),
268 dirichletBCFlag(false),
269 columnReorderingFlag(false),
299 Report::UserWarning() <<
"Both transportFlag and diffusionFlag set in " <<
getName() <<
". Using transportFlag";
316 int numRegions=
regVec.size();
318 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
321 if (!(rdVec1.empty()))
323 Xyce::dout() <<
"Model Region Data vector:" << std::endl;
324 for (
int ireg=0;ireg<numRegions;++ireg)
327 Xyce::dout() << ireg <<
": "<< rd;
354 double dn =
static_cast<double>(size-1);
355 double dx = (xmax-xmin)/dn;
358 xVec.resize(size,0.0);
359 dxVec.resize(size,0.0);
371 for (i=0;i<size-1;++i)
412 std::vector<RegionData*> * rdVecPtr(0);
418 for (iReg=0;iReg!=numReg;++iReg)
422 std::ostringstream oss;
423 oss <<
getName() <<
"_" << std::setw(3) << std::setfill(
'0') << iReg;
424 regDataPtr->
name = oss.str();
428 std::ostringstream oss;
429 oss <<
outputName <<
"_" << std::setw(3) << std::setfill(
'0') << iReg;
430 regDataPtr->
outName = oss.str();
436 (*rdVecPtr).push_back(regDataPtr);
454 for (iReg=0;iReg!=numReg;++iReg)
463 regPtr =
new Region(*((*rdVecPtr)[iReg]),
472 regPtr =
new Region(*((*rdVecPtr)[iReg]),
477 ((*rdVecPtr)[iReg])->doNothing=
true;
479 regPtr =
new Region(*((*rdVecPtr)[iReg]),
489 for (iReg=0;iReg!=numReg;++iReg)
499 ((*rdVecPtr)[iReg])->doNothing=
true;
581 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
587 Xyce::dout() << Xyce::section_divider << std::endl;
588 Xyce::dout() <<
"Instance::initializeChemistry ():" << std::endl;
589 for (; itSource!=itSourceEnd; ++itSource)
591 std::string speciesName (itSource->first);
592 Xyce::dout() <<
"speciesName = " << speciesName << std::endl;
594 Xyce::dout() << Xyce::section_divider << std::endl;
597 std::vector<RegionData*> * rdVecPtr(0);
602 int numRegions=
regVec.size();
603 for (
int ireg=0;ireg<numRegions;++ireg)
610 if (!(diMap.empty()))
614 std::map<std::string, DopeInfo *>::iterator iter;
615 std::map<std::string, DopeInfo *>::iterator start = diMap.begin();
616 std::map<std::string, DopeInfo *>::iterator end = diMap.end();
618 for ( iter = start; iter != end; ++iter )
622 bool reactantExist =
false;
639 if (
regVec[ireg]->reactantExist(
"BM"))
641 regVec[ireg]->setInitialCondition(
"BM", (*rdVecPtr)[ireg]->Boron_Concentration);
644 if (
regVec[ireg]->reactantExist(
"PP"))
646 regVec[ireg]->setInitialCondition(
"PP", (*rdVecPtr)[ireg]->Phosphorus_Concentration);
657 sourceOn = (
xVec[ireg] >= xlos) && (
xVec[ireg] <= xhis);
664 for (; itSource!=itSourceEnd; ++itSource)
666 std::string speciesName (itSource->first);
667 regVec[ireg]->addMasterSource(speciesName);
674 regVec[ireg]->scaleVariables ();
694 int localPosIndex = 0;
695 int localNegIndex = 1;
696 int indexCounter=localNegIndex+1;
701 jacStamp[localPosIndex][localPosIndex] = localPosIndex;
702 jacStamp[localPosIndex][localNegIndex] = localNegIndex;
705 jacStamp[localNegIndex][localPosIndex] = localPosIndex;
706 jacStamp[localNegIndex][localNegIndex] = localNegIndex;
716 int numRegions=
regVec.size();
717 for (ireg=0;ireg<numRegions;++ireg)
719 int concentrationSize =
regVec[ireg]->getNumSpecies();
720 if (concentrationSize != 0)
723 std::vector<int> voltageNodeColDep(2,-1);
724 voltageNodeColDep[0]=localPosIndex;
725 voltageNodeColDep[1]=localNegIndex;
727 int firstReactant=-1;
729 regVec[ireg]->setupJacStamp(
jacStamp,voltageNodeColDep, firstReactant, lastIndex);
739 int numSpecies =
thVec.size();
742 for (ireg=0;ireg<numRegions;++ireg)
744 if (!(
regVec[ireg]->getDoNothingFlag()) )
754 Xyce::dout() <<
regVec[ireg]->getName ()
761 for (isp=0;isp<numSpecies;++isp)
768 for (ireg=0;ireg<numRegions;++ireg)
771 if (row < 0)
continue;
780 else if (ireg==numRegions-1)
806 int posSize =
jacStamp[posRow].size();
808 int negSize =
jacStamp[negRow].size();
809 for (ireg=0;ireg<numRegions;++ireg)
816 int posRowSize =
jacStamp[posRow].size();
817 jacStamp[posRow].resize(posRowSize+numSpecie);
819 int negRowSize =
jacStamp[negRow].size();
820 jacStamp[negRow].resize(negRowSize+numSpecie);
822 for (isp=0;isp<numSpecie;++isp)
824 int icol = posRowSize+isp;
825 jacStamp[posRow][icol] = posIndex+isp ;
827 icol = negRowSize+isp;
828 jacStamp[negRow][icol] = posIndex+isp ;
847 int mapSize =
jacMap.size();
848 for (
int i=0;i<mapSize;++i)
852 for (
int j=0;j<
jacStamp[i].size();++j)
869 std::vector< std::vector<int> > tempStamp_eric;
870 std::vector< std::vector<int> > tempMap2_eric;
878 if (DEBUG_DEVICE && isActive(Diag::DEVICE_JACSTAMP) &&
getSolverState().debugTimeFlag)
880 Xyce::dout() <<
"jacStamp Before removing terminal nodes:"<<std::endl;
882 Xyce::dout() <<
"jacMap2 Before removing terminal nodes:"<<std::endl;
899 std::vector<RegionData*> * rdVecPtr(0);
902 int size = (*rdVecPtr).size();
911 for (i=0;i<size-1;++i)
921 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
925 Xyce::dout() <<
"Scaled Mesh: xVec["<<i<<
"] = " <<
xVec[i] << std::endl;
927 Xyce::dout() << std::endl;
928 for (i=0;i<size-1;++i)
930 Xyce::dout() <<
"Scaled Mesh: dxVec["<<i<<
"] = " <<
dxVec[i] << std::endl;
932 Xyce::dout() << std::endl;
947 std::vector<RegionData*> * rdVecPtr(0);
949 if ( !((*rdVecPtr).empty()) )
952 int numSpecies =
thVec.size();
954 int size = (*rdVecPtr).size();
955 for (isp=0;isp<numSpecies;++isp)
957 thVec[isp].fluxVec.resize(size-1,0.0);
972 bool bsuccess =
true;
974 bool skipOutput =
false;
980 double outMult =
static_cast<double> (
outputIndex);
992 if (force_final_output &&
995 if (skipOutput)
return bsuccess;
1002 int numRegions =
regVec.size();
1005 for (
int ireg=0;ireg<numRegions;++ireg)
1009 bs1 =
regVec[ireg]->outputTecplot ();
1010 bsuccess = bsuccess && bs1;
1020 bsuccess = bsuccess && bs1;
1025 bsuccess = bsuccess && bs1;
1030 int numRegions =
regVec.size();
1031 if (outputRegion < numRegions && outputRegion >= 0)
1036 bsuccess = bsuccess && bs1;
1054 bool bsuccess =
true;
1060 for(i=0;i<256;++i) filename[i] = static_cast<char>(0);
1062 sprintf(filename,
"%s.dat",
outputName.c_str());
1066 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
1068 Xyce::dout() <<
" Instance::outputTecplot. filename = " << std::string(filename) <<std::endl;
1073 fp1 = fopen(filename,
"w");
1075 " TITLE = \"Spatially Dependent defect data for compact rxn device: %s time = %20.12e seconds.\",\n",
1080 fp1 = fopen(filename,
"a");
1083 int rSize=(
regVec[0])->getNumSpecies();
1084 int cSize=(
regVec[0])->getNumConstants();
1088 fprintf(fp1,
"%s",
"\tVARIABLES = \"X \",\n");
1091 for (
int iconst=0;iconst<cSize;++iconst)
1096 for (
int ispec=0;ispec<rSize;++ispec)
1098 fprintf(fp1,
"\t \"%s \",\n", ( reg.
getSpeciesName(ispec)).c_str());
1103 fprintf(fp1,
"\tZONE F=POINT,I=%d", NX);
1107 fprintf(fp1,
" T = \"DCOP step = %d\" \n",
callsOTEC);
1111 fprintf(fp1,
" T = \"time step = %d, time=%20.12e\" AUXDATA time = \"%20.12e seconds\" \n",
callsOTEC , time, time);
1114 std::vector<RegionData*> * rdVecPtr(0);
1119 fprintf(fp1,
" %20.12e", time);
1127 fprintf(fp1,
" %20.12e", val);
1131 for (
int iconst=0;iconst<cSize;++iconst)
1134 fprintf(fp1,
" %20.12e", val);
1138 fprintf(fp1,
"%s",
"\n"); numprint = 0;
1146 for (
int ispec=0;ispec<rSize;++ispec)
1153 fprintf(fp1,
" %20.12e", val);
1157 fprintf(fp1,
"%s",
"\n"); numprint = 0;
1166 fprintf(fp1,
"%s",
"\n");
1184 bool bsuccess =
true;
1190 for(i=0;i<256;++i) filename[i] = static_cast<char>(0);
1192 sprintf(filename,
"%s.dat",
outputName.c_str());
1198 fp1 = fopen(filename,
"w");
1200 " TITLE = \"Spatially Dependent defect data for compact rxn device: %s time = %20.12e seconds.\",\n",
1205 fp1 = fopen(filename,
"a");
1208 int rSize=(
regVec[0])->getNumSpecies();
1209 int cSize=(
regVec[0])->getNumConstants();
1213 fprintf(fp1,
"%s",
"\tVARIABLES = \"X \",\n");
1214 fprintf(fp1,
"%s",
"\t \"Time(sec) \",\n");
1217 for (
int iconst=0;iconst<cSize;++iconst)
1222 for (
int ispec=0;ispec<rSize;++ispec)
1224 fprintf(fp1,
"\t \"%s \",\n", ( reg.
getSpeciesName(ispec)).c_str());
1227 fprintf(fp1,
"\tZONE F=POINT,I=%d", NX);
1230 fprintf(fp1,
"%s",
" \n");
1232 std::vector<RegionData*> * rdVecPtr(0);
1237 fprintf(fp1,
" %20.12e", time);
1244 val = ((*rdVecPtr)[i])->xloc;
1245 fprintf(fp1,
" %20.12e", val);
1247 fprintf(fp1,
" %20.12e", time);
1251 for (
int iconst=0;iconst<cSize;++iconst)
1254 fprintf(fp1,
" %20.12e", val);
1258 fprintf(fp1,
"%s",
"\n"); numprint = 0;
1266 for (
int ispec=0;ispec<rSize;++ispec)
1269 fprintf(fp1,
" %20.12e", val);
1273 fprintf(fp1,
"%s",
"\n"); numprint = 0;
1282 fprintf(fp1,
"%s",
"\n");
1300 bool bsuccess =
true;
1304 char filename[256];
for(i=0;i<256;++i) filename[i] = static_cast<char>(0);
1305 sprintf(filename,
"%scarrier.dat",
outputName.c_str());
1308 fp1 = fopen(filename,
"w");
1309 int cSize=(
regVec[0])->getNumConstants();
1311 std::vector<RegionData*> * rdVecPtr(0);
1317 val = ((*rdVecPtr)[i])->xloc;
1318 fprintf(fp1,
" %20.12e", val);
1322 for (
int iconst=0;iconst<cSize;++iconst)
1325 fprintf(fp1,
" %20.12e", val);
1327 fprintf(fp1,
"%s",
"\n");
1348 int size =
regVec.size();
1350 for (i=0;i<size;++i)
1363 std::map<std::string,DopeInfo *>::iterator iter;
1364 std::map<std::string,DopeInfo *>::iterator begin =
dopeInfoMap.begin();
1365 std::map<std::string,DopeInfo *>::iterator end =
dopeInfoMap.end ();
1367 for(iter=begin;iter!=end;++iter)
1369 if (iter->second != 0)
delete iter->second;
1386 const std::vector<int> & extLIDVecRef )
1391 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
1393 Xyce::dout() << section_divider << std::endl;
1394 Xyce::dout() <<
" Instance::registerLIDs" <<std::endl;
1395 Xyce::dout() <<
" name = " <<
getName() << std::endl;
1396 Xyce::dout() <<
" number of internal variables: " <<
numIntVars << std::endl;
1397 Xyce::dout() <<
" number of external variables: " <<
numExtVars << std::endl;
1398 Xyce::dout() <<
" numIntVars = " <<
numIntVars << std::endl;
1399 Xyce::dout() <<
" numExtVars = " <<
numExtVars << std::endl;
1406 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
1408 Xyce::dout() <<
" Internal LID List" << std::endl;
1409 for(
int i = 0; i <
intLIDVec.size(); ++i )
1410 Xyce::dout() <<
" " <<
intLIDVec[i] << std::endl;
1411 Xyce::dout() <<
" External LID List" << std::endl;
1412 for(
int i = 0; i <
extLIDVec.size(); ++i )
1413 Xyce::dout() <<
" " <<
extLIDVec[i] << std::endl;
1424 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
1426 Xyce::dout() <<
" li_Pos = " <<
li_Pos << std::endl;
1427 Xyce::dout() <<
" li_Neg = " <<
li_Neg << std::endl;
1431 int numRegions =
regVec.size();
1432 for (
int ireg=0;ireg<numRegions;++ireg)
1440 int numSpecies =
thVec.size();
1441 int size =
regVec.size();
1445 for (ispec=0;ispec<numSpecies;++ispec)
1447 std::string speciesName =
regVec[0]->getSpeciesName(ispec);
1448 thVec[ispec].specie_id.resize(size,-1);
1449 for (i=0;i<size;++i)
1451 thVec[ispec].specie_id[i] = (
regVec[i])->getSpeciesLID (speciesName);
1456 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
1458 Xyce::dout() << section_divider << std::endl;
1474 for (std::vector<Region *>::const_iterator it =
regVec.begin(), end =
regVec.end(); it != end; ++it)
1475 (*it)->loadNodeSymbols(symbol_table, *
this);
1495 int numRegions =
regVec.size();
1496 for (
int ireg=0;ireg<numRegions;++ireg)
1498 regVec[ireg]->registerStateLIDs(staLIDVec,i);
1540 std::vector<int> &map=
jacMap;
1541 std::vector< std::vector<int> > &map2=
jacMap2;
1552 int numRegions =
regVec.size();
1553 for (
int ireg=0;ireg<numRegions;++ireg)
1566 for (
int ireg=0;ireg<numRegions;++ireg)
1568 int row = regPosIndexVec[ireg] + regV0subIndexVec[ireg];
1569 if (row < 0)
continue;
1571 int rowSize =
jacStamp[row].size();
1574 int col = regPosIndexVec[1] + regV0subIndexVec[1];
1578 else if (ireg==numRegions-1)
1580 int col = regPosIndexVec[numRegions-2] + regV0subIndexVec[numRegions-2];
1586 int col1 = regPosIndexVec[ireg+1] + regV0subIndexVec[ireg+1];
1587 int col2 = regPosIndexVec[ireg-1] + regV0subIndexVec[ireg-1];
1595 for (
int iReg=0;iReg<numRegions;++iReg)
1623 int numRegions =
regVec.size();
1633 for (
int ireg=0;ireg<numRegions;++ireg)
1637 regVec[ireg]->setupPointers (dFdx,dQdx);
1653 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) &&
getSolverState().debugTimeFlag)
1655 Xyce::dout() <<
"Start Instance::updateTemperature" << std::endl;
1656 Xyce::dout() <<
"temp = "<<temp << std::endl;
1658 if( temp != -999.0 )
TEMP = temp;
1670 int numRegions =
regVec.size();
1671 for (
int i=0;i<numRegions;++i)
1679 int numSpecies =
regVec[0]->getNumSpecies();
1680 thVec.reserve(numSpecies);
1681 for (
int ispec=0;ispec<numSpecies;++ispec)
1683 std::string speciesName =
regVec[0]->getSpeciesName(ispec);
1685 double Dtmp = (
regVec[0])->getDiffusionCoefficient (ispec,
TEMP);
1689 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
1693 Xyce::dout() <<
"Vacancy Diffusion: scaling=TRUE ";
1694 Xyce::dout() <<
"D_"<<speciesName<<
" = " << Dtmp << std::endl;
1698 Xyce::dout() <<
"Vacancy Diffusion: scaling=FALSE ";
1699 Xyce::dout() <<
"D_"<<speciesName<<
" = " << Dtmp << std::endl;
1704 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
1706 for (
int ispec=0;ispec<numSpecies;++ispec)
1708 Xyce::dout() <<
"Vacancy Diffusion: D_" <<
thVec[ispec].name <<
" transportFlag = ";
1710 else Xyce::dout() <<
"FALSE";
1711 Xyce::dout() << std::endl;
1737 int numRegions =
regVec.size();
1740 for (
int ireg=0;ireg<numRegions;++ireg)
1742 regVec[ireg]->loadErrorWeightMask (maskVector);
1769 int numRegions =
regVec.size();
1770 for (
int ireg=0;ireg<numRegions;++ireg)
1772 regVec[ireg]->loadDAEQVector (daeQVec);
1796 double vbe_diff = 0.0;
1800 int numRegions =
regVec.size();
1801 for (
int ireg=0;ireg<numRegions;++ireg)
1804 regVec[ireg]->loadDAEFVector (daeFVec);
1805 regVec[ireg]->loadDAEdFdxdV(dFdxdVp, vbe_diff);
1812 int numSpecies =
thVec.size();
1814 for (isp=0;isp<numSpecies;++isp)
1819 int size =
regVec.size();
1821 std::vector<int> & specie_id =
thVec[isp].specie_id;
1823 double dx1 =
dxVec[0];
1824 double xloVal = (
thVec[isp].fluxVec[0]-
thVec[isp].flux_bc1)/dx1;
1825 daeFVec[specie_id[0]] += xloVal;
1827 for (i=1;i<size-1;++i)
1829 double fluxDif = (
thVec[isp].fluxVec[i]-
thVec[isp].fluxVec[i-1]);
1831 daeFVec[specie_id[i]] += (fluxDif)/aveDx;
1834 double dx2 =
dxVec[size-2];
1835 double xhiVal = (
thVec[isp].flux_bc2-
thVec[isp].fluxVec[size-2])/dx2;
1836 daeFVec[specie_id[size-1]] += xhiVal;
1861 bool bsuccess =
true;
1862 bool tmpBool =
true;
1867 Xyce::dout() << subsection_divider << std::endl;
1868 Xyce::dout() <<
"Rxn dQdx load:" << std::endl;
1869 Xyce::dout() <<
" name = " <<
getName() << std::endl;
1873 bsuccess = bsuccess && tmpBool;
1875 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) &&
getSolverState().debugTimeFlag)
1876 Xyce::dout() << subsection_divider << std::endl;
1895 bool bsuccess =
true;
1899 int numRegions =
regVec.size();
1900 for (
int ireg=0;ireg<numRegions;++ireg)
1902 regVec[ireg]->loadDAEdQdx (dQdxMat);
1921 bool bsuccess =
true;
1922 bool tmpBool =
true;
1928 Xyce::dout() << subsection_divider << std::endl;
1929 Xyce::dout() <<
"Rxn dFdx load:" << std::endl;
1930 Xyce::dout() <<
" name = " <<
getName() << std::endl;
1934 bsuccess = bsuccess && tmpBool;
1936 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) &&
getSolverState().debugTimeFlag)
1938 Xyce::dout() << subsection_divider << std::endl;
1962 int numRegions =
regVec.size();
1967 cSize = (
regVec[0])->getNumConstants();
1968 rSize = (
regVec[0])->getNumSpecies();
1969 for (
int ireg=0;ireg<numRegions;++ireg)
1971 regVec[ireg]->loadDAEdFdx(dFdxMat);
1973 if (
cols.size() < rSize)
cols.resize(rSize,0);
1982 int numSpecies =
thVec.size();
1984 for (isp=0;isp<numSpecies;++isp)
1989 int size =
regVec.size();
1991 double DiffC =
thVec[isp].D_specie;
1992 std::vector<int> & specie_id =
thVec[isp].specie_id;
1994 for (i=0;i<size;++i)
1996 int row = specie_id[i];
1999 double aveDx = (
dxVec[i]);
2000 double coef = DiffC/(aveDx*
dxVec[i]);
2003 cols[0] = specie_id[i ];
vals[0] =
thVec[isp].bcScale1 * coef;
2004 cols[1] = specie_id[i+1];
vals[1] =-coef;
2006 bool bs1 = dFdxMat.sumIntoLocalRow (row, count, &
vals[0], &
cols[0]);
2008 else if (i==(size-1))
2010 double aveDx = (
dxVec[i-1]);
2011 double coef = DiffC/(aveDx*
dxVec[i-1]);
2013 cols[0] = specie_id[i-1];
vals[0] =-coef;
2014 cols[1] = specie_id[i ];
vals[1] =
thVec[isp].bcScale2 * coef;
2016 bool bs1 = dFdxMat.sumIntoLocalRow (row, count, &
vals[0], &
cols[0]);
2021 double coef1 = DiffC/(aveDx*
dxVec[i-1]);
2022 double coef2 = DiffC/(aveDx*
dxVec[i ]);
2023 double coefSum = coef1+coef2;
2026 cols[0] = specie_id[i-1];
vals[0] =-coef1;
2027 cols[1] = specie_id[i ];
vals[1] = coefSum;
2028 cols[2] = specie_id[i+1];
vals[2] =-coef2;
2030 bool bs1 = dFdxMat.sumIntoLocalRow (row, count, &
vals[0], &
cols[0]);
2050 bool bsuccess =
true;
2052 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) &&
getSolverState().debugTimeFlag)
2054 Xyce::dout() << subsection_divider << std::endl;
2055 Xyce::dout() <<
" Start Instance::updatePrimaryState\n";
2056 Xyce::dout() <<
" name = " <<
getName() << std::endl;
2068 int numRegions =
regVec.size();
2069 for (
int ireg=0;ireg<numRegions;++ireg)
2073 int rSize =
regVec[ireg]->getNumSpecies();
2074 for (
int i=0;i<rSize;++i)
2076 staVector[
regVec[ireg]->getStateConcentrationLID(i)] = regVec[ireg]->getStateConcentration(i);
2089 numRegions =
regVec.size();
2090 for (
int ireg=0;ireg<numRegions;++ireg)
2094 int rSize =
regVec[ireg]->getNumSpecies();
2095 for (
int i=0;i<rSize;++i)
2097 currStaVector[
regVec[ireg]->getStateConcentrationLID(i)] = regVec[ireg]->getStateConcentration(i);
2118 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) &&
getSolverState().debugTimeFlag)
2120 Xyce::dout() << subsection_divider << std::endl;
2121 Xyce::dout() <<
" Start Instance::updateSecondaryState\n";
2122 Xyce::dout() <<
" name = " <<
getName() << std::endl;
2126 int numRegions =
regVec.size();
2127 for (
int ireg=0;ireg<numRegions;++ireg)
2129 regVec[ireg]->updateSecondaryState (staDeriv);
2151 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) &&
getSolverState().debugTimeFlag)
2153 Xyce::dout() << subsection_divider << std::endl;
2154 Xyce::dout() <<
" In Instance::updateIntermediateVars" << std::endl;
2155 Xyce::dout() <<
" name = " <<
getName() << std::endl;
2165 int numRegions =
regVec.size();
2166 for (
int ireg=0;ireg<numRegions;++ireg)
2169 regVec[ireg]->updateIntermediateVars (solVec, oldSolVec, time);
2173 int numSpecies =
thVec.size();
2177 for (isp=0;isp<numSpecies;++isp)
2182 int size =
thVec[isp].fluxVec.size();
2183 double DiffC =
thVec[isp].D_specie;
2184 for (i=0;i<size;++i)
2186 double n2 = solVec[
thVec[isp].specie_id[i ]];
2187 double n1 = solVec[
thVec[isp].specie_id[i+1]];
2189 thVec[isp].fluxVec[i] = DiffC*(n2-n1)/
dxVec[i];
2198 n1 = solVec[
thVec[isp].specie_id[0]];
2200 thVec[isp].flux_bc1 = DiffC*(n2-n1)/
dxVec[0];
2203 n2 = solVec[
thVec[isp].specie_id[size]];
2204 thVec[isp].flux_bc2 = DiffC*(n2-n1)/
dxVec[size];
2206 thVec[isp].bcScale1=2.0;
2207 thVec[isp].bcScale2=2.0;
2211 thVec[isp].flux_bc1 = 0.0;
2212 thVec[isp].flux_bc2 = 0.0;
2236 std::vector<Util::BreakPoint> &breakPointTimes)
2238 int numRegions =
regVec.size();
2240 for (
int ireg=0;ireg<numRegions;++ireg)
2243 junk=
regVec[ireg]->getBreakTime();
2244 breakPointTimes.push_back(junk);
2262 Report::UserWarning0() <<
"No material layer defined in the device, defaulting to silicon.\n"
2263 <<
"A simple material model (and the default inserted here) looks like:\n"
2264 <<
" + layer = {name = DeviceMaterial\n"
2265 <<
" + material = si\n"
2266 <<
" + ConductionBandDOS = 2.86e19\n"
2267 <<
" + ValenceBandDOS = 2.66e19}";
2285 if (cName ==
"DOPINGPROFILES" || cName ==
"REGION")
2289 return (static_cast<CompositeParam *> (doping));
2291 else if (cName ==
"SOURCELIST")
2295 return (static_cast<CompositeParam *> (sources));
2297 if (cName ==
"LAYER")
2302 return (static_cast<CompositeParam *> (n));
2306 Report::UserError() <<
"Unrecognized composite name " << cName;
2336 std::vector<Instance*>::iterator iter;
2340 for (iter=first; iter!=last; ++iter)
2342 (*iter)->processParams();
2360 :
DevicePDEModel(MB,configuration.getModelParameters(), factory_block),
2364 rxnFileName(
"NOFILE"),
2370 xlo_sourceGiven(false),
2371 xhi_sourceGiven(false),
2391 UserWarning(*
this) <<
"XLO_SOURCE >= XHI_SOURCE. Ignoring, and using a spatially uniform source";
2425 std::vector<Instance*>::iterator iter;
2429 for (iter=first; iter!=last; ++iter)
2438 for (i=0;i<size;++i)
2451 std::map<std::string,DopeInfo *>::iterator iter;
2452 std::map<std::string,DopeInfo *>::iterator begin =
dopeInfoMap.begin();
2453 std::map<std::string,DopeInfo *>::iterator end =
dopeInfoMap.end ();
2455 for(iter=begin;iter!=end;++iter)
2457 if (iter->second != 0)
delete iter->second;
2464 std::map<std::string,SpecieSource *>::iterator iter;
2465 std::map<std::string,SpecieSource *>::iterator begin =
defectSourceMap.begin();
2466 std::map<std::string,SpecieSource *>::iterator end =
defectSourceMap.end ();
2468 for(iter=begin;iter!=end;++iter)
2470 if (iter->second != 0)
2472 delete iter->second;
2505 std::vector<Instance*>::const_iterator iter;
2510 os <<
" name model name Parameters" << std::endl;
2511 for (i = 0, iter = first; iter != last; ++iter, ++i)
2513 os <<
" " << i <<
": " << (*iter)->getName() <<
" ";
2517 os <<
" TEMP = " << (*iter)->TEMP << std::endl;
2528 for (std::vector<Instance *>::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
2542 .registerDevice(
"rxn", 1)
2543 .registerModelType(
"rxn", 1);
const InstanceName & getName() const
std::vector< double > xVec
void loadErrorWeightMask()
double * nextStaDerivVectorRawPtr
bool updateSecondaryState()
bool outputPlotFiles(bool force_final_output)
std::vector< MaterialLayer * > materialVec
std::vector< std::vector< double * > > APosEqu_ConstPtr
std::vector< std::vector< int > > jacStamp
static void initThermalModel(ParametricData< T > ¶metric_data)
Add the parameter "TEMPMODEL" to the parametric_data.
bool loadQMatrix(Linear::Matrix &dQdxMat)
bool updateDependentParameters()
std::vector< std::vector< double * > > APosEqu_SpeciesPtr
static ParametricData< MaterialLayer > & getParametricData()
const SolverState & solverState_
static Device * factory(const Configuration &configuration, const FactoryBlock &factory_block)
Descriptor & addPar(const char *parName, T default_value, T U::*varPtr)
Adds the parameter description to the parameter map.
bool outputCarrierDensities()
double * daeQVectorRawPtr
static ParametricData< DopeInfo > & getParametricData()
double getSpeciesVal(int i)
void loadNodeSymbols(Util::SymbolTable &symbol_table) const
Populates and returns the store name map.
double * dFdxdVpVectorRawPtr
std::vector< int > devConMap
std::vector< double > & vals
bool given(const std::string ¶meter_name) const
Pure virtual class to augment a linear system.
Parameter may be specified as time dependent expression from netlist.
double * currStaVectorRawPtr
void registerLIDs(const std::vector< int > &intLIDVecRef, const std::vector< int > &extLIDVecRef)
bool processInstanceParams()
processInstanceParams
void registerJacLIDs(const std::vector< std::vector< int > > &jacLIDVec)
std::vector< int > regFirstReactantIndexVec
bool layerCompositeSpecified
virtual std::ostream & printOutInstances(std::ostream &os) const
bool updateIntermediateVars()
void jacStampMap_fixOrder(const JacobianStamp &stamp_parent, JacobianStamp &map2_parent, JacobianStamp &stamp, JacobianStamp &map2)
virtual void registerJacLIDs(const JacobianStamp &jacLIDVec)
std::map< std::string, SpecieSource * > defectSourceMap
std::vector< std::vector< double * > > ANegEqu_ConstPtr
const std::vector< std::string > & getDepSolnVars()
bool useScaledVariablesFlag
double tnom
nominal temperature for device params.
static ParametricData< SpecieSource > & getParametricData()
std::vector< RegionData * > regionDataVec
std::vector< Param > params
Parameters from the line.
std::vector< int > xhiStencilVec
void setParams(const std::vector< Param > ¶ms)
const std::string & getName() const
CompositeParam * constructComposite(const std::string &cName, const std::string &pName)
double * daeFVectorRawPtr
const std::vector< std::vector< int > > & jacobianStamp() const
The FactoryBlock contains parameters needed by the device, instance and model creation functions...
bool loadFMatrix(Linear::Matrix &dFdxMat)
const DeviceOptions & getDeviceOptions() const
bool updatePrimaryState()
std::vector< std::vector< int > > jacMap2
void addComposite(const char *comp_name, const ParametricData< U > &composite_pars, std::map< std::string, U * > V::*composite_map)
Adds a composite parameter to the parameter map.
std::vector< std::vector< double * > > ANegEqu_SpeciesPtr
bool excludeNoSourceRegionsFlagGiven
std::vector< Instance * > instanceContainer
std::vector< int > xloStencilVec
const DeviceOptions & deviceOptions_
Linear::Vector * deviceErrorWeightMask_
std::vector< int > jacMap
const std::string & getSpeciesName(int i)
static Config< T > & addConfiguration()
Adds the device to the Xyce device configuration.
static void loadModelParameters(ParametricData< Model > &model_parameters)
Linear::Matrix * dFdxMatrixPtr
bool excludeNoSourceRegionsFlag
bool processParams()
processParams
The Device class is an interface for device implementations.
std::map< std::string, DopeInfo * > dopeInfoMap
void resolveMaterialModel()
bool columnReorderingFlag
double * dQdxdVpVectorRawPtr
Class Configuration contains device configuration data.
void outputJacStamp(const JacobianStamp &jac)
Instance(const Configuration &configuration, const InstanceBlock &IB, Model &it_MB, const FactoryBlock &factory_block)
bool interpolateTNOM(double)
void setApplySources(bool flag)
const std::string tecplotTimeDateStamp()
const SolverState & getSolverState() const
virtual void forEachInstance(DeviceInstanceOp &op) const
void initializeChemistry()
std::map< std::string, DopeInfo * > dopeInfoMap
const NetlistLocation & netlistLocation() const
std::vector< double > dxVec
static void loadInstanceParameters(ParametricData< Instance > &instance_parameters)
double * nextStaVectorRawPtr
bool reactionFileCopyFlag
void registerStateLIDs(const std::vector< int > &stateLIDVecRef)
std::vector< TransportHelper > thVec
std::vector< int > regLastIndexVec
std::vector< Region * > regVec
double getConstantsVal(int i)
bool getInstanceBreakPoints(std::vector< Util::BreakPoint > &breakPointTimes)
std::vector< double > splintDopeVec
const std::string & getConstantsName(int i)
double * currSolVectorRawPtr
const ExternData & extData
ModelBlock represents a .MODEL line from the netlist.
Manages parameter binding for class C.
InstanceBlock represent a device instance line from the netlist.
double currTime_
DeviceEntity for expression time, breakpoints DeviceMgr for dependent parameters, breakpoints...
std::vector< int > regNumSpecieVec
Util::Param temp
operating temperature of ckt.
std::vector< Param > params
Linear::Matrix * dQdxMatrixPtr
std::vector< int > & cols
void setReactionNetworkFromFile(const NetlistLocation &netlist_location, const std::string &fileName)
CompositeParam is the base class for classes that wish to only manage the processing of parameter dat...
virtual const std::vector< std::string > & getDepSolnVars()
void setModParams(const std::vector< Param > ¶ms)
double * nextSolVectorRawPtr
bool updateTemperature(const double &temp=-999.0)