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: 1985 Thomas L. Quarles
5          1992 Stephen R. Whiteley
6 ****************************************************************************/
7 
8 #include "spice.h"
9 #include <stdio.h>
10 #include "devdefs.h"
11 #include "tskdefs.h"
12 #include "dcodefs.h"
13 #include "sperror.h"
14 #include "outdata.h"
15 #include "util.h"
16 #include "cktext.h"
17 
18 
19 /* ARGSUSED */
20 int
DCOan(cktp,restart)21 DCOan(cktp,restart)
22 
23 GENERIC *cktp;
24 int restart;
25 {
26     CKTcircuit *ckt = (CKTcircuit *)cktp;
27     struct sOUTdata outd;
28     int converged;
29     int error;
30     GENERIC *plot;
31 
32     if (ckt->CKTjjPresent) {
33         (*(SPfrontEnd->IFerror))(ERR_FATAL,
34             "DC analysis not possible with Josephson junctions", NULL);
35             return (OK);
36     }
37     error = CKTnames(ckt,&outd.numNames,&outd.dataNames);
38     if (error)
39         return (error);
40 
41     outd.circuitPtr = (GENERIC *)ckt;
42     outd.analysisPtr = (GENERIC*)ckt->CKTcurJob;
43     outd.analName = ckt->CKTcurJob->JOBname;
44     outd.refName = (IFuid)NULL;
45     outd.refType = IF_REAL;
46     outd.dataType = IF_REAL;
47     outd.plotPtr = &plot;
48     outd.numPts = 1;
49     outd.initValue = 0;
50     outd.finalValue = 0;
51     outd.step = 0;
52     (*(SPfrontEnd->OUTbeginPlot))((GENERIC*)&outd);
53 
54     error = CKTic(ckt);
55     if (error)
56         return (error);
57 
58     converged = CKTop(ckt,
59             MODEDCOP | MODEINITJCT,
60             MODEDCOP | MODEINITFLOAT,
61             ckt->CKTdcMaxIter);
62 
63     if (converged != 0)
64         return (converged);
65 
66     ckt->CKTmode = MODEDCOP | MODEINITSMSIG;
67     converged = CKTload(ckt);
68     CKTdump(ckt,(double)0,plot);
69     (*(SPfrontEnd->OUTendPlot))(plot);
70 
71     return (converged);
72 }
73 
74 
75 int
CKTop(ckt,firstmode,continuemode,iterlim)76 CKTop(ckt,firstmode, continuemode, iterlim)
77 
78 CKTcircuit *ckt;
79 long firstmode;
80 long continuemode;
81 int iterlim;
82 {
83     int converged;
84     int i;
85 
86     ckt->CKTmode = firstmode;
87     if (!ckt->CKTnoOpIter) {
88         converged = NIiter(ckt,iterlim);
89     }
90     else {
91         converged = 1;  /* the 'go directly to gmin stepping' option */
92     }
93     if (converged != 0) {
94         /* no convergence on the first try, so we do something else */
95         /* first, check if we should try gmin stepping */
96         /* note that no path out of this code allows ckt->CKTdiagGmin to be
97          * anything but 0.000000000
98          */
99         if (ckt->CKTnumGminSteps >1) {
100             ckt->CKTmode = firstmode;
101             (*(SPfrontEnd->IFerror))(ERR_INFO,
102                     "starting Gmin stepping",(IFuid *)NULL);
103             ckt->CKTdiagGmin = ckt->CKTgmin;
104             for (i = 0; i < ckt->CKTnumGminSteps; i++) {
105                 ckt->CKTdiagGmin *= 10;
106             }
107             for (i = 0; i <= ckt->CKTnumGminSteps; i++) {
108                 ckt->CKTnoncon = 1;
109                 converged = NIiter(ckt,iterlim);
110                 if (converged != 0) {
111                     ckt->CKTdiagGmin = 0;
112                     (*(SPfrontEnd->IFerror))(ERR_WARNING,
113                             "Gmin step failed",(IFuid *)NULL);
114                     break;
115                 }
116                 ckt->CKTdiagGmin /= 10;
117                 ckt->CKTmode=continuemode;
118                 (*(SPfrontEnd->IFerror))(ERR_INFO,
119                         "One sucessful Gmin step",(IFuid *)NULL);
120             }
121             ckt->CKTdiagGmin = 0;
122             converged = NIiter(ckt,iterlim);
123             if (converged == 0) {
124                 (*(SPfrontEnd->IFerror))(ERR_INFO,
125                         "Gmin stepping completed",(IFuid *)NULL);
126                 return (0);
127             }
128             (*(SPfrontEnd->IFerror))(ERR_WARNING,
129                     "Gmin stepping failed",(IFuid *)NULL);
130 
131         }
132         /* now, we'll try source stepping - we scale the sources
133          * to 0, converge, then start stepping them up until they
134          * are at their normal values
135          *
136          * note that no path out of this code allows ckt->CKTsrcFact to be
137          * anything but 1.000000000
138          */
139         if (ckt->CKTnumSrcSteps > 1) {
140             ckt->CKTmode = firstmode;
141             (*(SPfrontEnd->IFerror))(ERR_INFO,
142                     "starting source stepping",(IFuid *)NULL);
143             for (i = 0; i <= ckt->CKTnumSrcSteps; i++) {
144                 ckt->CKTsrcFact = ((double)i)/((double)ckt->CKTnumSrcSteps);
145                 converged = NIiter(ckt,iterlim);
146                 ckt->CKTmode = continuemode;
147                 if (converged != 0) {
148                     ckt->CKTsrcFact = 1;
149                     ckt->CKTcurrentAnalysis = DOING_TRAN;
150                     (*(SPfrontEnd->IFerror))(ERR_WARNING,
151                             "source stepping failed",(IFuid *)NULL);
152                     return (converged);
153                 }
154                 (*(SPfrontEnd->IFerror))(ERR_INFO,
155                         "One successful source step",(IFuid *)NULL);
156             }
157             (*(SPfrontEnd->IFerror))(ERR_INFO,
158                     "Source stepping completed",(IFuid *)NULL);
159             ckt->CKTsrcFact = 1;
160             return (0);
161         }
162         else {
163             return (converged);
164         }
165     }
166     return (0);
167 }
168 
169 
170 /* CKTconvTest(ckt)
171  *    this is a driver program to iterate through all the various
172  *    convTest functions provided for the circuit elements in the
173  *    given circuit
174  */
175 
176 int
CKTconvTest(ckt)177 CKTconvTest(ckt)
178 
179 CKTcircuit *ckt;
180 {
181     extern SPICEdev *DEVices[];
182     int error;
183     struct sCKTmodHead *mh;
184     int (*func)();
185 
186     for (mh = ckt->CKTheadList; mh != NULL; mh = mh->next) {
187         if ((func = DEVices[mh->type]->DEVconvTest) != NULL) {
188             error = (*func)(mh->head,ckt);
189             if (error) return (error);
190         }
191         if (ckt->CKTnoncon) {
192             /*
193             printf("convTest: device %s failed\n",
194                 (*DEVices[mh->type]).DEVpublic.name);
195             */
196             return (OK);
197         }
198     }
199     return (OK);
200 }
201