⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 twoadmit.c

📁 ngspice又一个电子CAD仿真软件代码.功能更全
💻 C
📖 第 1 页 / 共 3 页
字号:
	  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 + -