ngspice/src/spicelib/analysis/cktop.c

642 lines
16 KiB
C
Raw Normal View History

2000-04-27 22:03:57 +02:00
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
Modified: 2000 AlansFixes
2005-06-25 21:11:57 +02:00
Modified: 2005 Paolo Nenzi - Restructured
2000-04-27 22:03:57 +02:00
**********/
#include "ngspice.h"
#include "cktdefs.h"
#include "devdefs.h"
#include "sperror.h"
2005-06-25 21:11:57 +02:00
static int dynamic_gmin (CKTcircuit *, long int, long int, int);
static int spice3_gmin (CKTcircuit *, long int, long int, int);
static int gillespie_src (CKTcircuit *, long int, long int, int);
static int spice3_src (CKTcircuit *, long int, long int, int);
2009-04-28 23:53:29 +02:00
#ifdef HAS_WINDOWS
void SetAnalyse( char * Analyse, int Percent);
#endif
2005-06-25 21:11:57 +02:00
2000-04-27 22:03:57 +02:00
int
2005-06-25 21:11:57 +02:00
CKTop (CKTcircuit * ckt, long int firstmode, long int continuemode,
int iterlim)
2000-04-27 22:03:57 +02:00
{
2005-06-25 21:11:57 +02:00
int converged;
2009-04-28 23:53:29 +02:00
#ifdef HAS_WINDOWS
SetAnalyse("op", 0);
#endif
2005-06-25 21:11:57 +02:00
ckt->CKTmode = firstmode;
if (!ckt->CKTnoOpIter){
#ifdef XSPICE
/* gtri - begin - wbk - add convergence problem reporting flags */
if ((ckt->CKTnumGminSteps <= 0) && (ckt->CKTnumSrcSteps <= 0))
ckt->enh->conv_debug.last_NIiter_call = MIF_TRUE;
else
ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE;
/* gtri - end - wbk - add convergence problem reporting flags */
#endif
converged = NIiter (ckt, iterlim);
2000-04-27 22:03:57 +02:00
} else {
2005-06-25 21:11:57 +02:00
converged = 1; /* the 'go directly to gmin stepping' option */
}
2005-06-25 21:11:57 +02:00
if (converged != 0)
{
/* no convergence on the first try, so we do something else */
/* first, check if we should try gmin stepping */
2005-06-25 21:11:57 +02:00
if (ckt->CKTnumGminSteps >= 1){
2010-03-09 20:29:44 +01:00
if (ckt->CKTnumGminSteps == 1)
2005-06-25 21:11:57 +02:00
converged = dynamic_gmin(ckt, firstmode, continuemode, iterlim);
2010-03-09 20:29:44 +01:00
else
2005-06-25 21:11:57 +02:00
converged = spice3_gmin(ckt, firstmode, continuemode, iterlim);
}
if (!converged) /* If gmin-stepping worked... move out */
return (0);
2005-06-25 21:11:57 +02:00
/* ... otherwise try stepping sources ...
* now, we'll try source stepping - we scale the sources
* to 0, converge, then start stepping them up until they
* are at their normal values
*/
2005-06-25 21:11:57 +02:00
if (ckt->CKTnumSrcSteps >= 1){
if (ckt->CKTnumSrcSteps == 1)
converged = gillespie_src(ckt, firstmode, continuemode, iterlim);
2010-03-09 20:29:44 +01:00
else
2005-06-25 21:11:57 +02:00
converged = spice3_src(ckt, firstmode, continuemode, iterlim);
2010-03-09 20:29:44 +01:00
}
2005-06-25 21:11:57 +02:00
#ifdef XSPICE
/* gtri - begin - wbk - add convergence problem reporting flags */
ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE;
/* gtri - end - wbk - add convergence problem reporting flags */
#endif
2010-03-09 20:29:44 +01:00
}
2005-06-25 21:11:57 +02:00
return (converged);
2000-04-27 22:03:57 +02:00
}
2005-06-25 21:11:57 +02:00
2000-04-27 22:03:57 +02:00
/* CKTconvTest(ckt)
* this is a driver program to iterate through all the various
* convTest functions provided for the circuit elements in the
* given circuit
*/
int
2005-06-25 21:11:57 +02:00
CKTconvTest (CKTcircuit * ckt)
2000-04-27 22:03:57 +02:00
{
2005-06-25 21:11:57 +02:00
int i;
int error = OK;
2000-04-27 22:03:57 +02:00
#ifdef PARALLEL_ARCH
2005-06-25 21:11:57 +02:00
int ibuf[2];
long type = MT_CONV, length = 2;
2000-04-27 22:03:57 +02:00
#endif /* PARALLEL_ARCH */
2005-06-25 21:11:57 +02:00
for (i = 0; i < DEVmaxnum; i++)
{
2007-06-17 05:20:42 +02:00
if (DEVices[i] && ((*DEVices[i]).DEVconvTest != NULL) && (ckt->CKThead[i] != NULL))
2005-06-25 21:11:57 +02:00
{
error = (*((*DEVices[i]).DEVconvTest)) (ckt->CKThead[i], ckt);
}
2000-04-27 22:03:57 +02:00
#ifdef PARALLEL_ARCH
2005-06-25 21:11:57 +02:00
if (error || ckt->CKTnoncon)
goto combine;
2000-04-27 22:03:57 +02:00
#else
2005-06-25 21:11:57 +02:00
if (error)
return (error);
if (ckt->CKTnoncon)
{
/* printf("convTest: device %s failed\n",
* (*DEVices[i]).DEVpublic.name); */
return (OK);
}
2000-04-27 22:03:57 +02:00
#endif /* PARALLEL_ARCH */
}
#ifdef PARALLEL_ARCH
combine:
2005-06-25 21:11:57 +02:00
/* See if any of the DEVconvTest functions bailed. If not, proceed. */
ibuf[0] = error;
ibuf[1] = ckt->CKTnoncon;
IGOP_ (&type, ibuf, &length, "+");
ckt->CKTnoncon = ibuf[1];
if (ibuf[0] != error)
{
error = E_MULTIERR;
2000-04-27 22:03:57 +02:00
}
2005-06-25 21:11:57 +02:00
return (error);
2000-04-27 22:03:57 +02:00
#else
2005-06-25 21:11:57 +02:00
return (OK);
2000-04-27 22:03:57 +02:00
#endif /* PARALLEL_ARCH */
}
2005-06-25 21:11:57 +02:00
/* Dynamic gmin stepping
* Algorithm by Alan Gillespie
* Modified 2005 - Paolo Nenzi (extracted from CKTop.c code)
*
* return value:
* 0 -> method converged
* 1 -> method failed
*
* Note that no path out of this code allows ckt->CKTdiagGmin to be
* anything but CKTgshunt.
*/
static int
dynamic_gmin (CKTcircuit * ckt, long int firstmode,
long int continuemode, int iterlim)
{
double OldGmin, gtarget, factor;
int success, failed, converged;
int NumNodes, iters, i;
double *OldRhsOld, *OldCKTstate0;
CKTnode *n;
ckt->CKTmode = firstmode;
(*(SPfrontEnd->IFerror)) (ERR_INFO,
2010-03-09 20:29:44 +01:00
"Starting dynamic gmin stepping", (IFuid *) NULL);
2005-06-25 21:11:57 +02:00
NumNodes = 0;
for (n = ckt->CKTnodes; n; n = n->next)
NumNodes++;
OldRhsOld = TMALLOC(double, NumNodes + 1);
2005-06-25 21:11:57 +02:00
OldCKTstate0 =
TMALLOC(double, ckt->CKTnumStates + 1);
2005-06-25 21:11:57 +02:00
for (n = ckt->CKTnodes; n; n = n->next)
*(ckt->CKTrhsOld + n->number) = 0;
for (i = 0; i < ckt->CKTnumStates; i++)
*(ckt->CKTstate0 + i) = 0;
factor = ckt->CKTgminFactor;
OldGmin = 1e-2;
ckt->CKTdiagGmin = OldGmin / factor;
gtarget = MAX (ckt->CKTgmin, ckt->CKTgshunt);
success = failed = 0;
while ((!success) && (!failed)){
2010-03-09 20:29:44 +01:00
fprintf (stderr, "Trying gmin = %12.4E ", ckt->CKTdiagGmin);
2005-06-25 21:11:57 +02:00
ckt->CKTnoncon = 1;
iters = ckt->CKTstat->STATnumIter;
converged = NIiter (ckt, ckt->CKTdcTrcvMaxIter);
iters = (ckt->CKTstat->STATnumIter) - iters;
if (converged == 0){
2010-03-09 20:29:44 +01:00
ckt->CKTmode = continuemode;
(*(SPfrontEnd->IFerror)) (ERR_INFO,
"One successful gmin step", (IFuid *) NULL);
2005-06-25 21:11:57 +02:00
2010-03-09 20:29:44 +01:00
if (ckt->CKTdiagGmin <= gtarget){
2005-06-25 21:11:57 +02:00
success = 1;
2010-03-09 20:29:44 +01:00
} else {
i = 0;
for (n = ckt->CKTnodes; n; n = n->next){
2005-06-25 21:11:57 +02:00
OldRhsOld[i] = *(ckt->CKTrhsOld + n->number);
i++;
2010-03-09 20:29:44 +01:00
}
2005-06-25 21:11:57 +02:00
2010-03-09 20:29:44 +01:00
for (i = 0; i < ckt->CKTnumStates; i++){
2005-06-25 21:11:57 +02:00
*(OldCKTstate0 + i) = *(ckt->CKTstate0 + i);
2010-03-09 20:29:44 +01:00
}
2005-06-25 21:11:57 +02:00
2010-03-09 20:29:44 +01:00
if (iters <= (ckt->CKTdcTrcvMaxIter / 4)){
2005-06-25 21:11:57 +02:00
factor *= sqrt (factor);
if (factor > ckt->CKTgminFactor)
factor = ckt->CKTgminFactor;
2010-03-09 20:29:44 +01:00
}
2005-06-25 21:11:57 +02:00
2010-03-09 20:29:44 +01:00
if (iters > (3 * ckt->CKTdcTrcvMaxIter / 4))
2005-06-25 21:11:57 +02:00
factor = sqrt (factor);
2010-03-09 20:29:44 +01:00
OldGmin = ckt->CKTdiagGmin;
2005-06-25 21:11:57 +02:00
2010-03-09 20:29:44 +01:00
if ((ckt->CKTdiagGmin) < (factor * gtarget)){
2005-06-25 21:11:57 +02:00
factor = ckt->CKTdiagGmin / gtarget;
ckt->CKTdiagGmin = gtarget;
2010-03-09 20:29:44 +01:00
} else {
2005-06-25 21:11:57 +02:00
ckt->CKTdiagGmin /= factor;
}
2010-03-09 20:29:44 +01:00
}
} else {
if (factor < 1.00005){
failed = 1;
(*(SPfrontEnd->IFerror)) (ERR_WARNING,
2005-06-25 21:11:57 +02:00
"Last gmin step failed",
(IFuid *) NULL);
2010-03-09 20:29:44 +01:00
} else {
(*(SPfrontEnd->IFerror)) (ERR_WARNING,
"Further gmin increment",
(IFuid *) NULL);
factor = sqrt (sqrt (factor));
ckt->CKTdiagGmin = OldGmin / factor;
2005-06-25 21:11:57 +02:00
2010-03-09 20:29:44 +01:00
i = 0;
for (n = ckt->CKTnodes; n; n = n->next){
2005-06-25 21:11:57 +02:00
*(ckt->CKTrhsOld + n->number) = OldRhsOld[i];
i++;
}
2010-03-09 20:29:44 +01:00
for (i = 0; i < ckt->CKTnumStates; i++){
2005-06-25 21:11:57 +02:00
*(ckt->CKTstate0 + i) = *(OldCKTstate0 + i);
}
2010-03-09 20:29:44 +01:00
}
2005-06-25 21:11:57 +02:00
}
2010-03-09 20:29:44 +01:00
}
2005-06-25 21:11:57 +02:00
ckt->CKTdiagGmin = ckt->CKTgshunt;
FREE (OldRhsOld);
FREE (OldCKTstate0);
#ifdef XSPICE
/* gtri - begin - wbk - add convergence problem reporting flags */
if (ckt->CKTnumSrcSteps <= 0)
ckt->enh->conv_debug.last_NIiter_call = MIF_TRUE;
else
ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE;
/* gtri - end - wbk - add convergence problem reporting flags */
#endif
converged = NIiter (ckt, iterlim);
if (converged != 0){
(*(SPfrontEnd->IFerror)) (ERR_WARNING,
2010-03-09 20:29:44 +01:00
"Dynamic gmin stepping failed",
2005-06-25 21:11:57 +02:00
(IFuid *) NULL);
} else {
(*(SPfrontEnd->IFerror)) (ERR_INFO,
2010-03-09 20:29:44 +01:00
"Dynamic gmin stepping completed",
2005-06-25 21:11:57 +02:00
(IFuid *) NULL);
#ifdef XSPICE
/* gtri - begin - wbk - add convergence problem reporting flags */
ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE;
/* gtri - end - wbk - add convergence problem reporting flags */
#endif
}
return (converged);
}
/* Spice3 gmin stepping
* Modified 2000 - Alan Gillespie (added gshunt)
* Modified 2005 - Paolo Nenzi (extracted from CKTop.c code)
*
* return value:
* 0 -> method converged
* 1 -> method failed
*
* Note that no path out of this code allows ckt->CKTdiagGmin to be
* anything but CKTgshunt.
*/
static int
spice3_gmin (CKTcircuit * ckt, long int firstmode,
long int continuemode, int iterlim)
{
int converged, i;
ckt->CKTmode = firstmode;
(*(SPfrontEnd->IFerror)) (ERR_INFO,
2010-03-09 20:29:44 +01:00
"Starting gmin stepping", (IFuid *) NULL);
2005-06-25 21:11:57 +02:00
if (ckt->CKTgshunt == 0)
ckt->CKTdiagGmin = ckt->CKTgmin;
else
ckt->CKTdiagGmin = ckt->CKTgshunt;
for (i = 0; i < ckt->CKTnumGminSteps; i++)
ckt->CKTdiagGmin *= ckt->CKTgminFactor;
for (i = 0; i <= ckt->CKTnumGminSteps; i++){
fprintf (stderr, "Trying gmin = %12.4E ", ckt->CKTdiagGmin);
ckt->CKTnoncon = 1;
converged = NIiter (ckt, ckt->CKTdcTrcvMaxIter);
if (converged != 0){
ckt->CKTdiagGmin = ckt->CKTgshunt;
(*(SPfrontEnd->IFerror)) (ERR_WARNING,
2010-03-09 20:29:44 +01:00
"gmin step failed", (IFuid *) NULL);
2005-06-25 21:11:57 +02:00
break;
2010-03-09 20:29:44 +01:00
}
2005-06-25 21:11:57 +02:00
ckt->CKTdiagGmin /= ckt->CKTgminFactor;
ckt->CKTmode = continuemode;
(*(SPfrontEnd->IFerror)) (ERR_INFO,
2010-03-09 20:29:44 +01:00
"One successful gmin step", (IFuid *) NULL);
}
2005-06-25 21:11:57 +02:00
ckt->CKTdiagGmin = ckt->CKTgshunt;
#ifdef XSPICE
/* gtri - begin - wbk - add convergence problem reporting flags */
if (ckt->CKTnumSrcSteps <= 0)
ckt->enh->conv_debug.last_NIiter_call = MIF_TRUE;
else
ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE;
/* gtri - end - wbk - add convergence problem reporting flags */
#endif
converged = NIiter (ckt, iterlim);
if (converged == 0){
(*(SPfrontEnd->IFerror)) (ERR_INFO,
2010-03-09 20:29:44 +01:00
"gmin stepping completed", (IFuid *) NULL);
2005-06-25 21:11:57 +02:00
#ifdef XSPICE
/* gtri - begin - wbk - add convergence problem reporting flags */
ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE;
/* gtri - end - wbk - add convergence problem reporting flags */
#endif
} else {
(*(SPfrontEnd->IFerror)) (ERR_WARNING,
2010-03-09 20:29:44 +01:00
"gmin stepping failed", (IFuid *) NULL);
2005-06-25 21:11:57 +02:00
}
return (converged);
}
/* Gillespie's Source stepping
* Modified 2005 - Paolo Nenzi (extracted from CKTop.c code)
*
* return value:
* 0 -> method converged
* 1 -> method failed
*
* Note that no path out of this code allows ckt->CKTsrcFact to be
* anything but 1.00000.
*/
static int
gillespie_src (CKTcircuit * ckt, long int firstmode,
long int continuemode, int iterlim)
{
int converged, NumNodes, i, iters;
double raise, ConvFact;
double *OldRhsOld, *OldCKTstate0;
CKTnode *n;
ckt->CKTmode = firstmode;
(*(SPfrontEnd->IFerror)) (ERR_INFO,
2010-03-09 20:29:44 +01:00
"Starting source stepping", (IFuid *) NULL);
2005-06-25 21:11:57 +02:00
ckt->CKTsrcFact = 0;
raise = 0.001;
ConvFact = 0;
NumNodes = 0;
for (n = ckt->CKTnodes; n; n = n->next){
NumNodes++;
2010-03-09 20:29:44 +01:00
}
2005-06-25 21:11:57 +02:00
OldRhsOld = TMALLOC(double, NumNodes + 1);
2005-06-25 21:11:57 +02:00
OldCKTstate0 =
TMALLOC(double, ckt->CKTnumStates + 1);
2005-06-25 21:11:57 +02:00
for (n = ckt->CKTnodes; n; n = n->next)
*(ckt->CKTrhsOld + n->number) = 0;
for (i = 0; i < ckt->CKTnumStates; i++)
*(ckt->CKTstate0 + i) = 0;
/* First, try a straight solution with all sources at zero */
2010-03-25 23:44:37 +01:00
fprintf (stderr, "Supplies reduced to %8.4f%% ", ckt->CKTsrcFact * 100);
2005-06-25 21:11:57 +02:00
converged = NIiter (ckt, ckt->CKTdcTrcvMaxIter);
/* If this doesn't work, try gmin stepping as well for the first solution */
if (converged != 0){
fprintf (stderr, "\n");
if (ckt->CKTgshunt <= 0){
ckt->CKTdiagGmin = ckt->CKTgmin;
2010-03-09 20:29:44 +01:00
} else {
2005-06-25 21:11:57 +02:00
ckt->CKTdiagGmin = ckt->CKTgshunt;
2010-03-09 20:29:44 +01:00
}
2005-06-25 21:11:57 +02:00
for (i = 0; i < 10; i++)
ckt->CKTdiagGmin *= 10;
for (i = 0; i <= 10; i++){
fprintf (stderr, "Trying gmin = %12.4E ", ckt->CKTdiagGmin);
ckt->CKTnoncon = 1;
#ifdef XSPICE
/* gtri - begin - wbk - add convergence problem reporting flags */
ckt->enh->conv_debug.last_NIiter_call = MIF_TRUE;
/* gtri - end - wbk - add convergence problem reporting flags */
#endif
converged = NIiter (ckt, ckt->CKTdcTrcvMaxIter);
if (converged != 0){
ckt->CKTdiagGmin = ckt->CKTgshunt;
(*(SPfrontEnd->IFerror)) (ERR_WARNING,
2010-03-09 20:29:44 +01:00
"gmin step failed", (IFuid *) NULL);
2005-06-25 21:11:57 +02:00
#ifdef XSPICE
/* gtri - begin - wbk - add convergence problem reporting flags */
ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE;
/* gtri - end - wbk - add convergence problem reporting flags */
#endif
break;
2010-03-09 20:29:44 +01:00
}
2005-06-25 21:11:57 +02:00
ckt->CKTdiagGmin /= 10;
ckt->CKTmode = continuemode;
(*(SPfrontEnd->IFerror)) (ERR_INFO,
2010-03-09 20:29:44 +01:00
"One successful gmin step",
2005-06-25 21:11:57 +02:00
(IFuid *) NULL);
2010-03-09 20:29:44 +01:00
}
2005-06-25 21:11:57 +02:00
ckt->CKTdiagGmin = ckt->CKTgshunt;
}
/* If we've got convergence, then try stepping up the sources */
if (converged == 0){
i = 0;
for (n = ckt->CKTnodes; n; n = n->next){
OldRhsOld[i] = *(ckt->CKTrhsOld + n->number);
i++;
}
for (i = 0; i < ckt->CKTnumStates; i++)
*(OldCKTstate0 + i) = *(ckt->CKTstate0 + i);
(*(SPfrontEnd->IFerror)) (ERR_INFO,
"One successful source step", (IFuid *) NULL);
ckt->CKTsrcFact = ConvFact + raise;
2010-03-09 20:29:44 +01:00
}
2005-06-25 21:11:57 +02:00
if (converged == 0)
do {
fprintf (stderr,
2010-03-25 23:44:37 +01:00
"Supplies reduced to %8.4f%% ", ckt->CKTsrcFact * 100);
2005-06-25 21:11:57 +02:00
iters = ckt->CKTstat->STATnumIter;
#ifdef XSPICE
/* gtri - begin - wbk - add convergence problem reporting flags */
ckt->enh->conv_debug.last_NIiter_call = MIF_TRUE;
/* gtri - end - wbk - add convergence problem reporting flags */
#endif
converged = NIiter (ckt, ckt->CKTdcTrcvMaxIter);
iters = (ckt->CKTstat->STATnumIter) - iters;
ckt->CKTmode = continuemode;
if (converged == 0){
ConvFact = ckt->CKTsrcFact;
i = 0;
for (n = ckt->CKTnodes; n; n = n->next){
OldRhsOld[i] = *(ckt->CKTrhsOld + n->number);
i++;
}
for (i = 0; i < ckt->CKTnumStates; i++)
*(OldCKTstate0 + i) = *(ckt->CKTstate0 + i);
(*(SPfrontEnd->IFerror)) (ERR_INFO,
"One successful source step",
(IFuid *) NULL);
ckt->CKTsrcFact = ConvFact + raise;
if (iters <= (ckt->CKTdcTrcvMaxIter / 4)){
raise = raise * 1.5;
}
if (iters > (3 * ckt->CKTdcTrcvMaxIter / 4)){
raise = raise * 0.5;
}
/* if (raise>0.01) raise=0.01; */
} else {
if ((ckt->CKTsrcFact - ConvFact) < 1e-8)
break;
raise = raise / 10;
if (raise > 0.01)
raise = 0.01;
ckt->CKTsrcFact = ConvFact;
i = 0;
for (n = ckt->CKTnodes; n; n = n->next){
*(ckt->CKTrhsOld + n->number) = OldRhsOld[i];
i++;
}
for (i = 0; i < ckt->CKTnumStates; i++)
*(ckt->CKTstate0 + i) = *(OldCKTstate0 + i);
}
if ((ckt->CKTsrcFact) > 1)
ckt->CKTsrcFact = 1;
}
while ((raise >= 1e-7) && (ConvFact < 1));
FREE (OldRhsOld);
FREE (OldCKTstate0);
ckt->CKTsrcFact = 1;
if (ConvFact != 1)
{
ckt->CKTsrcFact = 1;
ckt->CKTcurrentAnalysis = DOING_TRAN;
(*(SPfrontEnd->IFerror)) (ERR_WARNING,
"source stepping failed", (IFuid *) NULL);
return (E_ITERLIM);
}
else
{
(*(SPfrontEnd->IFerror)) (ERR_INFO,
"Source stepping completed", (IFuid *) NULL);
return (0);
}
}
/* Spice3 Source stepping
* Modified 2005 - Paolo Nenzi (extracted from CKTop.c code)
*
* return value:
* 0 -> method converged
* 1 -> method failed
*
* Note that no path out of this code allows ckt->CKTsrcFact to be
* anything but 1.00000.
*/
static int
spice3_src (CKTcircuit * ckt, long int firstmode,
long int continuemode, int iterlim)
{
int converged, i;
ckt->CKTmode = firstmode;
(*(SPfrontEnd->IFerror)) (ERR_INFO,
2010-03-09 20:29:44 +01:00
"Starting source stepping", (IFuid *) NULL);
2005-06-25 21:11:57 +02:00
for (i = 0; i <= ckt->CKTnumSrcSteps; i++)
{
ckt->CKTsrcFact = ((double) i) / ((double) ckt->CKTnumSrcSteps);
#ifdef XSPICE
/* gtri - begin - wbk - add convergence problem reporting flags */
ckt->enh->conv_debug.last_NIiter_call = MIF_TRUE;
/* gtri - end - wbk - add convergence problem reporting flags */
#endif
converged = NIiter (ckt, ckt->CKTdcTrcvMaxIter);
ckt->CKTmode = continuemode;
if (converged != 0)
{
ckt->CKTsrcFact = 1;
ckt->CKTcurrentAnalysis = DOING_TRAN;
(*(SPfrontEnd->IFerror)) (ERR_WARNING,
"source stepping failed", (IFuid *) NULL);
#ifdef XSPICE
/* gtri - begin - wbk - add convergence problem reporting flags */
ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE;
/* gtri - end - wbk - add convergence problem reporting flags */
#endif
return (converged);
}
(*(SPfrontEnd->IFerror)) (ERR_INFO,
"One successful source step", (IFuid *) NULL);
}
(*(SPfrontEnd->IFerror)) (ERR_INFO,
"Source stepping completed", (IFuid *) NULL);
ckt->CKTsrcFact = 1;
#ifdef XSPICE
/* gtri - begin - wbk - add convergence problem reporting flags */
ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE;
/* gtri - end - wbk - add convergence problem reporting flags */
#endif
return (0);
}