2003-08-11 21:25:28 +02:00
|
|
|
/**********
|
|
|
|
|
Copyright 1991 Regents of the University of California. All rights reserved.
|
|
|
|
|
Author: 1987 Kartikeya Mayaram, U. C. Berkeley CAD Group
|
|
|
|
|
Author: 1991 David A. Gates, U. C. Berkeley CAD Group
|
|
|
|
|
**********/
|
|
|
|
|
|
2011-12-11 19:05:00 +01:00
|
|
|
#include "ngspice/ngspice.h"
|
|
|
|
|
#include "ngspice/numglobs.h"
|
|
|
|
|
#include "ngspice/numenum.h"
|
|
|
|
|
#include "ngspice/twomesh.h"
|
2003-08-11 21:25:28 +02:00
|
|
|
#include "twoddefs.h"
|
|
|
|
|
#include "twodext.h"
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
nodeFields(TWOelem *pElem, TWOnode *pNode, double *ex, double *ey)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
TWOelem *pElemTL, *pElemTR, *pElemBL, *pElemBR;
|
|
|
|
|
TWOedge *pEdgeT, *pEdgeB, *pEdgeL, *pEdgeR;
|
|
|
|
|
int materT, materB, materL, materR;
|
|
|
|
|
double dxL = 0.0, dxR = 0.0, dyT = 0.0, dyB = 0.0;
|
|
|
|
|
double ef1, ef2, coeff1, coeff2;
|
|
|
|
|
|
2010-11-16 21:38:24 +01:00
|
|
|
NG_IGNORE(pElem);
|
2010-11-16 20:11:32 +01:00
|
|
|
|
2003-08-11 21:25:28 +02:00
|
|
|
/* Find all four neighboring elements */
|
|
|
|
|
pElemTL = pNode->pTLElem;
|
|
|
|
|
pElemTR = pNode->pTRElem;
|
|
|
|
|
pElemBL = pNode->pBLElem;
|
|
|
|
|
pElemBR = pNode->pBRElem;
|
|
|
|
|
|
|
|
|
|
/* Null edge pointers */
|
2013-07-18 20:52:57 +02:00
|
|
|
pEdgeT = pEdgeB = pEdgeL = pEdgeR = NULL;
|
2003-08-11 21:25:28 +02:00
|
|
|
|
|
|
|
|
/* Find edges next to node */
|
2013-07-18 20:52:57 +02:00
|
|
|
if (pElemTL != NULL) {
|
2003-08-11 21:25:28 +02:00
|
|
|
if (pElemTL->evalEdges[1]) {
|
|
|
|
|
pEdgeT = pElemTL->pRightEdge;
|
|
|
|
|
materT = pElemTL->elemType;
|
|
|
|
|
dyT = pElemTL->dy;
|
|
|
|
|
}
|
|
|
|
|
if (pElemTL->evalEdges[2]) {
|
|
|
|
|
pEdgeL = pElemTL->pBotEdge;
|
|
|
|
|
materL = pElemTL->elemType;
|
|
|
|
|
dxL = pElemTL->dx;
|
|
|
|
|
}
|
|
|
|
|
}
|
2013-07-18 20:52:57 +02:00
|
|
|
if (pElemTR != NULL) {
|
2003-08-11 21:25:28 +02:00
|
|
|
if (pElemTR->evalEdges[3]) {
|
|
|
|
|
pEdgeT = pElemTR->pLeftEdge;
|
|
|
|
|
materT = pElemTR->elemType;
|
|
|
|
|
dyT = pElemTR->dy;
|
|
|
|
|
}
|
|
|
|
|
if (pElemTR->evalEdges[2]) {
|
|
|
|
|
pEdgeR = pElemTR->pBotEdge;
|
|
|
|
|
materR = pElemTR->elemType;
|
|
|
|
|
dxR = pElemTR->dx;
|
|
|
|
|
}
|
|
|
|
|
}
|
2013-07-18 20:52:57 +02:00
|
|
|
if (pElemBR != NULL) {
|
2003-08-11 21:25:28 +02:00
|
|
|
if (pElemBR->evalEdges[3]) {
|
|
|
|
|
pEdgeB = pElemBR->pLeftEdge;
|
|
|
|
|
materB = pElemBR->elemType;
|
|
|
|
|
dyB = pElemBR->dy;
|
|
|
|
|
}
|
|
|
|
|
if (pElemBR->evalEdges[0]) {
|
|
|
|
|
pEdgeR = pElemBR->pTopEdge;
|
|
|
|
|
materR = pElemBR->elemType;
|
|
|
|
|
dxR = pElemBR->dx;
|
|
|
|
|
}
|
|
|
|
|
}
|
2013-07-18 20:52:57 +02:00
|
|
|
if (pElemBL != NULL) {
|
2003-08-11 21:25:28 +02:00
|
|
|
if (pElemBL->evalEdges[1]) {
|
|
|
|
|
pEdgeB = pElemBL->pRightEdge;
|
|
|
|
|
materB = pElemBL->elemType;
|
|
|
|
|
dyB = pElemBL->dy;
|
|
|
|
|
}
|
|
|
|
|
if (pElemBL->evalEdges[0]) {
|
|
|
|
|
pEdgeL = pElemBL->pTopEdge;
|
|
|
|
|
materL = pElemBL->elemType;
|
|
|
|
|
dxL = pElemBL->dx;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/* compute horizontal vector components */
|
|
|
|
|
/* No more than one of Left Edge or Right Edge is absent */
|
2013-07-18 20:52:57 +02:00
|
|
|
if (pEdgeL == NULL) {
|
2003-08-11 21:25:28 +02:00
|
|
|
if (pNode->nodeType == CONTACT) {
|
|
|
|
|
*ex = -pEdgeR->dPsi / dxR;
|
|
|
|
|
} else {
|
|
|
|
|
*ex = 0.0;
|
|
|
|
|
}
|
2013-07-18 20:52:57 +02:00
|
|
|
} else if (pEdgeR == NULL) {
|
2003-08-11 21:25:28 +02:00
|
|
|
if (pNode->nodeType == CONTACT) {
|
|
|
|
|
*ex = -pEdgeL->dPsi / dxL;
|
|
|
|
|
} else {
|
|
|
|
|
*ex = 0.0;
|
|
|
|
|
}
|
|
|
|
|
} else { /* Both edges are present */
|
|
|
|
|
coeff1 = dxL / (dxL + dxR);
|
|
|
|
|
coeff2 = dxR / (dxL + dxR);
|
|
|
|
|
ef1 = -pEdgeL->dPsi / dxL;
|
|
|
|
|
ef2 = -pEdgeR->dPsi / dxR;
|
|
|
|
|
*ex = coeff2 * ef1 + coeff1 * ef2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* compute vertical vector components */
|
|
|
|
|
/* No more than one of Top Edge or Bottom Edge is absent */
|
2013-07-18 20:52:57 +02:00
|
|
|
if (pEdgeT == NULL) {
|
2003-08-11 21:25:28 +02:00
|
|
|
if (pNode->nodeType == CONTACT) {
|
|
|
|
|
*ey = -pEdgeB->dPsi / dyB;
|
|
|
|
|
} else {
|
|
|
|
|
*ey = 0.0;
|
|
|
|
|
}
|
2013-07-18 20:52:57 +02:00
|
|
|
} else if (pEdgeB == NULL) {
|
2003-08-11 21:25:28 +02:00
|
|
|
if (pNode->nodeType == CONTACT) {
|
|
|
|
|
*ey = -pEdgeT->dPsi / dyT;
|
|
|
|
|
} else {
|
|
|
|
|
*ey = 0.0;
|
|
|
|
|
}
|
|
|
|
|
} else { /* Both edges are present */
|
|
|
|
|
coeff1 = dyT / (dyT + dyB);
|
|
|
|
|
coeff2 = dyB / (dyT + dyB);
|
|
|
|
|
ef1 = -pEdgeT->dPsi / dyT;
|
|
|
|
|
ef2 = -pEdgeB->dPsi / dyB;
|
|
|
|
|
*ey = coeff2 * ef1 + coeff1 * ef2;
|
|
|
|
|
}
|
|
|
|
|
}
|