Try to speedup KCL (Part 1)

This commit is contained in:
Francesco Lannutti 2013-10-15 21:09:04 +02:00
parent 89d15214f3
commit b2c663c61b
5 changed files with 170 additions and 108 deletions

View File

@ -122,6 +122,12 @@ struct CKTcircuit {
int *CKTnodeIsLinear ; /* Flag to indicate if a node is linear or non-linear */
CKTmkCurKCLnode **CKTmkCurKCLarray ; /* Array of KCL Currents */
double **CKTdiag ;
double **CKTrhsOrdered ;
double **CKTrhsOldOrdered ;
CKTmkCurKCLnode **CKTmkCurKCLarrayOrdered ;
double **CKTfvkOrdered ;
int CKTvoltageNonLinearNodes ;
int CKTcurrentNonLinearNodes ;
#endif
double *CKTrhsSpare; /* spare rhs value for reordering */

View File

@ -47,89 +47,93 @@ NIconvTest (CKTcircuit *ckt)
#endif /* STEPDEBUG */
#endif
#ifdef KIRCHHOFF
for (i = 0 ; i < ckt->CKTvoltageNonLinearNodes ; i++)
{
new = *(ckt->CKTrhsOrdered [i]) ;
old = *(ckt->CKTrhsOldOrdered [i]) ;
tol = ckt->CKTreltol * (MAX (fabs (old), fabs (new))) + ckt->CKTvoltTol ;
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 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 ;
}
/* KCL Verification */
maximum = 0 ;
ptr = ckt->CKTmkCurKCLarrayOrdered [i] ;
#ifdef STEPDEBUG
j = 0 ;
#endif
while (ptr != NULL)
{
if (maximum < fabs (ptr->KCLcurrent))
maximum = fabs (ptr->KCLcurrent) ;
#ifdef STEPDEBUG
fprintf (stderr, "Index KCL Array: %d\tValue: %-.9g\tMaximum: %-.9g\n", j, fabs (ptr->KCLcurrent), maximum) ;
j++ ;
#endif
ptr = ptr->next ;
}
// if (maximum < fabs (ckt->CKTdiagGmin * ckt->CKTrhsOld [i]))
// maximum = fabs (ckt->CKTdiagGmin * ckt->CKTrhsOld [i]) ;
#ifdef STEPDEBUG
fprintf (stderr, "Index: %d\tValue: %-.9g\tThreshold: %-.9g\tMaximum: %-.9g\n", i, fabs (ckt->CKTfvk [i]),
ckt->CKTreltol * maximum + ckt->CKTabstol, maximum) ;
#endif
/* Check Convergence */
// if (fabs (ckt->CKTfvk [i] + ckt->CKTdiagGmin * ckt->CKTrhsOld [i]) > (ckt->CKTreltol * maximum + ckt->CKTabstol))
if (fabs (*(ckt->CKTfvkOrdered [i])) > (ckt->CKTreltol * maximum + ckt->CKTabstol))
{
ckt->CKTtroubleNode = i ;
ckt->CKTtroubleElt = NULL ;
return 1 ;
}
}
for (i = ckt->CKTvoltageNonLinearNodes ; i < ckt->CKTvoltageNonLinearNodes + ckt->CKTcurrentNonLinearNodes ; i++)
{
new = *(ckt->CKTrhsOrdered [i]) ;
old = *(ckt->CKTrhsOldOrdered [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 ;
}
}
#else
for (i = 1 ; i <= size ; i++)
{
node = node->next ;
#ifdef KIRCHHOFF
if ((node->type == SP_VOLTAGE) && (!ckt->CKTnodeIsLinear [i]))
{
new = ckt->CKTrhs [i] ;
old = ckt->CKTrhsOld [i] ;
tol = ckt->CKTreltol * (MAX (fabs (old), fabs (new))) + ckt->CKTvoltTol ;
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 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 ;
}
/* KCL Verification */
maximum = 0 ;
ptr = ckt->CKTmkCurKCLarray [i] ;
#ifdef STEPDEBUG
j = 0 ;
#endif
while (ptr != NULL)
{
if (maximum < fabs (ptr->KCLcurrent))
maximum = fabs (ptr->KCLcurrent) ;
#ifdef STEPDEBUG
fprintf (stderr, "Index KCL Array: %d\tValue: %-.9g\tMaximum: %-.9g\n", j, fabs (ptr->KCLcurrent), maximum) ;
j++ ;
#endif
ptr = ptr->next ;
}
if (maximum < fabs (ckt->CKTdiagGmin * ckt->CKTrhsOld [i]))
maximum = fabs (ckt->CKTdiagGmin * ckt->CKTrhsOld [i]) ;
#ifdef STEPDEBUG
fprintf (stderr, "Index: %d\tValue: %-.9g\tThreshold: %-.9g\tMaximum: %-.9g\n", i, fabs (ckt->CKTfvk [i]),
ckt->CKTreltol * maximum + ckt->CKTabstol, maximum) ;
#endif
/* Check Convergence */
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 ;
}
}
#else
new = ckt->CKTrhs [i] ;
old = ckt->CKTrhsOld [i] ;
if (node->type == SP_VOLTAGE)
@ -164,9 +168,8 @@ NIconvTest (CKTcircuit *ckt)
return 1 ;
}
}
#endif /* KIRCHHOFF */
}
#endif /* KIRCHHOFF */
#ifdef KIRCHHOFF
return 0 ;

