cktop.c: indentation

This commit is contained in:
h_vogt 2013-06-09 10:20:20 +02:00
parent 4f2b086e15
commit 2c5b78c18b
1 changed files with 423 additions and 433 deletions

View File

@ -21,61 +21,60 @@ int
CKTop (CKTcircuit * ckt, long int firstmode, long int continuemode, CKTop (CKTcircuit * ckt, long int firstmode, long int continuemode,
int iterlim) int iterlim)
{ {
int converged; int converged;
#ifdef HAS_PROGREP #ifdef HAS_PROGREP
SetAnalyse("op", 0); SetAnalyse("op", 0);
#endif #endif
ckt->CKTmode = firstmode; ckt->CKTmode = firstmode;
if (!ckt->CKTnoOpIter){ if (!ckt->CKTnoOpIter) {
#ifdef XSPICE #ifdef XSPICE
/* gtri - begin - wbk - add convergence problem reporting flags */ /* gtri - begin - wbk - add convergence problem reporting flags */
if ((ckt->CKTnumGminSteps <= 0) && (ckt->CKTnumSrcSteps <= 0)) if ((ckt->CKTnumGminSteps <= 0) && (ckt->CKTnumSrcSteps <= 0))
ckt->enh->conv_debug.last_NIiter_call = MIF_TRUE; ckt->enh->conv_debug.last_NIiter_call = MIF_TRUE;
else else
ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE; ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE;
/* gtri - end - wbk - add convergence problem reporting flags */ /* gtri - end - wbk - add convergence problem reporting flags */
#endif #endif
converged = NIiter (ckt, iterlim); converged = NIiter (ckt, iterlim);
} else { } else {
converged = 1; /* the 'go directly to gmin stepping' option */ converged = 1; /* the 'go directly to gmin stepping' option */
} }
if (converged != 0) if (converged != 0) {
{ /* no convergence on the first try, so we do something else */
/* no convergence on the first try, so we do something else */ /* first, check if we should try gmin stepping */
/* first, check if we should try gmin stepping */
if (ckt->CKTnumGminSteps >= 1){ if (ckt->CKTnumGminSteps >= 1) {
if (ckt->CKTnumGminSteps == 1) if (ckt->CKTnumGminSteps == 1)
converged = dynamic_gmin(ckt, firstmode, continuemode, iterlim); converged = dynamic_gmin(ckt, firstmode, continuemode, iterlim);
else else
converged = spice3_gmin(ckt, firstmode, continuemode, iterlim); converged = spice3_gmin(ckt, firstmode, continuemode, iterlim);
} }
if (!converged) /* If gmin-stepping worked... move out */ if (!converged) /* If gmin-stepping worked... move out */
return (0); return (0);
/* ... otherwise try stepping sources ... /* ... otherwise try stepping sources ...
* now, we'll try source stepping - we scale the sources * now, we'll try source stepping - we scale the sources
* to 0, converge, then start stepping them up until they * to 0, converge, then start stepping them up until they
* are at their normal values * are at their normal values
*/ */
if (ckt->CKTnumSrcSteps >= 1){ if (ckt->CKTnumSrcSteps >= 1) {
if (ckt->CKTnumSrcSteps == 1) if (ckt->CKTnumSrcSteps == 1)
converged = gillespie_src(ckt, firstmode, continuemode, iterlim); converged = gillespie_src(ckt, firstmode, continuemode, iterlim);
else else
converged = spice3_src(ckt, firstmode, continuemode, iterlim); converged = spice3_src(ckt, firstmode, continuemode, iterlim);
} }
#ifdef XSPICE #ifdef XSPICE
/* gtri - begin - wbk - add convergence problem reporting flags */ /* gtri - begin - wbk - add convergence problem reporting flags */
ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE; ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE;
/* gtri - end - wbk - add convergence problem reporting flags */ /* gtri - end - wbk - add convergence problem reporting flags */
#endif #endif
} }
return (converged); return (converged);
} }
@ -93,18 +92,15 @@ CKTconvTest (CKTcircuit * ckt)
int i; int i;
int error = OK; int error = OK;
for (i = 0; i < DEVmaxnum; i++) for (i = 0; i < DEVmaxnum; i++) {
{ if (DEVices[i] && DEVices[i]->DEVconvTest && ckt->CKThead[i]) {
if (DEVices[i] && DEVices[i]->DEVconvTest && ckt->CKThead[i])
{
error = DEVices[i]->DEVconvTest (ckt->CKThead[i], ckt); error = DEVices[i]->DEVconvTest (ckt->CKThead[i], ckt);
} }
if (error) if (error)
return (error); return (error);
if (ckt->CKTnoncon) if (ckt->CKTnoncon) {
{
/* printf("convTest: device %s failed\n", /* printf("convTest: device %s failed\n",
* DEVices[i]->DEVpublic.name); */ * DEVices[i]->DEVpublic.name); */
return (OK); return (OK);
@ -129,140 +125,140 @@ CKTconvTest (CKTcircuit * ckt)
static int static int
dynamic_gmin (CKTcircuit * ckt, long int firstmode, dynamic_gmin (CKTcircuit * ckt, long int firstmode,
long int continuemode, int iterlim) long int continuemode, int iterlim)
{ {
double OldGmin, gtarget, factor; double OldGmin, gtarget, factor;
int success, failed, converged; int success, failed, converged;
int NumNodes, iters, i; int NumNodes, iters, i;
double *OldRhsOld, *OldCKTstate0; double *OldRhsOld, *OldCKTstate0;
CKTnode *n; CKTnode *n;
ckt->CKTmode = firstmode; ckt->CKTmode = firstmode;
SPfrontEnd->IFerror (ERR_INFO, SPfrontEnd->IFerror (ERR_INFO,
"Starting dynamic gmin stepping", NULL); "Starting dynamic gmin stepping", NULL);
NumNodes = 0; NumNodes = 0;
for (n = ckt->CKTnodes; n; n = n->next) for (n = ckt->CKTnodes; n; n = n->next)
NumNodes++; NumNodes++;
OldRhsOld = TMALLOC(double, NumNodes + 1); OldRhsOld = TMALLOC(double, NumNodes + 1);
OldCKTstate0 = OldCKTstate0 =
TMALLOC(double, ckt->CKTnumStates + 1); TMALLOC(double, ckt->CKTnumStates + 1);
for (n = ckt->CKTnodes; n; n = n->next) for (n = ckt->CKTnodes; n; n = n->next)
ckt->CKTrhsOld [n->number] = 0; ckt->CKTrhsOld [n->number] = 0;
for (i = 0; i < ckt->CKTnumStates; i++) for (i = 0; i < ckt->CKTnumStates; i++)
ckt->CKTstate0 [i] = 0; ckt->CKTstate0 [i] = 0;
factor = ckt->CKTgminFactor; factor = ckt->CKTgminFactor;
OldGmin = 1e-2; OldGmin = 1e-2;
ckt->CKTdiagGmin = OldGmin / factor; ckt->CKTdiagGmin = OldGmin / factor;
gtarget = MAX (ckt->CKTgmin, ckt->CKTgshunt); gtarget = MAX (ckt->CKTgmin, ckt->CKTgshunt);
success = failed = 0; success = failed = 0;
while ((!success) && (!failed)){ while ((!success) && (!failed)) {
fprintf (stderr, "Trying gmin = %12.4E ", ckt->CKTdiagGmin); fprintf (stderr, "Trying gmin = %12.4E ", ckt->CKTdiagGmin);
ckt->CKTnoncon = 1; ckt->CKTnoncon = 1;
iters = ckt->CKTstat->STATnumIter; iters = ckt->CKTstat->STATnumIter;
converged = NIiter (ckt, ckt->CKTdcTrcvMaxIter); converged = NIiter (ckt, ckt->CKTdcTrcvMaxIter);
iters = (ckt->CKTstat->STATnumIter) - iters; iters = (ckt->CKTstat->STATnumIter) - iters;
if (converged == 0){ if (converged == 0) {
ckt->CKTmode = continuemode; ckt->CKTmode = continuemode;
SPfrontEnd->IFerror (ERR_INFO, SPfrontEnd->IFerror (ERR_INFO,
"One successful gmin step", NULL); "One successful gmin step", NULL);
if (ckt->CKTdiagGmin <= gtarget){ if (ckt->CKTdiagGmin <= gtarget) {
success = 1; success = 1;
} else { } else {
i = 0; i = 0;
for (n = ckt->CKTnodes; n; n = n->next){ for (n = ckt->CKTnodes; n; n = n->next) {
OldRhsOld[i] = ckt->CKTrhsOld[n->number]; OldRhsOld[i] = ckt->CKTrhsOld[n->number];
i++; i++;
} }
for (i = 0; i < ckt->CKTnumStates; i++){ for (i = 0; i < ckt->CKTnumStates; i++) {
OldCKTstate0[i] = ckt->CKTstate0[i]; OldCKTstate0[i] = ckt->CKTstate0[i];
} }
if (iters <= (ckt->CKTdcTrcvMaxIter / 4)){ if (iters <= (ckt->CKTdcTrcvMaxIter / 4)) {
factor *= sqrt (factor); factor *= sqrt (factor);
if (factor > ckt->CKTgminFactor) if (factor > ckt->CKTgminFactor)
factor = ckt->CKTgminFactor; factor = ckt->CKTgminFactor;
} }
if (iters > (3 * ckt->CKTdcTrcvMaxIter / 4)) if (iters > (3 * ckt->CKTdcTrcvMaxIter / 4))
factor = sqrt (factor); factor = sqrt (factor);
OldGmin = ckt->CKTdiagGmin; OldGmin = ckt->CKTdiagGmin;
if ((ckt->CKTdiagGmin) < (factor * gtarget)){ if ((ckt->CKTdiagGmin) < (factor * gtarget)) {
factor = ckt->CKTdiagGmin / gtarget; factor = ckt->CKTdiagGmin / gtarget;
ckt->CKTdiagGmin = gtarget; ckt->CKTdiagGmin = gtarget;
} else { } else {
ckt->CKTdiagGmin /= factor; ckt->CKTdiagGmin /= factor;
} }
} }
} else { } else {
if (factor < 1.00005){ if (factor < 1.00005) {
failed = 1; failed = 1;
SPfrontEnd->IFerror (ERR_WARNING, SPfrontEnd->IFerror (ERR_WARNING,
"Last gmin step failed", "Last gmin step failed",
NULL); NULL);
} else { } else {
SPfrontEnd->IFerror (ERR_WARNING, SPfrontEnd->IFerror (ERR_WARNING,
"Further gmin increment", "Further gmin increment",
NULL); NULL);
factor = sqrt (sqrt (factor)); factor = sqrt (sqrt (factor));
ckt->CKTdiagGmin = OldGmin / factor; ckt->CKTdiagGmin = OldGmin / factor;
i = 0; i = 0;
for (n = ckt->CKTnodes; n; n = n->next){ for (n = ckt->CKTnodes; n; n = n->next) {
ckt->CKTrhsOld[n->number] = OldRhsOld[i]; ckt->CKTrhsOld[n->number] = OldRhsOld[i];
i++; i++;
} }
for (i = 0; i < ckt->CKTnumStates; i++){ for (i = 0; i < ckt->CKTnumStates; i++) {
ckt->CKTstate0[i] = OldCKTstate0[i]; ckt->CKTstate0[i] = OldCKTstate0[i];
} }
} }
} }
} }
ckt->CKTdiagGmin = ckt->CKTgshunt; ckt->CKTdiagGmin = ckt->CKTgshunt;
FREE (OldRhsOld); FREE (OldRhsOld);
FREE (OldCKTstate0); FREE (OldCKTstate0);
#ifdef XSPICE #ifdef XSPICE
/* gtri - begin - wbk - add convergence problem reporting flags */ /* gtri - begin - wbk - add convergence problem reporting flags */
if (ckt->CKTnumSrcSteps <= 0) if (ckt->CKTnumSrcSteps <= 0)
ckt->enh->conv_debug.last_NIiter_call = MIF_TRUE; ckt->enh->conv_debug.last_NIiter_call = MIF_TRUE;
else else
ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE; ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE;
/* gtri - end - wbk - add convergence problem reporting flags */ /* gtri - end - wbk - add convergence problem reporting flags */
#endif #endif
converged = NIiter (ckt, iterlim); converged = NIiter (ckt, iterlim);
if (converged != 0){ if (converged != 0) {
SPfrontEnd->IFerror (ERR_WARNING, SPfrontEnd->IFerror (ERR_WARNING,
"Dynamic gmin stepping failed", "Dynamic gmin stepping failed",
NULL); NULL);
} else { } else {
SPfrontEnd->IFerror (ERR_INFO, SPfrontEnd->IFerror (ERR_INFO,
"Dynamic gmin stepping completed", "Dynamic gmin stepping completed",
NULL); NULL);
#ifdef XSPICE #ifdef XSPICE
/* gtri - begin - wbk - add convergence problem reporting flags */ /* gtri - begin - wbk - add convergence problem reporting flags */
ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE; ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE;
/* gtri - end - wbk - add convergence problem reporting flags */ /* gtri - end - wbk - add convergence problem reporting flags */
#endif #endif
} }
return (converged); return (converged);
} }
@ -280,72 +276,72 @@ dynamic_gmin (CKTcircuit * ckt, long int firstmode,
static int static int
spice3_gmin (CKTcircuit * ckt, long int firstmode, spice3_gmin (CKTcircuit * ckt, long int firstmode,
long int continuemode, int iterlim) long int continuemode, int iterlim)
{ {
int converged, i; int converged, i;
ckt->CKTmode = firstmode; ckt->CKTmode = firstmode;
SPfrontEnd->IFerror (ERR_INFO, SPfrontEnd->IFerror (ERR_INFO,
"Starting gmin stepping", NULL); "Starting gmin stepping", NULL);
if (ckt->CKTgshunt == 0) if (ckt->CKTgshunt == 0)
ckt->CKTdiagGmin = ckt->CKTgmin; ckt->CKTdiagGmin = ckt->CKTgmin;
else else
ckt->CKTdiagGmin = ckt->CKTgshunt; ckt->CKTdiagGmin = ckt->CKTgshunt;
for (i = 0; i < ckt->CKTnumGminSteps; i++) for (i = 0; i < ckt->CKTnumGminSteps; i++)
ckt->CKTdiagGmin *= ckt->CKTgminFactor; ckt->CKTdiagGmin *= ckt->CKTgminFactor;
for (i = 0; i <= ckt->CKTnumGminSteps; i++){ for (i = 0; i <= ckt->CKTnumGminSteps; i++) {
fprintf (stderr, "Trying gmin = %12.4E ", ckt->CKTdiagGmin); fprintf (stderr, "Trying gmin = %12.4E ", ckt->CKTdiagGmin);
ckt->CKTnoncon = 1; ckt->CKTnoncon = 1;
converged = NIiter (ckt, ckt->CKTdcTrcvMaxIter); converged = NIiter (ckt, ckt->CKTdcTrcvMaxIter);
if (converged != 0){ if (converged != 0) {
ckt->CKTdiagGmin = ckt->CKTgshunt; ckt->CKTdiagGmin = ckt->CKTgshunt;
SPfrontEnd->IFerror (ERR_WARNING, SPfrontEnd->IFerror (ERR_WARNING,
"gmin step failed", NULL); "gmin step failed", NULL);
break; break;
} }
ckt->CKTdiagGmin /= ckt->CKTgminFactor; ckt->CKTdiagGmin /= ckt->CKTgminFactor;
ckt->CKTmode = continuemode; ckt->CKTmode = continuemode;
SPfrontEnd->IFerror (ERR_INFO, SPfrontEnd->IFerror (ERR_INFO,
"One successful gmin step", NULL); "One successful gmin step", NULL);
} }
ckt->CKTdiagGmin = ckt->CKTgshunt; ckt->CKTdiagGmin = ckt->CKTgshunt;
#ifdef XSPICE #ifdef XSPICE
/* gtri - begin - wbk - add convergence problem reporting flags */ /* gtri - begin - wbk - add convergence problem reporting flags */
if (ckt->CKTnumSrcSteps <= 0) if (ckt->CKTnumSrcSteps <= 0)
ckt->enh->conv_debug.last_NIiter_call = MIF_TRUE; ckt->enh->conv_debug.last_NIiter_call = MIF_TRUE;
else else
ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE; ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE;
/* gtri - end - wbk - add convergence problem reporting flags */ /* gtri - end - wbk - add convergence problem reporting flags */
#endif #endif
converged = NIiter (ckt, iterlim); converged = NIiter (ckt, iterlim);
if (converged == 0){ if (converged == 0) {
SPfrontEnd->IFerror (ERR_INFO, SPfrontEnd->IFerror (ERR_INFO,
"gmin stepping completed", NULL); "gmin stepping completed", NULL);
#ifdef XSPICE #ifdef XSPICE
/* gtri - begin - wbk - add convergence problem reporting flags */ /* gtri - begin - wbk - add convergence problem reporting flags */
ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE; ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE;
/* gtri - end - wbk - add convergence problem reporting flags */ /* gtri - end - wbk - add convergence problem reporting flags */
#endif #endif
} else { } else {
SPfrontEnd->IFerror (ERR_WARNING, SPfrontEnd->IFerror (ERR_WARNING,
"gmin stepping failed", NULL); "gmin stepping failed", NULL);
} }
return (converged); return (converged);
} }
@ -362,201 +358,197 @@ spice3_gmin (CKTcircuit * ckt, long int firstmode,
*/ */
static int static int
gillespie_src (CKTcircuit * ckt, long int firstmode, gillespie_src (CKTcircuit * ckt, long int firstmode,
long int continuemode, int iterlim) long int continuemode, int iterlim)
{ {
int converged, NumNodes, i, iters; int converged, NumNodes, i, iters;
double raise, ConvFact; double raise, ConvFact;
double *OldRhsOld, *OldCKTstate0; double *OldRhsOld, *OldCKTstate0;
CKTnode *n; CKTnode *n;
NG_IGNORE(iterlim); NG_IGNORE(iterlim);
ckt->CKTmode = firstmode; ckt->CKTmode = firstmode;
SPfrontEnd->IFerror (ERR_INFO, SPfrontEnd->IFerror (ERR_INFO,
"Starting source stepping", NULL); "Starting source stepping", NULL);
ckt->CKTsrcFact = 0; ckt->CKTsrcFact = 0;
raise = 0.001; raise = 0.001;
ConvFact = 0; ConvFact = 0;
NumNodes = 0; NumNodes = 0;
for (n = ckt->CKTnodes; n; n = n->next){ for (n = ckt->CKTnodes; n; n = n->next) {
NumNodes++; NumNodes++;
}
OldRhsOld = TMALLOC(double, NumNodes + 1);
OldCKTstate0 =
TMALLOC(double, ckt->CKTnumStates + 1);
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 */
fprintf (stderr, "Supplies reduced to %8.4f%% ", ckt->CKTsrcFact * 100);
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;
} else {
ckt->CKTdiagGmin = ckt->CKTgshunt;
}
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,
"gmin step failed", 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
break;
}
ckt->CKTdiagGmin /= 10;
ckt->CKTmode = continuemode;
SPfrontEnd->IFerror (ERR_INFO,
"One successful gmin step",
NULL);
}
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", NULL);
ckt->CKTsrcFact = ConvFact + raise;
}
if (converged == 0)
do {
fprintf (stderr,
"Supplies reduced to %8.4f%% ", ckt->CKTsrcFact * 100);
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",
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", NULL);
return (E_ITERLIM);
} }
else
{ OldRhsOld = TMALLOC(double, NumNodes + 1);
SPfrontEnd->IFerror (ERR_INFO, OldCKTstate0 =
"Source stepping completed", NULL); TMALLOC(double, ckt->CKTnumStates + 1);
return (0);
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 */
fprintf (stderr, "Supplies reduced to %8.4f%% ", ckt->CKTsrcFact * 100);
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;
} else {
ckt->CKTdiagGmin = ckt->CKTgshunt;
}
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,
"gmin step failed", 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
break;
}
ckt->CKTdiagGmin /= 10;
ckt->CKTmode = continuemode;
SPfrontEnd->IFerror (ERR_INFO,
"One successful gmin step",
NULL);
}
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", NULL);
ckt->CKTsrcFact = ConvFact + raise;
}
if (converged == 0)
do {
fprintf (stderr,
"Supplies reduced to %8.4f%% ", ckt->CKTsrcFact * 100);
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",
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", NULL);
return (E_ITERLIM);
} else {
SPfrontEnd->IFerror (ERR_INFO,
"Source stepping completed", NULL);
return (0);
} }
} }
@ -573,50 +565,48 @@ gillespie_src (CKTcircuit * ckt, long int firstmode,
*/ */
static int static int
spice3_src (CKTcircuit * ckt, long int firstmode, spice3_src (CKTcircuit * ckt, long int firstmode,
long int continuemode, int iterlim) long int continuemode, int iterlim)
{ {
int converged, i; int converged, i;
NG_IGNORE(iterlim); NG_IGNORE(iterlim);
ckt->CKTmode = firstmode; ckt->CKTmode = firstmode;
SPfrontEnd->IFerror (ERR_INFO, SPfrontEnd->IFerror (ERR_INFO,
"Starting source stepping", NULL); "Starting source stepping", NULL);
for (i = 0; i <= ckt->CKTnumSrcSteps; i++) for (i = 0; i <= ckt->CKTnumSrcSteps; i++) {
{ ckt->CKTsrcFact = ((double) i) / ((double) ckt->CKTnumSrcSteps);
ckt->CKTsrcFact = ((double) i) / ((double) ckt->CKTnumSrcSteps);
#ifdef XSPICE #ifdef XSPICE
/* gtri - begin - wbk - add convergence problem reporting flags */ /* gtri - begin - wbk - add convergence problem reporting flags */
ckt->enh->conv_debug.last_NIiter_call = MIF_TRUE; ckt->enh->conv_debug.last_NIiter_call = MIF_TRUE;
/* gtri - end - wbk - add convergence problem reporting flags */ /* gtri - end - wbk - add convergence problem reporting flags */
#endif #endif
converged = NIiter (ckt, ckt->CKTdcTrcvMaxIter); converged = NIiter (ckt, ckt->CKTdcTrcvMaxIter);
ckt->CKTmode = continuemode; ckt->CKTmode = continuemode;
if (converged != 0) if (converged != 0) {
{ ckt->CKTsrcFact = 1;
ckt->CKTsrcFact = 1; ckt->CKTcurrentAnalysis = DOING_TRAN;
ckt->CKTcurrentAnalysis = DOING_TRAN; SPfrontEnd->IFerror (ERR_WARNING,
SPfrontEnd->IFerror (ERR_WARNING, "source stepping failed", NULL);
"source stepping failed", NULL);
#ifdef XSPICE #ifdef XSPICE
/* gtri - begin - wbk - add convergence problem reporting flags */ /* gtri - begin - wbk - add convergence problem reporting flags */
ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE; ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE;
/* gtri - end - wbk - add convergence problem reporting flags */ /* gtri - end - wbk - add convergence problem reporting flags */
#endif #endif
return (converged); return (converged);
} }
SPfrontEnd->IFerror (ERR_INFO, SPfrontEnd->IFerror (ERR_INFO,
"One successful source step", NULL); "One successful source step", NULL);
} }
SPfrontEnd->IFerror (ERR_INFO, SPfrontEnd->IFerror (ERR_INFO,
"Source stepping completed", NULL); "Source stepping completed", NULL);
ckt->CKTsrcFact = 1; ckt->CKTsrcFact = 1;
#ifdef XSPICE #ifdef XSPICE
/* gtri - begin - wbk - add convergence problem reporting flags */ /* gtri - begin - wbk - add convergence problem reporting flags */
ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE; ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE;
/* gtri - end - wbk - add convergence problem reporting flags */ /* gtri - end - wbk - add convergence problem reporting flags */
#endif #endif
return (0); return (0);
} }