📄 onecond.c
字号:
/**********Copyright 1992 Regents of the University of California. All rights reserved.Author: 1987 Kartikeya Mayaram, U. C. Berkeley CAD Group**********//* Functions to compute device conductances and currents */#include <math.h>#include "numglobs.h"#include "numenum.h"#include "nummacs.h"#include "onemesh.h"#include "onedev.h"voidNUMDconductance(pDevice, tranAnalysis, intCoeff, gd) ONEdevice *pDevice; BOOLEAN tranAnalysis; double *intCoeff; double *gd;{ ONEelem *pElem = pDevice->elemArray[pDevice->numNodes - 1]; ONEnode *pNode; ONEedge *pEdge; int index; double dPsiDv, dNDv, dPDv, *incVpn; *gd = 0.0; /* zero the rhs before loading in the new rhs */ for (index = 1; index <= pDevice->numEqns; index++) { pDevice->rhs[index] = 0.0; } /* compute incremental changes due to N contact */ pNode = pElem->pLeftNode; pDevice->rhs[pNode->psiEqn] = pElem->epsRel * pElem->rDx; if (pElem->elemType IS SEMICON) { pEdge = pElem->pEdge; pDevice->rhs[pNode->nEqn] = -pEdge->dJnDpsiP1; pDevice->rhs[pNode->pEqn] = -pEdge->dJpDpsiP1; } incVpn = pDevice->dcDeltaSolution; spSolve(pDevice->matrix, pDevice->rhs, incVpn); pElem = pDevice->elemArray[1]; pNode = pElem->pRightNode; pEdge = pElem->pEdge; dPsiDv = incVpn[pNode->psiEqn]; if (pElem->elemType IS SEMICON) { dNDv = incVpn[pNode->nEqn]; dPDv = incVpn[pNode->pEqn]; *gd += pEdge->dJnDpsiP1 * dPsiDv + pEdge->dJnDnP1 * dNDv + pEdge->dJpDpsiP1 * dPsiDv + pEdge->dJpDpP1 * dPDv; } /* For transient analysis, add the displacement term */ if (tranAnalysis) { *gd -= intCoeff[0] * pElem->epsRel * pElem->rDx * dPsiDv; } *gd *= -GNorm * pDevice->area;}voidNBJTconductance(pDevice, tranAnalysis, intCoeff, dIeDVce, dIcDVce, dIeDVbe, dIcDVbe) ONEdevice *pDevice; BOOLEAN tranAnalysis; double *intCoeff; double *dIeDVce, *dIcDVce, *dIeDVbe, *dIcDVbe;{ ONEelem *pLastElem = pDevice->elemArray[pDevice->numNodes - 1]; ONEelem *pBaseElem = pDevice->elemArray[pDevice->baseIndex - 1]; ONEelem *pElem; ONEnode *pNode; ONEedge *pEdge; int index; double dPsiDVce, dPsiDVbe, dNDVce, dNDVbe, dPDVce, dPDVbe; double *incVce, *incVbe; double nConc, pConc; double area = pDevice->area; *dIeDVce = 0.0; *dIcDVce = 0.0; *dIeDVbe = 0.0; *dIcDVbe = 0.0; /* zero the rhs before loading in the new rhs */ for (index = 1; index <= pDevice->numEqns; index++) { pDevice->rhs[index] = 0.0; } /* store the new rhs for computing CE incremental quantities */ pNode = pLastElem->pLeftNode; pDevice->rhs[pNode->psiEqn] = pLastElem->epsRel * pLastElem->rDx; if (pLastElem->elemType IS SEMICON) { pEdge = pLastElem->pEdge; pDevice->rhs[pNode->nEqn] = -pEdge->dJnDpsiP1; pDevice->rhs[pNode->pEqn] = -pEdge->dJpDpsiP1; } incVce = pDevice->dcDeltaSolution; spSolve(pDevice->matrix, pDevice->rhs, incVce); /* zero the rhs before loading in the new rhs base contribution */ for (index = 1; index <= pDevice->numEqns; index++) { pDevice->rhs[index] = 0.0; } pNode = pBaseElem->pRightNode; if (pNode->baseType IS N_TYPE) { nConc = *(pDevice->devState0 + pNode->nodeN); pDevice->rhs[pNode->nEqn] = nConc * pNode->eg; } else if (pNode->baseType IS P_TYPE) { pConc = *(pDevice->devState0 + pNode->nodeP); pDevice->rhs[pNode->pEqn] = pConc * pNode->eg; } else { printf("NBJTconductance: unknown base type\n"); } incVbe = pDevice->copiedSolution; spSolve(pDevice->matrix, pDevice->rhs, incVbe); pElem = pDevice->elemArray[1];/* first element */ pEdge = pElem->pEdge; pNode = pElem->pRightNode; dPsiDVce = incVce[pNode->psiEqn]; dPsiDVbe = incVbe[pNode->psiEqn]; if (pElem->elemType IS SEMICON) { dNDVce = incVce[pNode->nEqn]; dPDVce = incVce[pNode->pEqn]; dNDVbe = incVbe[pNode->nEqn]; dPDVbe = incVbe[pNode->pEqn]; *dIeDVce += pEdge->dJnDpsiP1 * dPsiDVce + pEdge->dJnDnP1 * dNDVce + pEdge->dJpDpsiP1 * dPsiDVce + pEdge->dJpDpP1 * dPDVce; *dIeDVbe += pEdge->dJnDpsiP1 * dPsiDVbe + pEdge->dJnDnP1 * dNDVbe + pEdge->dJpDpsiP1 * dPsiDVbe + pEdge->dJpDpP1 * dPDVbe; } /* For transient analysis add the displacement term */ if (tranAnalysis) { *dIeDVce -= intCoeff[0] * pElem->epsRel * dPsiDVce * pElem->rDx; *dIeDVbe -= intCoeff[0] * pElem->epsRel * dPsiDVbe * pElem->rDx; } pElem = pDevice->elemArray[pDevice->numNodes - 1]; /* last element */ pEdge = pElem->pEdge; pNode = pElem->pLeftNode; dPsiDVce = incVce[pNode->psiEqn]; dPsiDVbe = incVbe[pNode->psiEqn]; if (pElem->elemType IS SEMICON) { dNDVce = incVce[pNode->nEqn]; dPDVce = incVce[pNode->pEqn]; dNDVbe = incVbe[pNode->nEqn]; dPDVbe = incVbe[pNode->pEqn]; *dIcDVce += -pEdge->dJnDpsiP1 * dPsiDVce + pEdge->dJnDn * dNDVce + -pEdge->dJpDpsiP1 * dPsiDVce + pEdge->dJpDp * dPDVce + /* add terms since adjacent to boundary */ pEdge->dJnDpsiP1 + pEdge->dJpDpsiP1; *dIcDVbe += -pEdge->dJnDpsiP1 * dPsiDVbe + pEdge->dJnDn * dNDVbe + -pEdge->dJpDpsiP1 * dPsiDVbe + pEdge->dJpDp * dPDVbe; } if (tranAnalysis) { *dIcDVce += intCoeff[0] * pElem->epsRel * (dPsiDVce - 1.0) * pElem->rDx; *dIcDVbe += intCoeff[0] * pElem->epsRel * dPsiDVbe * pElem->rDx; } *dIeDVce *= -GNorm * area; *dIcDVce *= -GNorm * area; *dIeDVbe *= -GNorm * area; *dIcDVbe *= -GNorm * area;}voidNUMDcurrent(pDevice, tranAnalysis, intCoeff, id) ONEdevice *pDevice; BOOLEAN tranAnalysis; double *intCoeff; double *id;{ ONEnode *pNode; ONEelem *pElem; ONEedge *pEdge; int index; double *delta = pDevice->dcDeltaSolution; double dPsi, dN, dP, *solution; *id = 0.0; pElem = pDevice->elemArray[1]; pNode = pElem->pRightNode; pEdge = pElem->pEdge; dPsi = delta[pNode->psiEqn]; *id = pEdge->jn + pEdge->jp + pElem->epsRel * pEdge->jd; if (pElem->elemType IS SEMICON) { dN = delta[pNode->nEqn]; dP = delta[pNode->pEqn]; *id += pEdge->dJnDpsiP1 * dPsi + pEdge->dJnDnP1 * dN + pEdge->dJpDpsiP1 * dPsi + pEdge->dJpDpP1 * dP; } /* for transient analysis add the displacement term */ if (tranAnalysis) { *id -= intCoeff[0] * pElem->epsRel * pElem->rDx * dPsi; } *id *= JNorm * pDevice->area;}voidNBJTcurrent(pDevice, tranAnalysis, intCoeff, ie, ic) ONEdevice *pDevice; BOOLEAN tranAnalysis; double *intCoeff; double *ie, *ic;{ ONEnode *pNode; ONEelem *pElem; ONEedge *pEdge; int index; double dPsi, dN, dP; double *solution; solution = pDevice->dcDeltaSolution; /* first edge for calculating ie */ pElem = pDevice->elemArray[1]; pNode = pElem->pRightNode; pEdge = pElem->pEdge; dPsi = solution[pNode->psiEqn]; *ie = pEdge->jn + pEdge->jp + pElem->epsRel * pEdge->jd; if (pElem->elemType IS SEMICON) { dN = solution[pNode->nEqn]; dP = solution[pNode->pEqn]; *ie += pEdge->dJnDpsiP1 * dPsi + pEdge->dJnDnP1 * dN + pEdge->dJpDpsiP1 * dPsi + pEdge->dJpDpP1 * dP; } /* for transient analysis add the displacement term */ if (tranAnalysis) { *ie -= intCoeff[0] * pElem->epsRel * dPsi * pElem->rDx; } /* last edge for calculating ic */ pElem = pDevice->elemArray[pDevice->numNodes - 1]; pNode = pElem->pLeftNode; pEdge = pElem->pEdge; dPsi = solution[pNode->psiEqn]; *ic = pEdge->jn + pEdge->jp + pElem->epsRel * pEdge->jd; if (pElem->elemType IS SEMICON) { dN = solution[pNode->nEqn]; dP = solution[pNode->pEqn]; *ic += -pEdge->dJnDpsiP1 * dPsi + pEdge->dJnDn * dN + -pEdge->dJpDpsiP1 * dPsi + pEdge->dJpDp * dP; } if (tranAnalysis) { *ic += intCoeff[0] * pElem->epsRel * dPsi * pElem->rDx; } *ic *= -JNorm * pDevice->area; *ie *= -JNorm * pDevice->area;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -