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>
114 .setDescription(
"If set the density will be scaled by a fraction of the maximum doping.");
117 .setDescription(
"Fraction of the maximum doping by which density will be scaled.");
134 #ifdef Xyce_DEBUG_DEVICE
135 p.
addPar(
"ANODEINDEX", 1, &DiodePDE::Instance::anodeIndex_user)
136 .setGivenMember(&DiodePDE::Instance::anodeIndex_userGiven);
137 p.
addPar(
"CATHODEINDEX", 0, &DiodePDE::Instance::cathodeIndex_user)
138 .setGivenMember(&DiodePDE::Instance::cathodeIndex_userGiven);
151 .setDescription(
"If true, use field dependent mobility.");
160 .setDescription(
"If set to true, then some variables are excluded from the time integration error control calculation.");
178 .setDescription(
"Flag for using Dirichlet boundary conditions for defects.");
181 .setDescription(
"Flag for using old(inaccurate) intrinsic carrier calculation.");
230 indicesSetup_(false),
231 includeBaseNode_(false),
232 useElectrodeSpec_(false),
233 maskVarsTIAFlag_(false),
234 scaleDensityToMaxDoping_(true),
235 densityScalarFraction_(1.0e-1),
236 useVoltageOutputOffset_(true),
237 offsetWithFirstElectrode_(false),
253 junctionArea(1.0e-5),
256 useOldNiGiven(false),
257 dopingFileName(
"NOFILE"),
258 ndopeFileName(
"NOFILE"),
259 pdopeFileName(
"NOFILE"),
278 baseLocation(0.5e-3),
279 baseLocationGiven(false),
281 gradedJunctionFlag(false),
282 bjtEnableFlag(false),
283 displCurrentFlag(false),
284 calledBeforeUIVB(false),
288 lastOutputTime(-10.0),
290 outputIntervalGiven(false),
292 outputNLPoisson(false),
297 includeAugerRecomb(true),
298 includeSRHRecomb(true),
300 #ifdef Xyce_DEBUG_DEVICE
302 anodeIndex_userGiven(false),
303 cathodeIndex_user(0),
304 cathodeIndex_userGiven(false),
308 enableContinuationCalled(false),
310 dirichletBCFlag(false),
311 columnReorderingFlag(false)
334 std::string msg =
"DiodePDEInstance:";
336 msg +=
" too many external nodes are set! Set no more than 3.";
337 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg);
348 if (
given(
"PDOPE_FILE") && !
given(
"NDOPE_FILE") )
350 std::string msg =
"Ndope file specified with no Pdope file. Exiting.";
351 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg);
354 if ( !
given(
"PDOPE_FILE") &&
given(
"NDOPE_FILE") )
356 std::string msg =
"Pdope file specified with no Ndope file. Exiting.";
357 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg);
364 if (
given(
"MESHFILE"))
366 std::string msg =
"Instance constructor."
367 "mesh file was specified. The 1D device doesn't need a mesh file."
368 " Either add a model statement of level=2, or get rid of the mesh"
369 " file specification.";
370 N_ERH_ErrorMgr::report( N_ERH_ErrorMgr::DEV_FATAL_0,msg);
375 if (
given(
"GNUPLOTLEVEL") && !
given(
"TECPLOTLEVEL"))
388 bool bsuccess =
true;
393 bs1 =
setupMesh (); bsuccess = bsuccess && bs1;
394 bs1 =
setupNodes (); bsuccess = bsuccess && bs1;
433 if (compositeName ==
"DOPINGPROFILES" || compositeName ==
"REGION")
439 else if (compositeName ==
"NODE" || compositeName ==
"ELECTRODE")
442 ExtendedString electrodeName = paramName;
443 electrodeName.toUpper ();
445 bc.
eName = electrodeName;
446 bc.
nName = paramName;
450 if (electrodeName ==
"ANODE")
471 "Instance::constructComposite: unrecognized composite name: ";
472 msg += compositeName;
473 N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
592 int collectorIndex=0;
594 bcVec[collectorIndex].eName =
"collector";
596 bcVec[collectorIndex].VequGiven =
given(
"COLLECTOR.BC");
598 bcVec[collectorIndex].areaGiven =
given(
"COLLECTOR.AREA");
599 bcVec[collectorIndex].meshIndex =
LX;
600 bcVec[collectorIndex].neighborNode =
LX-1;
606 bcVec[baseIndex].eName =
"base";
610 for (
int i=0;i<
NX;++i)
613 if (deltaX < minDelta)
621 bcVec[baseIndex].VequGiven =
given(
"BASE.BC");
623 bcVec[baseIndex].areaGiven =
given(
"BASE.AREA");
625 bcVec[baseIndex].meshIndex = bIndex;
626 bcVec[baseIndex].neighborNode =
bcVec[baseIndex].meshIndex-1;
632 bcVec[emitterIndex].eName =
"emitter";
634 bcVec[emitterIndex].VequGiven =
given(
"EMITTER.BC");
636 bcVec[emitterIndex].areaGiven =
given(
"EMITTER.AREA");
637 bcVec[emitterIndex].meshIndex = 0;
638 bcVec[emitterIndex].neighborNode = 1;
646 bcVec[anodeIndex].eName =
"anode";
648 bcVec[anodeIndex].VequGiven =
given(
"ANODE.BC");
650 bcVec[anodeIndex].areaGiven =
given(
"ANODE.AREA");
651 bcVec[anodeIndex].meshIndex = 0;
652 bcVec[anodeIndex].neighborNode = 1;
658 bcVec[cathodeIndex].eName =
"cathode";
660 bcVec[cathodeIndex].VequGiven =
given(
"CATHODE.BC");
662 bcVec[cathodeIndex].areaGiven =
given(
"CATHODE.AREA");
663 bcVec[cathodeIndex].meshIndex =
LX;
664 bcVec[cathodeIndex].neighborNode =
LX-1;
672 std::vector<int> tmpMeshSten(
NX,0);
674 for (
int iBC=0;iBC<
bcVec.size();++iBC)
682 ExtendedString side = electrode.
side;
686 bcVec[iBC].meshIndex = 0;
687 bcVec[iBC].neighborNode = 1;
690 else if (side ==
"right")
692 bcVec[iBC].meshIndex =
LX;
693 bcVec[iBC].neighborNode =
LX-1;
696 else if (side ==
"middle" || side ==
"mid")
699 double location = electrode.
location;
703 for (
int imesh=0;imesh<
NX;++imesh)
705 double deltaX=fabs(location-
xVec[imesh]);
706 if (deltaX < minDelta)
713 bcVec[iBC].meshIndex = bIndex;
714 bcVec[iBC].neighborNode = bIndex-1;
718 if (tmpMeshSten[bIndex] == 1)
720 std::string msg =
"Instance::setupNodes. Failed to find mesh index for " + bcVec[iBC].eName;
721 N_ERH_ErrorMgr::report( N_ERH_ErrorMgr::DEV_FATAL_0,msg);
726 std::string msg =
"Instance::setupNodes. unrecognized side specified.";
727 N_ERH_ErrorMgr::report( N_ERH_ErrorMgr::DEV_FATAL_0,msg);
736 bcVec[iBC].areaGiven = electrode.
areaGiven;
739 bcVec[iBC].area = electrode.
area;
746 #ifdef Xyce_DEBUG_DEVICE
749 Xyce::dout() <<
" area = " <<
area << std::endl;
750 Xyce::dout() <<
" areaGiven = " <<
given(
"AREA") << std::endl;
751 int isize=
bcVec.size();
752 for (
int i=0;i<isize;++i)
754 Xyce::dout() <<
" bcVec["<<i<<
"].area = " <<
bcVec[i].area << std::endl;
755 Xyce::dout() <<
" bcVec["<<i<<
"].areaGiven = " <<
bcVec[i].areaGiven << std::endl;
756 Xyce::dout() <<
" bcVec["<<i<<
"].meshIndex = " <<
bcVec[i].meshIndex << std::endl;
762 int bcSize=
bcVec.size();
763 for (
int i=0;i<bcSize;++i)
765 bcVec[i].colArray.resize(colmax,-1);
766 bcVec[i].dIdXcols.resize(colmax,-1);
767 bcVec[i].dIdX.resize(colmax,-1);
768 bcVec[i].dFdVckt.resize(colmax,0.0);
777 condVec[iE].resize(numElectrodes,0.0);
785 for (
int i=0;i<bcSize;++i)
787 int meshIndex=
bcVec[i].meshIndex;
789 if (meshIndex==0 || meshIndex==
LX)
833 std::string msg =
"Instance constructor."
834 " NX parameter was not specified.";
835 N_ERH_ErrorMgr::report( N_ERH_ErrorMgr::DEV_FATAL_0,msg);
857 int baseIndex_m1 = 0;
858 int baseIndex_p1 = 0;
883 int bcSize=
bcVec.size();
885 for (
int iBC=0;iBC<bcSize;++iBC)
887 int meshIndex=
bcVec[iBC].meshIndex;
892 for (
int i=0;i<
NX;++i)
901 for (iBC=0;iBC<
bcVec.size();++iBC)
903 iMeshNode =
bcVec[iBC].meshIndex;
907 std::string msg =
"Instance::setupJacStamp:";
908 msg +=
"Boundary point not in the stencil.";
909 N_ERH_ErrorMgr::report( N_ERH_ErrorMgr::DEV_FATAL,msg);
912 int iNN =
bcVec[iBC].neighborNode;
913 baseIndex = numVars*
meshToLID[iMeshNode ] + extVarOffset;
914 Vindex = baseIndex + Voffset;
915 Nindex = baseIndex + Noffset;
916 Pindex = baseIndex + Poffset;
920 baseIndex_m1 = numVars*
meshToLID[iMeshNode-1] + extVarOffset;
922 Vindex_m1 = baseIndex_m1 + Voffset;
923 Nindex_m1 = baseIndex_m1 + Noffset;
924 Pindex_m1 = baseIndex_m1 + Poffset;
938 baseIndex_p1 = numVars*
meshToLID[iMeshNode+1] + extVarOffset;
940 Vindex_p1 = baseIndex_p1 + Voffset;
941 Nindex_p1 = baseIndex_p1 + Noffset;
942 Pindex_p1 = baseIndex_p1 + Poffset;
960 for (iBC=0;iBC<
bcVec.size();++iBC)
962 iMeshNode =
bcVec[iBC].meshIndex;
963 int iNN =
bcVec[iBC].neighborNode;
966 baseIndex = numVars*
meshToLID[iMeshNode ] + extVarOffset;
967 Vindex = baseIndex + Voffset;
968 Nindex = baseIndex + Noffset;
969 Pindex = baseIndex + Poffset;
979 baseIndex_p1 = numVars*
meshToLID[iMeshNode+1] + extVarOffset;
980 Vindex_p1 = baseIndex_p1 + Voffset;
981 Nindex_p1 = baseIndex_p1 + Noffset;
982 Pindex_p1 = baseIndex_p1 + Poffset;
985 jacStamp[Vindex][col++] = NodeIndex;
987 jacStamp[Vindex][col++] = Vindex_p1;
991 jacStamp[Nindex][col++] = Nindex_p1;
993 jacStamp[Nindex][col++] = Pindex_p1;
997 jacStamp[Pindex][col++] = Pindex_p1;
999 jacStamp[Pindex][col++] = Nindex_p1;
1003 baseIndex_m1 = numVars*
meshToLID[iMeshNode-1] + extVarOffset;
1004 Vindex_m1 = baseIndex_m1 + Voffset;
1005 Nindex_m1 = baseIndex_m1 + Noffset;
1006 Pindex_m1 = baseIndex_m1 + Poffset;
1009 jacStamp[Vindex][col++] = Vindex_m1;
1011 jacStamp[Vindex][col++] = NodeIndex;
1014 jacStamp[Nindex][col++] = Nindex_m1;
1016 jacStamp[Nindex][col++] = Pindex_m1;
1020 jacStamp[Pindex][col++] = Pindex_m1;
1022 jacStamp[Pindex][col++] = Nindex_m1;
1033 baseIndex_m1 = numVars*
meshToLID[iMeshNode-1] + extVarOffset;
1034 baseIndex = numVars*
meshToLID[iMeshNode ] + extVarOffset;
1035 baseIndex_p1 = numVars*
meshToLID[iMeshNode+1] + extVarOffset;
1037 Vindex_m1 = baseIndex_m1 + Voffset;
1038 Nindex_m1 = baseIndex_m1 + Noffset;
1039 Pindex_m1 = baseIndex_m1 + Poffset;
1040 Vindex = baseIndex + Voffset;
1041 Nindex = baseIndex + Noffset;
1042 Pindex = baseIndex + Poffset;
1043 Vindex_p1 = baseIndex_p1 + Voffset;
1044 Nindex_p1 = baseIndex_p1 + Noffset;
1045 Pindex_p1 = baseIndex_p1 + Poffset;
1050 jacStamp[Vindex][col++] = NodeIndex;
1051 jacStamp[Vindex][col++] = Vindex_m1;
1053 jacStamp[Vindex][col++] = Vindex_p1;
1060 jacStamp[Nindex][col++] = Nindex_m1;
1062 jacStamp[Nindex][col++] = Nindex_p1;
1063 jacStamp[Nindex][col++] = Vindex_m1;
1065 jacStamp[Nindex][col++] = Vindex_p1;
1066 jacStamp[Nindex][col++] = Pindex_m1;
1068 jacStamp[Nindex][col++] = Pindex_p1;
1073 jacStamp[Pindex][col++] = Pindex_m1;
1075 jacStamp[Pindex][col++] = Pindex_p1;
1076 jacStamp[Pindex][col++] = Vindex_m1;
1078 jacStamp[Pindex][col++] = Vindex_p1;
1079 jacStamp[Pindex][col++] = Nindex_m1;
1081 jacStamp[Pindex][col++] = Nindex_p1;
1086 std::string msg =
"Instance::setupJacStamp:";
1087 msg +=
"Boundary point not in the stencil.";
1088 N_ERH_ErrorMgr::report( N_ERH_ErrorMgr::DEV_FATAL,msg);
1093 for (iMeshNode=0;iMeshNode<
NX;++iMeshNode)
1097 baseIndex_m1 = numVars*
meshToLID[iMeshNode-1] + extVarOffset;
1098 baseIndex = numVars*
meshToLID[iMeshNode ] + extVarOffset;
1099 baseIndex_p1 = numVars*
meshToLID[iMeshNode+1] + extVarOffset;
1101 Vindex_m1 = baseIndex_m1 + Voffset;
1102 Nindex_m1 = baseIndex_m1 + Noffset;
1103 Pindex_m1 = baseIndex_m1 + Poffset;
1104 Vindex = baseIndex + Voffset;
1105 Nindex = baseIndex + Noffset;
1106 Pindex = baseIndex + Poffset;
1107 Vindex_p1 = baseIndex_p1 + Voffset;
1108 Nindex_p1 = baseIndex_p1 + Noffset;
1109 Pindex_p1 = baseIndex_p1 + Poffset;
1114 jacStamp[Vindex][col++] = Vindex_m1;
1116 jacStamp[Vindex][col++] = Vindex_p1;
1123 jacStamp[Nindex][col++] = Nindex_m1;
1125 jacStamp[Nindex][col++] = Nindex_p1;
1126 jacStamp[Nindex][col++] = Vindex_m1;
1128 jacStamp[Nindex][col++] = Vindex_p1;
1129 jacStamp[Nindex][col++] = Pindex_m1;
1131 jacStamp[Nindex][col++] = Pindex_p1;
1136 jacStamp[Pindex][col++] = Pindex_m1;
1138 jacStamp[Pindex][col++] = Pindex_p1;
1139 jacStamp[Pindex][col++] = Vindex_m1;
1141 jacStamp[Pindex][col++] = Vindex_p1;
1142 jacStamp[Pindex][col++] = Nindex_m1;
1144 jacStamp[Pindex][col++] = Nindex_p1;
1147 #ifdef Xyce_DEBUG_DEVICE
1152 Xyce::dout() <<
"jacStamp size = " << jacSize << std::endl;
1154 for(
int i=0;i<jacSize;++i)
1157 for (
int j=0;j<colSize;++j)
1159 Xyce::dout() <<
" jacStamp["<<i<<
"]["<<j<<
"] = " <<
jacStamp[i][j] << std::endl;
1188 int mapSize =
jacMap.size();
1189 for (
int i=0;i<mapSize;++i)
1193 for (
int j=0;j<
jacStamp[i].size();++j)
1207 std::vector< std::vector<int> > tempStamp_eric;
1208 std::vector< std::vector<int> > tempMap2_eric;
1235 for (itmp=0;itmp<128;++itmp) tmpchar[itmp] = 0;
1238 for (itmp=0;itmp<
NX;++itmp)
1242 sprintf(tmpchar,
"%s_V_%d",
getName().c_str(), itmp);
1248 sprintf(tmpchar,
"%s_N_%d",
getName().c_str(), itmp);
1254 sprintf(tmpchar,
"%s_P_%d",
getName().c_str(), itmp);
1272 const std::vector<int> & extLIDVecRef)
1277 #ifdef Xyce_DEBUG_DEVICE
1280 Xyce::dout() << section_divider << std::endl;
1281 Xyce::dout() <<
"Instance::registerLIDs:\n";
1282 Xyce::dout() <<
" name = " <<
getName() << std::endl;
1283 Xyce::dout() <<
" numInt = " <<
numIntVars << std::endl;
1284 Xyce::dout() <<
" numEXt = " <<
numExtVars << std::endl;
1285 Xyce::dout() <<
" NX = " <<
NX << std::endl;
1293 for (
int iBC=0;iBC<
bcVec.size();++iBC)
1311 for (
int iBC=0;iBC<
bcVec.size();++iBC)
1313 meshIndex =
bcVec[iBC].meshIndex;
1322 for (meshIndex=0;meshIndex<
NX;++meshIndex)
1331 #ifdef Xyce_DEBUG_DEVICE
1335 Xyce::dout() <<
"\n solution indices:\n";
1337 for (
int i=0;i<
NX;++i)
1339 Xyce::dout() <<
" li_Vrowarray["<<i<<
"] = " <<
li_Vrowarray[i];
1340 Xyce::dout() <<
"\tli_Nrowarray["<<i<<
"] = " <<
li_Nrowarray[i];
1341 Xyce::dout() <<
"\tli_Prowarray["<<i<<
"] = " <<
li_Prowarray[i] << std::endl;
1343 Xyce::dout() << section_divider << std::endl;
1361 #ifdef Xyce_DEBUG_DEVICE
1364 Xyce::dout() << std::endl;
1365 Xyce::dout() << section_divider << std::endl;
1366 Xyce::dout() <<
" In Instance::registerStateLIDs\n\n";
1367 Xyce::dout() <<
" name = " <<
getName() << std::endl;
1368 Xyce::dout() <<
" Number of State LIDs: " <<
numStateVars << std::endl;
1377 for (i=0;i<
bcVec.size();++i)
1382 for (i=0,j=2;i<
NX-1;++i,++j)
1387 #ifdef Xyce_DEBUG_DEVICE
1390 Xyce::dout() <<
" State indices:" << std::endl;
1391 Xyce::dout() << std::endl;
1392 for (i=0;i<
bcVec.size();++i)
1394 Xyce::dout() <<
"bcVec["<<i<<
"].li_stateC = "<<
bcVec[i].li_stateC<< std::endl;
1396 Xyce::dout() << std::endl;
1398 Xyce::dout() <<
" Displacement current state variable local indices:" << std::endl;
1399 for (i=0;i<NX-1;++i)
1401 Xyce::dout() <<
" li_stateDispl["<<i<<
"] = " <<
li_stateDispl[i] << std::endl;
1403 Xyce::dout() << section_divider << std::endl;
1430 (
const std::vector< std::vector<int> > & jacLIDVec )
1443 #ifdef Xyce_DEBUG_DEVICE
1447 int extVarOffset = numExtVars;
1449 #ifdef Xyce_DEBUG_DEVICE
1450 if (getDeviceOptions().debugLevel > 0)
1452 Xyce::dout() << section_divider << std::endl;
1453 Xyce::dout() <<
"Instance::registerJacLIDs" << std::endl;
1455 int jacLIDSize = jacLIDVec.size();
1456 Xyce::dout() <<
"jacLIDSize = " << jacLIDSize << std::endl;
1457 for (i=0;i<jacLIDSize;++i)
1459 int jacLIDcolSize = jacLIDVec[i].size();
1460 Xyce::dout() << std::endl;
1461 Xyce::dout() <<
"jacLIDVec["<<i<<
"].size = " << jacLIDcolSize << std::endl;
1462 for (j=0;j<jacLIDcolSize;++j)
1464 Xyce::dout() <<
"jacLIDVec["<<i<<
"]["<<j<<
"] = ";
1465 Xyce::dout() << jacLIDVec[i][j] << std::endl;
1471 li_Vcolarray.resize(NX);
1472 li_Ncolarray.resize(NX);
1473 li_Pcolarray.resize(NX);
1476 for (
int iBC=0;iBC<bcVec.size();++iBC)
1479 int numCols = jacLIDVec[iBC].size();
1480 bcVec[iBC].li_colArray.resize(numCols,-1);
1482 for (i1=0;i1<numCols;++i1)
1484 bcVec[iBC].li_colArray[i1] = jacLIDVec[iBC][i1];
1487 int iMeshNode = bcVec[iBC].meshIndex;
1489 bcVec[iBC].lidOffset = jacLIDVec[iBC][0];
1491 #ifdef Xyce_DEBUG_DEVICE
1492 if (getDeviceOptions().debugLevel > 0)
1494 Xyce::dout() << std::endl;
1495 for(i=0;i<bcVec[iBC].li_colArray.size();++i)
1497 Xyce::dout() << bcVec[iBC].eName <<
": li_colArray["<<i<<
"] = "<<bcVec[iBC].li_colArray[i]<< std::endl;
1499 Xyce::dout() << std::endl;
1505 for (iMeshNode=0;iMeshNode<NX;++iMeshNode)
1507 if (boundarySten[iMeshNode]==1)
continue;
1509 baseIndex = numVars*meshToLID[iMeshNode ] + extVarOffset;
1511 Vindex = baseIndex + Voffset;
1512 Nindex = baseIndex + Noffset;
1513 Pindex = baseIndex + Poffset;
1518 li_Vcolarray[iMeshNode].resize(5,-1);
1519 li_Vcolarray[iMeshNode][i1++] = jacLIDVec[Vindex][j1++];
1520 li_Vcolarray[iMeshNode][i1++] = jacLIDVec[Vindex][j1++];
1521 li_Vcolarray[iMeshNode][i1++] = jacLIDVec[Vindex][j1++];
1522 li_Vcolarray[iMeshNode][i1++] = jacLIDVec[Vindex][j1++];
1523 li_Vcolarray[iMeshNode][i1++] = jacLIDVec[Vindex][j1++];
1527 li_Ncolarray[iMeshNode].resize(9,-1);
1528 li_Ncolarray[iMeshNode][i1++] = jacLIDVec[Nindex][j1++];
1529 li_Ncolarray[iMeshNode][i1++] = jacLIDVec[Nindex][j1++];
1530 li_Ncolarray[iMeshNode][i1++] = jacLIDVec[Nindex][j1++];
1531 li_Ncolarray[iMeshNode][i1++] = jacLIDVec[Nindex][j1++];
1532 li_Ncolarray[iMeshNode][i1++] = jacLIDVec[Nindex][j1++];
1533 li_Ncolarray[iMeshNode][i1++] = jacLIDVec[Nindex][j1++];
1534 li_Ncolarray[iMeshNode][i1++] = jacLIDVec[Nindex][j1++];
1535 li_Ncolarray[iMeshNode][i1++] = jacLIDVec[Nindex][j1++];
1536 li_Ncolarray[iMeshNode][i1++] = jacLIDVec[Nindex][j1++];
1541 li_Pcolarray[iMeshNode].resize(9,-1);
1542 li_Pcolarray[iMeshNode][i1++] = jacLIDVec[Pindex][j1++];
1543 li_Pcolarray[iMeshNode][i1++] = jacLIDVec[Pindex][j1++];
1544 li_Pcolarray[iMeshNode][i1++] = jacLIDVec[Pindex][j1++];
1545 li_Pcolarray[iMeshNode][i1++] = jacLIDVec[Pindex][j1++];
1546 li_Pcolarray[iMeshNode][i1++] = jacLIDVec[Pindex][j1++];
1547 li_Pcolarray[iMeshNode][i1++] = jacLIDVec[Pindex][j1++];
1548 li_Pcolarray[iMeshNode][i1++] = jacLIDVec[Pindex][j1++];
1549 li_Pcolarray[iMeshNode][i1++] = jacLIDVec[Pindex][j1++];
1550 li_Pcolarray[iMeshNode][i1++] = jacLIDVec[Pindex][j1++];
1552 #ifdef Xyce_DEBUG_DEVICE
1553 if (getDeviceOptions().debugLevel > 0)
1555 Xyce::dout() << std::endl;
1556 Xyce::dout() <<
"registerJacLIDs: iMeshNode = " << iMeshNode << std::endl;
1557 Xyce::dout() <<
"jacLIDVec[Vindex].size = " << jacLIDVec[Vindex].size()<<std::endl;
1558 Xyce::dout() <<
"jacLIDVec[Nindex].size = " << jacLIDVec[Nindex].size()<<std::endl;
1559 Xyce::dout() <<
"jacLIDVec[Pindex].size = " << jacLIDVec[Pindex].size()<<std::endl;
1563 Xyce::dout() <<
" li_Vcolarray["<<iMeshNode<<
"]["<<i<<
"] = ";
1564 Xyce::dout() << li_Vcolarray[iMeshNode][i] << std::endl;
1566 Xyce::dout() << std::endl;
1569 Xyce::dout() <<
" li_Ncolarray["<<iMeshNode<<
"]["<<i<<
"] = ";
1570 Xyce::dout() << li_Ncolarray[iMeshNode][i] << std::endl;
1572 Xyce::dout() << std::endl;
1575 Xyce::dout() <<
" li_Pcolarray["<<iMeshNode<<
"]["<<i<<
"] = ";
1576 Xyce::dout() << li_Pcolarray[iMeshNode][i] << std::endl;
1578 Xyce::dout() << std::endl;
1584 for (
int iBC=0;iBC<bcVec.size();++iBC)
1586 iMeshNode = bcVec[iBC].meshIndex;
1587 int iNN = bcVec[iBC].neighborNode;
1589 baseIndex = numVars*meshToLID[iMeshNode ] + extVarOffset;
1590 Vindex = baseIndex + Voffset;
1591 Nindex = baseIndex + Noffset;
1592 Pindex = baseIndex + Poffset;
1594 if (edgeBoundarySten[iMeshNode]==1)
1598 li_Vcolarray[iMeshNode].resize(3,-1);
1599 li_Vcolarray[iMeshNode][i1++] = jacLIDVec[Vindex][j1++];
1600 li_Vcolarray[iMeshNode][i1++] = jacLIDVec[Vindex][j1++];
1601 li_Vcolarray[iMeshNode][i1++] = jacLIDVec[Vindex][j1++];
1604 if (iMeshNode < iNN)
1607 li_Ncolarray[iMeshNode].resize(3,-1);
1608 li_Ncolarray[iMeshNode][i1++] = -1;
1609 li_Ncolarray[iMeshNode][i1++] = jacLIDVec[Nindex][j1++];
1610 li_Ncolarray[iMeshNode][i1++] = jacLIDVec[Nindex][j1++];
1613 li_Pcolarray[iMeshNode].resize(3,-1);
1614 li_Pcolarray[iMeshNode][i1++] = -1;
1615 li_Pcolarray[iMeshNode][i1++] = jacLIDVec[Pindex][j1++];
1616 li_Pcolarray[iMeshNode][i1++] = jacLIDVec[Pindex][j1++];
1621 li_Ncolarray[iMeshNode].resize(3,-1);
1622 li_Ncolarray[iMeshNode][i1++] = jacLIDVec[Nindex][j1++];
1623 li_Ncolarray[iMeshNode][i1++] = jacLIDVec[Nindex][j1++];
1626 li_Pcolarray[iMeshNode].resize(3,-1);
1627 li_Pcolarray[iMeshNode][i1++] = jacLIDVec[Pindex][j1++];
1628 li_Pcolarray[iMeshNode][i1++] = jacLIDVec[Pindex][j1++];
1631 else if (internalBoundarySten[iMeshNode]==1)
1636 li_Vcolarray[iMeshNode].resize(6,-1);
1637 li_Vcolarray[iMeshNode][i1++] = jacLIDVec[Vindex][j1++];
1638 li_Vcolarray[iMeshNode][i1++] = jacLIDVec[Vindex][j1++];
1639 li_Vcolarray[iMeshNode][i1++] = jacLIDVec[Vindex][j1++];
1640 li_Vcolarray[iMeshNode][i1++] = jacLIDVec[Vindex][j1++];
1641 li_Vcolarray[iMeshNode][i1++] = jacLIDVec[Vindex][j1++];
1642 li_Vcolarray[iMeshNode][i1++] = jacLIDVec[Vindex][j1++];
1646 li_Ncolarray[iMeshNode].resize(9,-1);
1647 li_Ncolarray[iMeshNode][i1++] = jacLIDVec[Nindex][j1++];
1648 li_Ncolarray[iMeshNode][i1++] = jacLIDVec[Nindex][j1++];
1649 li_Ncolarray[iMeshNode][i1++] = jacLIDVec[Nindex][j1++];
1650 li_Ncolarray[iMeshNode][i1++] = jacLIDVec[Nindex][j1++];
1651 li_Ncolarray[iMeshNode][i1++] = jacLIDVec[Nindex][j1++];
1652 li_Ncolarray[iMeshNode][i1++] = jacLIDVec[Nindex][j1++];
1653 li_Ncolarray[iMeshNode][i1++] = jacLIDVec[Nindex][j1++];
1654 li_Ncolarray[iMeshNode][i1++] = jacLIDVec[Nindex][j1++];
1655 li_Ncolarray[iMeshNode][i1++] = jacLIDVec[Nindex][j1++];
1659 li_Pcolarray[iMeshNode].resize(9,-1);
1660 li_Pcolarray[iMeshNode][i1++] = jacLIDVec[Pindex][j1++];
1661 li_Pcolarray[iMeshNode][i1++] = jacLIDVec[Pindex][j1++];
1662 li_Pcolarray[iMeshNode][i1++] = jacLIDVec[Pindex][j1++];
1663 li_Pcolarray[iMeshNode][i1++] = jacLIDVec[Pindex][j1++];
1664 li_Pcolarray[iMeshNode][i1++] = jacLIDVec[Pindex][j1++];
1665 li_Pcolarray[iMeshNode][i1++] = jacLIDVec[Pindex][j1++];
1666 li_Pcolarray[iMeshNode][i1++] = jacLIDVec[Pindex][j1++];
1667 li_Pcolarray[iMeshNode][i1++] = jacLIDVec[Pindex][j1++];
1668 li_Pcolarray[iMeshNode][i1++] = jacLIDVec[Pindex][j1++];
1672 std::string msg =
"Instance::registerJacLIDs:";
1673 msg +=
"Boundary point not in the stencil.";
1674 N_ERH_ErrorMgr::report( N_ERH_ErrorMgr::DEV_FATAL,msg);
1677 #ifdef Xyce_DEBUG_DEVICE
1678 if (getDeviceOptions().debugLevel > 0)
1680 Xyce::dout() << std::endl;
1681 Xyce::dout() <<
"registerJacLIDs: ("<<bcVec[iBC].eName<<
") iMeshNode = ";
1682 Xyce::dout() << iMeshNode << std::endl;
1685 Xyce::dout() <<
" li_Vcolarray["<<iMeshNode<<
"]["<<i<<
"] = ";
1686 Xyce::dout() << li_Vcolarray[iMeshNode][i] << std::endl;
1688 Xyce::dout() << std::endl;
1691 Xyce::dout() <<
" li_Ncolarray["<<iMeshNode<<
"]["<<i<<
"] = ";
1692 Xyce::dout() << li_Ncolarray[iMeshNode][i] << std::endl;
1694 Xyce::dout() << std::endl;
1697 Xyce::dout() <<
" li_Pcolarray["<<iMeshNode<<
"]["<<i<<
"] = ";
1698 Xyce::dout() << li_Pcolarray[iMeshNode][i] << std::endl;
1700 Xyce::dout() << std::endl;
1731 for (
int i=0;i<
NX;++i)
1740 for (
int j=0;j<vSize;++j)
1749 for (
int j=0;j<nSize;++j)
1758 for (
int j=0;j<pSize;++j)
1777 bool bsuccess =
true;
1780 #ifdef Xyce_DEBUG_DEVICE
1783 Xyce::dout() << section_divider << std::endl;
1784 Xyce::dout() <<
"updateIntermediateVars. name = " <<
getName() << std::endl;
1789 bs1 =
calcEfield (); bsuccess = bsuccess && bs1;
1795 #ifdef Xyce_DEBUG_DEVICE
1798 Xyce::dout() << section_divider << std::endl;
1821 bool bsuccess =
true;
1827 for (iBC=0;iBC<
bcVec.size();++iBC)
1829 int index =
bcVec[iBC].meshIndex;
1830 int iNN=
bcVec[iBC].neighborNode;
1832 double A0=J0*a0*
area;
1834 double sign = ((iNN > index)?1.0:-1.0);
1835 int edgeIndex= ((iNN > index)?index:iNN);
1837 bcVec[iBC].elecCurrent = sign*
JnxVec[edgeIndex]*A0;
1838 bcVec[iBC].holeCurrent = sign*
JpxVec[edgeIndex]*A0;
1842 bcVec[iBC].currentSum =
bcVec[iBC].elecCurrent +
bcVec[iBC].holeCurrent;
1846 std::string & type =
bcVec[iBC].type;
1851 bcVec[iBC].currentSum =
bcVec[iBC].elecCurrent;
1853 else if (type==
"ptype")
1855 bcVec[iBC].currentSum =
bcVec[iBC].holeCurrent;
1859 std::string msg =
"Instance::calcTerminalCurrents";
1860 msg +=
"Unrecognized type on boundary.";
1861 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg);
1866 std::string msg =
"Instance::calcTerminalCurrents";
1867 msg +=
"Unrecognized boundary.";
1868 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg);
1873 bcVec[iBC].currentSum +=
bcVec[iBC].displCurrent;
1880 #ifdef Xyce_DEBUG_DEVICE
1883 Xyce::dout() << Xyce::subsection_divider << std::endl
1884 <<
"Calculated currents, etc., coming from the DD calculation:" << std::endl
1885 <<
" scalingVars.J0 = " << J0<<std::endl
1886 <<
" scalingVars.a0 = " << a0<<std::endl
1887 << Xyce::subsection_divider << std::endl;
1888 for (
int iBC=0;iBC<
bcVec.size();++iBC)
1890 Xyce::dout() <<
bcVec[iBC];
1892 Xyce::dout() << Xyce::subsection_divider << std::endl;
1946 int bcSize =
bcVec.size();
1947 for (iBC=0; iBC < bcSize; ++iBC)
1949 bcVec[iBC].dIdVckt = 0.0;
1955 for (iBC=0;iBC<
bcVec.size();++iBC)
1957 int iN =
bcVec[iBC].meshIndex;
1958 int iNN =
bcVec[iBC].neighborNode;
1959 int dFdVcktIndex = 0;
1975 for (iBC=0;iBC<bcSize;++iBC)
1978 i=
bcVec[iBC].meshIndex;
1982 std::string msg =
"Instance::pdTerminalCurrents";
1983 msg +=
"Unrecognized boundary.";
1984 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg);
1987 int iNN=
bcVec[iBC].neighborNode;
1989 double A0=J0*a0*
area;
1990 std::vector<int> & colA =
bcVec[iBC].li_colArray;
1992 double sign = ((iNN > i)?1.0:-1.0);
1998 double dJndV_nn = 0.0;
1999 double dJpdV_nn = 0.0;
2000 double dJndn_nn = 0.0;
2001 double dJpdp_nn = 0.0;
2034 double Vcoef = (sign* dJndV + sign* dJpdV)*A0;
2035 double Ncoef = (sign* dJndn)*A0;
2036 double Pcoef = (sign* dJpdp)*A0;
2039 double Vcoef_nn = (sign* dJndV_nn + sign* dJpdV_nn)*A0;
2040 double Ncoef_nn = (sign* dJndn_nn)*A0;
2041 double Pcoef_nn = (sign* dJpdp_nn)*A0;
2045 std::string & type =
bcVec[iBC].type;
2053 else if (type==
"ptype")
2060 std::string msg =
"Instance::pdTerminalCurrents";
2061 msg +=
"Unrecognized type on boundary.";
2062 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg);
2072 if (
bcVec[iBC].li_colArray[liOffIndex] != -1)
2074 bcVec[iBC].dIdXcols[count] =
bcVec[iBC].li_colArray[liOffIndex];
2075 bcVec[iBC].dIdX[count] = Vcoef;
2081 if (
bcVec[iBC].li_colArray[liOffIndex] != -1)
2083 bcVec[iBC].dIdXcols[count] =
bcVec[iBC].li_colArray[liOffIndex];
2084 bcVec[iBC].dIdX[count] = Vcoef_nn;
2090 if (
bcVec[iBC].li_colArray[liOffIndex] != -1)
2092 bcVec[iBC].dIdXcols[count] =
bcVec[iBC].li_colArray[liOffIndex];
2093 bcVec[iBC].dIdX[count] = Ncoef;
2099 if (
bcVec[iBC].li_colArray[liOffIndex] != -1)
2101 bcVec[iBC].dIdXcols[count] =
bcVec[iBC].li_colArray[liOffIndex];
2102 bcVec[iBC].dIdX[count] = Ncoef_nn;
2108 if (
bcVec[iBC].li_colArray[liOffIndex] != -1)
2110 bcVec[iBC].dIdXcols[count] =
bcVec[iBC].li_colArray[liOffIndex];
2111 bcVec[iBC].dIdX[count] = Pcoef;
2117 if (
bcVec[iBC].li_colArray[liOffIndex] != -1)
2119 bcVec[iBC].dIdXcols[count] =
bcVec[iBC].li_colArray[liOffIndex];
2120 bcVec[iBC].dIdX[count] = Pcoef_nn;
2155 bool bsuccess =
true;
2157 N_LAS_Vector & dfdv = *(dfdvPtr);
2214 bool bsuccess =
true;
2215 const N_LAS_Vector & dxdv = *dxdvPtr;
2217 #ifdef Xyce_DEBUG_DEVICE
2218 char filename1[256];
2220 for (
int ich = 0; ich < 256; ++ich)
2221 { filename1[ich] = 0; }
2225 Xyce::dout() << section_divider <<
"\n";
2226 Xyce::dout() <<
"calcConductances name = " <<
getName() << std::endl;
2227 Xyce::dout() <<
"electrode = " <<
bcVec[iElectrode].eName;
2228 Xyce::dout() <<
" dIdVckt = " <<
bcVec[iElectrode].dIdVckt;
2229 Xyce::dout() << std::endl;
2230 Xyce::dout() << std::endl;
2234 if (!(
bcVec[iElectrode].dxdvAllocated))
2237 bcVec[iElectrode].dxdvAllocated =
true;
2243 *(
bcVec[iElectrode].dxdvPtr) = *(dxdvPtr);
2250 double dIidVj = 0.0;
2251 double dIidVj_chain = 0.0;
2267 if (iElectrode != iEqu) dIidVj = 0.0;
2268 else dIidVj =
bcVec[iEqu].dIdVckt;
2272 int DIDXSize =
bcVec[iEqu].dIdX.size();
2273 for (
int iDIDX=0;iDIDX<DIDXSize;++iDIDX)
2275 int index =
bcVec[iEqu].dIdXcols[iDIDX];
2276 double coef =
bcVec[iEqu].dIdX[iDIDX];
2278 if (index < 0)
continue;
2283 #ifdef Xyce_DEBUG_DEVICE
2284 sprintf(filename1,
"dIdX%02d.txt", iEqu);
2291 Gij = dIidVj_chain + dIidVj;
2293 condVec[iEqu][iElectrode] = Gij;
2295 #ifdef Xyce_DEBUG_DEVICE
2298 char outstring[128];
2299 double Itmp =
bcVec[iEqu].currentSum;
2300 double Vtmp =
bcVec[iEqu].Vckt -
bcVec[iElectrode].Vckt;
2302 double GV = Gij*Vtmp;
2303 for(
int i=0;i<128;++i) outstring[i] = static_cast<char>(0);
2305 "(%2d,%2d): dotPr=%12.4e G=%12.4e",
2306 iEqu,iElectrode,dIidVj_chain,Gij);
2307 Xyce::dout() << std::string(outstring) << std::endl;
2310 "(%2d,%2d): G=%12.4e G*V=%12.4e I=%12.4e V=%12.4e",
2311 iEqu,iElectrode,Gij,GV,Itmp,Vtmp);
2312 Xyce::dout() << std::string(outstring) << std::endl;
2317 #ifdef Xyce_DEBUG_DEVICE
2320 Xyce::dout() << section_divider << std::endl;
2338 bool bsuccess =
true;
2342 for (
int iBC=0;iBC<
bcVec.size();++iBC)
2344 int li_state=
bcVec[iBC].li_stateC;
2345 staVector[li_state] =
bcVec[iBC].currentSum;
2351 for (i = 0; i<
NX-1; ++i)
2370 bool bsuccess =
true;
2375 for(
int i = 0; i<
NX-1; ++i)
2410 for (
int i=0;i<
NX;++i)
2413 (*maskVectorPtr)[Vrow] = 0.0;
2414 (*maskVectorPtr)[Vrow] = 0.0;
2432 bool bsuccess =
true;
2460 bool bsuccess =
true;
2462 int Vrow, Nrow, Prow;
2473 for (
int iBC=0;iBC<
bcVec.size();++iBC)
2475 int i =
bcVec[iBC].meshIndex;
2482 rhs[Vrow] +=
VVec[i] - (
bcVec[iBC].Vequ);
2505 coef2 = -(holeDens-elecDens+
CVec[i]);
2528 bool bsuccess =
true;
2530 int Vrow, Nrow, Prow;
2538 for (
int iBC=0;iBC<
bcVec.size();++iBC)
2540 rhs[
bcVec[iBC].lid] += bcVec[iBC].currentSum;
2548 for (
int iBC=0;iBC<
bcVec.size();++iBC)
2550 int i =
bcVec[iBC].meshIndex;
2564 std::string & type =
bcVec[iBC].type;
2572 else if (type==
"ptype")
2579 std::string msg =
"Instance::loadVecDDForm";
2580 msg +=
"Unrecognized type on boundary.";
2581 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg);
2586 std::string msg =
"Instance::loadVecDDForm";
2587 msg +=
"Unrecognized stencil on boundary.";
2588 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg);
2642 std::vector<N_UTL_BreakPoint> &breakPointTimes)
2661 bool bsuccess =
true;
2662 int Vrow, Nrow, Prow;
2666 double rUt = 1.0/
Ut;
2668 double elecDens, holeDens;
2676 for (iBC=0;iBC<
bcVec.size();++iBC)
2678 mat[
bcVec[iBC].lid][
bcVec[iBC].lidOffset] = 1.0;
2682 for (
int iBC=0;iBC<
bcVec.size();++iBC)
2684 int i =
bcVec[iBC].meshIndex;
2695 mat[Vrow][offset1] = 0.0;
2696 mat[Vrow][offset2] = 1.0;
2697 mat[Vrow][offset3] = 0.0;
2701 mat[Vrow][offset1] = 0.0;
2702 mat[Vrow][offset2] = 1.0;
2703 mat[Vrow][offset3] = 0.0;
2707 mat[Vrow][offset1] = 0.0;
2708 mat[Vrow][offset2] = 0.0;
2709 mat[Vrow][offset3] = 1.0;
2739 mat[Vrow][offset1] = -L0/(dx1*dx2);
2740 mat[Vrow][offset2] = 2.0*L0/(dx1*dx2) + rUt*holeDens + rUt*elecDens;
2741 mat[Vrow][offset3] = -L0/(dx1*dx2);
2773 for (iBC=0;iBC<
bcVec.size();++iBC)
2776 i=
bcVec[iBC].meshIndex;
2780 std::string msg =
"Instance::loadMatKCLForm";
2781 msg +=
"Unrecognized boundary.";
2782 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg);
2785 int iNN=
bcVec[iBC].neighborNode;
2786 li_row =
bcVec[iBC].lid;
2788 double A0=J0*a0*
area;
2789 std::vector<int> & colA =
bcVec[iBC].li_colArray;
2791 double sign = ((iNN > i)?1.0:-1.0);
2799 double dJndV_nn = 0.0;
2800 double dJpdV_nn = 0.0;
2801 double dJndn_nn = 0.0;
2802 double dJndp_nn = 0.0;
2803 double dJpdp_nn = 0.0;
2804 double dJpdn_nn = 0.0;
2845 double Vcoef = sign*(dJndV + dJpdV)*A0;
2846 double Ncoef = sign*(dJndn + dJpdn)*A0;
2847 double Pcoef = sign*(dJndp + dJpdp)*A0;
2850 double Vcoef_nn = sign*(dJndV_nn + dJpdV_nn)*A0;
2851 double Ncoef_nn = sign*(dJndn_nn + dJpdn_nn)*A0;
2852 double Pcoef_nn = sign*(dJndp_nn + dJpdp_nn)*A0;
2856 std::string & type =
bcVec[iBC].type;
2864 else if (type==
"ptype")
2871 std::string msg =
"Instance::loadMatKCLForm";
2872 msg +=
"Unrecognized type on boundary.";
2873 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg);
2879 mat[li_row][colA[liOffIndex++]] += Vcoef;
2882 mat[li_row][colA[liOffIndex++]] += Vcoef_nn;
2885 mat[li_row][colA[liOffIndex++]] += Ncoef;
2888 mat[li_row][colA[liOffIndex++]] += Ncoef_nn;
2891 mat[li_row][colA[liOffIndex++]] += Pcoef;
2894 mat[li_row][colA[liOffIndex++]] += Pcoef_nn;
2911 bool bsuccess =
true;
2916 for (iBC=0;iBC<
bcVec.size();++iBC)
2918 mat[
bcVec[iBC].lid][
bcVec[iBC].lidOffset] = 1.0;
2934 bool bsuccess =
true;
2937 int Vrow, Nrow, Prow;
2948 #ifdef Xyce_DEBUG_DEVICE
2951 for (
int i=1;i<
LX;++i)
2963 bsuccess = bsuccess && bs1;
2968 bsuccess = bsuccess && bs1;
2972 for (
int iBC=0;iBC<
bcVec.size();++iBC)
2974 int i =
bcVec[iBC].meshIndex;
2982 mat[Vrow][li_Vcolarray[i][1]] = 1.0;
2983 mat[Vrow][li_Vcolarray[i][2]] = 0.0;
2991 mat[Vrow][li_Vcolarray[i][1]] = 1.0;
3000 mat[Vrow][li_Vcolarray[i][2]] = 1.0;
3002 std::string & type =
bcVec[iBC].type;
3015 mat[Prow][li_Pcolarray[i][1]] =
3019 mat[Prow][li_Pcolarray[i][2]] = -
dJpdp2Vec[i]/aveDx;
3022 mat[Prow][li_Pcolarray[i][3]] = (
dJpdV1Vec[i-1]/aveDx);
3025 mat[Prow][li_Pcolarray[i][4]] =
3029 mat[Prow][li_Pcolarray[i][5]] = (-
dJpdV2Vec[i]/aveDx);
3035 mat[Prow][li_Pcolarray[i][6]] =
dJpdn1Vec[i-1]/aveDx;
3038 mat[Prow][li_Pcolarray[i][7]] =
3042 mat[Prow][li_Pcolarray[i][8]] = -
dJpdn2Vec[i]/aveDx;
3044 else if (type==
"ptype")
3054 mat[Nrow][li_Ncolarray[i][1]] =
3058 mat[Nrow][li_Ncolarray[i][2]] =
dJndn2Vec[i]/aveDx;
3061 mat[Nrow][li_Ncolarray[i][3]] = (-
dJndV1Vec[i-1]/aveDx);
3064 mat[Nrow][li_Ncolarray[i][4]] =
3068 mat[Nrow][li_Ncolarray[i][5]] = (
dJndV2Vec[i]/aveDx);
3071 mat[Nrow][li_Ncolarray[i][6]] =
dJndp1Vec[i-1]/aveDx;
3074 mat[Nrow][li_Ncolarray[i][7]] =
3078 mat[Nrow][li_Ncolarray[i][8]] = -
dJndp2Vec[i]/aveDx;
3082 std::string msg =
"Instance::loadMatDDForm";
3083 msg +=
"Unrecognized type on boundary.";
3084 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg);
3102 double dx1 =
dxVec[i-1];
3103 double dx2 =
dxVec[i];
3110 *(
fVmatPtr[i][1])=(2.0*L0/(dx1*dx2));
3201 for (
int i=0;i<
NX;++i)
3221 bool bsuccess =
true;
3232 ci.
N = fabs(
CVec[i]);
3235 if (ci.
N == 0.0) ci.
N = 1.0;
3257 unE_Vec[i] = (unVec[i+1]+unVec[i])/2.0;
3258 upE_Vec[i] = (upVec[i+1]+upVec[i])/2.0;
3263 ci.
N = (fabs(
CVec[i+1])+fabs(
CVec[i]))*0.5;
3266 if (ci.
N == 0.0) ci.
N = 1.0;
3269 ci.
n = pow((fabs(
nnVec[i+1])*fabs(
nnVec[i])),0.5)*
3272 ci.
p = pow((fabs(
npVec[i+1])*fabs(
npVec[i])),0.5)*
3304 bool bsuccess =
true;
3317 mi.
N = (fabs(
CVec[i+1])+fabs(
CVec[i]))*0.5;
3326 if (mi.
N == 0.0) mi.
N = 1.0;
3367 Xyce::dout() <<
"\tfieldDep=true";
3371 Xyce::dout() <<
"\tfieldDep=false";
3373 Xyce::dout() <<
"\tefield ="<<mi.
epar;
3374 Xyce::dout() <<
"\tn ="<<mi.
n;
3375 Xyce::dout() <<
"\tp ="<<mi.
p;
3376 Xyce::dout() <<
"\tNd ="<<mi.
Nd;
3377 Xyce::dout() <<
"\tNa ="<<mi.
Na;
3380 #ifdef Xyce_DEBUG_DEVICE
3383 Xyce::dout() <<
"\tunE["<<i<<
"]="<<
unE_Vec[i];
3384 Xyce::dout() <<
"\tupE["<<i<<
"]="<<
upE_Vec[i];
3385 Xyce::dout() << std::endl;
3420 bool bsuccess =
true;
3466 for (
int i=0;i<
NX;++i)
3484 bool bsuccess (
false);
3485 bool fromFile (
false);
3488 #ifdef Xyce_DEBUG_DEVICE
3491 Xyce::dout() << section_divider << std::endl;
3492 Xyce::dout() <<
"Instance::setupDopingProfile\n";
3533 double xtmp =
xVec[i];
3534 double ndopeDopeValue(0.0), pdopeDopeValue(0.0);
3539 CVec[i] = ndopeDopeValue-pdopeDopeValue;
3552 for (iBC=0;iBC<
bcVec.size();++iBC)
3554 int i =
bcVec[iBC].meshIndex;
3557 bcVec[iBC].type =
"ntype";
3561 bcVec[iBC].type =
"ptype";
3565 #ifdef Xyce_DEBUG_DEVICE
3568 Xyce::dout() <<
"Na = " <<
Na << std::endl;
3569 Xyce::dout() <<
"Nd = " <<
Nd << std::endl;
3572 Xyce::dout() <<
"x[" << i <<
"] = " <<
xVec[i] <<
"\t";
3573 Xyce::dout() <<
"C[" << i <<
"] = " <<
CVec[i] << std::endl;
3576 Xyce::dout() << section_divider << std::endl;
3602 bool bsuccess =
true;
3618 midpoint =
width/2.0;
3619 XL = midpoint -
WJ/2.0;
3620 XR = midpoint +
WJ/2.0;
3643 std::map<std::string, DopeInfo *>::iterator iter;
3644 std::map<std::string, DopeInfo *>::iterator start =
dopeInfoMap.begin();
3645 std::map<std::string, DopeInfo *>::iterator end =
dopeInfoMap.end();
3647 for ( iter = start; iter != end; ++iter )
3665 if (
Na == 0.0 ||
Nd == 0.0)
3669 sprintf(tmpChar,
"Mistake in doping. Na=%12.4e Nd=%12.4e\n",
Na,
Nd);
3670 std::string msg(tmpChar);
3671 N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
3689 double dx_tmp =
width/(
static_cast<double>(
LX));
3691 for (
int i=0;i<
NX;++i)
3693 xVec[i] =
static_cast<double>(i)*dx_tmp;
3696 for (
int i=0;i<
LX;++i)
3702 #ifdef Xyce_DEBUG_DEVICE
3705 for (
int i=0;i<
NX;++i)
3707 Xyce::dout() <<
"x["<<i<<
"] = " <<
xVec[i];
3708 Xyce::dout() <<
"\tdx["<<i<<
"] = " <<
dxVec[i];
3709 Xyce::dout() << std::endl;
3749 bool bsuccess =
true;
3828 #ifdef Xyce_DEBUG_DEVICE
3831 Xyce::dout() <<
"scalingVars.x0 = " <<
scalingVars.
x0 << std::endl;
3832 Xyce::dout() <<
"scalingVars.a0 = " <<
scalingVars.
a0 << std::endl;
3833 Xyce::dout() <<
"scalingVars.T0 = " <<
scalingVars.
T0 << std::endl;
3834 Xyce::dout() <<
"scalingVars.V0 = " <<
scalingVars.
V0 << std::endl;
3835 Xyce::dout() <<
"scalingVars.C0 = " <<
scalingVars.
C0 << std::endl;
3836 Xyce::dout() <<
"scalingVars.D0 = " <<
scalingVars.
D0 << std::endl;
3837 Xyce::dout() <<
"scalingVars.u0 = " <<
scalingVars.
u0 << std::endl;
3838 Xyce::dout() <<
"scalingVars.R0 = " <<
scalingVars.
R0 << std::endl;
3839 Xyce::dout() <<
"scalingVars.t0 = " <<
scalingVars.
t0 << std::endl;
3840 Xyce::dout() <<
"scalingVars.E0 = " <<
scalingVars.
E0 << std::endl;
3841 Xyce::dout() <<
"scalingVars.F0 = " <<
scalingVars.
F0 << std::endl;
3842 Xyce::dout() <<
"scalingVars.J0 = " <<
scalingVars.
J0 << std::endl;
3843 Xyce::dout() <<
"scalingVars.L0 = " <<
scalingVars.
L0 << std::endl;
3871 for (i=0;i<
bcVec.size();++i)
3931 for (i=0;i<
bcVec.size();++i)
3984 bool bsuccess =
true;
3994 for (
int i=0;i<
NX;++i)
4001 tmp = (fabs(Ci)+sqrt(Cisq+4*Nisq))/2.0;
4002 nnVec[i] = ((Ci>=0)?(tmp):(0.0)) + ((Ci<0)?(Nisq/tmp):(0.0));
4005 tmp = (fabs(Ci)+sqrt(Cisq+4*Nisq))/2.0;
4006 npVec[i] = ((Ci<=0)?(tmp):(0.0)) + ((Ci>0)?(Nisq/tmp):(0.0));
4010 double Vmax = -1.0e99;
4011 double Vmin = +1.0e99;
4012 for (
int i=0;i<
NX;++i)
4025 if (Vmax <
VVec[i]) Vmax =
VVec[i];
4026 if (Vmin >
VVec[i]) Vmin =
VVec[i];
4033 for (
int i=0;i<
NX;++i)
4039 for (
int i=0;i<
NX;++i)
4059 bool bsuccess =
true;
4064 double VminBC =+1.0e+99;
4065 double VmaxBC =-1.0e+99;
4067 int bcSize=
bcVec.size();
4068 for (
int i=0;i<bcSize;++i)
4070 int mIndex =
bcVec[i].meshIndex;
4071 double Ci =
CVec[mIndex];
4072 double Cisq = Ci*Ci;
4073 double Nisq = Ni*
Ni;
4074 double tmp, nnTmp, npTmp;
4077 tmp = (fabs(Ci)+sqrt(Cisq+4*Nisq))/2.0;
4078 nnTmp = ((Ci>=0)?(tmp):(0.0)) + ((Ci<0)?(Nisq/tmp):(0.0));
4081 tmp = (fabs(Ci)+sqrt(Cisq+4*Nisq))/2.0;
4082 npTmp = ((Ci<=0)?(tmp):(0.0)) + ((Ci>0)?(Nisq/tmp):(0.0));
4086 ExtendedString mater =
bcVec[i].material;
4089 if (
bcVec[i].VequGiven != 1)
4091 if (mater==
"neutral")
4096 bcVec[i].Vequ = +
Vt * log(nnTmp/Ni);
4100 bcVec[i].Vequ = -
Vt * log(npTmp/Ni);
4111 + 2.0 *
Vt * log(nnTmp/Ni);
4118 - 2.0 *
Vt * log(npTmp/Ni);
4123 if (VminBC >
bcVec[i].Vequ) VminBC =
bcVec[i].Vequ;
4124 if (VmaxBC <
bcVec[i].Vequ) VmaxBC =
bcVec[i].Vequ;
4147 bool bsuccess =
true;
4159 for (iBC=0;iBC<
bcVec.size();++iBC)
4161 int i1 =
bcVec[iBC].meshIndex;
4190 bool bsuccess =
true;
4193 int bcSize=
bcVec.size();
4196 for (iBC=0;iBC<bcSize;++iBC)
4203 for (iBC=0;iBC<bcSize;++iBC)
4235 for (iBC=0;iBC<
bcVec.size();++iBC)
4237 bcVec[iBC].Vckt = (*solVectorPtr)[
bcVec[iBC].lid];
4260 for (
int iBC=0;iBC<
bcVec.size();++iBC)
4264 double delV1 = v1 - v1_old;
4266 if ( delV1 > 1.25 ) v1 = v1_old + 1.25;
4268 if ( delV1 < -0.75) v1 = v1_old - 0.75;
4288 bool bsuccess =
true;
4325 #ifdef Xyce_PDE_DENSITY_CONSTRAINT
4331 #ifdef Xyce_PDE_DENSITY_CONSTRAINT
4369 bool bsuccess =
true;
4371 bool skipOutput =
false;
4382 double outMult =
static_cast<double> (
outputIndex);
4397 if (skipOutput)
return bsuccess;
4401 #ifdef Xyce_DEBUG_DEVICE
4440 char filename[32];
for(i=0;i<32;++i) filename[i] = static_cast<char>(0);
4448 sprintf(filename,
"%s.dat",
outputName.c_str());
4456 fp1 = fopen(filename,
"w");
4462 fp1 = fopen(filename,
"w");
4466 fp1 = fopen(filename,
"a");
4475 " TITLE = \"Spatially Dependent data for PDE diode: %s time = %20.12e seconds. equation set = nonlinear Poisson\",\n",
4481 " TITLE = \"Spatially Dependent data for PDE diode: %s time = %20.12e seconds. equation set = drift diffusion\",\n",
4490 " TITLE = \"Spatially Dependent data for PDE diode: %s time = %20.12e seconds.\",\n",
4500 fprintf(fp1,
"%s",
"\tVARIABLES = \"X \",\n");
4502 fprintf(fp1,
"%s",
"\t \"V \",\n");
4503 fprintf(fp1,
"%s",
"\t \"nn (electron dens.) \",\n");
4504 fprintf(fp1,
"%s",
"\t \"np (hole dens.) \",\n");
4505 fprintf(fp1,
"%s",
"\t \"nn*np (carrier product) \",\n");
4506 fprintf(fp1,
"%s",
"\t \"Dopant density \",\n");
4507 fprintf(fp1,
"%s",
"\t \"fabs(Dopant density)\",\n");
4508 fprintf(fp1,
"%s",
"\t \"electron lifetime \",\n");
4509 fprintf(fp1,
"%s",
"\t \"hole lifetime \",\n");
4512 fprintf(fp1,
"%s",
"\t \"Jn \",\n");
4513 fprintf(fp1,
"%s",
"\t \"Jp \",\n");
4514 fprintf(fp1,
"%s",
"\t \"R \",\n");
4515 fprintf(fp1,
"%s",
"\t \"Ex \",\n");
4516 fprintf(fp1,
"%s",
"\t \"Idispl \", \n");
4520 fprintf(fp1,
"\tZONE F=POINT,I=%d", NX);
4524 fprintf(fp1,
" T = \"DCOP step = %d\" \n",
callsOTEC);
4528 fprintf(fp1,
" T = \"time step = %d time = %20.12e\" AUXDATA time = \"%20.12e seconds\" \n",
callsOTEC , time, time);
4531 double vcorrection = 0.0;
4549 fprintf(fp1,
"%s",
"\n");
4554 fprintf(fp1,
"%s",
"\n");
4558 fprintf(fp1,
"%s",
"\n");
4562 fprintf(fp1,
"%s",
"\n");
4566 fprintf(fp1,
"%s",
"\n");
4568 fprintf(fp1,
"%s",
"\n");
4595 static const int LEN_IDENT2 = 31;
4597 for (i = 0 ; i < 32; ++i)
4598 fileName[i] = static_cast<char>(0);
4603 FILE * handle1 = fopen(fileName,
"w");
4606 double timeVar = 0.0;
4611 sprintf(title,
"%s",
"Xyce diodePDE 1D output");
4613 fwrite(&inx ,
sizeof( UINT), 1, handle1);
4614 fwrite(&numArrays,
sizeof( UINT), 1, handle1);
4615 fwrite( title ,
sizeof(
char),64, handle1);
4616 fwrite(&timeVar ,
sizeof(
double), 1, handle1);
4618 char names[3][LEN_IDENT2];
4619 sprintf(names[0],
"%s",
"V");
4620 sprintf(names[1],
"%s",
"Ne");
4621 sprintf(names[2],
"%s",
"Np");
4624 for(i=0;i<numArrays;++i)
4626 fwrite(names[i],
sizeof(
char),(LEN_IDENT2), handle1);
4629 double vcorrection = 0.0;
4651 fwrite( &
xVec[0],
sizeof(
double),inx , handle1 );
4654 fwrite( &
VVec[0],
sizeof(
double),inx , handle1 );
4657 fwrite( &
nnVec[0],
sizeof(
double),inx , handle1 );
4660 fwrite( &
npVec[0],
sizeof(
double),inx , handle1 );
4686 for (
int i=0;i<
NX;++i)
4691 double n =
nnVec[i];
4692 double p =
npVec[i];
4693 double tn =
tnVec[i];
4694 double tp =
tpVec[i];
4706 RVec[i] = (Rsrh + Raug);
4740 double n =
nnVec[i];
4741 double p =
npVec[i];
4742 double tn =
tnVec[i];
4743 double tp =
tpVec[i];
4757 dRdnVec[i] = dRsrhdn + dRaugdn;
4758 dRdpVec[i] = dRsrhdp + dRaugdp;
4775 for (
int i=0;i<
LX;++i)
4798 for (
int i=0;i<
LX;++i)
4841 for (
int i=0;i<
LX;++i)
4865 for (
int i=0;i<
LX;++i)
4909 for (
int i=0;i<
LX;++i)
4913 absEx = fabs(
ExVec[i]);
4936 bool bnoChange =
true;
4938 int bcSize=
bcVec.size();
4944 for (iBC=0;iBC<bcSize;++iBC)
4952 for (iBC=0;iBC<bcSize;++iBC)
4964 for (iBC=0;iBC<bcSize;++iBC)
4966 double dV,tmp1V, tmp2V;
4967 tmp1V =
bcVec[iBC].Vckt_final;
4968 tmp2V =
bcVec[iBC].Vckt_old;
4971 bcVec[iBC].Vckt_delta = dV;
4973 bcVec[iBC].Vckt_deltaC = dV/
4980 if (fabs(
bcVec[iBC].Vckt_deltaC) > maxDelta)
4982 int tmp_steps =
static_cast<int>(fabs(dV)/maxDelta) + 1;
4985 bcVec[iBC].Vckt_deltaC = dV/
4989 if (fabs(dV) > 1.0e-3) bnoChange =
false;
4992 bcVec[iBC].Vckt_ramp_old =
bcVec[iBC].Vckt_old;
4997 bool bnoChangePhotogen;
4999 bnoChangePhotogen = enablePhotogenContinuation ();
5001 bnoChange = bnoChange && bnoChangePhotogen;
5008 return (!bnoChange);
5023 int bcSize=
bcVec.size();
5024 for (iBC=0;iBC<bcSize;++iBC)
5046 #ifdef Xyce_DEBUG_DEVICE
5047 Xyce::dout() << section_divider << std::endl;
5048 Xyce::dout() <<
"Instance::setPDEContinuationAlpha" << std::endl;
5053 int bcSize=
bcVec.size();
5054 for (
int iBC=0;iBC<bcSize;++iBC)
5056 bcVec[iBC].Vckt_ramp =
bcVec[iBC].Vckt_old + (
bcVec[iBC].Vckt_delta)*alpha;
5059 if ((
bcVec[iBC].Vckt_delta > 0 &&
bcVec[iBC].Vckt_ramp >
bcVec[iBC].Vckt_final) ||
5060 (
bcVec[iBC].Vckt_delta <= 0 &&
bcVec[iBC].Vckt_ramp <=
bcVec[iBC].Vckt_final) )
5062 bcVec[iBC].Vckt_ramp =
bcVec[iBC].Vckt_final;
5065 #ifdef Xyce_DEBUG_DEVICE
5066 Xyce::dout() <<
" " <<
bcVec[iBC].eName <<
" Vckt_ramp = " <<
bcVec[iBC].Vckt_ramp << std::endl;
5081 #ifdef Xyce_DEBUG_DEVICE
5082 Xyce::dout() <<
" photoA1_ramp = " <<
photoA1_ramp << std::endl;
5083 Xyce::dout() << section_divider << std::endl;
5099 .registerDevice(
"pde", 1)
5100 .registerModelType(
"pde", 1)
5101 .registerModelType(
"zod", 1);