1 /**********
2 Copyright 1991 Regents of the University of California.  All rights reserved.
3 Author:	1987 Kartikeya Mayaram, U. C. Berkeley CAD Group
4 Author:	1991 David A. Gates, U. C. Berkeley CAD Group
5 **********/
6 
7 #include "ngspice/ngspice.h"
8 #include "ngspice/numglobs.h"
9 #include "ngspice/numenum.h"
10 #include "ngspice/twomesh.h"
11 #include "twoddefs.h"
12 #include "twodext.h"
13 
14 void
nodeFields(TWOelem * pElem,TWOnode * pNode,double * ex,double * ey)15 nodeFields(TWOelem *pElem, TWOnode *pNode, double *ex, double *ey)
16 {
17 
18   TWOelem *pElemTL, *pElemTR, *pElemBL, *pElemBR;
19   TWOedge *pEdgeT, *pEdgeB, *pEdgeL, *pEdgeR;
20   int materT, materB, materL, materR;
21   double dxL = 0.0, dxR = 0.0, dyT = 0.0, dyB = 0.0;
22   double ef1, ef2, coeff1, coeff2;
23 
24   NG_IGNORE(pElem);
25 
26   /* Find all four neighboring elements */
27   pElemTL = pNode->pTLElem;
28   pElemTR = pNode->pTRElem;
29   pElemBL = pNode->pBLElem;
30   pElemBR = pNode->pBRElem;
31 
32   /* Null edge pointers */
33   pEdgeT = pEdgeB = pEdgeL = pEdgeR = NULL;
34 
35   /* Find edges next to node */
36   if (pElemTL != NULL) {
37     if (pElemTL->evalEdges[1]) {
38       pEdgeT = pElemTL->pRightEdge;
39       materT = pElemTL->elemType;
40       dyT = pElemTL->dy;
41     }
42     if (pElemTL->evalEdges[2]) {
43       pEdgeL = pElemTL->pBotEdge;
44       materL = pElemTL->elemType;
45       dxL = pElemTL->dx;
46     }
47   }
48   if (pElemTR != NULL) {
49     if (pElemTR->evalEdges[3]) {
50       pEdgeT = pElemTR->pLeftEdge;
51       materT = pElemTR->elemType;
52       dyT = pElemTR->dy;
53     }
54     if (pElemTR->evalEdges[2]) {
55       pEdgeR = pElemTR->pBotEdge;
56       materR = pElemTR->elemType;
57       dxR = pElemTR->dx;
58     }
59   }
60   if (pElemBR != NULL) {
61     if (pElemBR->evalEdges[3]) {
62       pEdgeB = pElemBR->pLeftEdge;
63       materB = pElemBR->elemType;
64       dyB = pElemBR->dy;
65     }
66     if (pElemBR->evalEdges[0]) {
67       pEdgeR = pElemBR->pTopEdge;
68       materR = pElemBR->elemType;
69       dxR = pElemBR->dx;
70     }
71   }
72   if (pElemBL != NULL) {
73     if (pElemBL->evalEdges[1]) {
74       pEdgeB = pElemBL->pRightEdge;
75       materB = pElemBL->elemType;
76       dyB = pElemBL->dy;
77     }
78     if (pElemBL->evalEdges[0]) {
79       pEdgeL = pElemBL->pTopEdge;
80       materL = pElemBL->elemType;
81       dxL = pElemBL->dx;
82     }
83   }
84   /* compute horizontal vector components */
85   /* No more than one of Left Edge or Right Edge is absent */
86   if (pEdgeL == NULL) {
87     if (pNode->nodeType == CONTACT) {
88       *ex = -pEdgeR->dPsi / dxR;
89     } else {
90       *ex = 0.0;
91     }
92   } else if (pEdgeR == NULL) {
93     if (pNode->nodeType == CONTACT) {
94       *ex = -pEdgeL->dPsi / dxL;
95     } else {
96       *ex = 0.0;
97     }
98   } else {			/* Both edges are present */
99     coeff1 = dxL / (dxL + dxR);
100     coeff2 = dxR / (dxL + dxR);
101     ef1 = -pEdgeL->dPsi / dxL;
102     ef2 = -pEdgeR->dPsi / dxR;
103     *ex = coeff2 * ef1 + coeff1 * ef2;
104   }
105 
106   /* compute vertical vector components */
107   /* No more than one of Top Edge or Bottom Edge is absent */
108   if (pEdgeT == NULL) {
109     if (pNode->nodeType == CONTACT) {
110       *ey = -pEdgeB->dPsi / dyB;
111     } else {
112       *ey = 0.0;
113     }
114   } else if (pEdgeB == NULL) {
115     if (pNode->nodeType == CONTACT) {
116       *ey = -pEdgeT->dPsi / dyT;
117     } else {
118       *ey = 0.0;
119     }
120   } else {			/* Both edges are present */
121     coeff1 = dyT / (dyT + dyB);
122     coeff2 = dyB / (dyT + dyB);
123     ef1 = -pEdgeT->dPsi / dyT;
124     ef2 = -pEdgeB->dPsi / dyB;
125     *ey = coeff2 * ef1 + coeff1 * ef2;
126   }
127 }
128