View File

@ -81,13 +81,13 @@ CKTload(CKTcircuit *ckt)
#ifdef KIRCHHOFF
/* GMIN Stepping */
for (i = 1 ; i <= size ; i++)
{
if (ckt->CKTdiag [i] != NULL)
{
*(ckt->CKTdiag [i]) += ckt->CKTdiagGmin ;
}
}
// 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->CKTdiagGmin = OldGmin / factor;
ckt->CKTgmin = OldGmin / factor;
success = failed = 0;
while ((!success) && (!failed)) {
fprintf (stderr, "Trying gmin = %12.4E ", ckt->CKTdiagGmin);
fprintf (stderr, "Trying gmin = %12.4E ", ckt->CKTgmin);
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->CKTdiagGmin <= gtarget) {
if (ckt->CKTgmin <= 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->CKTdiagGmin;
OldGmin = ckt->CKTgmin;
if ((ckt->CKTdiagGmin) < (factor * gtarget)) {
factor = ckt->CKTdiagGmin / gtarget;
ckt->CKTdiagGmin = gtarget;
if ((ckt->CKTgmin) < (factor * gtarget)) {
factor = ckt->CKTgmin / gtarget;
ckt->CKTgmin = gtarget;
} else {
ckt->CKTdiagGmin /= factor;
ckt->CKTgmin /= factor;
}
}
} else {
@ -213,7 +213,7 @@ dynamic_gmin (CKTcircuit * ckt, long int firstmode,
"Further gmin increment",
NULL);
factor = sqrt (sqrt (factor));
ckt->CKTdiagGmin = OldGmin / factor;
ckt->CKTgmin = 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);

View File

@ -129,18 +129,21 @@ CKTsetup(CKTcircuit *ckt)
#endif
#ifdef KIRCHHOFF
CKTnode *node ;
/**
* Gmin Stepping
*/
// CKTnode *node ;
node = ckt->CKTnodes ;
for (i = 1 ; i <= SMPmatSize (ckt->CKTmatrix) ; i++)
{
node = node->next ;
// node = ckt->CKTnodes ;
// for (i = 1 ; i <= SMPmatSize (ckt->CKTmatrix) ; i++)
// {
// node = node->next ;
if (node->type == SP_VOLTAGE)
{
ckt->CKTdiag [i] = SMPmakeElt (ckt->CKTmatrix, i, i) ;
}
}
// if (node->type == SP_VOLTAGE)
// {
// ckt->CKTdiag [i] = SMPmakeElt (ckt->CKTmatrix, i, i) ;
// }
// }
/** Marking node as Non-Linear when needed
* By default every node is Linear
@ -154,6 +157,56 @@ CKTsetup(CKTcircuit *ckt)
return (error) ;
}
}
/**
* Reordering nodes for convergence tests
*/
int j, non_linear_nodes ;
non_linear_nodes = 0 ;
for (i = 1 ; i <= SMPmatSize (ckt->CKTmatrix) ; i++)
{
if (!ckt->CKTnodeIsLinear [i])
{
non_linear_nodes++ ;
}
}
CKALLOC (ckt->CKTrhsOrdered, non_linear_nodes, double*) ;
CKALLOC (ckt->CKTrhsOldOrdered, non_linear_nodes, double*) ;
CKALLOC (ckt->CKTmkCurKCLarrayOrdered, non_linear_nodes, CKTmkCurKCLnode*) ;
CKALLOC (ckt->CKTfvkOrdered, non_linear_nodes, double*) ;
j = 0 ;
node = ckt->CKTnodes ;
for (i = 1 ; i <= SMPmatSize (ckt->CKTmatrix) ; i++)
{
node = node->next ;
if ((node->type == SP_VOLTAGE) && (!ckt->CKTnodeIsLinear [i]))
{
ckt->CKTrhsOrdered [j] = &(ckt->CKTrhs [i]) ;
ckt->CKTrhsOldOrdered [j] = &(ckt->CKTrhsOld [i]) ;
ckt->CKTmkCurKCLarrayOrdered [j] = ckt->CKTmkCurKCLarray [i] ;
ckt->CKTfvkOrdered [j] = &(ckt->CKTfvk [i]) ;
j++ ;
}
}
ckt->CKTvoltageNonLinearNodes = j ;
node = ckt->CKTnodes ;
for (i = 1 ; i <= SMPmatSize (ckt->CKTmatrix) ; i++)
{
node = node->next ;
if ((node->type == SP_CURRENT) && (!ckt->CKTnodeIsLinear [i]))
{
ckt->CKTrhsOrdered [j] = &(ckt->CKTrhs [i]) ;
ckt->CKTrhsOldOrdered [j] = &(ckt->CKTrhsOld [i]) ;
j++ ;
}
}
ckt->CKTcurrentNonLinearNodes = j - ckt->CKTvoltageNonLinearNodes ;
#endif
return(OK);