|
|
|
@ -35,7 +35,9 @@ NIiter(CKTcircuit *ckt, int maxIter) |
|
|
|
CKTnode *node; /* current matrix entry */ |
|
|
|
double diff, maxdiff, damp_factor, *OldCKTstate0=NULL; |
|
|
|
|
|
|
|
if ( maxIter < 100 ) maxIter = 100; /* some convergence issues that get resolved by increasing max iter */ |
|
|
|
/* some convergence issues that get resolved by increasing max iter */ |
|
|
|
if (maxIter < 100) |
|
|
|
maxIter = 100; |
|
|
|
|
|
|
|
iterno=0; |
|
|
|
ipass=0; |
|
|
|
@ -44,15 +46,15 @@ NIiter(CKTcircuit *ckt, int maxIter) |
|
|
|
if( (ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC)) { |
|
|
|
SWAP(double *, ckt->CKTrhs, ckt->CKTrhsOld); |
|
|
|
error = CKTload(ckt); |
|
|
|
if(error) { |
|
|
|
if(error) |
|
|
|
return(error); |
|
|
|
} |
|
|
|
return(OK); |
|
|
|
} |
|
|
|
#ifdef WANT_SENSE2 |
|
|
|
if(ckt->CKTsenInfo) { |
|
|
|
error = NIsenReinit(ckt); |
|
|
|
if(error) return(error); |
|
|
|
if(error) |
|
|
|
return(error); |
|
|
|
} |
|
|
|
#endif |
|
|
|
if(ckt->CKTniState & NIUNINITIALIZED) { |
|
|
|
@ -70,10 +72,9 @@ NIiter(CKTcircuit *ckt, int maxIter) |
|
|
|
for(;;) { |
|
|
|
ckt->CKTnoncon=0; |
|
|
|
#ifdef NEWPRED |
|
|
|
if(!(ckt->CKTmode & MODEINITPRED)) { |
|
|
|
#else /* NEWPRED */ |
|
|
|
if(1) { /* } */ |
|
|
|
#endif /* NEWPRED */ |
|
|
|
if(!(ckt->CKTmode & MODEINITPRED)) |
|
|
|
#endif |
|
|
|
{ |
|
|
|
error = CKTload(ckt); |
|
|
|
/*printf("loaded, noncon is %d\n",ckt->CKTnoncon);*/ |
|
|
|
/*fflush(stdout);*/ |
|
|
|
@ -102,7 +103,8 @@ NIiter(CKTcircuit *ckt, int maxIter) |
|
|
|
ckt->CKTniState |= NIDIDPREORDER; |
|
|
|
} |
|
|
|
if( (ckt->CKTmode & MODEINITJCT) || |
|
|
|
( (ckt->CKTmode & MODEINITTRAN) && (iterno==1))) { |
|
|
|
( (ckt->CKTmode & MODEINITTRAN) && (iterno==1))) |
|
|
|
{ |
|
|
|
ckt->CKTniState |= NISHOULDREORDER; |
|
|
|
} |
|
|
|
|
|
|
|
@ -158,8 +160,8 @@ NIiter(CKTcircuit *ckt, int maxIter) |
|
|
|
|
|
|
|
startTime = SPfrontEnd->IFseconds(); |
|
|
|
SMPsolve(ckt->CKTmatrix,ckt->CKTrhs,ckt->CKTrhsSpare); |
|
|
|
ckt->CKTstat->STATsolveTime += SPfrontEnd->IFseconds() - |
|
|
|
startTime; |
|
|
|
ckt->CKTstat->STATsolveTime += |
|
|
|
SPfrontEnd->IFseconds() - startTime; |
|
|
|
#ifdef STEPDEBUG |
|
|
|
/*XXXX*/ |
|
|
|
if (*ckt->CKTrhs != 0.0) |
|
|
|
@ -187,11 +189,10 @@ NIiter(CKTcircuit *ckt, int maxIter) |
|
|
|
FREE(OldCKTstate0); |
|
|
|
return(E_ITERLIM); |
|
|
|
} |
|
|
|
if(ckt->CKTnoncon==0 && iterno!=1) { |
|
|
|
if((ckt->CKTnoncon==0) && (iterno!=1)) |
|
|
|
ckt->CKTnoncon = NIconvTest(ckt); |
|
|
|
} else { |
|
|
|
else |
|
|
|
ckt->CKTnoncon = 1; |
|
|
|
} |
|
|
|
#ifdef STEPDEBUG |
|
|
|
printf("noncon is %d\n",ckt->CKTnoncon); |
|
|
|
#endif |
|
|
|
@ -199,28 +200,27 @@ NIiter(CKTcircuit *ckt, int maxIter) |
|
|
|
|
|
|
|
if( (ckt->CKTnodeDamping!=0) && (ckt->CKTnoncon!=0) && |
|
|
|
((ckt->CKTmode & MODETRANOP) || (ckt->CKTmode & MODEDCOP)) && |
|
|
|
(iterno>1) ) { |
|
|
|
(iterno>1) ) |
|
|
|
{ |
|
|
|
maxdiff=0; |
|
|
|
for (node = ckt->CKTnodes->next; node; node = node->next) { |
|
|
|
for (node = ckt->CKTnodes->next; node; node = node->next) |
|
|
|
if(node->type == SP_VOLTAGE) { |
|
|
|
diff = ckt->CKTrhs [node->number] - |
|
|
|
ckt->CKTrhsOld [node->number]; |
|
|
|
if (diff>maxdiff) maxdiff=diff; |
|
|
|
diff = ckt->CKTrhs[node->number] - ckt->CKTrhsOld[node->number]; |
|
|
|
if (maxdiff < diff) |
|
|
|
maxdiff = diff; |
|
|
|
} |
|
|
|
} |
|
|
|
if (maxdiff>10) { |
|
|
|
damp_factor=10/maxdiff; |
|
|
|
if (damp_factor<0.1) damp_factor=0.1; |
|
|
|
if (damp_factor<0.1) |
|
|
|
damp_factor=0.1; |
|
|
|
for (node = ckt->CKTnodes->next; node; node = node->next) { |
|
|
|
diff = ckt->CKTrhs[node->number] - |
|
|
|
ckt->CKTrhsOld[node->number]; |
|
|
|
ckt->CKTrhs[node->number] = ckt->CKTrhsOld[node->number] + |
|
|
|
(damp_factor * diff); |
|
|
|
diff = ckt->CKTrhs[node->number] - ckt->CKTrhsOld[node->number]; |
|
|
|
ckt->CKTrhs[node->number] = |
|
|
|
ckt->CKTrhsOld[node->number] + (damp_factor * diff); |
|
|
|
} |
|
|
|
for(i=0; i<ckt->CKTnumStates; i++) { |
|
|
|
diff = ckt->CKTstate0[i] - OldCKTstate0[i]; |
|
|
|
ckt->CKTstate0[i] = OldCKTstate0[i] + |
|
|
|
(damp_factor * diff); |
|
|
|
ckt->CKTstate0[i] = OldCKTstate0[i] + (damp_factor * diff); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
@ -228,11 +228,9 @@ NIiter(CKTcircuit *ckt, int maxIter) |
|
|
|
|
|
|
|
|
|
|
|
if(ckt->CKTmode & MODEINITFLOAT) { |
|
|
|
if ((ckt->CKTmode & MODEDC) && |
|
|
|
( ckt->CKThadNodeset) ) { |
|
|
|
if(ipass) { |
|
|
|
if ((ckt->CKTmode & MODEDC) && ckt->CKThadNodeset) { |
|
|
|
if(ipass) |
|
|
|
ckt->CKTnoncon=ipass; |
|
|
|
} |
|
|
|
ipass=0; |
|
|
|
} |
|
|
|
if(ckt->CKTnoncon == 0) { |
|
|
|
@ -241,19 +239,20 @@ NIiter(CKTcircuit *ckt, int maxIter) |
|
|
|
return(OK); |
|
|
|
} |
|
|
|
} else if(ckt->CKTmode & MODEINITJCT) { |
|
|
|
ckt->CKTmode = (ckt->CKTmode&(~INITF))|MODEINITFIX; |
|
|
|
ckt->CKTmode = (ckt->CKTmode& ~INITF )|MODEINITFIX; |
|
|
|
ckt->CKTniState |= NISHOULDREORDER; |
|
|
|
} else if (ckt->CKTmode & MODEINITFIX) { |
|
|
|
if(ckt->CKTnoncon==0) ckt->CKTmode = |
|
|
|
(ckt->CKTmode&(~INITF))|MODEINITFLOAT; |
|
|
|
if(ckt->CKTnoncon==0) |
|
|
|
ckt->CKTmode = (ckt->CKTmode& ~INITF )|MODEINITFLOAT; |
|
|
|
ipass=1; |
|
|
|
} else if (ckt->CKTmode & MODEINITSMSIG) { |
|
|
|
ckt->CKTmode = (ckt->CKTmode&(~INITF))|MODEINITFLOAT; |
|
|
|
ckt->CKTmode = (ckt->CKTmode& ~INITF )|MODEINITFLOAT; |
|
|
|
} else if (ckt->CKTmode & MODEINITTRAN) { |
|
|
|
if(iterno<=1) ckt->CKTniState |= NISHOULDREORDER; |
|
|
|
ckt->CKTmode = (ckt->CKTmode&(~INITF))|MODEINITFLOAT; |
|
|
|
if(iterno<=1) |
|
|
|
ckt->CKTniState |= NISHOULDREORDER; |
|
|
|
ckt->CKTmode = (ckt->CKTmode& ~INITF )|MODEINITFLOAT; |
|
|
|
} else if (ckt->CKTmode & MODEINITPRED) { |
|
|
|
ckt->CKTmode = (ckt->CKTmode&(~INITF))|MODEINITFLOAT; |
|
|
|
ckt->CKTmode = (ckt->CKTmode& ~INITF )|MODEINITFLOAT; |
|
|
|
} else { |
|
|
|
ckt->CKTstat->STATnumIter += iterno; |
|
|
|
#ifdef STEPDEBUG |
|
|
|
|