1 /**********
2 Copyright 1990 Regents of the University of California. All rights reserved.
3 Author: 1985 Thomas L. Quarles
4 Modified: 2000 AlansFixes
5 Modified: 2005 Paolo Nenzi - Restructured
6 **********/
7
8 #include "ngspice/ngspice.h"
9 #include "ngspice/cktdefs.h"
10 #include "ngspice/devdefs.h"
11 #include "ngspice/sperror.h"
12 #include "ngspice/cpextern.h"
13
14 #ifdef XSPICE
15 #include "ngspice/enh.h"
16 #endif
17
18
19 static int dynamic_gmin(CKTcircuit *, long int, long int, int);
20 static int spice3_gmin(CKTcircuit *, long int, long int, int);
21 static int new_gmin(CKTcircuit*, long int, long int, int);
22 static int gillespie_src(CKTcircuit *, long int, long int, int);
23 static int spice3_src(CKTcircuit *, long int, long int, int);
24
25
26 int
CKTop(CKTcircuit * ckt,long int firstmode,long int continuemode,int iterlim)27 CKTop (CKTcircuit *ckt, long int firstmode, long int continuemode,
28 int iterlim)
29 {
30 int converged;
31
32 #ifdef HAS_PROGREP
33 SetAnalyse("op", 0);
34 #endif
35
36 ckt->CKTmode = firstmode;
37
38 if (!ckt->CKTnoOpIter) {
39 #ifdef XSPICE
40 /* gtri - wbk - add convergence problem reporting flags */
41 ckt->enh->conv_debug.last_NIiter_call =
42 (ckt->CKTnumGminSteps <= 0) && (ckt->CKTnumSrcSteps <= 0);
43 #endif
44 converged = NIiter (ckt, iterlim);
45 if (converged == 0)
46 return converged; /* successfull */
47 } else {
48 converged = 1; /* the 'go directly to gmin stepping' option */
49 }
50
51
52 /* no convergence on the first try, so we do something else */
53 /* first, check if we should try gmin stepping */
54
55 if (ckt->CKTnumGminSteps >= 1) {
56 if (ckt->CKTnumGminSteps == 1) {
57 /* only the old gmin */
58 if (cp_getvar("dyngmin", CP_BOOL, NULL, 0)) {
59 converged = dynamic_gmin(ckt, firstmode, continuemode, iterlim);
60 }
61 /* first the new gmin, then the old gmin */
62 else {
63 converged = new_gmin(ckt, firstmode, continuemode, iterlim);
64 if(converged != 0) {
65 converged = dynamic_gmin(ckt, firstmode, continuemode, iterlim);
66 }
67
68 }
69 }
70 else {
71 converged = spice3_gmin(ckt, firstmode, continuemode, iterlim);
72 }
73 if (converged == 0) /* If gmin-stepping worked... move out */
74 return converged;
75 }
76
77 /* ... otherwise try stepping sources ...
78 * now, we'll try source stepping - we scale the sources
79 * to 0, converge, then start stepping them up until they
80 * are at their normal values
81 */
82
83 if (ckt->CKTnumSrcSteps >= 1) {
84 if (ckt->CKTnumSrcSteps == 1)
85 converged = gillespie_src(ckt, firstmode, continuemode, iterlim);
86 else
87 converged = spice3_src(ckt, firstmode, continuemode, iterlim);
88 }
89
90 #ifdef XSPICE
91 /* gtri - wbk - add convergence problem reporting flags */
92 ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE;
93 #endif
94
95 return converged;
96 }
97
98
99 /* CKTconvTest(ckt)
100 * this is a driver program to iterate through all the various
101 * convTest functions provided for the circuit elements in the
102 * given circuit
103 */
104
105 int
CKTconvTest(CKTcircuit * ckt)106 CKTconvTest (CKTcircuit *ckt)
107 {
108 int i;
109
110 for (i = 0; i < DEVmaxnum; i++) {
111
112 if (DEVices[i] && DEVices[i]->DEVconvTest && ckt->CKThead[i]) {
113 int error = DEVices[i]->DEVconvTest (ckt->CKThead[i], ckt);
114 if (error)
115 return error;
116 }
117
118 if (ckt->CKTnoncon) {
119 /* printf("convTest: device %s failed\n",
120 * DEVices[i]->DEVpublic.name); */
121 return OK;
122 }
123 }
124
125 return OK;
126 }
127
128
129 /* Dynamic gmin stepping
130 * Algorithm by Alan Gillespie
131 * Modified 2005 - Paolo Nenzi (extracted from CKTop.c code)
132 *
133 * return value:
134 * 0 -> method converged
135 * 1 -> method failed
136 *
137 * Note that no path out of this code allows ckt->CKTdiagGmin to be
138 * anything but CKTgshunt.
139 */
140
141 static int
dynamic_gmin(CKTcircuit * ckt,long int firstmode,long int continuemode,int iterlim)142 dynamic_gmin (CKTcircuit *ckt, long int firstmode,
143 long int continuemode, int iterlim)
144 {
145 double OldGmin, gtarget, factor;
146 int converged;
147
148 int NumNodes, iters, i;
149 double *OldRhsOld, *OldCKTstate0;
150 CKTnode *n;
151
152 ckt->CKTmode = firstmode;
153 SPfrontEnd->IFerrorf (ERR_INFO, "Starting dynamic gmin stepping");
154
155 NumNodes = 0;
156 for (n = ckt->CKTnodes; n; n = n->next)
157 NumNodes++;
158
159 OldRhsOld = TMALLOC(double, NumNodes + 1);
160 OldCKTstate0 = TMALLOC(double, ckt->CKTnumStates + 1);
161
162 for (n = ckt->CKTnodes; n; n = n->next)
163 ckt->CKTrhsOld [n->number] = 0;
164
165 for (i = 0; i < ckt->CKTnumStates; i++)
166 ckt->CKTstate0 [i] = 0;
167
168 factor = ckt->CKTgminFactor;
169 OldGmin = 1e-2;
170 ckt->CKTdiagGmin = OldGmin / factor;
171 gtarget = MAX (ckt->CKTgmin, ckt->CKTgshunt);
172
173 for (;;) {
174 fprintf (stderr, "Trying gmin = %12.4E ", ckt->CKTdiagGmin);
175
176 ckt->CKTnoncon = 1;
177 iters = ckt->CKTstat->STATnumIter;
178 converged = NIiter (ckt, ckt->CKTdcTrcvMaxIter);
179 iters = ckt->CKTstat->STATnumIter - iters;
180
181 if (converged == 0) {
182 ckt->CKTmode = continuemode;
183 SPfrontEnd->IFerrorf (ERR_INFO, "One successful gmin step");
184
185 if (ckt->CKTdiagGmin <= gtarget)
186 break; /* successfull */
187
188 for (i = 0, n = ckt->CKTnodes; n; n = n->next)
189 OldRhsOld[i++] = ckt->CKTrhsOld[n->number];
190
191 memcpy(OldCKTstate0, ckt->CKTstate0,
192 (size_t) ckt->CKTnumStates * sizeof(double));
193
194 if (iters <= (ckt->CKTdcTrcvMaxIter / 4)) {
195 factor *= sqrt (factor);
196 if (factor > ckt->CKTgminFactor)
197 factor = ckt->CKTgminFactor;
198 }
199
200 if (iters > (3 * ckt->CKTdcTrcvMaxIter / 4))
201 factor = MAX(sqrt (factor), 1.00005);
202
203 OldGmin = ckt->CKTdiagGmin;
204
205 if (ckt->CKTdiagGmin < factor * gtarget) {
206 factor = ckt->CKTdiagGmin / gtarget;
207 ckt->CKTdiagGmin = gtarget;
208 } else {
209 ckt->CKTdiagGmin /= factor;
210 }
211 } else {
212 if (factor < 1.00005) {
213 SPfrontEnd->IFerrorf (ERR_WARNING, "Last gmin step failed");
214 break; /* failed */
215 }
216 SPfrontEnd->IFerrorf (ERR_WARNING, "Further gmin increment");
217 factor = sqrt (sqrt (factor));
218 ckt->CKTdiagGmin = OldGmin / factor;
219
220 for (i = 0, n = ckt->CKTnodes; n; n = n->next)
221 ckt->CKTrhsOld[n->number] = OldRhsOld[i++];
222
223 memcpy(ckt->CKTstate0, OldCKTstate0,
224 (size_t) ckt->CKTnumStates * sizeof(double));
225 }
226 }
227
228 ckt->CKTdiagGmin = ckt->CKTgshunt;
229 FREE (OldRhsOld);
230 FREE (OldCKTstate0);
231
232 #ifdef XSPICE
233 /* gtri - wbk - add convergence problem reporting flags */
234 ckt->enh->conv_debug.last_NIiter_call = (ckt->CKTnumSrcSteps <= 0);
235 #endif
236
237 converged = NIiter (ckt, iterlim);
238
239 if (converged != 0) {
240 SPfrontEnd->IFerrorf (ERR_WARNING, "Dynamic gmin stepping failed");
241 } else {
242 SPfrontEnd->IFerrorf (ERR_INFO, "Dynamic gmin stepping completed");
243 #ifdef XSPICE
244 /* gtri - wbk - add convergence problem reporting flags */
245 ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE;
246 #endif
247 }
248
249 return converged;
250 }
251
252
253 /* Spice3 gmin stepping
254 * Modified 2000 - Alan Gillespie (added gshunt)
255 * Modified 2005 - Paolo Nenzi (extracted from CKTop.c code)
256 *
257 * return value:
258 * 0 -> method converged
259 * 1 -> method failed
260 *
261 * Note that no path out of this code allows ckt->CKTdiagGmin to be
262 * anything but CKTgshunt.
263 */
264
265 static int
spice3_gmin(CKTcircuit * ckt,long int firstmode,long int continuemode,int iterlim)266 spice3_gmin (CKTcircuit *ckt, long int firstmode,
267 long int continuemode, int iterlim)
268 {
269 int converged, i;
270
271 ckt->CKTmode = firstmode;
272 SPfrontEnd->IFerrorf (ERR_INFO, "Starting gmin stepping");
273
274 ckt->CKTdiagGmin =
275 (ckt->CKTgshunt == 0) ? ckt->CKTgmin : ckt->CKTgshunt;
276
277 for (i = 0; i < ckt->CKTnumGminSteps; i++)
278 ckt->CKTdiagGmin *= ckt->CKTgminFactor;
279
280 for (i = 0; i <= ckt->CKTnumGminSteps; i++) {
281 fprintf (stderr, "Trying gmin = %12.4E ", ckt->CKTdiagGmin);
282
283 ckt->CKTnoncon = 1;
284 converged = NIiter (ckt, ckt->CKTdcTrcvMaxIter);
285
286 if (converged != 0) {
287 ckt->CKTdiagGmin = ckt->CKTgshunt;
288 SPfrontEnd->IFerrorf (ERR_WARNING, "gmin step failed");
289 break;
290 }
291
292 ckt->CKTdiagGmin /= ckt->CKTgminFactor;
293 ckt->CKTmode = continuemode;
294
295 SPfrontEnd->IFerrorf (ERR_INFO, "One successful gmin step");
296 }
297
298 ckt->CKTdiagGmin = ckt->CKTgshunt;
299
300 #ifdef XSPICE
301 /* gtri - wbk - add convergence problem reporting flags */
302 ckt->enh->conv_debug.last_NIiter_call = (ckt->CKTnumSrcSteps <= 0);
303 #endif
304
305 converged = NIiter (ckt, iterlim);
306
307 if (converged == 0) {
308 SPfrontEnd->IFerrorf (ERR_INFO, "gmin stepping completed");
309
310 #ifdef XSPICE
311 /* gtri - wbk - add convergence problem reporting flags */
312 ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE;
313 #endif
314
315 } else {
316 SPfrontEnd->IFerrorf (ERR_WARNING, "gmin stepping failed");
317 }
318
319 return converged;
320 }
321
322 /* just step the real gmin found in every device model */
323 static int
new_gmin(CKTcircuit * ckt,long int firstmode,long int continuemode,int iterlim)324 new_gmin(CKTcircuit* ckt, long int firstmode,
325 long int continuemode, int iterlim)
326 {
327 double OldGmin, gtarget, factor, startgmin;
328 int converged;
329
330 int NumNodes, iters, i;
331 double* OldRhsOld, * OldCKTstate0;
332 CKTnode* n;
333
334 ckt->CKTmode = firstmode;
335 SPfrontEnd->IFerrorf(ERR_INFO, "Starting true gmin stepping");
336
337 NumNodes = 0;
338 for (n = ckt->CKTnodes; n; n = n->next)
339 NumNodes++;
340
341 OldRhsOld = TMALLOC(double, NumNodes + 1);
342 OldCKTstate0 = TMALLOC(double, ckt->CKTnumStates + 1);
343
344 for (n = ckt->CKTnodes; n; n = n->next)
345 ckt->CKTrhsOld[n->number] = 0;
346
347 for (i = 0; i < ckt->CKTnumStates; i++)
348 ckt->CKTstate0[i] = 0;
349
350 startgmin = ckt->CKTgmin;
351 factor = ckt->CKTgminFactor;
352 OldGmin = 1e-2;
353 /*ckt->CKTdiagGmin = */ckt->CKTgmin = OldGmin / factor;
354 gtarget = MAX(startgmin, ckt->CKTgshunt);
355
356 for (;;) {
357 fprintf(stderr, "Trying gmin = %12.4E ", ckt->CKTgmin);
358
359 ckt->CKTnoncon = 1;
360 iters = ckt->CKTstat->STATnumIter;
361 converged = NIiter(ckt, ckt->CKTdcTrcvMaxIter);
362 iters = ckt->CKTstat->STATnumIter - iters;
363
364 if (converged == 0) {
365 ckt->CKTmode = continuemode;
366 SPfrontEnd->IFerrorf(ERR_INFO, "One successful gmin step");
367
368 if (ckt->CKTgmin <= gtarget)
369 break; /* successfull */
370
371 for (i = 0, n = ckt->CKTnodes; n; n = n->next)
372 OldRhsOld[i++] = ckt->CKTrhsOld[n->number];
373
374 memcpy(OldCKTstate0, ckt->CKTstate0,
375 (size_t)ckt->CKTnumStates * sizeof(double));
376
377 if (iters <= (ckt->CKTdcTrcvMaxIter / 4)) {
378 factor *= sqrt(factor);
379 if (factor > ckt->CKTgminFactor)
380 factor = ckt->CKTgminFactor;
381 }
382
383 if (iters > (3 * ckt->CKTdcTrcvMaxIter / 4))
384 factor = MAX(sqrt(factor), 1.00005);
385
386 OldGmin = ckt->CKTgmin;
387
388 if (ckt->CKTgmin < factor * gtarget) {
389 factor = ckt->CKTgmin / gtarget;
390 /*ckt->CKTdiagGmin = */ckt->CKTgmin = gtarget;
391 }
392 else {
393 /*ckt->CKTdiagGmin = */ckt->CKTgmin /= factor;
394 }
395 }
396 else {
397 if (factor < 1.00005) {
398 SPfrontEnd->IFerrorf(ERR_WARNING, "Last gmin step failed");
399 break; /* failed */
400 }
401 SPfrontEnd->IFerrorf(ERR_WARNING, "Further gmin increment");
402 factor = sqrt(sqrt(factor));
403 /*ckt->CKTdiagGmin = */ckt->CKTgmin = OldGmin / factor;
404
405 for (i = 0, n = ckt->CKTnodes; n; n = n->next)
406 ckt->CKTrhsOld[n->number] = OldRhsOld[i++];
407
408 memcpy(ckt->CKTstate0, OldCKTstate0,
409 (size_t)ckt->CKTnumStates * sizeof(double));
410 }
411 }
412
413 /*ckt->CKTdiagGmin = */ckt->CKTgmin = MAX(startgmin, ckt->CKTgshunt);
414 FREE(OldRhsOld);
415 FREE(OldCKTstate0);
416
417 #ifdef XSPICE
418 /* gtri - wbk - add convergence problem reporting flags */
419 ckt->enh->conv_debug.last_NIiter_call = (ckt->CKTnumSrcSteps <= 0);
420 #endif
421
422 converged = NIiter(ckt, iterlim);
423
424 if (converged != 0) {
425 SPfrontEnd->IFerrorf(ERR_WARNING, "True gmin stepping failed");
426 }
427 else {
428 SPfrontEnd->IFerrorf(ERR_INFO, "True gmin stepping completed");
429 #ifdef XSPICE
430 /* gtri - wbk - add convergence problem reporting flags */
431 ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE;
432 #endif
433 }
434
435 return converged;
436 }
437
438
439 /* Gillespie's Source stepping
440 * Modified 2005 - Paolo Nenzi (extracted from CKTop.c code)
441 *
442 * return value:
443 * 0 -> method converged
444 * 1 -> method failed
445 *
446 * Note that no path out of this code allows ckt->CKTsrcFact to be
447 * anything but 1.00000.
448 */
449
450 static int
gillespie_src(CKTcircuit * ckt,long int firstmode,long int continuemode,int iterlim)451 gillespie_src (CKTcircuit *ckt, long int firstmode,
452 long int continuemode, int iterlim)
453 {
454 int converged, i, iters;
455 double ConvFact;
456 CKTnode *n;
457 double gminstart = ckt->CKTgmin;
458
459 NG_IGNORE(iterlim);
460
461 ckt->CKTmode = firstmode;
462 SPfrontEnd->IFerrorf (ERR_INFO, "Starting source stepping");
463
464 ckt->CKTsrcFact = 0;
465 ConvFact = 0;
466
467 for (n = ckt->CKTnodes; n; n = n->next)
468 ckt->CKTrhsOld[n->number] = 0;
469
470 for (i = 0; i < ckt->CKTnumStates; i++)
471 ckt->CKTstate0[i] = 0;
472
473 /* First, try a straight solution with all sources at zero */
474
475 fprintf (stderr, "Supplies reduced to %8.4f%% ", ckt->CKTsrcFact * 100);
476 converged = NIiter (ckt, ckt->CKTdcTrcvMaxIter);
477
478 /* If this doesn't work, try gmin stepping as well for the first solution */
479
480 if (converged != 0) {
481 fprintf (stderr, "\n");
482
483 ckt->CKTdiagGmin =
484 (ckt->CKTgshunt <= 0) ? ckt->CKTgmin : ckt->CKTgshunt;
485
486 for (i = 0; i < 10; i++)
487 ckt->CKTdiagGmin *= 10;
488
489 for (i = 0; i <= 10; i++) {
490 fprintf (stderr, "Trying gmin = %12.4E ", ckt->CKTdiagGmin);
491
492 #ifdef XSPICE
493 /* gtri - wbk - add convergence problem reporting flags */
494 ckt->enh->conv_debug.last_NIiter_call = MIF_TRUE;
495 #endif
496
497 ckt->CKTnoncon = 1;
498 converged = NIiter (ckt, ckt->CKTdcTrcvMaxIter);
499
500 if (converged != 0) {
501 ckt->CKTdiagGmin = ckt->CKTgshunt;
502 SPfrontEnd->IFerrorf (ERR_WARNING, "gmin step failed");
503 #ifdef XSPICE
504 /* gtri - wbk - add convergence problem reporting flags */
505 ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE;
506 #endif
507 break;
508 }
509
510 ckt->CKTdiagGmin /= 10;
511 ckt->CKTmode = continuemode;
512 SPfrontEnd->IFerrorf (ERR_INFO, "One successful gmin step");
513 }
514 ckt->CKTdiagGmin = ckt->CKTgshunt;
515 }
516
517 /* If we've got convergence, then try stepping up the sources */
518
519 if (converged == 0) {
520
521 double *OldRhsOld, *OldCKTstate0, raise = 0.001;
522
523 int NumNodes = 0;
524 for (n = ckt->CKTnodes; n; n = n->next)
525 NumNodes++;
526
527 OldRhsOld = TMALLOC(double, NumNodes + 1);
528 OldCKTstate0 = TMALLOC(double, ckt->CKTnumStates + 1);
529
530 for (i = 0, n = ckt->CKTnodes; n; n = n->next)
531 OldRhsOld[i++] = ckt->CKTrhsOld[n->number];
532
533 memcpy(OldCKTstate0, ckt->CKTstate0,
534 (size_t) ckt->CKTnumStates * sizeof(double));
535
536 SPfrontEnd->IFerrorf (ERR_INFO, "One successful source step");
537 ckt->CKTsrcFact = ConvFact + raise;
538
539 do {
540 fprintf (stderr,
541 "Supplies reduced to %8.4f%% ", ckt->CKTsrcFact * 100);
542
543 #ifdef XSPICE
544 /* gtri - wbk - add convergence problem reporting flags */
545 ckt->enh->conv_debug.last_NIiter_call = MIF_TRUE;
546 #endif
547
548 iters = ckt->CKTstat->STATnumIter;
549 converged = NIiter (ckt, ckt->CKTdcTrcvMaxIter);
550 iters = ckt->CKTstat->STATnumIter - iters;
551
552 ckt->CKTmode = continuemode;
553
554 if (converged == 0) {
555 ConvFact = ckt->CKTsrcFact;
556
557 for (i = 0, n = ckt->CKTnodes; n; n = n->next)
558 OldRhsOld[i++] = ckt->CKTrhsOld[n->number];
559
560 memcpy(OldCKTstate0, ckt->CKTstate0,
561 (size_t) ckt->CKTnumStates * sizeof(double));
562
563 SPfrontEnd->IFerrorf (ERR_INFO, "One successful source step");
564
565 ckt->CKTsrcFact = ConvFact + raise;
566
567 if (iters <= (ckt->CKTdcTrcvMaxIter / 4))
568 raise *= 1.5;
569
570 if (iters > (3 * ckt->CKTdcTrcvMaxIter / 4))
571 raise *= 0.5;
572
573 /* if (raise > 0.01)
574 * raise = 0.01;
575 */
576
577 }
578 /* else if (ckt->CKTgmin < 1e-3){
579 ckt->CKTdiagGmin = ckt->CKTgmin *= 10;
580 fprintf(stderr,
581 "gmin raised to %8.4e\n", ckt->CKTgmin);
582 }*/
583 else {
584
585 if (ckt->CKTsrcFact - ConvFact < 1e-8)
586 break;
587
588 raise /= 10;
589
590 if (raise > 0.01)
591 raise = 0.01;
592
593 ckt->CKTsrcFact = ConvFact;
594
595 for (i = 0, n = ckt->CKTnodes; n; n = n->next)
596 ckt->CKTrhsOld[n->number] = OldRhsOld[i++];
597
598 memcpy(ckt->CKTstate0, OldCKTstate0,
599 (size_t) ckt->CKTnumStates * sizeof(double));
600 }
601
602 if (ckt->CKTsrcFact > 1)
603 ckt->CKTsrcFact = 1;
604
605 } while ((raise >= 1e-7) && (ConvFact < 1));
606
607 ckt->CKTdiagGmin = ckt->CKTgmin = gminstart;
608 FREE (OldRhsOld);
609 FREE (OldCKTstate0);
610 }
611
612 ckt->CKTsrcFact = 1;
613
614 if (ConvFact != 1) {
615 ckt->CKTcurrentAnalysis = DOING_TRAN;
616 SPfrontEnd->IFerrorf (ERR_WARNING, "source stepping failed");
617 return E_ITERLIM;
618 } else {
619 SPfrontEnd->IFerrorf (ERR_INFO, "Source stepping completed");
620 return 0;
621 }
622 }
623
624
625 /* Spice3 Source stepping
626 * Modified 2005 - Paolo Nenzi (extracted from CKTop.c code)
627 *
628 * return value:
629 * 0 -> method converged
630 * 1 -> method failed
631 *
632 * Note that no path out of this code allows ckt->CKTsrcFact to be
633 * anything but 1.00000.
634 */
635
636 static int
spice3_src(CKTcircuit * ckt,long int firstmode,long int continuemode,int iterlim)637 spice3_src (CKTcircuit *ckt, long int firstmode,
638 long int continuemode, int iterlim)
639 {
640 int converged, i;
641
642 NG_IGNORE(iterlim);
643
644 ckt->CKTmode = firstmode;
645 SPfrontEnd->IFerrorf (ERR_INFO, "Starting source stepping");
646
647 for (i = 0; i <= ckt->CKTnumSrcSteps; i++) {
648 ckt->CKTsrcFact = ((double) i) / ((double) ckt->CKTnumSrcSteps);
649 #ifdef XSPICE
650 /* gtri - wbk - add convergence problem reporting flags */
651 ckt->enh->conv_debug.last_NIiter_call = MIF_TRUE;
652 #endif
653 converged = NIiter (ckt, ckt->CKTdcTrcvMaxIter);
654 ckt->CKTmode = continuemode;
655 if (converged != 0) {
656 ckt->CKTsrcFact = 1;
657 ckt->CKTcurrentAnalysis = DOING_TRAN;
658 SPfrontEnd->IFerrorf (ERR_WARNING, "source stepping failed");
659 #ifdef XSPICE
660 /* gtri - wbk - add convergence problem reporting flags */
661 ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE;
662 #endif
663 return converged;
664 }
665 SPfrontEnd->IFerrorf (ERR_INFO, "One successful source step");
666 }
667
668 SPfrontEnd->IFerrorf (ERR_INFO, "Source stepping completed");
669 ckt->CKTsrcFact = 1;
670
671 #ifdef XSPICE
672 /* gtri - wbk - add convergence problem reporting flags */
673 ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE;
674 #endif
675
676 return 0;
677 }
678