51 #include <Xyce_config.h>
54 #ifdef Xyce_DEBUG_DEVICE
71 #include <N_LAS_Vector.h>
72 #include <N_LAS_Matrix.h>
73 #include <N_LAS_System.h>
74 #include <N_LAS_Builder.h>
76 #include <N_UTL_BreakPoint.h>
77 #include <N_UTL_Expression.h>
150 #ifdef Xyce_OXIDE_ENABLED
174 .setDescription(
"Flag for using old (inaccurate) intrinsic carrier calculation.");
204 penaltyPrefacGiven(false),
205 penaltyPowGiven(false),
225 useOldNiGiven(false),
228 usingInternalMesh(false),
230 deviceInitialized(false),
231 meshPerturbed (false),
232 dopingPerturbed (false),
233 photogenPerturbed (false),
237 deviceLength(1.0e-3),
244 #ifdef Xyce_OXIDE_ENABLED
248 gradedJunctionFlag(false),
249 calledBeforeSIGB(false),
256 displCurrentFlag(false),
257 constBoundaryFlag(false),
258 calcConductanceFlag(false),
262 outputNLPoisson(false),
263 lastOutputTime(-10.0),
270 useMatrixGIDFlag(false),
271 useVectorGIDFlag(false),
273 meshCopyContainerPtr(0),
318 boundaryNeighborSten(),
345 meshNeighborMultiMap(),
352 numInterfaceMeshPoints(0),
360 pdTermsAllocated(false),
387 if (
given(
"PH.TYPE"))
395 std::string msg =
"::: ph.type not recognized.\n";
396 N_ERH_ErrorMgr::report( N_ERH_ErrorMgr::DEV_FATAL_0,msg);
403 tmpTypeName.toUpper ();
407 #ifdef Xyce_DEBUG_DEVICE
409 Xyce::dout() <<
"Doing standard initialization of ."<< std::endl;
456 std::map<std::string,DopeInfo *>::iterator iter;
457 std::map<std::string,DopeInfo *>::iterator begin =
dopeInfoMap.begin();
458 std::map<std::string,DopeInfo *>::iterator end =
dopeInfoMap.end ();
460 for(iter=begin;iter!=end;++iter)
462 if (iter->second != 0)
delete iter->second;
469 std::map<std::string, PDE_2DElectrode * >::iterator iterE;
470 std::map<std::string, PDE_2DElectrode * >::iterator beginE =
electrodeMap.begin();
471 std::map<std::string, PDE_2DElectrode * >::iterator endE =
electrodeMap.end ();
473 for(iterE=beginE;iterE!=endE;++iterE)
475 if (iterE->second != 0)
delete iterE->second;
490 if (compositeName ==
"DOPINGPROFILES" || compositeName ==
"REGION")
494 return (static_cast<CompositeParam *> (n));
496 if (compositeName ==
"NODE")
499 ExtendedString dIName = paramName;
502 dINode.
eName = dIName;
503 dINode.
nName = paramName;
512 return (static_cast<CompositeParam *> (n));
515 "Instance::constructComposite: unrecognized composite name: ";
516 msg += compositeName;
517 N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
535 bool bsuccess =
true;
538 #ifdef Xyce_DEBUG_DEVICE
541 Xyce::dout() << section_divider <<
"\n";
542 Xyce::dout() <<
"updateIntermediateVars. name = " <<
getName() << std::endl;
552 bs1 =
calcEfield (); bsuccess = bsuccess && bs1;
563 bsuccess = bsuccess && bs1;
569 bsuccess = bsuccess && bs1;
574 #ifdef Xyce_DEBUG_DEVICE
577 Xyce::dout() << section_divider << std::endl;
595 bool bsuccess =
true;
597 #ifdef Xyce_DEBUG_DEVICE
600 Xyce::dout() << section_divider <<
"\n";
601 Xyce::dout() <<
"calcTerminalCurrents. name = " <<
getName() << std::endl;
606 std::vector<DeviceInterfaceNode>::iterator firstDI =
dIVec.begin ();
607 std::vector<DeviceInterfaceNode>::iterator lastDI =
dIVec.end ();
608 std::vector<DeviceInterfaceNode>::iterator iterDI;
611 for (iterDI=firstDI; iterDI!=lastDI; ++iterDI, ++ind)
619 std::vector<int>::iterator firstI = labelPtr->
mNodeVector.begin();
620 std::vector<int>::iterator lastI = labelPtr->
mNodeVector.end ();
621 std::vector<int>::iterator iterI;
623 iterDI->currentSum = 0.0;
626 for(nodeIndex=0,iterI=firstI;iterI!=lastI;++iterI,++nodeIndex)
632 std::vector<EDGEINFO>::iterator firstEI = nodePtr->
edgeInfoVector.begin();
633 std::vector<EDGEINFO>::iterator lastEI = nodePtr->
edgeInfoVector.end ();
634 std::vector<EDGEINFO>::iterator iterEI;
638 #ifdef Xyce_DEBUG_DEVICE
641 Xyce::dout() <<
" --------------- " << std::endl;
642 Xyce::dout() <<
"name = " << iterDI->eName;
643 Xyce::dout() <<
" node = " << *iterI << std::endl;
647 for (iterEI=firstEI;iterEI!=lastEI;++iterEI)
649 int iedge = iterEI->iedge;
650 int neighbor = iterEI->inode;
652 double ilen = edgePtr->
ilen;
654 double sign = (*iterI < neighbor) ? 1.0 : -1.0;
656 sum += (sign*
JnVec[iedge] + sign*
JpVec[iedge])*ilen;
659 #ifdef Xyce_DEBUG_DEVICE
662 Xyce::dout() <<
" sum*scalingVars.a0 = "<< sum*
scalingVars.
a0 << std::endl;
663 Xyce::dout() <<
" sum = " << sum << std::endl;
664 Xyce::dout() <<
" --------------- " << std::endl;
670 iterDI->currentSum += sum;
691 #ifdef Xyce_DEBUG_DEVICE
694 Xyce::dout().setf(std::ios::scientific);
695 Xyce::dout() <<
" " << iterDI->eName;
696 Xyce::dout() <<
" Ickt = " << iterDI->currentSum << std::endl;
702 #ifdef Xyce_DEBUG_DEVICE
705 Xyce::dout() << section_divider << std::endl;
752 bool bsuccess =
true;
754 std::vector<DeviceInterfaceNode>::iterator firstDI =
dIVec.begin ();
755 std::vector<DeviceInterfaceNode>::iterator lastDI =
dIVec.end ();
756 std::vector<DeviceInterfaceNode>::iterator iterDI;
770 double nodeArea,ilen,elen;
779 for(iterDI=firstDI;iterDI!=lastDI;++iterDI)
781 iterDI->dIdVckt = 0.0;
786 #ifdef Xyce_DEBUG_DEVICE
789 Xyce::dout() << Xyce::subsection_divider << std::endl;
793 if (iterDI->gid ==-1)
continue;
798 std::vector<int>::iterator firstI = labelPtr->
mNodeVector.begin();
799 std::vector<int>::iterator lastI = labelPtr->
mNodeVector.end ();
800 std::vector<int>::iterator iterI;
802 std::vector<EDGEINFO>::iterator firstEI;
803 std::vector<EDGEINFO>::iterator lastEI;
804 std::vector<EDGEINFO>::iterator iterEI;
813 for(nodeIndex=0,iterI=firstI;iterI!=lastI;++iterI,++nodeIndex)
821 for (iterEI=firstEI; iterEI!=lastEI; ++iterEI)
823 iedge = iterEI->iedge;
824 inodeB = iterEI->inode;
826 ilen = edgePtr->
ilen;
833 sign = (*iterI < inodeB) ? 1.0 : -1.0;
846 coef += (sign* dJndV + sign* dJpdV)*ilen;
851 iterDI->dIdVckt += tmpsum;
853 #ifdef Xyce_DEBUG_DEVICE
856 Xyce::dout().setf(std::ios::left);
857 Xyce::dout() << iterDI->eName<<
":";
858 Xyce::dout() <<
" KCL pdTerminalCurrent row = " << iterDI->gid;
859 Xyce::dout() <<
" contrib = " << tmpsum;
860 Xyce::dout() <<
" dIdVckt = " << iterDI->dIdVckt << std::endl;
866 #endif // Xyce_NEW_BC
870 #ifdef Xyce_DEBUG_DEVICE
873 Xyce::dout() << Xyce::subsection_divider << std::endl;
876 #endif // Xyce_NEW_BC
880 for(iterDI=firstDI;iterDI!=lastDI;++iterDI)
885 int size = iterDI->dFdVckt.size();
886 for (itmp=0;itmp<size;++itmp)
888 iterDI->dFdVckt[itmp] = 0.0;
891 int numNeighbor = iterDI->neighborNodes.size();
895 for (iNeighbor=0;iNeighbor<numNeighbor;++iNeighbor)
897 int inode = iterDI->neighborNodes[iNeighbor];
900 nodeArea = nodePtr->
area;
904 for (iNN=0;iNN<nodePtr->
cnode;++iNN)
924 iterDI->dFdVckt[dFdVindex] = coef;
929 if (inode>inodeB) { dJdV =
dJndV1Vec[iedge]; }
932 coef = ((inode<inodeB)?1.0:-1.0) * dJdV * ilen/nodeArea;
935 iterDI->dFdVckt[dFdVindex] = coef;
940 if (inode>inodeB) { dJdV =
dJpdV1Vec[iedge]; }
943 coef = -((inode<inodeB)?1.0:-1.0) * dJdV * ilen/nodeArea;
946 iterDI->dFdVckt[dFdVindex] = coef;
950 #ifdef Xyce_DEBUG_DEVICE
953 Xyce::dout() <<
"-----" << std::endl;
954 Xyce::dout() <<
"neighbor nodes for boundary: " << iterDI->eName << std::endl;
955 Xyce::dout() <<
"-----" << std::endl;
956 for (iNeighbor=0;iNeighbor<numNeighbor;++iNeighbor)
958 int inode = iterDI->neighborNodes[iNeighbor];
959 Xyce::dout() <<
"\t"<<iNeighbor<<
" "<< inode << std::endl;
962 Xyce::dout() <<
"-----" << std::endl;
963 Xyce::dout() <<
"dFdVckt vector for boundary: " << iterDI->eName << std::endl;
964 Xyce::dout() <<
"-----" << std::endl;
968 for (iNeighbor=0;iNeighbor<numNeighbor;++iNeighbor)
970 int inode = iterDI->neighborNodes[iNeighbor];
979 for (iNN=0;iNN<nodePtr->
cnode;++iNN)
990 dfdV = iterDI->dFdVckt[idf];
991 Xyce::dout() <<
"\t"<<idf;
992 Xyce::dout() <<
" \tv_"<<inode<<
"\t"<<Vrow<<
"\t"<<dfdV<< std::endl;
995 dfdV = iterDI->dFdVckt[idf];
996 Xyce::dout() <<
"\t"<<idf;
997 Xyce::dout() <<
" \tn_"<<inode<<
"\t"<<Nrow<<
"\t"<<dfdV<< std::endl;
1000 dfdV = iterDI->dFdVckt[idf];
1001 Xyce::dout() <<
"\t"<<idf;
1002 Xyce::dout() <<
" \tp_"<<inode<<
"\t"<<Prow<<
"\t"<<dfdV<< std::endl;
1006 Xyce::dout() <<
"-----" << std::endl;
1010 #else // old BC not set up yet.
1012 #endif // Xyce_NEW_BC
1018 for(iterDI=firstDI;iterDI!=lastDI;++iterDI)
1023 int numdIdX = iterDI->dIdX.size ();
1024 for (
int j=0;j<numdIdX;++j)
1026 iterDI->dIdX[j] = 0.0;
1032 std::vector<int>::iterator firstI = labelPtr->
mNodeVector.begin();
1033 std::vector<int>::iterator lastI = labelPtr->
mNodeVector.end ();
1034 std::vector<int>::iterator iterI;
1036 std::vector<EDGEINFO>::iterator firstEI;
1037 std::vector<EDGEINFO>::iterator lastEI;
1038 std::vector<EDGEINFO>::iterator iterEI;
1046 for(nodeIndex=0,iterI=firstI;iterI!=lastI;++iterI,++nodeIndex)
1056 for (iterEI=firstEI; iterEI!=lastEI; ++iterEI)
1058 iedge = iterEI->iedge;
1059 inodeB = iterEI->inode;
1060 sign = (*iterI < inodeB) ? 1.0 : -1.0;
1062 ilen = edgePtr->
ilen;
1079 Vcoef += (sign* dJndV + sign* dJpdV)*ilen;
1080 Ncoef += (sign* dJndn)*ilen;
1081 Pcoef += (sign* dJpdp)*ilen;
1085 col1 = iterDI->Vcol[iVcol];
1090 int size = iterDI->dIdXcols.size();
1091 for (cnt2=0;cnt2<size;++cnt2)
1093 if (iterDI->dIdXcols[cnt2] == col1)
1094 { bmatch =
true;
break; }
1098 msg =
"pdTerminalCurrents: Could not find a column match in dIdXcols";
1099 N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
1104 Xyce::dout() << iterDI->eName;
1107 col1 = iterDI->Ncol[iNcol];
1112 int size = iterDI->dIdXcols.size();
1113 for (cnt2=0;cnt2<size;++cnt2)
1115 if (iterDI->dIdXcols[cnt2] == col1)
1116 { bmatch =
true;
break; }
1120 msg =
"pdTerminalCurrents: Could not find a column match in dIdXcols";
1121 N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
1127 col1 = iterDI->Pcol[iPcol];
1132 int size = iterDI->dIdXcols.size();
1133 for (cnt2=0;cnt2<size;++cnt2)
1135 if (iterDI->dIdXcols[cnt2] == col1)
1136 { bmatch =
true;
break; }
1140 msg =
"pdTerminalCurrents: Could not find a column match in dIdXcols";
1141 N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
1152 for (iterEI=firstEI; iterEI!=lastEI; ++iterEI,++iVcol,++iNcol,++iPcol)
1154 iedge = iterEI->iedge;
1155 inodeB = iterEI->inode;
1156 sign = (*iterI < inodeB) ? 1.0 : -1.0;
1158 ilen = edgePtr->
ilen;
1175 Vcoef = (sign* dJndV + sign* dJpdV)*ilen;
1176 Ncoef = (sign* dJndn)*ilen;
1177 Pcoef = (sign* dJpdp)*ilen;
1179 col1 = iterDI->Vcol[iVcol];
1184 int size = iterDI->dIdXcols.size();
1185 for (cnt2=0;cnt2<size;++cnt2)
1187 if (iterDI->dIdXcols[cnt2] == col1)
1188 { bmatch =
true;
break; }
1192 msg =
"pdTerminalCurrents: Could not find a column match in dIdXcols";
1193 N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
1199 col1 = iterDI->Ncol[iNcol];
1204 for (cnt2=0;cnt2<iterDI->dIdXcols.size();++cnt2)
1206 if (iterDI->dIdXcols[cnt2] == col1)
1207 { bmatch =
true;
break; }
1211 msg =
"pdTerminalCurrents: Could not find a column match in dIdXcols";
1212 N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
1218 col1 = iterDI->Pcol[iPcol];
1223 int size = iterDI->dIdXcols.size();
1224 for (cnt2=0;cnt2<size;++cnt2)
1226 if (iterDI->dIdXcols[cnt2] == col1)
1227 { bmatch =
true;
break; }
1231 msg =
"pdTerminalCurrents: Could not find a column match in dIdXcols";
1232 N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
1241 #ifdef Xyce_DEBUG_DEVICE
1244 for(iterDI=firstDI;iterDI!=lastDI;++iterDI)
1246 int size = iterDI->dIdXcols.size();
1247 int size2= iterDI->dIdX.size ();
1248 Xyce::dout() <<
"dIdX for electrode: " << iterDI->eName << std::endl;
1249 for (
int ididx=0;ididx<size;++ididx)
1251 Xyce::dout() <<
"\t"<< iterDI->dIdXcols[ididx];
1252 Xyce::dout() <<
"\t"<< iterDI->dIdX[ididx] << std::endl;
1255 Xyce::dout() <<
"Done with Instance::pdTerminalCurrents" << std::endl;
1279 bool bsuccess =
true;
1281 #ifdef Xyce_DEBUG_DEVICE
1284 Xyce::dout() << section_divider <<
"\n";
1285 Xyce::dout() <<
"calcTerminalCharges. name = " <<
getName() << std::endl;
1290 std::vector<DeviceInterfaceNode>::iterator firstDI =
dIVec.begin ();
1291 std::vector<DeviceInterfaceNode>::iterator lastDI =
dIVec.end ();
1292 std::vector<DeviceInterfaceNode>::iterator iterDI;
1294 for (iterDI=firstDI; iterDI!=lastDI; ++iterDI)
1302 std::vector<int>::iterator firstI = labelPtr->
mNodeVector.begin();
1303 std::vector<int>::iterator lastI = labelPtr->
mNodeVector.end ();
1304 std::vector<int>::iterator iterI;
1306 iterDI->chargeSum = 0.0;
1309 for(nodeIndex=0,iterI=firstI;iterI!=lastI;++iterI,++nodeIndex)
1315 std::vector<EDGEINFO>::iterator firstEI = nodePtr->
edgeInfoVector.begin();
1316 std::vector<EDGEINFO>::iterator lastEI = nodePtr->
edgeInfoVector.end ();
1317 std::vector<EDGEINFO>::iterator iterEI;
1321 #ifdef Xyce_DEBUG_DEVICE
1324 Xyce::dout() <<
" --------------- " << std::endl;
1325 Xyce::dout() <<
"name = " << iterDI->eName;
1326 Xyce::dout() <<
" node = " << *iterI << std::endl;
1330 for (iterEI=firstEI;iterEI!=lastEI;++iterEI)
1332 int iedge = iterEI->iedge;
1333 int neighbor = iterEI->inode;
1336 double ilen = edgePtr->
ilen;
1338 double sign = (*iterI < neighbor) ? +1.0 : -1.0;
1343 #ifdef Xyce_DEBUG_DEVICE
1346 Xyce::dout() <<
"neighbor = "<< neighbor;
1347 Xyce::dout() <<
" Efield = " <<
EfieldVec[iedge];
1348 Xyce::dout() <<
" contrib = " << contrib << std::endl;
1354 #ifdef Xyce_DEBUG_DEVICE
1357 Xyce::dout() <<
" sum*scalingVars.a0 = "<< sum*tmp << std::endl;
1358 Xyce::dout() <<
" sum = " << sum << std::endl;
1359 Xyce::dout() <<
" --------------- " << std::endl;
1365 iterDI->chargeSum += sum;
1369 #ifdef Xyce_DEBUG_DEVICE
1372 Xyce::dout().setf(std::ios::scientific);
1373 Xyce::dout() <<
" " << iterDI->eName;
1374 Xyce::dout() <<
" terminal charge = " << iterDI->chargeSum << std::endl;
1380 #ifdef Xyce_DEBUG_DEVICE
1383 Xyce::dout() << section_divider << std::endl;
1419 bool bsuccess =
true;
1421 std::vector<DeviceInterfaceNode>::iterator firstDI =
dIVec.begin ();
1422 std::vector<DeviceInterfaceNode>::iterator lastDI =
dIVec.end ();
1423 std::vector<DeviceInterfaceNode>::iterator iterDI;
1441 for(iterDI=firstDI;iterDI!=lastDI;++iterDI)
1443 iterDI->dQdVckt = 0.0;
1448 #ifdef Xyce_DEBUG_DEVICE
1451 Xyce::dout() << Xyce::subsection_divider << std::endl;
1455 if (iterDI->gid ==-1)
continue;
1460 std::vector<int>::iterator firstI = labelPtr->
mNodeVector.begin();
1461 std::vector<int>::iterator lastI = labelPtr->
mNodeVector.end ();
1462 std::vector<int>::iterator iterI;
1464 std::vector<EDGEINFO>::iterator firstEI;
1465 std::vector<EDGEINFO>::iterator lastEI;
1466 std::vector<EDGEINFO>::iterator iterEI;
1475 for(nodeIndex=0,iterI=firstI;iterI!=lastI;++iterI,++nodeIndex)
1483 for (iterEI=firstEI; iterEI!=lastEI; ++iterEI)
1485 iedge = iterEI->iedge;
1486 inodeB = iterEI->inode;
1489 double elen = edgePtr->
elen;
1490 double ilen = edgePtr->
ilen;
1502 coef += sign* dEdV * ilen;
1507 iterDI->dQdVckt += tmpsum;
1509 #ifdef Xyce_DEBUG_DEVICE
1512 Xyce::dout().setf(std::ios::left);
1513 Xyce::dout() << iterDI->eName<<
":";
1514 Xyce::dout() <<
" KCL pdTerminalCharges row = " << iterDI->gid;
1515 Xyce::dout() <<
" contrib = " << tmpsum;
1516 Xyce::dout() <<
" dQdVckt = " << iterDI->dQdVckt << std::endl;
1522 #endif // Xyce_NEW_BC
1527 #ifdef Xyce_DEBUG_DEVICE
1530 Xyce::dout() << Xyce::subsection_divider << std::endl;
1533 #endif // Xyce_NEW_BC
1537 for(iterDI=firstDI;iterDI!=lastDI;++iterDI)
1541 int numdQdX = iterDI->dQdX.size ();
1542 for (
int j=0;j<numdQdX;++j)
1544 iterDI->dQdX[j] = 0.0;
1550 std::vector<int>::iterator firstI = labelPtr->
mNodeVector.begin();
1551 std::vector<int>::iterator lastI = labelPtr->
mNodeVector.end ();
1552 std::vector<int>::iterator iterI;
1554 std::vector<EDGEINFO>::iterator firstEI;
1555 std::vector<EDGEINFO>::iterator lastEI;
1556 std::vector<EDGEINFO>::iterator iterEI;
1564 for(nodeIndex=0,iterI=firstI;iterI!=lastI;++iterI,++nodeIndex)
1572 for (iterEI=firstEI; iterEI!=lastEI; ++iterEI)
1574 iedge = iterEI->iedge;
1575 inodeB = iterEI->inode;
1580 double elen = edgePtr->
elen;
1581 double ilen = edgePtr->
ilen;
1584 Vcoef += sign* dEdV * ilen;
1588 col1 = iterDI->Vcol[iVcol];
1593 for (cnt2=0;cnt2<iterDI->dIdXcols.size();++cnt2)
1595 if (iterDI->dIdXcols[cnt2] == col1)
1596 { bmatch =
true;
break; }
1600 msg =
"pdTerminalCharges: Could not find a column match in dIdXcols";
1601 N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
1610 for (iterEI=firstEI; iterEI!=lastEI; ++iterEI,++iVcol,++iNcol,++iPcol)
1612 iedge = iterEI->iedge;
1613 inodeB = iterEI->inode;
1618 double elen = edgePtr->
elen;
1619 double ilen = edgePtr->
ilen;
1622 Vcoef = sign* dEdV * ilen;
1624 col1 = iterDI->Vcol[iVcol];
1629 for (cnt2=0;cnt2<iterDI->dIdXcols.size();++cnt2)
1631 if (iterDI->dIdXcols[cnt2] == col1)
1632 { bmatch =
true;
break; }
1636 msg =
"pdTerminalCharges: Could not find a column match in dIdXcols";
1637 N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
1646 #ifdef Xyce_DEBUG_DEVICE
1649 for(iterDI=firstDI;iterDI!=lastDI;++iterDI)
1651 int size = iterDI->dIdXcols.size();
1652 int size2= iterDI->dQdX.size ();
1653 Xyce::dout() <<
"dQdX for electrode: " << iterDI->eName << std::endl;
1654 for (
int ididx=0;ididx<size;++ididx)
1656 Xyce::dout() <<
"\t"<< iterDI->dIdXcols[ididx];
1657 Xyce::dout() <<
"\t"<< iterDI->dQdX[ididx] << std::endl;
1660 Xyce::dout() <<
"Done with Instance::pdTerminalCharges" << std::endl;
1692 bool bsuccess =
true;
1695 N_LAS_Vector & dfdv = *dfdvPtr;
1702 for (iNeighbor=0;iNeighbor<numNeighbor;++iNeighbor)
1712 for (iNN=0;iNN<nodePtr->
cnode;++iNN)
1724 coef = dINode.
dFdVckt[dFdVindex];
1729 bs1 = dfdv.setElementByGlobalIndex(Vrow, -coef, 0);
1730 bsuccess = bsuccess && bs1;
1741 coef = dINode.
dFdVckt[dFdVindex];
1746 bs1 = dfdv.setElementByGlobalIndex(Nrow, -coef, 0);
1747 bsuccess = bsuccess && bs1;
1758 coef = dINode.
dFdVckt[dFdVindex];
1763 bs1 = dfdv.setElementByGlobalIndex(Prow, -coef, 0);
1764 bsuccess = bsuccess && bs1;
1819 bool bsuccess =
true;
1820 const N_LAS_Vector & dxdv = *dxdvPtr;
1824 #ifdef Xyce_DEBUG_DEVICE
1827 Xyce::dout() << section_divider <<
"\n";
1828 Xyce::dout() <<
"calcConductances name = " <<
getName() << std::endl;
1829 Xyce::dout() <<
"electrode = " <<
dIVec[iElectrode].eName;
1830 Xyce::dout() <<
" dIdVckt = " <<
dIVec[iElectrode].dIdVckt;
1831 Xyce::dout() << std::endl;
1832 Xyce::dout() << std::endl;
1836 if (!(
dIVec[iElectrode].dxdvAllocated))
1839 dIVec[iElectrode].dxdvAllocated =
true;
1845 *(
dIVec[iElectrode].dxdvPtr) = *(dxdvPtr);
1852 double dIidVj = 0.0;
1853 double dIidVj_chain = 0.0;
1856 double dQidVj = 0.0;
1857 double dQidVj_chain = 0.0;
1873 if (iElectrode != iEqu)
1880 dIidVj =
dIVec[iEqu].dIdVckt;
1881 dQidVj =
dIVec[iEqu].dQdVckt;
1887 int DIDXSize =
dIVec[iEqu].dIdX.size();
1888 for (
int iDIDX=0;iDIDX<DIDXSize;++iDIDX)
1890 int index =
dIVec[iEqu].dIdXcols[iDIDX];
1891 double coefI =
dIVec[iEqu].dIdX[iDIDX];
1892 double coefQ =
dIVec[iEqu].dQdX[iDIDX];
1911 #ifdef Xyce_DEBUG_DEVICE
1913 std::ostringstream oss;
1914 oss <<
"dIdX" << std::setw(2) << std::setfill(
'0') << iEqu <<
".txt";
1918 std::ostringstream oss;
1919 oss <<
"dQdX" << std::setw(2) << std::setfill(
'0') << iEqu <<
".txt";
1928 Gij = dIidVj_chain + dIidVj;
1929 condVec[iEqu][iElectrode] = Gij;
1936 Cij = dQidVj_chain + dQidVj;
1937 capVec[iEqu][iElectrode] = Cij;
1939 #ifdef Xyce_DEBUG_DEVICE
1942 char outstring[128];
1943 double Itmp =
dIVec[iEqu].currentSum;
1944 double Vtmp =
dIVec[iEqu].Vckt -
dIVec[iElectrode].Vckt;
1946 double GV = Gij*Vtmp;
1947 for(
int i=0;i<128;++i) outstring[i] = static_cast<char>(0);
1949 "(%2d,%2d): dotPr=%12.4e G=%12.4e",
1950 iEqu,iElectrode,dIidVj_chain,Gij);
1951 Xyce::dout() << std::string(outstring) << std::endl;
1954 "(%2d,%2d): G=%12.4e G*V=%12.4e I=%12.4e V=%12.4e",
1955 iEqu,iElectrode,Gij,GV,Itmp,Vtmp);
1956 Xyce::dout() << std::string(outstring) << std::endl;
1961 #ifdef Xyce_DEBUG_DEVICE
1964 Xyce::dout() << section_divider << std::endl;
1981 bool bsuccess =
true;
1985 std::vector<DeviceInterfaceNode>::iterator firstDI =
dIVec.begin();
1986 std::vector<DeviceInterfaceNode>::iterator lastDI =
dIVec.end ();
1987 std::vector<DeviceInterfaceNode>::iterator iterDI = firstDI;
1989 for (; iterDI!=lastDI;++iterDI)
1993 if (iterDI->stateC_owned)
1996 (staVectorPtr)->setElementByGlobalIndex( iterDI->stateC,
1997 iterDI->currentSum, 0);
2002 (*staVectorPtr)[iterDI->li_stateC] = iterDI->currentSum;
2009 #ifdef Xyce_OLD_DISPLACEMENT
2020 (staVectorPtr)->setElementByGlobalIndex(
stateDispl[i], D, 0);
2065 bool bsuccess =
true;
2072 std::vector<DeviceInterfaceNode>::iterator firstDI =
dIVec.begin();
2073 std::vector<DeviceInterfaceNode>::iterator lastDI =
dIVec.end ();
2074 std::vector<DeviceInterfaceNode>::iterator iterDI = firstDI;
2076 for (; iterDI!=lastDI;++iterDI)
2081 iterDI->currentSum =
2082 (staVectorPtr)->getElementByGlobalIndex( iterDI->stateC, 0);
2086 iterDI->currentSum = (*staVectorPtr)[iterDI->li_stateC];
2094 #ifdef Xyce_OLD_DISPLACEMENT
2134 int inodeA = edgePtr->
inodeA;
2135 int inodeB = edgePtr->
inodeB;
2136 double elen = edgePtr->
elen;
2146 #ifdef Xyce_DEBUG_DEVICE
2148 Xyce::dout() <<
" Maximum displacement current: " << dcmax << std::endl;
2176 bool bsuccess =
true;
2179 #ifdef Xyce_DEBUG_DEVICE
2182 Xyce::dout() <<
"Instance::setInitialGuess\n";
2199 #ifdef Xyce_DEBUG_DEVICE
2237 bool bsuccess =
true;
2241 int Vrow, Nrow, Prow;
2246 double ilen, elen, nodeArea;
2252 #ifdef Xyce_DEBUG_DEVICE
2255 Xyce::dout() << section_divider <<
"\n";
2256 Xyce::dout() <<
"Instance::loadVecNLPoisson\n";
2257 Xyce::dout() <<
" name = " <<
getName() <<
"\n";
2259 Xyce::dout() <<
" Vt = " <<
Vt <<
"\n";
2260 Xyce::dout() <<
" Ut = " <<
Ut <<
"\n";
2261 Xyce::dout() <<
" scalingVars.V0 = " <<
scalingVars.
V0 <<
"\n";
2269 #ifdef Xyce_DEBUG_DEVICE
2272 Xyce::dout() <<
"--------" << std::endl;
2273 Xyce::dout() <<
"Mesh Point i = " << i;
2300 #else // "old" boundary condition:
2301 bool doneFlag =
false;
2311 int i1 =
dIVec[DIindex].meshGlobalToLocal[i];
2312 coef = vtmp -
dIVec[DIindex].VbcVec[i1];
2314 #ifdef Xyce_DEBUG_DEVICE
2317 Xyce::dout() <<
"BC load: Vrow = " << Vrow <<
" coef = " << coef << std::endl;
2318 Xyce::dout() <<
" vtmp = " << vtmp << std::endl;
2319 Xyce::dout() <<
" Vckt = " <<
dIVec[DIindex].Vckt << std::endl;
2324 bs1 = vecPtr->sumElementByGlobalIndex(Vrow, -scalar*coef, 0);
2325 bsuccess = bsuccess && bs1;
2326 bs1 = vecPtr->sumElementByGlobalIndex(Nrow, 0.0 , 0);
2327 bsuccess = bsuccess && bs1;
2328 bs1 = vecPtr->sumElementByGlobalIndex(Prow, 0.0 , 0);
2329 bsuccess = bsuccess && bs1;
2333 (*vecPtr)[Vrow] += -scalar*coef;
2334 (*vecPtr)[Nrow] += 0.0;
2335 (*vecPtr)[Prow] += 0.0;
2343 if (doneFlag)
continue;
2344 #endif // Xyce_NEW_BC
2348 nodeArea = nodePtr->
area;
2349 #ifdef Xyce_DEBUG_DEVICE
2352 Xyce::dout() <<
"--------" << std::endl;
2353 Xyce::dout() <<
"Interior: mesh point: " << i <<
" Vrow = " << Vrow;
2354 Xyce::dout() << std::endl;
2359 for (
int iNN=0;iNN<nodePtr->
cnode;++iNN)
2366 double efield_loc = (
VVec[i]-
VVec[inodeB])/elen;
2367 coef += -efield_loc * ilen ;
2368 #ifdef Xyce_DEBUG_DEVICE
2371 Xyce::dout() <<
"----" << std::endl;
2372 Xyce::dout() <<
" iedge = " << iedge << std::endl;
2373 Xyce::dout() <<
" Vlocal = " <<
VVec[i] << std::endl;
2374 Xyce::dout() <<
" Vneigh = " <<
VVec[inodeB] << std::endl;
2375 Xyce::dout() <<
" efield = " << efield_loc << std::endl;
2376 Xyce::dout() <<
" elen = " << elen << std::endl;
2377 Xyce::dout() <<
" ilen = " << ilen << std::endl;
2378 Xyce::dout() <<
" inodeB = " << inodeB;
2381 Xyce::dout() << std::endl;
2389 coef2 = -(holeDens-elecDens+
CVec[i]);
2391 #ifdef Xyce_OXIDE_ENABLED
2400 #ifdef Xyce_DEBUG_DEVICE
2403 Xyce::dout() <<
"--------" << std::endl;
2404 Xyce::dout() <<
" holeD = " << holeDens << std::endl;
2405 Xyce::dout() <<
" elecD = " << elecDens << std::endl;
2406 Xyce::dout() <<
" dopeD = " <<
CVec[i] << std::endl;
2407 Xyce::dout() <<
" coef2 = " << coef2 << std::endl;
2409 Xyce::dout() <<
" nodeArea = " << nodeArea << std::endl;
2410 Xyce::dout() <<
" coef = " << coef << std::endl;
2411 Xyce::dout() <<
"--------" << std::endl;
2417 bs1 = vecPtr->sumElementByGlobalIndex(Vrow, -scalar*coef, 0);
2418 bsuccess = bsuccess && bs1;
2419 bs1 = vecPtr->sumElementByGlobalIndex(Nrow, 0.0 , 0);
2420 bsuccess = bsuccess && bs1;
2421 bs1 = vecPtr->sumElementByGlobalIndex(Prow, 0.0 , 0);
2422 bsuccess = bsuccess && bs1;
2426 (*vecPtr)[Vrow] += -scalar*coef;
2427 (*vecPtr)[Nrow] += 0.0;
2428 (*vecPtr)[Prow] += 0.0;
2433 #ifdef Xyce_DEBUG_DEVICE
2435 Xyce::dout() << section_divider << std::endl;
2450 (
double scalar,
double dndtScalar, N_LAS_Vector * vecPtr)
2452 bool bsuccess =
true;
2454 std::string semi(bulkMaterial);
2457 int Vrow, Nrow, Prow;
2459 double ilen, elen, nodeArea;
2460 double holeDens, elecDens;
2467 #ifdef Xyce_DEBUG_DEVICE
2468 if (getDeviceOptions().debugLevel > 0 && getSolverState().debugTimeFlag)
2470 Xyce::dout() <<
"\n"<<section_divider << std::endl;
2471 Xyce::dout() <<
"Instance::loadVecDDForm\n";
2472 Xyce::dout() <<
" name = " <<
getName() <<
"\n";
2477 std::vector<DeviceInterfaceNode>::iterator firstDI = dIVec.begin();
2478 std::vector<DeviceInterfaceNode>::iterator lastDI = dIVec.end ();
2479 std::vector<DeviceInterfaceNode>::iterator iterDI = firstDI;
2485 for (;iterDI!=lastDI;++iterDI)
2487 coef = iterDI->currentSum;
2489 if( useVectorGIDFlag )
2491 if (iterDI->gid != -1)
2493 bs1 = vecPtr->sumElementByGlobalIndex(iterDI->gid, -scalar*coef, 0);
2494 bsuccess = bsuccess && bs1;
2499 (*vecPtr)[iterDI->lid] += -scalar*coef;
2502 #ifdef Xyce_DEBUG_DEVICE
2503 if (getDeviceOptions().debugLevel > 0 && getSolverState().debugTimeFlag)
2505 Xyce::dout() <<
"KCL for "<< iterDI->eName <<
":\n";
2506 Xyce::dout() <<
" row = " << iterDI->gid <<
"\n";
2507 Xyce::dout() <<
"coef = " << coef <<
"\n";
2515 for (i=0;i<numMeshPoints;++i)
2517 #ifdef Xyce_DEBUG_DEVICE
2518 if (getDeviceOptions().debugLevel > 1 && getSolverState().debugTimeFlag)
2520 Xyce::dout() <<
"--------" << std::endl;
2521 Xyce::dout() <<
"Mesh Point i = " << i;
2522 Xyce::dout() <<
" x = " << xVec[i]*scalingVars.x0;
2523 Xyce::dout() <<
" y = " << yVec[i]*scalingVars.x0 << std::endl;
2527 if( useVectorGIDFlag )
2529 Vrow = Vrowarray[i];
2530 Nrow = Nrowarray[i];
2531 Prow = Prowarray[i];
2535 Vrow = li_Vrowarray[i];
2536 Nrow = li_Nrowarray[i];
2537 Prow = li_Prowarray[i];
2540 bool doneFlagV =
false;
2541 bool doneFlagN =
false;
2542 bool doneFlagP =
false;
2548 if (boundarySten[i])
continue;
2550 bool doneFlag =
false;
2557 if (boundarySten[i])
2559 int DIindex = labelDIMap[labelNameVector[i]];
2561 if (dIVec[DIindex].given)
2563 int ilocal = dIVec[DIindex].meshGlobalToLocal[i];
2565 if (dIVec[DIindex].neumannBCFlagV==
false)
2568 if (vOwnVec[i] == 1) vtmp = VVec[i];
2570 coef = vtmp - dIVec[DIindex].VbcVec[ilocal];
2572 if( useVectorGIDFlag )
2574 bs1 = vecPtr->sumElementByGlobalIndex(Vrow, -scalar*coef, 0);
2575 bsuccess = bsuccess && bs1;
2579 (*vecPtr)[Vrow] += -scalar*coef;
2582 #ifdef Xyce_DEBUG_DEVICE
2583 if (getDeviceOptions().debugLevel > 1 && getSolverState().debugTimeFlag)
2585 Xyce::dout() <<
"BC load: Vrow = " << Vrow;
2586 Xyce::dout() <<
" coef = " << coef << std::endl;
2587 Xyce::dout() <<
" vtmp = " << vtmp << std::endl;
2588 Xyce::dout() <<
" Vckt = " << dIVec[DIindex].Vckt << std::endl;
2589 Xyce::dout() <<
" Vequ = " << dIVec[DIindex].VequVec[ilocal] << std::endl;
2595 if (dIVec[DIindex].neumannBCFlagN==
false)
2598 if (nnOwnVec[i] == 1) ntmp = nnVec[i];
2599 coef = ntmp - (dIVec[DIindex].nnbcVec[ilocal]);
2601 if( useVectorGIDFlag )
2603 bs1 = vecPtr->sumElementByGlobalIndex(Nrow, -scalar*coef , 0);
2604 bsuccess = bsuccess && bs1;
2608 (*vecPtr)[Nrow] += -scalar*coef;
2611 #ifdef Xyce_DEBUG_DEVICE
2612 if (getDeviceOptions().debugLevel > 1 && getSolverState().debugTimeFlag)
2614 Xyce::dout() <<
"BC load: Nrow = ";
2615 Xyce::dout() << Nrow <<
" coef = " << coef << std::endl;
2616 Xyce::dout() <<
" ntmp = " << ntmp << std::endl;
2617 Xyce::dout() <<
" nnbc = " << dIVec[DIindex].nnbcVec[ilocal] << std::endl;
2624 if (dIVec[DIindex].neumannBCFlagP==
false)
2627 if (npOwnVec[i] == 1) ptmp = npVec[i];
2628 coef = ptmp - (dIVec[DIindex].npbcVec[ilocal]);
2630 if( useVectorGIDFlag )
2632 bs1 = vecPtr->sumElementByGlobalIndex(Prow, -scalar*coef , 0);
2633 bsuccess = bsuccess && bs1;
2637 (*vecPtr)[Prow] += -scalar*coef;
2640 #ifdef Xyce_DEBUG_DEVICE
2641 if (getDeviceOptions().debugLevel > 1 && getSolverState().debugTimeFlag)
2643 Xyce::dout() <<
"BC load: Prow = ";
2644 Xyce::dout() << Prow <<
" coef = " << coef << std::endl;
2645 Xyce::dout() <<
" ptmp = " << ptmp << std::endl;
2646 Xyce::dout() <<
" npbc = " << dIVec[DIindex].npbcVec[ilocal] << std::endl;
2652 doneFlag = (doneFlagV && doneFlagN && doneFlagP);
2657 if (doneFlag)
continue;
2659 #endif // Xyce_NEW_BC
2663 mNode * nodePtr = meshContainerPtr->getNode(i);
2664 nodeArea = nodePtr->
area;
2665 #ifdef Xyce_DEBUG_DEVICE
2666 if (getDeviceOptions().debugLevel > 1 && getSolverState().debugTimeFlag)
2668 Xyce::dout() <<
"--------" << std::endl;
2669 Xyce::dout() <<
"Interior: mesh point: " << i <<
" Vrow = " << Vrow;
2670 Xyce::dout() << std::endl;
2677 #ifdef Xyce_DEBUG_DEVICE
2678 if (getDeviceOptions().debugLevel > 1 && getSolverState().debugTimeFlag)
2680 Xyce::dout() <<
"--------" << std::endl;
2681 Xyce::dout() <<
" Poisson equ:";
2686 for (iNN=0;iNN<nodePtr->
cnode;++iNN)
2694 double efield_loc = (VVec[i]-VVec[inodeB])/elen;
2695 coef += -efield_loc * ilen ;
2696 #ifdef Xyce_DEBUG_DEVICE
2697 if (getDeviceOptions().debugLevel > 1 && getSolverState().debugTimeFlag)
2699 Xyce::dout() <<
"----" << std::endl;
2700 Xyce::dout() <<
" iedge = " << iedge << std::endl;
2701 Xyce::dout() <<
" Vlocal = " << VVec[i] << std::endl;
2702 Xyce::dout() <<
" Vneigh = " << VVec[inodeB] << std::endl;
2703 Xyce::dout() <<
" efield = " << efield_loc << std::endl;
2704 Xyce::dout() <<
" elen = " << elen << std::endl;
2705 Xyce::dout() <<
" ilen = " << ilen << std::endl;
2706 Xyce::dout() <<
" inodeB = " << inodeB;
2707 Xyce::dout() <<
" x[b] = " << xVec[inodeB]*scalingVars.x0;
2708 Xyce::dout() <<
" y[b] = " << yVec[inodeB]*scalingVars.x0 << std::endl;
2709 Xyce::dout() << std::endl;
2715 holeDens = npVec[i];
2716 elecDens = nnVec[i];
2717 coef2 = -(holeDens-elecDens+CVec[i]);
2719 #ifdef Xyce_OXIDE_ENABLED
2728 #ifdef Xyce_DEBUG_DEVICE
2729 if (getDeviceOptions().debugLevel > 1 && getSolverState().debugTimeFlag)
2731 Xyce::dout() <<
"--------" << std::endl;
2732 Xyce::dout() <<
" holeD = " << holeDens << std::endl;
2733 Xyce::dout() <<
" elecD = " << elecDens << std::endl;
2734 Xyce::dout() <<
" dopeD = " << CVec[i] << std::endl;
2735 Xyce::dout() <<
" coef2 = " << coef2 << std::endl;
2737 Xyce::dout() <<
" nodeArea = " << nodeArea << std::endl;
2738 Xyce::dout() <<
" coef = " << coef << std::endl;
2739 Xyce::dout() <<
"--------" << std::endl;
2742 if ( getSolverState().chargeHomotopy )
2744 coef *= getSolverState().chargeAlpha;
2747 if( useVectorGIDFlag )
2749 bs1 = vecPtr->sumElementByGlobalIndex(Vrow, -scalar*coef, 0);
2750 bsuccess = bsuccess && bs1;
2754 (*vecPtr)[Vrow] += -scalar*coef;
2766 #ifdef Xyce_DEBUG_DEVICE
2767 if (getDeviceOptions().debugLevel > 1 && getSolverState().debugTimeFlag)
2769 Xyce::dout() <<
"--------" << std::endl;
2770 Xyce::dout() <<
" Electron equ:";
2776 for (iNN=0;iNN<nodePtr->
cnode;++iNN)
2783 coef += ((i<inodeB)?1.0:-1.0) * JnVec[iedge] * ilen ;
2785 #ifdef Xyce_DEBUG_DEVICE
2786 if (getDeviceOptions().debugLevel > 1 && getSolverState().debugTimeFlag)
2788 Xyce::dout() <<
"----" << std::endl;
2789 Xyce::dout() <<
" iedge = " << iedge << std::endl;
2790 Xyce::dout() <<
" Jn = " << JnVec[iedge] << std::endl;
2791 Xyce::dout() <<
" nlocal = " << nnVec[i] << std::endl;
2792 Xyce::dout() <<
" nneigh = " << nnVec[inodeB] << std::endl;
2793 Xyce::dout() <<
" elen = " << elen << std::endl;
2794 Xyce::dout() <<
" ilen = " << ilen << std::endl;
2795 Xyce::dout() <<
" inodeB = " << inodeB;
2796 Xyce::dout() <<
" x[b] = " << xVec[inodeB]*scalingVars.x0;
2797 Xyce::dout() <<
" y[b] = " << yVec[inodeB]*scalingVars.x0 << std::endl;
2798 Xyce::dout() << std::endl;
2804 coef += - totSrcVec[i] - dndt;
2806 coef += - RVec[i] - dndt;
2809 coef += elecPenalty[i];
2811 #ifdef Xyce_DEBUG_DEVICE
2812 if (getDeviceOptions().debugLevel > 1 && getSolverState().debugTimeFlag)
2814 Xyce::dout() <<
"--------" << std::endl;
2815 Xyce::dout().setf(std::ios::left);
2816 Xyce::dout() <<
" row = " << Nrow;
2817 Xyce::dout().setf(std::ios::scientific);
2818 Xyce::dout() <<
" coef=" << coef;
2819 Xyce::dout() <<
" nodeArea ="<<nodeArea;
2820 Xyce::dout() <<
" R[i]="<<RVec[i];
2821 Xyce::dout() <<
" dndt="<<dndt;
2822 Xyce::dout() <<
"\n";
2823 Xyce::dout() <<
"--------" << std::endl;
2827 if( useVectorGIDFlag )
2829 bs1 = vecPtr->setElementByGlobalIndex(Nrow,-scalar*coef,0);
2830 bsuccess = bsuccess && bs1;
2834 (*vecPtr)[Nrow] += -scalar*coef;
2845 #ifdef Xyce_DEBUG_DEVICE
2846 if (getDeviceOptions().debugLevel > 1 && getSolverState().debugTimeFlag)
2848 Xyce::dout() <<
"--------" << std::endl;
2849 Xyce::dout() <<
" Hole equ:";
2855 for (iNN=0;iNN<nodePtr->
cnode;++iNN)
2862 coef += ((i<inodeB)?1.0:-1.0) * JpVec[iedge] * ilen ;
2864 #ifdef Xyce_DEBUG_DEVICE
2865 if (getDeviceOptions().debugLevel > 1 && getSolverState().debugTimeFlag)
2867 Xyce::dout() <<
"----" << std::endl;
2868 Xyce::dout() <<
" iedge = " << iedge << std::endl;
2869 Xyce::dout() <<
" Jp = " << JpVec[iedge] << std::endl;
2870 Xyce::dout() <<
" plocal = " << npVec[i] << std::endl;
2871 Xyce::dout() <<
" pneigh = " << npVec[inodeB] << std::endl;
2872 Xyce::dout() <<
" elen = " << elen << std::endl;
2873 Xyce::dout() <<
" ilen = " << ilen << std::endl;
2874 Xyce::dout() <<
" inodeB = " << inodeB;
2875 Xyce::dout() <<
" x[b] = " << xVec[inodeB]*scalingVars.x0;
2876 Xyce::dout() <<
" y[b] = " << yVec[inodeB]*scalingVars.x0 << std::endl;
2877 Xyce::dout() << std::endl;
2884 coef += - totSrcVec[i] - dpdt;
2886 coef += - RVec[i] - dpdt;
2888 coef += holePenalty[i];
2890 #ifdef Xyce_DEBUG_DEVICE
2891 if (getDeviceOptions().debugLevel > 1 && getSolverState().debugTimeFlag)
2893 Xyce::dout() <<
"--------" << std::endl;
2894 Xyce::dout().setf(std::ios::left);
2895 Xyce::dout() <<
" row = " << Prow;
2896 Xyce::dout().setf(std::ios::scientific);
2897 Xyce::dout() <<
" coef=" << coef;
2898 Xyce::dout() <<
" nodeArea ="<<nodeArea;
2899 Xyce::dout() <<
" RVec[i]="<<RVec[i];
2900 Xyce::dout() <<
" dpdt="<<dpdt;
2901 Xyce::dout() <<
"\n";
2902 Xyce::dout() <<
"--------" << std::endl;
2906 if( useVectorGIDFlag )
2908 bs1 = vecPtr->setElementByGlobalIndex(Prow,-scalar*coef,0);
2909 bsuccess = bsuccess && bs1;
2913 (*vecPtr)[Prow] += -scalar*coef;
2922 #ifdef Xyce_DEBUG_DEVICE
2923 if (getDeviceOptions().debugLevel > 0 && getSolverState().debugTimeFlag)
2924 Xyce::dout() << section_divider << std::endl;
2941 bool bsuccess =
true;
2944 int Vrow, Nrow, Prow;
2946 #ifdef Xyce_DEBUG_DEVICE
2949 Xyce::dout() << section_divider <<
"\n";
2950 Xyce::dout() <<
"Instance::loadJacNonlinPoisson" <<
"\n";
2951 Xyce::dout() <<
" name = " <<
getName() <<
"\n";
2952 Xyce::dout() <<
"\n";
2960 double pre = 1.0/
Ut;
2968 double ilen, elen, nodeArea;
2970 #ifdef Xyce_DEBUG_DEVICE
2974 Xyce::dout() <<
"pre = " << pre <<
"\n";
2975 Xyce::dout() <<
"Vt = " <<
Vt <<
"\n";
2976 Xyce::dout() <<
"eps = " <<
eps <<
"\n";
2977 Xyce::dout() <<
"q = " << q <<
"\n";
2978 Xyce::dout() <<
"Na = " <<
Na <<
"\n";
2979 Xyce::dout() <<
"Nd = " <<
Nd <<
"\n";
2980 Xyce::dout() <<
"NpMax = " <<
NpMax <<
"\n";
2981 Xyce::dout() <<
"NnMax = " <<
NnMax <<
"\n";
2986 int numCol =
cols.size();
2996 for (j=0;j<numCol;++j)
3002 std::vector<DeviceInterfaceNode>::iterator firstDI =
dIVec.begin ();
3003 std::vector<DeviceInterfaceNode>::iterator lastDI =
dIVec.end ();
3004 std::vector<DeviceInterfaceNode>::iterator iterDI;
3011 for(iterDI=firstDI;iterDI!=lastDI;++iterDI)
3013 if (iterDI->gid !=-1)
3015 cols[0] = iterDI->gid;
3016 bs1 = matPtr->putRow (iterDI->gid, 1, &
vals[0], &
cols[0]);
3017 bsuccess = bsuccess && bs1;
3026 #ifdef Xyce_DEBUG_DEVICE
3029 Xyce::dout() <<
"\nmesh point i = " << i << std::endl;
3032 for (j=0;j<numCol;++j)
3045 bool doneFlag =
false;
3062 if (
dIVec[DIindex].gid != -1)
3072 bs1 = matPtr->putRow (Vrow, count, &
vals[0], &
cols[0]);
3073 bsuccess = bsuccess && bs1;
3075 #ifdef Xyce_DEBUG_DEVICE
3078 Xyce::dout() <<
"BC load: Vrow = " << Vrow << std::endl;
3079 for (
int eric=0;eric<count;++eric)
3081 Xyce::dout() <<
" cols["<<eric<<
"] = " <<
cols[eric];
3082 Xyce::dout() <<
" vals["<<eric<<
"] = " <<
vals[eric];
3083 Xyce::dout() << std::endl;
3094 bs1 = matPtr->putRow (Nrow, 1, &
vals[0], &
cols[0]);
3095 bsuccess = bsuccess && bs1;
3097 #ifdef Xyce_DEBUG_DEVICE
3100 Xyce::dout() <<
"BC load: Nrow = " << Nrow;
3101 Xyce::dout() <<
" coef = " <<
vals[0] << std::endl;
3112 bs1 = matPtr->putRow (Prow, 1, &
vals[0], &
cols[0]);
3113 bsuccess = bsuccess && bs1;
3115 #ifdef Xyce_DEBUG_DEVICE
3118 Xyce::dout() <<
"BC load: Prow = " << Vrow;
3119 Xyce::dout() <<
" coef = " <<
vals[0] << std::endl;
3129 if (doneFlag)
continue;
3130 #endif // Xyce_NEW_BC
3135 #ifdef Xyce_OXIDE_ENABLED
3147 nodeArea = nodePtr->
area;
3152 for (iNN=0;iNN<nodePtr->
cnode;++iNN)
3163 #ifdef Xyce_OXIDE_ENABLED
3166 coef += pre*holeDens + pre*elecDens;
3169 coef += pre*holeDens + pre*elecDens;
3180 Xyce::dout() <<
" center point: i="<<i;
3181 Xyce::dout() <<
" xVec[i] = " <<
xVec[i];
3182 Xyce::dout() <<
" yVec[i] = " <<
yVec[i];
3183 Xyce::dout() << std::endl;
3185 Xyce::dout() <<
" boundarySten = " <<
boundarySten[i] << std::endl;
3186 Xyce::dout() <<
" Vcolarray[i][0] = ";
3187 Xyce::dout() <<
Vcolarray[i][0] << std::endl;
3192 for (iNN=0;iNN<nodePtr->
cnode;++iNN)
3194 #ifdef Xyce_DEBUG_DEVICE
3197 Xyce::dout() <<
"non-center point: i="<<i;
3198 Xyce::dout() <<
" Vcolarray[i]["<<iNN+1<<
"] = ";
3199 Xyce::dout() <<
Vcolarray[i][iNN+1] << std::endl;
3202 if (
Vcolarray[i][iNN+1] == -1)
continue;
3216 #ifdef Xyce_DEBUG_DEVICE
3219 Xyce::dout() <<
"\n";
3220 Xyce::dout().setf(std::ios::left);
3221 Xyce::dout() <<
" POISSON LOAD: row = " << Vrow;
3222 Xyce::dout() <<
" count = " << count <<
"\n";
3223 Xyce::dout().setf(std::ios::scientific);
3224 for (j=0;j<count;++j)
3226 Xyce::dout() <<
" cols["<<j<<
"] = " <<
cols[j];
3227 Xyce::dout() <<
" vals["<<j<<
"] = " <<
vals[j];
3228 Xyce::dout() << std::endl;
3233 if (Vrow != -1 && count > 0)
3235 bs1 = matPtr->putRow (Vrow, count, &
vals[0], &
cols[0]);
3236 bsuccess = bsuccess && bs1;
3240 Xyce::dout() <<
"OOOPS!" << std::endl;
3249 bs1 = matPtr->putRow (Nrow, 1, &
vals[0], &
cols[0]);
3250 bsuccess = bsuccess && bs1;
3257 bs1 = matPtr->putRow (Prow, 1, &
vals[0], &
cols[0]);
3258 bsuccess = bsuccess && bs1;
3261 #ifdef Xyce_DEBUG_DEVICE
3264 Xyce::dout() << subsection_divider <<
"\n";
3284 bool doneFlag =
false;
3297 (*matPtr)[Vrow][Voff[0]] = 1.0;
3301 (*matPtr)[Nrow][Noff[0]] = 1.0;
3304 (*matPtr)[Prow][Poff[0]] = 1.0;
3310 if (doneFlag)
continue;
3311 #endif // Xyce_NEW_BC
3316 #ifdef Xyce_OXIDE_ENABLED
3328 nodeArea = nodePtr->
area;
3333 for (iNN=0;iNN<nodePtr->
cnode;++iNN)
3344 #ifdef Xyce_OXIDE_ENABLED
3347 coef += pre*holeDens + pre*elecDens;
3350 coef += pre*holeDens + pre*elecDens;
3353 (*matPtr)[Vrow][Voff[0]] += coef;
3357 for (iNN=0;iNN<nodePtr->
cnode;++iNN)
3361 if (
Vcolarray[i][iNN+1] == -1)
continue;
3370 (*matPtr)[Vrow][Voff[iNN+1]] += coef;
3374 (*matPtr)[Nrow][Noff[0]] = 1.0;
3377 (*matPtr)[Prow][Poff[0]] = 1.0;
3382 #ifdef Xyce_DEBUG_DEVICE
3385 Xyce::dout() << section_divider << std::endl;
3402 bool bsuccess =
true;
3407 #ifdef Xyce_DEBUG_DEVICE
3410 Xyce::dout() <<
"Starting Instance::loadJacKCLDDFormulation" << std::endl;
3414 std::vector<DeviceInterfaceNode>::iterator firstDI =
dIVec.begin ();
3415 std::vector<DeviceInterfaceNode>::iterator lastDI =
dIVec.end ();
3416 std::vector<DeviceInterfaceNode>::iterator iterDI;
3420 int numCol =
cols.size();
3424 for (j=0;j<numCol;++j)
3430 for(iterDI=firstDI;iterDI!=lastDI;++iterDI)
3432 if (iterDI->gid ==-1)
continue;
3435 cols[count] = iterDI->gid;
3443 vals[0] = iterDI->dIdVckt;
3445 #ifdef Xyce_DEBUG_DEVICE
3448 Xyce::dout() <<
"\n";
3449 Xyce::dout().setf(std::ios::left);
3450 Xyce::dout() <<
" KCL new BC LOAD: row = " << iterDI->gid;
3451 Xyce::dout() <<
" count = " << count;
3452 Xyce::dout() <<
" name = " << iterDI->eName <<
"\n";
3454 Xyce::dout().setf(std::ios::scientific);
3455 Xyce::dout() <<
" cols[0] = " <<
cols[0];
3456 Xyce::dout() <<
" vals[0] = " <<
vals[0];
3457 Xyce::dout() << std::endl;
3460 bs1 = matPtr->sumIntoRow (iterDI->gid, count, &
vals[0], &
cols[0]);
3461 bsuccess = bsuccess && bs1;
3462 #endif // Xyce_NEW_BC
3466 count = iterDI->dIdXcols.size();
3468 #ifdef Xyce_DEBUG_DEVICE
3471 Xyce::dout() <<
"\n";
3472 Xyce::dout().setf(std::ios::left);
3473 Xyce::dout() <<
" KCL LOAD: row = " << iterDI->gid;
3474 Xyce::dout() <<
" count = " << count;
3475 Xyce::dout() <<
" name = " << iterDI->eName <<
"\n";
3477 Xyce::dout().setf(std::ios::scientific);
3478 for (j=0;j<count;++j)
3480 Xyce::dout() <<
" cols["<<j<<
"] = " << iterDI->dIdXcols[j];
3481 Xyce::dout() <<
" vals["<<j<<
"] = " << iterDI->dIdX[j];
3482 Xyce::dout() << std::endl;
3487 bs1 = matPtr->sumIntoRow
3488 (iterDI->gid, count, &(iterDI->dIdX[0]), &(iterDI->dIdXcols[0]));
3489 bsuccess = bsuccess && bs1;
3495 for(iterDI=firstDI;iterDI!=lastDI;++iterDI)
3499 int offset = iterDI->lidOffset;
3502 coef = iterDI->dIdVckt;
3503 #endif // Xyce_NEW_BC
3505 (*matPtr)[iterDI->lid][offset] += coef;
3509 int size = iterDI->dIdXcols.size();
3510 for (
int i=0;i<size;++i)
3512 coef = iterDI->dIdX[i];
3513 offset = iterDI->dIdXoffset[i];
3514 (*matPtr)[iterDI->lid][offset] += coef;
3515 #ifdef Xyce_DEBUG_DEVICE
3518 Xyce::dout() <<
"dIdX["<<i<<
"] = " << iterDI->dIdX[i];
3519 Xyce::dout() <<
" dIdXcols["<<i<<
"] = " << iterDI->dIdXcols[i];
3520 Xyce::dout() <<
" dIdXoffset["<<i<<
"] = " << iterDI->dIdXoffset[i];
3521 Xyce::dout() << std::endl;
3528 #ifdef Xyce_DEBUG_DEVICE
3531 Xyce::dout() <<
"Done with Instance::loadJacKCLDDFormulation" << std::endl;
3552 bool bsuccess =
true;
3556 int numCol =
cols.size();
3559 std::vector<DeviceInterfaceNode>::iterator firstDI =
dIVec.begin ();
3560 std::vector<DeviceInterfaceNode>::iterator lastDI =
dIVec.end ();
3561 std::vector<DeviceInterfaceNode>::iterator iterDI;
3566 for(iterDI=firstDI;iterDI!=lastDI;++iterDI)
3568 if (iterDI->gid !=-1)
3570 cols[0] = iterDI->gid;
3571 bs1 = matPtr->putRow (iterDI->gid, 1, &
vals[0], &
cols[0]);
3572 bsuccess = bsuccess && bs1;
3578 for(iterDI=firstDI;iterDI!=lastDI;++iterDI)
3580 (*matPtr)[iterDI->lid][iterDI->lidOffset] = 1.0;
3596 (
double dndtScalar, N_LAS_Matrix * matPtr)
3598 bool bsuccess =
true;
3601 int Vrow, Nrow, Prow;
3603 #ifdef Xyce_DEBUG_DEVICE
3604 if (getDeviceOptions().debugLevel > 1 && getSolverState().debugTimeFlag)
3606 Xyce::dout() <<
"\n"<<section_divider <<
"\n";
3607 Xyce::dout() <<
"Instance::loadMatDDForm" <<
"\n";
3608 Xyce::dout() <<
" name = " <<
getName() <<
"\n";
3609 Xyce::dout() <<
"\n";
3622 double ilen, elen, nodeArea;
3625 int numCol = cols.size();
3626 if (vals.size () < cols.size()) numCol = vals.size();
3628 #ifdef Xyce_DEBUG_DEVICE
3636 if (!(getSolverState().dcopFlag))
3638 dDNDTdn = getSolverState().pdt*scalingVars.t0*dndtScalar;
3639 dDPDTdp = getSolverState().pdt*scalingVars.t0*dndtScalar;
3648 for (j=0;j<numCol;++j) { cols[j] = -1; vals[j] = 0.0; }
3651 if( useMatrixGIDFlag )
3653 for (i=0;i<numMeshPoints;++i)
3655 Vrow = Vrowarray[i];
3656 Nrow = Nrowarray[i];
3657 Prow = Prowarray[i];
3659 #ifdef Xyce_DEBUG_DEVICE
3660 if (getDeviceOptions().debugLevel > 2 && getSolverState().debugTimeFlag)
3662 Xyce::dout() << subsection_divider <<
"\n";
3663 Xyce::dout() <<
"mesh point i = " << i;
3664 Xyce::dout() <<
" Vrow = " << Vrow;
3665 Xyce::dout() <<
" Nrow = " << Nrow;
3666 Xyce::dout() <<
" Prow = " << Prow;
3667 Xyce::dout() <<
"\n";
3671 bool doneFlagV =
false;
3672 bool doneFlagN =
false;
3673 bool doneFlagP =
false;
3674 bool doneFlag =
false;
3676 if (boundarySten[i])
continue;
3681 if (boundarySten[i])
3683 int DIindex = labelDIMap[labelNameVector[i]];
3685 if (dIVec[DIindex].given)
3687 if (dIVec[DIindex].neumannBCFlagV==
false)
3689 #ifdef Xyce_DEBUG_DEVICE
3690 if (getDeviceOptions().debugLevel > 2 && getSolverState().debugTimeFlag)
3692 Xyce::dout() <<
"BC load: Vrow = " << Vrow << std::endl;
3702 if (dIVec[DIindex].gid != -1)
3705 vals[1] = -scalingVars.rV0;
3706 cols[1] = dIVec[DIindex].gid;
3712 bs1 = matPtr->putRow (Vrow, count, &vals[0], &cols[0]);
3713 bsuccess = bsuccess && bs1;
3715 #ifdef Xyce_DEBUG_DEVICE
3716 if (getDeviceOptions().debugLevel > 2 && getSolverState().debugTimeFlag)
3718 Xyce::dout() <<
"BC load: Vrow = " << Vrow << std::endl;
3719 for (
int eric=0;eric<count;++eric)
3721 Xyce::dout() <<
" cols["<<eric<<
"] = " << cols[eric];
3722 Xyce::dout() <<
" vals["<<eric<<
"] = " << vals[eric];
3723 Xyce::dout() << std::endl;
3732 if (dIVec[DIindex].neumannBCFlagN==
false)
3739 bs1 = matPtr->putRow (Nrow, 1, &vals[0], &cols[0]);
3740 bsuccess = bsuccess && bs1;
3742 #ifdef Xyce_DEBUG_DEVICE
3743 if (getDeviceOptions().debugLevel > 2 && getSolverState().debugTimeFlag)
3745 Xyce::dout() <<
"BC load: Nrow = " << Nrow << std::endl;
3746 for (
int eric=0;eric<count;++eric)
3748 Xyce::dout() <<
" cols["<<eric<<
"] = " << cols[eric];
3749 Xyce::dout() <<
" vals["<<eric<<
"] = " << vals[eric];
3750 Xyce::dout() << std::endl;
3758 if (dIVec[DIindex].neumannBCFlagP==
false)
3765 bs1 = matPtr->putRow (Prow, 1, &vals[0], &cols[0]);
3766 bsuccess = bsuccess && bs1;
3768 #ifdef Xyce_DEBUG_DEVICE
3769 if (getDeviceOptions().debugLevel > 2 && getSolverState().debugTimeFlag)
3771 Xyce::dout() <<
"BC load: Prow = " << Prow << std::endl;
3772 for (
int eric=0;eric<count;++eric)
3774 Xyce::dout() <<
" cols["<<eric<<
"] = " << cols[eric];
3775 Xyce::dout() <<
" vals["<<eric<<
"] = " << vals[eric];
3776 Xyce::dout() << std::endl;
3784 doneFlag = (doneFlagV && doneFlagN && doneFlagP);
3788 if (doneFlag)
continue;
3790 #endif // Xyce_NEW_BC
3793 std::string semi(bulkMaterial);
3795 mNode * nodePtr = meshContainerPtr->getNode(i);
3796 nodeArea = nodePtr->
area;
3801 for (j=0;j<numCol;++j) { cols[j] = -1; vals[j] = 0.0; }
3807 for (iNN=0;iNN<nodePtr->
cnode;++iNN)
3817 if (Vcolarray[i][0] != -1)
3819 cols[count] = Vcolarray[i][0];
3823 #ifdef Xyce_DEBUG_DEVICE
3826 Xyce::dout() <<
" center point: i="<<i;
3827 Xyce::dout() <<
" Vcolarray[i][0] = " << Vcolarray[i][0] << std::endl;
3834 for (iNN=0;iNN<nodePtr->
cnode;++iNN)
3836 #ifdef Xyce_DEBUG_DEVICE
3837 if (getDeviceOptions().debugLevel > 2 && getSolverState().debugTimeFlag)
3839 Xyce::dout() <<
"non-center point: i="<<i;
3840 Xyce::dout() <<
" Vcolarray[i]["<<iNN+1<<
"] = ";
3841 Xyce::dout() << Vcolarray[i][iNN+1] << std::endl;
3844 int tmpCol = Vcolarray[i][iNN+1];
3846 if (tmpCol == -1)
continue;
3855 coef *= ((boundarySten[inodeB]==1)?(scalingVars.rV0):1.0);
3858 if (boundarySten[inodeB]==1)
3861 for (cnt2=0;cnt2<count;++cnt2)
3863 if (cols[cnt2] == tmpCol)
3864 { bmatch =
true;
break; }
3866 if (!bmatch) { cnt2 = count; ++count;}
3876 #endif // Xyce_NEW_BC
3877 cols[cnt2] = tmpCol;
3882 if (Ncolarray[i][0] != -1)
3884 cols[count] = Ncolarray[i][0];
3890 if (Pcolarray[i][0] != -1)
3892 cols[count] = Pcolarray[i][0];
3897 #ifdef Xyce_DEBUG_DEVICE
3898 if (getDeviceOptions().debugLevel > 2 && getSolverState().debugTimeFlag)
3900 Xyce::dout() <<
"\n";
3901 Xyce::dout().setf(std::ios::left);
3902 Xyce::dout() <<
" POISSON LOAD: row = " << Vrow;
3903 Xyce::dout() <<
" count = " << count <<
"\n";
3904 Xyce::dout().setf(std::ios::scientific);
3905 for (j=0;j<count;++j)
3907 Xyce::dout() <<
" cols["<<j<<
"] = " << cols[j];
3908 Xyce::dout() <<
" vals["<<j<<
"] = " << vals[j];
3909 Xyce::dout() << std::endl;
3914 if (Vrow != -1 && count > 0)
3916 bs1 = matPtr->sumIntoRow (Vrow, count, &vals[0], &cols[0]);
3917 bsuccess = bsuccess && bs1;
3921 Xyce::dout() <<
"OOOPS 1!" << std::endl;
3931 for (j=0;j<numCol;++j) { cols[j] = -1; vals[j] = 0.0; }
3937 for (iNN=0;iNN<nodePtr->
cnode;++iNN)
3947 dJdn = dJndn1Vec[iedge];
3951 dJdn = dJndn2Vec[iedge];
3954 coef += ((i<inodeB)?1.0:-1.0) * dJdn * ilen;
3958 coef += - dRdnVec[i] - dDNDTdn;
3960 coef += pdElecPenalty[i];
3963 cols[count] = Ncolarray[i][0];
3968 for (iNN=0;iNN<nodePtr->
cnode;++iNN)
3970 if (Ncolarray[i][iNN+1] == -1)
continue;
3980 dJdn = dJndn1Vec[iedge];
3984 dJdn = dJndn2Vec[iedge];
3987 coef = ((i<inodeB)?1.0:-1.0) * dJdn * ilen/nodeArea;
3990 cols[count] = Ncolarray[i][iNN+1];
3997 for (iNN=0;iNN<nodePtr->
cnode;++iNN)
4007 dJdV = dJndV1Vec[iedge];
4011 dJdV = dJndV2Vec[iedge];
4014 coef += ((i<inodeB)?1.0:-1.0) * dJdV * ilen;
4018 if (Vcolarray[i][0] != -1)
4021 cols[count] = Vcolarray[i][0];
4027 for (iNN=0;iNN<nodePtr->
cnode;++iNN)
4029 int tmpCol = Vcolarray[i][iNN+1];
4030 if (tmpCol == -1)
continue;
4041 dJdV = dJndV1Vec[iedge];
4045 dJdV = dJndV2Vec[iedge];
4048 coef = ((i<inodeB)?1.0:-1.0) * dJdV * ilen/nodeArea;
4050 coef *= ((boundarySten[inodeB]==1)?(scalingVars.rV0):1.0);
4053 if (boundarySten[inodeB]==1)
4056 for (cnt2=0;cnt2<count;++cnt2)
4058 if (cols[cnt2] == tmpCol)
4059 { bmatch =
true;
break; }
4061 if (!bmatch) { cnt2 = count; ++count;}
4071 #endif // Xyce_NEW_BC
4073 cols[cnt2] = tmpCol;
4077 if (Pcolarray[i][0] != -1)
4079 vals[count] = -dRdpVec[i];
4080 cols[count] = Pcolarray[i][0];
4084 #ifdef Xyce_DEBUG_DEVICE
4085 if (getDeviceOptions().debugLevel > 2 && getSolverState().debugTimeFlag)
4087 Xyce::dout() <<
"\n";
4088 Xyce::dout().setf(std::ios::left);
4089 Xyce::dout() <<
"ELECTRON LOAD: row = " << Nrow;
4090 Xyce::dout() <<
" count = " << count<<
"\n";
4091 Xyce::dout().setf(std::ios::scientific);
4092 for (j=0;j<count;++j)
4094 Xyce::dout() <<
" cols["<<j<<
"] = " << cols[j];
4095 Xyce::dout() <<
" vals["<<j<<
"] = " << vals[j];
4096 Xyce::dout() << std::endl;
4101 if (Nrow != -1 && count > 0)
4103 bs1 = matPtr->sumIntoRow (Nrow,count,&vals[0],&cols[0]);
4104 bsuccess = bsuccess && bs1;
4108 Xyce::dout() <<
"OOOPS 2!" << std::endl;
4119 for (j=0;j<numCol;++j) { cols[j] = -1; vals[j] = 0.0; }
4125 for (iNN=0;iNN<nodePtr->
cnode;++iNN)
4135 dJdp = dJpdn1Vec[iedge];
4139 dJdp = dJpdn2Vec[iedge];
4142 coef += - ((i<inodeB)?1.0:-1.0) * dJdp * ilen;
4146 coef += - dRdpVec[i] - dDPDTdp;
4148 coef += pdHolePenalty[i];
4151 cols[count] = Pcolarray[i][0];
4156 for (iNN=0;iNN<nodePtr->
cnode;++iNN)
4158 if (Pcolarray[i][iNN+1] == -1)
continue;
4168 dJdp = dJpdn1Vec[iedge];
4172 dJdp = dJpdn2Vec[iedge];
4175 coef =-((i<inodeB)?1.0:-1.0) * dJdp * ilen/nodeArea;
4178 cols[count] = Pcolarray[i][iNN+1];
4184 for (iNN=0;iNN<nodePtr->
cnode;++iNN)
4194 dJdV = dJpdV1Vec[iedge];
4198 dJdV = dJpdV2Vec[iedge];
4201 coef += -((i<inodeB)?1.0:-1.0) * dJdV * ilen;
4205 if (Vcolarray[i][0] != -1)
4208 cols[count] = Vcolarray[i][0];
4214 for (iNN=0;iNN<nodePtr->
cnode;++iNN)
4216 int tmpCol = Vcolarray[i][iNN+1];
4217 if (tmpCol == -1)
continue;
4228 dJdV = dJpdV1Vec[iedge];
4232 dJdV = dJpdV2Vec[iedge];
4235 coef =-((i<inodeB)?1.0:-1.0) * dJdV * ilen/nodeArea;
4237 coef *= ((boundarySten[inodeB]==1)?(scalingVars.rV0):1.0);
4240 if (boundarySten[inodeB]==1)
4243 for (cnt2=0;cnt2<count;++cnt2)
4245 if (cols[cnt2] == tmpCol)
4246 { bmatch =
true;
break; }
4248 if (!bmatch) { cnt2 = count; ++count;}
4258 #endif // Xyce_NEW_BC
4260 cols[cnt2] = tmpCol;
4264 if (Ncolarray[i][0] != -1)
4266 vals[count] = -dRdnVec[i];
4267 cols[count] = Ncolarray[i][0];
4271 #ifdef Xyce_DEBUG_DEVICE
4272 if (getDeviceOptions().debugLevel > 2 && getSolverState().debugTimeFlag)
4274 Xyce::dout() <<
"\n";
4275 Xyce::dout().setf(std::ios::left);
4276 Xyce::dout() <<
" HOLE LOAD: row = " << Prow;
4277 Xyce::dout() <<
" count = " << count<<
"\n";
4278 Xyce::dout().setf(std::ios::scientific);
4279 for (j=0;j<count;++j)
4281 Xyce::dout() <<
" cols["<<j<<
"] = " << cols[j];
4282 Xyce::dout() <<
" vals["<<j<<
"] = " << vals[j];
4283 Xyce::dout() << std::endl;
4288 if (Prow != -1 && count > 0)
4290 bs1 = matPtr->sumIntoRow (Prow,count,&vals[0],&cols[0]);
4291 bsuccess = bsuccess && bs1;
4295 Xyce::dout() <<
"OOOPS 3!" << std::endl;
4303 #ifdef Xyce_DEBUG_DEVICE
4304 if (getDeviceOptions().debugLevel > 2 && getSolverState().debugTimeFlag)
4306 Xyce::dout() << subsection_divider <<
"\n";
4313 for (i=0;i<numMeshPoints;++i)
4317 Vrow = li_Vrowarray[i];
4318 Nrow = li_Nrowarray[i];
4319 Prow = li_Prowarray[i];
4321 std::vector<int> & Voff = li_VoffsetArray[i];
4322 std::vector<int> & Noff = li_NoffsetArray[i];
4323 std::vector<int> & Poff = li_PoffsetArray[i];
4325 bool doneFlagV =
false;
4326 bool doneFlagN =
false;
4327 bool doneFlagP =
false;
4328 bool doneFlag =
false;
4330 #ifdef Xyce_DEBUG_DEVICE
4331 if (getDeviceOptions().debugLevel > 2 && getSolverState().debugTimeFlag)
4333 Xyce::dout() <<
"mesh point i = " << i << std::endl;
4338 if (boundarySten[i])
continue;
4343 if (boundarySten[i])
4345 #ifdef Xyce_DEBUG_DEVICE
4346 if (getDeviceOptions().debugLevel > 2 && getSolverState().debugTimeFlag)
4348 Xyce::dout() <<
" Doing BC load" << std::endl;
4351 int DIindex = labelDIMap[labelNameVector[i]];
4353 if (dIVec[DIindex].given)
4355 if (dIVec[DIindex].neumannBCFlagV==
false)
4360 (*matPtr)[Vrow][Voff[0]] = 1.0;
4361 (*matPtr)[Vrow][Voff[1]] = -scalingVars.rV0;
4366 if (dIVec[DIindex].neumannBCFlagN==
false)
4370 (*matPtr)[Nrow][Noff[0]] = 1.0;
4375 if (dIVec[DIindex].neumannBCFlagP==
false)
4379 (*matPtr)[Prow][Poff[0]] = 1.0;
4384 doneFlag = (doneFlagV && doneFlagN && doneFlagP);
4388 if (doneFlag)
continue;
4390 #endif // Xyce_NEW_BC
4395 mNode * nodePtr = meshContainerPtr->getNode(i);
4396 nodeArea = nodePtr->
area;
4402 #ifdef Xyce_DEBUG_DEVICE
4403 if (getDeviceOptions().debugLevel > 2 && getSolverState().debugTimeFlag)
4405 Xyce::dout() <<
" Doing Poisson load" << std::endl;
4408 std::string semi(bulkMaterial);
4411 for (iNN=0;iNN<nodePtr->
cnode;++iNN)
4421 (*matPtr)[Vrow][Voff[0]] += coef;
4424 coef = 0.0; iNN=0; ioffset=1;
4425 for (iNN=0;iNN<nodePtr->
cnode;++iNN)
4427 if (Vcolarray[i][iNN+1] == -1)
continue;
4435 #ifdef Xyce_NEW_BC // again CHECK the offset value.
4436 coef *= ((boundarySten[inodeB]==1)?(scalingVars.rV0):1.0);
4437 #endif // Xyce_NEW_BC
4438 (*matPtr)[Vrow][Voff[ioffset]] += coef;
4443 (*matPtr)[Vrow][Voff[ioffset]] += 1.0;
4447 (*matPtr)[Vrow][Voff[ioffset]] += -1.0;
4454 #ifdef Xyce_DEBUG_DEVICE
4455 if (getDeviceOptions().debugLevel > 2 && getSolverState().debugTimeFlag)
4457 Xyce::dout() <<
" Doing electron load" << std::endl;
4463 coef = 0.0; ioffset=0;
4465 for (iNN=0;iNN<nodePtr->
cnode;++iNN)
4475 dJdn = dJndn1Vec[iedge];
4479 dJdn = dJndn2Vec[iedge];
4482 coef += ((i<inodeB)?1.0:-1.0) * dJdn * ilen;
4486 coef += - dRdnVec[i] - dDNDTdn;
4487 coef += pdElecPenalty[i];
4489 (*matPtr)[Nrow][Noff[0]] += coef;
4492 coef = 0.0; ioffset=1;
4493 for (iNN=0;iNN<nodePtr->
cnode;++iNN)
4495 if (Ncolarray[i][iNN+1] == -1)
continue;
4505 dJdn = dJndn1Vec[iedge];
4509 dJdn = dJndn2Vec[iedge];
4512 coef = ((i<inodeB)?1.0:-1.0) * dJdn * ilen/nodeArea;
4514 (*matPtr)[Nrow][Noff[ioffset]] += coef;
4520 for (iNN=0;iNN<nodePtr->
cnode;++iNN)
4530 dJdV = dJndV1Vec[iedge];
4534 dJdV = dJndV2Vec[iedge];
4537 coef += ((i<inodeB)?1.0:-1.0) * dJdV * ilen;
4541 (*matPtr)[Nrow][Noff[ioffset]] += coef;
4546 for (iNN=0;iNN<nodePtr->
cnode;++iNN)
4548 if (Vcolarray[i][iNN+1] == -1)
continue;
4559 dJdV = dJndV1Vec[iedge];
4563 dJdV = dJndV2Vec[iedge];
4566 coef = ((i<inodeB)?1.0:-1.0) * dJdV * ilen/nodeArea;
4568 coef *= ((boundarySten[inodeB]==1)?(scalingVars.rV0):1.0);
4569 #endif // Xyce_NEW_BC
4570 (*matPtr)[Nrow][Noff[ioffset]] += coef;
4575 (*matPtr)[Nrow][Noff[ioffset]] += -dRdpVec[i];
4583 #ifdef Xyce_DEBUG_DEVICE
4584 if (getDeviceOptions().debugLevel > 2 && getSolverState().debugTimeFlag)
4586 Xyce::dout() <<
" Doing hole load" << std::endl;
4591 coef = 0.0; ioffset=0;
4593 for (iNN=0;iNN<nodePtr->
cnode;++iNN)
4603 dJdp = dJpdn1Vec[iedge];
4607 dJdp = dJpdn2Vec[iedge];
4610 coef += - ((i<inodeB)?1.0:-1.0) * dJdp * ilen;
4614 coef += - dRdpVec[i] - dDPDTdp;
4615 coef += pdHolePenalty[i];
4617 (*matPtr)[Prow][Poff[0]] += coef;
4620 coef = 0.0; ioffset=1;
4621 for (iNN=0;iNN<nodePtr->
cnode;++iNN)
4623 if (Pcolarray[i][iNN+1] == -1)
continue;
4633 dJdp = dJpdn1Vec[iedge];
4637 dJdp = dJpdn2Vec[iedge];
4640 coef =-((i<inodeB)?1.0:-1.0) * dJdp * ilen/nodeArea;
4642 (*matPtr)[Prow][Poff[ioffset]] += coef;
4648 for (iNN=0;iNN<nodePtr->
cnode;++iNN)
4658 dJdV = dJpdV1Vec[iedge];
4662 dJdV = dJpdV2Vec[iedge];
4665 coef += -((i<inodeB)?1.0:-1.0) * dJdV * ilen;
4669 (*matPtr)[Prow][Poff[ioffset]] += coef;
4674 for (iNN=0;iNN<nodePtr->
cnode;++iNN)
4676 if (Vcolarray[i][iNN+1] == -1)
continue;
4687 dJdV = dJpdV1Vec[iedge];
4691 dJdV = dJpdV2Vec[iedge];
4694 coef =-((i<inodeB)?1.0:-1.0) * dJdV * ilen/nodeArea;
4695 #ifdef Xyce_NEW_BC // CHECK!
4696 coef *= ((boundarySten[inodeB]==1)?(scalingVars.rV0):1.0);
4697 #endif // Xyce_NEW_BC
4698 (*matPtr)[Prow][Poff[ioffset]] += coef;
4703 (*matPtr)[Prow][Poff[ioffset]] += -dRdnVec[i];
4712 #ifdef Xyce_DEBUG_DEVICE
4713 if (getDeviceOptions().debugLevel > 1 && getSolverState().debugTimeFlag)
4715 Xyce::dout() << section_divider <<
"\n";
4733 bool bsuccess =
true;
4736 #ifdef Xyce_DEBUG_DEVICE
4739 Xyce::dout() << section_divider <<
"\n";
4740 Xyce::dout() <<
"Instance::calcLifetimes" <<
"\n";
4750 #ifdef Xyce_DEBUG_DEVICE
4755 Xyce::dout() <<
" tnVec["<<i<<
"] = " <<
tnVec[i];
4756 Xyce::dout() <<
" tpVec["<<i<<
"] = " <<
tpVec[i];
4757 Xyce::dout() <<
"\n";
4763 Xyce::dout() << section_divider <<
"\n";
4786 bool bsuccess =
true;
4789 #ifdef Xyce_DEBUG_DEVICE
4792 Xyce::dout() << section_divider <<
"\n";
4793 Xyce::dout() <<
"Instance::calcMobilities" <<
"\n";
4805 ci.
N = fabs(
CVec[i]);
4808 if (ci.
N == 0.0) ci.
N = 1.0;
4824 #ifdef Xyce_DEBUG_DEVICE
4827 Xyce::dout() <<
"Nodal Mobilities:" << std::endl;
4830 Xyce::dout() <<
" unVec["<<i<<
"] = " <<
unVec[i];
4831 Xyce::dout() <<
" upVec["<<i<<
"] = " <<
upVec[i];
4832 Xyce::dout() <<
"\n";
4834 Xyce::dout() << std::endl;
4842 int inodeA = edgePtr->
inodeA;
4843 int inodeB = edgePtr->
inodeB;
4854 ci.
N = (fabs(
CVec[inodeA])+fabs(
CVec[inodeB]))*0.5;
4857 if (ci.
N == 0.0) ci.
N = 1.0;
4860 ci.
n = pow((fabs(
nnVec[inodeA])*fabs(
nnVec[inodeB])),0.5)*
4863 ci.
p = pow((fabs(
npVec[inodeA])*fabs(
npVec[inodeB])),0.5)*
4866 #ifdef Xyce_DEBUG_DEVICE
4867 if (ci.
n != 0.0 && !(ci.
n > 0.0) && !(ci.
n < 0.0))
4869 Xyce::dout() <<
"ci.n is nan" << std::endl;
4870 Xyce::dout() <<
"nnVec[A] = " <<
nnVec[inodeA];
4871 Xyce::dout() <<
"nnVec[B] = " <<
nnVec[inodeB];
4872 Xyce::dout() << std::endl;
4888 #ifdef Xyce_DEBUG_DEVICE
4891 Xyce::dout() <<
"Edge Mobilities" << std::endl;
4894 Xyce::dout() <<
" unE_Vec["<<i<<
"] = " <<
unE_Vec[i];
4895 Xyce::dout() <<
" upE_Vec["<<i<<
"] = " <<
upE_Vec[i];
4896 Xyce::dout() <<
"\n";
4902 Xyce::dout() << section_divider << std::endl;
4936 bool bsuccess =
true;
4974 bool bsuccess =
true;
4979 #ifdef Xyce_DEBUG_DEVICE
4982 Xyce::dout() << section_divider <<
"\n";
4983 Xyce::dout() <<
"Instance::calcVoltDepDensities\n";
4993 #ifdef Xyce_DEBUG_DEVICE
4996 Xyce::dout() << section_divider <<
"\n";
5014 bool bsuccess =
true;
5019 #ifdef Xyce_DEBUG_DEVICE
5022 Xyce::dout() << section_divider <<
"\n";
5023 Xyce::dout() <<
"Instance::calcDopingProfile\n";
5033 #ifdef Xyce_OXIDE_ENABLED
5034 if (allOxideFlag)
return bsuccess;
5049 double NaTmp = 1.0e+99;
5050 double NdTmp =-1.0e+99;
5054 if(NaTmp >
CVec[i]) NaTmp =
CVec[i];
5055 if(NdTmp <
CVec[i]) NdTmp =
CVec[i];
5074 XL = midpoint -
WJ/2.0;
5075 XR = midpoint +
WJ/2.0;
5084 XL = midpoint -
WJ/2.0;
5085 XR = midpoint +
WJ/2.0;
5088 #ifdef Xyce_DEBUG_DEVICE
5091 Xyce::dout() <<
"deviceWidth = " <<
deviceWidth << std::endl;
5092 Xyce::dout() <<
"midpoint = " << midpoint << std::endl;
5093 Xyce::dout() <<
"XL = " <<
XL << std::endl;
5094 Xyce::dout() <<
"XR = " <<
XR << std::endl;
5095 Xyce::dout() <<
"WJ = " <<
WJ << std::endl;
5101 double yloc =
yVec[i];
5147 double Re = 0.5 * We;
5148 double Rb = 0.5 * Wad;
5158 Ae = log(Ne/Nb)/(Re*Re);
5159 Ab = log(Nb/Nc)/(Rb*Rb);
5178 Ae = log(Ne/Nb)/(Re*Re);
5179 Ab = log(Nb/Nc)/(Rb*Rb);
5201 double NaTmp = 1.0e+99;
5202 double NdTmp =-1.0e+99;
5206 if(NaTmp >
CVec[i]) NaTmp =
CVec[i];
5207 if(NdTmp <
CVec[i]) NdTmp =
CVec[i];
5245 double WDIFF = (WDEV-WOX)/2;
5247 double DT = 1.0e-11;
5276 double NaTmp = 1.0e+99;
5277 double NdTmp =-1.0e+99;
5281 if(NaTmp >
CVec[i]) NaTmp =
CVec[i];
5282 if(NdTmp <
CVec[i]) NdTmp =
CVec[i];
5298 std::map<std::string, DopeInfo *>::iterator iter;
5299 std::map<std::string, DopeInfo *>::iterator start =
dopeInfoMap.begin();
5300 std::map<std::string, DopeInfo *>::iterator end =
dopeInfoMap.end();
5302 #ifdef Xyce_DEBUG_DEVICE
5305 Xyce::dout() <<
"dope info map:" << std::endl;
5308 for ( iter = start; iter != end; ++iter )
5312 #ifdef Xyce_DEBUG_DEVICE
5334 #ifdef Xyce_DEBUG_DEVICE
5337 Xyce::dout().width(20);
5338 Xyce::dout().precision(12);
5339 Xyce::dout().setf(std::ios::scientific);
5340 Xyce::dout() << std::endl;
5341 Xyce::dout() <<
"Na = " <<
Na << std::endl;
5342 Xyce::dout() <<
"Nd = " <<
Nd << std::endl<< std::endl;
5349 Xyce::dout() <<
xVec[inode];
5350 Xyce::dout() <<
" " <<
yVec[inode];
5351 Xyce::dout() <<
" CVec["<<inode<<
"] = " <<
CVec[inode] << std::endl;
5356 #ifdef Xyce_DEBUG_DEVICE
5359 Xyce::dout() << section_divider << std::endl;
5398 bool bsuccess =
true;
5439 #ifdef Xyce_DEBUG_DEVICE
5442 Xyce::dout() << std::endl;
5443 Xyce::dout() <<
" scalingVars.x0 = " <<
scalingVars.
x0 <<
"\n";
5444 Xyce::dout() <<
" scalingVars.a0 = " <<
scalingVars.
a0 <<
"\n";
5445 Xyce::dout() <<
" scalingVars.T0 = " <<
scalingVars.
T0 <<
"\n";
5446 Xyce::dout() <<
" scalingVars.V0 = " <<
scalingVars.
V0 <<
"\n";
5447 Xyce::dout() <<
" scalingVars.C0 = " <<
scalingVars.
C0 <<
"\n";
5448 Xyce::dout() <<
" scalingVars.D0 = " <<
scalingVars.
D0 <<
"\n";
5449 Xyce::dout() <<
" scalingVars.u0 = " <<
scalingVars.
u0 <<
"\n";
5450 Xyce::dout() <<
" scalingVars.R0 = " <<
scalingVars.
R0 <<
"\n";
5451 Xyce::dout() <<
" scalingVars.t0 = " <<
scalingVars.
t0 <<
"\n";
5452 Xyce::dout() <<
" scalingVars.E0 = " <<
scalingVars.
E0 <<
"\n";
5453 Xyce::dout() <<
" scalingVars.J0 = " <<
scalingVars.
J0 <<
"\n";
5454 Xyce::dout() <<
" scalingVars.L0 = " <<
scalingVars.
L0 << std::endl;
5455 Xyce::dout() << std::endl;
5476 bool bsuccess =
true;
5495 std::vector<DeviceInterfaceNode>::iterator firstDI =
dIVec.begin();
5496 std::vector<DeviceInterfaceNode>::iterator lastDI =
dIVec.end ();
5497 std::vector<DeviceInterfaceNode>::iterator iterDI = firstDI;
5499 for (;iterDI!=lastDI;++iterDI)
5501 for (i=0;i<iterDI->numBoundaryPoints;++i)
5512 int size = iterDI->areaVector.size();
5513 for (i = 0; i < size; ++i)
5534 #endif // Xyce_NEW_BC
5539 (solVectorPtr)->setElementByGlobalIndex(
Vrowarray[i],
VVec[i], 0);
5541 (solVectorPtr)->setElementByGlobalIndex(
Nrowarray[i],
nnVec[i], 0);
5543 (solVectorPtr)->setElementByGlobalIndex(
Prowarray[i],
npVec[i], 0);
5580 bool bsuccess =
true;
5599 std::vector<DeviceInterfaceNode>::iterator firstDI =
dIVec.begin();
5600 std::vector<DeviceInterfaceNode>::iterator lastDI =
dIVec.end ();
5601 std::vector<DeviceInterfaceNode>::iterator iterDI = firstDI;
5603 for (;iterDI!=lastDI;++iterDI)
5605 for (i=0;i<iterDI->numBoundaryPoints;++i)
5616 int size = iterDI->areaVector.size();
5617 for (i = 0; i < size; ++i)
5638 #endif // Xyce_NEW_BC
5643 (solVectorPtr)->setElementByGlobalIndex(
Vrowarray[i],
VVec[i], 0);
5645 (solVectorPtr)->setElementByGlobalIndex(
Nrowarray[i],
nnVec[i], 0);
5647 (solVectorPtr)->setElementByGlobalIndex(
Prowarray[i],
npVec[i], 0);
5686 bool bsuccess =
true;
5696 std::vector<DeviceInterfaceNode>::iterator firstDI =
dIVec.begin();
5697 std::vector<DeviceInterfaceNode>::iterator lastDI =
dIVec.end ();
5698 std::vector<DeviceInterfaceNode>::iterator iterDI = firstDI;
5700 for (;iterDI!=lastDI;++iterDI)
5702 for (i=0;i<iterDI->numBoundaryPoints;++i)
5751 bool bsuccess =
true;
5785 bool bsuccess =
true;
5789 #ifdef Xyce_DEBUG_DEVICE
5792 Xyce::dout() << section_divider << std::endl;
5793 Xyce::dout() <<
"Instance::calcInitialGuess"<< std::endl;
5794 Xyce::dout() <<
" name = " <<
getName() << std::endl;
5804 double Cisq(0.0), Nisq(0.0);
5813 tmp = (fabs(Ci)+sqrt(Cisq+4*Nisq))/2.0;
5814 nnVec[i] = ((Ci>=0)?(tmp):(0.0)) + ((Ci<0)?(Nisq/tmp):(0.0));
5817 tmp = (fabs(Ci)+sqrt(Cisq+4*Nisq))/2.0;
5818 npVec[i] = ((Ci<=0)?(tmp):(0.0)) + ((Ci>0)?(Nisq/tmp):(0.0));
5820 #ifdef Xyce_DEBUG_DEVICE
5823 Xyce::dout() <<
"nnVec[" << i <<
"] = " <<
nnVec[i];
5824 Xyce::dout() <<
" npVec[" << i <<
"] = " <<
npVec[i];
5825 Xyce::dout() << std::endl;
5843 #ifdef Xyce_DEBUG_DEVICE
5846 Xyce::dout() <<
"VVec[" << i <<
"] = " <<
VVec[i] << std::endl;
5853 double VminTmp = +1.0e+99;
5854 double VmaxTmp = -1.0e+99;
5856 double VminBC = +1.0e+99;
5857 double VmaxBC = -1.0e+99;
5859 std::vector<DeviceInterfaceNode>::iterator firstDI =
dIVec.begin();
5860 std::vector<DeviceInterfaceNode>::iterator lastDI =
dIVec.end ();
5861 std::vector<DeviceInterfaceNode>::iterator iterDI;
5863 for (iterDI=firstDI;iterDI!=lastDI;++iterDI)
5866 std::vector<int>::iterator iterNode = labelPtr->
mNodeVector.begin();
5867 std::vector<int>::iterator lastNode = labelPtr->
mNodeVector.end ();
5869 for ( ;iterNode!=lastNode;++iterNode)
5871 if (VminTmp >
VVec[*iterNode]) VminTmp =
VVec[*iterNode];
5872 if (VmaxTmp <
VVec[*iterNode]) VmaxTmp =
VVec[*iterNode];
5874 int ilocal = iterDI->meshGlobalToLocal[*iterNode];
5875 if (VminBC > iterDI->VequVec[ilocal]) VminBC = iterDI->VequVec[ilocal];
5876 if (VmaxBC < iterDI->VequVec[ilocal]) VmaxBC = iterDI->VequVec[ilocal];
5880 double Voffset = -VminTmp;
5881 double VtotDiff = VmaxTmp-VminTmp;
5882 double VBCDiff = VmaxBC-VminBC;
5883 double Vscale = (VtotDiff!=0.0)?(VBCDiff/VtotDiff):1.0;
5885 #ifdef Xyce_DEBUG_DEVICE
5888 Xyce::dout() <<
"Voffset = " << Voffset << std::endl;
5889 Xyce::dout() <<
"VtotDiff = " << VtotDiff << std::endl;
5890 Xyce::dout() <<
"VBCDiff = " << VBCDiff << std::endl;
5891 Xyce::dout() <<
"Vscale = " << Vscale << std::endl;
5909 #ifdef Xyce_DEBUG_DEVICE
5912 Xyce::dout() <<
"VVec[" << i <<
"] = " <<
VVec[i] << std::endl;
5918 #endif // Xyce_NEW_BC
5925 (solVectorPtr)->setElementByGlobalIndex(
Vrowarray[i],
VVec[i], 0);
5927 (solVectorPtr)->setElementByGlobalIndex(
Nrowarray[i],
nnVec[i], 0);
5929 (solVectorPtr)->setElementByGlobalIndex(
Prowarray[i],
npVec[i], 0);
5950 #ifdef Xyce_DEBUG_DEVICE
5953 Xyce::dout() << std::endl;
5954 Xyce::dout().setf(std::ios::scientific);
5955 Xyce::dout() <<
"Vmax = " <<
VmaxExp << std::endl;
5956 Xyce::dout() <<
"Vmin = " <<
VminExp << std::endl;
5957 Xyce::dout() << std::endl;
5961 #ifdef Xyce_DEBUG_DEVICE
5964 Xyce::dout() << section_divider << std::endl;
5984 bool bsuccess =
true;
5987 #ifdef Xyce_DEBUG_DEVICE
5990 Xyce::dout() << section_divider << std::endl;
5991 Xyce::dout() <<
"Instance::calcVequBCs"<< std::endl;
5992 Xyce::dout() <<
" name = " <<
getName() << std::endl;
5993 Xyce::dout() <<
" Na = "<<
Na << std::endl;
5994 Xyce::dout() <<
" Nd = "<<
Nd << std::endl;
5998 double VminBC =+1.0e+99;
5999 double VmaxBC =-1.0e+99;
6001 std::vector<DeviceInterfaceNode>::iterator firstDI =
dIVec.begin();
6002 std::vector<DeviceInterfaceNode>::iterator lastDI =
dIVec.end ();
6003 std::vector<DeviceInterfaceNode>::iterator iterDI;
6005 for (iterDI=firstDI;iterDI!=lastDI;++iterDI)
6007 #ifdef Xyce_DEBUG_DEVICE
6010 Xyce::dout() <<
"DI name = " << iterDI->eName << std::endl;
6011 Xyce::dout() <<
"material = " << iterDI->material << std::endl;
6012 if (iterDI->materialGiven)
6014 Xyce::dout() <<
"material was given" << std::endl;
6018 Xyce::dout() <<
"material was NOT given" << std::endl;
6021 if (iterDI->oxideBndryFlag)
6023 Xyce::dout() <<
"This is a boundary WITH an oxide." << std::endl;
6027 Xyce::dout() <<
"This is a boundary WITHOUT an oxide." << std::endl;
6030 Xyce::dout().setf(std::ios::scientific);
6034 std::string insul =
"sio2";
6037 std::vector<int>::iterator iterNode = labelPtr->
mNodeVector.begin();
6038 std::vector<int>::iterator lastNode = labelPtr->
mNodeVector.end ();
6040 for (i=0;i<iterDI->numBoundaryPoints;++i,++iterNode)
6042 double Ci =
CVec[*iterNode];
6043 double ns =
nnVec[*iterNode];
6044 double Cisq = Ci*Ci;
6045 double Nisq =
Ni*
Ni;
6046 double tmp, nnTmp, npTmp;
6049 tmp = (fabs(Ci)+sqrt(Cisq+4*Nisq))/2.0;
6050 nnTmp = ((Ci>=0)?(tmp):(0.0)) + ((Ci<0)?(Nisq/tmp):(0.0));
6053 tmp = (fabs(Ci)+sqrt(Cisq+4*Nisq))/2.0;
6054 npTmp = ((Ci<=0)?(tmp):(0.0)) + ((Ci>0)?(Nisq/tmp):(0.0));
6056 ExtendedString mater = iterDI->material;
6059 if (mater==
"neutral")
6064 iterDI->VequVec[i] = +
Vt * log(nnTmp/Ni);
6069 iterDI->VequVec[i] = -
Vt * log(npTmp/Ni);
6080 + 2.0 *
Vt * log(nnTmp/Ni);
6087 - 2.0 *
Vt * log(npTmp/Ni);
6095 if (iterDI->oxideBndryFlag)
6097 iterDI->VequVec[i] += - iterDI->oxcharge *
charge *iterDI->oxthick/
6101 iterDI->VbcVec [i] = 0.0;
6103 if (VminBC > iterDI->VequVec[i]) VminBC = iterDI->VequVec[i];
6104 if (VmaxBC < iterDI->VequVec[i]) VmaxBC = iterDI->VequVec[i];
6106 #ifdef Xyce_DEBUG_DEVICE
6109 Xyce::dout() <<
"Vequ["<<i<<
"]=" << iterDI->VequVec[i];
6110 Xyce::dout() << std::endl;
6116 #ifdef Xyce_DEBUG_DEVICE
6119 Xyce::dout() <<
"After offset:" << std::endl;
6124 double Voffset = -VminBC;
6126 for (iterDI=firstDI;iterDI!=lastDI;++iterDI)
6128 #ifdef Xyce_DEBUG_DEVICE
6131 Xyce::dout() <<
"DI name = " << iterDI->eName << std::endl;
6132 Xyce::dout().setf(std::ios::scientific);
6136 for (i=0;i<iterDI->numBoundaryPoints;++i)
6138 iterDI->VequVec[i] += Voffset;
6139 #ifdef Xyce_DEBUG_DEVICE
6142 Xyce::dout() <<
"VequVec["<<i<<
"] = " << iterDI->VequVec[i] << std::endl;
6148 #ifdef Xyce_DEBUG_DEVICE
6151 Xyce::dout() << section_divider << std::endl;
6173 bool bsuccess =
true;
6174 std::vector<DeviceInterfaceNode>::iterator firstDI =
dIVec.begin();
6175 std::vector<DeviceInterfaceNode>::iterator lastDI =
dIVec.end ();
6176 std::vector<DeviceInterfaceNode>::iterator iterDI;
6178 #ifdef Xyce_DEBUG_DEVICE
6181 Xyce::dout() << section_divider<< std::endl;
6182 Xyce::dout() << std::endl <<
"In Instance::calcDensityBCs" << std::endl;
6192 for (iterDI=firstDI;iterDI!=lastDI;++iterDI)
6194 #ifdef Xyce_DEBUG_DEVICE
6197 Xyce::dout() << iterDI->eName<<
":" << std::endl;
6203 for (
int i=0;i<iterDI->numBoundaryPoints;++i)
6212 iterDI->nnbcVec[i] =
6215 iterDI->npbcVec[i] =
6216 0.5*(sqrt(
CVec[nIndex]*
CVec[nIndex]+4*Ni*Ni)-
CVec[nIndex]);
6218 if (NnMax < iterDI->nnbcVec[i])
NnMax = iterDI->nnbcVec[i];
6219 if (NpMax < iterDI->npbcVec[i])
NpMax = iterDI->npbcVec[i];
6221 if (
NnMin > iterDI->nnbcVec[i])
NnMin = iterDI->nnbcVec[i];
6222 if (
NpMin > iterDI->npbcVec[i])
NpMin = iterDI->npbcVec[i];
6224 #ifdef Xyce_DEBUG_DEVICE
6227 Xyce::dout() <<
"\tCVec["<<nIndex<<
"] = " <<
CVec[nIndex]<< std::endl;
6228 Xyce::dout() <<
"\tnnbc["<<i<<
"] = " << iterDI->nnbcVec[i] << std::endl;
6229 Xyce::dout() <<
"\tnpbc["<<i<<
"] = " << iterDI->npbcVec[i] << std::endl;
6237 std::vector<int>::iterator iterNode = labelPtr->
mNodeVector.begin();
6238 std::vector<int>::iterator lastNode = labelPtr->
mNodeVector.end ();
6240 for ( ;iterNode!=lastNode;++iterNode)
6242 int i1 = iterDI->meshGlobalToLocal[*iterNode];
6251 #ifdef Xyce_DEBUG_DEVICE
6254 Xyce::dout() << std::endl;
6255 Xyce::dout() <<
"NnMax = " <<
NnMax << std::endl;
6256 Xyce::dout() <<
"NpMax = " <<
NpMax << std::endl;
6257 Xyce::dout() <<
"NnMin = " <<
NnMin << std::endl;
6258 Xyce::dout() <<
"NpMin = " <<
NpMin << std::endl;
6259 Xyce::dout() << section_divider<< std::endl;
6283 bool bsuccess =
true;
6285 std::vector<DeviceInterfaceNode>::iterator firstDI =
dIVec.begin();
6286 std::vector<DeviceInterfaceNode>::iterator lastDI =
dIVec.end ();
6287 std::vector<DeviceInterfaceNode>::iterator iterDI;
6289 #ifdef Xyce_DEBUG_DEVICE
6292 Xyce::dout() << std::endl << section_divider << std::endl;
6293 Xyce::dout() << std::endl <<
"In Instance::calcBoundaryConditions" << std::endl;
6297 for (iterDI=firstDI;iterDI!=lastDI;++iterDI)
6301 for (i=0;i<iterDI->numBoundaryPoints;++i)
6303 iterDI->VbcVec[i] = iterDI->Vckt_ramp + iterDI->VequVec[i];
6308 for (i=0;i<iterDI->numBoundaryPoints;++i)
6310 iterDI->VbcVec[i] = iterDI->Vckt + iterDI->VequVec[i];
6318 std::vector<int>::iterator iterNode = labelPtr->
mNodeVector.begin();
6319 std::vector<int>::iterator lastNode = labelPtr->
mNodeVector.end ();
6321 for ( ;iterNode!=lastNode;++iterNode)
6323 int i1 = iterDI->meshGlobalToLocal[*iterNode];
6324 VVec[*iterNode] = iterDI->VbcVec [i1];
6325 nnVec[*iterNode] = iterDI->nnbcVec[i1];
6326 npVec[*iterNode] = iterDI->npbcVec[i1];
6328 #endif // Xyce_NEW_BC
6330 #ifdef Xyce_DEBUG_DEVICE
6333 Xyce::dout() << iterDI->eName <<
":" << std::endl;
6334 for (i=0;i<iterDI->numBoundaryPoints;++i)
6336 Xyce::dout()<<
"Vbc["<<i<<
"] = "<<iterDI->VbcVec[i]<<
", "<<iterDI->VbcVec[i]*
scalingVars.
V0;
6337 Xyce::dout() <<
" nnbc["<<i<<
"] = "<< iterDI->nnbcVec[i];
6339 Xyce::dout() <<
" npbc["<<i<<
"] = "<< iterDI->npbcVec[i];
6341 Xyce::dout() << std::endl;
6347 #ifdef Xyce_DEBUG_DEVICE
6350 Xyce::dout() << section_divider << std::endl;
6377 bool bsuccess =
true;
6379 #ifdef Xyce_DEBUG_DEVICE
6382 Xyce::dout() << std::endl << section_divider << std::endl;
6383 Xyce::dout() << std::endl <<
"In Instance::obtainNodeVoltages" << std::endl;
6389 std::vector<DeviceInterfaceNode>::iterator firstDI =
dIVec.begin();
6390 std::vector<DeviceInterfaceNode>::iterator lastDI =
dIVec.end ();
6391 std::vector<DeviceInterfaceNode>::iterator iterDI;
6393 for (iterDI=firstDI;iterDI!=lastDI;++iterDI)
6398 if (iterDI->gid != -1)
6399 iterDI->Vckt = (solVectorPtr)->getElementByGlobalIndex(iterDI->gid, 0);
6405 iterDI->Vckt = (*solVectorPtr)[iterDI->lid];
6410 #ifdef Xyce_DEBUG_DEVICE
6413 Xyce::dout() << iterDI->eName <<
" Vckt = " << iterDI->Vckt;
6414 Xyce::dout() <<
" Vckt*scalingVars.V0 = " << (iterDI->Vckt *
scalingVars.
V0) << std::endl;
6419 #ifdef Xyce_DEBUG_DEVICE
6422 Xyce::dout() << section_divider << std::endl;
6444 bool bsuccess =
true;
6446 std::vector<DeviceInterfaceNode>::iterator firstDI =
dIVec.begin();
6447 std::vector<DeviceInterfaceNode>::iterator lastDI =
dIVec.end ();
6448 std::vector<DeviceInterfaceNode>::iterator iterDI;
6450 #ifdef Xyce_DEBUG_DEVICE
6453 Xyce::dout() << std::endl << section_divider << std::endl;
6454 Xyce::dout() <<
"device: " <<
getName() << std::endl;
6458 for (iterDI=firstDI;iterDI!=lastDI;++iterDI)
6462 #ifdef Xyce_DEBUG_DEVICE
6463 double v1_orig = v1;
6466 double delV1 = v1 - v1_old;
6468 if ( delV1 > 1.25 ) v1 = v1_old + 1.25;
6469 if ( delV1 < -0.75 ) v1 = v1_old - 0.75;
6471 #ifdef Xyce_DEBUG_DEVICE
6474 Xyce::dout() <<
"electrode = " << iterDI->eName << std::endl;
6475 Xyce::dout() <<
"v1 = " << v1 << std::endl;
6476 Xyce::dout() <<
"v1_old = " << v1_old << std::endl;
6477 Xyce::dout() <<
"v1_orig = " << v1_orig << std::endl;
6478 Xyce::dout() <<
"v1/scalingVars.V0 = " << v1/
scalingVars.
V0 << std::endl;
6479 Xyce::dout() <<
"v1_old/scalingVars.V0 = " << v1_old/
scalingVars.
V0 << std::endl;
6480 Xyce::dout() <<
"v1_orig/scalingVars.V0 = " << v1_orig/
scalingVars.
V0 << std::endl;
6481 Xyce::dout() << std::endl;
6489 #ifdef Xyce_DEBUG_DEVICE
6492 Xyce::dout() << section_divider << std::endl;
6510 bool bsuccess =
true;
6515 #ifdef Xyce_DEBUG_DEVICE
6518 Xyce::dout() << section_divider <<
"\n";
6519 Xyce::dout() <<
"Instance::obtainSolution\n";
6520 Xyce::dout() <<
"solVectorPtr = " << solVectorPtr << std::endl;
6525 bsuccess = bsuccess && bs1;
6534 #endif // Xyce_NEW_BC
6542 VVec[i] = (solVectorPtr)->getElementByGlobalIndex(
Vrowarray[i], 0);
6551 #ifdef Xyce_DEBUG_DEVICE
6556 Xyce::dout() <<
"VVec["<<i<<
"]=\t";
6557 Xyce::dout().width(20);
6558 Xyce::dout().precision(12);
6559 Xyce::dout().setf(std::ios::scientific);
6560 Xyce::dout() <<
VVec[i];
6562 Xyce::dout() <<
"\n";
6574 #ifdef Xyce_DEBUG_DEVICE
6577 Xyce::dout() <<
" About to get the density.\n";
6578 if (
getSolverState().dcopFlag) Xyce::dout() <<
"DCOP load" << std::endl;
6579 else Xyce::dout() <<
"Transient load" << std::endl;
6592 #endif // Xyce_NEW_BC
6613 #ifdef Xyce_DEBUG_DEVICE
6616 Xyce::dout()<<
" Obtaining densities from solution vector (not voltage dep.)\n";
6624 #endif // Xyce_NEW_BC
6631 nnVec[i] = (solVectorPtr)->getElementByGlobalIndex(
Nrowarray[i], 0);
6638 #ifdef Xyce_PDE_DENSITY_CONSTRAINT
6647 (solVectorPtr)->setElementByGlobalIndex(
Nrowarray[i], 0.0, 0);
6661 npVec[i] = (solVectorPtr)->getElementByGlobalIndex(
Prowarray[i], 0);
6669 #ifdef Xyce_PDE_DENSITY_CONSTRAINT
6677 (solVectorPtr)->setElementByGlobalIndex(
Prowarray[i], 0.0, 0);
6688 #ifdef Xyce_DEBUG_DEVICE
6693 Xyce::dout() <<
"nnVec["<<i<<
"]=\t";
6694 Xyce::dout().width(14);
6695 Xyce::dout().precision(6);
6696 Xyce::dout().setf(std::ios::scientific);
6697 Xyce::dout() <<
nnVec[i];
6700 Xyce::dout() <<
" npVec["<<i<<
"]=\t";
6701 Xyce::dout().width(14);
6702 Xyce::dout().precision(6);
6703 Xyce::dout().setf(std::ios::scientific);
6704 Xyce::dout() <<
npVec[i];
6707 Xyce::dout() << std::endl;
6723 bsuccess = bsuccess && bs1;
6730 bsuccess = bsuccess && bs1;
6734 #ifdef Xyce_DEBUG_DEVICE
6737 Xyce::dout() << section_divider << std::endl;
6754 bool bsuccess =
true;
6759 #ifdef Xyce_DEBUG_DEVICE
6762 Xyce::dout() << section_divider <<
"\n";
6763 Xyce::dout() <<
"Instance::calcRecombination\n";
6764 Xyce::dout() <<
"\n";
6770 double n =
nnVec[i];
6771 double p =
npVec[i];
6772 double tn =
tnVec[i];
6773 double tp =
tpVec[i];
6779 RVec[i] = (Rsrh + Raug);
6781 #ifdef Xyce_DEBUG_DEVICE
6784 Xyce::dout().precision(4);
6785 Xyce::dout() <<
" nnVec="<<n<<
" npVec="<<p;
6786 Xyce::dout() <<
" tnVec="<<tn<<
" tpVec="<<tp;
6787 Xyce::dout() <<
" Rsrh="<<Rsrh;
6788 Xyce::dout() <<
" Raug="<<Raug;
6789 Xyce::dout() <<
" RVec["<<i<<
"]="<<
RVec[i];
6790 Xyce::dout() <<
"\n";
6795 Xyce::dout().precision(4);
6796 Xyce::dout() <<
" RVec["<<i<<
"]="<<
RVec[i];
6797 Xyce::dout() << std::endl;
6802 #ifdef Xyce_DEBUG_DEVICE
6805 Xyce::dout() << section_divider << std::endl;
6827 bool bsuccess =
true;
6829 Util::Expression expr;
6835 ndParam.setTag(
"PULSEDATA");
6836 expr.set(
"spice_pulse(V1, V2, TD, TR, TF, PW, PER)");
6837 expr.make_constant(
"V1", 0.0);
6838 expr.make_constant(
"V2",
photoA1);
6839 expr.make_constant(
"TD",
photoTd);
6840 expr.make_constant(
"TR",
photoTr);
6841 expr.make_constant(
"TF",
photoTf);
6842 expr.make_constant(
"PW",
photoPw);
6843 expr.make_constant(
"PER",
photoPer);
6844 ndParam.setVal(expr);
6849 ndParam.setTag(
"PULSEDATA");
6851 expr.make_constant(
"CONST",
photoA1);
6852 ndParam.setVal(expr);
6891 bool bsuccess =
true;
6897 #ifdef Xyce_DEBUG_DEVICE
6901 Xyce::dout() << section_divider <<
"\n";
6902 Xyce::dout() <<
"Instance::calcPhotogen\n";
6903 Xyce::dout() <<
"time = " << time;
6908 { Xyce::dout() <<
" photogen is on right now." << std::endl; }
6910 { Xyce::dout() <<
" photogen is off right now." << std::endl; }
6912 Xyce::dout() <<
"\n";
6941 #ifdef Xyce_DEBUG_DEVICE
6944 Xyce::dout() <<
"Value of photogen source = " << val << std::endl;
6945 Xyce::dout() << section_divider << std::endl;
6978 bool bsuccess =
true;
6981 #ifdef Xyce_DEBUG_DEVICE
6982 bool nonZeroFlag =
false;
7013 double epen = prefac*pow(elec,power);
7017 double hpen = prefac*pow(hole,power);
7020 #ifdef Xyce_DEBUG_DEVICE
7027 #ifdef Xyce_DEBUG_DEVICE
7032 Xyce::dout() <<
" e- Pen["<<i<<
"] = " <<
elecPenalty[i];
7033 Xyce::dout() <<
" e- den["<<i<<
"] = " <<
nnVec[i];
7035 Xyce::dout() <<
" h+ Pen["<<i<<
"] = " <<
holePenalty[i];
7036 Xyce::dout() <<
" h+ den["<<i<<
"] = " <<
npVec[i];
7037 Xyce::dout() << std::endl;
7079 bool bsuccess =
true;
7104 double power2 = power - 1.0;
7108 double elec =
nnVec[i];
7109 double hole =
npVec[i];
7113 double epen = power*prefac*Cpow*pow(elec,power2);
7117 double hpen = power*prefac*Cpow*pow(hole,power2);
7139 bool bsuccess =
true;
7142 #ifdef Xyce_DEBUG_DEVICE
7146 Xyce::dout() << section_divider <<
"\n";
7147 Xyce::dout() <<
"Instance::sumSources\n";
7148 Xyce::dout() <<
"\n";
7157 #ifdef Xyce_DEBUG_DEVICE
7160 Xyce::dout() <<
"RVec["<<i<<
"] = " <<
RVec[i];
7161 Xyce::dout() <<
" SVec["<<i<<
"] = " << SVec[i];
7162 Xyce::dout() <<
" totSrcVec["<<i<<
"] = " <<
totSrcVec[i] <<
"\n";
7167 #ifdef Xyce_DEBUG_DEVICE
7170 Xyce::dout() << section_divider << std::endl;
7188 bool bsuccess =
true;
7197 #ifdef Xyce_DEBUG_DEVICE
7200 Xyce::dout() << section_divider <<
"\n";
7201 Xyce::dout() <<
"Instance::pdRecombination\n";
7202 Xyce::dout() <<
"\n";
7208 double n =
nnVec[i];
7209 double p =
npVec[i];
7210 double tn =
tnVec[i];
7211 double tp =
tpVec[i];
7219 dRdnVec[i] = (dRsrhdn + dRaugdn);
7220 dRdpVec[i] = (dRsrhdp + dRaugdp);
7222 #ifdef Xyce_DEBUG_DEVICE
7225 Xyce::dout() <<
" dRdnVec["<<i<<
"] = " <<
dRdnVec[i];
7226 Xyce::dout() <<
" dRdpVec["<<i<<
"] = " <<
dRdpVec[i];
7227 Xyce::dout() <<
"\n";
7232 #ifdef Xyce_DEBUG_DEVICE
7235 Xyce::dout() << section_divider << std::endl;
7252 bool bsuccess =
true;
7259 #ifdef Xyce_DEBUG_DEVICE
7263 Xyce::dout() << section_divider <<
"\n";
7264 Xyce::dout() <<
"Instance::calcElectronCurrent\n";
7265 Xyce::dout() <<
"\n";
7273 #ifdef Xyce_DEBUG_DEVICE
7276 Xyce::dout() <<
"\n";
7277 Xyce::dout() <<
"i="<<i<<
"\n";
7283 int inodeA = edgePtr->
inodeA;
7284 int inodeB = edgePtr->
inodeB;
7285 double elen = edgePtr->
elen;
7290 if (jnMax < fabs(
JnVec[i]) )
7292 #ifdef Xyce_DEBUG_DEVICE
7295 jnMax = fabs(
JnVec[i]);
7298 #ifdef Xyce_DEBUG_DEVICE
7307 #ifdef Xyce_DEBUG_DEVICE
7310 double jScale = 1.0;
7311 double xScale = 1.0;
7314 Xyce::dout().setf(std::ios::scientific);
7315 Xyce::dout() <<
" Max Electron current = " << jnMax;
7316 Xyce::dout() <<
" jScale = " << jScale;
7317 Xyce::dout() <<
"\n";
7320 int inodeA = edgePtr->
inodeA;
7321 int inodeB = edgePtr->
inodeB;
7323 Xyce::dout() <<
" max locations A: (x,y) = (" <<
xVec[inodeA]*xScale<<
", ";
7324 Xyce::dout() <<
yVec[inodeA]*xScale<<
")\n";
7325 Xyce::dout() <<
" max locations B: (x,y) = (" <<
xVec[inodeB]*xScale<<
", ";
7326 Xyce::dout() <<
yVec[inodeB]*xScale<<
")\n";
7327 Xyce::dout() <<
" nodes: inodeA = "<<inodeA<<
" inodeB = " << inodeB<< std::endl;
7329 Xyce::dout() <<
" VVec["<<inodeA<<
"] = " <<
VVec[inodeA];
7330 Xyce::dout() <<
" VVec["<<inodeB<<
"] = " << VVec[inodeB] << std::endl;
7332 Xyce::dout() <<
" nnVec["<<inodeA<<
"] = " <<
nnVec[inodeA];
7333 Xyce::dout() <<
" nnVec["<<inodeB<<
"] = " << nnVec[inodeB] << std::endl;
7335 Xyce::dout() <<
" elen = " << edgePtr->
elen << std::endl;
7336 Xyce::dout() << section_divider << std::endl;
7355 bool bsuccess =
true;
7360 #ifdef Xyce_DEBUG_DEVICE
7363 Xyce::dout() << section_divider <<
"\n";
7364 Xyce::dout() <<
"Instance::pdElectronCurrent\n";
7365 Xyce::dout() <<
"\n";
7372 #ifdef Xyce_DEBUG_DEVICE
7375 Xyce::dout() << subsection_divider <<
"\n";
7376 Xyce::dout() <<
"i="<<i;
7381 int inodeA = edgePtr->
inodeA;
7382 int inodeB = edgePtr->
inodeB;
7383 double elen = edgePtr->
elen;
7397 #ifdef Xyce_DEBUG_DEVICE
7400 Xyce::dout() <<
" dJndn1="<<
dJndn1Vec[i];
7401 Xyce::dout() <<
" dJndn2="<<
dJndn2Vec[i];
7402 Xyce::dout() <<
" dJndV1="<<
dJndV1Vec[i];
7403 Xyce::dout() <<
" dJndV2="<<
dJndV2Vec[i];
7404 Xyce::dout() <<
"\n";
7409 #ifdef Xyce_DEBUG_DEVICE
7412 Xyce::dout() << section_divider << std::endl;
7429 bool bsuccess =
true;
7435 #ifdef Xyce_DEBUG_DEVICE
7439 Xyce::dout() << section_divider <<
"\n";
7440 Xyce::dout() <<
"Instance::calcHoleCurrent\n";
7441 Xyce::dout() <<
"\n";
7448 #ifdef Xyce_DEBUG_DEVICE
7451 Xyce::dout() <<
"\n";
7452 Xyce::dout() <<
"i="<<i<<
"\n";
7458 int inodeA = edgePtr->
inodeA;
7459 int inodeB = edgePtr->
inodeB;
7460 double elen = edgePtr->
elen;
7465 if (jpMax < fabs(
JpVec[i]) )
7467 #ifdef Xyce_DEBUG_DEVICE
7470 jpMax = fabs(
JpVec[i]);
7473 #ifdef Xyce_DEBUG_DEVICE
7482 #ifdef Xyce_DEBUG_DEVICE
7485 double jScale = 1.0;
7486 double xScale = 1.0;
7489 Xyce::dout().setf(std::ios::scientific);
7490 Xyce::dout() <<
" Max Hole current = " << jpMax;
7491 Xyce::dout() <<
" jScale = " << jScale;
7492 Xyce::dout() <<
"\n";
7495 int inodeA = edgePtr->
inodeA;
7496 int inodeB = edgePtr->
inodeB;
7498 Xyce::dout() <<
" max locations A: (x,y) = (" <<
xVec[inodeA]*xScale<<
", ";
7499 Xyce::dout() <<
yVec[inodeA]*xScale<<
")\n";
7500 Xyce::dout() <<
" max locations B: (x,y) = (" <<
xVec[inodeB]*xScale<<
", ";
7501 Xyce::dout() <<
yVec[inodeB]*xScale<<
")\n";
7502 Xyce::dout() <<
" nodes: inodeA = "<<inodeA<<
" inodeB = " << inodeB<< std::endl;
7504 Xyce::dout() <<
" VVec["<<inodeA<<
"] = " <<
VVec[inodeA];
7505 Xyce::dout() <<
" VVec["<<inodeB<<
"] = " << VVec[inodeB] << std::endl;
7507 Xyce::dout() <<
" npVec["<<inodeA<<
"] = " <<
npVec[inodeA];
7508 Xyce::dout() <<
" npVec["<<inodeB<<
"] = " << npVec[inodeB] << std::endl;
7510 Xyce::dout() <<
" elen = " << edgePtr->
elen << std::endl;
7511 Xyce::dout() << section_divider << std::endl;
7529 bool bsuccess =
true;
7534 #ifdef Xyce_DEBUG_DEVICE
7537 Xyce::dout() << section_divider <<
"\n";
7538 Xyce::dout() <<
"Instance::pdHoleCurrent\n";
7539 Xyce::dout() <<
"\n";
7547 #ifdef Xyce_DEBUG_DEVICE
7550 Xyce::dout() << subsection_divider <<
"\n";
7551 Xyce::dout() <<
"i="<<i;
7552 Xyce::dout() <<
"\n";
7557 int inodeA = edgePtr->
inodeA;
7558 int inodeB = edgePtr->
inodeB;
7559 double elen = edgePtr->
elen;
7573 #ifdef Xyce_DEBUG_DEVICE
7576 Xyce::dout() <<
" dJpdn1="<<
dJpdn1Vec[i];
7577 Xyce::dout() <<
" dJpdn2="<<
dJpdn2Vec[i];
7578 Xyce::dout() <<
" dJpdV1="<<
dJpdV1Vec[i];
7579 Xyce::dout() <<
" dJpdV2="<<
dJpdV2Vec[i];
7580 Xyce::dout() <<
"\n" <<
"\n";
7586 #ifdef Xyce_DEBUG_DEVICE
7589 Xyce::dout() << section_divider << std::endl;
7613 bool bsuccess =
true;
7616 #ifdef Xyce_DEBUG_DEVICE
7621 Xyce::dout() << section_divider <<
"\n";
7622 Xyce::dout() <<
"Instance::calcEfield\n";
7623 Xyce::dout() <<
"\n";
7634 int inodeA = edgePtr->
inodeA;
7635 int inodeB = edgePtr->
inodeB;
7636 double elen = edgePtr->
elen;
7640 #ifdef Xyce_DEBUG_DEVICE
7643 Xyce::dout() <<
" VV[A] = " <<
VVec[inodeA];
7644 Xyce::dout() <<
" VV[B] = " <<
VVec[inodeB];
7645 Xyce::dout() <<
" elen = " << elen;
7647 Xyce::dout() <<
" EfieldVec["<<i<<
"] = " <<
EfieldVec[i];
7648 Xyce::dout() <<
" E*scalingVars.E0 = " << EfieldVec[i]*
scalingVars.
E0;
7649 Xyce::dout() <<
"\n";
7654 Xyce::dout() <<
" edge = " << i;
7655 Xyce::dout() <<
" elen = " << elen;
7656 Xyce::dout() <<
" elen less than zero. Exiting" << std::endl;
7661 if (absEfield >
Emax)
7664 #ifdef Xyce_DEBUG_DEVICE
7672 else { eScale = 1.0; }
7676 #ifdef Xyce_DEBUG_DEVICE
7679 else { xScale = 1.0; }
7683 Xyce::dout().setf(std::ios::scientific);
7684 Xyce::dout() <<
" Max Efield = " <<
Emax;
7685 Xyce::dout() <<
" eScale = " << eScale;
7686 Xyce::dout() <<
"\n";
7689 int inodeA = edgePtr->
inodeA;
7690 int inodeB = edgePtr->
inodeB;
7692 Xyce::dout() <<
" max locations A: (x,y) = (" <<
xVec[inodeA]*xScale<<
", ";
7693 Xyce::dout() <<
yVec[inodeA]*xScale<<
")\n";
7694 Xyce::dout() <<
" max locations B: (x,y) = (" <<
xVec[inodeB]*xScale<<
", ";
7695 Xyce::dout() <<
yVec[inodeB]*xScale<<
")\n";
7696 Xyce::dout() <<
" nodes: inodeA = "<<inodeA<<
" inodeB = " << inodeB<< std::endl;
7697 Xyce::dout() <<
" VVec["<<inodeA<<
"] = " <<
VVec[inodeA];
7698 Xyce::dout() <<
" VVec["<<inodeB<<
"] = " << VVec[inodeB] << std::endl;
7699 Xyce::dout() <<
" elen = " << edgePtr->
elen << std::endl;
7700 Xyce::dout() << section_divider << std::endl;
7725 bool bnoChange =
true;
7727 #ifdef Xyce_DEBUG_DEVICE
7730 Xyce::dout() << section_divider <<
"\n";
7731 Xyce::dout() <<
"Instance::enableContinuation. " <<
outputName;
7732 Xyce::dout() << std::endl;
7738 std::vector<DeviceInterfaceNode>::iterator firstDI =
dIVec.begin();
7739 std::vector<DeviceInterfaceNode>::iterator lastDI =
dIVec.end ();
7740 std::vector<DeviceInterfaceNode>::iterator iterDI;
7750 for (iterDI=firstDI;iterDI!=lastDI;++iterDI)
7752 iterDI->Vckt_old = iterDI->Vckt;
7758 for (iterDI=firstDI;iterDI!=lastDI;++iterDI)
7760 iterDI->Vckt_final = iterDI->Vckt;
7761 iterDI->Vckt_orig = iterDI->Vckt;
7770 for (iterDI=firstDI;iterDI!=lastDI;++iterDI)
7772 double dV,tmp1V, tmp2V;
7773 tmp1V = iterDI->Vckt_final;
7774 tmp2V = iterDI->Vckt_old;
7777 iterDI->Vckt_delta = dV;
7779 iterDI->Vckt_deltaC = dV/
7786 if (fabs(iterDI->Vckt_deltaC) > maxDelta)
7788 int tmp_steps =
static_cast<int>(fabs(dV)/maxDelta) + 1;
7791 iterDI->Vckt_deltaC = dV/
7795 if (fabs(dV) > 1.0e-3) bnoChange =
false;
7797 #ifdef Xyce_DEBUG_DEVICE
7800 Xyce::dout() << std::endl;
7802 Xyce::dout().width(10);
7803 Xyce::dout() << iterDI->eName;
7804 Xyce::dout().width(10); Xyce::dout().precision(2);
7805 Xyce::dout() <<
": dV = " << dV;
7806 Xyce::dout() <<
" Vckt_final = " << iterDI->Vckt_final;
7807 Xyce::dout() <<
" Vckt_old = " << iterDI->Vckt_old << std::endl;
7808 Xyce::dout() <<
" delta = " << iterDI->Vckt_delta;
7809 Xyce::dout() <<
" deltaC = " << iterDI->Vckt_deltaC;
7811 Xyce::dout() << std::endl;
7815 iterDI->Vckt_ramp = iterDI->Vckt_old;
7816 iterDI->Vckt_ramp_old = iterDI->Vckt_old;
7820 bool bnoChangePhotogen =
true;
7824 std::string msg =
"Instance::enablePDEContinuation: PhotogenContinuation not supported";
7825 N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
7828 bnoChange = bnoChange && bnoChangePhotogen;
7830 #ifdef Xyce_DEBUG_DEVICE
7833 if (bnoChange) Xyce::dout() <<
"bnoChange is TRUE" << std::endl;
7834 else Xyce::dout() <<
"bnoChange is FALSE" << std::endl;
7840 #ifdef Xyce_DEBUG_DEVICE
7843 Xyce::dout() << section_divider << std::endl;
7849 return (!bnoChange);
7866 std::vector<DeviceInterfaceNode>::iterator firstDI =
dIVec.begin();
7867 std::vector<DeviceInterfaceNode>::iterator lastDI =
dIVec.end ();
7868 std::vector<DeviceInterfaceNode>::iterator iterDI;
7870 for (iterDI=firstDI;iterDI!=lastDI;++iterDI)
7872 iterDI->Vckt_old = iterDI->Vckt_final;
7890 #ifdef Xyce_DEBUG_DEVICE
7891 Xyce::dout() << section_divider << std::endl;
7892 Xyce::dout() <<
"Instance::setPDEContinuationAlpha" << std::endl;
7897 std::vector<DeviceInterfaceNode>::iterator firstDI =
dIVec.begin();
7898 std::vector<DeviceInterfaceNode>::iterator lastDI =
dIVec.end ();
7899 std::vector<DeviceInterfaceNode>::iterator iterDI;
7901 for (iterDI=firstDI;iterDI!=lastDI;++iterDI)
7903 iterDI->Vckt_ramp = iterDI->Vckt_old + (iterDI->Vckt_delta)*alpha;
7906 if ((iterDI->Vckt_delta > 0 && iterDI->Vckt_ramp > iterDI->Vckt_final) ||
7907 (iterDI->Vckt_delta <= 0 && iterDI->Vckt_ramp <= iterDI->Vckt_final) )
7909 iterDI->Vckt_ramp = iterDI->Vckt_final;
7911 #ifdef Xyce_NEW_PDE_CONTINUATION
7913 iterDI->Vckt_old = iterDI->Vckt_final;
7917 #ifdef Xyce_DEBUG_DEVICE
7921 Xyce::dout().width(10);
7922 Xyce::dout() <<iterDI->eName;
7923 Xyce::dout() <<
"\tVckt_ramp = " << iterDI->Vckt_ramp;
7924 Xyce::dout() <<
"\tVckt_old = " << iterDI->Vckt_old;
7925 Xyce::dout() <<
"\talpha = " << alpha;
7926 Xyce::dout() << std::endl;
7940 #ifdef Xyce_NEW_PDE_CONTINUATION
7946 #ifdef Xyce_DEBUG_DEVICE
7947 Xyce::dout() <<
" photoA1_ramp = " <<
photoA1_ramp << std::endl;
7948 Xyce::dout() << section_divider << std::endl;
7963 #ifdef Xyce_DEBUG_DEVICE
7964 Xyce::dout() << section_divider << std::endl;
7965 Xyce::dout() <<
"Instance::setPDEContinuationBeta" << std::endl;
7969 std::vector<DeviceInterfaceNode>::iterator firstDI =
dIVec.begin();
7970 std::vector<DeviceInterfaceNode>::iterator lastDI =
dIVec.end ();
7971 std::vector<DeviceInterfaceNode>::iterator iterDI;
7973 for (iterDI=firstDI;iterDI!=lastDI;++iterDI)
7975 iterDI->Vckt_ramp = iterDI->Vckt*beta;
7976 #ifdef Xyce_DEBUG_DEVICE
7977 Xyce::dout() <<
" " << iterDI->eName <<
" Vckt_ramp = " << iterDI->Vckt_ramp << std::endl;
7993 .registerDevice(
"pde", 2)
7994 .registerModelType(
"pde", 2)
7995 .registerModelType(
"zod", 2);