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