Jspice3
dctan.c
Go to the documentation of this file.
1 /***************************************************************************
2 JSPICE3 adaptation of Spice3e2 - Copyright (c) Stephen R. Whiteley 1992
3 Copyright 1990 Regents of the University of California. All rights reserved.
4 Authors: 1985 Thomas L. Quarles
5  1992 Stephen R. Whiteley
6 ****************************************************************************/
7 
8 #define ANAL_EXT
9 
10 #include "spice.h"
11 #include "misc.h"
12 #include <stdio.h>
13 #include "srcdefs.h"
14 #include "sperror.h"
15 #include "outdata.h"
16 #include "dctdefs.h"
17 #include "util.h"
18 #include "cktext.h"
19 #include "niext.h"
20 
21 #ifdef __STDC__
22 static int dct_init(CKTcircuit*,struct sOUTdata*);
23 static int dct_operation(CKTcircuit*,struct sOUTdata*,int);
24 #else
25 static int dct_init();
26 static int dct_operation();
27 #endif
28 
29 
30 int
31 DCTan(cktp,restart)
32 
33 GENERIC *cktp;
34 int restart; /* forced restart flag */
35 {
36  CKTcircuit *ckt = (CKTcircuit *)cktp;
37  DCTAN *job = (DCTAN*)ckt->CKTcurJob;
38  static struct sOUTdata outd;
39  int i, error;
40 
41  if (ckt->CKTjjPresent) {
42  (*(SPfrontEnd->IFerror))(ERR_FATAL,
43  "DC analysis not possible with Josephson junctions", NULL);
44  return (OK);
45  }
46  if (restart) {
47  error = dct_init(ckt,&outd);
48  if (error)
49  return (error);
50  }
51 
52  error = DCTloop(dct_operation,ckt,restart,&job->DC,&outd);
53 
54  if (error == E_PAUSE)
55  return (error);
56 
57  (*(SPfrontEnd->OUTendPlot))(*outd.plotPtr);
58 
59  return (error);
60 }
61 
62 
63 static int
64 dct_init(ckt,outd)
65 
66 CKTcircuit *ckt;
67 struct sOUTdata *outd;
68 {
69  DCTAN *job = (DCTAN*)ckt->CKTcurJob;
70  int i;
71  int code;
72  int error;
73  char *swp;
74 
75  code = CKTtypelook("Source");
76  ckt->CKTtime = 0;
77  ckt->CKTdelta = job->DC.vstep[0];
78  ckt->CKTmode = MODEDCTRANCURVE | MODEINITJCT;
79  ckt->CKTorder = 1;
80 
81  for (i = 0; i < 7; i++) {
82  ckt->CKTdeltaOld[i] = ckt->CKTdelta;
83  }
84  for (i = 0; i <= job->DC.nestLevel; i++) {
85  SRCinstance *here;
86 
87  here = (SRCinstance*)NULL;
88  error = CKTfndDev((GENERIC*)ckt,&code,(GENERIC**)&here,
89  job->DC.eltName[i], (GENERIC *)NULL,(IFuid)NULL);
90 
91  if (error) {
92  (*(SPfrontEnd->IFerror))(ERR_FATAL,
93  "DCtrCurv: source %s not in circuit",
94  &(job->DC.eltName[i]));
95  return (E_NOTFOUND);
96  }
97  job->DC.elt[i] = (GENinstance*)here;
98  job->DC.vsave[i] = here->SRCdcValue;
99  }
100  error = CKTnames(ckt,&outd->numNames,&outd->dataNames);
101  if (error)
102  return (error);
103 
104  if (*(char*)(job->DC.eltName[0]) == 'v' ||
105  *(char*)(job->DC.eltName[0]) == 'V')
106  swp = "vsweep";
107  else
108  swp = "isweep";
109 
110  (*(SPfrontEnd->IFnewUid))((GENERIC *)ckt,&outd->refName,(IFuid )NULL,
111  swp, UID_OTHER, (GENERIC **)NULL);
112 
113  outd->circuitPtr = (GENERIC *)ckt;
114  outd->analysisPtr = (GENERIC*)ckt->CKTcurJob;
115  outd->analName = ckt->CKTcurJob->JOBname;
116  outd->refType = IF_REAL;
117  outd->dataType = IF_REAL;
118  outd->plotPtr = &job->DCTplot;
119  outd->numPts = 1;
120  outd->initValue = job->DC.vstart[0];
121  outd->finalValue = job->DC.vstop[0];
122  outd->step = job->DC.vstep[0];
123  outd->count = 0;
124  (*(SPfrontEnd->OUTbeginPlot))((GENERIC*)outd);
125  return (OK);
126 }
127 
128 
129 /* ARGSUSED */
130 static int
131 dct_operation(ckt,outd,restart)
132 
133 CKTcircuit *ckt;
134 struct sOUTdata *outd;
135 int restart;
136 {
137  DCTAN *job = (DCTAN*)ckt->CKTcurJob;
138  int i, converged = 1;
139  double *temp;
140 
141 
142  if (ckt->CKTmode & MODEINITPRED) {
143  temp = ckt->CKTstates[ckt->CKTmaxOrder+1];
144  for (i = ckt->CKTmaxOrder; i >= 0; i--) {
145  ckt->CKTstates[i+1] = ckt->CKTstates[i];
146  }
147  ckt->CKTstate0 = temp;
148  converged = NIiter(ckt,ckt->CKTdcTrcvMaxIter);
149  }
150  if (converged) {
151 
152  converged = CKTic(ckt);
153  if (converged)
154  return (converged);
155 
156  converged = CKTop(ckt,
159  ckt->CKTdcMaxIter);
160  if (converged) {
161  return (converged);
162  }
163  bcopy((char *)ckt->CKTstate0,(char *)ckt->CKTstate1,
164  ckt->CKTnumStates*sizeof(double));
165  }
166  ckt->CKTmode = MODEDCTRANCURVE | MODEINITPRED;
167  ckt->CKTtime = ((SRCinstance *)(job->DC.elt[0]))->SRCdcValue;
168 
169  CKTdump(ckt,ckt->CKTtime,*outd->plotPtr);
170  outd->count++;
171 
172  return (OK);
173 }
174 
175 
176 int
177 DCTloop(func,ckt,restart,dc,outd)
178 
179 #ifdef __STDC__
180 int (*func)(CKTcircuit*,struct sOUTdata*,int);
181 #else
182 int (*func)();
183 #endif
184 CKTcircuit *ckt;
185 int restart;
186 struct sDCTprms *dc;
187 struct sOUTdata *outd;
188 {
189  double tt;
190  int i, j;
191  int error;
192 
193  if (dc->elt[0] == NULL) {
194  /* no dc sources specified */
195  return ( (*func)(ckt,outd,restart) );
196  }
197 
198  if (restart) {
199  /* reset static variables */
200  dc->dims[0] = dc->dims[1] = 0;
201  dc->nestSave = 0;
202  dc->skip = 0;
203  for (i = 0; i <= dc->nestLevel; i++)
204  ((SRCinstance *)dc->elt[i])->SRCdcValue = dc->vstart[i];
205  }
206  else {
207  for (i = 0; i <= dc->nestLevel; i++)
208  ((SRCinstance *)dc->elt[i])->SRCdcValue = dc->vstate[i];
209  }
210 
211  i = dc->nestSave;
212 
213  if (dc->skip) {
214  /* paused in (*func)() */
215  dc->skip = 0;
216  goto didpause;
217  }
218 
219  for (;;) {
220 
221  tt = ((SRCinstance*)dc->elt[i])->SRCdcValue - dc->vstop[i];
222 
223  if ((dc->vstep[i] > 0 && tt > 1e-8) ||
224  (dc->vstep[i] < 0 && tt < 1e-8) ||
225  dc->vstep[i] == 0) {
226 
227  i++;
228  ckt->CKTmode =
229  (ckt->CKTmode & MODEUIC) | MODEDCTRANCURVE | MODEINITJCT;
230  if (i > dc->nestLevel)
231  break;
232  dc->dims[0]++;
233  if (dc->dims[2] <= 1) {
234  (*(SPfrontEnd->OUTsetDims))(*outd->plotPtr,dc->dims,2);
235  }
236  }
237  else {
238  if (!dc->dims[0])
239  dc->dims[1]++;
240 
241  while (i > 0) {
242  i--;
243  ((SRCinstance *)dc->elt[i])->SRCdcValue = dc->vstart[i];
244  }
245 
246  /* do operation */
247  outd->count = 0;
248 didpause:
249  error = (*func)(ckt,outd,restart);
250  if (error) {
251  dc->nestSave = i;
252  dc->skip = 1;
253  /* save state, put everything back to normal */
254  for (i = 0; i <= dc->nestLevel; i++) {
255  dc->vstate[i] = ((SRCinstance *)dc->elt[i])->SRCdcValue;
256  ((SRCinstance *)dc->elt[i])->SRCdcValue = dc->vsave[i];
257  }
258  return (error);
259  }
260  /* so next sub-analysis starts properly */
261  restart = true;
262 
263  /* store block size in dims[] */
264  dc->dims[2] = outd->count;
265 
266  if (dc->dims[2] > 1) {
267 
268  if (dc->dims[0])
269  (*(SPfrontEnd->OUTsetDims))(*outd->plotPtr,dc->dims,3);
270  else
271  (*(SPfrontEnd->OUTsetDims))(*outd->plotPtr,dc->dims+1,2);
272  }
273  if (*SPfrontEnd->OUTendit) {
274  *SPfrontEnd->OUTendit = false;
275  for (i = 0; i <= dc->nestLevel; i++) {
276  dc->vstate[i] = ((SRCinstance *)dc->elt[i])->SRCdcValue;
277  ((SRCinstance *)dc->elt[i])->SRCdcValue = dc->vsave[i];
278  }
279  return (OK);
280  }
281  }
282 
283  ((SRCinstance*)dc->elt[i])->SRCdcValue += dc->vstep[i];
284 
285  if ( (*(SPfrontEnd->IFpauseTest))() ) {
286  /* user asked us to pause, so save state */
287  dc->nestSave = i;
288  dc->skip = 0;
289  /* save state, put everything back to normal */
290  for (i = 0; i <= dc->nestLevel; i++) {
291  dc->vstate[i] = ((SRCinstance *)dc->elt[i])->SRCdcValue;
292  ((SRCinstance *)dc->elt[i])->SRCdcValue = dc->vsave[i];
293  }
294  return (E_PAUSE);
295  }
296  }
297 
298  /* done, put everything back to normal */
299  for (i = 0; i <= dc->nestLevel; i++)
300  ((SRCinstance *)dc->elt[i])->SRCdcValue = dc->vsave[i];
301  return (OK);
302 }
#define E_PAUSE
Definition: iferrmsg.h:15
int numPts
Definition: outdata.h:22
double initValue
Definition: outdata.h:24
double vstep[DCTNESTLEVEL]
Definition: analysis.h:29
#define MODEINITPRED
Definition: cktdefs.h:161
int CKTnames()
int dims[DCTNESTLEVEL+1]
Definition: analysis.h:37
#define MODEDCTRANCURVE
Definition: cktdefs.h:152
int refType
Definition: outdata.h:17
Definition: dctdefs.h:18
IFuid * dataNames
Definition: outdata.h:19
int * OUTendit
Definition: ifsim.h:513
IFuid analName
Definition: outdata.h:15
if(TDesc==NULL)
Definition: cd.c:1326
int numNames
Definition: outdata.h:18
#define MODEINITFLOAT
Definition: cktdefs.h:156
Definition: xforms.c:16
#define ERR_FATAL
Definition: ifsim.h:518
int NIiter()
#define E_NOTFOUND
Definition: iferrmsg.h:35
int DCTloop(int(*func)(), CKTcircuit *ckt, int restart, struct sDCTprms *dc, struct sOUTdata *outd)
Definition: dctan.c:177
static double e
Definition: vectors.c:17
IFfrontEnd * SPfrontEnd
Definition: main.c:917
double SRCdcValue
Definition: srcdefs.h:77
int CKTtypelook()
double step
Definition: outdata.h:26
double vstart[DCTNESTLEVEL]
Definition: analysis.h:27
IFuid eltName[DCTNESTLEVEL]
Definition: analysis.h:34
static int dct_init()
#define OK
Definition: iferrmsg.h:17
GENERIC * IFuid
Definition: ifsim.h:72
#define NULL
Definition: spdefs.h:121
int nestSave
Definition: analysis.h:36
static int dct_operation()
GENERIC * circuitPtr
Definition: outdata.h:13
struct sDCTprms DC
Definition: dctdefs.h:23
double vstate[DCTNESTLEVEL]
Definition: analysis.h:32
int CKTjjPresent
Definition: cktdefs.h:168
double vsave[DCTNESTLEVEL]
Definition: analysis.h:30
int CKTic()
#define IF_REAL
Definition: ifsim.h:108
double finalValue
Definition: outdata.h:25
void CKTdump()
Definition: fteparse.h:37
double vstop[DCTNESTLEVEL]
Definition: analysis.h:28
int CKTop()
return(True)
int count
Definition: outdata.h:23
int DCTan(GENERIC *cktp, int restart)
Definition: dctan.c:31
#define UID_OTHER
Definition: ifsim.h:85
GENERIC * analysisPtr
Definition: outdata.h:14
int CKTfndDev()
GENERIC * DCTplot
Definition: dctdefs.h:22
void bcopy(char *from, char *to, int num)
Definition: string.c:339
int skip
Definition: analysis.h:38
GENERIC ** plotPtr
Definition: outdata.h:21
JOB * CKTcurJob
Definition: cktdefs.h:216
IFuid refName
Definition: outdata.h:16
#define MODEINITJCT
Definition: cktdefs.h:157
#define MODEUIC
Definition: cktdefs.h:166
int nestLevel
Definition: analysis.h:35
GENinstance * elt[DCTNESTLEVEL]
Definition: analysis.h:33
char GENERIC
Definition: ifsim.h:27
int dataType
Definition: outdata.h:20