📄 twoadmit.c
字号:
if (pElem->elemType == SEMICON) { /* compute the derivatives with n,p */ if (pHNode->nodeType != CONTACT) { indexN = pHNode->nEqn; indexP = pHNode->pEqn; CMPLX_ASSIGN_VALUE(nAc, xReal[indexN], xImag[indexN]); CMPLX_ASSIGN_VALUE(pAc, xReal[indexP], xImag[indexP]); CMPLX_MULT_SCALAR(prod1, nAc, pHEdge->dJnDn); CMPLX_MULT_SCALAR(prod2, pAc, pHEdge->dJpDp); CMPLX_ADD(sum, prod1, prod2); CMPLX_MULT_SCALAR(prod1, sum, 0.5 * pElem->dy); CMPLX_SUBT_ASSIGN(yTotal, prod1); } if (pVNode->nodeType != CONTACT) { indexN = pVNode->nEqn; indexP = pVNode->pEqn; CMPLX_ASSIGN_VALUE(nAc, xReal[indexN], xImag[indexN]); CMPLX_ASSIGN_VALUE(pAc, xReal[indexP], xImag[indexP]); CMPLX_MULT_SCALAR(prod1, nAc, pVEdge->dJnDnP1); CMPLX_MULT_SCALAR(prod2, pAc, pVEdge->dJpDpP1); CMPLX_ADD(sum, prod1, prod2); CMPLX_MULT_SCALAR(prod1, sum, 0.5 * pElem->dx); CMPLX_ADD_ASSIGN(yTotal, prod1); } } break; } if (pElem->elemType == SEMICON) { if (pHNode->nodeType != CONTACT) { indexPsi = pHNode->psiEqn; CMPLX_ASSIGN_VALUE(psiAc, xReal[indexPsi], xImag[indexPsi]); temp = 0.5 * pElem->dy * (pHEdge->dJnDpsiP1 + pHEdge->dJpDpsiP1); CMPLX_MULT_SCALAR(prod1, psiAc, temp); CMPLX_ADD_ASSIGN(yTotal, prod1); if (delVContact) { CMPLX_ADD_SELF_SCALAR(yTotal, -temp); } } if (pVNode->nodeType != CONTACT) { indexPsi = pVNode->psiEqn; CMPLX_ASSIGN_VALUE(psiAc, xReal[indexPsi], xImag[indexPsi]); temp = 0.5 * pElem->dx * (pVEdge->dJnDpsiP1 + pVEdge->dJpDpsiP1); CMPLX_MULT_SCALAR(prod1, psiAc, temp); CMPLX_ADD_ASSIGN(yTotal, prod1); if (delVContact) { CMPLX_ADD_SELF_SCALAR(yTotal, -temp); } } } /* displacement current terms */ if (pHNode->nodeType != CONTACT) { indexPsi = pHNode->psiEqn; CMPLX_ASSIGN_VALUE(psiAc, xReal[indexPsi], xImag[indexPsi]); CMPLX_MULT_SCALAR(prod1, *cOmega, pElem->epsRel * 0.5 * pElem->dyOverDx); CMPLX_MULT(prod2, prod1, psiAc); CMPLX_SUBT_ASSIGN(yTotal, prod2); if (delVContact) { CMPLX_ADD_ASSIGN(yTotal, prod1); } } if (pVNode->nodeType != CONTACT) { indexPsi = pVNode->psiEqn; CMPLX_ASSIGN_VALUE(psiAc, xReal[indexPsi], xImag[indexPsi]); CMPLX_MULT_SCALAR(prod1, *cOmega, pElem->epsRel * 0.5 * pElem->dxOverDy); CMPLX_MULT(prod2, prod1, psiAc); CMPLX_SUBT_ASSIGN(yTotal, prod2); if (delVContact) { CMPLX_ADD_ASSIGN(yTotal, prod1); } } } } } return (&yTotal); /* XXX */}SPcomplex *oxideAdmittance(TWOdevice *pDevice, TWOcontact *pContact, BOOLEAN delVContact, double *xReal, double *xImag, SPcomplex *cOmega){ TWOnode *pNode, *pHNode = NULL, *pVNode = NULL; TWOedge *pHEdge, *pVEdge; int index, i, indexPsi, numContactNodes; TWOelem *pElem; SPcomplex psiAc; SPcomplex prod1, prod2; CMPLX_ASSIGN_VALUE(yTotal, 0.0, 0.0); numContactNodes = pContact->numNodes; for (index = 0; index < numContactNodes; index++) { pNode = pContact->pNodes[index]; for (i = 0; i <= 3; i++) { pElem = pNode->pElems[i]; if (pElem != NIL(TWOelem)) { switch (i) { case 0: /* the TL element */ pHNode = pElem->pBLNode; pVNode = pElem->pTRNode; pHEdge = pElem->pBotEdge; pVEdge = pElem->pRightEdge; break; case 1: /* the TR element */ pHNode = pElem->pBRNode; pVNode = pElem->pTLNode; pHEdge = pElem->pBotEdge; pVEdge = pElem->pLeftEdge; break; case 2: /* the BR element */ pHNode = pElem->pTRNode; pVNode = pElem->pBLNode; pHEdge = pElem->pTopEdge; pVEdge = pElem->pLeftEdge; break; case 3: /* the BL element */ pHNode = pElem->pTLNode; pVNode = pElem->pBRNode; pHEdge = pElem->pTopEdge; pVEdge = pElem->pRightEdge; break; } /* displacement current terms */ if (pHNode->nodeType != CONTACT) { indexPsi = pHNode->psiEqn; CMPLX_ASSIGN_VALUE(psiAc, xReal[indexPsi], xImag[indexPsi]); CMPLX_MULT_SCALAR(prod1, *cOmega, pElem->epsRel * 0.5 * pElem->dyOverDx); CMPLX_MULT(prod2, prod1, psiAc); CMPLX_SUBT_ASSIGN(yTotal, prod2); if (delVContact) { CMPLX_ADD_ASSIGN(yTotal, prod1); } } if (pVNode->nodeType != CONTACT) { indexPsi = pVNode->psiEqn; CMPLX_ASSIGN_VALUE(psiAc, xReal[indexPsi], xImag[indexPsi]); CMPLX_MULT_SCALAR(prod1, *cOmega, pElem->epsRel * 0.5 * pElem->dxOverDy); CMPLX_MULT(prod2, prod1, psiAc); CMPLX_SUBT_ASSIGN(yTotal, prod2); if (delVContact) { CMPLX_ADD_ASSIGN(yTotal, prod1); } } } } } return (&yTotal);}voidNUMD2ys(TWOdevice *pDevice, SPcomplex *s, SPcomplex *yIn){ TWOnode *pNode; TWOelem *pElem; int index, eIndex; double dxdy; double *solnReal, *solnImag; double *rhsReal, *rhsImag; SPcomplex yAc, *y; BOOLEAN deltaVContact = FALSE; SPcomplex temp, cOmega; /* * change context names of solution vectors for ac analysis dcDeltaSolution * stores the real part and copiedSolution stores the imaginary part of the * ac solution vector */ pDevice->solverType = SLV_SMSIG; rhsReal = pDevice->rhs; rhsImag = pDevice->rhsImag; solnReal = pDevice->dcDeltaSolution; solnImag = pDevice->copiedSolution; /* use a normalized radian frequency */ CMPLX_MULT_SCALAR(cOmega, *s, TNorm); for (index = 1; index <= pDevice->numEqns; index++) { rhsImag[index] = 0.0; } /* solve the system of equations directly */ if (!OneCarrier) { TWO_jacLoad(pDevice); } else if (OneCarrier == N_TYPE) { TWONjacLoad(pDevice); } else if (OneCarrier == P_TYPE) { TWOPjacLoad(pDevice); } storeNewRhs(pDevice, pDevice->pLastContact); spSetComplex(pDevice->matrix); for (eIndex = 1; eIndex <= pDevice->numElems; eIndex++) { pElem = pDevice->elements[eIndex]; if (pElem->elemType == SEMICON) { dxdy = 0.25 * pElem->dx * pElem->dy; for (index = 0; index <= 3; index++) { pNode = pElem->pNodes[index]; if (pNode->nodeType != CONTACT) { if (!OneCarrier) { CMPLX_MULT_SCALAR(temp, cOmega, dxdy); spADD_COMPLEX_ELEMENT(pNode->fNN, -temp.real, -temp.imag); spADD_COMPLEX_ELEMENT(pNode->fPP, temp.real, temp.imag); } else if (OneCarrier == N_TYPE) { CMPLX_MULT_SCALAR(temp, cOmega, dxdy); spADD_COMPLEX_ELEMENT(pNode->fNN, -temp.real, -temp.imag); } else if (OneCarrier == P_TYPE) { CMPLX_MULT_SCALAR(temp, cOmega, dxdy); spADD_COMPLEX_ELEMENT(pNode->fPP, temp.real, temp.imag); } } } } } spFactor(pDevice->matrix); spSolve(pDevice->matrix, rhsReal, solnReal, rhsImag, solnImag); y = contactAdmittance(pDevice, pDevice->pFirstContact, deltaVContact, solnReal, solnImag, &cOmega); CMPLX_ASSIGN_VALUE(yAc, y->real, y->imag); CMPLX_ASSIGN(*yIn, yAc); CMPLX_NEGATE_SELF(*yIn); CMPLX_MULT_SELF_SCALAR(*yIn, GNorm * pDevice->width * LNorm);}voidNBJT2ys(TWOdevice *pDevice, SPcomplex *s, SPcomplex *yIeVce, SPcomplex *yIcVce, SPcomplex *yIeVbe, SPcomplex *yIcVbe){ TWOcontact *pEmitContact = pDevice->pLastContact; TWOcontact *pColContact = pDevice->pFirstContact; TWOcontact *pBaseContact = pDevice->pFirstContact->next; TWOnode *pNode; TWOelem *pElem; int index, eIndex; double width = pDevice->width; double dxdy; double *solnReal, *solnImag; double *rhsReal, *rhsImag; SPcomplex *y; SPcomplex pIeVce, pIcVce, pIeVbe, pIcVbe; SPcomplex temp, cOmega; pDevice->solverType = SLV_SMSIG; rhsReal = pDevice->rhs; rhsImag = pDevice->rhsImag; solnReal = pDevice->dcDeltaSolution; solnImag = pDevice->copiedSolution; /* use a normalized radian frequency */ CMPLX_MULT_SCALAR(cOmega, *s, TNorm); for (index = 1; index <= pDevice->numEqns; index++) { rhsImag[index] = 0.0; } /* solve the system of equations directly */ if (!OneCarrier) { TWO_jacLoad(pDevice); } else if (OneCarrier == N_TYPE) { TWONjacLoad(pDevice); } else if (OneCarrier == P_TYPE) { TWOPjacLoad(pDevice); } storeNewRhs(pDevice, pColContact); spSetComplex(pDevice->matrix); for (eIndex = 1; eIndex <= pDevice->numElems; eIndex++) { pElem = pDevice->elements[eIndex]; if (pElem->elemType == SEMICON) { dxdy = 0.25 * pElem->dx * pElem->dy; for (index = 0; index <= 3; index++) { pNode = pElem->pNodes[index]; if (pNode->nodeType != CONTACT) { if (!OneCarrier) { CMPLX_MULT_SCALAR(temp, cOmega, dxdy); spADD_COMPLEX_ELEMENT(pNode->fNN, -temp.real, -temp.imag); spADD_COMPLEX_ELEMENT(pNode->fPP, temp.real, temp.imag); } else if (OneCarrier == N_TYPE) { CMPLX_MULT_SCALAR(temp, cOmega, dxdy); spADD_COMPLEX_ELEMENT(pNode->fNN, -temp.real, -temp.imag); } else if (OneCarrier == P_TYPE) { CMPLX_MULT_SCALAR(temp, cOmega, dxdy); spADD_COMPLEX_ELEMENT(pNode->fPP, temp.real, temp.imag); } } } } } spFactor(pDevice->matrix); spSolve(pDevice->matrix, rhsReal, solnReal, rhsImag, solnImag); y = contactAdmittance(pDevice, pEmitContact, FALSE, solnReal, solnImag, &cOmega); CMPLX_ASSIGN_VALUE(pIeVce, y->real, y->imag); y = contactAdmittance(pDevice, pColContact, TRUE, solnReal, solnImag, &cOmega); CMPLX_ASSIGN_VALUE(pIcVce, y->real, y->imag); for (index = 1; index <= pDevice->numEqns; index++) { rhsImag[index] = 0.0; } storeNewRhs(pDevice, pBaseContact); /* don't need to LU factor the jacobian since it exists */ spSolve(pDevice->matrix, rhsReal, solnReal, rhsImag, solnImag); y = contactAdmittance(pDevice, pEmitContact, FALSE, solnReal, solnImag, &cOmega); CMPLX_ASSIGN_VALUE(pIeVbe, y->real, y->imag); y = contactAdmittance(pDevice, pColContact, FALSE, solnReal, solnImag, &cOmega); CMPLX_ASSIGN_VALUE(pIcVbe, y->real, y->imag); CMPLX_ASSIGN(*yIeVce, pIeVce); CMPLX_ASSIGN(*yIeVbe, pIeVbe); CMPLX_ASSIGN(*yIcVce, pIcVce); CMPLX_ASSIGN(*yIcVbe, pIcVbe); CMPLX_MULT_SELF_SCALAR(*yIeVce, GNorm * width * LNorm); CMPLX_MULT_SELF_SCALAR(*yIeVbe, GNorm * width * LNorm); CMPLX_MULT_SELF_SCALAR(*yIcVce, GNorm * width * LNorm); CMPLX_MULT_SELF_SCALAR(*yIcVbe, GNorm * width * LNorm);}voidNUMOSys(TWOdevice *pDevice, SPcomplex *s, struct mosAdmittances *yAc){ TWOcontact *pDContact = pDevice->pFirstContact; TWOcontact *pGContact = pDevice->pFirstContact->next; TWOcontact *pSContact = pDevice->pFirstContact->next->next;/* TWOcontact *pBContact = pDevice->pLastContact; */ TWOnode *pNode; TWOelem *pElem; int index, eIndex; double width = pDevice->width; double dxdy; double *rhsReal, *rhsImag; double *solnReal, *solnImag; SPcomplex *y; SPcomplex temp, cOmega; pDevice->solverType = SLV_SMSIG; rhsReal = pDevice->rhs; rhsImag = pDevice->rhsImag; solnReal = pDevice->dcDeltaSolution; solnImag = pDevice->copiedSolution; /* use a normalized radian frequency */ CMPLX_MULT_SCALAR(cOmega, *s, TNorm); for (index = 1; index <= pDevice->numEqns; index++) { rhsImag[index] = 0.0; } /* solve the system of equations directly */ if (!OneCarrier) { TWO_jacLoad(pDevice); } else if (OneCarrier == N_TYPE) { TWONjacLoad(pDevice); } else if (OneCarrier == P_TYPE) { TWOPjacLoad(pDevice); } storeNewRhs(pDevice, pDContact); spSetComplex(pDevice->matrix); for (eIndex = 1; eIndex <= pDevice->numElems; eIndex++) { pElem = pDevice->elements[eIndex]; if (pElem->elemType == SEMICON) { dxdy = 0.25 * pElem->dx * pElem->dy; for (index = 0; index <= 3; index++) { pNode = pElem->pNodes[index]; if (pNode->nodeType != CONTACT) { if (!OneCarrier) { CMPLX_MULT_SCALAR(temp, cOmega, dxdy); spADD_COMPLEX_ELEMENT(pNode->fNN, -temp.real, -temp.imag); spADD_COMPLEX_ELEMENT(pNode->fPP, temp.real, temp.imag); } else if (OneCarrier == N_TYPE) { CMPLX_MULT_SCALAR(temp, cOmega, dxdy); spADD_COMPLEX_ELEMENT(pNode->fNN, -temp.real, -temp.imag); } else if (OneCarrier == P_TYPE) { CMPLX_MULT_SCALAR(temp, cOmega, dxdy); spADD_COMPLEX_ELEMENT(pNode->fPP, temp.real, temp.imag); } } } } } spFactor(pDevice->matrix); spSolve(pDevice->matrix, rhsReal, solnReal, rhsImag, solnImag); y = contactAdmittance(pDevice, pDContact, TRUE, solnReal, solnImag, &cOmega); CMPLX_ASSIGN_VALUE(yAc->yIdVdb, y->real, y->imag); y = contactAdmittance(pDevice, pSContact, FALSE, solnReal, solnImag, &cOmega); CMPLX_ASSIGN_VALUE(yAc->yIsVdb, y->real, y->imag); y = GateTypeAdmittance(pDevice, pGContact, FALSE, solnReal, solnImag, &cOmega); CMPLX_ASSIGN_VALUE(yAc->yIgVdb, y->real, y->imag); for (index = 1; index <= pDevice->numEqns; index++) { rhsImag[index] = 0.0; } storeNewRhs(pDevice, pSContact); /* don't need to LU factor the jacobian since it exists */ spSolve(pDevice->matrix, rhsReal, solnReal, rhsImag, solnImag); y = contactAdmittance(pDevice, pDContact, FALSE, solnReal, solnImag, &cOmega); CMPLX_ASSIGN_VALUE(yAc->yIdVsb, y->real, y->imag); y = contactAdmittance(pDevice, pSContact, TRUE, solnReal, solnImag, &cOmega); CMPLX_ASSIGN_VALUE(yAc->yIsVsb, y->real, y->imag); y = GateTypeAdmittance(pDevice, pGContact, FALSE, solnReal, solnImag, &cOmega); CMPLX_ASSIGN_VALUE(yAc->yIgVsb, y->real, y->imag); for (index = 1; index <= pDevice->numEqns; index++) { rhsImag[index] = 0.0; } storeNewRhs(pDevice, pGContact); spSolve(pDevice->matrix, rhsReal, solnReal, rhsImag, solnImag); y = contactAdmittance(pDevice, pDContact, FALSE, solnReal, solnImag, &cOmega); CMPLX_ASSIGN_VALUE(yAc->yIdVgb, y->real, y->imag); y = contactAdmittance(pDevice, pSContact, FALSE, solnReal, solnImag, &cOmega); CMPLX_ASSIGN_VALUE(yAc->yIsVgb, y->real, y->imag); y = GateTypeAdmittance(pDevice, pGContact, TRUE, solnReal, solnImag, &cOmega); CMPLX_ASSIGN_VALUE(yAc->yIgVgb, y->real, y->imag); CMPLX_MULT_SELF_SCALAR(yAc->yIdVdb, GNorm * width * LNorm); CMPLX_MULT_SELF_SCALAR(yAc->yIdVsb, GNorm * width * LNorm); CMPLX_MULT_SELF_SCALAR(yAc->yIdVgb, GNorm * width * LNorm); CMPLX_MULT_SELF_SCALAR(yAc->yIsVdb, GNorm * width * LNorm); CMPLX_MULT_SELF_SCALAR(yAc->yIsVsb, GNorm * width * LNorm); CMPLX_MULT_SELF_SCALAR(yAc->yIsVgb, GNorm * width * LNorm); CMPLX_MULT_SELF_SCALAR(yAc->yIgVdb, GNorm * width * LNorm); CMPLX_MULT_SELF_SCALAR(yAc->yIgVsb, GNorm * width * LNorm); CMPLX_MULT_SELF_SCALAR(yAc->yIgVgb, GNorm * width * LNorm);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -