From 89d15214f31ab423bdb3e25ced6d8766034092c5 Mon Sep 17 00:00:00 2001 From: Francesco Lannutti Date: Sat, 5 Oct 2013 19:23:44 +0200 Subject: [PATCH] Final Version of the KCL Verification with the SPICE2 GMIN Stepping Algorithm --- src/maths/ni/niconv.c | 36 ++++++++++++++++++++++++--------- src/maths/sparse/spsmp.c | 36 +++++++++++++++++---------------- src/spicelib/analysis/cktload.c | 4 ++-- src/spicelib/analysis/cktop.c | 20 +++++++++--------- 4 files changed, 58 insertions(+), 38 deletions(-) diff --git a/src/maths/ni/niconv.c b/src/maths/ni/niconv.c index c7be7780c..30dbcf31a 100644 --- a/src/maths/ni/niconv.c +++ b/src/maths/ni/niconv.c @@ -61,7 +61,8 @@ NIconvTest (CKTcircuit *ckt) { #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, " 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 voltTol: %g (tol=reltol*(MAX(fabs(old),fabs(new))) + voltTol)\n", ckt->CKTreltol, ckt->CKTvoltTol) ; #endif /* STEPDEBUG */ @@ -93,8 +94,8 @@ NIconvTest (CKTcircuit *ckt) ptr = ptr->next ; } -// if (maximum < fabs (ckt->CKTgmin * ckt->CKTrhsOld [i])) -// maximum = fabs (ckt->CKTgmin * ckt->CKTrhsOld [i]) ; + if (maximum < fabs (ckt->CKTdiagGmin * ckt->CKTrhsOld [i])) + maximum = fabs (ckt->CKTdiagGmin * ckt->CKTrhsOld [i]) ; #ifdef STEPDEBUG @@ -103,12 +104,28 @@ NIconvTest (CKTcircuit *ckt) #endif /* Check Convergence */ -// if (fabs (ckt->CKTfvk [i] + ckt->CKTgmin * ckt->CKTrhsOld [i]) > (ckt->CKTreltol * maximum + ckt->CKTabstol)) - if (fabs (ckt->CKTfvk [i]) > (ckt->CKTreltol * maximum + ckt->CKTabstol)) + if (fabs (ckt->CKTfvk [i] + ckt->CKTdiagGmin * ckt->CKTrhsOld [i]) > (ckt->CKTreltol * maximum + ckt->CKTabstol)) { ckt->CKTtroubleNode = i ; ckt->CKTtroubleElt = NULL ; + return 1 ; + } + } else { + new = ckt->CKTrhs [i] ; + old = ckt->CKTrhsOld [i] ; + 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 ; } } @@ -122,7 +139,8 @@ NIconvTest (CKTcircuit *ckt) { #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, " 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 voltTol: %g (tol=reltol*(MAX(fabs(old),fabs(new))) + voltTol)\n", ckt->CKTreltol, ckt->CKTvoltTol) ; #endif /* STEPDEBUG */ @@ -136,8 +154,8 @@ NIconvTest (CKTcircuit *ckt) { #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, " 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 */ @@ -146,7 +164,7 @@ NIconvTest (CKTcircuit *ckt) return 1 ; } } -#endif +#endif /* KIRCHHOFF */ } diff --git a/src/maths/sparse/spsmp.c b/src/maths/sparse/spsmp.c index d5845f960..7b6ecb54c 100644 --- a/src/maths/sparse/spsmp.c +++ b/src/maths/sparse/spsmp.c @@ -106,7 +106,7 @@ extern double scalbn(double, int); extern double logb(double); #endif -static void LoadGmin(SMPmatrix *Matrix, double Gmin); +//static void LoadGmin(SMPmatrix *Matrix, double Gmin); /* @@ -169,6 +169,7 @@ int SMPluFac(SMPmatrix *Matrix, double PivTol, double Gmin) { NG_IGNORE(PivTol); + NG_IGNORE(Gmin); spSetReal( Matrix ); // LoadGmin( Matrix, Gmin ); return spFactor( Matrix ); @@ -194,6 +195,7 @@ int SMPreorder(SMPmatrix *Matrix, double PivTol, double PivRel, double Gmin) { spSetReal( Matrix ); + NG_IGNORE(Gmin); // LoadGmin( Matrix, Gmin ); return spOrderAndFactor( Matrix, NULL, PivRel, PivTol, YES ); @@ -419,25 +421,25 @@ SMPcDProd(SMPmatrix *Matrix, SPcomplex *pMantissa, int *pExponent) * for compatibility with Spice3. */ -static void -LoadGmin(SMPmatrix *Matrix, double Gmin) -{ - int I; - ArrayOfElementPtrs Diag; - ElementPtr diag; +//static void +//LoadGmin(SMPmatrix *Matrix, double Gmin) +//{ +// int I; +// ArrayOfElementPtrs Diag; +// ElementPtr diag; /* Begin `LoadGmin'. */ - assert( IS_SPARSE( Matrix ) ); +// assert( IS_SPARSE( Matrix ) ); - if (Gmin != 0.0) { - Diag = Matrix->Diag; - for (I = Matrix->Size; I > 0; I--) { - if ((diag = Diag[I]) != NULL) - diag->Real += Gmin; - } - } - return; -} +// if (Gmin != 0.0) { +// Diag = Matrix->Diag; +// for (I = Matrix->Size; I > 0; I--) { +// if ((diag = Diag[I]) != NULL) +// diag->Real += Gmin; +// } +// } +// return; +//} diff --git a/src/spicelib/analysis/cktload.c b/src/spicelib/analysis/cktload.c index f9ceade55..8de8c7749 100644 --- a/src/spicelib/analysis/cktload.c +++ b/src/spicelib/analysis/cktload.c @@ -81,13 +81,13 @@ CKTload(CKTcircuit *ckt) #ifdef KIRCHHOFF /* GMIN Stepping */ -/* for (i = 1 ; i <= size ; i++) + for (i = 1 ; i <= size ; i++) { if (ckt->CKTdiag [i] != NULL) { *(ckt->CKTdiag [i]) += ckt->CKTdiagGmin ; } - }*/ + } #endif #ifdef XSPICE diff --git a/src/spicelib/analysis/cktop.c b/src/spicelib/analysis/cktop.c index cfd07a422..90549af90 100644 --- a/src/spicelib/analysis/cktop.c +++ b/src/spicelib/analysis/cktop.c @@ -155,11 +155,11 @@ dynamic_gmin (CKTcircuit * ckt, long int firstmode, factor = ckt->CKTgminFactor; OldGmin = 1e-2; gtarget = MAX (ckt->CKTgmin, ckt->CKTgshunt); - ckt->CKTgmin = OldGmin / factor; + ckt->CKTdiagGmin = OldGmin / factor; success = failed = 0; while ((!success) && (!failed)) { - fprintf (stderr, "Trying gmin = %12.4E ", ckt->CKTgmin); + fprintf (stderr, "Trying gmin = %12.4E ", ckt->CKTdiagGmin); ckt->CKTnoncon = 1; iters = ckt->CKTstat->STATnumIter; @@ -171,7 +171,7 @@ dynamic_gmin (CKTcircuit * ckt, long int firstmode, SPfrontEnd->IFerror (ERR_INFO, "One successful gmin step", NULL); - if (ckt->CKTgmin <= gtarget) { + if (ckt->CKTdiagGmin <= gtarget) { success = 1; } else { i = 0; @@ -193,13 +193,13 @@ dynamic_gmin (CKTcircuit * ckt, long int firstmode, if (iters > (3 * ckt->CKTdcTrcvMaxIter / 4)) factor = sqrt (factor); - OldGmin = ckt->CKTgmin; + OldGmin = ckt->CKTdiagGmin; - if ((ckt->CKTgmin) < (factor * gtarget)) { - factor = ckt->CKTgmin / gtarget; - ckt->CKTgmin = gtarget; + if ((ckt->CKTdiagGmin) < (factor * gtarget)) { + factor = ckt->CKTdiagGmin / gtarget; + ckt->CKTdiagGmin = gtarget; } else { - ckt->CKTgmin /= factor; + ckt->CKTdiagGmin /= factor; } } } else { @@ -213,7 +213,7 @@ dynamic_gmin (CKTcircuit * ckt, long int firstmode, "Further gmin increment", NULL); factor = sqrt (sqrt (factor)); - ckt->CKTgmin = OldGmin / factor; + ckt->CKTdiagGmin = OldGmin / factor; i = 0; for (n = ckt->CKTnodes; n; n = n->next) { @@ -228,7 +228,7 @@ dynamic_gmin (CKTcircuit * ckt, long int firstmode, } } -// ckt->CKTdiagGmin = ckt->CKTgshunt; + ckt->CKTdiagGmin = ckt->CKTgshunt; FREE (OldRhsOld); FREE (OldCKTstate0);