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

📄 twomesh.c

📁 spice中支持多层次元件模型仿真的可单独运行的插件源码
💻 C
📖 第 1 页 / 共 2 页
字号:
  /* Assign the dx and dy terms in the elements while we're at it. */  for (yIndex = 1; yIndex < numYNodes; yIndex++) {    for (xIndex = 1; xIndex < numXNodes; xIndex++) {      pElem = pDevice->elemArray[xIndex][yIndex];      if (pElem ISNOT NIL(TWOelem)) {	pElem->dx = xScale[xIndex + 1] - xScale[xIndex];	pElem->dy = yScale[yIndex + 1] - yScale[yIndex];	pElem->dxOverDy = pElem->dx / pElem->dy;	pElem->dyOverDx = pElem->dy / pElem->dx;	/*	 * Semiconductor elements take precedence over Insulator elements, so	 * set them up first.	 */	for (index = 0; index <= 3; index++) {	  if (pElem->elemType IS SEMICON) {	    pNode = pElem->pNodes[index];	    if (NOT pNode->evaluated) {	      pNode->evaluated = TRUE;	      pElem->evalNodes[index] = TRUE;	    } else {	      pElem->evalNodes[index] = FALSE;	    }	    pEdge = pElem->pEdges[index];	    if (NOT pEdge->evaluated) {	      pEdge->evaluated = TRUE;	      pElem->evalEdges[index] = TRUE;	    } else {	      pElem->evalEdges[index] = FALSE;	    }	  }	}      }    }  }  /* Do a second setup pass for Insulator elements */  /* Do mobility coefficients now, because we set up dx and dy   * in the previous pass   */  for (yIndex = 1; yIndex < numYNodes; yIndex++) {    for (xIndex = 1; xIndex < numXNodes; xIndex++) {      pElem = pDevice->elemArray[xIndex][yIndex];      if (pElem ISNOT NIL(TWOelem)) {	pElem->direction = 0;	pElem->channel = 0;	pElem->surface = FALSE;	for (index = 0; index <= 3; index++) {	  if (pElem->elemType IS SEMICON) {	    doMobCoeffs( pElem, index );	  } else if (pElem->elemType IS INSULATOR) {	    pNode = pElem->pNodes[index];	    if (NOT pNode->evaluated) {	      pNode->evaluated = TRUE;	      pElem->evalNodes[index] = TRUE;	    } else {	      pElem->evalNodes[index] = FALSE;	    }	    pEdge = pElem->pEdges[index];	    if (NOT pEdge->evaluated) {	      pEdge->evaluated = TRUE;	      pElem->evalEdges[index] = TRUE;	    } else {	      pElem->evalEdges[index] = FALSE;	    }	  }	}      }    }  }  /* Set up the equation numbers for nodes. */  poiEqn = numEqn = 1;  for (eIndex = 1; eIndex <= pDevice->numElems; eIndex++) {    pElem = pDevice->elements[eIndex];    for (index = 0; index <= 3; index++) {      if (pElem->evalNodes[index]) {	pNode = pElem->pNodes[index];	if (pNode->nodeType ISNOT CONTACT) {	  /* First assign potential equation numbers */	  if (pNode->nodeType ISNOT SCHOTTKY) {	    pNode->poiEqn = poiEqn++;	    pNode->psiEqn = numEqn++;	  }	  /* Now assign carrier-concentration equation numbers */	  if (pElem->elemType IS INSULATOR) {	    pNode->nEqn = 0;	    pNode->pEqn = 0;	  } else {	    if (OneCarrier) {	      /* n and p get same number */	      pNode->nEqn = numEqn;	      pNode->pEqn = numEqn++;	    } else {	      pNode->nEqn = numEqn++;	      pNode->pEqn = numEqn++;	    }	  }	} else {		/* This is a contact node. */	  pNode->poiEqn = 0;	  pNode->psiEqn = 0;	  pNode->nEqn = 0;	  pNode->pEqn = 0;	}      }    }  }  pDevice->dimEquil = poiEqn;  pDevice->dimBias = numEqn;  /* Open and Print Mesh Output File for Debugging */  /* Nuked from release version */#ifdef NOTDEF  if (!(meshFile = fopen("mesh.out", "w"))) {    perror("mesh.out");    exit(-1);  }  for (eIndex = 1; eIndex <= pDevice->numElems; eIndex++) {    pElem = pDevice->elements[eIndex];    for (index = 0; index <= 3; index++) {      if (pElem->evalNodes[index]) {	pNode = pElem->pNodes[index];	fprintf(meshFile, "node: %5d %5d %5d %5d\n", pNode->nodeI,	    pNode->nodeJ, pNode->poiEqn, pNode->psiEqn);      }    }  }  fflush(meshFile);  fclose(meshFile);#endif  /* Delete work arrays. */  for (xIndex = 1; xIndex <= numXNodes; xIndex++) {    FREE(nodeArray[xIndex]);    FREE(edgeArrayV[xIndex]);  }  for (xIndex = 1; xIndex < numXNodes; xIndex++) {    FREE(edgeArrayH[xIndex]);  }  FREE(nodeArray);  FREE(edgeArrayV);  FREE(edgeArrayH);  /*   * TWOprnMesh( pDevice );   */}intTWOprnMesh(pDevice)  TWOdevice *pDevice;{  int eIndex, index;  TWOelem *pElem;  TWOnode *pNode;  TWOedge *pEdge;  char *name;  for (eIndex = 1; eIndex <= pDevice->numElems; eIndex++) {    pElem = pDevice->elements[eIndex];    fprintf(stderr, "elem %5d:\n", eIndex);    for (index = 0; index <= 3; index++) {      if (pElem->evalNodes[index]) {	pNode = pElem->pNodes[index];	switch (pNode->nodeType) {	case SEMICON:	  name = "semiconductor";	  break;	case INSULATOR:	  name = "insulator";	  break;	case CONTACT:	  name = "contact";	  break;	case SCHOTTKY:	  name = "schottky";	  break;	case INTERFACE:	  name = "interface";	  break;	default:	  name = "unknown";	  break;	}	fprintf(stderr, "node %5d: %s %5d %5d\n", index, name,	    pNode->nodeI, pNode->nodeJ);      }      if (pElem->evalEdges[index]) {	pEdge = pElem->pEdges[index];	switch (pEdge->edgeType) {	case SEMICON:	  name = "semiconductor";	  break;	case INSULATOR:	  name = "insulator";	  break;	case CONTACT:	  name = "contact";	  break;	case SCHOTTKY:	  name = "schottky";	  break;	case INTERFACE:	  name = "interface";	  break;	default:	  name = "unknown";	  break;	}	fprintf(stderr, "edge %5d: %s\n", index, name);      }    }  }}/* * We have a separate function for this, so that the setup routines can * reset the state pointers without rebuilding the entire mesh. */voidTWOgetStatePointers( pDevice, numStates )TWOdevice *pDevice;int *numStates;{  int eIndex, index;  TWOelem *pElem;  TWOnode *pNode;  TWOedge *pEdge;  for (eIndex = 1; eIndex <= pDevice->numElems; eIndex++) {    pElem = pDevice->elements[eIndex];    for (index = 0; index <= 3; index++) {      if (pElem->evalNodes[index]) {	pNode = pElem->pNodes[index];	pNode->nodeState = *numStates;	*numStates += TWOnumNodeStates;      }      if (pElem->evalEdges[index]) {	pEdge = pElem->pEdges[index];	pEdge->edgeState = *numStates;	*numStates += TWOnumEdgeStates;      }    }  }}/* * This function computes the percentages of the total semiconductor * width of an edge on the negative and positive sides of the edge */static voiddoMobCoeffs( pElem, index )TWOelem *pElem;int index;{  TWOelem *pNElem;  TWOedge *pEdge;  double dl1, dl2;  pNElem = pElem->pElems[ index ];  pEdge = pElem->pEdges[ index ];  /* If neighbor is not SEMICON, assign and return */  if ( pNElem IS NIL(TWOelem) OR pNElem->elemType IS INSULATOR ) {    if ( index IS 0 OR index IS 3 ) {      pEdge->kNeg = 0.0;      pEdge->kPos = 1.0;    } else {      pEdge->kNeg = 1.0;      pEdge->kPos = 0.0;    }    return;  }  /* Find appropriate dimensions of the elements */  switch ( index ) {  case 0:    dl1 = pNElem->dy;    dl2 = pElem->dy;    break;  case 1:    dl1 = pElem->dx;    dl2 = pNElem->dx;    break;  case 2:    dl1 = pElem->dy;    dl2 = pNElem->dy;    break;  case 3:    dl1 = pNElem->dx;    dl2 = pElem->dx;    break;  }  /* Assign coefficients */  pEdge->kNeg = dl1 / (dl1 + dl2);  pEdge->kPos = dl2 / (dl1 + dl2);}static void resetEvalFlag(pDevice)  TWOdevice *pDevice;{  int index, eIndex;  TWOelem *pElem;  for (eIndex = 1; eIndex <= pDevice->numElems; eIndex++) {    pElem = pDevice->elements[eIndex];    for (index = 0; index <= 3; index++) {      pElem->pNodes[index]->evaluated = FALSE;      pElem->pEdges[index]->evaluated = FALSE;    }  }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -