1 /***************************************************************************
2 JSPICE3 adaptation of Spice3f2 - Copyright (c) Stephen R. Whiteley 1992
3 Copyright 1990 Regents of the University of California.  All rights reserved.
4 Authors: 1988 Jaijeet S Roychowdhury
5          1992 Stephen R. Whiteley
6 ****************************************************************************/
7 
8 #include "spice.h"
9 #include <math.h>
10 #include <stdio.h>
11 #include "diodefs.h"
12 #include "distodef.h"
13 #include "util.h"
14 #include "sperror.h"
15 #include "distoext.h"
16 
17 int
DIOdisto(mode,genmodel,ckt)18 DIOdisto(mode,genmodel,ckt)
19 
20 /* assuming here that ckt->CKTomega has been initialised to
21  * the correct value
22  */
23 GENmodel *genmodel;
24 CKTcircuit *ckt;
25 int mode;
26 {
27     DIOmodel *model = (DIOmodel *) genmodel;
28     DISTOAN* job = (DISTOAN*) ckt->CKTcurJob;
29     double td;
30     DpassStr pass;
31     double g2,g3;
32     double cdiff2,cdiff3;
33     double cjunc2,cjunc3;
34     double r1h1x,i1h1x;
35     double r1h2x, i1h2x;
36     double r1hm2x,i1hm2x;
37     double r2h11x,i2h11x;
38     double r2h1m2x,i2h1m2x;
39     double temp, itemp;
40     DIOinstance *here;
41 
42     if (mode == D_SETUP)
43     return (DIOdSetup(model,ckt));
44 
45     if ((mode == D_TWOF1) || (mode == D_THRF1) ||
46         (mode == D_F1PF2) || (mode == D_F1MF2) ||
47         (mode == D_2F1MF2)) {
48 
49         /* loop through all the DIO models */
50         for ( ; model != NULL; model = model->DIOnextModel) {
51 
52             /* loop through all the instances of the model */
53             for (here = model->DIOinstances; here != NULL;
54                     here = here->DIOnextInstance) {
55 
56                 /* loading starts here */
57 
58                 switch (mode) {
59 
60     case D_TWOF1:
61         g2=here->id_x2;
62 
63         cdiff2=here->cdif_x2;
64 
65         cjunc2=here->cjnc_x2;
66 
67         /* getting first order (linear) Volterra kernel */
68         r1h1x = *(job->r1H1ptr + (here->DIOposPrimeNode)) -
69             *(job->r1H1ptr + (here->DIOnegNode));
70         i1h1x = *(job->i1H1ptr + (here->DIOposPrimeNode)) -
71             *(job->i1H1ptr + (here->DIOnegNode));
72 
73         /* formulae start here */
74 
75         temp = D1n2F1(g2,r1h1x,i1h1x);
76         itemp = D1i2F1(g2,r1h1x,i1h1x);
77 
78         /* the above are for the memoryless nonlinearity */
79 
80         if ((cdiff2 + cjunc2) != 0.0) {
81             temp +=  - ckt->CKTomega * D1i2F1
82                 (cdiff2+cjunc2,r1h1x,i1h1x);
83             itemp += ckt->CKTomega * D1n2F1
84                 ((cdiff2 + cjunc2),r1h1x,i1h1x);
85         }
86 
87         *(ckt->CKTrhs + (here->DIOposPrimeNode)) -= temp;
88         *(ckt->CKTirhs + (here->DIOposPrimeNode)) -= itemp;
89         *(ckt->CKTrhs + (here->DIOnegNode)) += temp;
90         *(ckt->CKTirhs + (here->DIOnegNode)) += itemp;
91 
92         break;
93 
94     case D_THRF1:
95 
96         g2=here->id_x2;
97         g3=here->id_x3;
98 
99         cdiff2=here->cdif_x2;
100         cdiff3=here->cdif_x3;
101 
102         cjunc2=here->cjnc_x2;
103         cjunc3=here->cjnc_x3;
104 
105         /* getting first order (linear) Volterra kernel */
106         r1h1x = *(job->r1H1ptr + (here->DIOposPrimeNode)) -
107             *(job->r1H1ptr + (here->DIOnegNode));
108         i1h1x = *(job->i1H1ptr + (here->DIOposPrimeNode)) -
109             *(job->i1H1ptr + (here->DIOnegNode));
110 
111         /* getting second order kernel at (F1_F1) */
112         r2h11x = *(job->r2H11ptr + (here->DIOposPrimeNode)) -
113             *(job->r2H11ptr + (here->DIOnegNode));
114         i2h11x = *(job->i2H11ptr + (here->DIOposPrimeNode)) -
115             *(job->i2H11ptr + (here->DIOnegNode));
116 
117         /* formulae start here */
118 
119         temp = D1n3F1(g2,g3,r1h1x,i1h1x,r2h11x,
120                         i2h11x);
121         itemp = D1i3F1(g2,g3,r1h1x,i1h1x,r2h11x,
122                         i2h11x);
123 
124         /* the above are for the memoryless nonlinearity */
125         /* the following are for the capacitors */
126 
127         if ((cdiff2 + cjunc2) != 0.0) {
128             temp += -ckt->CKTomega * D1i3F1
129                 (cdiff2+cjunc2,cdiff3+cjunc3,r1h1x,
130                         i1h1x,r2h11x,i2h11x);
131 
132             itemp += ckt->CKTomega * D1n3F1
133                 (cdiff2+cjunc2,cdiff3+cjunc3,r1h1x,
134                         i1h1x,r2h11x,i2h11x);
135         }
136 
137         /* end of formulae */
138 
139         *(ckt->CKTrhs + (here->DIOposPrimeNode)) -= temp;
140         *(ckt->CKTirhs + (here->DIOposPrimeNode)) -= itemp;
141         *(ckt->CKTrhs + (here->DIOnegNode)) += temp;
142         *(ckt->CKTirhs + (here->DIOnegNode)) += itemp;
143 
144         break;
145 
146     case D_F1PF2:
147 
148         g2=here->id_x2;
149         g3=here->id_x3;
150 
151         cdiff2=here->cdif_x2;
152         cdiff3=here->cdif_x3;
153 
154         cjunc2=here->cjnc_x2;
155         cjunc3=here->cjnc_x3;
156 
157         /* getting first order (linear) Volterra kernel for F1*/
158         r1h1x = *(job->r1H1ptr + (here->DIOposPrimeNode)) -
159             *(job->r1H1ptr + (here->DIOnegNode));
160         i1h1x = *(job->i1H1ptr + (here->DIOposPrimeNode)) -
161             *(job->i1H1ptr + (here->DIOnegNode));
162 
163         /* getting first order (linear) Volterra kernel for F2*/
164         r1h2x = *(job->r1H2ptr + (here->DIOposPrimeNode)) -
165             *(job->r1H2ptr + (here->DIOnegNode));
166         i1h2x = *(job->i1H2ptr + (here->DIOposPrimeNode)) -
167             *(job->i1H2ptr + (here->DIOnegNode));
168 
169         /* formulae start here */
170 
171         temp = D1nF12(g2,r1h1x,i1h1x,r1h2x,i1h2x);
172         itemp = D1iF12(g2,r1h1x,i1h1x,r1h2x,i1h2x);
173 
174         /* the above are for the memoryless nonlinearity */
175         /* the following are for the capacitors */
176 
177         if ((cdiff2 + cjunc2) != 0.0) {
178             temp += - ckt->CKTomega * D1iF12
179                 (cdiff2+cjunc2,r1h1x,i1h1x,r1h2x,i1h2x);
180             itemp += ckt->CKTomega * D1nF12
181                 (cdiff2+cjunc2,r1h1x,i1h1x,r1h2x,i1h2x);
182         }
183 
184         /* end of formulae */
185 
186         *(ckt->CKTrhs + (here->DIOposPrimeNode)) -= temp;
187         *(ckt->CKTirhs + (here->DIOposPrimeNode)) -= itemp;
188         *(ckt->CKTrhs + (here->DIOnegNode)) += temp;
189         *(ckt->CKTirhs + (here->DIOnegNode)) += itemp;
190 
191         break;
192 
193     case D_F1MF2:
194 
195         g2=here->id_x2;
196         g3=here->id_x3;
197 
198         cdiff2=here->cdif_x2;
199         cdiff3=here->cdif_x3;
200 
201         cjunc2=here->cjnc_x2;
202         cjunc3=here->cjnc_x3;
203 
204         /* getting first order (linear) Volterra kernel for F1*/
205         r1h1x = *(job->r1H1ptr + (here->DIOposPrimeNode)) -
206             *(job->r1H1ptr + (here->DIOnegNode));
207         i1h1x = *(job->i1H1ptr + (here->DIOposPrimeNode)) -
208             *(job->i1H1ptr + (here->DIOnegNode));
209 
210         /* getting first order (linear) Volterra kernel for F2*/
211         r1h2x = *(job->r1H2ptr + (here->DIOposPrimeNode)) -
212             *(job->r1H2ptr + (here->DIOnegNode));
213         i1hm2x = -(*(job->i1H2ptr + (here->DIOposPrimeNode)) -
214             *(job->i1H2ptr + (here->DIOnegNode)));
215 
216         /* formulae start here */
217 
218         temp = D1nF12(g2,r1h1x,i1h1x,r1h2x,i1hm2x);
219         itemp = D1iF12(g2,r1h1x,i1h1x,r1h2x,i1hm2x);
220 
221         /* the above are for the memoryless nonlinearity */
222         /* the following are for the capacitors */
223 
224         if ((cdiff2 + cjunc2) != 0.0) {
225             temp += - ckt->CKTomega * D1iF12
226                 (cdiff2+cjunc2,r1h1x,i1h1x,r1h2x,i1hm2x);
227             itemp += ckt->CKTomega * D1nF12
228                 (cdiff2+cjunc2,r1h1x,i1h1x,r1h2x,i1hm2x);
229         }
230 
231         /* end of formulae */
232 
233         *(ckt->CKTrhs + (here->DIOposPrimeNode)) -= temp;
234         *(ckt->CKTirhs + (here->DIOposPrimeNode)) -= itemp;
235         *(ckt->CKTrhs + (here->DIOnegNode)) += temp;
236         *(ckt->CKTirhs + (here->DIOnegNode)) += itemp;
237 
238         break;
239 
240     case D_2F1MF2:
241 
242         g2=here->id_x2;
243         g3=here->id_x3;
244 
245         cdiff2=here->cdif_x2;
246         cdiff3=here->cdif_x3;
247 
248         cjunc2=here->cjnc_x2;
249         cjunc3=here->cjnc_x3;
250 
251         /* getting first order (linear) Volterra kernel at F1*/
252         r1h1x = *(job->r1H1ptr + (here->DIOposPrimeNode)) -
253             *(job->r1H1ptr + (here->DIOnegNode));
254         i1h1x = *(job->i1H1ptr + (here->DIOposPrimeNode)) -
255             *(job->i1H1ptr + (here->DIOnegNode));
256 
257         /* getting first order (linear) Volterra kernel at minusF2*/
258         r1h2x = *(job->r1H2ptr + (here->DIOposPrimeNode)) -
259             *(job->r1H2ptr + (here->DIOnegNode));
260         i1hm2x = -(*(job->i1H2ptr + (here->DIOposPrimeNode)) -
261             *(job->i1H2ptr + (here->DIOnegNode)));
262 
263         /* getting second order kernel at (F1_F1) */
264         r2h11x = *(job->r2H11ptr + (here->DIOposPrimeNode)) -
265             *(job->r2H11ptr + (here->DIOnegNode));
266         i2h11x = *(job->i2H11ptr + (here->DIOposPrimeNode)) -
267             *(job->i2H11ptr + (here->DIOnegNode));
268 
269         /* getting second order kernel at (F1_minusF2) */
270         r2h1m2x = *(job->r2H1m2ptr + (here->DIOposPrimeNode)) -
271             *(job->r2H1m2ptr + (here->DIOnegNode));
272         i2h1m2x = *(job->i2H1m2ptr + (here->DIOposPrimeNode)) -
273             *(job->i2H1m2ptr + (here->DIOnegNode));
274 
275         /* formulae start here */
276 
277         temp = D1n2F12(g2,g3,r1h1x,i1h1x,r1h2x,
278                 i1hm2x,r2h11x,i2h11x,
279                     r2h1m2x,i2h1m2x);
280         itemp = D1i2F12(g2,g3,r1h1x,i1h1x,
281                 r1h2x,i1hm2x,r2h11x,i2h11x,
282                     r2h1m2x,i2h1m2x);
283 
284         /* the above are for the memoryless nonlinearity */
285         /* the following are for the capacitors */
286 
287         if ((cdiff2 + cjunc2) != 0.0) {
288             temp += -ckt->CKTomega *
289                 D1i2F12(cdiff2+cjunc2,cdiff3+cjunc3,
290                 r1h1x,i1h1x,r1h2x,i1hm2x,r2h11x,
291                     i2h11x,r2h1m2x,i2h1m2x);
292             itemp += ckt->CKTomega *
293                 D1n2F12(cdiff2+cjunc2,cdiff3+cjunc3,
294                 r1h1x,i1h1x,r1h2x,i1hm2x,r2h11x,
295                     i2h11x,r2h1m2x,i2h1m2x);
296         }
297 
298         /* end of formulae */
299 
300         *(ckt->CKTrhs + (here->DIOposPrimeNode)) -= temp;
301         *(ckt->CKTirhs + (here->DIOposPrimeNode)) -= itemp;
302         *(ckt->CKTrhs + (here->DIOnegNode)) += temp;
303         *(ckt->CKTirhs + (here->DIOnegNode)) += itemp;
304 
305         break;
306 
307     default:
308         ;
309                 }
310             }
311         }
312         return(OK);
313     }
314     else
315         return(E_BADPARM);
316 }
317