📄 twomesh.c
字号:
/* 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 + -