Jspice3
jjload.c
Go to the documentation of this file.
1 /***************************************************************************
2 JSPICE3 adaptation of Spice3f2 - Copyright (c) Stephen R. Whiteley 1992
3 Author: 1993 Stephen R. Whiteley
4 ****************************************************************************/
5 
6 #include "spice.h"
7 #include <stdio.h>
8 #include "jjdefs.h"
9 #include "const.h"
10 #include "sperror.h"
11 #include "util.h"
12 #include "niext.h"
13 
14 #if __GNUC__
15 #ifdef i386
16 #define ASM_SINCOS
17 #endif
18 #endif
19 
20 struct jjstuff {
21  double js_vj;
22  double js_phi;
23  double js_ci;
24  double js_gqt;
25  double js_crhs;
26  double js_crt;
27  double js_dcrt;
28  double js_pfac;
29  double js_ddv;
30 };
31 
32 
33 #ifdef __STDC__
34 static void jj_limiting(CKTcircuit*,JJmodel*,JJinstance*,struct jjstuff*);
35 static void jj_iv(JJmodel*,JJinstance*,struct jjstuff*);
36 static void jj_ic(JJmodel*,JJinstance*,struct jjstuff*);
37 static void jj_load(CKTcircuit*,JJmodel*,JJinstance*,struct jjstuff*);
38 #else
39 static void jj_limiting();
40 static void jj_iv();
41 static void jj_ic();
42 static void jj_load();
43 #endif
44 
45 
46 int
47 JJload(inModel,ckt)
48 
49 GENmodel *inModel;
50 CKTcircuit *ckt;
51 {
52 
53  JJmodel *model = (JJmodel *)inModel;
54  JJinstance *here;
55  struct jjstuff js;
56  double absvj;
57  double temp;
58  int error; /* used in NI_SUM macro */
59 
60  if (ckt->CKTmode & MODEDC)
61  return (OK);
62 
63  js.js_pfac = ckt->CKTdelta / JJcphi;
64  if (ckt->CKTorder > 1)
65  js.js_pfac *= .5;
66 
67  if (ckt->CKTmode & MODEINITFLOAT) {
68  double absold, absdvj, maxvj;
69 
70  for ( ; model != NULL; model = model->JJnextModel) {
71 
72  for (here = model->JJinstances; here != NULL;
73  here = here->JJnextInstance) {
74 
75  js.js_ci = (here->JJcontrol) ?
76  *(ckt->CKTrhsOld + here->JJbranch) : 0;
77 
78  js.js_vj = *(ckt->CKTrhsOld + here->JJposNode) -
79  *(ckt->CKTrhsOld + here->JJnegNode);
80 
81  absvj = js.js_vj < 0 ? -js.js_vj : js.js_vj;
82  temp = *(ckt->CKTstate0 + here->JJvoltage);
83  absold = temp < 0 ? -temp : temp;
84  maxvj = MAX(absvj,absold);
85  temp -= js.js_vj;
86  absdvj = temp < 0 ? -temp : temp;
87 
88  if (maxvj >= model->JJvless) {
89  temp = model->JJdelv * 0.5;
90  if (absdvj > temp) {
91  js.js_ddv = temp;
92  jj_limiting(ckt,model,here,&js);
93  absvj = js.js_vj < 0 ? -js.js_vj : js.js_vj;
94  maxvj = MAX(absvj,absold);
95  temp = js.js_vj -
96  *(ckt->CKTstate0 + here->JJvoltage);
97  absdvj = temp < 0 ? -temp : temp;
98  }
99  }
100 
101  /* check convergence */
102 
103  if (!ckt->CKTnoncon) {
104  double tol;
105 
106  tol = ckt->CKTreltol*maxvj + ckt->CKTabstol;
107  if (absdvj > tol) {
108  ckt->CKTnoncon++;
109  }
110  }
111 
112  js.js_phi = *(ckt->CKTstate1 + here->JJphase);
113  temp = js.js_vj;
114  if (ckt->CKTorder > 1)
115  temp += *(ckt->CKTstate1 + here->JJvoltage);
116  js.js_phi += js.js_pfac*temp;
117 
118  js.js_crhs = 0;
119  js.js_dcrt = 0;
120  js.js_crt = here->JJcriti;
121 
122  /*
123  * compute quasiparticle current and derivatives
124  */
125  if (model->JJrtype == 1) {
126 
127  if (absvj < model->JJvless)
128  js.js_gqt = here->JJg0;
129  else if (absvj < model->JJvmore) {
130  js.js_gqt = here->JJgs;
131  if (js.js_vj >= 0)
132  js.js_crhs =
133  (here->JJg0 - js.js_gqt)*model->JJvless;
134  else
135  js.js_crhs =
136  (js.js_gqt - here->JJg0)*model->JJvless;
137  }
138  else
139  js.js_gqt = here->JJgn;
140  }
141  else {
142  jj_iv(model,here,&js);
143  }
144  if (model->JJictype != 1) {
145  jj_ic(model,here,&js);
146  }
147  jj_load(ckt,model,here,&js);
148  }
149  }
150  return (OK);
151  }
152 
153  if (ckt->CKTmode & MODEINITPRED) {
154  double y0, y1, y2, y3, rag0, *dtfac;
155 
156  rag0 = ckt->CKTorder == 1 ? ckt->CKTdelta : .5*ckt->CKTdelta;
157  dtfac = ckt->CKTpred;
158 
159  for ( ; model != NULL; model = model->JJnextModel) {
160 
161  for (here = model->JJinstances; here != NULL;
162  here = here->JJnextInstance) {
163 
164  y1 = *(ckt->CKTstate1 + here->JJdvdt);
165  y2 = *(ckt->CKTstate2 + here->JJdvdt);
166  y3 = *(ckt->CKTstate3 + here->JJdvdt);
167 
168  y0 = y1*dtfac[0] + y2*dtfac[1] + y3*dtfac[2]
169  + *(ckt->CKTstate0 + here->JJdvdt)*dtfac[3];
170 
171  temp = *(ckt->CKTstate1 + here->JJvoltage);
172  if (ckt->CKTorder != 1)
173  y0 += y1;
174  js.js_vj = temp + rag0*y0;
175 
176  js.js_phi = *(ckt->CKTstate1 + here->JJphase);
177  temp = js.js_vj;
178  if (ckt->CKTorder > 1)
179  temp += *(ckt->CKTstate1 + here->JJvoltage);
180  js.js_phi += js.js_pfac*temp;
181 
182  if (here->JJcontrol) {
183 
184  y1 = *(ckt->CKTstate1 + here->JJconI);
185  y2 = *(ckt->CKTstate2 + here->JJconI);
186  y3 = *(ckt->CKTstate3 + here->JJconI);
187 
188  js.js_ci = y1*dtfac[0] + y2*dtfac[1] + y3*dtfac[2]
189  + *(ckt->CKTstate0 + here->JJconI)*dtfac[3];
190  }
191  else {
192  js.js_ci = 0;
193  }
194 
195  NI_SUM(ckt,here->JJdelVdelT,here->JJvoltage);
196 
197  js.js_crhs = 0;
198  js.js_dcrt = 0;
199  js.js_crt = here->JJcriti;
200 
201  if (model->JJrtype == 1) {
202  absvj = js.js_vj < 0 ? -js.js_vj : js.js_vj;
203 
204  if (absvj < model->JJvless)
205  js.js_gqt = here->JJg0;
206  else if (absvj < model->JJvmore) {
207  js.js_gqt = here->JJgs;
208  if (js.js_vj >= 0)
209  js.js_crhs =
210  (here->JJg0 - js.js_gqt)*model->JJvless;
211  else
212  js.js_crhs =
213  (js.js_gqt - here->JJg0)*model->JJvless;
214  }
215  else
216  js.js_gqt = here->JJgn;
217  }
218  else {
219  jj_iv(model,here,&js);
220  }
221  if (model->JJictype != 1) {
222  jj_ic(model,here,&js);
223  }
224  jj_load(ckt,model,here,&js);
225  }
226  }
227  return (OK);
228  }
229 
230  if (ckt->CKTmode & MODEINITTRAN) {
231 
232  for ( ; model != NULL; model = model->JJnextModel) {
233 
234  for (here = model->JJinstances; here != NULL;
235  here = here->JJnextInstance) {
236 
237  js.js_vj = here->JJinitVoltage;
238  js.js_phi = here->JJinitPhase;
239  js.js_ci = here->JJinitControl;
240 
241  *(ckt->CKTstate1 + here->JJvoltage) = js.js_vj;
242  *(ckt->CKTstate1 + here->JJphase) = js.js_phi;
243  *(ckt->CKTstate1 + here->JJconI) = js.js_ci;
244 
245  NI_SUM(ckt,here->JJdelVdelT,here->JJvoltage);
246 
247  js.js_crhs = 0;
248  js.js_dcrt = 0;
249  js.js_crt = here->JJcriti;
250 
251  if (model->JJrtype == 1) {
252  absvj = js.js_vj < 0 ? -js.js_vj : js.js_vj;
253 
254  if (absvj < model->JJvless)
255  js.js_gqt = here->JJg0;
256  else if (absvj < model->JJvmore) {
257  js.js_gqt = here->JJgs;
258  if (js.js_vj >= 0)
259  js.js_crhs =
260  (here->JJg0 - js.js_gqt)*model->JJvless;
261  else
262  js.js_crhs =
263  (js.js_gqt - here->JJg0)*model->JJvless;
264  }
265  else
266  js.js_gqt = here->JJgn;
267  }
268  else {
269  jj_iv(model,here,&js);
270  }
271  if (model->JJictype != 1) {
272  jj_ic(model,here,&js);
273  }
274  jj_load(ckt,model,here,&js);
275  }
276  }
277  }
278  return (OK);
279 }
280 
281 
282 static void
283 jj_limiting(ckt,model,here,js)
284 
285 CKTcircuit *ckt;
286 JJmodel *model;
287 JJinstance *here;
288 struct jjstuff *js;
289 {
290  double vprev;
291  double absold;
292  double vtop;
293  double vbot;
294 
295  /* limit new junction voltage */
296 
297  vprev = *(ckt->CKTstate0 + here->JJvoltage);
298  absold = vprev < 0 ? -vprev : vprev;
299 
300  vtop = vprev + js->js_ddv;
301  vbot = vprev - js->js_ddv;
302  if (absold < model->JJvless) {
303  vtop = MAX(vtop,model->JJvless);
304  vbot = MIN(vbot,-model->JJvless);
305  }
306  else if (vprev > model->JJvmore) {
307  vtop += 1.0;
308  vbot = MIN(vbot,model->JJvmore);
309  }
310  else if (vprev < -model->JJvmore) {
311  vtop = MAX(vtop,-model->JJvmore);
312  vbot -= 1.0;
313  }
314  if (js->js_vj > vtop)
315  js->js_vj = vtop;
316  else if (js->js_vj < vbot)
317  js->js_vj = vbot;
318 }
319 
320 
321 static void
322 jj_iv(model,here,js)
323 
324 JJmodel *model;
325 JJinstance *here;
326 struct jjstuff *js;
327 {
328  double vj;
329  double absvj;
330 
331  vj = js->js_vj;
332  absvj = vj < 0 ? -vj : vj;
333 
334  if (model->JJrtype == 3) {
335 
336  if (absvj < model->JJvmore) {
337  /* cj = g0*vj + g1*vj**3 + g2*vj**5,
338  * crhs = cj - vj*gqt
339  */
340  double temp1 = vj*vj;
341  double temp2 = temp1*temp1;
342  js->js_gqt = here->JJg0 + 3.0*here->JJg1*temp1 +
343  5.0*here->JJg2*temp2;
344  temp1 *= vj;
345  temp2 *= vj;
346  js->js_crhs = -2.0*temp1*here->JJg1 - 4.0*temp2*here->JJg2;
347  }
348  else
349  js->js_gqt = here->JJgn;
350  }
351 
352  else if (model->JJrtype == 2) {
353  double avj, gam, expgam, exngam, xp, xn;
354 
355  avj = absvj / model->JJdelv;
356  gam = avj - model->JJvg/model->JJdelv;
357  if (gam > 30.0) gam = 30.0;
358  if (gam < -30.0) gam = -30.0;
359  expgam = exp(gam);
360  exngam = 1.0 / expgam;
361  xp = 1.0 + expgam;
362  xn = 1.0 + exngam;
363  js->js_crhs = vj*(here->JJg0 + here->JJgn*expgam)/xp;
364  js->js_gqt = here->JJgn*(xn + avj*exngam)/(xn*xn) +
365  here->JJg0*(xp - avj*expgam)/(xp*xp);
366  js->js_crhs -= js->js_gqt*vj;
367  }
368 
369  else if (model->JJrtype == 4) {
370  double vless, vmore, vg, gs;
371  double temp = 1;
372 
373  if (here->JJcontrol)
374  temp = js->js_ci < 0 ? -js->js_ci : js->js_ci;
375  if (temp > 1) temp = 1;
376  js->js_crt *= temp;
377  gs = here->JJgs*temp;
378  if (gs < here->JJgn)
379  gs = here->JJgn;
380  vg = model->JJvg*temp;
381  temp = .5*model->JJdelv;
382  vless = vg - temp;
383  vmore = vg + temp;
384 
385  if (vless > 0) {
386  if (absvj < vless)
387  js->js_gqt = here->JJg0;
388  else if (absvj < vmore) {
389  js->js_gqt = gs;
390  if (vj >= 0)
391  js->js_crhs = (here->JJg0 - js->js_gqt)*vless;
392  else
393  js->js_crhs = (js->js_gqt - here->JJg0)*vless;
394  }
395  else
396  js->js_gqt = here->JJgn;
397  }
398  else
399  js->js_gqt = here->JJgn;
400 
401  if (model->JJictype > 1) model->JJictype = 0;
402  }
403  else {
404  js->js_gqt = 0;
405  }
406 }
407 
408 
409 static void
410 jj_ic(model,here,js)
411 
412 /* Nondefault supercurrent
413  * For shaped junction types, parameters scale with
414  * area as in small junctions, control current does not scale.
415  */
416 JJmodel *model;
417 JJinstance *here;
418 struct jjstuff *js;
419 {
420  double ci;
421  double temp;
422 
423  ci = js->js_ci;
424 
425  if (model->JJictype == 2) {
426 
427  if (ci != 0.0) {
428  double ang, xx = js->js_crt;
429  ang = M_PI * ci / model->JJccsens;
430  js->js_crt *= sin(ang)/ang;
431  js->js_dcrt = xx*(cos(ang) - js->js_crt)/ci;
432  }
433  }
434 
435  else if (model->JJictype == 3) {
436 
437  temp = ci < 0 ? -ci : ci;
438  if (temp < model->JJccsens) {
439  js->js_dcrt = js->js_crt / model->JJccsens;
440  js->js_crt *= (1.0 - temp/model->JJccsens);
441  if (ci > 0.0) js->js_dcrt = -js->js_dcrt;
442  if (ci == 0.0) js->js_dcrt = 0.0;
443  }
444  else js->js_crt = 0.0;
445  }
446 
447  else if (model->JJictype == 4) {
448 
449  temp = ci < 0 ? -ci : ci;
450  if (temp < model->JJccsens) {
451  temp = model->JJccsens + model->JJccsens;
452  js->js_dcrt = -js->js_crt / temp;
453  js->js_crt *= (model->JJccsens - ci)/temp;
454  if (ci == 0.0) js->js_dcrt = 0.0;
455  }
456  else js->js_crt = 0.0;
457  }
458  else {
459  js->js_crt = 0.0;
460  }
461 }
462 
463 
464 static void
465 jj_load(ckt,model,here,js)
466 
467 CKTcircuit *ckt;
468 JJmodel *model;
469 JJinstance *here;
470 struct jjstuff *js;
471 {
472  double si;
473  double gcs;
474  double gqt;
475  double crhs;
476  double crt;
477  double temp;
478 
479  gqt = js->js_gqt;
480  crhs = js->js_crhs;
481  crt = js->js_crt;
482 
483  *(ckt->CKTstate0 + here->JJvoltage) = js->js_vj;
484  *(ckt->CKTstate0 + here->JJphase) = js->js_phi;
485  *(ckt->CKTstate0 + here->JJconI) = js->js_ci;
486 
487 #ifdef ASM_SINCOS
488  asm("fsincos" : "=t" (temp), "=u" (si) : "0" (js->js_phi));
489  /*
490  sincos(js->js_phi,&si,&temp);
491  */
492  gcs = js->js_pfac*crt*temp;
493 #else
494  gcs = js->js_pfac*crt*cos(js->js_phi);
495  si = sin(js->js_phi);
496 #endif
497 
498  crt *= si;
499  crhs += crt - gcs*js->js_vj;
500  gqt += gcs + ckt->CKTag[0]*here->JJcap;
501  crhs += here->JJdelVdelT*here->JJcap;
502 
503  /* load matrix, rhs vector */
504  if (here->JJphsNode)
505  *(ckt->CKTrhs + here->JJphsNode) = js->js_phi +
506  (2*M_PI)* *(int*)(ckt->CKTstate1 + here->JJphsInt);
507 
508  if (!here->JJnegNode) {
509  *(here->JJposPosPtr) += gqt;
510  if (!here->JJcontrol) {
511  *(ckt->CKTrhs + here->JJposNode) -= crhs;
512  }
513  else {
514  temp = js->js_dcrt*si;
515  *(here->JJposIbrPtr) += temp;
516  crhs -= temp*js->js_ci;
517  *(ckt->CKTrhs + here->JJposNode) -= crhs;
518  }
519  }
520  else if (!here->JJposNode) {
521  *(here->JJnegNegPtr) += gqt;
522  if (!here->JJcontrol) {
523  *(ckt->CKTrhs + here->JJnegNode) += crhs;
524  }
525  else {
526  temp = js->js_dcrt*si;
527  *(here->JJnegIbrPtr) -= temp;
528  crhs -= temp*js->js_ci;
529  *(ckt->CKTrhs + here->JJnegNode) += crhs;
530  }
531  }
532  else {
533  *(here->JJposPosPtr) += gqt;
534  *(here->JJposNegPtr) -= gqt;
535  *(here->JJnegPosPtr) -= gqt;
536  *(here->JJnegNegPtr) += gqt;
537  if (!here->JJcontrol) {
538  *(ckt->CKTrhs + here->JJposNode) -= crhs;
539  *(ckt->CKTrhs + here->JJnegNode) += crhs;
540  }
541  else {
542  temp = js->js_dcrt*si;
543  *(here->JJposIbrPtr) += temp;
544  *(here->JJnegIbrPtr) -= temp;
545  crhs -= temp*js->js_ci;
546  *(ckt->CKTrhs + here->JJposNode) -= crhs;
547  *(ckt->CKTrhs + here->JJnegNode) += crhs;
548  }
549  }
550 }
double JJg1
Definition: jjdefs.h:44
IFuid JJcontrol
Definition: jjdefs.h:27
double JJcap
Definition: jjdefs.h:40
double JJinitControl
Definition: jjdefs.h:34
#define MODEINITPRED
Definition: cktdefs.h:161
#define MODEDC
Definition: cktdefs.h:149
#define MAX(a, b)
Definition: spdefs.h:135
double JJdelv
Definition: jjdefs.h:91
double CKTdelta
Definition: cktdefs.h:78
#define MIN(a, b)
Definition: spdefs.h:136
#define MODEINITFLOAT
Definition: cktdefs.h:156
#define MODEINITTRAN
Definition: cktdefs.h:160
#define M_PI
Definition: spice.h:132
#define NI_SUM(ckt, ceq, qcap)
Definition: devdefs.h:130
double JJvless
Definition: jjdefs.h:97
double js_pfac
Definition: jjload.c:28
int JJphsNode
Definition: jjdefs.h:25
double CKTreltol
Definition: cktdefs.h:183
double js_dcrt
Definition: jjload.c:27
Definition: jjload.c:20
double js_crt
Definition: jjload.c:26
double * JJnegPosPtr
Definition: jjdefs.h:49
int JJposNode
Definition: jjdefs.h:23
static void jj_limiting()
JJinstance * JJinstances
Definition: jjdefs.h:84
int CKTorder
Definition: cktdefs.h:87
int JJnegNode
Definition: jjdefs.h:24
double CKTpred[4]
Definition: cktdefs.h:105
#define JJcphi
Definition: jjdefs.h:117
double CKTabstol
Definition: cktdefs.h:180
#define OK
Definition: iferrmsg.h:17
double * CKTrhsOld
Definition: cktdefs.h:98
double JJg0
Definition: jjdefs.h:41
double JJvmore
Definition: jjdefs.h:98
double * JJnegIbrPtr
Definition: jjdefs.h:59
double JJcriti
Definition: jjdefs.h:39
double JJg2
Definition: jjdefs.h:45
double JJdelVdelT
Definition: jjdefs.h:36
double js_crhs
Definition: jjload.c:25
double js_ddv
Definition: jjload.c:29
#define NULL
Definition: spdefs.h:121
double JJgs
Definition: jjdefs.h:43
double cos()
double js_ci
Definition: jjload.c:23
double sin()
static char model[32]
Definition: subckt.c:76
double js_phi
Definition: jjload.c:22
int JJictype
Definition: jjdefs.h:89
struct sJJmodel * JJnextModel
Definition: jjdefs.h:82
double * JJnegNegPtr
Definition: jjdefs.h:53
double js_gqt
Definition: jjload.c:24
int JJrtype
Definition: jjdefs.h:88
static void jj_load()
static void jj_ic()
double * JJposNegPtr
Definition: jjdefs.h:47
struct sJJinstance * JJnextInstance
Definition: jjdefs.h:17
double * JJposIbrPtr
Definition: jjdefs.h:57
double * JJposPosPtr
Definition: jjdefs.h:51
int CKTnoncon
Definition: cktdefs.h:203
int JJload(GENmodel *inModel, CKTcircuit *ckt)
Definition: jjload.c:47
double JJgn
Definition: jjdefs.h:42
long CKTmode
Definition: cktdefs.h:139
static void jj_iv()
double js_vj
Definition: jjload.c:21
int JJbranch
Definition: jjdefs.h:26