diff --git a/src/include/ngspice/klu.h b/src/include/ngspice/klu.h index f46eccc15..5171c38d0 100644 --- a/src/include/ngspice/klu.h +++ b/src/include/ngspice/klu.h @@ -982,6 +982,7 @@ typedef struct sKLUmatrix { unsigned int KLUmatrixLinkedListNZ ; /* KLU nz for the Initial Parsing */ double *KLUmatrixTrashCOO ; /* KLU COO Trash Pointer for Ground Node not Stored in the Matrix */ double **KLUmatrixDiag ; /* KLU pointer to diagonal element to perform Gmin */ + unsigned int KLUloadDiagGmin:1 ; /* KLU flag to load Diag Gmin */ #ifdef CIDER int *KLUmatrixColCOOforCIDER ; /* KLU Col Index for COO storage (for CIDER) */ diff --git a/src/maths/KLU/klusmp.c b/src/maths/KLU/klusmp.c index a641f96f5..c75d162cd 100644 --- a/src/maths/KLU/klusmp.c +++ b/src/maths/KLU/klusmp.c @@ -477,7 +477,9 @@ SMPluFac (SMPmatrix *Matrix, double PivTol, double Gmin) if (Matrix->CKTkluMODE) { - LoadGmin_CSC (Matrix->SMPkluMatrix->KLUmatrixDiag, Matrix->SMPkluMatrix->KLUmatrixN, Gmin) ; + if (Matrix->SMPkluMatrix->KLUloadDiagGmin) { + LoadGmin_CSC (Matrix->SMPkluMatrix->KLUmatrixDiag, Matrix->SMPkluMatrix->KLUmatrixN, Gmin) ; + } ret = klu_refactor (Matrix->SMPkluMatrix->KLUmatrixAp, Matrix->SMPkluMatrix->KLUmatrixAi, Matrix->SMPkluMatrix->KLUmatrixAx, Matrix->SMPkluMatrix->KLUmatrixSymbolic, Matrix->SMPkluMatrix->KLUmatrixNumeric, Matrix->SMPkluMatrix->KLUmatrixCommon) ; @@ -619,7 +621,9 @@ SMPreorder (SMPmatrix *Matrix, double PivTol, double PivRel, double Gmin) { if (Matrix->CKTkluMODE) { - LoadGmin_CSC (Matrix->SMPkluMatrix->KLUmatrixDiag, Matrix->SMPkluMatrix->KLUmatrixN, Gmin) ; + if (Matrix->SMPkluMatrix->KLUloadDiagGmin) { + LoadGmin_CSC (Matrix->SMPkluMatrix->KLUmatrixDiag, Matrix->SMPkluMatrix->KLUmatrixN, Gmin) ; + } Matrix->SMPkluMatrix->KLUmatrixCommon->tol = PivRel ; if (Matrix->SMPkluMatrix->KLUmatrixNumeric != NULL) { diff --git a/src/maths/ni/niiter.c b/src/maths/ni/niiter.c index 41b811bc6..7671db3df 100644 --- a/src/maths/ni/niiter.c +++ b/src/maths/ni/niiter.c @@ -112,6 +112,11 @@ NIiter(CKTcircuit *ckt, int maxIter) if (ckt->CKTniState & NISHOULDREORDER) { startTime = SPfrontEnd->IFseconds(); + +#ifdef KLU + ckt->CKTmatrix->SMPkluMatrix->KLUloadDiagGmin = 1 ; +#endif + error = SMPreorder(ckt->CKTmatrix, ckt->CKTpivotAbsTol, ckt->CKTpivotRelTol, ckt->CKTdiagGmin); ckt->CKTstat->STATreorderTime += @@ -139,6 +144,11 @@ NIiter(CKTcircuit *ckt, int maxIter) ckt->CKTniState &= ~NISHOULDREORDER; } else { startTime = SPfrontEnd->IFseconds(); + +#ifdef KLU + ckt->CKTmatrix->SMPkluMatrix->KLUloadDiagGmin = 1 ; +#endif + error = SMPluFac(ckt->CKTmatrix, ckt->CKTpivotAbsTol, ckt->CKTdiagGmin); ckt->CKTstat->STATdecompTime += @@ -155,6 +165,7 @@ NIiter(CKTcircuit *ckt, int maxIter) fprintf (stderr, "Warning: KLU ReFactor failed. Factoring again...\n") ; ckt->CKTniState |= NISHOULDREORDER; + ckt->CKTmatrix->SMPkluMatrix->KLUloadDiagGmin = 0 ; error = SMPreorder(ckt->CKTmatrix, ckt->CKTpivotAbsTol, ckt->CKTpivotRelTol, ckt->CKTdiagGmin); ckt->CKTstat->STATreorderTime += SPfrontEnd->IFseconds() - startTime; if (error) { @@ -171,6 +182,19 @@ NIiter(CKTcircuit *ckt, int maxIter) FREE(OldCKTstate0); return(error); } + } else if (error) { + SMPgetError(ckt->CKTmatrix, &i, &j); + SPfrontEnd->IFerrorf (ERR_WARNING, "singular matrix: check nodes %s and %s\n", NODENAME(ckt, i), NODENAME(ckt, j)); + + /* CKTload(ckt); */ + /* SMPprint(ckt->CKTmatrix, stdout); */ + /* seems to be singular - pass the bad news up */ + ckt->CKTstat->STATnumIter += iterno; +#ifdef STEPDEBUG + printf("lufac returned error \n"); +#endif + FREE(OldCKTstate0); + return(error); } #else if (error) {