1 /**********
2 Copyright 1990 Regents of the University of California.  All rights reserved.
3 Author: 1985 Thomas L. Quarles
4 Modified: 2000 AlansFixes
5 **********/
6 
7 #include "ngspice/ngspice.h"
8 #include "ngspice/cktdefs.h"
9 #include "ngspice/sperror.h"
10 #include "ngspice/trandefs.h"
11 #include "ngspice/cpextern.h"
12 #include "ngspice/fteext.h"
13 
14 #include "analysis.h"
15 
16 #ifdef XSPICE
17 /* gtri - add - wbk - 11/26/90 - add include for MIF and EVT global data */
18 #include "ngspice/mif.h"
19 #include "ngspice/evtproto.h"
20 /* gtri - end - wbk - 11/26/90 */
21 /* gtri - add - 12/12/90 - wbk - include ipc stuff */
22 #include "ngspice/ipctiein.h"
23 /* gtri - end - 12/12/90 */
24 #endif
25 
26 extern SPICEanalysis *analInfo[];
27 
28 int
CKTdoJob(CKTcircuit * ckt,int reset,TSKtask * task)29 CKTdoJob(CKTcircuit *ckt, int reset, TSKtask *task)
30 {
31     JOB		*job;
32     double	startTime;
33     int		error, i, error2;
34 
35     int         ANALmaxnum = spice_num_analysis();
36 
37 #ifdef WANT_SENSE2
38     int		senflag;
39     static int	sens_num = -1;
40 
41     /* Sensitivity is special */
42     if (sens_num < 0) {
43 	for (i = 0; i <  ANALmaxnum; i++)
44 	    if (!strcmp("SENS2", analInfo[i]->if_analysis.name))
45 		break;
46 	sens_num = i;
47     }
48 #endif
49 
50     startTime = SPfrontEnd->IFseconds();
51 
52     ckt->CKTtemp  = task->TSKtemp;
53     ckt->CKTnomTemp  = task->TSKnomTemp;
54     ckt->CKTmaxOrder  = task->TSKmaxOrder;
55     ckt->CKTintegrateMethod  = task->TSKintegrateMethod;
56     ckt->CKTindverbosity  = task->TSKindverbosity;
57     ckt->CKTxmu  = task->TSKxmu;
58     ckt->CKTbypass  = task->TSKbypass;
59     ckt->CKTdcMaxIter  = task->TSKdcMaxIter;
60     ckt->CKTdcTrcvMaxIter  = task->TSKdcTrcvMaxIter;
61     ckt->CKTtranMaxIter  = task->TSKtranMaxIter;
62     ckt->CKTnumSrcSteps  = task->TSKnumSrcSteps;
63     ckt->CKTnumGminSteps  = task->TSKnumGminSteps;
64     ckt->CKTgminFactor  = task->TSKgminFactor;
65     ckt->CKTminBreak  = task->TSKminBreak;
66     ckt->CKTabstol  = task->TSKabstol;
67     ckt->CKTpivotAbsTol  = task->TSKpivotAbsTol;
68     ckt->CKTpivotRelTol  = task->TSKpivotRelTol;
69     ckt->CKTreltol  = task->TSKreltol;
70     ckt->CKTchgtol  = task->TSKchgtol;
71     ckt->CKTvoltTol  = task->TSKvoltTol;
72     ckt->CKTgmin  = task->TSKgmin;
73     ckt->CKTgshunt  = task->TSKgshunt;
74     ckt->CKTcshunt  = task->TSKcshunt;
75     ckt->CKTdelmin  = task->TSKdelmin;
76     ckt->CKTtrtol  = task->TSKtrtol;
77 #ifdef XSPICE
78 /* Lower value of trtol to give smaller stepsize and more accuracy,
79    but only if there are 'A' devices in the circuit,
80    may be overridden by 'set xtrtol=newval' */
81     if (ckt->CKTadevFlag  &&  (ckt->CKTtrtol > 1)) {
82       int newtol;
83       if (cp_getvar("xtrtol", CP_NUM, &newtol, 0)) {
84         printf("Override trtol to %d for xspice 'A' devices\n", newtol);
85         ckt->CKTtrtol  = newtol;
86       }
87       else {
88         printf("Reducing trtol to 1 for xspice 'A' devices\n");
89         ckt->CKTtrtol  = 1;
90       }
91     }
92 #endif
93     ckt->CKTdefaultMosM  = task->TSKdefaultMosM;
94     ckt->CKTdefaultMosL  = task->TSKdefaultMosL;
95     ckt->CKTdefaultMosW  = task->TSKdefaultMosW;
96     ckt->CKTdefaultMosAD  = task->TSKdefaultMosAD;
97     ckt->CKTdefaultMosAS  = task->TSKdefaultMosAS;
98     ckt->CKTfixLimit  = task->TSKfixLimit;
99     ckt->CKTnoOpIter  = task->TSKnoOpIter;
100     ckt->CKTtryToCompact = task->TSKtryToCompact;
101     ckt->CKTbadMos3 = task->TSKbadMos3;
102     ckt->CKTkeepOpInfo = task->TSKkeepOpInfo;
103     ckt->CKTcopyNodesets = task->TSKcopyNodesets;
104     ckt->CKTnodeDamping = task->TSKnodeDamping;
105     ckt->CKTabsDv = task->TSKabsDv;
106     ckt->CKTrelDv = task->TSKrelDv;
107     ckt->CKTtroubleNode  = 0;
108     ckt->CKTtroubleElt  = NULL;
109     ckt->CKTnoopac = task->TSKnoopac && ckt->CKTisLinear;
110     ckt->CKTepsmin = task->TSKepsmin;
111 #ifdef NEWTRUNC
112     ckt->CKTlteReltol = task->TSKlteReltol;
113     ckt->CKTlteAbstol = task->TSKlteAbstol;
114 #endif /* NEWTRUNC */
115 
116     fprintf(stdout, "Doing analysis at TEMP = %f and TNOM = %f\n\n",
117     ckt->CKTtemp - CONSTCtoK, ckt->CKTnomTemp - CONSTCtoK);
118 
119     /* call altermod and alter on device and model parameters assembled in
120        devtlist and modtlist (if using temper) because we have a new temperature */
121     inp_evaluate_temper(ft_curckt);
122 
123     error = 0;
124 
125     if (reset) {
126 
127 	ckt->CKTdelta = 0.0;
128 	ckt->CKTtime = 0.0;
129 	ckt->CKTcurrentAnalysis = 0;
130 
131 #ifdef WANT_SENSE2
132 	senflag = 0;
133 	if (sens_num < ANALmaxnum)
134 	    for (job = task->jobs; !error && job; job = job->JOBnextJob) {
135 		if (job->JOBtype == sens_num) {
136 		    senflag = 1;
137 		    ckt->CKTcurJob = job;
138 		    ckt->CKTsenInfo = (SENstruct *) job;
139 		    error = analInfo[sens_num]->an_func (ckt, reset);
140 		}
141 	    }
142 
143 	if (ckt->CKTsenInfo && (!senflag || error))
144 	    FREE(ckt->CKTsenInfo);
145 #endif
146 
147         /* make sure this is either up do date or NULL */
148         ckt->CKTcurJob = NULL;
149 
150 	/* normal reset */
151 	if (!error)
152 	    error = CKTunsetup(ckt);
153 
154 #ifdef XSPICE
155         /* gtri - add - 12/12/90 - wbk - set ipc syntax error flag */
156         if(error)   g_ipc.syntax_error = IPC_TRUE;
157         /* gtri - end - 12/12/90 */
158 #endif
159 
160 	if (!error)
161 	    error = CKTsetup(ckt);
162 
163 #ifdef XSPICE
164         /* gtri - add - 12/12/90 - wbk - set ipc syntax error flag */
165         if(error)   g_ipc.syntax_error = IPC_TRUE;
166         /* gtri - end - 12/12/90 */
167 #endif
168 
169 	if (!error)
170 	    error = CKTtemp(ckt);
171 
172 #ifdef XSPICE
173         /* gtri - add - 12/12/90 - wbk - set ipc syntax error flag */
174         if(error)   g_ipc.syntax_error = IPC_TRUE;
175         /* gtri - end - 12/12/90 */
176 #endif
177 
178 	if (error) {
179 
180 #ifdef XSPICE
181           /* gtri - add - 12/12/90 - wbk - return if syntax errors from parsing */
182           if(g_ipc.enabled) {
183             if(g_ipc.syntax_error)
184               ;
185             else {
186               /* else, send (GO) errchk status if we got this far */
187               /* Caller is responsible for sending NOGO status if we returned earlier */
188               ipc_send_errchk();
189             }
190           }
191           /* gtri - end - 12/12/90 */
192 #endif
193 
194 
195             return error;
196 
197 
198         }/* if error  */
199     }
200 
201     error2 = OK;
202 
203     /* Analysis order is important */
204     for (i = 0; i < ANALmaxnum; i++) {
205 
206 #ifdef WANT_SENSE2
207 	if (i == sens_num)
208 	    continue;
209 #endif
210 
211 	for (job = task->jobs; job; job = job->JOBnextJob) {
212 	    if (job->JOBtype == i) {
213                 ckt->CKTcurJob=job;
214 		error = OK;
215 		if (analInfo[i]->an_init)
216 		    error = analInfo[i]->an_init (ckt, job);
217 		if (!error && analInfo[i]->do_ic)
218 		    error = CKTic(ckt);
219 		if (!error){
220 #ifdef XSPICE
221             if(reset) {
222                   /* gtri - begin - 6/10/91 - wbk - Setup event-driven data */
223                   error = EVTsetup(ckt);
224                   if(error) {
225                     ckt->CKTstat->STATtotAnalTime +=
226                       SPfrontEnd->IFseconds() - startTime;
227                     return(error);
228                   }
229                   /* gtri - end - 6/10/91 - wbk - Setup event-driven data */
230             }
231 #endif
232 		    error = analInfo[i]->an_func (ckt, reset);
233 			/* txl, cpl addition */
234 			if (error == 1111) break;
235 		}
236 		if (error)
237 		    error2 = error;
238 	    }
239 	}
240     }
241 
242     ckt->CKTstat->STATtotAnalTime += SPfrontEnd->IFseconds() - startTime;
243 
244 #ifdef WANT_SENSE2
245     if (ckt->CKTsenInfo)
246 	SENdestroy(ckt->CKTsenInfo);
247 #endif
248 
249     return(error2);
250 }
251 
252