diff --git a/src/include/ngspice/cktdefs.h b/src/include/ngspice/cktdefs.h index 80ac6259e..cf38fbb13 100644 --- a/src/include/ngspice/cktdefs.h +++ b/src/include/ngspice/cktdefs.h @@ -110,6 +110,7 @@ struct CKTcircuit { double *CKTrhs; /* current rhs value - being loaded */ double *CKTrhsOld; /* previous rhs value for convergence testing */ + double *CKTfvk ; /* KCL Verification array */ double *CKTrhsSpare; /* spare rhs value for reordering */ double *CKTirhs; /* current rhs value - being loaded (imag) */ @@ -429,6 +430,10 @@ extern void NInzIter(CKTcircuit *, int, int); extern int NIpred(CKTcircuit *ckt); #endif +/* KCL Verification */ +extern int NIkclVerification (CKTcircuit *) ; +/********************/ + extern IFfrontEnd *SPfrontEnd; #endif diff --git a/src/maths/ni/niconv.c b/src/maths/ni/niconv.c index 988fd30f2..deb9c9016 100644 --- a/src/maths/ni/niconv.c +++ b/src/maths/ni/niconv.c @@ -45,18 +45,6 @@ NIconvTest(CKTcircuit *ckt) #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); - } - } else { - tol = ckt->CKTreltol * (MAX(fabs(old),fabs(new))) + - ckt->CKTabstol; - if (fabs(new-old) >tol ) { -#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); - printf(" 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; @@ -74,3 +62,42 @@ NIconvTest(CKTcircuit *ckt) return(0); #endif /* NEWCONV */ } + + +/** + * Routine to Verify the KCL + */ + +int NIkclVerification (CKTcircuit *ckt) +{ + int i, size ; + double maximum = 0 ; + CKTnode *node ; + + size = SMPmatSize (ckt->CKTmatrix) ; + + node = ckt->CKTnodes ; + for (i = 1 ; i <= size ; i++) + { + if (node->type == SP_CURRENT) + { + if (maximum < fabs (ckt->CKTrhsOld [i])) + maximum = fabs (ckt->CKTrhsOld [i]) ; + } + node = node->next ; + } + + node = ckt->CKTnodes ; + for (i = 1 ; i <= size ; i++) + { + if (node->type == SP_VOLTAGE) + { + if ((ckt->CKTfvk [i] + ckt->CKTdiagGmin * ckt->CKTrhsOld [i]) > (ckt->CKTreltol * maximum + ckt->CKTabstol)) +// if ((ckt->CKTfvk [i]) > (ckt->CKTreltol * maximum + ckt->CKTabstol)) + return 1 ; + } + node = node->next ; + } + + return 0 ; +} diff --git a/src/maths/ni/niiter.c b/src/maths/ni/niiter.c index 4d6c83e08..d540cae43 100644 --- a/src/maths/ni/niiter.c +++ b/src/maths/ni/niiter.c @@ -37,6 +37,9 @@ NIiter(CKTcircuit *ckt, int maxIter) CKTnode *node; /* current matrix entry */ double diff, maxdiff, damp_factor, *OldCKTstate0=NULL; + /* KCL_verified */ + int KCL_verified ; + if ( maxIter < 100 ) maxIter = 100; /* some convergence issues that get resolved by increasing max iter */ iterno=0; @@ -110,6 +113,16 @@ NIiter(CKTcircuit *ckt, int maxIter) ckt->CKTniState |= NISHOULDREORDER; } + /* KCL Verification */ + if ((ckt->CKTnoncon == 0) && (iterno != 1)) + { + KCL_verified = NIkclVerification (ckt) ; + if (KCL_verified) /* NOT VERIFIED */ + ckt->CKTnoncon = 1 ; + else + ckt->CKTnoncon = 0 ; + } + if(ckt->CKTniState & NISHOULDREORDER) { startTime = SPfrontEnd->IFseconds(); error = SMPreorder(ckt->CKTmatrix,ckt->CKTpivotAbsTol, diff --git a/src/maths/ni/nireinit.c b/src/maths/ni/nireinit.c index cc14aee53..3c2641fc4 100644 --- a/src/maths/ni/nireinit.c +++ b/src/maths/ni/nireinit.c @@ -29,6 +29,7 @@ NIreinit( CKTcircuit *ckt) size = SMPmatSize(ckt->CKTmatrix); CKALLOC(CKTrhs,size+1,double); CKALLOC(CKTrhsOld,size+1,double); + CKALLOC(CKTfvk,size+1,double); CKALLOC(CKTrhsSpare,size+1,double); CKALLOC(CKTirhs,size+1,double); CKALLOC(CKTirhsOld,size+1,double); diff --git a/src/spicelib/analysis/cktload.c b/src/spicelib/analysis/cktload.c index 62b6f2a47..ca5a7cadc 100644 --- a/src/spicelib/analysis/cktload.c +++ b/src/spicelib/analysis/cktload.c @@ -52,6 +52,7 @@ CKTload(CKTcircuit *ckt) size = SMPmatSize(ckt->CKTmatrix); for (i = 0; i <= size; i++) { ckt->CKTrhs[i] = 0; + ckt->CKTfvk[i] = 0; } SMPclear(ckt->CKTmatrix); #ifdef STEPDEBUG