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),
227 useOldNiGiven(false),
230 usingInternalMesh(false),
232 deviceInitialized(false),
233 meshPerturbed (false),
234 dopingPerturbed (false),
235 photogenPerturbed (false),
239 deviceLength(1.0e-3),
246 #ifdef Xyce_OXIDE_ENABLED
250 gradedJunctionFlag(false),
251 calledBeforeSIGB(false),
258 displCurrentFlag(false),
259 constBoundaryFlag(false),
260 calcConductanceFlag(false),
264 outputNLPoisson(false),
265 lastOutputTime(-10.0),
272 useMatrixGIDFlag(false),
273 useVectorGIDFlag(false),
275 meshCopyContainerPtr(0),
320 boundaryNeighborSten(),
347 meshNeighborMultiMap(),
354 numInterfaceMeshPoints(0),
362 pdTermsAllocated(false),
368 vector<Param>::const_iterator iter_t;
369 vector<Param>::const_iterator begin_t = parameterVec.begin();
370 vector<Param>::const_iterator end_t = parameterVec.end();
372 for (iter_t = begin_t; iter_t != end_t; ++iter_t)
374 Xyce::dout() <<
"Tag: " << iter_t->tag();
375 Xyce::dout() <<
" Value = " << iter_t->sVal() <<
" Given: " << iter_t->
given() << endl;
403 if (
given(
"PH.TYPE"))
411 std::string msg =
"::: ph.type not recognized.\n";
412 N_ERH_ErrorMgr::report( N_ERH_ErrorMgr::DEV_FATAL_0,msg);
419 tmpTypeName.toUpper ();
423 #ifdef Xyce_DEBUG_DEVICE
425 Xyce::dout() <<
"Doing standard initialization of ."<< std::endl;
472 std::map<std::string,DopeInfo *>::iterator iter;
473 std::map<std::string,DopeInfo *>::iterator begin =
dopeInfoMap.begin();
474 std::map<std::string,DopeInfo *>::iterator end =
dopeInfoMap.end ();
476 for(iter=begin;iter!=end;++iter)
478 if (iter->second != 0)
delete iter->second;
485 std::map<std::string, PDE_2DElectrode * >::iterator iterE;
486 std::map<std::string, PDE_2DElectrode * >::iterator beginE =
electrodeMap.begin();
487 std::map<std::string, PDE_2DElectrode * >::iterator endE =
electrodeMap.end ();
489 for(iterE=beginE;iterE!=endE;++iterE)
491 if (iterE->second != 0)
delete iterE->second;
506 if (compositeName ==
"DOPINGPROFILES" || compositeName ==
"REGION")
510 return (static_cast<CompositeParam *> (n));
512 if (compositeName ==
"NODE")
515 ExtendedString dIName = paramName;
518 dINode.
eName = dIName;
519 dINode.
nName = paramName;
528 return (static_cast<CompositeParam *> (n));
531 "Instance::constructComposite: unrecognized composite name: ";
532 msg += compositeName;
533 N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
551 bool bsuccess =
true;
554 #ifdef Xyce_DEBUG_DEVICE
557 Xyce::dout() << section_divider <<
"\n";
558 Xyce::dout() <<
"updateIntermediateVars. name = " <<
getName() << std::endl;
568 bs1 =
calcEfield (); bsuccess = bsuccess && bs1;
579 bsuccess = bsuccess && bs1;
585 bsuccess = bsuccess && bs1;
590 #ifdef Xyce_DEBUG_DEVICE
593 Xyce::dout() << section_divider << std::endl;
611 bool bsuccess =
true;
613 #ifdef Xyce_DEBUG_DEVICE
616 Xyce::dout() << section_divider <<
"\n";
617 Xyce::dout() <<
"calcTerminalCurrents. name = " <<
getName() << std::endl;
622 std::vector<DeviceInterfaceNode>::iterator firstDI =
dIVec.begin ();
623 std::vector<DeviceInterfaceNode>::iterator lastDI =
dIVec.end ();
624 std::vector<DeviceInterfaceNode>::iterator iterDI;
627 for (iterDI=firstDI; iterDI!=lastDI; ++iterDI, ++ind)
635 std::vector<int>::iterator firstI = labelPtr->
mNodeVector.begin();
636 std::vector<int>::iterator lastI = labelPtr->
mNodeVector.end ();
637 std::vector<int>::iterator iterI;
639 iterDI->currentSum = 0.0;
642 for(nodeIndex=0,iterI=firstI;iterI!=lastI;++iterI,++nodeIndex)
648 std::vector<EDGEINFO>::iterator firstEI = nodePtr->
edgeInfoVector.begin();
649 std::vector<EDGEINFO>::iterator lastEI = nodePtr->
edgeInfoVector.end ();
650 std::vector<EDGEINFO>::iterator iterEI;
654 #ifdef Xyce_DEBUG_DEVICE
657 Xyce::dout() <<
" --------------- " << std::endl;
658 Xyce::dout() <<
"name = " << iterDI->eName;
659 Xyce::dout() <<
" node = " << *iterI << std::endl;
663 for (iterEI=firstEI;iterEI!=lastEI;++iterEI)
665 int iedge = iterEI->iedge;
666 int neighbor = iterEI->inode;
668 double ilen = edgePtr->
ilen;
670 double sign = (*iterI < neighbor) ? 1.0 : -1.0;
672 sum += (sign*
JnVec[iedge] + sign*
JpVec[iedge])*ilen;
675 #ifdef Xyce_DEBUG_DEVICE
678 Xyce::dout() <<
" sum*scalingVars.a0 = "<< sum*
scalingVars.
a0 << std::endl;
679 Xyce::dout() <<
" sum = " << sum << std::endl;
680 Xyce::dout() <<
" --------------- " << std::endl;
686 iterDI->currentSum += sum;
707 #ifdef Xyce_DEBUG_DEVICE
710 Xyce::dout().setf(std::ios::scientific);
711 Xyce::dout() <<
" " << iterDI->eName;
712 Xyce::dout() <<
" Ickt = " << iterDI->currentSum << std::endl;
718 #ifdef Xyce_DEBUG_DEVICE
721 Xyce::dout() << section_divider << std::endl;
768 bool bsuccess =
true;
770 std::vector<DeviceInterfaceNode>::iterator firstDI =
dIVec.begin ();
771 std::vector<DeviceInterfaceNode>::iterator lastDI =
dIVec.end ();
772 std::vector<DeviceInterfaceNode>::iterator iterDI;
786 double nodeArea,ilen,elen;
795 for(iterDI=firstDI;iterDI!=lastDI;++iterDI)
797 iterDI->dIdVckt = 0.0;
802 #ifdef Xyce_DEBUG_DEVICE
805 Xyce::dout() << Xyce::subsection_divider << std::endl;
809 if (iterDI->gid ==-1)
continue;
814 std::vector<int>::iterator firstI = labelPtr->
mNodeVector.begin();
815 std::vector<int>::iterator lastI = labelPtr->
mNodeVector.end ();
816 std::vector<int>::iterator iterI;
818 std::vector<EDGEINFO>::iterator firstEI;
819 std::vector<EDGEINFO>::iterator lastEI;
820 std::vector<EDGEINFO>::iterator iterEI;
829 for(nodeIndex=0,iterI=firstI;iterI!=lastI;++iterI,++nodeIndex)
837 for (iterEI=firstEI; iterEI!=lastEI; ++iterEI)
839 iedge = iterEI->iedge;
840 inodeB = iterEI->inode;
842 ilen = edgePtr->
ilen;
849 sign = (*iterI < inodeB) ? 1.0 : -1.0;
862 coef += (sign* dJndV + sign* dJpdV)*ilen;
867 iterDI->dIdVckt += tmpsum;
869 #ifdef Xyce_DEBUG_DEVICE
872 Xyce::dout().setf(std::ios::left);
873 Xyce::dout() << iterDI->eName<<
":";
874 Xyce::dout() <<
" KCL pdTerminalCurrent row = " << iterDI->gid;
875 Xyce::dout() <<
" contrib = " << tmpsum;
876 Xyce::dout() <<
" dIdVckt = " << iterDI->dIdVckt << std::endl;
882 #endif // Xyce_NEW_BC
886 #ifdef Xyce_DEBUG_DEVICE
889 Xyce::dout() << Xyce::subsection_divider << std::endl;
892 #endif // Xyce_NEW_BC
896 for(iterDI=firstDI;iterDI!=lastDI;++iterDI)
901 int size = iterDI->dFdVckt.size();
902 for (itmp=0;itmp<size;++itmp)
904 iterDI->dFdVckt[itmp] = 0.0;
907 int numNeighbor = iterDI->neighborNodes.size();
911 for (iNeighbor=0;iNeighbor<numNeighbor;++iNeighbor)
913 int inode = iterDI->neighborNodes[iNeighbor];
916 nodeArea = nodePtr->
area;
920 for (iNN=0;iNN<nodePtr->
cnode;++iNN)
940 iterDI->dFdVckt[dFdVindex] = coef;
945 if (inode>inodeB) { dJdV =
dJndV1Vec[iedge]; }
948 coef = ((inode<inodeB)?1.0:-1.0) * dJdV * ilen/nodeArea;
951 iterDI->dFdVckt[dFdVindex] = coef;
956 if (inode>inodeB) { dJdV =
dJpdV1Vec[iedge]; }
959 coef = -((inode<inodeB)?1.0:-1.0) * dJdV * ilen/nodeArea;
962 iterDI->dFdVckt[dFdVindex] = coef;
966 #ifdef Xyce_DEBUG_DEVICE
969 Xyce::dout() <<
"-----" << std::endl;
970 Xyce::dout() <<
"neighbor nodes for boundary: " << iterDI->eName << std::endl;
971 Xyce::dout() <<
"-----" << std::endl;
972 for (iNeighbor=0;iNeighbor<numNeighbor;++iNeighbor)
974 int inode = iterDI->neighborNodes[iNeighbor];
975 Xyce::dout() <<
"\t"<<iNeighbor<<
" "<< inode << std::endl;
978 Xyce::dout() <<
"-----" << std::endl;
979 Xyce::dout() <<
"dFdVckt vector for boundary: " << iterDI->eName << std::endl;
980 Xyce::dout() <<
"-----" << std::endl;
984 for (iNeighbor=0;iNeighbor<numNeighbor;++iNeighbor)
986 int inode = iterDI->neighborNodes[iNeighbor];
995 for (iNN=0;iNN<nodePtr->
cnode;++iNN)
1006 dfdV = iterDI->dFdVckt[idf];
1007 Xyce::dout() <<
"\t"<<idf;
1008 Xyce::dout() <<
" \tv_"<<inode<<
"\t"<<Vrow<<
"\t"<<dfdV<< std::endl;
1011 dfdV = iterDI->dFdVckt[idf];
1012 Xyce::dout() <<
"\t"<<idf;
1013 Xyce::dout() <<
" \tn_"<<inode<<
"\t"<<Nrow<<
"\t"<<dfdV<< std::endl;
1016 dfdV = iterDI->dFdVckt[idf];
1017 Xyce::dout() <<
"\t"<<idf;
1018 Xyce::dout() <<
" \tp_"<<inode<<
"\t"<<Prow<<
"\t"<<dfdV<< std::endl;
1022 Xyce::dout() <<
"-----" << std::endl;
1026 #else // old BC not set up yet.
1028 #endif // Xyce_NEW_BC
1034 for(iterDI=firstDI;iterDI!=lastDI;++iterDI)
1039 int numdIdX = iterDI->dIdX.size ();
1040 for (
int j=0;j<numdIdX;++j)
1042 iterDI->dIdX[j] = 0.0;
1048 std::vector<int>::iterator firstI = labelPtr->
mNodeVector.begin();
1049 std::vector<int>::iterator lastI = labelPtr->
mNodeVector.end ();
1050 std::vector<int>::iterator iterI;
1052 std::vector<EDGEINFO>::iterator firstEI;
1053 std::vector<EDGEINFO>::iterator lastEI;
1054 std::vector<EDGEINFO>::iterator iterEI;
1062 for(nodeIndex=0,iterI=firstI;iterI!=lastI;++iterI,++nodeIndex)
1072 for (iterEI=firstEI; iterEI!=lastEI; ++iterEI)
1074 iedge = iterEI->iedge;
1075 inodeB = iterEI->inode;
1076 sign = (*iterI < inodeB) ? 1.0 : -1.0;
1078 ilen = edgePtr->
ilen;
1095 Vcoef += (sign* dJndV + sign* dJpdV)*ilen;
1096 Ncoef += (sign* dJndn)*ilen;
1097 Pcoef += (sign* dJpdp)*ilen;
1101 col1 = iterDI->Vcol[iVcol];
1106 int size = iterDI->dIdXcols.size();
1107 for (cnt2=0;cnt2<size;++cnt2)
1109 if (iterDI->dIdXcols[cnt2] == col1)
1110 { bmatch =
true;
break; }
1114 msg =
"pdTerminalCurrents: Could not find a column match in dIdXcols";
1115 N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
1120 Xyce::dout() << iterDI->eName;
1123 col1 = iterDI->Ncol[iNcol];
1128 int size = iterDI->dIdXcols.size();
1129 for (cnt2=0;cnt2<size;++cnt2)
1131 if (iterDI->dIdXcols[cnt2] == col1)
1132 { bmatch =
true;
break; }
1136 msg =
"pdTerminalCurrents: Could not find a column match in dIdXcols";
1137 N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
1143 col1 = iterDI->Pcol[iPcol];
1148 int size = iterDI->dIdXcols.size();
1149 for (cnt2=0;cnt2<size;++cnt2)
1151 if (iterDI->dIdXcols[cnt2] == col1)
1152 { bmatch =
true;
break; }
1156 msg =
"pdTerminalCurrents: Could not find a column match in dIdXcols";
1157 N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
1168 for (iterEI=firstEI; iterEI!=lastEI; ++iterEI,++iVcol,++iNcol,++iPcol)
1170 iedge = iterEI->iedge;
1171 inodeB = iterEI->inode;
1172 sign = (*iterI < inodeB) ? 1.0 : -1.0;
1174 ilen = edgePtr->
ilen;
1191 Vcoef = (sign* dJndV + sign* dJpdV)*ilen;
1192 Ncoef = (sign* dJndn)*ilen;
1193 Pcoef = (sign* dJpdp)*ilen;
1195 col1 = iterDI->Vcol[iVcol];
1200 int size = iterDI->dIdXcols.size();
1201 for (cnt2=0;cnt2<size;++cnt2)
1203 if (iterDI->dIdXcols[cnt2] == col1)
1204 { bmatch =
true;
break; }
1208 msg =
"pdTerminalCurrents: Could not find a column match in dIdXcols";
1209 N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
1215 col1 = iterDI->Ncol[iNcol];
1220 for (cnt2=0;cnt2<iterDI->dIdXcols.size();++cnt2)
1222 if (iterDI->dIdXcols[cnt2] == col1)
1223 { bmatch =
true;
break; }
1227 msg =
"pdTerminalCurrents: Could not find a column match in dIdXcols";
1228 N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
1234 col1 = iterDI->Pcol[iPcol];
1239 int size = iterDI->dIdXcols.size();
1240 for (cnt2=0;cnt2<size;++cnt2)
1242 if (iterDI->dIdXcols[cnt2] == col1)
1243 { bmatch =
true;
break; }
1247 msg =
"pdTerminalCurrents: Could not find a column match in dIdXcols";
1248 N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
1257 #ifdef Xyce_DEBUG_DEVICE
1260 for(iterDI=firstDI;iterDI!=lastDI;++iterDI)
1262 int size = iterDI->dIdXcols.size();
1263 int size2= iterDI->dIdX.size ();
1264 Xyce::dout() <<
"dIdX for electrode: " << iterDI->eName << std::endl;
1265 for (
int ididx=0;ididx<size;++ididx)
1267 Xyce::dout() <<
"\t"<< iterDI->dIdXcols[ididx];
1268 Xyce::dout() <<
"\t"<< iterDI->dIdX[ididx] << std::endl;
1271 Xyce::dout() <<
"Done with Instance::pdTerminalCurrents" << std::endl;
1295 bool bsuccess =
true;
1297 #ifdef Xyce_DEBUG_DEVICE
1300 Xyce::dout() << section_divider <<
"\n";
1301 Xyce::dout() <<
"calcTerminalCharges. name = " <<
getName() << std::endl;
1306 std::vector<DeviceInterfaceNode>::iterator firstDI =
dIVec.begin ();
1307 std::vector<DeviceInterfaceNode>::iterator lastDI =
dIVec.end ();
1308 std::vector<DeviceInterfaceNode>::iterator iterDI;
1310 for (iterDI=firstDI; iterDI!=lastDI; ++iterDI)
1318 std::vector<int>::iterator firstI = labelPtr->
mNodeVector.begin();
1319 std::vector<int>::iterator lastI = labelPtr->
mNodeVector.end ();
1320 std::vector<int>::iterator iterI;
1322 iterDI->chargeSum = 0.0;
1325 for(nodeIndex=0,iterI=firstI;iterI!=lastI;++iterI,++nodeIndex)
1331 std::vector<EDGEINFO>::iterator firstEI = nodePtr->
edgeInfoVector.begin();
1332 std::vector<EDGEINFO>::iterator lastEI = nodePtr->
edgeInfoVector.end ();
1333 std::vector<EDGEINFO>::iterator iterEI;
1337 #ifdef Xyce_DEBUG_DEVICE
1340 Xyce::dout() <<
" --------------- " << std::endl;
1341 Xyce::dout() <<
"name = " << iterDI->eName;
1342 Xyce::dout() <<
" node = " << *iterI << std::endl;
1346 for (iterEI=firstEI;iterEI!=lastEI;++iterEI)
1348 int iedge = iterEI->iedge;
1349 int neighbor = iterEI->inode;
1352 double ilen = edgePtr->
ilen;
1354 double sign = (*iterI < neighbor) ? +1.0 : -1.0;
1359 #ifdef Xyce_DEBUG_DEVICE
1362 Xyce::dout() <<
"neighbor = "<< neighbor;
1363 Xyce::dout() <<
" Efield = " <<
EfieldVec[iedge];
1364 Xyce::dout() <<
" contrib = " << contrib << std::endl;
1370 #ifdef Xyce_DEBUG_DEVICE
1373 Xyce::dout() <<
" sum*scalingVars.a0 = "<< sum*tmp << std::endl;
1374 Xyce::dout() <<
" sum = " << sum << std::endl;
1375 Xyce::dout() <<
" --------------- " << std::endl;
1381 iterDI->chargeSum += sum;
1385 #ifdef Xyce_DEBUG_DEVICE
1388 Xyce::dout().setf(std::ios::scientific);
1389 Xyce::dout() <<
" " << iterDI->eName;
1390 Xyce::dout() <<
" terminal charge = " << iterDI->chargeSum << std::endl;
1396 #ifdef Xyce_DEBUG_DEVICE
1399 Xyce::dout() << section_divider << std::endl;
1435 bool bsuccess =
true;
1437 std::vector<DeviceInterfaceNode>::iterator firstDI =
dIVec.begin ();
1438 std::vector<DeviceInterfaceNode>::iterator lastDI =
dIVec.end ();
1439 std::vector<DeviceInterfaceNode>::iterator iterDI;
1457 for(iterDI=firstDI;iterDI!=lastDI;++iterDI)
1459 iterDI->dQdVckt = 0.0;
1464 #ifdef Xyce_DEBUG_DEVICE
1467 Xyce::dout() << Xyce::subsection_divider << std::endl;
1471 if (iterDI->gid ==-1)
continue;
1476 std::vector<int>::iterator firstI = labelPtr->
mNodeVector.begin();
1477 std::vector<int>::iterator lastI = labelPtr->
mNodeVector.end ();
1478 std::vector<int>::iterator iterI;
1480 std::vector<EDGEINFO>::iterator firstEI;
1481 std::vector<EDGEINFO>::iterator lastEI;
1482 std::vector<EDGEINFO>::iterator iterEI;
1491 for(nodeIndex=0,iterI=firstI;iterI!=lastI;++iterI,++nodeIndex)
1499 for (iterEI=firstEI; iterEI!=lastEI; ++iterEI)
1501 iedge = iterEI->iedge;
1502 inodeB = iterEI->inode;
1505 double elen = edgePtr->
elen;
1506 double ilen = edgePtr->
ilen;
1518 coef += sign* dEdV * ilen;
1523 iterDI->dQdVckt += tmpsum;
1525 #ifdef Xyce_DEBUG_DEVICE
1528 Xyce::dout().setf(std::ios::left);
1529 Xyce::dout() << iterDI->eName<<
":";
1530 Xyce::dout() <<
" KCL pdTerminalCharges row = " << iterDI->gid;
1531 Xyce::dout() <<
" contrib = " << tmpsum;
1532 Xyce::dout() <<
" dQdVckt = " << iterDI->dQdVckt << std::endl;
1538 #endif // Xyce_NEW_BC
1543 #ifdef Xyce_DEBUG_DEVICE
1546 Xyce::dout() << Xyce::subsection_divider << std::endl;
1549 #endif // Xyce_NEW_BC
1553 for(iterDI=firstDI;iterDI!=lastDI;++iterDI)
1557 int numdQdX = iterDI->dQdX.size ();
1558 for (
int j=0;j<numdQdX;++j)
1560 iterDI->dQdX[j] = 0.0;
1566 std::vector<int>::iterator firstI = labelPtr->
mNodeVector.begin();
1567 std::vector<int>::iterator lastI = labelPtr->
mNodeVector.end ();
1568 std::vector<int>::iterator iterI;
1570 std::vector<EDGEINFO>::iterator firstEI;
1571 std::vector<EDGEINFO>::iterator lastEI;
1572 std::vector<EDGEINFO>::iterator iterEI;
1580 for(nodeIndex=0,iterI=firstI;iterI!=lastI;++iterI,++nodeIndex)
1588 for (iterEI=firstEI; iterEI!=lastEI; ++iterEI)
1590 iedge = iterEI->iedge;
1591 inodeB = iterEI->inode;
1596 double elen = edgePtr->
elen;
1597 double ilen = edgePtr->
ilen;
1600 Vcoef += sign* dEdV * ilen;
1604 col1 = iterDI->Vcol[iVcol];
1609 for (cnt2=0;cnt2<iterDI->dIdXcols.size();++cnt2)
1611 if (iterDI->dIdXcols[cnt2] == col1)
1612 { bmatch =
true;
break; }
1616 msg =
"pdTerminalCharges: Could not find a column match in dIdXcols";
1617 N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
1626 for (iterEI=firstEI; iterEI!=lastEI; ++iterEI,++iVcol,++iNcol,++iPcol)
1628 iedge = iterEI->iedge;
1629 inodeB = iterEI->inode;
1634 double elen = edgePtr->
elen;
1635 double ilen = edgePtr->
ilen;
1638 Vcoef = sign* dEdV * ilen;
1640 col1 = iterDI->Vcol[iVcol];
1645 for (cnt2=0;cnt2<iterDI->dIdXcols.size();++cnt2)
1647 if (iterDI->dIdXcols[cnt2] == col1)
1648 { bmatch =
true;
break; }
1652 msg =
"pdTerminalCharges: Could not find a column match in dIdXcols";
1653 N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
1662 #ifdef Xyce_DEBUG_DEVICE
1665 for(iterDI=firstDI;iterDI!=lastDI;++iterDI)
1667 int size = iterDI->dIdXcols.size();
1668 int size2= iterDI->dQdX.size ();
1669 Xyce::dout() <<
"dQdX for electrode: " << iterDI->eName << std::endl;
1670 for (
int ididx=0;ididx<size;++ididx)
1672 Xyce::dout() <<
"\t"<< iterDI->dIdXcols[ididx];
1673 Xyce::dout() <<
"\t"<< iterDI->dQdX[ididx] << std::endl;
1676 Xyce::dout() <<
"Done with Instance::pdTerminalCharges" << std::endl;
1708 bool bsuccess =
true;
1711 N_LAS_Vector & dfdv = *dfdvPtr;
1718 for (iNeighbor=0;iNeighbor<numNeighbor;++iNeighbor)
1728 for (iNN=0;iNN<nodePtr->
cnode;++iNN)
1740 coef = dINode.
dFdVckt[dFdVindex];
1745 bs1 = dfdv.setElementByGlobalIndex(Vrow, -coef, 0);
1746 bsuccess = bsuccess && bs1;
1757 coef = dINode.
dFdVckt[dFdVindex];
1762 bs1 = dfdv.setElementByGlobalIndex(Nrow, -coef, 0);
1763 bsuccess = bsuccess && bs1;
1774 coef = dINode.
dFdVckt[dFdVindex];
1779 bs1 = dfdv.setElementByGlobalIndex(Prow, -coef, 0);
1780 bsuccess = bsuccess && bs1;
1835 bool bsuccess =
true;
1836 const N_LAS_Vector & dxdv = *dxdvPtr;
1840 #ifdef Xyce_DEBUG_DEVICE
1841 char filename1[256];
1843 for (
int ich = 0; ich < 256; ++ich)
1844 { filename1[ich] = 0; }
1848 Xyce::dout() << section_divider <<
"\n";
1849 Xyce::dout() <<
"calcConductances name = " <<
getName() << std::endl;
1850 Xyce::dout() <<
"electrode = " <<
dIVec[iElectrode].eName;
1851 Xyce::dout() <<
" dIdVckt = " <<
dIVec[iElectrode].dIdVckt;
1852 Xyce::dout() << std::endl;
1853 Xyce::dout() << std::endl;
1857 if (!(
dIVec[iElectrode].dxdvAllocated))
1860 dIVec[iElectrode].dxdvAllocated =
true;
1866 *(
dIVec[iElectrode].dxdvPtr) = *(dxdvPtr);
1873 double dIidVj = 0.0;
1874 double dIidVj_chain = 0.0;
1877 double dQidVj = 0.0;
1878 double dQidVj_chain = 0.0;
1894 if (iElectrode != iEqu)
1901 dIidVj =
dIVec[iEqu].dIdVckt;
1902 dQidVj =
dIVec[iEqu].dQdVckt;
1908 int DIDXSize =
dIVec[iEqu].dIdX.size();
1909 for (
int iDIDX=0;iDIDX<DIDXSize;++iDIDX)
1911 int index =
dIVec[iEqu].dIdXcols[iDIDX];
1912 double coefI =
dIVec[iEqu].dIdX[iDIDX];
1913 double coefQ =
dIVec[iEqu].dQdX[iDIDX];
1932 #ifdef Xyce_DEBUG_DEVICE
1933 sprintf(filename1,
"dIdX%02d.txt", iEqu);
1936 sprintf(filename1,
"dQdX%02d.txt", iEqu);
1944 Gij = dIidVj_chain + dIidVj;
1945 condVec[iEqu][iElectrode] = Gij;
1952 Cij = dQidVj_chain + dQidVj;
1953 capVec[iEqu][iElectrode] = Cij;
1955 #ifdef Xyce_DEBUG_DEVICE
1958 char outstring[128];
1959 double Itmp =
dIVec[iEqu].currentSum;
1960 double Vtmp =
dIVec[iEqu].Vckt -
dIVec[iElectrode].Vckt;
1962 double GV = Gij*Vtmp;
1963 for(
int i=0;i<128;++i) outstring[i] = static_cast<char>(0);
1965 "(%2d,%2d): dotPr=%12.4e G=%12.4e",
1966 iEqu,iElectrode,dIidVj_chain,Gij);
1967 Xyce::dout() << std::string(outstring) << std::endl;
1970 "(%2d,%2d): G=%12.4e G*V=%12.4e I=%12.4e V=%12.4e",
1971 iEqu,iElectrode,Gij,GV,Itmp,Vtmp);
1972 Xyce::dout() << std::string(outstring) << std::endl;
1977 #ifdef Xyce_DEBUG_DEVICE
1980 Xyce::dout() << section_divider << std::endl;
1997 bool bsuccess =
true;
2001 std::vector<DeviceInterfaceNode>::iterator firstDI =
dIVec.begin();
2002 std::vector<DeviceInterfaceNode>::iterator lastDI =
dIVec.end ();
2003 std::vector<DeviceInterfaceNode>::iterator iterDI = firstDI;
2005 for (; iterDI!=lastDI;++iterDI)
2009 if (iterDI->stateC_owned)
2012 (staVectorPtr)->setElementByGlobalIndex( iterDI->stateC,
2013 iterDI->currentSum, 0);
2018 (*staVectorPtr)[iterDI->li_stateC] = iterDI->currentSum;
2025 #ifdef Xyce_OLD_DISPLACEMENT
2036 (staVectorPtr)->setElementByGlobalIndex(
stateDispl[i], D, 0);
2081 bool bsuccess =
true;
2088 std::vector<DeviceInterfaceNode>::iterator firstDI =
dIVec.begin();
2089 std::vector<DeviceInterfaceNode>::iterator lastDI =
dIVec.end ();
2090 std::vector<DeviceInterfaceNode>::iterator iterDI = firstDI;
2092 for (; iterDI!=lastDI;++iterDI)
2097 iterDI->currentSum =
2098 (staVectorPtr)->getElementByGlobalIndex( iterDI->stateC, 0);
2102 iterDI->currentSum = (*staVectorPtr)[iterDI->li_stateC];
2110 #ifdef Xyce_OLD_DISPLACEMENT
2150 int inodeA = edgePtr->
inodeA;
2151 int inodeB = edgePtr->
inodeB;
2152 double elen = edgePtr->
elen;
2162 #ifdef Xyce_DEBUG_DEVICE
2164 Xyce::dout() <<
" Maximum displacement current: " << dcmax << std::endl;
2192 bool bsuccess =
true;
2195 #ifdef Xyce_DEBUG_DEVICE
2198 Xyce::dout() <<
"Instance::setInitialGuess\n";
2215 #ifdef Xyce_DEBUG_DEVICE
2253 bool bsuccess =
true;
2257 int Vrow, Nrow, Prow;
2262 double ilen, elen, nodeArea;
2268 #ifdef Xyce_DEBUG_DEVICE
2271 Xyce::dout() << section_divider <<
"\n";
2272 Xyce::dout() <<
"Instance::loadVecNLPoisson\n";
2273 Xyce::dout() <<
" name = " <<
getName() <<
"\n";
2275 Xyce::dout() <<
" Vt = " <<
Vt <<
"\n";
2276 Xyce::dout() <<
" Ut = " <<
Ut <<
"\n";
2277 Xyce::dout() <<
" scalingVars.V0 = " <<
scalingVars.
V0 <<
"\n";
2285 #ifdef Xyce_DEBUG_DEVICE
2288 Xyce::dout() <<
"--------" << std::endl;
2289 Xyce::dout() <<
"Mesh Point i = " << i;
2316 #else // "old" boundary condition:
2317 bool doneFlag =
false;
2327 int i1 =
dIVec[DIindex].meshGlobalToLocal[i];
2328 coef = vtmp -
dIVec[DIindex].VbcVec[i1];
2330 #ifdef Xyce_DEBUG_DEVICE
2333 Xyce::dout() <<
"BC load: Vrow = " << Vrow <<
" coef = " << coef << std::endl;
2334 Xyce::dout() <<
" vtmp = " << vtmp << std::endl;
2335 Xyce::dout() <<
" Vckt = " <<
dIVec[DIindex].Vckt << std::endl;
2340 bs1 = vecPtr->sumElementByGlobalIndex(Vrow, -scalar*coef, 0);
2341 bsuccess = bsuccess && bs1;
2342 bs1 = vecPtr->sumElementByGlobalIndex(Nrow, 0.0 , 0);
2343 bsuccess = bsuccess && bs1;
2344 bs1 = vecPtr->sumElementByGlobalIndex(Prow, 0.0 , 0);
2345 bsuccess = bsuccess && bs1;
2349 (*vecPtr)[Vrow] += -scalar*coef;
2350 (*vecPtr)[Nrow] += 0.0;
2351 (*vecPtr)[Prow] += 0.0;
2359 if (doneFlag)
continue;
2360 #endif // Xyce_NEW_BC
2364 nodeArea = nodePtr->
area;
2365 #ifdef Xyce_DEBUG_DEVICE
2368 Xyce::dout() <<
"--------" << std::endl;
2369 Xyce::dout() <<
"Interior: mesh point: " << i <<
" Vrow = " << Vrow;
2370 Xyce::dout() << std::endl;
2375 for (
int iNN=0;iNN<nodePtr->
cnode;++iNN)
2382 double efield_loc = (
VVec[i]-
VVec[inodeB])/elen;
2383 coef += -efield_loc * ilen ;
2384 #ifdef Xyce_DEBUG_DEVICE
2387 Xyce::dout() <<
"----" << std::endl;
2388 Xyce::dout() <<
" iedge = " << iedge << std::endl;
2389 Xyce::dout() <<
" Vlocal = " <<
VVec[i] << std::endl;
2390 Xyce::dout() <<
" Vneigh = " <<
VVec[inodeB] << std::endl;
2391 Xyce::dout() <<
" efield = " << efield_loc << std::endl;
2392 Xyce::dout() <<
" elen = " << elen << std::endl;
2393 Xyce::dout() <<
" ilen = " << ilen << std::endl;
2394 Xyce::dout() <<
" inodeB = " << inodeB;
2397 Xyce::dout() << std::endl;
2405 coef2 = -(holeDens-elecDens+
CVec[i]);
2407 #ifdef Xyce_OXIDE_ENABLED
2416 #ifdef Xyce_DEBUG_DEVICE
2419 Xyce::dout() <<
"--------" << std::endl;
2420 Xyce::dout() <<
" holeD = " << holeDens << std::endl;
2421 Xyce::dout() <<
" elecD = " << elecDens << std::endl;
2422 Xyce::dout() <<
" dopeD = " <<
CVec[i] << std::endl;
2423 Xyce::dout() <<
" coef2 = " << coef2 << std::endl;
2425 Xyce::dout() <<
" nodeArea = " << nodeArea << std::endl;
2426 Xyce::dout() <<
" coef = " << coef << std::endl;
2427 Xyce::dout() <<
"--------" << std::endl;
2433 bs1 = vecPtr->sumElementByGlobalIndex(Vrow, -scalar*coef, 0);
2434 bsuccess = bsuccess && bs1;
2435 bs1 = vecPtr->sumElementByGlobalIndex(Nrow, 0.0 , 0);
2436 bsuccess = bsuccess && bs1;
2437 bs1 = vecPtr->sumElementByGlobalIndex(Prow, 0.0 , 0);
2438 bsuccess = bsuccess && bs1;
2442 (*vecPtr)[Vrow] += -scalar*coef;
2443 (*vecPtr)[Nrow] += 0.0;
2444 (*vecPtr)[Prow] += 0.0;
2449 #ifdef Xyce_DEBUG_DEVICE
2451 Xyce::dout() << section_divider << std::endl;
2466 (
double scalar,
double dndtScalar, N_LAS_Vector * vecPtr)
2468 bool bsuccess =
true;
2470 std::string semi(bulkMaterial);
2473 int Vrow, Nrow, Prow;
2475 double ilen, elen, nodeArea;
2476 double holeDens, elecDens;
2483 #ifdef Xyce_DEBUG_DEVICE
2484 if (getDeviceOptions().debugLevel > 0 && getSolverState().debugTimeFlag)
2486 Xyce::dout() <<
"\n"<<section_divider << std::endl;
2487 Xyce::dout() <<
"Instance::loadVecDDForm\n";
2488 Xyce::dout() <<
" name = " << getName() <<
"\n";
2493 std::vector<DeviceInterfaceNode>::iterator firstDI = dIVec.begin();
2494 std::vector<DeviceInterfaceNode>::iterator lastDI = dIVec.end ();
2495 std::vector<DeviceInterfaceNode>::iterator iterDI = firstDI;
2499 if ( !(getSolverState().twoLevelNewtonCouplingMode==
INNER_PROBLEM))
2501 for (;iterDI!=lastDI;++iterDI)
2503 coef = iterDI->currentSum;
2505 if( useVectorGIDFlag )
2507 if (iterDI->gid != -1)
2509 bs1 = vecPtr->sumElementByGlobalIndex(iterDI->gid, -scalar*coef, 0);
2510 bsuccess = bsuccess && bs1;
2515 (*vecPtr)[iterDI->lid] += -scalar*coef;
2518 #ifdef Xyce_DEBUG_DEVICE
2519 if (getDeviceOptions().debugLevel > 0 && getSolverState().debugTimeFlag)
2521 Xyce::dout() <<
"KCL for "<< iterDI->eName <<
":\n";
2522 Xyce::dout() <<
" row = " << iterDI->gid <<
"\n";
2523 Xyce::dout() <<
"coef = " << coef <<
"\n";
2531 for (i=0;i<numMeshPoints;++i)
2533 #ifdef Xyce_DEBUG_DEVICE
2534 if (getDeviceOptions().debugLevel > 1 && getSolverState().debugTimeFlag)
2536 Xyce::dout() <<
"--------" << std::endl;
2537 Xyce::dout() <<
"Mesh Point i = " << i;
2538 Xyce::dout() <<
" x = " << xVec[i]*scalingVars.x0;
2539 Xyce::dout() <<
" y = " << yVec[i]*scalingVars.x0 << std::endl;
2543 if( useVectorGIDFlag )
2545 Vrow = Vrowarray[i];
2546 Nrow = Nrowarray[i];
2547 Prow = Prowarray[i];
2551 Vrow = li_Vrowarray[i];
2552 Nrow = li_Nrowarray[i];
2553 Prow = li_Prowarray[i];
2556 bool doneFlagV =
false;
2557 bool doneFlagN =
false;
2558 bool doneFlagP =
false;
2564 if (boundarySten[i])
continue;
2566 bool doneFlag =
false;
2573 if (boundarySten[i])
2575 int DIindex = labelDIMap[labelNameVector[i]];
2577 if (dIVec[DIindex].given)
2579 int ilocal = dIVec[DIindex].meshGlobalToLocal[i];
2581 if (dIVec[DIindex].neumannBCFlagV==
false)
2584 if (vOwnVec[i] == 1) vtmp = VVec[i];
2586 coef = vtmp - dIVec[DIindex].VbcVec[ilocal];
2588 if( useVectorGIDFlag )
2590 bs1 = vecPtr->sumElementByGlobalIndex(Vrow, -scalar*coef, 0);
2591 bsuccess = bsuccess && bs1;
2595 (*vecPtr)[Vrow] += -scalar*coef;
2598 #ifdef Xyce_DEBUG_DEVICE
2599 if (getDeviceOptions().debugLevel > 1 && getSolverState().debugTimeFlag)
2601 Xyce::dout() <<
"BC load: Vrow = " << Vrow;
2602 Xyce::dout() <<
" coef = " << coef << std::endl;
2603 Xyce::dout() <<
" vtmp = " << vtmp << std::endl;
2604 Xyce::dout() <<
" Vckt = " << dIVec[DIindex].Vckt << std::endl;
2605 Xyce::dout() <<
" Vequ = " << dIVec[DIindex].VequVec[ilocal] << std::endl;
2611 if (dIVec[DIindex].neumannBCFlagN==
false)
2614 if (nnOwnVec[i] == 1) ntmp = nnVec[i];
2615 coef = ntmp - (dIVec[DIindex].nnbcVec[ilocal]);
2617 if( useVectorGIDFlag )
2619 bs1 = vecPtr->sumElementByGlobalIndex(Nrow, -scalar*coef , 0);
2620 bsuccess = bsuccess && bs1;
2624 (*vecPtr)[Nrow] += -scalar*coef;
2627 #ifdef Xyce_DEBUG_DEVICE
2628 if (getDeviceOptions().debugLevel > 1 && getSolverState().debugTimeFlag)
2630 Xyce::dout() <<
"BC load: Nrow = ";
2631 Xyce::dout() << Nrow <<
" coef = " << coef << std::endl;
2632 Xyce::dout() <<
" ntmp = " << ntmp << std::endl;
2633 Xyce::dout() <<
" nnbc = " << dIVec[DIindex].nnbcVec[ilocal] << std::endl;
2640 if (dIVec[DIindex].neumannBCFlagP==
false)
2643 if (npOwnVec[i] == 1) ptmp = npVec[i];
2644 coef = ptmp - (dIVec[DIindex].npbcVec[ilocal]);
2646 if( useVectorGIDFlag )
2648 bs1 = vecPtr->sumElementByGlobalIndex(Prow, -scalar*coef , 0);
2649 bsuccess = bsuccess && bs1;
2653 (*vecPtr)[Prow] += -scalar*coef;
2656 #ifdef Xyce_DEBUG_DEVICE
2657 if (getDeviceOptions().debugLevel > 1 && getSolverState().debugTimeFlag)
2659 Xyce::dout() <<
"BC load: Prow = ";
2660 Xyce::dout() << Prow <<
" coef = " << coef << std::endl;
2661 Xyce::dout() <<
" ptmp = " << ptmp << std::endl;
2662 Xyce::dout() <<
" npbc = " << dIVec[DIindex].npbcVec[ilocal] << std::endl;
2668 doneFlag = (doneFlagV && doneFlagN && doneFlagP);
2673 if (doneFlag)
continue;
2675 #endif // Xyce_NEW_BC
2679 mNode * nodePtr = meshContainerPtr->getNode(i);
2680 nodeArea = nodePtr->
area;
2681 #ifdef Xyce_DEBUG_DEVICE
2682 if (getDeviceOptions().debugLevel > 1 && getSolverState().debugTimeFlag)
2684 Xyce::dout() <<
"--------" << std::endl;
2685 Xyce::dout() <<
"Interior: mesh point: " << i <<
" Vrow = " << Vrow;
2686 Xyce::dout() << std::endl;
2693 #ifdef Xyce_DEBUG_DEVICE
2694 if (getDeviceOptions().debugLevel > 1 && getSolverState().debugTimeFlag)
2696 Xyce::dout() <<
"--------" << std::endl;
2697 Xyce::dout() <<
" Poisson equ:";
2702 for (iNN=0;iNN<nodePtr->
cnode;++iNN)
2710 double efield_loc = (VVec[i]-VVec[inodeB])/elen;
2711 coef += -efield_loc * ilen ;
2712 #ifdef Xyce_DEBUG_DEVICE
2713 if (getDeviceOptions().debugLevel > 1 && getSolverState().debugTimeFlag)
2715 Xyce::dout() <<
"----" << std::endl;
2716 Xyce::dout() <<
" iedge = " << iedge << std::endl;
2717 Xyce::dout() <<
" Vlocal = " << VVec[i] << std::endl;
2718 Xyce::dout() <<
" Vneigh = " << VVec[inodeB] << std::endl;
2719 Xyce::dout() <<
" efield = " << efield_loc << std::endl;
2720 Xyce::dout() <<
" elen = " << elen << std::endl;
2721 Xyce::dout() <<
" ilen = " << ilen << std::endl;
2722 Xyce::dout() <<
" inodeB = " << inodeB;
2723 Xyce::dout() <<
" x[b] = " << xVec[inodeB]*scalingVars.x0;
2724 Xyce::dout() <<
" y[b] = " << yVec[inodeB]*scalingVars.x0 << std::endl;
2725 Xyce::dout() << std::endl;
2729 coef *= -scalingVars.L0 * matSupport.getRelPerm(semi)/nodeArea;
2731 holeDens = npVec[i];
2732 elecDens = nnVec[i];
2733 coef2 = -(holeDens-elecDens+CVec[i]);
2735 #ifdef Xyce_OXIDE_ENABLED
2744 #ifdef Xyce_DEBUG_DEVICE
2745 if (getDeviceOptions().debugLevel > 1 && getSolverState().debugTimeFlag)
2747 Xyce::dout() <<
"--------" << std::endl;
2748 Xyce::dout() <<
" holeD = " << holeDens << std::endl;
2749 Xyce::dout() <<
" elecD = " << elecDens << std::endl;
2750 Xyce::dout() <<
" dopeD = " << CVec[i] << std::endl;
2751 Xyce::dout() <<
" coef2 = " << coef2 << std::endl;
2752 Xyce::dout() <<
" scalingVars.L0 = " << scalingVars.L0 * matSupport.getRelPerm(semi) << std::endl;
2753 Xyce::dout() <<
" nodeArea = " << nodeArea << std::endl;
2754 Xyce::dout() <<
" coef = " << coef << std::endl;
2755 Xyce::dout() <<
"--------" << std::endl;
2758 if ( getSolverState().chargeHomotopy )
2760 coef *= getSolverState().chargeAlpha;
2763 if( useVectorGIDFlag )
2765 bs1 = vecPtr->sumElementByGlobalIndex(Vrow, -scalar*coef, 0);
2766 bsuccess = bsuccess && bs1;
2770 (*vecPtr)[Vrow] += -scalar*coef;
2782 #ifdef Xyce_DEBUG_DEVICE
2783 if (getDeviceOptions().debugLevel > 1 && getSolverState().debugTimeFlag)
2785 Xyce::dout() <<
"--------" << std::endl;
2786 Xyce::dout() <<
" Electron equ:";
2793 if( useVectorGIDFlag )
2795 if ( !((getSolverState().dcopFlag) || Nrowarray[i] == -1) )
2797 dndt = (extData.nextSolDerivVectorPtr)->getElementByGlobalIndex
2803 if ( !(getSolverState().dcopFlag) )
2804 dndt = (*extData.nextSolDerivVectorPtr)[li_Nrowarray[i]];
2807 dndt *= scalingVars.t0*dndtScalar;
2811 for (iNN=0;iNN<nodePtr->
cnode;++iNN)
2818 coef += ((i<inodeB)?1.0:-1.0) * JnVec[iedge] * ilen ;
2820 #ifdef Xyce_DEBUG_DEVICE
2821 if (getDeviceOptions().debugLevel > 1 && getSolverState().debugTimeFlag)
2823 Xyce::dout() <<
"----" << std::endl;
2824 Xyce::dout() <<
" iedge = " << iedge << std::endl;
2825 Xyce::dout() <<
" Jn = " << JnVec[iedge] << std::endl;
2826 Xyce::dout() <<
" nlocal = " << nnVec[i] << std::endl;
2827 Xyce::dout() <<
" nneigh = " << nnVec[inodeB] << std::endl;
2828 Xyce::dout() <<
" elen = " << elen << std::endl;
2829 Xyce::dout() <<
" ilen = " << ilen << std::endl;
2830 Xyce::dout() <<
" inodeB = " << inodeB;
2831 Xyce::dout() <<
" x[b] = " << xVec[inodeB]*scalingVars.x0;
2832 Xyce::dout() <<
" y[b] = " << yVec[inodeB]*scalingVars.x0 << std::endl;
2833 Xyce::dout() << std::endl;
2839 coef += - totSrcVec[i] - dndt;
2841 coef += - RVec[i] - dndt;
2844 coef += elecPenalty[i];
2846 #ifdef Xyce_DEBUG_DEVICE
2847 if (getDeviceOptions().debugLevel > 1 && getSolverState().debugTimeFlag)
2849 Xyce::dout() <<
"--------" << std::endl;
2850 Xyce::dout().setf(std::ios::left);
2851 Xyce::dout() <<
" row = " << Nrow;
2852 Xyce::dout().setf(std::ios::scientific);
2853 Xyce::dout() <<
" coef=" << coef;
2854 Xyce::dout() <<
" nodeArea ="<<nodeArea;
2855 Xyce::dout() <<
" R[i]="<<RVec[i];
2856 Xyce::dout() <<
" dndt="<<dndt;
2857 Xyce::dout() <<
"\n";
2858 Xyce::dout() <<
"--------" << std::endl;
2862 if( useVectorGIDFlag )
2864 bs1 = vecPtr->setElementByGlobalIndex(Nrow,-scalar*coef,0);
2865 bsuccess = bsuccess && bs1;
2869 (*vecPtr)[Nrow] += -scalar*coef;
2880 #ifdef Xyce_DEBUG_DEVICE
2881 if (getDeviceOptions().debugLevel > 1 && getSolverState().debugTimeFlag)
2883 Xyce::dout() <<
"--------" << std::endl;
2884 Xyce::dout() <<
" Hole equ:";
2890 if( useVectorGIDFlag )
2892 if ( !((getSolverState().dcopFlag) || Prowarray[i] == -1) )
2893 dpdt = (extData.nextSolDerivVectorPtr)->getElementByGlobalIndex
2898 if ( !(getSolverState().dcopFlag) )
2899 dpdt = (*extData.nextSolDerivVectorPtr)[li_Prowarray[i]];
2902 dpdt *= scalingVars.t0*dndtScalar;
2906 for (iNN=0;iNN<nodePtr->
cnode;++iNN)
2913 coef += ((i<inodeB)?1.0:-1.0) * JpVec[iedge] * ilen ;
2915 #ifdef Xyce_DEBUG_DEVICE
2916 if (getDeviceOptions().debugLevel > 1 && getSolverState().debugTimeFlag)
2918 Xyce::dout() <<
"----" << std::endl;
2919 Xyce::dout() <<
" iedge = " << iedge << std::endl;
2920 Xyce::dout() <<
" Jp = " << JpVec[iedge] << std::endl;
2921 Xyce::dout() <<
" plocal = " << npVec[i] << std::endl;
2922 Xyce::dout() <<
" pneigh = " << npVec[inodeB] << std::endl;
2923 Xyce::dout() <<
" elen = " << elen << std::endl;
2924 Xyce::dout() <<
" ilen = " << ilen << std::endl;
2925 Xyce::dout() <<
" inodeB = " << inodeB;
2926 Xyce::dout() <<
" x[b] = " << xVec[inodeB]*scalingVars.x0;
2927 Xyce::dout() <<
" y[b] = " << yVec[inodeB]*scalingVars.x0 << std::endl;
2928 Xyce::dout() << std::endl;
2935 coef += - totSrcVec[i] - dpdt;
2937 coef += - RVec[i] - dpdt;
2939 coef += holePenalty[i];
2941 #ifdef Xyce_DEBUG_DEVICE
2942 if (getDeviceOptions().debugLevel > 1 && getSolverState().debugTimeFlag)
2944 Xyce::dout() <<
"--------" << std::endl;
2945 Xyce::dout().setf(std::ios::left);
2946 Xyce::dout() <<
" row = " << Prow;
2947 Xyce::dout().setf(std::ios::scientific);
2948 Xyce::dout() <<
" coef=" << coef;
2949 Xyce::dout() <<
" nodeArea ="<<nodeArea;
2950 Xyce::dout() <<
" RVec[i]="<<RVec[i];
2951 Xyce::dout() <<
" dpdt="<<dpdt;
2952 Xyce::dout() <<
"\n";
2953 Xyce::dout() <<
"--------" << std::endl;
2957 if( useVectorGIDFlag )
2959 bs1 = vecPtr->setElementByGlobalIndex(Prow,-scalar*coef,0);
2960 bsuccess = bsuccess && bs1;
2964 (*vecPtr)[Prow] += -scalar*coef;
2973 #ifdef Xyce_DEBUG_DEVICE
2974 if (getDeviceOptions().debugLevel > 0 && getSolverState().debugTimeFlag)
2975 Xyce::dout() << section_divider << std::endl;
2992 bool bsuccess =
true;
2995 int Vrow, Nrow, Prow;
2997 #ifdef Xyce_DEBUG_DEVICE
3000 Xyce::dout() << section_divider <<
"\n";
3001 Xyce::dout() <<
"Instance::loadJacNonlinPoisson" <<
"\n";
3002 Xyce::dout() <<
" name = " <<
getName() <<
"\n";
3003 Xyce::dout() <<
"\n";
3011 double pre = 1.0/
Ut;
3019 double ilen, elen, nodeArea;
3021 #ifdef Xyce_DEBUG_DEVICE
3025 Xyce::dout() <<
"pre = " << pre <<
"\n";
3026 Xyce::dout() <<
"Vt = " <<
Vt <<
"\n";
3027 Xyce::dout() <<
"eps = " <<
eps <<
"\n";
3028 Xyce::dout() <<
"q = " << q <<
"\n";
3029 Xyce::dout() <<
"Na = " <<
Na <<
"\n";
3030 Xyce::dout() <<
"Nd = " <<
Nd <<
"\n";
3031 Xyce::dout() <<
"NpMax = " <<
NpMax <<
"\n";
3032 Xyce::dout() <<
"NnMax = " <<
NnMax <<
"\n";
3037 int numCol =
cols.size();
3047 for (j=0;j<numCol;++j)
3053 std::vector<DeviceInterfaceNode>::iterator firstDI =
dIVec.begin ();
3054 std::vector<DeviceInterfaceNode>::iterator lastDI =
dIVec.end ();
3055 std::vector<DeviceInterfaceNode>::iterator iterDI;
3062 for(iterDI=firstDI;iterDI!=lastDI;++iterDI)
3064 if (iterDI->gid !=-1)
3066 cols[0] = iterDI->gid;
3067 bs1 = matPtr->putRow (iterDI->gid, 1, &
vals[0], &
cols[0]);
3068 bsuccess = bsuccess && bs1;
3077 #ifdef Xyce_DEBUG_DEVICE
3080 Xyce::dout() <<
"\nmesh point i = " << i << std::endl;
3083 for (j=0;j<numCol;++j)
3096 bool doneFlag =
false;
3113 if (
dIVec[DIindex].gid != -1)
3123 bs1 = matPtr->putRow (Vrow, count, &
vals[0], &
cols[0]);
3124 bsuccess = bsuccess && bs1;
3126 #ifdef Xyce_DEBUG_DEVICE
3129 Xyce::dout() <<
"BC load: Vrow = " << Vrow << std::endl;
3130 for (
int eric=0;eric<count;++eric)
3132 Xyce::dout() <<
" cols["<<eric<<
"] = " <<
cols[eric];
3133 Xyce::dout() <<
" vals["<<eric<<
"] = " <<
vals[eric];
3134 Xyce::dout() << std::endl;
3145 bs1 = matPtr->putRow (Nrow, 1, &
vals[0], &
cols[0]);
3146 bsuccess = bsuccess && bs1;
3148 #ifdef Xyce_DEBUG_DEVICE
3151 Xyce::dout() <<
"BC load: Nrow = " << Nrow;
3152 Xyce::dout() <<
" coef = " <<
vals[0] << std::endl;
3163 bs1 = matPtr->putRow (Prow, 1, &
vals[0], &
cols[0]);
3164 bsuccess = bsuccess && bs1;
3166 #ifdef Xyce_DEBUG_DEVICE
3169 Xyce::dout() <<
"BC load: Prow = " << Vrow;
3170 Xyce::dout() <<
" coef = " <<
vals[0] << std::endl;
3180 if (doneFlag)
continue;
3181 #endif // Xyce_NEW_BC
3186 #ifdef Xyce_OXIDE_ENABLED
3198 nodeArea = nodePtr->
area;
3203 for (iNN=0;iNN<nodePtr->
cnode;++iNN)
3214 #ifdef Xyce_OXIDE_ENABLED
3217 coef += pre*holeDens + pre*elecDens;
3220 coef += pre*holeDens + pre*elecDens;
3231 Xyce::dout() <<
" center point: i="<<i;
3232 Xyce::dout() <<
" xVec[i] = " <<
xVec[i];
3233 Xyce::dout() <<
" yVec[i] = " <<
yVec[i];
3234 Xyce::dout() << std::endl;
3236 Xyce::dout() <<
" boundarySten = " <<
boundarySten[i] << std::endl;
3237 Xyce::dout() <<
" Vcolarray[i][0] = ";
3238 Xyce::dout() <<
Vcolarray[i][0] << std::endl;
3243 for (iNN=0;iNN<nodePtr->
cnode;++iNN)
3245 #ifdef Xyce_DEBUG_DEVICE
3248 Xyce::dout() <<
"non-center point: i="<<i;
3249 Xyce::dout() <<
" Vcolarray[i]["<<iNN+1<<
"] = ";
3250 Xyce::dout() <<
Vcolarray[i][iNN+1] << std::endl;
3253 if (
Vcolarray[i][iNN+1] == -1)
continue;
3267 #ifdef Xyce_DEBUG_DEVICE
3270 Xyce::dout() <<
"\n";
3271 Xyce::dout().setf(std::ios::left);
3272 Xyce::dout() <<
" POISSON LOAD: row = " << Vrow;
3273 Xyce::dout() <<
" count = " << count <<
"\n";
3274 Xyce::dout().setf(std::ios::scientific);
3275 for (j=0;j<count;++j)
3277 Xyce::dout() <<
" cols["<<j<<
"] = " <<
cols[j];
3278 Xyce::dout() <<
" vals["<<j<<
"] = " <<
vals[j];
3279 Xyce::dout() << std::endl;
3284 if (Vrow != -1 && count > 0)
3286 bs1 = matPtr->putRow (Vrow, count, &
vals[0], &
cols[0]);
3287 bsuccess = bsuccess && bs1;
3291 Xyce::dout() <<
"OOOPS!" << std::endl;
3300 bs1 = matPtr->putRow (Nrow, 1, &
vals[0], &
cols[0]);
3301 bsuccess = bsuccess && bs1;
3308 bs1 = matPtr->putRow (Prow, 1, &
vals[0], &
cols[0]);
3309 bsuccess = bsuccess && bs1;
3312 #ifdef Xyce_DEBUG_DEVICE
3315 Xyce::dout() << subsection_divider <<
"\n";
3335 bool doneFlag =
false;
3348 (*matPtr)[Vrow][Voff[0]] = 1.0;
3352 (*matPtr)[Nrow][Noff[0]] = 1.0;
3355 (*matPtr)[Prow][Poff[0]] = 1.0;
3361 if (doneFlag)
continue;
3362 #endif // Xyce_NEW_BC
3367 #ifdef Xyce_OXIDE_ENABLED
3379 nodeArea = nodePtr->
area;
3384 for (iNN=0;iNN<nodePtr->
cnode;++iNN)
3395 #ifdef Xyce_OXIDE_ENABLED
3398 coef += pre*holeDens + pre*elecDens;
3401 coef += pre*holeDens + pre*elecDens;
3404 (*matPtr)[Vrow][Voff[0]] += coef;
3408 for (iNN=0;iNN<nodePtr->
cnode;++iNN)
3412 if (
Vcolarray[i][iNN+1] == -1)
continue;
3421 (*matPtr)[Vrow][Voff[iNN+1]] += coef;
3425 (*matPtr)[Nrow][Noff[0]] = 1.0;
3428 (*matPtr)[Prow][Poff[0]] = 1.0;
3433 #ifdef Xyce_DEBUG_DEVICE
3436 Xyce::dout() << section_divider << std::endl;
3453 bool bsuccess =
true;
3458 #ifdef Xyce_DEBUG_DEVICE
3461 Xyce::dout() <<
"Starting Instance::loadJacKCLDDFormulation" << std::endl;
3465 std::vector<DeviceInterfaceNode>::iterator firstDI =
dIVec.begin ();
3466 std::vector<DeviceInterfaceNode>::iterator lastDI =
dIVec.end ();
3467 std::vector<DeviceInterfaceNode>::iterator iterDI;
3471 int numCol =
cols.size();
3475 for (j=0;j<numCol;++j)
3481 for(iterDI=firstDI;iterDI!=lastDI;++iterDI)
3483 if (iterDI->gid ==-1)
continue;
3486 cols[count] = iterDI->gid;
3494 vals[0] = iterDI->dIdVckt;
3496 #ifdef Xyce_DEBUG_DEVICE
3499 Xyce::dout() <<
"\n";
3500 Xyce::dout().setf(std::ios::left);
3501 Xyce::dout() <<
" KCL new BC LOAD: row = " << iterDI->gid;
3502 Xyce::dout() <<
" count = " << count;
3503 Xyce::dout() <<
" name = " << iterDI->eName <<
"\n";
3505 Xyce::dout().setf(std::ios::scientific);
3506 Xyce::dout() <<
" cols[0] = " <<
cols[0];
3507 Xyce::dout() <<
" vals[0] = " <<
vals[0];
3508 Xyce::dout() << std::endl;
3511 bs1 = matPtr->sumIntoRow (iterDI->gid, count, &
vals[0], &
cols[0]);
3512 bsuccess = bsuccess && bs1;
3513 #endif // Xyce_NEW_BC
3517 count = iterDI->dIdXcols.size();
3519 #ifdef Xyce_DEBUG_DEVICE
3522 Xyce::dout() <<
"\n";
3523 Xyce::dout().setf(std::ios::left);
3524 Xyce::dout() <<
" KCL LOAD: row = " << iterDI->gid;
3525 Xyce::dout() <<
" count = " << count;
3526 Xyce::dout() <<
" name = " << iterDI->eName <<
"\n";
3528 Xyce::dout().setf(std::ios::scientific);
3529 for (j=0;j<count;++j)
3531 Xyce::dout() <<
" cols["<<j<<
"] = " << iterDI->dIdXcols[j];
3532 Xyce::dout() <<
" vals["<<j<<
"] = " << iterDI->dIdX[j];
3533 Xyce::dout() << std::endl;
3538 bs1 = matPtr->sumIntoRow
3539 (iterDI->gid, count, &(iterDI->dIdX[0]), &(iterDI->dIdXcols[0]));
3540 bsuccess = bsuccess && bs1;
3546 for(iterDI=firstDI;iterDI!=lastDI;++iterDI)
3550 int offset = iterDI->lidOffset;
3553 coef = iterDI->dIdVckt;
3554 #endif // Xyce_NEW_BC
3556 (*matPtr)[iterDI->lid][offset] += coef;
3560 int size = iterDI->dIdXcols.size();
3561 for (
int i=0;i<size;++i)
3563 coef = iterDI->dIdX[i];
3564 offset = iterDI->dIdXoffset[i];
3565 (*matPtr)[iterDI->lid][offset] += coef;
3566 #ifdef Xyce_DEBUG_DEVICE
3569 Xyce::dout() <<
"dIdX["<<i<<
"] = " << iterDI->dIdX[i];
3570 Xyce::dout() <<
" dIdXcols["<<i<<
"] = " << iterDI->dIdXcols[i];
3571 Xyce::dout() <<
" dIdXoffset["<<i<<
"] = " << iterDI->dIdXoffset[i];
3572 Xyce::dout() << std::endl;
3579 #ifdef Xyce_DEBUG_DEVICE
3582 Xyce::dout() <<
"Done with Instance::loadJacKCLDDFormulation" << std::endl;
3603 bool bsuccess =
true;
3607 int numCol =
cols.size();
3610 std::vector<DeviceInterfaceNode>::iterator firstDI =
dIVec.begin ();
3611 std::vector<DeviceInterfaceNode>::iterator lastDI =
dIVec.end ();
3612 std::vector<DeviceInterfaceNode>::iterator iterDI;
3617 for(iterDI=firstDI;iterDI!=lastDI;++iterDI)
3619 if (iterDI->gid !=-1)
3621 cols[0] = iterDI->gid;
3622 bs1 = matPtr->putRow (iterDI->gid, 1, &
vals[0], &
cols[0]);
3623 bsuccess = bsuccess && bs1;
3629 for(iterDI=firstDI;iterDI!=lastDI;++iterDI)
3631 (*matPtr)[iterDI->lid][iterDI->lidOffset] = 1.0;
3647 (
double dndtScalar, N_LAS_Matrix * matPtr)
3649 bool bsuccess =
true;
3652 int Vrow, Nrow, Prow;
3654 #ifdef Xyce_DEBUG_DEVICE
3655 if (getDeviceOptions().debugLevel > 1 && getSolverState().debugTimeFlag)
3657 Xyce::dout() <<
"\n"<<section_divider <<
"\n";
3658 Xyce::dout() <<
"Instance::loadMatDDForm" <<
"\n";
3659 Xyce::dout() <<
" name = " << getName() <<
"\n";
3660 Xyce::dout() <<
"\n";
3673 double ilen, elen, nodeArea;
3676 int numCol = cols.size();
3677 if (vals.size () < cols.size()) numCol = vals.size();
3679 #ifdef Xyce_DEBUG_DEVICE
3687 if (!(getSolverState().dcopFlag))
3689 dDNDTdn = getSolverState().pdt*scalingVars.t0*dndtScalar;
3690 dDPDTdp = getSolverState().pdt*scalingVars.t0*dndtScalar;
3699 for (j=0;j<numCol;++j) { cols[j] = -1; vals[j] = 0.0; }
3702 if( useMatrixGIDFlag )
3704 for (i=0;i<numMeshPoints;++i)
3706 Vrow = Vrowarray[i];
3707 Nrow = Nrowarray[i];
3708 Prow = Prowarray[i];
3710 #ifdef Xyce_DEBUG_DEVICE
3711 if (getDeviceOptions().debugLevel > 2 && getSolverState().debugTimeFlag)
3713 Xyce::dout() << subsection_divider <<
"\n";
3714 Xyce::dout() <<
"mesh point i = " << i;
3715 Xyce::dout() <<
" Vrow = " << Vrow;
3716 Xyce::dout() <<
" Nrow = " << Nrow;
3717 Xyce::dout() <<
" Prow = " << Prow;
3718 Xyce::dout() <<
"\n";
3722 bool doneFlagV =
false;
3723 bool doneFlagN =
false;
3724 bool doneFlagP =
false;
3725 bool doneFlag =
false;
3727 if (boundarySten[i])
continue;
3732 if (boundarySten[i])
3734 int DIindex = labelDIMap[labelNameVector[i]];
3736 if (dIVec[DIindex].given)
3738 if (dIVec[DIindex].neumannBCFlagV==
false)
3740 #ifdef Xyce_DEBUG_DEVICE
3741 if (getDeviceOptions().debugLevel > 2 && getSolverState().debugTimeFlag)
3743 Xyce::dout() <<
"BC load: Vrow = " << Vrow << std::endl;
3753 if (dIVec[DIindex].gid != -1)
3756 vals[1] = -scalingVars.rV0;
3757 cols[1] = dIVec[DIindex].gid;
3763 bs1 = matPtr->putRow (Vrow, count, &vals[0], &cols[0]);
3764 bsuccess = bsuccess && bs1;
3766 #ifdef Xyce_DEBUG_DEVICE
3767 if (getDeviceOptions().debugLevel > 2 && getSolverState().debugTimeFlag)
3769 Xyce::dout() <<
"BC load: Vrow = " << Vrow << std::endl;
3770 for (
int eric=0;eric<count;++eric)
3772 Xyce::dout() <<
" cols["<<eric<<
"] = " << cols[eric];
3773 Xyce::dout() <<
" vals["<<eric<<
"] = " << vals[eric];
3774 Xyce::dout() << std::endl;
3783 if (dIVec[DIindex].neumannBCFlagN==
false)
3790 bs1 = matPtr->putRow (Nrow, 1, &vals[0], &cols[0]);
3791 bsuccess = bsuccess && bs1;
3793 #ifdef Xyce_DEBUG_DEVICE
3794 if (getDeviceOptions().debugLevel > 2 && getSolverState().debugTimeFlag)
3796 Xyce::dout() <<
"BC load: Nrow = " << Nrow << std::endl;
3797 for (
int eric=0;eric<count;++eric)
3799 Xyce::dout() <<
" cols["<<eric<<
"] = " << cols[eric];
3800 Xyce::dout() <<
" vals["<<eric<<
"] = " << vals[eric];
3801 Xyce::dout() << std::endl;
3809 if (dIVec[DIindex].neumannBCFlagP==
false)
3816 bs1 = matPtr->putRow (Prow, 1, &vals[0], &cols[0]);
3817 bsuccess = bsuccess && bs1;
3819 #ifdef Xyce_DEBUG_DEVICE
3820 if (getDeviceOptions().debugLevel > 2 && getSolverState().debugTimeFlag)
3822 Xyce::dout() <<
"BC load: Prow = " << Prow << std::endl;
3823 for (
int eric=0;eric<count;++eric)
3825 Xyce::dout() <<
" cols["<<eric<<
"] = " << cols[eric];
3826 Xyce::dout() <<
" vals["<<eric<<
"] = " << vals[eric];
3827 Xyce::dout() << std::endl;
3835 doneFlag = (doneFlagV && doneFlagN && doneFlagP);
3839 if (doneFlag)
continue;
3841 #endif // Xyce_NEW_BC
3844 std::string semi(bulkMaterial);
3846 mNode * nodePtr = meshContainerPtr->getNode(i);
3847 nodeArea = nodePtr->
area;
3852 for (j=0;j<numCol;++j) { cols[j] = -1; vals[j] = 0.0; }
3858 for (iNN=0;iNN<nodePtr->
cnode;++iNN)
3866 coef *= -scalingVars.L0 * matSupport.getRelPerm(semi)/nodeArea;
3868 if (Vcolarray[i][0] != -1)
3870 cols[count] = Vcolarray[i][0];
3874 #ifdef Xyce_DEBUG_DEVICE
3877 Xyce::dout() <<
" center point: i="<<i;
3878 Xyce::dout() <<
" Vcolarray[i][0] = " << Vcolarray[i][0] << std::endl;
3885 for (iNN=0;iNN<nodePtr->
cnode;++iNN)
3887 #ifdef Xyce_DEBUG_DEVICE
3888 if (getDeviceOptions().debugLevel > 2 && getSolverState().debugTimeFlag)
3890 Xyce::dout() <<
"non-center point: i="<<i;
3891 Xyce::dout() <<
" Vcolarray[i]["<<iNN+1<<
"] = ";
3892 Xyce::dout() << Vcolarray[i][iNN+1] << std::endl;
3895 int tmpCol = Vcolarray[i][iNN+1];
3897 if (tmpCol == -1)
continue;
3904 coef *= -scalingVars.L0 * matSupport.getRelPerm(semi)/nodeArea;
3906 coef *= ((boundarySten[inodeB]==1)?(scalingVars.rV0):1.0);
3909 if (boundarySten[inodeB]==1)
3912 for (cnt2=0;cnt2<count;++cnt2)
3914 if (cols[cnt2] == tmpCol)
3915 { bmatch =
true;
break; }
3917 if (!bmatch) { cnt2 = count; ++count;}
3927 #endif // Xyce_NEW_BC
3928 cols[cnt2] = tmpCol;
3933 if (Ncolarray[i][0] != -1)
3935 cols[count] = Ncolarray[i][0];
3941 if (Pcolarray[i][0] != -1)
3943 cols[count] = Pcolarray[i][0];
3948 #ifdef Xyce_DEBUG_DEVICE
3949 if (getDeviceOptions().debugLevel > 2 && getSolverState().debugTimeFlag)
3951 Xyce::dout() <<
"\n";
3952 Xyce::dout().setf(std::ios::left);
3953 Xyce::dout() <<
" POISSON LOAD: row = " << Vrow;
3954 Xyce::dout() <<
" count = " << count <<
"\n";
3955 Xyce::dout().setf(std::ios::scientific);
3956 for (j=0;j<count;++j)
3958 Xyce::dout() <<
" cols["<<j<<
"] = " << cols[j];
3959 Xyce::dout() <<
" vals["<<j<<
"] = " << vals[j];
3960 Xyce::dout() << std::endl;
3965 if (Vrow != -1 && count > 0)
3967 bs1 = matPtr->sumIntoRow (Vrow, count, &vals[0], &cols[0]);
3968 bsuccess = bsuccess && bs1;
3972 Xyce::dout() <<
"OOOPS 1!" << std::endl;
3982 for (j=0;j<numCol;++j) { cols[j] = -1; vals[j] = 0.0; }
3988 for (iNN=0;iNN<nodePtr->
cnode;++iNN)
3998 dJdn = dJndn1Vec[iedge];
4002 dJdn = dJndn2Vec[iedge];
4005 coef += ((i<inodeB)?1.0:-1.0) * dJdn * ilen;
4009 coef += - dRdnVec[i] - dDNDTdn;
4011 coef += pdElecPenalty[i];
4014 cols[count] = Ncolarray[i][0];
4019 for (iNN=0;iNN<nodePtr->
cnode;++iNN)
4021 if (Ncolarray[i][iNN+1] == -1)
continue;
4031 dJdn = dJndn1Vec[iedge];
4035 dJdn = dJndn2Vec[iedge];
4038 coef = ((i<inodeB)?1.0:-1.0) * dJdn * ilen/nodeArea;
4041 cols[count] = Ncolarray[i][iNN+1];
4048 for (iNN=0;iNN<nodePtr->
cnode;++iNN)
4058 dJdV = dJndV1Vec[iedge];
4062 dJdV = dJndV2Vec[iedge];
4065 coef += ((i<inodeB)?1.0:-1.0) * dJdV * ilen;
4069 if (Vcolarray[i][0] != -1)
4072 cols[count] = Vcolarray[i][0];
4078 for (iNN=0;iNN<nodePtr->
cnode;++iNN)
4080 int tmpCol = Vcolarray[i][iNN+1];
4081 if (tmpCol == -1)
continue;
4092 dJdV = dJndV1Vec[iedge];
4096 dJdV = dJndV2Vec[iedge];
4099 coef = ((i<inodeB)?1.0:-1.0) * dJdV * ilen/nodeArea;
4101 coef *= ((boundarySten[inodeB]==1)?(scalingVars.rV0):1.0);
4104 if (boundarySten[inodeB]==1)
4107 for (cnt2=0;cnt2<count;++cnt2)
4109 if (cols[cnt2] == tmpCol)
4110 { bmatch =
true;
break; }
4112 if (!bmatch) { cnt2 = count; ++count;}
4122 #endif // Xyce_NEW_BC
4124 cols[cnt2] = tmpCol;
4128 if (Pcolarray[i][0] != -1)
4130 vals[count] = -dRdpVec[i];
4131 cols[count] = Pcolarray[i][0];
4135 #ifdef Xyce_DEBUG_DEVICE
4136 if (getDeviceOptions().debugLevel > 2 && getSolverState().debugTimeFlag)
4138 Xyce::dout() <<
"\n";
4139 Xyce::dout().setf(std::ios::left);
4140 Xyce::dout() <<
"ELECTRON LOAD: row = " << Nrow;
4141 Xyce::dout() <<
" count = " << count<<
"\n";
4142 Xyce::dout().setf(std::ios::scientific);
4143 for (j=0;j<count;++j)
4145 Xyce::dout() <<
" cols["<<j<<
"] = " << cols[j];
4146 Xyce::dout() <<
" vals["<<j<<
"] = " << vals[j];
4147 Xyce::dout() << std::endl;
4152 if (Nrow != -1 && count > 0)
4154 bs1 = matPtr->sumIntoRow (Nrow,count,&vals[0],&cols[0]);
4155 bsuccess = bsuccess && bs1;
4159 Xyce::dout() <<
"OOOPS 2!" << std::endl;
4170 for (j=0;j<numCol;++j) { cols[j] = -1; vals[j] = 0.0; }
4176 for (iNN=0;iNN<nodePtr->
cnode;++iNN)
4186 dJdp = dJpdn1Vec[iedge];
4190 dJdp = dJpdn2Vec[iedge];
4193 coef += - ((i<inodeB)?1.0:-1.0) * dJdp * ilen;
4197 coef += - dRdpVec[i] - dDPDTdp;
4199 coef += pdHolePenalty[i];
4202 cols[count] = Pcolarray[i][0];
4207 for (iNN=0;iNN<nodePtr->
cnode;++iNN)
4209 if (Pcolarray[i][iNN+1] == -1)
continue;
4219 dJdp = dJpdn1Vec[iedge];
4223 dJdp = dJpdn2Vec[iedge];
4226 coef =-((i<inodeB)?1.0:-1.0) * dJdp * ilen/nodeArea;
4229 cols[count] = Pcolarray[i][iNN+1];
4235 for (iNN=0;iNN<nodePtr->
cnode;++iNN)
4245 dJdV = dJpdV1Vec[iedge];
4249 dJdV = dJpdV2Vec[iedge];
4252 coef += -((i<inodeB)?1.0:-1.0) * dJdV * ilen;
4256 if (Vcolarray[i][0] != -1)
4259 cols[count] = Vcolarray[i][0];
4265 for (iNN=0;iNN<nodePtr->
cnode;++iNN)
4267 int tmpCol = Vcolarray[i][iNN+1];
4268 if (tmpCol == -1)
continue;
4279 dJdV = dJpdV1Vec[iedge];
4283 dJdV = dJpdV2Vec[iedge];
4286 coef =-((i<inodeB)?1.0:-1.0) * dJdV * ilen/nodeArea;
4288 coef *= ((boundarySten[inodeB]==1)?(scalingVars.rV0):1.0);
4291 if (boundarySten[inodeB]==1)
4294 for (cnt2=0;cnt2<count;++cnt2)
4296 if (cols[cnt2] == tmpCol)
4297 { bmatch =
true;
break; }
4299 if (!bmatch) { cnt2 = count; ++count;}
4309 #endif // Xyce_NEW_BC
4311 cols[cnt2] = tmpCol;
4315 if (Ncolarray[i][0] != -1)
4317 vals[count] = -dRdnVec[i];
4318 cols[count] = Ncolarray[i][0];
4322 #ifdef Xyce_DEBUG_DEVICE
4323 if (getDeviceOptions().debugLevel > 2 && getSolverState().debugTimeFlag)
4325 Xyce::dout() <<
"\n";
4326 Xyce::dout().setf(std::ios::left);
4327 Xyce::dout() <<
" HOLE LOAD: row = " << Prow;
4328 Xyce::dout() <<
" count = " << count<<
"\n";
4329 Xyce::dout().setf(std::ios::scientific);
4330 for (j=0;j<count;++j)
4332 Xyce::dout() <<
" cols["<<j<<
"] = " << cols[j];
4333 Xyce::dout() <<
" vals["<<j<<
"] = " << vals[j];
4334 Xyce::dout() << std::endl;
4339 if (Prow != -1 && count > 0)
4341 bs1 = matPtr->sumIntoRow (Prow,count,&vals[0],&cols[0]);
4342 bsuccess = bsuccess && bs1;
4346 Xyce::dout() <<
"OOOPS 3!" << std::endl;
4354 #ifdef Xyce_DEBUG_DEVICE
4355 if (getDeviceOptions().debugLevel > 2 && getSolverState().debugTimeFlag)
4357 Xyce::dout() << subsection_divider <<
"\n";
4364 for (i=0;i<numMeshPoints;++i)
4368 Vrow = li_Vrowarray[i];
4369 Nrow = li_Nrowarray[i];
4370 Prow = li_Prowarray[i];
4372 std::vector<int> & Voff = li_VoffsetArray[i];
4373 std::vector<int> & Noff = li_NoffsetArray[i];
4374 std::vector<int> & Poff = li_PoffsetArray[i];
4376 bool doneFlagV =
false;
4377 bool doneFlagN =
false;
4378 bool doneFlagP =
false;
4379 bool doneFlag =
false;
4381 #ifdef Xyce_DEBUG_DEVICE
4382 if (getDeviceOptions().debugLevel > 2 && getSolverState().debugTimeFlag)
4384 Xyce::dout() <<
"mesh point i = " << i << std::endl;
4389 if (boundarySten[i])
continue;
4394 if (boundarySten[i])
4396 #ifdef Xyce_DEBUG_DEVICE
4397 if (getDeviceOptions().debugLevel > 2 && getSolverState().debugTimeFlag)
4399 Xyce::dout() <<
" Doing BC load" << std::endl;
4402 int DIindex = labelDIMap[labelNameVector[i]];
4404 if (dIVec[DIindex].given)
4406 if (dIVec[DIindex].neumannBCFlagV==
false)
4411 (*matPtr)[Vrow][Voff[0]] = 1.0;
4412 (*matPtr)[Vrow][Voff[1]] = -scalingVars.rV0;
4417 if (dIVec[DIindex].neumannBCFlagN==
false)
4421 (*matPtr)[Nrow][Noff[0]] = 1.0;
4426 if (dIVec[DIindex].neumannBCFlagP==
false)
4430 (*matPtr)[Prow][Poff[0]] = 1.0;
4435 doneFlag = (doneFlagV && doneFlagN && doneFlagP);
4439 if (doneFlag)
continue;
4441 #endif // Xyce_NEW_BC
4446 mNode * nodePtr = meshContainerPtr->getNode(i);
4447 nodeArea = nodePtr->
area;
4453 #ifdef Xyce_DEBUG_DEVICE
4454 if (getDeviceOptions().debugLevel > 2 && getSolverState().debugTimeFlag)
4456 Xyce::dout() <<
" Doing Poisson load" << std::endl;
4459 std::string semi(bulkMaterial);
4462 for (iNN=0;iNN<nodePtr->
cnode;++iNN)
4470 coef *= -scalingVars.L0 * matSupport.getRelPerm(semi)/nodeArea;
4472 (*matPtr)[Vrow][Voff[0]] += coef;
4475 coef = 0.0; iNN=0; ioffset=1;
4476 for (iNN=0;iNN<nodePtr->
cnode;++iNN)
4478 if (Vcolarray[i][iNN+1] == -1)
continue;
4485 coef *= -scalingVars.L0 * matSupport.getRelPerm(semi)/nodeArea;
4486 #ifdef Xyce_NEW_BC // again CHECK the offset value.
4487 coef *= ((boundarySten[inodeB]==1)?(scalingVars.rV0):1.0);
4488 #endif // Xyce_NEW_BC
4489 (*matPtr)[Vrow][Voff[ioffset]] += coef;
4494 (*matPtr)[Vrow][Voff[ioffset]] += 1.0;
4498 (*matPtr)[Vrow][Voff[ioffset]] += -1.0;
4505 #ifdef Xyce_DEBUG_DEVICE
4506 if (getDeviceOptions().debugLevel > 2 && getSolverState().debugTimeFlag)
4508 Xyce::dout() <<
" Doing electron load" << std::endl;
4514 coef = 0.0; ioffset=0;
4516 for (iNN=0;iNN<nodePtr->
cnode;++iNN)
4526 dJdn = dJndn1Vec[iedge];
4530 dJdn = dJndn2Vec[iedge];
4533 coef += ((i<inodeB)?1.0:-1.0) * dJdn * ilen;
4537 coef += - dRdnVec[i] - dDNDTdn;
4538 coef += pdElecPenalty[i];
4540 (*matPtr)[Nrow][Noff[0]] += coef;
4543 coef = 0.0; ioffset=1;
4544 for (iNN=0;iNN<nodePtr->
cnode;++iNN)
4546 if (Ncolarray[i][iNN+1] == -1)
continue;
4556 dJdn = dJndn1Vec[iedge];
4560 dJdn = dJndn2Vec[iedge];
4563 coef = ((i<inodeB)?1.0:-1.0) * dJdn * ilen/nodeArea;
4565 (*matPtr)[Nrow][Noff[ioffset]] += coef;
4571 for (iNN=0;iNN<nodePtr->
cnode;++iNN)
4581 dJdV = dJndV1Vec[iedge];
4585 dJdV = dJndV2Vec[iedge];
4588 coef += ((i<inodeB)?1.0:-1.0) * dJdV * ilen;
4592 (*matPtr)[Nrow][Noff[ioffset]] += coef;
4597 for (iNN=0;iNN<nodePtr->
cnode;++iNN)
4599 if (Vcolarray[i][iNN+1] == -1)
continue;
4610 dJdV = dJndV1Vec[iedge];
4614 dJdV = dJndV2Vec[iedge];
4617 coef = ((i<inodeB)?1.0:-1.0) * dJdV * ilen/nodeArea;
4619 coef *= ((boundarySten[inodeB]==1)?(scalingVars.rV0):1.0);
4620 #endif // Xyce_NEW_BC
4621 (*matPtr)[Nrow][Noff[ioffset]] += coef;
4626 (*matPtr)[Nrow][Noff[ioffset]] += -dRdpVec[i];
4634 #ifdef Xyce_DEBUG_DEVICE
4635 if (getDeviceOptions().debugLevel > 2 && getSolverState().debugTimeFlag)
4637 Xyce::dout() <<
" Doing hole load" << std::endl;
4642 coef = 0.0; ioffset=0;
4644 for (iNN=0;iNN<nodePtr->
cnode;++iNN)
4654 dJdp = dJpdn1Vec[iedge];
4658 dJdp = dJpdn2Vec[iedge];
4661 coef += - ((i<inodeB)?1.0:-1.0) * dJdp * ilen;
4665 coef += - dRdpVec[i] - dDPDTdp;
4666 coef += pdHolePenalty[i];
4668 (*matPtr)[Prow][Poff[0]] += coef;
4671 coef = 0.0; ioffset=1;
4672 for (iNN=0;iNN<nodePtr->
cnode;++iNN)
4674 if (Pcolarray[i][iNN+1] == -1)
continue;
4684 dJdp = dJpdn1Vec[iedge];
4688 dJdp = dJpdn2Vec[iedge];
4691 coef =-((i<inodeB)?1.0:-1.0) * dJdp * ilen/nodeArea;
4693 (*matPtr)[Prow][Poff[ioffset]] += coef;
4699 for (iNN=0;iNN<nodePtr->
cnode;++iNN)
4709 dJdV = dJpdV1Vec[iedge];
4713 dJdV = dJpdV2Vec[iedge];
4716 coef += -((i<inodeB)?1.0:-1.0) * dJdV * ilen;
4720 (*matPtr)[Prow][Poff[ioffset]] += coef;
4725 for (iNN=0;iNN<nodePtr->
cnode;++iNN)
4727 if (Vcolarray[i][iNN+1] == -1)
continue;
4738 dJdV = dJpdV1Vec[iedge];
4742 dJdV = dJpdV2Vec[iedge];
4745 coef =-((i<inodeB)?1.0:-1.0) * dJdV * ilen/nodeArea;
4746 #ifdef Xyce_NEW_BC // CHECK!
4747 coef *= ((boundarySten[inodeB]==1)?(scalingVars.rV0):1.0);
4748 #endif // Xyce_NEW_BC
4749 (*matPtr)[Prow][Poff[ioffset]] += coef;
4754 (*matPtr)[Prow][Poff[ioffset]] += -dRdnVec[i];
4763 #ifdef Xyce_DEBUG_DEVICE
4764 if (getDeviceOptions().debugLevel > 1 && getSolverState().debugTimeFlag)
4766 Xyce::dout() << section_divider <<
"\n";
4784 bool bsuccess =
true;
4787 #ifdef Xyce_DEBUG_DEVICE
4790 Xyce::dout() << section_divider <<
"\n";
4791 Xyce::dout() <<
"Instance::calcLifetimes" <<
"\n";
4801 #ifdef Xyce_DEBUG_DEVICE
4806 Xyce::dout() <<
" tnVec["<<i<<
"] = " <<
tnVec[i];
4807 Xyce::dout() <<
" tpVec["<<i<<
"] = " <<
tpVec[i];
4808 Xyce::dout() <<
"\n";
4814 Xyce::dout() << section_divider <<
"\n";
4837 bool bsuccess =
true;
4840 #ifdef Xyce_DEBUG_DEVICE
4843 Xyce::dout() << section_divider <<
"\n";
4844 Xyce::dout() <<
"Instance::calcMobilities" <<
"\n";
4856 ci.
N = fabs(
CVec[i]);
4859 if (ci.
N == 0.0) ci.
N = 1.0;
4875 #ifdef Xyce_DEBUG_DEVICE
4878 Xyce::dout() <<
"Nodal Mobilities:" << std::endl;
4881 Xyce::dout() <<
" unVec["<<i<<
"] = " <<
unVec[i];
4882 Xyce::dout() <<
" upVec["<<i<<
"] = " <<
upVec[i];
4883 Xyce::dout() <<
"\n";
4885 Xyce::dout() << std::endl;
4893 int inodeA = edgePtr->
inodeA;
4894 int inodeB = edgePtr->
inodeB;
4905 ci.
N = (fabs(
CVec[inodeA])+fabs(
CVec[inodeB]))*0.5;
4908 if (ci.
N == 0.0) ci.
N = 1.0;
4911 ci.
n = pow((fabs(
nnVec[inodeA])*fabs(
nnVec[inodeB])),0.5)*
4914 ci.
p = pow((fabs(
npVec[inodeA])*fabs(
npVec[inodeB])),0.5)*
4917 #ifdef Xyce_DEBUG_DEVICE
4918 if (ci.
n != 0.0 && !(ci.
n > 0.0) && !(ci.
n < 0.0))
4920 Xyce::dout() <<
"ci.n is nan" << std::endl;
4921 Xyce::dout() <<
"nnVec[A] = " <<
nnVec[inodeA];
4922 Xyce::dout() <<
"nnVec[B] = " <<
nnVec[inodeB];
4923 Xyce::dout() << std::endl;
4939 #ifdef Xyce_DEBUG_DEVICE
4942 Xyce::dout() <<
"Edge Mobilities" << std::endl;
4945 Xyce::dout() <<
" unE_Vec["<<i<<
"] = " <<
unE_Vec[i];
4946 Xyce::dout() <<
" upE_Vec["<<i<<
"] = " <<
upE_Vec[i];
4947 Xyce::dout() <<
"\n";
4953 Xyce::dout() << section_divider << std::endl;
4987 bool bsuccess =
true;
5025 bool bsuccess =
true;
5030 #ifdef Xyce_DEBUG_DEVICE
5033 Xyce::dout() << section_divider <<
"\n";
5034 Xyce::dout() <<
"Instance::calcVoltDepDensities\n";
5044 #ifdef Xyce_DEBUG_DEVICE
5047 Xyce::dout() << section_divider <<
"\n";
5065 bool bsuccess =
true;
5070 #ifdef Xyce_DEBUG_DEVICE
5073 Xyce::dout() << section_divider <<
"\n";
5074 Xyce::dout() <<
"Instance::calcDopingProfile\n";
5084 #ifdef Xyce_OXIDE_ENABLED
5085 if (allOxideFlag)
return bsuccess;
5100 double NaTmp = 1.0e+99;
5101 double NdTmp =-1.0e+99;
5105 if(NaTmp >
CVec[i]) NaTmp =
CVec[i];
5106 if(NdTmp <
CVec[i]) NdTmp =
CVec[i];
5125 XL = midpoint -
WJ/2.0;
5126 XR = midpoint +
WJ/2.0;
5135 XL = midpoint -
WJ/2.0;
5136 XR = midpoint +
WJ/2.0;
5139 #ifdef Xyce_DEBUG_DEVICE
5142 Xyce::dout() <<
"deviceWidth = " <<
deviceWidth << std::endl;
5143 Xyce::dout() <<
"midpoint = " << midpoint << std::endl;
5144 Xyce::dout() <<
"XL = " <<
XL << std::endl;
5145 Xyce::dout() <<
"XR = " <<
XR << std::endl;
5146 Xyce::dout() <<
"WJ = " <<
WJ << std::endl;
5152 double yloc =
yVec[i];
5198 double Re = 0.5 * We;
5199 double Rb = 0.5 * Wad;
5209 Ae = log(Ne/Nb)/(Re*Re);
5210 Ab = log(Nb/Nc)/(Rb*Rb);
5229 Ae = log(Ne/Nb)/(Re*Re);
5230 Ab = log(Nb/Nc)/(Rb*Rb);
5252 double NaTmp = 1.0e+99;
5253 double NdTmp =-1.0e+99;
5257 if(NaTmp >
CVec[i]) NaTmp =
CVec[i];
5258 if(NdTmp <
CVec[i]) NdTmp =
CVec[i];
5296 double WDIFF = (WDEV-WOX)/2;
5298 double DT = 1.0e-11;
5327 double NaTmp = 1.0e+99;
5328 double NdTmp =-1.0e+99;
5332 if(NaTmp >
CVec[i]) NaTmp =
CVec[i];
5333 if(NdTmp <
CVec[i]) NdTmp =
CVec[i];
5349 std::map<std::string, DopeInfo *>::iterator iter;
5350 std::map<std::string, DopeInfo *>::iterator start =
dopeInfoMap.begin();
5351 std::map<std::string, DopeInfo *>::iterator end =
dopeInfoMap.end();
5353 #ifdef Xyce_DEBUG_DEVICE
5356 Xyce::dout() <<
"dope info map:" << std::endl;
5359 for ( iter = start; iter != end; ++iter )
5363 #ifdef Xyce_DEBUG_DEVICE
5385 #ifdef Xyce_DEBUG_DEVICE
5388 Xyce::dout().width(20);
5389 Xyce::dout().precision(12);
5390 Xyce::dout().setf(std::ios::scientific);
5391 Xyce::dout() << std::endl;
5392 Xyce::dout() <<
"Na = " <<
Na << std::endl;
5393 Xyce::dout() <<
"Nd = " <<
Nd << std::endl<< std::endl;
5400 Xyce::dout() <<
xVec[inode];
5401 Xyce::dout() <<
" " <<
yVec[inode];
5402 Xyce::dout() <<
" CVec["<<inode<<
"] = " <<
CVec[inode] << std::endl;
5407 #ifdef Xyce_DEBUG_DEVICE
5410 Xyce::dout() << section_divider << std::endl;
5449 bool bsuccess =
true;
5490 #ifdef Xyce_DEBUG_DEVICE
5493 Xyce::dout() << std::endl;
5494 Xyce::dout() <<
" scalingVars.x0 = " <<
scalingVars.
x0 <<
"\n";
5495 Xyce::dout() <<
" scalingVars.a0 = " <<
scalingVars.
a0 <<
"\n";
5496 Xyce::dout() <<
" scalingVars.T0 = " <<
scalingVars.
T0 <<
"\n";
5497 Xyce::dout() <<
" scalingVars.V0 = " <<
scalingVars.
V0 <<
"\n";
5498 Xyce::dout() <<
" scalingVars.C0 = " <<
scalingVars.
C0 <<
"\n";
5499 Xyce::dout() <<
" scalingVars.D0 = " <<
scalingVars.
D0 <<
"\n";
5500 Xyce::dout() <<
" scalingVars.u0 = " <<
scalingVars.
u0 <<
"\n";
5501 Xyce::dout() <<
" scalingVars.R0 = " <<
scalingVars.
R0 <<
"\n";
5502 Xyce::dout() <<
" scalingVars.t0 = " <<
scalingVars.
t0 <<
"\n";
5503 Xyce::dout() <<
" scalingVars.E0 = " <<
scalingVars.
E0 <<
"\n";
5504 Xyce::dout() <<
" scalingVars.J0 = " <<
scalingVars.
J0 <<
"\n";
5505 Xyce::dout() <<
" scalingVars.L0 = " <<
scalingVars.
L0 << std::endl;
5506 Xyce::dout() << std::endl;
5527 bool bsuccess =
true;
5548 std::vector<DeviceInterfaceNode>::iterator firstDI =
dIVec.begin();
5549 std::vector<DeviceInterfaceNode>::iterator lastDI =
dIVec.end ();
5550 std::vector<DeviceInterfaceNode>::iterator iterDI = firstDI;
5552 for (;iterDI!=lastDI;++iterDI)
5554 for (i=0;i<iterDI->numBoundaryPoints;++i)
5565 int size = iterDI->areaVector.size();
5566 for (i = 0; i < size; ++i)
5587 #endif // Xyce_NEW_BC
5592 (solVectorPtr)->setElementByGlobalIndex(
Vrowarray[i],
VVec[i], 0);
5594 (solVectorPtr)->setElementByGlobalIndex(
Nrowarray[i],
nnVec[i], 0);
5596 (solVectorPtr)->setElementByGlobalIndex(
Prowarray[i],
npVec[i], 0);
5633 bool bsuccess =
true;
5654 std::vector<DeviceInterfaceNode>::iterator firstDI =
dIVec.begin();
5655 std::vector<DeviceInterfaceNode>::iterator lastDI =
dIVec.end ();
5656 std::vector<DeviceInterfaceNode>::iterator iterDI = firstDI;
5658 for (;iterDI!=lastDI;++iterDI)
5660 for (i=0;i<iterDI->numBoundaryPoints;++i)
5671 int size = iterDI->areaVector.size();
5672 for (i = 0; i < size; ++i)
5693 #endif // Xyce_NEW_BC
5698 (solVectorPtr)->setElementByGlobalIndex(
Vrowarray[i],
VVec[i], 0);
5700 (solVectorPtr)->setElementByGlobalIndex(
Nrowarray[i],
nnVec[i], 0);
5702 (solVectorPtr)->setElementByGlobalIndex(
Prowarray[i],
npVec[i], 0);
5741 bool bsuccess =
true;
5751 std::vector<DeviceInterfaceNode>::iterator firstDI =
dIVec.begin();
5752 std::vector<DeviceInterfaceNode>::iterator lastDI =
dIVec.end ();
5753 std::vector<DeviceInterfaceNode>::iterator iterDI = firstDI;
5755 for (;iterDI!=lastDI;++iterDI)
5757 for (i=0;i<iterDI->numBoundaryPoints;++i)
5806 bool bsuccess =
true;
5840 bool bsuccess =
true;
5845 N_LAS_Vector * solVectorPtr;
5846 N_LAS_Vector * currSolVectorPtr;
5847 N_LAS_Vector * lastSolVectorPtr;
5857 #ifdef Xyce_DEBUG_DEVICE
5860 Xyce::dout() << section_divider << std::endl;
5861 Xyce::dout() <<
"Instance::calcInitialGuess"<< std::endl;
5862 Xyce::dout() <<
" name = " <<
getName() << std::endl;
5872 double Cisq(0.0), Nisq(0.0);
5881 tmp = (fabs(Ci)+sqrt(Cisq+4*Nisq))/2.0;
5882 nnVec[i] = ((Ci>=0)?(tmp):(0.0)) + ((Ci<0)?(Nisq/tmp):(0.0));
5885 tmp = (fabs(Ci)+sqrt(Cisq+4*Nisq))/2.0;
5886 npVec[i] = ((Ci<=0)?(tmp):(0.0)) + ((Ci>0)?(Nisq/tmp):(0.0));
5888 #ifdef Xyce_DEBUG_DEVICE
5891 Xyce::dout() <<
"nnVec[" << i <<
"] = " <<
nnVec[i];
5892 Xyce::dout() <<
" npVec[" << i <<
"] = " <<
npVec[i];
5893 Xyce::dout() << std::endl;
5911 #ifdef Xyce_DEBUG_DEVICE
5914 Xyce::dout() <<
"VVec[" << i <<
"] = " <<
VVec[i] << std::endl;
5921 double VminTmp = +1.0e+99;
5922 double VmaxTmp = -1.0e+99;
5924 double VminBC = +1.0e+99;
5925 double VmaxBC = -1.0e+99;
5927 std::vector<DeviceInterfaceNode>::iterator firstDI =
dIVec.begin();
5928 std::vector<DeviceInterfaceNode>::iterator lastDI =
dIVec.end ();
5929 std::vector<DeviceInterfaceNode>::iterator iterDI;
5931 for (iterDI=firstDI;iterDI!=lastDI;++iterDI)
5934 std::vector<int>::iterator iterNode = labelPtr->
mNodeVector.begin();
5935 std::vector<int>::iterator lastNode = labelPtr->
mNodeVector.end ();
5937 for ( ;iterNode!=lastNode;++iterNode)
5939 if (VminTmp >
VVec[*iterNode]) VminTmp =
VVec[*iterNode];
5940 if (VmaxTmp <
VVec[*iterNode]) VmaxTmp =
VVec[*iterNode];
5942 int ilocal = iterDI->meshGlobalToLocal[*iterNode];
5943 if (VminBC > iterDI->VequVec[ilocal]) VminBC = iterDI->VequVec[ilocal];
5944 if (VmaxBC < iterDI->VequVec[ilocal]) VmaxBC = iterDI->VequVec[ilocal];
5948 double Voffset = -VminTmp;
5949 double VtotDiff = VmaxTmp-VminTmp;
5950 double VBCDiff = VmaxBC-VminBC;
5951 double Vscale = (VtotDiff!=0.0)?(VBCDiff/VtotDiff):1.0;
5953 #ifdef Xyce_DEBUG_DEVICE
5956 Xyce::dout() <<
"Voffset = " << Voffset << std::endl;
5957 Xyce::dout() <<
"VtotDiff = " << VtotDiff << std::endl;
5958 Xyce::dout() <<
"VBCDiff = " << VBCDiff << std::endl;
5959 Xyce::dout() <<
"Vscale = " << Vscale << std::endl;
5977 #ifdef Xyce_DEBUG_DEVICE
5980 Xyce::dout() <<
"VVec[" << i <<
"] = " <<
VVec[i] << std::endl;
5986 #endif // Xyce_NEW_BC
5993 (solVectorPtr)->setElementByGlobalIndex(
Vrowarray[i],
VVec[i], 0);
5995 (solVectorPtr)->setElementByGlobalIndex(
Nrowarray[i],
nnVec[i], 0);
5997 (solVectorPtr)->setElementByGlobalIndex(
Prowarray[i],
npVec[i], 0);
6001 (currSolVectorPtr)->setElementByGlobalIndex(
Vrowarray[i],
VVec[i], 0);
6003 (currSolVectorPtr)->setElementByGlobalIndex(
Nrowarray[i],
nnVec[i], 0);
6005 (currSolVectorPtr)->setElementByGlobalIndex(
Prowarray[i],
npVec[i], 0);
6008 (lastSolVectorPtr)->setElementByGlobalIndex(
Vrowarray[i],
VVec[i], 0);
6010 (lastSolVectorPtr)->setElementByGlobalIndex(
Nrowarray[i],
nnVec[i], 0);
6012 (lastSolVectorPtr)->setElementByGlobalIndex(
Prowarray[i],
npVec[i], 0);
6022 (*currSolVectorPtr)[li_Vrowarray[i]] =
VVec[i];
6023 (*currSolVectorPtr)[li_Nrowarray[i]] =
nnVec[i];
6024 (*currSolVectorPtr)[li_Prowarray[i]] =
npVec[i];
6026 (*lastSolVectorPtr)[li_Vrowarray[i]] =
VVec[i];
6027 (*lastSolVectorPtr)[li_Nrowarray[i]] =
nnVec[i];
6028 (*lastSolVectorPtr)[li_Prowarray[i]] =
npVec[i];
6044 #ifdef Xyce_DEBUG_DEVICE
6047 Xyce::dout() << std::endl;
6048 Xyce::dout().setf(std::ios::scientific);
6049 Xyce::dout() <<
"Vmax = " <<
VmaxExp << std::endl;
6050 Xyce::dout() <<
"Vmin = " <<
VminExp << std::endl;
6051 Xyce::dout() << std::endl;
6055 #ifdef Xyce_DEBUG_DEVICE
6058 Xyce::dout() << section_divider << std::endl;
6078 bool bsuccess =
true;
6081 #ifdef Xyce_DEBUG_DEVICE
6084 Xyce::dout() << section_divider << std::endl;
6085 Xyce::dout() <<
"Instance::calcVequBCs"<< std::endl;
6086 Xyce::dout() <<
" name = " <<
getName() << std::endl;
6087 Xyce::dout() <<
" Na = "<<
Na << std::endl;
6088 Xyce::dout() <<
" Nd = "<<
Nd << std::endl;
6092 double VminBC =+1.0e+99;
6093 double VmaxBC =-1.0e+99;
6095 std::vector<DeviceInterfaceNode>::iterator firstDI =
dIVec.begin();
6096 std::vector<DeviceInterfaceNode>::iterator lastDI =
dIVec.end ();
6097 std::vector<DeviceInterfaceNode>::iterator iterDI;
6099 for (iterDI=firstDI;iterDI!=lastDI;++iterDI)
6101 #ifdef Xyce_DEBUG_DEVICE
6104 Xyce::dout() <<
"DI name = " << iterDI->eName << std::endl;
6105 Xyce::dout() <<
"material = " << iterDI->material << std::endl;
6106 if (iterDI->materialGiven)
6108 Xyce::dout() <<
"material was given" << std::endl;
6112 Xyce::dout() <<
"material was NOT given" << std::endl;
6115 if (iterDI->oxideBndryFlag)
6117 Xyce::dout() <<
"This is a boundary WITH an oxide." << std::endl;
6121 Xyce::dout() <<
"This is a boundary WITHOUT an oxide." << std::endl;
6124 Xyce::dout().setf(std::ios::scientific);
6128 std::string insul =
"sio2";
6131 std::vector<int>::iterator iterNode = labelPtr->
mNodeVector.begin();
6132 std::vector<int>::iterator lastNode = labelPtr->
mNodeVector.end ();
6134 for (i=0;i<iterDI->numBoundaryPoints;++i,++iterNode)
6136 double Ci =
CVec[*iterNode];
6137 double ns =
nnVec[*iterNode];
6138 double Cisq = Ci*Ci;
6139 double Nisq =
Ni*
Ni;
6140 double tmp, nnTmp, npTmp;
6143 tmp = (fabs(Ci)+sqrt(Cisq+4*Nisq))/2.0;
6144 nnTmp = ((Ci>=0)?(tmp):(0.0)) + ((Ci<0)?(Nisq/tmp):(0.0));
6147 tmp = (fabs(Ci)+sqrt(Cisq+4*Nisq))/2.0;
6148 npTmp = ((Ci<=0)?(tmp):(0.0)) + ((Ci>0)?(Nisq/tmp):(0.0));
6150 ExtendedString mater = iterDI->material;
6153 if (mater==
"neutral")
6158 iterDI->VequVec[i] = +
Vt * log(nnTmp/Ni);
6163 iterDI->VequVec[i] = -
Vt * log(npTmp/Ni);
6174 + 2.0 *
Vt * log(nnTmp/Ni);
6181 - 2.0 *
Vt * log(npTmp/Ni);
6189 if (iterDI->oxideBndryFlag)
6191 iterDI->VequVec[i] += - iterDI->oxcharge *
charge *iterDI->oxthick/
6195 iterDI->VbcVec [i] = 0.0;
6197 if (VminBC > iterDI->VequVec[i]) VminBC = iterDI->VequVec[i];
6198 if (VmaxBC < iterDI->VequVec[i]) VmaxBC = iterDI->VequVec[i];
6200 #ifdef Xyce_DEBUG_DEVICE
6203 Xyce::dout() <<
"Vequ["<<i<<
"]=" << iterDI->VequVec[i];
6204 Xyce::dout() << std::endl;
6210 #ifdef Xyce_DEBUG_DEVICE
6213 Xyce::dout() <<
"After offset:" << std::endl;
6218 double Voffset = -VminBC;
6220 for (iterDI=firstDI;iterDI!=lastDI;++iterDI)
6222 #ifdef Xyce_DEBUG_DEVICE
6225 Xyce::dout() <<
"DI name = " << iterDI->eName << std::endl;
6226 Xyce::dout().setf(std::ios::scientific);
6230 for (i=0;i<iterDI->numBoundaryPoints;++i)
6232 iterDI->VequVec[i] += Voffset;
6233 #ifdef Xyce_DEBUG_DEVICE
6236 Xyce::dout() <<
"VequVec["<<i<<
"] = " << iterDI->VequVec[i] << std::endl;
6242 #ifdef Xyce_DEBUG_DEVICE
6245 Xyce::dout() << section_divider << std::endl;
6267 bool bsuccess =
true;
6268 std::vector<DeviceInterfaceNode>::iterator firstDI =
dIVec.begin();
6269 std::vector<DeviceInterfaceNode>::iterator lastDI =
dIVec.end ();
6270 std::vector<DeviceInterfaceNode>::iterator iterDI;
6272 #ifdef Xyce_DEBUG_DEVICE
6275 Xyce::dout() << section_divider<< std::endl;
6276 Xyce::dout() << std::endl <<
"In Instance::calcDensityBCs" << std::endl;
6286 for (iterDI=firstDI;iterDI!=lastDI;++iterDI)
6288 #ifdef Xyce_DEBUG_DEVICE
6291 Xyce::dout() << iterDI->eName<<
":" << std::endl;
6297 for (
int i=0;i<iterDI->numBoundaryPoints;++i)
6306 iterDI->nnbcVec[i] =
6309 iterDI->npbcVec[i] =
6310 0.5*(sqrt(
CVec[nIndex]*
CVec[nIndex]+4*Ni*Ni)-
CVec[nIndex]);
6312 if (NnMax < iterDI->nnbcVec[i])
NnMax = iterDI->nnbcVec[i];
6313 if (NpMax < iterDI->npbcVec[i])
NpMax = iterDI->npbcVec[i];
6315 if (
NnMin > iterDI->nnbcVec[i])
NnMin = iterDI->nnbcVec[i];
6316 if (
NpMin > iterDI->npbcVec[i])
NpMin = iterDI->npbcVec[i];
6318 #ifdef Xyce_DEBUG_DEVICE
6321 Xyce::dout() <<
"\tCVec["<<nIndex<<
"] = " <<
CVec[nIndex]<< std::endl;
6322 Xyce::dout() <<
"\tnnbc["<<i<<
"] = " << iterDI->nnbcVec[i] << std::endl;
6323 Xyce::dout() <<
"\tnpbc["<<i<<
"] = " << iterDI->npbcVec[i] << std::endl;
6331 std::vector<int>::iterator iterNode = labelPtr->
mNodeVector.begin();
6332 std::vector<int>::iterator lastNode = labelPtr->
mNodeVector.end ();
6334 for ( ;iterNode!=lastNode;++iterNode)
6336 int i1 = iterDI->meshGlobalToLocal[*iterNode];
6345 #ifdef Xyce_DEBUG_DEVICE
6348 Xyce::dout() << std::endl;
6349 Xyce::dout() <<
"NnMax = " <<
NnMax << std::endl;
6350 Xyce::dout() <<
"NpMax = " <<
NpMax << std::endl;
6351 Xyce::dout() <<
"NnMin = " <<
NnMin << std::endl;
6352 Xyce::dout() <<
"NpMin = " <<
NpMin << std::endl;
6353 Xyce::dout() << section_divider<< std::endl;
6377 bool bsuccess =
true;
6379 std::vector<DeviceInterfaceNode>::iterator firstDI =
dIVec.begin();
6380 std::vector<DeviceInterfaceNode>::iterator lastDI =
dIVec.end ();
6381 std::vector<DeviceInterfaceNode>::iterator iterDI;
6383 #ifdef Xyce_DEBUG_DEVICE
6386 Xyce::dout() << std::endl << section_divider << std::endl;
6387 Xyce::dout() << std::endl <<
"In Instance::calcBoundaryConditions" << std::endl;
6391 for (iterDI=firstDI;iterDI!=lastDI;++iterDI)
6395 for (i=0;i<iterDI->numBoundaryPoints;++i)
6397 iterDI->VbcVec[i] = iterDI->Vckt_ramp + iterDI->VequVec[i];
6402 for (i=0;i<iterDI->numBoundaryPoints;++i)
6404 iterDI->VbcVec[i] = iterDI->Vckt + iterDI->VequVec[i];
6412 std::vector<int>::iterator iterNode = labelPtr->
mNodeVector.begin();
6413 std::vector<int>::iterator lastNode = labelPtr->
mNodeVector.end ();
6415 for ( ;iterNode!=lastNode;++iterNode)
6417 int i1 = iterDI->meshGlobalToLocal[*iterNode];
6418 VVec[*iterNode] = iterDI->VbcVec [i1];
6419 nnVec[*iterNode] = iterDI->nnbcVec[i1];
6420 npVec[*iterNode] = iterDI->npbcVec[i1];
6422 #endif // Xyce_NEW_BC
6424 #ifdef Xyce_DEBUG_DEVICE
6427 Xyce::dout() << iterDI->eName <<
":" << std::endl;
6428 for (i=0;i<iterDI->numBoundaryPoints;++i)
6430 Xyce::dout()<<
"Vbc["<<i<<
"] = "<<iterDI->VbcVec[i]<<
", "<<iterDI->VbcVec[i]*
scalingVars.
V0;
6431 Xyce::dout() <<
" nnbc["<<i<<
"] = "<< iterDI->nnbcVec[i];
6433 Xyce::dout() <<
" npbc["<<i<<
"] = "<< iterDI->npbcVec[i];
6435 Xyce::dout() << std::endl;
6441 #ifdef Xyce_DEBUG_DEVICE
6444 Xyce::dout() << section_divider << std::endl;
6471 bool bsuccess =
true;
6473 #ifdef Xyce_DEBUG_DEVICE
6476 Xyce::dout() << std::endl << section_divider << std::endl;
6477 Xyce::dout() << std::endl <<
"In Instance::obtainNodeVoltages" << std::endl;
6483 std::vector<DeviceInterfaceNode>::iterator firstDI =
dIVec.begin();
6484 std::vector<DeviceInterfaceNode>::iterator lastDI =
dIVec.end ();
6485 std::vector<DeviceInterfaceNode>::iterator iterDI;
6487 for (iterDI=firstDI;iterDI!=lastDI;++iterDI)
6492 if (iterDI->gid != -1)
6493 iterDI->Vckt = (solVectorPtr)->getElementByGlobalIndex(iterDI->gid, 0);
6499 iterDI->Vckt = (*solVectorPtr)[iterDI->lid];
6504 #ifdef Xyce_DEBUG_DEVICE
6507 Xyce::dout() << iterDI->eName <<
" Vckt = " << iterDI->Vckt;
6508 Xyce::dout() <<
" Vckt*scalingVars.V0 = " << (iterDI->Vckt *
scalingVars.
V0) << std::endl;
6513 #ifdef Xyce_DEBUG_DEVICE
6516 Xyce::dout() << section_divider << std::endl;
6538 bool bsuccess =
true;
6540 std::vector<DeviceInterfaceNode>::iterator firstDI =
dIVec.begin();
6541 std::vector<DeviceInterfaceNode>::iterator lastDI =
dIVec.end ();
6542 std::vector<DeviceInterfaceNode>::iterator iterDI;
6544 #ifdef Xyce_DEBUG_DEVICE
6547 Xyce::dout() << std::endl << section_divider << std::endl;
6548 Xyce::dout() <<
"device: " <<
getName() << std::endl;
6552 for (iterDI=firstDI;iterDI!=lastDI;++iterDI)
6556 #ifdef Xyce_DEBUG_DEVICE
6557 double v1_orig = v1;
6560 double delV1 = v1 - v1_old;
6562 if ( delV1 > 1.25 ) v1 = v1_old + 1.25;
6563 if ( delV1 < -0.75 ) v1 = v1_old - 0.75;
6565 #ifdef Xyce_DEBUG_DEVICE
6568 Xyce::dout() <<
"electrode = " << iterDI->eName << std::endl;
6569 Xyce::dout() <<
"v1 = " << v1 << std::endl;
6570 Xyce::dout() <<
"v1_old = " << v1_old << std::endl;
6571 Xyce::dout() <<
"v1_orig = " << v1_orig << std::endl;
6572 Xyce::dout() <<
"v1/scalingVars.V0 = " << v1/
scalingVars.
V0 << std::endl;
6573 Xyce::dout() <<
"v1_old/scalingVars.V0 = " << v1_old/
scalingVars.
V0 << std::endl;
6574 Xyce::dout() <<
"v1_orig/scalingVars.V0 = " << v1_orig/
scalingVars.
V0 << std::endl;
6575 Xyce::dout() << std::endl;
6583 #ifdef Xyce_DEBUG_DEVICE
6586 Xyce::dout() << section_divider << std::endl;
6604 bool bsuccess =
true;
6609 #ifdef Xyce_DEBUG_DEVICE
6612 Xyce::dout() << section_divider <<
"\n";
6613 Xyce::dout() <<
"Instance::obtainSolution\n";
6614 Xyce::dout() <<
"solVectorPtr = " << solVectorPtr << std::endl;
6619 bsuccess = bsuccess && bs1;
6628 #endif // Xyce_NEW_BC
6636 VVec[i] = (solVectorPtr)->getElementByGlobalIndex(
Vrowarray[i], 0);
6645 #ifdef Xyce_DEBUG_DEVICE
6650 Xyce::dout() <<
"VVec["<<i<<
"]=\t";
6651 Xyce::dout().width(20);
6652 Xyce::dout().precision(12);
6653 Xyce::dout().setf(std::ios::scientific);
6654 Xyce::dout() <<
VVec[i];
6656 Xyce::dout() <<
"\n";
6668 #ifdef Xyce_DEBUG_DEVICE
6671 Xyce::dout() <<
" About to get the density.\n";
6672 if (
getSolverState().dcopFlag) Xyce::dout() <<
"DCOP load" << std::endl;
6673 else Xyce::dout() <<
"Transient load" << std::endl;
6686 #endif // Xyce_NEW_BC
6707 #ifdef Xyce_DEBUG_DEVICE
6710 Xyce::dout()<<
" Obtaining densities from solution vector (not voltage dep.)\n";
6718 #endif // Xyce_NEW_BC
6725 nnVec[i] = (solVectorPtr)->getElementByGlobalIndex(
Nrowarray[i], 0);
6732 #ifdef Xyce_PDE_DENSITY_CONSTRAINT
6741 (solVectorPtr)->setElementByGlobalIndex(
Nrowarray[i], 0.0, 0);
6755 npVec[i] = (solVectorPtr)->getElementByGlobalIndex(
Prowarray[i], 0);
6763 #ifdef Xyce_PDE_DENSITY_CONSTRAINT
6771 (solVectorPtr)->setElementByGlobalIndex(
Prowarray[i], 0.0, 0);
6782 #ifdef Xyce_DEBUG_DEVICE
6787 Xyce::dout() <<
"nnVec["<<i<<
"]=\t";
6788 Xyce::dout().width(14);
6789 Xyce::dout().precision(6);
6790 Xyce::dout().setf(std::ios::scientific);
6791 Xyce::dout() <<
nnVec[i];
6794 Xyce::dout() <<
" npVec["<<i<<
"]=\t";
6795 Xyce::dout().width(14);
6796 Xyce::dout().precision(6);
6797 Xyce::dout().setf(std::ios::scientific);
6798 Xyce::dout() <<
npVec[i];
6801 Xyce::dout() << std::endl;
6817 bsuccess = bsuccess && bs1;
6824 bsuccess = bsuccess && bs1;
6828 #ifdef Xyce_DEBUG_DEVICE
6831 Xyce::dout() << section_divider << std::endl;
6848 bool bsuccess =
true;
6853 #ifdef Xyce_DEBUG_DEVICE
6856 Xyce::dout() << section_divider <<
"\n";
6857 Xyce::dout() <<
"Instance::calcRecombination\n";
6858 Xyce::dout() <<
"\n";
6864 double n =
nnVec[i];
6865 double p =
npVec[i];
6866 double tn =
tnVec[i];
6867 double tp =
tpVec[i];
6873 RVec[i] = (Rsrh + Raug);
6875 #ifdef Xyce_DEBUG_DEVICE
6878 Xyce::dout().precision(4);
6879 Xyce::dout() <<
" nnVec="<<n<<
" npVec="<<p;
6880 Xyce::dout() <<
" tnVec="<<tn<<
" tpVec="<<tp;
6881 Xyce::dout() <<
" Rsrh="<<Rsrh;
6882 Xyce::dout() <<
" Raug="<<Raug;
6883 Xyce::dout() <<
" RVec["<<i<<
"]="<<
RVec[i];
6884 Xyce::dout() <<
"\n";
6889 Xyce::dout().precision(4);
6890 Xyce::dout() <<
" RVec["<<i<<
"]="<<
RVec[i];
6891 Xyce::dout() << std::endl;
6896 #ifdef Xyce_DEBUG_DEVICE
6899 Xyce::dout() << section_divider << std::endl;
6921 bool bsuccess =
true;
6923 Util::Expression expr;
6929 ndParam.setTag(
"PULSEDATA");
6930 expr.set(
"spice_pulse(V1, V2, TD, TR, TF, PW, PER)");
6931 expr.make_constant(
"V1", 0.0);
6932 expr.make_constant(
"V2",
photoA1);
6933 expr.make_constant(
"TD",
photoTd);
6934 expr.make_constant(
"TR",
photoTr);
6935 expr.make_constant(
"TF",
photoTf);
6936 expr.make_constant(
"PW",
photoPw);
6937 expr.make_constant(
"PER",
photoPer);
6938 ndParam.setVal(expr);
6943 ndParam.setTag(
"PULSEDATA");
6945 expr.make_constant(
"CONST",
photoA1);
6946 ndParam.setVal(expr);
6985 bool bsuccess =
true;
6991 #ifdef Xyce_DEBUG_DEVICE
6995 Xyce::dout() << section_divider <<
"\n";
6996 Xyce::dout() <<
"Instance::calcPhotogen\n";
6997 Xyce::dout() <<
"time = " << time;
7002 { Xyce::dout() <<
" photogen is on right now." << std::endl; }
7004 { Xyce::dout() <<
" photogen is off right now." << std::endl; }
7006 Xyce::dout() <<
"\n";
7035 #ifdef Xyce_DEBUG_DEVICE
7038 Xyce::dout() <<
"Value of photogen source = " << val << std::endl;
7039 Xyce::dout() << section_divider << std::endl;
7072 bool bsuccess =
true;
7075 #ifdef Xyce_DEBUG_DEVICE
7076 bool nonZeroFlag =
false;
7107 double epen = prefac*pow(elec,power);
7111 double hpen = prefac*pow(hole,power);
7114 #ifdef Xyce_DEBUG_DEVICE
7121 #ifdef Xyce_DEBUG_DEVICE
7126 Xyce::dout() <<
" e- Pen["<<i<<
"] = " <<
elecPenalty[i];
7127 Xyce::dout() <<
" e- den["<<i<<
"] = " <<
nnVec[i];
7129 Xyce::dout() <<
" h+ Pen["<<i<<
"] = " <<
holePenalty[i];
7130 Xyce::dout() <<
" h+ den["<<i<<
"] = " <<
npVec[i];
7131 Xyce::dout() << std::endl;
7173 bool bsuccess =
true;
7198 double power2 = power - 1.0;
7202 double elec =
nnVec[i];
7203 double hole =
npVec[i];
7207 double epen = power*prefac*Cpow*pow(elec,power2);
7211 double hpen = power*prefac*Cpow*pow(hole,power2);
7233 bool bsuccess =
true;
7236 #ifdef Xyce_DEBUG_DEVICE
7240 Xyce::dout() << section_divider <<
"\n";
7241 Xyce::dout() <<
"Instance::sumSources\n";
7242 Xyce::dout() <<
"\n";
7251 #ifdef Xyce_DEBUG_DEVICE
7254 Xyce::dout() <<
"RVec["<<i<<
"] = " <<
RVec[i];
7255 Xyce::dout() <<
" SVec["<<i<<
"] = " << SVec[i];
7256 Xyce::dout() <<
" totSrcVec["<<i<<
"] = " <<
totSrcVec[i] <<
"\n";
7261 #ifdef Xyce_DEBUG_DEVICE
7264 Xyce::dout() << section_divider << std::endl;
7282 bool bsuccess =
true;
7299 #ifdef Xyce_DEBUG_DEVICE
7302 Xyce::dout() << section_divider <<
"\n";
7303 Xyce::dout() <<
"Instance::pdRecombination\n";
7304 Xyce::dout() <<
"\n";
7321 if (A1 >= exp(arg)) A1 = exp(arg);
7327 if (C1 >= exp(arg)) C1 = exp(arg);
7330 dBdn = -1.0/(C1*C1) *
tpVec[i];
7331 dBdp = -1.0/(C1*C1) *
tnVec[i];
7333 dRsrhdn = dAdn * B1 + dBdn * A1;
7334 dRsrhdp = dAdp * B1 + dBdp * A1;
7336 #ifdef Xyce_DEBUG_DEVICE
7339 Xyce::dout() <<
" dRsrhdn = " << dRsrhdn <<
" dRsrhdp = " << dRsrhdp;
7340 Xyce::dout() <<
"\n";
7341 Xyce::dout() <<
" nnVec = " <<
nnVec[i] <<
" npVec = " <<
npVec[i] <<
"\n";
7342 Xyce::dout() <<
" tnVec = " <<
tnVec[i] <<
" tpVec = " <<
tpVec[i] <<
"\n";
7343 Xyce::dout() <<
" A1 = " << A1 <<
" B1 = " << B1 <<
" C1 = " << C1 <<
"\n";
7344 Xyce::dout() <<
" dAdn = " << dAdn <<
" dBdn = " << dBdn <<
"\n";
7345 Xyce::dout() <<
" dAdp = " << dAdp <<
" dBdp = " << dBdp <<
"\n";
7352 if (B1 >= exp(arg)) B1 = exp(arg);
7357 dRaugdn = dAdn*B1 + A1*dBdn;
7358 dRaugdp = dAdp*B1 + A1*dBdp;
7360 #ifdef Xyce_DEBUG_DEVICE
7363 Xyce::dout() <<
" dRaugdn = " << dRaugdn <<
" dRaugdp = " << dRaugdp <<
"\n";
7364 Xyce::dout() <<
" A1 = " << A1 <<
" B1 = " << B1 <<
"\n";
7365 Xyce::dout() <<
" dAdn = " << dAdn <<
" dBdn = " << dBdn <<
"\n";
7366 Xyce::dout() <<
" dAdp = " << dAdp <<
" dBdp = " << dBdp <<
"\n";
7370 dRdnVec[i] = dRsrhdn + dRaugdn;
7371 dRdpVec[i] = dRsrhdp + dRaugdp;
7375 double n =
nnVec[i];
7376 double p =
npVec[i];
7377 double tn =
tnVec[i];
7378 double tp =
tpVec[i];
7388 dRdnVec[i] = (dRsrhdn + dRaugdn);
7389 dRdpVec[i] = (dRsrhdp + dRaugdp);
7391 #ifdef Xyce_DEBUG_DEVICE
7394 Xyce::dout() <<
" dRdnVec["<<i<<
"] = " <<
dRdnVec[i];
7395 Xyce::dout() <<
" dRdpVec["<<i<<
"] = " <<
dRdpVec[i];
7396 Xyce::dout() <<
"\n";
7401 #ifdef Xyce_DEBUG_DEVICE
7404 Xyce::dout() << section_divider << std::endl;
7421 bool bsuccess =
true;
7428 #ifdef Xyce_DEBUG_DEVICE
7432 Xyce::dout() << section_divider <<
"\n";
7433 Xyce::dout() <<
"Instance::calcElectronCurrent\n";
7434 Xyce::dout() <<
"\n";
7442 #ifdef Xyce_DEBUG_DEVICE
7445 Xyce::dout() <<
"\n";
7446 Xyce::dout() <<
"i="<<i<<
"\n";
7452 int inodeA = edgePtr->
inodeA;
7453 int inodeB = edgePtr->
inodeB;
7454 double elen = edgePtr->
elen;
7459 if (jnMax < fabs(
JnVec[i]) )
7461 #ifdef Xyce_DEBUG_DEVICE
7464 jnMax = fabs(
JnVec[i]);
7467 #ifdef Xyce_DEBUG_DEVICE
7476 #ifdef Xyce_DEBUG_DEVICE
7479 double jScale = 1.0;
7480 double xScale = 1.0;
7483 Xyce::dout().setf(std::ios::scientific);
7484 Xyce::dout() <<
" Max Electron current = " << jnMax;
7485 Xyce::dout() <<
" jScale = " << jScale;
7486 Xyce::dout() <<
"\n";
7489 int inodeA = edgePtr->
inodeA;
7490 int inodeB = edgePtr->
inodeB;
7492 Xyce::dout() <<
" max locations A: (x,y) = (" <<
xVec[inodeA]*xScale<<
", ";
7493 Xyce::dout() <<
yVec[inodeA]*xScale<<
")\n";
7494 Xyce::dout() <<
" max locations B: (x,y) = (" <<
xVec[inodeB]*xScale<<
", ";
7495 Xyce::dout() <<
yVec[inodeB]*xScale<<
")\n";
7496 Xyce::dout() <<
" nodes: inodeA = "<<inodeA<<
" inodeB = " << inodeB<< std::endl;
7498 Xyce::dout() <<
" VVec["<<inodeA<<
"] = " <<
VVec[inodeA];
7499 Xyce::dout() <<
" VVec["<<inodeB<<
"] = " << VVec[inodeB] << std::endl;
7501 Xyce::dout() <<
" nnVec["<<inodeA<<
"] = " <<
nnVec[inodeA];
7502 Xyce::dout() <<
" nnVec["<<inodeB<<
"] = " << nnVec[inodeB] << std::endl;
7504 Xyce::dout() <<
" elen = " << edgePtr->
elen << std::endl;
7505 Xyce::dout() << section_divider << std::endl;
7524 bool bsuccess =
true;
7529 #ifdef Xyce_DEBUG_DEVICE
7532 Xyce::dout() << section_divider <<
"\n";
7533 Xyce::dout() <<
"Instance::pdElectronCurrent\n";
7534 Xyce::dout() <<
"\n";
7541 #ifdef Xyce_DEBUG_DEVICE
7544 Xyce::dout() << subsection_divider <<
"\n";
7545 Xyce::dout() <<
"i="<<i;
7550 int inodeA = edgePtr->
inodeA;
7551 int inodeB = edgePtr->
inodeB;
7552 double elen = edgePtr->
elen;
7566 #ifdef Xyce_DEBUG_DEVICE
7569 Xyce::dout() <<
" dJndn1="<<
dJndn1Vec[i];
7570 Xyce::dout() <<
" dJndn2="<<
dJndn2Vec[i];
7571 Xyce::dout() <<
" dJndV1="<<
dJndV1Vec[i];
7572 Xyce::dout() <<
" dJndV2="<<
dJndV2Vec[i];
7573 Xyce::dout() <<
"\n";
7578 #ifdef Xyce_DEBUG_DEVICE
7581 Xyce::dout() << section_divider << std::endl;
7598 bool bsuccess =
true;
7604 #ifdef Xyce_DEBUG_DEVICE
7608 Xyce::dout() << section_divider <<
"\n";
7609 Xyce::dout() <<
"Instance::calcHoleCurrent\n";
7610 Xyce::dout() <<
"\n";
7617 #ifdef Xyce_DEBUG_DEVICE
7620 Xyce::dout() <<
"\n";
7621 Xyce::dout() <<
"i="<<i<<
"\n";
7627 int inodeA = edgePtr->
inodeA;
7628 int inodeB = edgePtr->
inodeB;
7629 double elen = edgePtr->
elen;
7634 if (jpMax < fabs(
JpVec[i]) )
7636 #ifdef Xyce_DEBUG_DEVICE
7639 jpMax = fabs(
JpVec[i]);
7642 #ifdef Xyce_DEBUG_DEVICE
7651 #ifdef Xyce_DEBUG_DEVICE
7654 double jScale = 1.0;
7655 double xScale = 1.0;
7658 Xyce::dout().setf(std::ios::scientific);
7659 Xyce::dout() <<
" Max Hole current = " << jpMax;
7660 Xyce::dout() <<
" jScale = " << jScale;
7661 Xyce::dout() <<
"\n";
7664 int inodeA = edgePtr->
inodeA;
7665 int inodeB = edgePtr->
inodeB;
7667 Xyce::dout() <<
" max locations A: (x,y) = (" <<
xVec[inodeA]*xScale<<
", ";
7668 Xyce::dout() <<
yVec[inodeA]*xScale<<
")\n";
7669 Xyce::dout() <<
" max locations B: (x,y) = (" <<
xVec[inodeB]*xScale<<
", ";
7670 Xyce::dout() <<
yVec[inodeB]*xScale<<
")\n";
7671 Xyce::dout() <<
" nodes: inodeA = "<<inodeA<<
" inodeB = " << inodeB<< std::endl;
7673 Xyce::dout() <<
" VVec["<<inodeA<<
"] = " <<
VVec[inodeA];
7674 Xyce::dout() <<
" VVec["<<inodeB<<
"] = " << VVec[inodeB] << std::endl;
7676 Xyce::dout() <<
" npVec["<<inodeA<<
"] = " <<
npVec[inodeA];
7677 Xyce::dout() <<
" npVec["<<inodeB<<
"] = " << npVec[inodeB] << std::endl;
7679 Xyce::dout() <<
" elen = " << edgePtr->
elen << std::endl;
7680 Xyce::dout() << section_divider << std::endl;
7698 bool bsuccess =
true;
7703 #ifdef Xyce_DEBUG_DEVICE
7706 Xyce::dout() << section_divider <<
"\n";
7707 Xyce::dout() <<
"Instance::pdHoleCurrent\n";
7708 Xyce::dout() <<
"\n";
7716 #ifdef Xyce_DEBUG_DEVICE
7719 Xyce::dout() << subsection_divider <<
"\n";
7720 Xyce::dout() <<
"i="<<i;
7721 Xyce::dout() <<
"\n";
7726 int inodeA = edgePtr->
inodeA;
7727 int inodeB = edgePtr->
inodeB;
7728 double elen = edgePtr->
elen;
7742 #ifdef Xyce_DEBUG_DEVICE
7745 Xyce::dout() <<
" dJpdn1="<<
dJpdn1Vec[i];
7746 Xyce::dout() <<
" dJpdn2="<<
dJpdn2Vec[i];
7747 Xyce::dout() <<
" dJpdV1="<<
dJpdV1Vec[i];
7748 Xyce::dout() <<
" dJpdV2="<<
dJpdV2Vec[i];
7749 Xyce::dout() <<
"\n" <<
"\n";
7755 #ifdef Xyce_DEBUG_DEVICE
7758 Xyce::dout() << section_divider << std::endl;
7782 bool bsuccess =
true;
7785 #ifdef Xyce_DEBUG_DEVICE
7790 Xyce::dout() << section_divider <<
"\n";
7791 Xyce::dout() <<
"Instance::calcEfield\n";
7792 Xyce::dout() <<
"\n";
7803 int inodeA = edgePtr->
inodeA;
7804 int inodeB = edgePtr->
inodeB;
7805 double elen = edgePtr->
elen;
7809 #ifdef Xyce_DEBUG_DEVICE
7812 Xyce::dout() <<
" VV[A] = " <<
VVec[inodeA];
7813 Xyce::dout() <<
" VV[B] = " <<
VVec[inodeB];
7814 Xyce::dout() <<
" elen = " << elen;
7816 Xyce::dout() <<
" EfieldVec["<<i<<
"] = " <<
EfieldVec[i];
7817 Xyce::dout() <<
" E*scalingVars.E0 = " << EfieldVec[i]*
scalingVars.
E0;
7818 Xyce::dout() <<
"\n";
7823 Xyce::dout() <<
" edge = " << i;
7824 Xyce::dout() <<
" elen = " << elen;
7825 Xyce::dout() <<
" elen less than zero. Exiting" << std::endl;
7830 if (absEfield >
Emax)
7833 #ifdef Xyce_DEBUG_DEVICE
7841 else { eScale = 1.0; }
7845 #ifdef Xyce_DEBUG_DEVICE
7848 else { xScale = 1.0; }
7852 Xyce::dout().setf(std::ios::scientific);
7853 Xyce::dout() <<
" Max Efield = " <<
Emax;
7854 Xyce::dout() <<
" eScale = " << eScale;
7855 Xyce::dout() <<
"\n";
7858 int inodeA = edgePtr->
inodeA;
7859 int inodeB = edgePtr->
inodeB;
7861 Xyce::dout() <<
" max locations A: (x,y) = (" <<
xVec[inodeA]*xScale<<
", ";
7862 Xyce::dout() <<
yVec[inodeA]*xScale<<
")\n";
7863 Xyce::dout() <<
" max locations B: (x,y) = (" <<
xVec[inodeB]*xScale<<
", ";
7864 Xyce::dout() <<
yVec[inodeB]*xScale<<
")\n";
7865 Xyce::dout() <<
" nodes: inodeA = "<<inodeA<<
" inodeB = " << inodeB<< std::endl;
7866 Xyce::dout() <<
" VVec["<<inodeA<<
"] = " <<
VVec[inodeA];
7867 Xyce::dout() <<
" VVec["<<inodeB<<
"] = " << VVec[inodeB] << std::endl;
7868 Xyce::dout() <<
" elen = " << edgePtr->
elen << std::endl;
7869 Xyce::dout() << section_divider << std::endl;
7894 bool bnoChange =
true;
7896 #ifdef Xyce_DEBUG_DEVICE
7899 Xyce::dout() << section_divider <<
"\n";
7900 Xyce::dout() <<
"Instance::enableContinuation. " <<
outputName;
7901 Xyce::dout() << std::endl;
7907 std::vector<DeviceInterfaceNode>::iterator firstDI =
dIVec.begin();
7908 std::vector<DeviceInterfaceNode>::iterator lastDI =
dIVec.end ();
7909 std::vector<DeviceInterfaceNode>::iterator iterDI;
7919 for (iterDI=firstDI;iterDI!=lastDI;++iterDI)
7921 iterDI->Vckt_old = iterDI->Vckt;
7927 for (iterDI=firstDI;iterDI!=lastDI;++iterDI)
7929 iterDI->Vckt_final = iterDI->Vckt;
7930 iterDI->Vckt_orig = iterDI->Vckt;
7939 for (iterDI=firstDI;iterDI!=lastDI;++iterDI)
7941 double dV,tmp1V, tmp2V;
7942 tmp1V = iterDI->Vckt_final;
7943 tmp2V = iterDI->Vckt_old;
7946 iterDI->Vckt_delta = dV;
7948 iterDI->Vckt_deltaC = dV/
7955 if (fabs(iterDI->Vckt_deltaC) > maxDelta)
7957 int tmp_steps =
static_cast<int>(fabs(dV)/maxDelta) + 1;
7960 iterDI->Vckt_deltaC = dV/
7964 if (fabs(dV) > 1.0e-3) bnoChange =
false;
7966 #ifdef Xyce_DEBUG_DEVICE
7969 Xyce::dout() << std::endl;
7971 Xyce::dout().width(10);
7972 Xyce::dout() << iterDI->eName;
7973 Xyce::dout().width(10); Xyce::dout().precision(2);
7974 Xyce::dout() <<
": dV = " << dV;
7975 Xyce::dout() <<
" Vckt_final = " << iterDI->Vckt_final;
7976 Xyce::dout() <<
" Vckt_old = " << iterDI->Vckt_old << std::endl;
7977 Xyce::dout() <<
" delta = " << iterDI->Vckt_delta;
7978 Xyce::dout() <<
" deltaC = " << iterDI->Vckt_deltaC;
7980 Xyce::dout() << std::endl;
7984 iterDI->Vckt_ramp = iterDI->Vckt_old;
7985 iterDI->Vckt_ramp_old = iterDI->Vckt_old;
7989 bool bnoChangePhotogen =
true;
7993 std::string msg =
"Instance::enablePDEContinuation: PhotogenContinuation not supported";
7994 N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
7997 bnoChange = bnoChange && bnoChangePhotogen;
7999 #ifdef Xyce_DEBUG_DEVICE
8002 if (bnoChange) Xyce::dout() <<
"bnoChange is TRUE" << std::endl;
8003 else Xyce::dout() <<
"bnoChange is FALSE" << std::endl;
8009 #ifdef Xyce_DEBUG_DEVICE
8012 Xyce::dout() << section_divider << std::endl;
8018 return (!bnoChange);
8035 std::vector<DeviceInterfaceNode>::iterator firstDI =
dIVec.begin();
8036 std::vector<DeviceInterfaceNode>::iterator lastDI =
dIVec.end ();
8037 std::vector<DeviceInterfaceNode>::iterator iterDI;
8039 for (iterDI=firstDI;iterDI!=lastDI;++iterDI)
8041 iterDI->Vckt_old = iterDI->Vckt_final;
8059 #ifdef Xyce_DEBUG_DEVICE
8060 Xyce::dout() << section_divider << std::endl;
8061 Xyce::dout() <<
"Instance::setPDEContinuationAlpha" << std::endl;
8066 std::vector<DeviceInterfaceNode>::iterator firstDI =
dIVec.begin();
8067 std::vector<DeviceInterfaceNode>::iterator lastDI =
dIVec.end ();
8068 std::vector<DeviceInterfaceNode>::iterator iterDI;
8070 for (iterDI=firstDI;iterDI!=lastDI;++iterDI)
8072 iterDI->Vckt_ramp = iterDI->Vckt_old + (iterDI->Vckt_delta)*alpha;
8075 if ((iterDI->Vckt_delta > 0 && iterDI->Vckt_ramp > iterDI->Vckt_final) ||
8076 (iterDI->Vckt_delta <= 0 && iterDI->Vckt_ramp <= iterDI->Vckt_final) )
8078 iterDI->Vckt_ramp = iterDI->Vckt_final;
8080 #ifdef Xyce_NEW_PDE_CONTINUATION
8082 iterDI->Vckt_old = iterDI->Vckt_final;
8086 #ifdef Xyce_DEBUG_DEVICE
8090 Xyce::dout().width(10);
8091 Xyce::dout() <<iterDI->eName;
8092 Xyce::dout() <<
"\tVckt_ramp = " << iterDI->Vckt_ramp;
8093 Xyce::dout() <<
"\tVckt_old = " << iterDI->Vckt_old;
8094 Xyce::dout() <<
"\talpha = " << alpha;
8095 Xyce::dout() << std::endl;
8109 #ifdef Xyce_NEW_PDE_CONTINUATION
8115 #ifdef Xyce_DEBUG_DEVICE
8116 Xyce::dout() <<
" photoA1_ramp = " <<
photoA1_ramp << std::endl;
8117 Xyce::dout() << section_divider << std::endl;
8132 #ifdef Xyce_DEBUG_DEVICE
8133 Xyce::dout() << section_divider << std::endl;
8134 Xyce::dout() <<
"Instance::setPDEContinuationBeta" << std::endl;
8138 std::vector<DeviceInterfaceNode>::iterator firstDI =
dIVec.begin();
8139 std::vector<DeviceInterfaceNode>::iterator lastDI =
dIVec.end ();
8140 std::vector<DeviceInterfaceNode>::iterator iterDI;
8142 for (iterDI=firstDI;iterDI!=lastDI;++iterDI)
8144 iterDI->Vckt_ramp = iterDI->Vckt*beta;
8145 #ifdef Xyce_DEBUG_DEVICE
8146 Xyce::dout() <<
" " << iterDI->eName <<
" Vckt_ramp = " << iterDI->Vckt_ramp << std::endl;
8162 .registerDevice(
"pde", 2)
8163 .registerModelType(
"pde", 2)
8164 .registerModelType(
"zod", 2);