Final Version of the KCL Verification with the SPICE2 GMIN Stepping Algorithm

This commit is contained in:
Francesco Lannutti 2013-10-05 19:23:44 +02:00
parent 5fdb0ae9af
commit 89d15214f3
4 changed files with 58 additions and 38 deletions

View File

@ -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 */
}

View File

@ -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;
//}

View File

@ -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

View File

@ -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);