Implemented the KCL for every node, avoiding Delta-V and Delta-I convergence tests.

The f(V) convergence test performed by every model isn't needed anymore.
This commit is contained in:
Francesco Lannutti 2013-07-27 18:37:32 +02:00
parent fb592a07f5
commit 3494e423fa
1 changed files with 66 additions and 60 deletions

View File

@ -17,74 +17,44 @@ Author: 1985 Thomas L. Quarles
int int
NIconvTest(CKTcircuit *ckt) NIconvTest (CKTcircuit *ckt)
{ {
int i; /* generic loop variable */ int i ; /* generic loop variable */
int size; /* size of the matrix */ int size ; /* size of the matrix */
CKTnode *node; /* current matrix entry */ CKTnode *node ; /* current matrix entry */
double old;
double new;
double tol;
#ifdef KIRCHHOFF #ifdef KIRCHHOFF
#ifdef STEPDEBUG
int j ;
#endif
double maximum ; double maximum ;
CKTmkCurKCLnode *ptr ; CKTmkCurKCLnode *ptr ;
#ifdef STEPDEBUG
int j ;
#endif
#else
double old, new, tol ;
#endif #endif
size = SMPmatSize(ckt->CKTmatrix); size = SMPmatSize (ckt->CKTmatrix) ;
node = ckt->CKTnodes; node = ckt->CKTnodes ;
#ifdef STEPDEBUG
for (i=1;i<=size;i++) {
new = ckt->CKTrhs [i] ;
old = ckt->CKTrhsOld [i] ;
printf("chk for convergence: %s new: %g old: %g\n",CKTnodName(ckt,i),new,old);
}
#endif /* STEPDEBUG */
for (i=1;i<=size;i++) {
node = node->next;
new = ckt->CKTrhs [i] ;
old = ckt->CKTrhsOld [i] ;
if(node->type == SP_VOLTAGE) {
tol = ckt->CKTreltol * (MAX(fabs(old),fabs(new))) +
ckt->CKTvoltTol;
if (fabs(new-old) >tol ) {
#ifdef STEPDEBUG
printf(" non-convergence at node (type=3) %s (fabs(new-old)>tol --> fabs(%g-%g)>%g)\n",CKTnodName(ckt,i),new,old,tol);
printf(" reltol: %g voltTol: %g (tol=reltol*(MAX(fabs(old),fabs(new))) + voltTol)\n",ckt->CKTreltol,ckt->CKTvoltTol);
#endif /* STEPDEBUG */
ckt->CKTtroubleNode = i;
ckt->CKTtroubleElt = NULL;
return(1);
}
#ifndef KIRCHHOFF #ifndef KIRCHHOFF
} else {
tol = ckt->CKTreltol * (MAX(fabs(old),fabs(new))) +
ckt->CKTabstol;
if (fabs(new-old) >tol ) {
#ifdef STEPDEBUG #ifdef STEPDEBUG
printf(" non-convergence at node (type=%d) %s (fabs(new-old)>tol --> fabs(%g-%g)>%g)\n",node->type,CKTnodName(ckt,i),new,old,tol); for (i = 1 ; i <= size ; i++)
printf(" reltol: %g abstol: %g (tol=reltol*(MAX(fabs(old),fabs(new))) + abstol)\n",ckt->CKTreltol,ckt->CKTabstol); {
new = ckt->CKTrhs [i] ;
old = ckt->CKTrhsOld [i] ;
fprintf (err, "chk for convergence: %s new: %g old: %g\n", CKTnodName (ckt, i), new, old) ;
}
#endif /* STEPDEBUG */ #endif /* STEPDEBUG */
#endif
ckt->CKTtroubleNode = i; for (i = 1 ; i <= size ; i++)
ckt->CKTtroubleElt = NULL; {
return(1); node = node->next ;
}
#else #ifdef KIRCHHOFF
/* KCL Verification */ /* KCL Verification */
} if ((node->type == SP_VOLTAGE) && (!ckt->CKTnodeIsLinear [i]))
if ((node->type == SP_VOLTAGE) && (!ckt->CKTnodeIsLinear [i]) && (ckt->CKTvoltCurNode [i]))
{ {
maximum = 0 ; maximum = 0 ;
ptr = ckt->CKTmkCurKCLarray [i] ; ptr = ckt->CKTmkCurKCLarray [i] ;
@ -111,19 +81,55 @@ NIconvTest(CKTcircuit *ckt)
ckt->CKTreltol * maximum + ckt->CKTabstol, maximum) ; ckt->CKTreltol * maximum + ckt->CKTabstol, maximum) ;
#endif #endif
if (fabs (ckt->CKTfvk [i]) > (ckt->CKTreltol * maximum + ckt->CKTabstol)) }
#else
new = ckt->CKTrhs [i] ;
old = ckt->CKTrhsOld [i] ;
if (node->type == SP_VOLTAGE)
{
tol = ckt->CKTreltol * (MAX (fabs (old), fabs (new))) + ckt->CKTvoltTol ;
if (fabs (new - old) > tol)
{
#ifdef STEPDEBUG
fprintf (err, " non-convergence at node (type=3) %s (fabs(new-old)>tol --> fabs(%g-%g)>%g)\n", CKTnodName (ckt, i), new, old, tol) ;
fprintf (err, " reltol: %g voltTol: %g (tol=reltol*(MAX(fabs(old),fabs(new))) + voltTol)\n", ckt->CKTreltol, ckt->CKTvoltTol) ;
#endif /* STEPDEBUG */
ckt->CKTtroubleNode = i ;
ckt->CKTtroubleElt = NULL ;
return 1 ; return 1 ;
}
} else {
tol = ckt->CKTreltol * (MAX (fabs (old), fabs (new))) + ckt->CKTabstol ;
if (fabs (new - old) > tol)
{
#ifdef STEPDEBUG
fprintf (err, " non-convergence at node (type=%d) %s (fabs(new-old)>tol --> fabs(%g-%g)>%g)\n", node->type,
CKTnodName (ckt, i), new, old, tol) ;
fprintf (err, " reltol: %g abstol: %g (tol=reltol*(MAX(fabs(old),fabs(new))) + abstol)\n", ckt->CKTreltol, ckt->CKTabstol) ;
#endif /* STEPDEBUG */
ckt->CKTtroubleNode = i ;
ckt->CKTtroubleElt = NULL ;
return 1 ;
}
}
#endif #endif
}
} }
#ifdef KIRCHHOFF
return 0 ;
#else
#ifdef NEWCONV #ifdef NEWCONV
i = CKTconvTest(ckt); i = CKTconvTest (ckt) ;
if (i) if (i)
ckt->CKTtroubleNode = 0; ckt->CKTtroubleNode = 0 ;
return(i); return i ;
#else /* NEWCONV */ #else /* NEWCONV */
return(0); return 0 ;
#endif /* NEWCONV */ #endif /* NEWCONV */
#endif /* KIRCHHOFF */
} }