📄 onecont.c
字号:
*(pNode->fPN) += dx * pNode->dUdN; } pNode1 = pElem->pRightNode; if (pNode1->nodeType ISNOT CONTACT) { *(pNode->fPsiPsiiP1) -= rDx; if (pElem->elemType IS SEMICON) { *(pNode->fNPsiiP1) += pEdge->dJnDpsiP1; *(pNode->fNNiP1) += pEdge->dJnDnP1; *(pNode->fPPsiiP1) += pEdge->dJpDpsiP1; *(pNode->fPPiP1) += pEdge->dJpDpP1; } } } pNode = pElem->pRightNode; if (pNode->nodeType ISNOT CONTACT) { pEdge = pElem->pEdge; dPsi = pEdge->dPsi; if (pElem->elemType IS SEMICON) { *(pNode->fNN) += -pEdge->dJnDnP1 - dx * pNode->dUdN; *(pNode->fNP) -= dx * pNode->dUdP; *(pNode->fPP) += -pEdge->dJpDpP1 + dx * pNode->dUdP; *(pNode->fPN) += dx * pNode->dUdN; } pNode1 = pElem->pLeftNode; if (pNode1->nodeType ISNOT CONTACT) { *(pNode->fPsiPsiiM1) -= rDx; if (pElem->elemType IS SEMICON) { *(pNode->fNPsiiM1) += pEdge->dJnDpsiP1; *(pNode->fNNiM1) -= pEdge->dJnDn; *(pNode->fPPsiiM1) += pEdge->dJpDpsiP1; *(pNode->fPPiM1) -= pEdge->dJpDp; } } } } if (AvalancheGen) { /* add the generation terms */ for (eIndex = 1; eIndex < pDevice->numNodes; eIndex++) { pElem = pDevice->elemArray[eIndex]; for (index = 0; index <= 1; index++) { if (pElem->evalNodes[index]) { pNode = pElem->pNodes[index]; if (pNode->nodeType ISNOT CONTACT AND pElem->elemType IS SEMICON) { generation = ONEavalanche(FALSE, pDevice, pNode); } } } } }}void ONE_rhsLoad(pDevice, tranAnalysis, info) ONEdevice *pDevice; BOOLEAN tranAnalysis; ONEtranInfo *info;{ ONEelem *pElem; ONEnode *pNode, *pNode1; ONEedge *pEdge; int index, eIndex; double *pRhs = pDevice->rhs; double dx, rDx, dPsi; double rhsN, rhsP, generation; double perTime; double fNd, fNa, fdNd, fdNa; double netConc, dNd, dNa, psi, nConc, pConc; /* first compute the currents and their derivatives */ ONE_commonTerms(pDevice, FALSE, tranAnalysis, info); /* find reciprocal timestep */ if (tranAnalysis) { perTime = info->intCoeff[0]; } /* zero the rhs vector */ for (index = 1; index <= pDevice->numEqns; index++) { pRhs[index] = 0.0; } for (eIndex = 1; eIndex < pDevice->numNodes; eIndex++) { pElem = pDevice->elemArray[eIndex]; dx = 0.5 * pElem->dx; rDx = pElem->epsRel * pElem->rDx; /* load for all i */ for (index = 0; index <= 1; index++) { pNode = pElem->pNodes[index]; if (pNode->nodeType ISNOT CONTACT) { pRhs[pNode->psiEqn] += pNode->qf; if (pElem->elemType IS SEMICON) { pEdge = pElem->pEdge; netConc = pNode->netConc; dNd = 0.0; dNa = 0.0; psi = *(pDevice->devState0 + pNode->nodePsi); nConc = *(pDevice->devState0 + pNode->nodeN); pConc = *(pDevice->devState0 + pNode->nodeP); if (FreezeOut) { ONE_freezeOut(pNode, nConc, pConc, &fNd, &fNa, &fdNd, &fdNa); netConc = pNode->nd * fNd - pNode->na * fNa; dNd = pNode->nd * fdNd; dNa = pNode->na * fdNa; } pRhs[pNode->psiEqn] += dx * (netConc + pConc - nConc); /* Handle generation terms */ pRhs[pNode->nEqn] -= -dx * pNode->uNet; pRhs[pNode->pEqn] -= dx * pNode->uNet; /* Handle dXdT continuity terms */ if (tranAnalysis) { pRhs[pNode->nEqn] += dx * pNode->dNdT; pRhs[pNode->pEqn] -= dx * pNode->dPdT; } /* Take care of base contact if necessary */ /* eg holds the base edge mu/dx */ if (pNode->baseType IS N_TYPE) { pRhs[pNode->nEqn] += 0.5 * pNode->eg * nConc * (pNode->vbe - psi + log(nConc / pNode->nie)); } else if (pNode->baseType IS P_TYPE) { pRhs[pNode->pEqn] += 0.5 * pNode->eg * pConc * (pNode->vbe - psi - log(pConc / pNode->nie)); } } } } pEdge = pElem->pEdge; dPsi = pEdge->dPsi; pNode = pElem->pLeftNode; if (pNode->nodeType ISNOT CONTACT) { pRhs[pNode->psiEqn] += rDx * dPsi; if (pElem->elemType IS SEMICON) { pRhs[pNode->nEqn] -= pEdge->jn; pRhs[pNode->pEqn] -= pEdge->jp; } } pNode = pElem->pRightNode; if (pNode->nodeType ISNOT CONTACT) { pRhs[pNode->psiEqn] -= rDx * dPsi; if (pElem->elemType IS SEMICON) { pRhs[pNode->nEqn] += pEdge->jn; pRhs[pNode->pEqn] += pEdge->jp; } } } if (AvalancheGen) { /* add the generation terms */ for (eIndex = 1; eIndex < pDevice->numNodes; eIndex++) { pElem = pDevice->elemArray[eIndex]; for (index = 0; index <= 1; index++) { if (pElem->evalNodes[index]) { pNode = pElem->pNodes[index]; if (pNode->nodeType ISNOT CONTACT AND pElem->elemType IS SEMICON) { generation = ONEavalanche(TRUE, pDevice, pNode); pRhs[pNode->nEqn] -= generation; pRhs[pNode->pEqn] += generation; } } } } }}void ONE_commonTerms(pDevice, currentOnly, tranAnalysis, info) ONEdevice *pDevice; BOOLEAN currentOnly, tranAnalysis; ONEtranInfo *info;{ ONEelem *pElem; ONEedge *pEdge; ONEnode *pNode, *pNode1; int index, eIndex; double psi1, psi2, psi, nConc, pConc, nC, pC, nP1, pP1; double dPsiN, dPsiP; double bPsiN, dbPsiN, bMPsiN, dbMPsiN; double bPsiP, dbPsiP, bMPsiP, dbMPsiP; double mun, dMun, mup, dMup, rDx; double conc1, conc2; double cnAug, cpAug; /* evaluate all node (including recombination) and edge quantities */ for (eIndex = 1; eIndex < pDevice->numNodes; eIndex++) { pElem = pDevice->elemArray[eIndex]; cnAug = pElem->matlInfo->cAug[ELEC]; cpAug = pElem->matlInfo->cAug[HOLE]; for (index = 0; index <= 1; index++) { if (pElem->evalNodes[index]) { pNode = pElem->pNodes[index]; if (pNode->nodeType ISNOT CONTACT) { psi = pDevice->dcSolution[pNode->psiEqn]; if (pElem->elemType IS SEMICON) { nConc = pDevice->dcSolution[pNode->nEqn]; pConc = pDevice->dcSolution[pNode->pEqn]; if (Srh) { recomb(nConc, pConc, pNode->tn, pNode->tp, cnAug, cpAug, pNode->nie, &pNode->uNet, &pNode->dUdN, &pNode->dUdP); } else { pNode->uNet = 0.0; pNode->dUdN = 0.0; pNode->dUdP = 0.0; } if (pNode->baseType IS P_TYPE AND pConc <= 0.0) { pConc = pNode->na; } else if (pNode->baseType IS N_TYPE AND nConc <= 0.0) { nConc = pNode->nd; } } } else { /* a contact node */ psi = pNode->psi; if (pElem->elemType IS SEMICON) { nConc = pNode->nConc; pConc = pNode->pConc; } } /* store info in the state tables */ *(pDevice->devState0 + pNode->nodePsi) = psi; if (pElem->elemType IS SEMICON) { *(pDevice->devState0 + pNode->nodeN) = nConc; *(pDevice->devState0 + pNode->nodeP) = pConc; if (tranAnalysis AND pNode->nodeType ISNOT CONTACT) { pNode->dNdT = integrate(pDevice->devStates, info, pNode->nodeN); pNode->dPdT = integrate(pDevice->devStates, info, pNode->nodeP); } } } } pEdge = pElem->pEdge; pNode = pElem->pLeftNode; if (pNode->nodeType ISNOT CONTACT) { psi1 = pDevice->dcSolution[pNode->psiEqn]; } else { psi1 = pNode->psi; } pNode = pElem->pRightNode; if (pNode->nodeType ISNOT CONTACT) { psi2 = pDevice->dcSolution[pNode->psiEqn]; } else { psi2 = pNode->psi; } pEdge->dPsi = psi2 - psi1; *(pDevice->devState0 + pEdge->edgeDpsi) = pEdge->dPsi; } /* calculate the current densities and mobility values */ for (eIndex = 1; eIndex < pDevice->numNodes; eIndex++) { pElem = pDevice->elemArray[eIndex]; pEdge = pElem->pEdge; if (pElem->elemType IS SEMICON) { dPsiN = pEdge->dPsi + pEdge->dCBand; dPsiP = pEdge->dPsi - pEdge->dVBand; bernoulli(dPsiN, &bPsiN, &dbPsiN, &bMPsiN, &dbMPsiN, NOT currentOnly); bernoulli(dPsiP, &bPsiP, &dbPsiP, &bMPsiP, &dbMPsiP, NOT currentOnly); nC = *(pDevice->devState0 + pElem->pLeftNode->nodeN); nP1 = *(pDevice->devState0 + pElem->pRightNode->nodeN); pC = *(pDevice->devState0 + pElem->pLeftNode->nodeP); pP1 = *(pDevice->devState0 + pElem->pRightNode->nodeP); conc1 = pElem->pLeftNode->totalConc; conc2 = pElem->pRightNode->totalConc; pEdge->jn = (bPsiN * nP1 - bMPsiN * nC); pEdge->jp = (bPsiP * pC - bMPsiP * pP1); mun = pEdge->mun; dMun = 0.0; mup = pEdge->mup; dMup = 0.0; MOBfieldDep(pElem->matlInfo, ELEC, dPsiN * pElem->rDx, &mun, &dMun); MOBfieldDep(pElem->matlInfo, HOLE, dPsiP * pElem->rDx, &mup, &dMup); mun *= pElem->rDx; dMun *= pElem->rDx * pElem->rDx; mup *= pElem->rDx; dMup *= pElem->rDx * pElem->rDx; /* * The base continuity equation makes use of mu/dx in eg. The base * length has already been calculated and converted to normalized, * reciprocal form during setup. The name should be changed, but that's * a big hassle. */ for (index = 0; index <= 1; index++) { if (pElem->evalNodes[index]) { pNode = pElem->pNodes[index]; if (pNode->baseType IS N_TYPE) { pNode->eg = pEdge->mun * pDevice->baseLength; } else if (pNode->baseType IS P_TYPE) { pNode->eg = pEdge->mup * pDevice->baseLength; } } } pEdge->jn *= mun; pEdge->jp *= mup; if (NOT currentOnly) { if (dMun IS 0.0) { pEdge->dJnDpsiP1 = mun * (dbPsiN * nP1 - dbMPsiN * nC); } else { pEdge->dJnDpsiP1 = dMun * (bPsiN * nP1 - bMPsiN * nC) + mun * (dbPsiN * nP1 - dbMPsiN * nC); } pEdge->dJnDn = -mun * bMPsiN; pEdge->dJnDnP1 = mun * bPsiN; if (dMup IS 0.0) { pEdge->dJpDpsiP1 = mup * (dbPsiP * pC - dbMPsiP * pP1); } else { pEdge->dJpDpsiP1 = dMup * (bPsiP * pC - bMPsiP * pP1) + mup * (dbPsiP * pC - dbMPsiP * pP1); } pEdge->dJpDp = mup * bPsiP; pEdge->dJpDpP1 = -mup * bMPsiP; } } if (tranAnalysis) { pEdge->jd = -integrate(pDevice->devStates, info, pEdge->edgeDpsi) * pElem->rDx; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -