47 #include <Xyce_config.h>
50 #include <N_UTL_Misc.h>
51 #ifdef Xyce_DEBUG_DEVICE
78 #include <N_LAS_Vector.h>
79 #include <N_LAS_Matrix.h>
80 #include <N_LAS_System.h>
81 #include <N_LAS_Builder.h>
110 .setDescription(
"Density scalar; adjust to mitigate convergence problems.");
115 .setDescription(
"If set the density will be scaled by a fraction of the maximum doping.");
118 .setDescription(
"Fraction of the maximum doping by which density will be scaled.");
123 .setDescription(
"Temperature");
131 .setDescription(
"Device width.");
134 .setDescription(
"Device width.");
138 .setDescription(
"Time interval for tecplot output (if enabled).");
141 #ifdef Xyce_DEBUG_DEVICE
142 p.
addPar(
"ANODEINDEX", 1, &DiodePDE::Instance::anodeIndex_user)
143 .setGivenMember(&DiodePDE::Instance::anodeIndex_userGiven);
144 p.
addPar(
"CATHODEINDEX", 0, &DiodePDE::Instance::cathodeIndex_user)
145 .setGivenMember(&DiodePDE::Instance::cathodeIndex_userGiven);
150 .setDescription(
"Cross sectional area used to compute recombination integral.");
159 .setDescription(
"If true, use field dependent mobility.");
168 .setDescription(
"If set to true, then some variables are excluded from the time integration error control calculation.");
171 .setDescription(
"Flag to turn on/off Auger recombination");
174 .setDescription(
"Flag to turn on/off Shockley-Reed-Hall recombination.");
189 .setDescription(
"File containing doping profile.");
194 .setDescription(
"Number of mesh points (if a single material).");
198 .setDescription(
"Flag for using Dirichlet boundary conditions for defects.");
201 .setDescription(
"Flag for using old(inaccurate) intrinsic carrier calculation.");
252 indicesSetup_(false),
253 includeBaseNode_(false),
254 useElectrodeSpec_(false),
255 maskVarsTIAFlag_(false),
256 scaleDensityToMaxDoping_(true),
257 densityScalarFraction_(1.0e-1),
258 useVoltageOutputOffset_(true),
259 offsetWithFirstElectrode_(false),
261 useLayerCompositeDoping_(false),
276 junctionArea(1.0e-5),
279 useOldNiGiven(false),
280 dopingFileName(
"NOFILE"),
281 ndopeFileName(
"NOFILE"),
282 pdopeFileName(
"NOFILE"),
303 baseLocation(0.5e-3),
304 baseLocationGiven(false),
306 gradedJunctionFlag(false),
307 bjtEnableFlag(false),
308 displCurrentFlag(false),
309 calledBeforeUIVB(false),
313 lastOutputTime(-10.0),
315 outputIntervalGiven(false),
317 outputNLPoisson(false),
322 includeAugerRecomb(true),
323 includeSRHRecomb(true),
324 fermiDiracFlag(false),
325 thermionicEmissionFlag(false),
326 tunnelingModelName(
"none"),
328 #ifdef Xyce_DEBUG_DEVICE
330 anodeIndex_userGiven(false),
331 cathodeIndex_user(0),
332 cathodeIndex_userGiven(false),
336 enableContinuationCalled(false),
337 dirichletBCFlag(false),
338 columnReorderingFlag(false),
339 layerCompositeSpecified(false)
362 UserFatal(*
this) <<
"Too many external nodes are set! Set no more than 3.";
372 if (
given(
"PDOPE_FILE") && !
given(
"NDOPE_FILE") )
374 std::string msg =
"Ndope file specified with no Pdope file. Exiting.";
375 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg);
378 if ( !
given(
"PDOPE_FILE") &&
given(
"NDOPE_FILE") )
380 std::string msg =
"Pdope file specified with no Ndope file. Exiting.";
381 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg);
388 if (
given(
"MESHFILE"))
390 std::string msg =
"Instance constructor."
391 "mesh file was specified. The 1D device doesn't need a mesh file."
392 " Either add a model statement of level=2, or get rid of the mesh"
393 " file specification.";
394 N_ERH_ErrorMgr::report( N_ERH_ErrorMgr::DEV_FATAL_0,msg);
402 if (
given(
"GNUPLOTLEVEL") && !
given(
"TECPLOTLEVEL"))
417 bool bsuccess =
true;
423 bs1 =
setupMesh (); bsuccess = bsuccess && bs1;
425 bs1 =
setupNodes (); bsuccess = bsuccess && bs1;
446 for (std::map<std::string, DopeInfo *>::iterator it =
dopeInfoMap.begin();
452 for (std::map<std::string, PDE_1DElectrode *>::iterator it =
electrodeMap.begin();
459 for (
int i=0;i<size;++i)
482 if (compositeName ==
"DOPINGPROFILES" || compositeName ==
"REGION")
488 else if (compositeName ==
"NODE" || compositeName ==
"ELECTRODE")
491 ExtendedString electrodeName = paramName;
492 electrodeName.toUpper ();
494 bc.
eName = electrodeName;
495 bc.
nName = paramName;
499 if (electrodeName ==
"ANODE")
517 else if (compositeName ==
"LAYER")
522 return (static_cast<CompositeParam *> (matPtr));
527 "Instance::constructComposite: unrecognized composite name: ";
528 msg += compositeName;
529 N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
665 int collectorIndex=0;
667 bcVec[collectorIndex].eName =
"collector";
669 bcVec[collectorIndex].VequGiven =
given(
"COLLECTOR.BC");
671 bcVec[collectorIndex].areaGiven =
given(
"COLLECTOR.AREA");
672 bcVec[collectorIndex].meshIndex =
LX;
673 bcVec[collectorIndex].neighborNode =
LX-1;
679 bcVec[baseIndex].eName =
"base";
683 for (
int i=0;i<
NX;++i)
686 if (deltaX < minDelta)
694 bcVec[baseIndex].VequGiven =
given(
"BASE.BC");
696 bcVec[baseIndex].areaGiven =
given(
"BASE.AREA");
698 bcVec[baseIndex].meshIndex = bIndex;
699 bcVec[baseIndex].neighborNode =
bcVec[baseIndex].meshIndex-1;
705 bcVec[emitterIndex].eName =
"emitter";
707 bcVec[emitterIndex].VequGiven =
given(
"EMITTER.BC");
709 bcVec[emitterIndex].areaGiven =
given(
"EMITTER.AREA");
710 bcVec[emitterIndex].meshIndex = 0;
711 bcVec[emitterIndex].neighborNode = 1;
719 bcVec[anodeIndex].eName =
"anode";
721 bcVec[anodeIndex].VequGiven =
given(
"ANODE.BC");
723 bcVec[anodeIndex].areaGiven =
given(
"ANODE.AREA");
724 bcVec[anodeIndex].meshIndex = 0;
725 bcVec[anodeIndex].neighborNode = 1;
731 bcVec[cathodeIndex].eName =
"cathode";
733 bcVec[cathodeIndex].VequGiven =
given(
"CATHODE.BC");
735 bcVec[cathodeIndex].areaGiven =
given(
"CATHODE.AREA");
736 bcVec[cathodeIndex].meshIndex =
LX;
737 bcVec[cathodeIndex].neighborNode =
LX-1;
745 std::vector<int> tmpMeshSten(
NX,0);
747 for (
int iBC=0;iBC<
bcVec.size();++iBC)
755 ExtendedString side = electrode.
side;
759 bcVec[iBC].meshIndex = 0;
760 bcVec[iBC].neighborNode = 1;
763 else if (side ==
"right")
765 bcVec[iBC].meshIndex =
LX;
766 bcVec[iBC].neighborNode =
LX-1;
769 else if (side ==
"middle" || side ==
"mid")
772 double location = electrode.
location;
776 for (
int imesh=0;imesh<
NX;++imesh)
778 double deltaX=fabs(location-
xVec[imesh]);
779 if (deltaX < minDelta)
786 bcVec[iBC].meshIndex = bIndex;
787 bcVec[iBC].neighborNode = bIndex-1;
791 if (tmpMeshSten[bIndex] == 1)
793 std::string msg =
"Instance::setupNodes. Failed to find mesh index for " + bcVec[iBC].eName;
794 N_ERH_ErrorMgr::report( N_ERH_ErrorMgr::DEV_FATAL_0,msg);
799 std::string msg =
"Instance::setupNodes. unrecognized side specified.";
800 N_ERH_ErrorMgr::report( N_ERH_ErrorMgr::DEV_FATAL_0,msg);
809 bcVec[iBC].areaGiven = electrode.
areaGiven;
812 bcVec[iBC].area = electrode.
area;
819 #ifdef Xyce_DEBUG_DEVICE
822 Xyce::dout() <<
" area = " <<
area << std::endl;
823 Xyce::dout() <<
" areaGiven = " <<
given(
"AREA") << std::endl;
824 int isize=
bcVec.size();
825 for (
int i=0;i<isize;++i)
827 Xyce::dout() <<
" bcVec["<<i<<
"].area = " <<
bcVec[i].area << std::endl;
828 Xyce::dout() <<
" bcVec["<<i<<
"].areaGiven = " <<
bcVec[i].areaGiven << std::endl;
829 Xyce::dout() <<
" bcVec["<<i<<
"].meshIndex = " <<
bcVec[i].meshIndex << std::endl;
835 int bcSize=
bcVec.size();
836 for (
int i=0;i<bcSize;++i)
838 bcVec[i].colArray.resize(colmax,-1);
839 bcVec[i].dIdXcols.resize(colmax,-1);
840 bcVec[i].dIdX.resize(colmax,-1);
841 bcVec[i].dFdVckt.resize(colmax,0.0);
850 condVec[iE].resize(numElectrodes,0.0);
858 for (
int i=0;i<bcSize;++i)
860 int meshIndex=
bcVec[i].meshIndex;
862 if (meshIndex==0 || meshIndex==
LX)
890 bool compositeGiven=
true;
896 for (
int i=0;i<matVecSize;++i)
902 matLay.
LX = matLay.
NX-1;
917 std::string msg =
"Instance constructor."
918 " NX parameter was not specified.";
919 N_ERH_ErrorMgr::report( N_ERH_ErrorMgr::DEV_FATAL_0,msg);
941 int baseIndex_m1 = 0;
942 int baseIndex_p1 = 0;
967 int bcSize=
bcVec.size();
969 for (
int iBC=0;iBC<bcSize;++iBC)
971 int meshIndex=
bcVec[iBC].meshIndex;
976 for (
int i=0;i<
NX;++i)
985 for (iBC=0;iBC<
bcVec.size();++iBC)
987 iMeshNode =
bcVec[iBC].meshIndex;
991 std::string msg =
"Instance::setupJacStamp:";
992 msg +=
"Boundary point not in the stencil.";
993 N_ERH_ErrorMgr::report( N_ERH_ErrorMgr::DEV_FATAL,msg);
996 int iNN =
bcVec[iBC].neighborNode;
997 baseIndex = numVars*
meshToLID[iMeshNode ] + extVarOffset;
998 Vindex = baseIndex + Voffset;
999 Nindex = baseIndex + Noffset;
1000 Pindex = baseIndex + Poffset;
1002 if (iMeshNode > iNN)
1004 baseIndex_m1 = numVars*
meshToLID[iMeshNode-1] + extVarOffset;
1006 Vindex_m1 = baseIndex_m1 + Voffset;
1007 Nindex_m1 = baseIndex_m1 + Noffset;
1008 Pindex_m1 = baseIndex_m1 + Poffset;
1022 baseIndex_p1 = numVars*
meshToLID[iMeshNode+1] + extVarOffset;
1024 Vindex_p1 = baseIndex_p1 + Voffset;
1025 Nindex_p1 = baseIndex_p1 + Noffset;
1026 Pindex_p1 = baseIndex_p1 + Poffset;
1044 for (iBC=0;iBC<
bcVec.size();++iBC)
1046 iMeshNode =
bcVec[iBC].meshIndex;
1047 int iNN =
bcVec[iBC].neighborNode;
1050 baseIndex = numVars*
meshToLID[iMeshNode ] + extVarOffset;
1051 Vindex = baseIndex + Voffset;
1052 Nindex = baseIndex + Noffset;
1053 Pindex = baseIndex + Poffset;
1061 if (iMeshNode < iNN)
1063 baseIndex_p1 = numVars*
meshToLID[iMeshNode+1] + extVarOffset;
1064 Vindex_p1 = baseIndex_p1 + Voffset;
1065 Nindex_p1 = baseIndex_p1 + Noffset;
1066 Pindex_p1 = baseIndex_p1 + Poffset;
1069 jacStamp[Vindex][col++] = NodeIndex;
1071 jacStamp[Vindex][col++] = Vindex_p1;
1075 jacStamp[Nindex][col++] = Nindex_p1;
1077 jacStamp[Nindex][col++] = Pindex_p1;
1081 jacStamp[Pindex][col++] = Pindex_p1;
1083 jacStamp[Pindex][col++] = Nindex_p1;
1087 baseIndex_m1 = numVars*
meshToLID[iMeshNode-1] + extVarOffset;
1088 Vindex_m1 = baseIndex_m1 + Voffset;
1089 Nindex_m1 = baseIndex_m1 + Noffset;
1090 Pindex_m1 = baseIndex_m1 + Poffset;
1093 jacStamp[Vindex][col++] = Vindex_m1;
1095 jacStamp[Vindex][col++] = NodeIndex;
1098 jacStamp[Nindex][col++] = Nindex_m1;
1100 jacStamp[Nindex][col++] = Pindex_m1;
1104 jacStamp[Pindex][col++] = Pindex_m1;
1106 jacStamp[Pindex][col++] = Nindex_m1;
1117 baseIndex_m1 = numVars*
meshToLID[iMeshNode-1] + extVarOffset;
1118 baseIndex = numVars*
meshToLID[iMeshNode ] + extVarOffset;
1119 baseIndex_p1 = numVars*
meshToLID[iMeshNode+1] + extVarOffset;
1121 Vindex_m1 = baseIndex_m1 + Voffset;
1122 Nindex_m1 = baseIndex_m1 + Noffset;
1123 Pindex_m1 = baseIndex_m1 + Poffset;
1124 Vindex = baseIndex + Voffset;
1125 Nindex = baseIndex + Noffset;
1126 Pindex = baseIndex + Poffset;
1127 Vindex_p1 = baseIndex_p1 + Voffset;
1128 Nindex_p1 = baseIndex_p1 + Noffset;
1129 Pindex_p1 = baseIndex_p1 + Poffset;
1134 jacStamp[Vindex][col++] = NodeIndex;
1135 jacStamp[Vindex][col++] = Vindex_m1;
1137 jacStamp[Vindex][col++] = Vindex_p1;
1144 jacStamp[Nindex][col++] = Nindex_m1;
1146 jacStamp[Nindex][col++] = Nindex_p1;
1147 jacStamp[Nindex][col++] = Vindex_m1;
1149 jacStamp[Nindex][col++] = Vindex_p1;
1150 jacStamp[Nindex][col++] = Pindex_m1;
1152 jacStamp[Nindex][col++] = Pindex_p1;
1157 jacStamp[Pindex][col++] = Pindex_m1;
1159 jacStamp[Pindex][col++] = Pindex_p1;
1160 jacStamp[Pindex][col++] = Vindex_m1;
1162 jacStamp[Pindex][col++] = Vindex_p1;
1163 jacStamp[Pindex][col++] = Nindex_m1;
1165 jacStamp[Pindex][col++] = Nindex_p1;
1170 std::string msg =
"Instance::setupJacStamp:";
1171 msg +=
"Boundary point not in the stencil.";
1172 N_ERH_ErrorMgr::report( N_ERH_ErrorMgr::DEV_FATAL,msg);
1177 for (iMeshNode=0;iMeshNode<
NX;++iMeshNode)
1181 baseIndex_m1 = numVars*
meshToLID[iMeshNode-1] + extVarOffset;
1182 baseIndex = numVars*
meshToLID[iMeshNode ] + extVarOffset;
1183 baseIndex_p1 = numVars*
meshToLID[iMeshNode+1] + extVarOffset;
1185 Vindex_m1 = baseIndex_m1 + Voffset;
1186 Nindex_m1 = baseIndex_m1 + Noffset;
1187 Pindex_m1 = baseIndex_m1 + Poffset;
1188 Vindex = baseIndex + Voffset;
1189 Nindex = baseIndex + Noffset;
1190 Pindex = baseIndex + Poffset;
1191 Vindex_p1 = baseIndex_p1 + Voffset;
1192 Nindex_p1 = baseIndex_p1 + Noffset;
1193 Pindex_p1 = baseIndex_p1 + Poffset;
1198 jacStamp[Vindex][col++] = Vindex_m1;
1200 jacStamp[Vindex][col++] = Vindex_p1;
1207 jacStamp[Nindex][col++] = Nindex_m1;
1209 jacStamp[Nindex][col++] = Nindex_p1;
1210 jacStamp[Nindex][col++] = Vindex_m1;
1212 jacStamp[Nindex][col++] = Vindex_p1;
1213 jacStamp[Nindex][col++] = Pindex_m1;
1215 jacStamp[Nindex][col++] = Pindex_p1;
1220 jacStamp[Pindex][col++] = Pindex_m1;
1222 jacStamp[Pindex][col++] = Pindex_p1;
1223 jacStamp[Pindex][col++] = Vindex_m1;
1225 jacStamp[Pindex][col++] = Vindex_p1;
1226 jacStamp[Pindex][col++] = Nindex_m1;
1228 jacStamp[Pindex][col++] = Nindex_p1;
1231 #ifdef Xyce_DEBUG_DEVICE
1236 Xyce::dout() <<
"jacStamp size = " << jacSize << std::endl;
1238 for(
int i=0;i<jacSize;++i)
1241 for (
int j=0;j<colSize;++j)
1243 Xyce::dout() <<
" jacStamp["<<i<<
"]["<<j<<
"] = " <<
jacStamp[i][j] << std::endl;
1272 int mapSize =
jacMap.size();
1273 for (
int i=0;i<mapSize;++i)
1277 for (
int j=0;j<
jacStamp[i].size();++j)
1291 std::vector< std::vector<int> > tempStamp_eric;
1292 std::vector< std::vector<int> > tempMap2_eric;
1319 for (itmp=0;itmp<128;++itmp) tmpchar[itmp] = 0;
1322 for (itmp=0;itmp<
NX;++itmp)
1326 std::ostringstream oss;
1327 oss <<
getName() <<
"_V_" << itmp;
1333 std::ostringstream oss;
1334 oss <<
getName() <<
"_N_" << itmp;
1340 std::ostringstream oss;
1341 oss <<
getName() <<
"_P_" << itmp;
1359 const std::vector<int> & extLIDVecRef)
1364 #ifdef Xyce_DEBUG_DEVICE
1367 Xyce::dout() << section_divider << std::endl;
1368 Xyce::dout() <<
"Instance::registerLIDs:\n";
1369 Xyce::dout() <<
" name = " <<
getName() << std::endl;
1370 Xyce::dout() <<
" numInt = " <<
numIntVars << std::endl;
1371 Xyce::dout() <<
" numEXt = " <<
numExtVars << std::endl;
1372 Xyce::dout() <<
" NX = " <<
NX << std::endl;
1380 for (
int iBC=0;iBC<
bcVec.size();++iBC)
1398 for (
int iBC=0;iBC<
bcVec.size();++iBC)
1400 meshIndex =
bcVec[iBC].meshIndex;
1409 for (meshIndex=0;meshIndex<
NX;++meshIndex)
1418 #ifdef Xyce_DEBUG_DEVICE
1422 Xyce::dout() <<
"\n solution indices:\n";
1424 for (
int i=0;i<
NX;++i)
1426 Xyce::dout() <<
" li_Vrowarray["<<i<<
"] = " <<
li_Vrowarray[i];
1427 Xyce::dout() <<
"\tli_Nrowarray["<<i<<
"] = " <<
li_Nrowarray[i];
1428 Xyce::dout() <<
"\tli_Prowarray["<<i<<
"] = " <<
li_Prowarray[i] << std::endl;
1430 Xyce::dout() << section_divider << std::endl;
1448 #ifdef Xyce_DEBUG_DEVICE
1451 Xyce::dout() << std::endl;
1452 Xyce::dout() << section_divider << std::endl;
1453 Xyce::dout() <<
" In Instance::registerStateLIDs\n\n";
1454 Xyce::dout() <<
" name = " <<
getName() << std::endl;
1455 Xyce::dout() <<
" Number of State LIDs: " <<
numStateVars << std::endl;
1464 for (i=0;i<
bcVec.size();++i)
1469 for (i=0,j=2;i<
NX-1;++i,++j)
1474 #ifdef Xyce_DEBUG_DEVICE
1477 Xyce::dout() <<
" State indices:" << std::endl;
1478 Xyce::dout() << std::endl;
1479 for (i=0;i<
bcVec.size();++i)
1481 Xyce::dout() <<
"bcVec["<<i<<
"].li_stateC = "<<
bcVec[i].li_stateC<< std::endl;
1483 Xyce::dout() << std::endl;
1485 Xyce::dout() <<
" Displacement current state variable local indices:" << std::endl;
1486 for (i=0;i<NX-1;++i)
1488 Xyce::dout() <<
" li_stateDispl["<<i<<
"] = " <<
li_stateDispl[i] << std::endl;
1490 Xyce::dout() << section_divider << std::endl;
1517 (
const std::vector< std::vector<int> > & jacLIDVec )
1530 #ifdef Xyce_DEBUG_DEVICE
1534 int extVarOffset = numExtVars;
1536 #ifdef Xyce_DEBUG_DEVICE
1537 if (getDeviceOptions().debugLevel > 0)
1539 Xyce::dout() << section_divider << std::endl;
1540 Xyce::dout() <<
"Instance::registerJacLIDs" << std::endl;
1542 int jacLIDSize = jacLIDVec.size();
1543 Xyce::dout() <<
"jacLIDSize = " << jacLIDSize << std::endl;
1544 for (i=0;i<jacLIDSize;++i)
1546 int jacLIDcolSize = jacLIDVec[i].size();
1547 Xyce::dout() << std::endl;
1548 Xyce::dout() <<
"jacLIDVec["<<i<<
"].size = " << jacLIDcolSize << std::endl;
1549 for (j=0;j<jacLIDcolSize;++j)
1551 Xyce::dout() <<
"jacLIDVec["<<i<<
"]["<<j<<
"] = ";
1552 Xyce::dout() << jacLIDVec[i][j] << std::endl;
1558 li_Vcolarray.resize(NX);
1559 li_Ncolarray.resize(NX);
1560 li_Pcolarray.resize(NX);
1563 for (
int iBC=0;iBC<bcVec.size();++iBC)
1566 int numCols = jacLIDVec[iBC].size();
1567 bcVec[iBC].li_colArray.resize(numCols,-1);
1569 for (i1=0;i1<numCols;++i1)
1571 bcVec[iBC].li_colArray[i1] = jacLIDVec[iBC][i1];
1574 int iMeshNode = bcVec[iBC].meshIndex;
1576 bcVec[iBC].lidOffset = jacLIDVec[iBC][0];
1578 #ifdef Xyce_DEBUG_DEVICE
1579 if (getDeviceOptions().debugLevel > 0)
1581 Xyce::dout() << std::endl;
1582 for(i=0;i<bcVec[iBC].li_colArray.size();++i)
1584 Xyce::dout() << bcVec[iBC].eName <<
": li_colArray["<<i<<
"] = "<<bcVec[iBC].li_colArray[i]<< std::endl;
1586 Xyce::dout() << std::endl;
1592 for (iMeshNode=0;iMeshNode<NX;++iMeshNode)
1594 if (boundarySten[iMeshNode]==1)
continue;
1596 baseIndex = numVars*meshToLID[iMeshNode ] + extVarOffset;
1598 Vindex = baseIndex + Voffset;
1599 Nindex = baseIndex + Noffset;
1600 Pindex = baseIndex + Poffset;
1605 li_Vcolarray[iMeshNode].resize(5,-1);
1606 li_Vcolarray[iMeshNode][i1++] = jacLIDVec[Vindex][j1++];
1607 li_Vcolarray[iMeshNode][i1++] = jacLIDVec[Vindex][j1++];
1608 li_Vcolarray[iMeshNode][i1++] = jacLIDVec[Vindex][j1++];
1609 li_Vcolarray[iMeshNode][i1++] = jacLIDVec[Vindex][j1++];
1610 li_Vcolarray[iMeshNode][i1++] = jacLIDVec[Vindex][j1++];
1614 li_Ncolarray[iMeshNode].resize(9,-1);
1615 li_Ncolarray[iMeshNode][i1++] = jacLIDVec[Nindex][j1++];
1616 li_Ncolarray[iMeshNode][i1++] = jacLIDVec[Nindex][j1++];
1617 li_Ncolarray[iMeshNode][i1++] = jacLIDVec[Nindex][j1++];
1618 li_Ncolarray[iMeshNode][i1++] = jacLIDVec[Nindex][j1++];
1619 li_Ncolarray[iMeshNode][i1++] = jacLIDVec[Nindex][j1++];
1620 li_Ncolarray[iMeshNode][i1++] = jacLIDVec[Nindex][j1++];
1621 li_Ncolarray[iMeshNode][i1++] = jacLIDVec[Nindex][j1++];
1622 li_Ncolarray[iMeshNode][i1++] = jacLIDVec[Nindex][j1++];
1623 li_Ncolarray[iMeshNode][i1++] = jacLIDVec[Nindex][j1++];
1628 li_Pcolarray[iMeshNode].resize(9,-1);
1629 li_Pcolarray[iMeshNode][i1++] = jacLIDVec[Pindex][j1++];
1630 li_Pcolarray[iMeshNode][i1++] = jacLIDVec[Pindex][j1++];
1631 li_Pcolarray[iMeshNode][i1++] = jacLIDVec[Pindex][j1++];
1632 li_Pcolarray[iMeshNode][i1++] = jacLIDVec[Pindex][j1++];
1633 li_Pcolarray[iMeshNode][i1++] = jacLIDVec[Pindex][j1++];
1634 li_Pcolarray[iMeshNode][i1++] = jacLIDVec[Pindex][j1++];
1635 li_Pcolarray[iMeshNode][i1++] = jacLIDVec[Pindex][j1++];
1636 li_Pcolarray[iMeshNode][i1++] = jacLIDVec[Pindex][j1++];
1637 li_Pcolarray[iMeshNode][i1++] = jacLIDVec[Pindex][j1++];
1639 #ifdef Xyce_DEBUG_DEVICE
1640 if (getDeviceOptions().debugLevel > 0)
1642 Xyce::dout() << std::endl;
1643 Xyce::dout() <<
"registerJacLIDs: iMeshNode = " << iMeshNode << std::endl;
1644 Xyce::dout() <<
"jacLIDVec[Vindex].size = " << jacLIDVec[Vindex].size()<<std::endl;
1645 Xyce::dout() <<
"jacLIDVec[Nindex].size = " << jacLIDVec[Nindex].size()<<std::endl;
1646 Xyce::dout() <<
"jacLIDVec[Pindex].size = " << jacLIDVec[Pindex].size()<<std::endl;
1650 Xyce::dout() <<
" li_Vcolarray["<<iMeshNode<<
"]["<<i<<
"] = ";
1651 Xyce::dout() << li_Vcolarray[iMeshNode][i] << std::endl;
1653 Xyce::dout() << std::endl;
1656 Xyce::dout() <<
" li_Ncolarray["<<iMeshNode<<
"]["<<i<<
"] = ";
1657 Xyce::dout() << li_Ncolarray[iMeshNode][i] << std::endl;
1659 Xyce::dout() << std::endl;
1662 Xyce::dout() <<
" li_Pcolarray["<<iMeshNode<<
"]["<<i<<
"] = ";
1663 Xyce::dout() << li_Pcolarray[iMeshNode][i] << std::endl;
1665 Xyce::dout() << std::endl;
1671 for (
int iBC=0;iBC<bcVec.size();++iBC)
1673 iMeshNode = bcVec[iBC].meshIndex;
1674 int iNN = bcVec[iBC].neighborNode;
1676 baseIndex = numVars*meshToLID[iMeshNode ] + extVarOffset;
1677 Vindex = baseIndex + Voffset;
1678 Nindex = baseIndex + Noffset;
1679 Pindex = baseIndex + Poffset;
1681 if (edgeBoundarySten[iMeshNode]==1)
1685 li_Vcolarray[iMeshNode].resize(3,-1);
1686 li_Vcolarray[iMeshNode][i1++] = jacLIDVec[Vindex][j1++];
1687 li_Vcolarray[iMeshNode][i1++] = jacLIDVec[Vindex][j1++];
1688 li_Vcolarray[iMeshNode][i1++] = jacLIDVec[Vindex][j1++];
1691 if (iMeshNode < iNN)
1694 li_Ncolarray[iMeshNode].resize(3,-1);
1695 li_Ncolarray[iMeshNode][i1++] = -1;
1696 li_Ncolarray[iMeshNode][i1++] = jacLIDVec[Nindex][j1++];
1697 li_Ncolarray[iMeshNode][i1++] = jacLIDVec[Nindex][j1++];
1700 li_Pcolarray[iMeshNode].resize(3,-1);
1701 li_Pcolarray[iMeshNode][i1++] = -1;
1702 li_Pcolarray[iMeshNode][i1++] = jacLIDVec[Pindex][j1++];
1703 li_Pcolarray[iMeshNode][i1++] = jacLIDVec[Pindex][j1++];
1708 li_Ncolarray[iMeshNode].resize(3,-1);
1709 li_Ncolarray[iMeshNode][i1++] = jacLIDVec[Nindex][j1++];
1710 li_Ncolarray[iMeshNode][i1++] = jacLIDVec[Nindex][j1++];
1713 li_Pcolarray[iMeshNode].resize(3,-1);
1714 li_Pcolarray[iMeshNode][i1++] = jacLIDVec[Pindex][j1++];
1715 li_Pcolarray[iMeshNode][i1++] = jacLIDVec[Pindex][j1++];
1718 else if (internalBoundarySten[iMeshNode]==1)
1723 li_Vcolarray[iMeshNode].resize(6,-1);
1724 li_Vcolarray[iMeshNode][i1++] = jacLIDVec[Vindex][j1++];
1725 li_Vcolarray[iMeshNode][i1++] = jacLIDVec[Vindex][j1++];
1726 li_Vcolarray[iMeshNode][i1++] = jacLIDVec[Vindex][j1++];
1727 li_Vcolarray[iMeshNode][i1++] = jacLIDVec[Vindex][j1++];
1728 li_Vcolarray[iMeshNode][i1++] = jacLIDVec[Vindex][j1++];
1729 li_Vcolarray[iMeshNode][i1++] = jacLIDVec[Vindex][j1++];
1733 li_Ncolarray[iMeshNode].resize(9,-1);
1734 li_Ncolarray[iMeshNode][i1++] = jacLIDVec[Nindex][j1++];
1735 li_Ncolarray[iMeshNode][i1++] = jacLIDVec[Nindex][j1++];
1736 li_Ncolarray[iMeshNode][i1++] = jacLIDVec[Nindex][j1++];
1737 li_Ncolarray[iMeshNode][i1++] = jacLIDVec[Nindex][j1++];
1738 li_Ncolarray[iMeshNode][i1++] = jacLIDVec[Nindex][j1++];
1739 li_Ncolarray[iMeshNode][i1++] = jacLIDVec[Nindex][j1++];
1740 li_Ncolarray[iMeshNode][i1++] = jacLIDVec[Nindex][j1++];
1741 li_Ncolarray[iMeshNode][i1++] = jacLIDVec[Nindex][j1++];
1742 li_Ncolarray[iMeshNode][i1++] = jacLIDVec[Nindex][j1++];
1746 li_Pcolarray[iMeshNode].resize(9,-1);
1747 li_Pcolarray[iMeshNode][i1++] = jacLIDVec[Pindex][j1++];
1748 li_Pcolarray[iMeshNode][i1++] = jacLIDVec[Pindex][j1++];
1749 li_Pcolarray[iMeshNode][i1++] = jacLIDVec[Pindex][j1++];
1750 li_Pcolarray[iMeshNode][i1++] = jacLIDVec[Pindex][j1++];
1751 li_Pcolarray[iMeshNode][i1++] = jacLIDVec[Pindex][j1++];
1752 li_Pcolarray[iMeshNode][i1++] = jacLIDVec[Pindex][j1++];
1753 li_Pcolarray[iMeshNode][i1++] = jacLIDVec[Pindex][j1++];
1754 li_Pcolarray[iMeshNode][i1++] = jacLIDVec[Pindex][j1++];
1755 li_Pcolarray[iMeshNode][i1++] = jacLIDVec[Pindex][j1++];
1759 std::string msg =
"Instance::registerJacLIDs:";
1760 msg +=
"Boundary point not in the stencil.";
1761 N_ERH_ErrorMgr::report( N_ERH_ErrorMgr::DEV_FATAL,msg);
1764 #ifdef Xyce_DEBUG_DEVICE
1765 if (getDeviceOptions().debugLevel > 0)
1767 Xyce::dout() << std::endl;
1768 Xyce::dout() <<
"registerJacLIDs: ("<<bcVec[iBC].eName<<
") iMeshNode = ";
1769 Xyce::dout() << iMeshNode << std::endl;
1772 Xyce::dout() <<
" li_Vcolarray["<<iMeshNode<<
"]["<<i<<
"] = ";
1773 Xyce::dout() << li_Vcolarray[iMeshNode][i] << std::endl;
1775 Xyce::dout() << std::endl;
1778 Xyce::dout() <<
" li_Ncolarray["<<iMeshNode<<
"]["<<i<<
"] = ";
1779 Xyce::dout() << li_Ncolarray[iMeshNode][i] << std::endl;
1781 Xyce::dout() << std::endl;
1784 Xyce::dout() <<
" li_Pcolarray["<<iMeshNode<<
"]["<<i<<
"] = ";
1785 Xyce::dout() << li_Pcolarray[iMeshNode][i] << std::endl;
1787 Xyce::dout() << std::endl;
1818 for (
int i=0;i<
NX;++i)
1827 for (
int j=0;j<vSize;++j)
1836 for (
int j=0;j<nSize;++j)
1845 for (
int j=0;j<pSize;++j)
1864 bool bsuccess =
true;
1867 #ifdef Xyce_DEBUG_DEVICE
1870 Xyce::dout() << section_divider << std::endl;
1871 Xyce::dout() <<
"updateIntermediateVars. name = " <<
getName() << std::endl;
1876 bs1 =
calcEfield (); bsuccess = bsuccess && bs1;
1882 #ifdef Xyce_DEBUG_DEVICE
1885 Xyce::dout() << section_divider << std::endl;
1908 bool bsuccess =
true;
1914 for (iBC=0;iBC<
bcVec.size();++iBC)
1916 int index =
bcVec[iBC].meshIndex;
1917 int iNN=
bcVec[iBC].neighborNode;
1919 double A0=J0*a0*
area;
1921 double sign = ((iNN > index)?1.0:-1.0);
1922 int edgeIndex= ((iNN > index)?index:iNN);
1924 bcVec[iBC].elecCurrent = sign*
JnxVec[edgeIndex]*A0;
1925 bcVec[iBC].holeCurrent = sign*
JpxVec[edgeIndex]*A0;
1929 bcVec[iBC].currentSum =
bcVec[iBC].elecCurrent +
bcVec[iBC].holeCurrent;
1933 std::string & type =
bcVec[iBC].type;
1938 bcVec[iBC].currentSum =
bcVec[iBC].elecCurrent;
1940 else if (type==
"ptype")
1942 bcVec[iBC].currentSum =
bcVec[iBC].holeCurrent;
1946 std::string msg =
"Instance::calcTerminalCurrents";
1947 msg +=
"Unrecognized type on boundary.";
1948 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg);
1953 std::string msg =
"Instance::calcTerminalCurrents";
1954 msg +=
"Unrecognized boundary.";
1955 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg);
1960 bcVec[iBC].currentSum +=
bcVec[iBC].displCurrent;
1964 #ifdef Xyce_DEBUG_DEVICE
1967 Xyce::dout() << Xyce::subsection_divider << std::endl
1968 <<
"Calculated currents, etc., coming from the DD calculation:" << std::endl
1969 <<
" scalingVars.J0 = " << J0<<std::endl
1970 <<
" scalingVars.a0 = " << a0<<std::endl
1971 << Xyce::subsection_divider << std::endl;
1972 for (
int iBC=0;iBC<
bcVec.size();++iBC)
1974 Xyce::dout() <<
bcVec[iBC];
1976 Xyce::dout() << Xyce::subsection_divider << std::endl;
2030 int bcSize =
bcVec.size();
2031 for (iBC=0; iBC < bcSize; ++iBC)
2033 bcVec[iBC].dIdVckt = 0.0;
2039 for (iBC=0;iBC<
bcVec.size();++iBC)
2041 int iN =
bcVec[iBC].meshIndex;
2042 int iNN =
bcVec[iBC].neighborNode;
2043 int dFdVcktIndex = 0;
2059 for (iBC=0;iBC<bcSize;++iBC)
2062 i=
bcVec[iBC].meshIndex;
2066 std::string msg =
"Instance::pdTerminalCurrents";
2067 msg +=
"Unrecognized boundary.";
2068 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg);
2071 int iNN=
bcVec[iBC].neighborNode;
2073 double A0=J0*a0*
area;
2074 std::vector<int> & colA =
bcVec[iBC].li_colArray;
2076 double sign = ((iNN > i)?1.0:-1.0);
2082 double dJndV_nn = 0.0;
2083 double dJpdV_nn = 0.0;
2084 double dJndn_nn = 0.0;
2085 double dJpdp_nn = 0.0;
2118 double Vcoef = (sign* dJndV + sign* dJpdV)*A0;
2119 double Ncoef = (sign* dJndn)*A0;
2120 double Pcoef = (sign* dJpdp)*A0;
2123 double Vcoef_nn = (sign* dJndV_nn + sign* dJpdV_nn)*A0;
2124 double Ncoef_nn = (sign* dJndn_nn)*A0;
2125 double Pcoef_nn = (sign* dJpdp_nn)*A0;
2129 std::string & type =
bcVec[iBC].type;
2137 else if (type==
"ptype")
2144 std::string msg =
"Instance::pdTerminalCurrents";
2145 msg +=
"Unrecognized type on boundary.";
2146 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg);
2156 if (
bcVec[iBC].li_colArray[liOffIndex] != -1)
2158 bcVec[iBC].dIdXcols[count] =
bcVec[iBC].li_colArray[liOffIndex];
2159 bcVec[iBC].dIdX[count] = Vcoef;
2165 if (
bcVec[iBC].li_colArray[liOffIndex] != -1)
2167 bcVec[iBC].dIdXcols[count] =
bcVec[iBC].li_colArray[liOffIndex];
2168 bcVec[iBC].dIdX[count] = Vcoef_nn;
2174 if (
bcVec[iBC].li_colArray[liOffIndex] != -1)
2176 bcVec[iBC].dIdXcols[count] =
bcVec[iBC].li_colArray[liOffIndex];
2177 bcVec[iBC].dIdX[count] = Ncoef;
2183 if (
bcVec[iBC].li_colArray[liOffIndex] != -1)
2185 bcVec[iBC].dIdXcols[count] =
bcVec[iBC].li_colArray[liOffIndex];
2186 bcVec[iBC].dIdX[count] = Ncoef_nn;
2192 if (
bcVec[iBC].li_colArray[liOffIndex] != -1)
2194 bcVec[iBC].dIdXcols[count] =
bcVec[iBC].li_colArray[liOffIndex];
2195 bcVec[iBC].dIdX[count] = Pcoef;
2201 if (
bcVec[iBC].li_colArray[liOffIndex] != -1)
2203 bcVec[iBC].dIdXcols[count] =
bcVec[iBC].li_colArray[liOffIndex];
2204 bcVec[iBC].dIdX[count] = Pcoef_nn;
2239 bool bsuccess =
true;
2241 N_LAS_Vector & dfdv = *(dfdvPtr);
2298 bool bsuccess =
true;
2299 const N_LAS_Vector & dxdv = *dxdvPtr;
2301 #ifdef Xyce_DEBUG_DEVICE
2302 char filename1[256];
2304 for (
int ich = 0; ich < 256; ++ich)
2305 { filename1[ich] = 0; }
2309 Xyce::dout() << section_divider <<
"\n";
2310 Xyce::dout() <<
"calcConductances name = " <<
getName() << std::endl;
2311 Xyce::dout() <<
"electrode = " <<
bcVec[iElectrode].eName;
2312 Xyce::dout() <<
" dIdVckt = " <<
bcVec[iElectrode].dIdVckt;
2313 Xyce::dout() << std::endl;
2314 Xyce::dout() << std::endl;
2318 if (!(
bcVec[iElectrode].dxdvAllocated))
2321 bcVec[iElectrode].dxdvAllocated =
true;
2327 *(
bcVec[iElectrode].dxdvPtr) = *(dxdvPtr);
2334 double dIidVj = 0.0;
2335 double dIidVj_chain = 0.0;
2351 if (iElectrode != iEqu) dIidVj = 0.0;
2352 else dIidVj =
bcVec[iEqu].dIdVckt;
2356 int DIDXSize =
bcVec[iEqu].dIdX.size();
2357 for (
int iDIDX=0;iDIDX<DIDXSize;++iDIDX)
2359 int index =
bcVec[iEqu].dIdXcols[iDIDX];
2360 double coef =
bcVec[iEqu].dIdX[iDIDX];
2362 if (index < 0)
continue;
2367 #ifdef Xyce_DEBUG_DEVICE
2368 sprintf(filename1,
"dIdX%02d.txt", iEqu);
2375 Gij = dIidVj_chain + dIidVj;
2377 condVec[iEqu][iElectrode] = Gij;
2379 #ifdef Xyce_DEBUG_DEVICE
2382 char outstring[128];
2383 double Itmp =
bcVec[iEqu].currentSum;
2384 double Vtmp =
bcVec[iEqu].Vckt -
bcVec[iElectrode].Vckt;
2386 double GV = Gij*Vtmp;
2387 for(
int i=0;i<128;++i) outstring[i] = static_cast<char>(0);
2389 "(%2d,%2d): dotPr=%12.4e G=%12.4e",
2390 iEqu,iElectrode,dIidVj_chain,Gij);
2391 Xyce::dout() << std::string(outstring) << std::endl;
2394 "(%2d,%2d): G=%12.4e G*V=%12.4e I=%12.4e V=%12.4e",
2395 iEqu,iElectrode,Gij,GV,Itmp,Vtmp);
2396 Xyce::dout() << std::string(outstring) << std::endl;
2401 #ifdef Xyce_DEBUG_DEVICE
2404 Xyce::dout() << section_divider << std::endl;
2422 bool bsuccess =
true;
2426 for (
int iBC=0;iBC<
bcVec.size();++iBC)
2428 int li_state=
bcVec[iBC].li_stateC;
2429 staVector[li_state] =
bcVec[iBC].currentSum;
2435 for (i = 0; i<
NX-1; ++i)
2454 bool bsuccess =
true;
2459 for(
int i = 0; i<
NX-1; ++i)
2494 for (
int i=0;i<
NX;++i)
2497 (*maskVectorPtr)[Vrow] = 0.0;
2498 (*maskVectorPtr)[Vrow] = 0.0;
2516 bool bsuccess =
true;
2544 bool bsuccess =
true;
2546 int Vrow(-1), Nrow(-1), Prow(-1);
2558 for (
int iBC=0;iBC<
bcVec.size();++iBC)
2560 int i =
bcVec[iBC].meshIndex;
2567 rhs[Vrow] +=
VVec[i] - (
bcVec[iBC].Vequ);
2574 for (
int ihet=0;ihet<hetSize;++ihet)
2613 coef2 = -(holeDens-elecDens+
CVec[i]);
2636 bool bsuccess =
true;
2638 int Vrow, Nrow, Prow;
2646 for (
int iBC=0;iBC<
bcVec.size();++iBC)
2648 rhs[
bcVec[iBC].lid] += bcVec[iBC].currentSum;
2656 for (
int iBC=0;iBC<
bcVec.size();++iBC)
2658 int i =
bcVec[iBC].meshIndex;
2672 std::string & type =
bcVec[iBC].type;
2680 else if (type==
"ptype")
2687 std::string msg =
"Instance::loadVecDDForm";
2688 msg +=
"Unrecognized type on boundary.";
2689 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg);
2694 std::string msg =
"Instance::loadVecDDForm";
2695 msg +=
"Unrecognized stencil on boundary.";
2696 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg);
2742 std::vector<N_UTL_BreakPoint> &breakPointTimes)
2760 bool bsuccess =
true;
2761 int Vrow, Nrow, Prow;
2765 double rUt = 1.0/
Ut;
2767 double elecDens, holeDens;
2775 for (iBC=0;iBC<
bcVec.size();++iBC)
2777 mat[
bcVec[iBC].lid][
bcVec[iBC].lidOffset] = 1.0;
2781 for (
int iBC=0;iBC<
bcVec.size();++iBC)
2783 int i =
bcVec[iBC].meshIndex;
2794 mat[Vrow][offset1] = 0.0;
2795 mat[Vrow][offset2] = 1.0;
2796 mat[Vrow][offset3] = 0.0;
2800 mat[Vrow][offset1] = 0.0;
2801 mat[Vrow][offset2] = 1.0;
2802 mat[Vrow][offset3] = 0.0;
2806 mat[Vrow][offset1] = 0.0;
2807 mat[Vrow][offset2] = 0.0;
2808 mat[Vrow][offset3] = 1.0;
2818 for (
int ihet=0;ihet<hetSize;++ihet)
2841 Xyce::dout() <<
"ihet="<<ihet<<
" perm1/dx1="<<perm1/dx1<<
" perm2/dx2="<<perm2/dx2;
2842 Xyce::dout() <<
" Vrow="<<Vrow<<
" Nrow="<<Nrow<<
" Prow="<<Prow<<std::endl;
2845 mat[Vrow][offset1] = perm1/dx1;
2846 mat[Vrow][offset2] = -perm1/dx1;
2847 mat[Vrow][offset3] = -perm2/dx2;
2858 mat[Nrow][li_Ncolarray[i2][1]] = 1.0;
2859 mat[Prow][li_Pcolarray[i2][1]] = 1.0;
2886 mat[Vrow][offset1] = -L0/(dx1*dx2);
2887 mat[Vrow][offset2] = 2.0*L0/(dx1*dx2) + rUt*holeDens + rUt*elecDens;
2888 mat[Vrow][offset3] = -L0/(dx1*dx2);
2920 for (iBC=0;iBC<
bcVec.size();++iBC)
2923 i=
bcVec[iBC].meshIndex;
2927 std::string msg =
"Instance::loadMatKCLForm";
2928 msg +=
"Unrecognized boundary.";
2929 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg);
2932 int iNN=
bcVec[iBC].neighborNode;
2933 li_row =
bcVec[iBC].lid;
2935 double A0=J0*a0*
area;
2936 std::vector<int> & colA =
bcVec[iBC].li_colArray;
2938 double sign = ((iNN > i)?1.0:-1.0);
2946 double dJndV_nn = 0.0;
2947 double dJpdV_nn = 0.0;
2948 double dJndn_nn = 0.0;
2949 double dJndp_nn = 0.0;
2950 double dJpdp_nn = 0.0;
2951 double dJpdn_nn = 0.0;
2992 double Vcoef = sign*(dJndV + dJpdV)*A0;
2993 double Ncoef = sign*(dJndn + dJpdn)*A0;
2994 double Pcoef = sign*(dJndp + dJpdp)*A0;
2997 double Vcoef_nn = sign*(dJndV_nn + dJpdV_nn)*A0;
2998 double Ncoef_nn = sign*(dJndn_nn + dJpdn_nn)*A0;
2999 double Pcoef_nn = sign*(dJndp_nn + dJpdp_nn)*A0;
3003 std::string & type =
bcVec[iBC].type;
3011 else if (type==
"ptype")
3018 std::string msg =
"Instance::loadMatKCLForm";
3019 msg +=
"Unrecognized type on boundary.";
3020 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg);
3026 mat[li_row][colA[liOffIndex++]] += Vcoef;
3029 mat[li_row][colA[liOffIndex++]] += Vcoef_nn;
3032 mat[li_row][colA[liOffIndex++]] += Ncoef;
3035 mat[li_row][colA[liOffIndex++]] += Ncoef_nn;
3038 mat[li_row][colA[liOffIndex++]] += Pcoef;
3041 mat[li_row][colA[liOffIndex++]] += Pcoef_nn;
3058 bool bsuccess =
true;
3063 for (iBC=0;iBC<
bcVec.size();++iBC)
3065 mat[
bcVec[iBC].lid][
bcVec[iBC].lidOffset] = 1.0;
3081 bool bsuccess =
true;
3084 int Vrow, Nrow, Prow;
3095 #ifdef Xyce_DEBUG_DEVICE
3098 for (
int i=1;i<
LX;++i)
3110 bsuccess = bsuccess && bs1;
3115 bsuccess = bsuccess && bs1;
3119 for (
int iBC=0;iBC<
bcVec.size();++iBC)
3121 int i =
bcVec[iBC].meshIndex;
3129 mat[Vrow][li_Vcolarray[i][1]] = 1.0;
3130 mat[Vrow][li_Vcolarray[i][2]] = 0.0;
3138 mat[Vrow][li_Vcolarray[i][1]] = 1.0;
3147 mat[Vrow][li_Vcolarray[i][2]] = 1.0;
3149 std::string & type =
bcVec[iBC].type;
3162 mat[Prow][li_Pcolarray[i][1]] =
3166 mat[Prow][li_Pcolarray[i][2]] = -
dJpdp2Vec[i]/aveDx;
3169 mat[Prow][li_Pcolarray[i][3]] = (
dJpdV1Vec[i-1]/aveDx);
3172 mat[Prow][li_Pcolarray[i][4]] =
3176 mat[Prow][li_Pcolarray[i][5]] = (-
dJpdV2Vec[i]/aveDx);
3182 mat[Prow][li_Pcolarray[i][6]] =
dJpdn1Vec[i-1]/aveDx;
3185 mat[Prow][li_Pcolarray[i][7]] =
3189 mat[Prow][li_Pcolarray[i][8]] = -
dJpdn2Vec[i]/aveDx;
3191 else if (type==
"ptype")
3201 mat[Nrow][li_Ncolarray[i][1]] =
3205 mat[Nrow][li_Ncolarray[i][2]] =
dJndn2Vec[i]/aveDx;
3208 mat[Nrow][li_Ncolarray[i][3]] = (-
dJndV1Vec[i-1]/aveDx);
3211 mat[Nrow][li_Ncolarray[i][4]] =
3215 mat[Nrow][li_Ncolarray[i][5]] = (
dJndV2Vec[i]/aveDx);
3218 mat[Nrow][li_Ncolarray[i][6]] =
dJndp1Vec[i-1]/aveDx;
3221 mat[Nrow][li_Ncolarray[i][7]] =
3225 mat[Nrow][li_Ncolarray[i][8]] = -
dJndp2Vec[i]/aveDx;
3229 std::string msg =
"Instance::loadMatDDForm";
3230 msg +=
"Unrecognized type on boundary.";
3231 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg);
3250 double dx1 =
dxVec[i-1];
3251 double dx2 =
dxVec[i];
3258 *(
fVmatPtr[i][1])=(2.0*L0/(dx1*dx2));
3349 for (
int i=0;i<
NX;++i)
3371 bool bsuccess =
true;
3384 mi.
N = (fabs(
CVec[i+1])+fabs(
CVec[i]))*0.5;
3393 if (mi.
N == 0.0) mi.
N = 1.0;
3425 #ifdef Xyce_DEBUG_DEVICE
3428 Xyce::dout() <<
"\tunE["<<i<<
"]="<<
unE_Vec[i];
3429 Xyce::dout() <<
"\tupE["<<i<<
"]="<<
upE_Vec[i];
3430 Xyce::dout() << std::endl;
3464 bool bsuccess =
true;
3510 for (
int i=0;i<
NX;++i)
3528 bool bsuccess (
false);
3529 bool fromFile (
false);
3537 #ifdef Xyce_DEBUG_DEVICE
3540 Xyce::dout() << section_divider << std::endl;
3541 Xyce::dout() <<
"Instance::setupDopingProfile\n";
3582 double xtmp =
xVec[i];
3583 double ndopeDopeValue(0.0), pdopeDopeValue(0.0);
3588 CVec[i] = ndopeDopeValue-pdopeDopeValue;
3601 for (iBC=0;iBC<
bcVec.size();++iBC)
3603 int i =
bcVec[iBC].meshIndex;
3606 bcVec[iBC].type =
"ntype";
3610 bcVec[iBC].type =
"ptype";
3614 #ifdef Xyce_DEBUG_DEVICE
3617 Xyce::dout() <<
"Na = " <<
Na << std::endl;
3618 Xyce::dout() <<
"Nd = " <<
Nd << std::endl;
3621 Xyce::dout() <<
"x[" << i <<
"] = " <<
xVec[i] <<
"\t";
3622 Xyce::dout() <<
"C[" << i <<
"] = " <<
CVec[i] << std::endl;
3625 Xyce::dout() << section_divider << std::endl;
3651 bool bsuccess =
true;
3667 midpoint =
width/2.0;
3668 XL = midpoint -
WJ/2.0;
3669 XR = midpoint +
WJ/2.0;
3698 std::map<std::string, DopeInfo *>::iterator iter;
3699 std::map<std::string, DopeInfo *>::iterator start =
dopeInfoMap.begin();
3700 std::map<std::string, DopeInfo *>::iterator end =
dopeInfoMap.end();
3702 for ( iter = start; iter != end; ++iter )
3720 if (
Na == 0.0 ||
Nd == 0.0)
3722 UserError(*
this) <<
"Mistake in doping. Na=" <<
Na <<
" %12.4e Nd=" <<
Nd;
3745 matPtr->
name=
"FULLDOMAIN";
3781 int totalMeshIndex = 1;
3782 for (
int imat=0;imat<matVecSize;++imat)
3785 Xyce::dout() <<
"name="<<matLay.
name <<
" NX="<<matLay.
NX<<
" LX="<<matLay.
LX <<std::endl;
3787 matLay.
LX = matLay.
NX-1;
3788 matLay.
begin = totalMeshIndex-1;
3794 double dx = matLay.
width /(
static_cast<double>(matLay.
LX));
3800 Xyce::dout() <<
"Setting xVec["<<matLay.
begin<<
"] to "<<
xVec[matLay.
begin] <<
"."<<std::endl;
3802 std::pair<int,int> hetPair = std::make_pair (matLayPrev.
end, matLay.
begin);
3808 for (
int ix=matLay.
begin;ix<=matLay.
end;++ix,++totalMeshIndex,++iloc)
3810 double extra=
static_cast<double>(iloc)*dx;
3811 xVec[ix] = base + extra;
3814 for (
int ix=matLay.
begin;ix<matLay.
end;++ix)
3829 double dx_tmp =
width/(
static_cast<double>(
LX));
3831 for (
int i=0;i<
NX;++i)
3833 xVec[i] =
static_cast<double>(i)*dx_tmp;
3836 for (
int i=0;i<
LX;++i)
3843 #ifdef Xyce_DEBUG_DEVICE
3846 for (
int i=0;i<
NX;++i)
3848 Xyce::dout() <<
"x["<<i<<
"] = " <<
xVec[i];
3849 Xyce::dout() <<
"\tdx["<<i<<
"] = " <<
dxVec[i];
3850 Xyce::dout() << std::endl;
3853 Xyce::dout() <<
"heterojunction boundary points:" <<std::endl;
3901 dnbnd0 = 2.0*pow(dnbnd0,1.5)/1.0e6;
3902 double kbq = 8.6173324e-5;
3906 for (
int im=0;im<size; ++im)
3910 int begin = matLayer.
begin;
3911 int end = matLayer.
end;
3913 double Ec = matLayer.
Ec;
3914 double Ev = matLayer.
Ev;
3915 double bg = fabs(Ec - Ev);
3917 double Nc = dnbnd0*(matLayer.
dnco);
3918 double Nv = dnbnd0*(matLayer.
dnva);
3920 double EcEff = matLayer.
Ec-matLayer.
narco;
3921 double EvEff = matLayer.
Ev+matLayer.
narva;
3922 double bgEff = fabs(EcEff-EvEff);
3925 double Ni = sqrt( Nc * Nv ) * exp (-bg/(2.0*kbq*
Temp));
3926 double NiEff = sqrt( Nc * Nv ) * exp (-bgEff/(2.0*kbq*Temp));
3929 matLayer.
NiEff = NiEff;
3931 matLayer.
bgEff = bgEff;
3933 #ifdef Xyce_DEBUG_DEVICE
3936 Xyce::dout() <<
"layer="<<matLayer.
name<<
"\t"<<matLayer.
material;
3937 Xyce::dout() <<
"\tNc="<<Nc<<
"\tNv="<<Nv<<
"\tbg="<<bg<<
"\tNi="<<Ni<<std::endl;
3941 for (
int i=begin;i<=end;++i)
3962 EiVec[i] = 0.5*(Ec+Ev)+0.5*
kb*Temp*log(Nv/Nc);
3963 EiEffVec[i] = 0.5*(EcEff+EvEff)+0.5*
kb*Temp*log(Nv/Nc);
3975 for (
int i=0;i<
NX;++i)
3984 #ifdef Xyce_DEBUG_DEVICE
3987 for (
int im=0;im<size; ++im)
3991 int begin = matLayer.
begin;
3992 int end = matLayer.
end;
3994 Xyce::dout() << matLayer.
name <<
"\tbegin="<<begin<<
"\tend="<<end<<std::endl;
3997 for (
int i=0;i<
NiVec.size();++i)
3999 Xyce::dout() << i <<
"\t"
4006 <<
NiVec[i] <<
"\n";
4008 Xyce::dout() << std::endl;
4047 bool bsuccess =
true;
4129 #ifdef Xyce_DEBUG_DEVICE
4132 Xyce::dout() <<
"scalingVars.x0 = " <<
scalingVars.
x0 << std::endl;
4133 Xyce::dout() <<
"scalingVars.a0 = " <<
scalingVars.
a0 << std::endl;
4134 Xyce::dout() <<
"scalingVars.T0 = " <<
scalingVars.
T0 << std::endl;
4135 Xyce::dout() <<
"scalingVars.V0 = " <<
scalingVars.
V0 << std::endl;
4136 Xyce::dout() <<
"scalingVars.C0 = " <<
scalingVars.
C0 << std::endl;
4137 Xyce::dout() <<
"scalingVars.D0 = " <<
scalingVars.
D0 << std::endl;
4138 Xyce::dout() <<
"scalingVars.u0 = " <<
scalingVars.
u0 << std::endl;
4139 Xyce::dout() <<
"scalingVars.R0 = " <<
scalingVars.
R0 << std::endl;
4140 Xyce::dout() <<
"scalingVars.t0 = " <<
scalingVars.
t0 << std::endl;
4141 Xyce::dout() <<
"scalingVars.E0 = " <<
scalingVars.
E0 << std::endl;
4142 Xyce::dout() <<
"scalingVars.F0 = " <<
scalingVars.
F0 << std::endl;
4143 Xyce::dout() <<
"scalingVars.J0 = " <<
scalingVars.
J0 << std::endl;
4144 Xyce::dout() <<
"scalingVars.L0 = " <<
scalingVars.
L0 << std::endl;
4172 for (i=0;i<
bcVec.size();++i)
4229 for (i=0;i<
bcVec.size();++i)
4279 bool bsuccess =
true;
4290 for (
int i=0;i<
NX;++i)
4297 tmp = (fabs(Ci)+sqrt(Cisq+4*Nisq))/2.0;
4298 nnVec[i] = ((Ci>=0)?(tmp):(0.0)) + ((Ci<0)?(Nisq/tmp):(0.0));
4301 tmp = (fabs(Ci)+sqrt(Cisq+4*Nisq))/2.0;
4302 npVec[i] = ((Ci<=0)?(tmp):(0.0)) + ((Ci>0)?(Nisq/tmp):(0.0));
4307 for (
int i=0;i<
NX;++i)
4310 double kbq_ = 8.6173324e-5;
4311 double dope_us_ =
CVec[i];
4312 double temp_us_ =
Temp;
4314 double Nc =
NcVec[i];
4315 double Nv =
NvVec[i];
4317 double cond_band =
EcVec[i];
4318 double vale_band =
EvVec[i];
4319 double bandgap = cond_band-vale_band;
4322 if (dope_us_ >= 0.0)
4328 double ef_m_ec_ = kbq_*temp_us_*
fdinvObj (dope_us_/Nc);
4331 double bgn_ = 3.23e-8 * std::pow(dope_us_, 1.0/3.0);
4334 double ef_m_ev_ = ef_m_ec_ + bandgap-bgn_;
4337 npVec[i] = Nv*std::exp(-ef_m_ev_/(kbq_*temp_us_));
4342 dope_us_ = std::fabs(dope_us_);
4346 double ev_m_ef_ = kbq_*temp_us_*
fdinvObj (dope_us_/Nv);
4349 double bgn_ = 2.55e-8 * std::pow(dope_us_, 1.0/3.0);
4352 double ec_m_ef_ = ev_m_ef_ + (bandgap-bgn_);
4355 nnVec[i] = Nc*std::exp(-ec_m_ef_/(kbq_*temp_us_));
4361 double Vmax = -1.0e99;
4362 double Vmin = +1.0e99;
4363 for (
int i=0;i<
NX;++i)
4376 if (Vmax <
VVec[i]) Vmax =
VVec[i];
4377 if (Vmin >
VVec[i]) Vmin =
VVec[i];
4384 for (
int i=0;i<
NX;++i)
4390 for (
int i=0;i<
NX;++i)
4410 bool bsuccess =
true;
4413 double VminBC =+1.0e+99;
4414 double VmaxBC =-1.0e+99;
4416 int bcSize=
bcVec.size();
4417 for (
int i=0;i<bcSize;++i)
4419 int mIndex =
bcVec[i].meshIndex;
4420 double Ci =
CVec[mIndex];
4421 double Cisq = Ci*Ci;
4422 double Nisq =
Ni*
Ni;
4423 double tmp, nnTmp, npTmp;
4426 tmp = (fabs(Ci)+sqrt(Cisq+4*Nisq))/2.0;
4427 nnTmp = ((Ci>=0)?(tmp):(0.0)) + ((Ci<0)?(Nisq/tmp):(0.0));
4430 tmp = (fabs(Ci)+sqrt(Cisq+4*Nisq))/2.0;
4431 npTmp = ((Ci<=0)?(tmp):(0.0)) + ((Ci>0)?(Nisq/tmp):(0.0));
4436 ExtendedString mater =
bcVec[i].material;
4439 if (
bcVec[i].VequGiven != 1)
4441 if (mater==
"neutral")
4446 bcVec[i].Vequ = +
Vt * log(nnTmp/Ni);
4450 bcVec[i].Vequ = -
Vt * log(npTmp/Ni);
4461 + 2.0 *
Vt * log(nnTmp/Ni);
4468 - 2.0 *
Vt * log(npTmp/Ni);
4473 if (VminBC >
bcVec[i].Vequ) VminBC =
bcVec[i].Vequ;
4474 if (VmaxBC <
bcVec[i].Vequ) VmaxBC =
bcVec[i].Vequ;
4497 bool bsuccess =
true;
4509 for (iBC=0;iBC<
bcVec.size();++iBC)
4511 int i1 =
bcVec[iBC].meshIndex;
4540 bool bsuccess =
true;
4543 int bcSize=
bcVec.size();
4546 for (iBC=0;iBC<bcSize;++iBC)
4553 for (iBC=0;iBC<bcSize;++iBC)
4585 for (iBC=0;iBC<
bcVec.size();++iBC)
4587 bcVec[iBC].Vckt = (*solVectorPtr)[
bcVec[iBC].lid];
4610 for (
int iBC=0;iBC<
bcVec.size();++iBC)
4614 double delV1 = v1 - v1_old;
4616 if ( delV1 > 1.25 ) v1 = v1_old + 1.25;
4618 if ( delV1 < -0.75) v1 = v1_old - 0.75;
4638 bool bsuccess =
true;
4675 #ifdef Xyce_PDE_DENSITY_CONSTRAINT
4681 #ifdef Xyce_PDE_DENSITY_CONSTRAINT
4719 bool bsuccess =
true;
4721 bool skipOutput =
false;
4732 double outMult =
static_cast<double> (
outputIndex);
4747 if (skipOutput)
return bsuccess;
4751 #ifdef Xyce_DEBUG_DEVICE
4790 char filename[32];
for(i=0;i<32;++i) filename[i] = static_cast<char>(0);
4798 sprintf(filename,
"%s.dat",
outputName.c_str());
4806 fp1 = fopen(filename,
"w");
4812 fp1 = fopen(filename,
"w");
4816 fp1 = fopen(filename,
"a");
4825 " TITLE = \"Spatially Dependent data for PDE diode: %s time = %20.12e seconds. equation set = nonlinear Poisson\",\n",
4831 " TITLE = \"Spatially Dependent data for PDE diode: %s time = %20.12e seconds. equation set = drift diffusion\",\n",
4840 " TITLE = \"Spatially Dependent data for PDE diode: %s time = %20.12e seconds.\",\n",
4850 fprintf(fp1,
"%s",
"\tVARIABLES = \"X \",\n");
4852 fprintf(fp1,
"%s",
"\t \"V \",\n");
4853 fprintf(fp1,
"%s",
"\t \"nn (electron dens.) \",\n");
4854 fprintf(fp1,
"%s",
"\t \"np (hole dens.) \",\n");
4855 fprintf(fp1,
"%s",
"\t \"nn*np (carrier product) \",\n");
4856 fprintf(fp1,
"%s",
"\t \"Dopant density \",\n");
4857 fprintf(fp1,
"%s",
"\t \"fabs(Dopant density)\",\n");
4858 fprintf(fp1,
"%s",
"\t \"electron lifetime \",\n");
4859 fprintf(fp1,
"%s",
"\t \"hole lifetime \",\n");
4862 fprintf(fp1,
"%s",
"\t \"Jn \",\n");
4863 fprintf(fp1,
"%s",
"\t \"Jp \",\n");
4864 fprintf(fp1,
"%s",
"\t \"R \",\n");
4865 fprintf(fp1,
"%s",
"\t \"Ex \",\n");
4866 fprintf(fp1,
"%s",
"\t \"Idispl \", \n");
4868 fprintf(fp1,
"%s",
"\t \"Conduction Band, uncorrected \", \n");
4869 fprintf(fp1,
"%s",
"\t \"Valance Band, uncorrected \", \n");
4871 fprintf(fp1,
"%s",
"\t \"Band-gap narrowing, Conduction Band \", \n");
4872 fprintf(fp1,
"%s",
"\t \"Band-gap narrowing, Valance Band \", \n");
4874 fprintf(fp1,
"%s",
"\t \"Conduction Band, corrected for BGN \", \n");
4875 fprintf(fp1,
"%s",
"\t \"Valance Band, corrected for BGN \", \n");
4876 fprintf(fp1,
"%s",
"\t \"Fermi Level\", \n");
4878 fprintf(fp1,
"%s",
"\t \"conduction band DOS\", \n");
4879 fprintf(fp1,
"%s",
"\t \"valance band DOS\", \n");
4881 fprintf(fp1,
"\t \"n0, Fermi-Dirac \",\n");
4882 fprintf(fp1,
"\t \"p0, Fermi-Dirac \",\n");
4883 fprintf(fp1,
"\t \"n0, Boltzmann\",\n");
4884 fprintf(fp1,
"\t \"p0, Boltzmann\",\n");
4885 fprintf(fp1,
"\t \"np0 Fermi-Dirac\",\n");
4886 fprintf(fp1,
"\t \"Ni^2 (Boltzmann np0)\",\n");
4887 fprintf(fp1,
"%s",
"\t \"Ni (intrinsic concentration) \", \n");
4890 fprintf(fp1,
"\tZONE F=POINT,I=%d",
NX);
4894 fprintf(fp1,
" T = \"DCOP step = %d\" \n",
callsOTEC);
4898 fprintf(fp1,
" T = \"time step = %d time = %20.12e\" AUXDATA time = \"%20.12e seconds\" \n",
callsOTEC , time, time);
4901 double vcorrection = 0.0;
4919 fprintf(fp1,
"%s",
"\n");
4924 fprintf(fp1,
"%s",
"\n");
4927 fprintf(fp1,
"%s",
"\n");
4930 fprintf(fp1,
"%s",
"\n");
4934 fprintf(fp1,
"%s",
"\n");
4936 fprintf(fp1,
" %20.12e",
EcVec[i]);
4937 fprintf(fp1,
" %20.12e",
EvVec[i]);
4938 fprintf(fp1,
" %20.12e",
bgnCVec[i]);
4939 fprintf(fp1,
" %20.12e",
bgnVVec[i]);
4943 fprintf(fp1,
" %20.12e", con);
4944 fprintf(fp1,
" %20.12e", val);
4946 fprintf(fp1,
"%s",
"\n");
4948 fprintf(fp1,
" %20.12e",
EfVec[i]);
4949 fprintf(fp1,
" %20.12e",
NcVec[i]);
4950 fprintf(fp1,
" %20.12e",
NvVec[i]);
4958 fprintf(fp1,
" %20.12e",n0);
4959 fprintf(fp1,
" %20.12e",p0);
4964 if (n0 != 0.0) { p0 = Ni*Ni/n0; }
4969 if (p0 != 0.0) { n0 = Ni*Ni/p0; }
4971 fprintf(fp1,
" %20.12e",n0);
4972 fprintf(fp1,
" %20.12e",p0);
4978 fprintf(fp1,
" %20.12e",np0);
4979 fprintf(fp1,
" %20.12e",Ni*Ni);
4980 fprintf(fp1,
" %20.12e",Ni);
4983 fprintf(fp1,
"%s",
"\n");
5010 static const int LEN_IDENT2 = 31;
5012 for (i = 0 ; i < 32; ++i)
5013 fileName[i] = static_cast<char>(0);
5018 FILE * handle1 = fopen(fileName,
"w");
5021 double timeVar = 0.0;
5026 sprintf(title,
"%s",
"Xyce diodePDE 1D output");
5028 fwrite(&inx ,
sizeof( UINT), 1, handle1);
5029 fwrite(&numArrays,
sizeof( UINT), 1, handle1);
5030 fwrite( title ,
sizeof(
char),64, handle1);
5031 fwrite(&timeVar ,
sizeof(
double), 1, handle1);
5033 char names[3][LEN_IDENT2];
5034 sprintf(names[0],
"%s",
"V");
5035 sprintf(names[1],
"%s",
"Ne");
5036 sprintf(names[2],
"%s",
"Np");
5039 for(i=0;i<numArrays;++i)
5041 fwrite(names[i],
sizeof(
char),(LEN_IDENT2), handle1);
5044 double vcorrection = 0.0;
5066 fwrite( &
xVec[0],
sizeof(
double),inx , handle1 );
5069 fwrite( &
VVec[0],
sizeof(
double),inx , handle1 );
5072 fwrite( &
nnVec[0],
sizeof(
double),inx , handle1 );
5075 fwrite( &
npVec[0],
sizeof(
double),inx , handle1 );
5101 for (
int i=0;i<
NX;++i)
5106 double n =
nnVec[i];
5107 double p =
npVec[i];
5108 double tn =
tnVec[i];
5109 double tp =
tpVec[i];
5121 RVec[i] = (Rsrh + Raug);
5155 double n =
nnVec[i];
5156 double p =
npVec[i];
5157 double tn =
tnVec[i];
5158 double tp =
tpVec[i];
5172 dRdnVec[i] = dRsrhdn + dRaugdn;
5173 dRdpVec[i] = dRsrhdp + dRaugdp;
5190 for (
int i=0;i<
LX;++i)
5220 for (
int i=0;i<
LX;++i)
5263 for (
int i=0;i<
LX;++i)
5294 for (
int i=0;i<
LX;++i)
5338 for (
int i=0;i<
LX;++i)
5349 absEx = fabs(
ExVec[i]);
5372 bool bnoChange =
true;
5374 int bcSize=
bcVec.size();
5380 for (iBC=0;iBC<bcSize;++iBC)
5388 for (iBC=0;iBC<bcSize;++iBC)
5400 for (iBC=0;iBC<bcSize;++iBC)
5402 double dV,tmp1V, tmp2V;
5403 tmp1V =
bcVec[iBC].Vckt_final;
5404 tmp2V =
bcVec[iBC].Vckt_old;
5407 bcVec[iBC].Vckt_delta = dV;
5409 bcVec[iBC].Vckt_deltaC = dV/
5416 if (fabs(
bcVec[iBC].Vckt_deltaC) > maxDelta)
5418 int tmp_steps =
static_cast<int>(fabs(dV)/maxDelta) + 1;
5421 bcVec[iBC].Vckt_deltaC = dV/
5425 if (fabs(dV) > 1.0e-3) bnoChange =
false;
5428 bcVec[iBC].Vckt_ramp_old =
bcVec[iBC].Vckt_old;
5433 bool bnoChangePhotogen;
5435 bnoChangePhotogen = enablePhotogenContinuation ();
5437 bnoChange = bnoChange && bnoChangePhotogen;
5444 return (!bnoChange);
5459 int bcSize=
bcVec.size();
5460 for (iBC=0;iBC<bcSize;++iBC)
5482 #ifdef Xyce_DEBUG_DEVICE
5483 Xyce::dout() << section_divider << std::endl;
5484 Xyce::dout() <<
"Instance::setPDEContinuationAlpha" << std::endl;
5489 int bcSize=
bcVec.size();
5490 for (
int iBC=0;iBC<bcSize;++iBC)
5492 bcVec[iBC].Vckt_ramp =
bcVec[iBC].Vckt_old + (
bcVec[iBC].Vckt_delta)*alpha;
5495 if ((
bcVec[iBC].Vckt_delta > 0 &&
bcVec[iBC].Vckt_ramp >
bcVec[iBC].Vckt_final) ||
5496 (
bcVec[iBC].Vckt_delta <= 0 &&
bcVec[iBC].Vckt_ramp <=
bcVec[iBC].Vckt_final) )
5498 bcVec[iBC].Vckt_ramp =
bcVec[iBC].Vckt_final;
5501 #ifdef Xyce_DEBUG_DEVICE
5502 Xyce::dout() <<
" " <<
bcVec[iBC].eName <<
" Vckt_ramp = " <<
bcVec[iBC].Vckt_ramp << std::endl;
5517 #ifdef Xyce_DEBUG_DEVICE
5518 Xyce::dout() <<
" photoA1_ramp = " <<
photoA1_ramp << std::endl;
5519 Xyce::dout() << section_divider << std::endl;
5535 .registerDevice(
"pde", 1)
5536 .registerModelType(
"pde", 1)
5537 .registerModelType(
"zod", 1);