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