diff --git a/src/include/ngspice/klu.h b/src/include/ngspice/klu.h index f8e23b9ba..1d4ed1eb1 100644 --- a/src/include/ngspice/klu.h +++ b/src/include/ngspice/klu.h @@ -130,6 +130,7 @@ typedef struct /* 64-bit version (otherwise same as above) */ /* Common->status values */ #define KLU_OK 0 #define KLU_SINGULAR (1) /* status > 0 is a warning, not an error */ +#define KLU_EMPTY_MATRIX (2) /* Modified by Francesco Lannutti - Case when the matrix is empty */ #define KLU_OUT_OF_MEMORY (-2) #define KLU_INVALID (-3) #define KLU_TOO_LARGE (-4) /* integer overflow has occured */ diff --git a/src/maths/KLU/klu_analyze_given.c b/src/maths/KLU/klu_analyze_given.c index bee547345..f38e1f8ee 100644 --- a/src/maths/KLU/klu_analyze_given.c +++ b/src/maths/KLU/klu_analyze_given.c @@ -41,6 +41,12 @@ KLU_symbolic *KLU_alloc_symbolic if (n <= 0 || Ap == NULL || Ai == NULL) { + if (n == 0) + { + Common->status = KLU_EMPTY_MATRIX ; + return (NULL) ; + } + /* Ap and Ai must be present, and n must be > 0 */ Common->status = KLU_INVALID ; return (NULL) ; diff --git a/src/maths/KLU/klu_factor.c b/src/maths/KLU/klu_factor.c index 50b52ea6d..f27dc9182 100644 --- a/src/maths/KLU/klu_factor.c +++ b/src/maths/KLU/klu_factor.c @@ -402,6 +402,10 @@ KLU_numeric *KLU_factor /* returns NULL if error, or a valid { return (NULL) ; } + if (Common->status == KLU_EMPTY_MATRIX) + { + return (NULL) ; + } Common->status = KLU_OK ; Common->numerical_rank = EMPTY ; Common->singular_col = EMPTY ; diff --git a/src/maths/KLU/klu_refactor.c b/src/maths/KLU/klu_refactor.c index 7eb6fe8a9..95dcb03b2 100644 --- a/src/maths/KLU/klu_refactor.c +++ b/src/maths/KLU/klu_refactor.c @@ -46,6 +46,10 @@ Int KLU_refactor /* returns TRUE if successful, FALSE otherwise */ { return (FALSE) ; } + if (Common->status == KLU_EMPTY_MATRIX) + { + return (FALSE) ; + } Common->status = KLU_OK ; if (Numeric == NULL) diff --git a/src/maths/KLU/klu_solve.c b/src/maths/KLU/klu_solve.c index d23a14095..1f148b47a 100644 --- a/src/maths/KLU/klu_solve.c +++ b/src/maths/KLU/klu_solve.c @@ -41,6 +41,10 @@ Int KLU_solve { return (FALSE) ; } + if (Common->status == KLU_EMPTY_MATRIX) + { + return (FALSE) ; + } if (Numeric == NULL || Symbolic == NULL || d < Symbolic->n || nrhs < 0 || B == NULL) { diff --git a/src/maths/KLU/klu_tsolve.c b/src/maths/KLU/klu_tsolve.c index c1f10f708..5075c0202 100644 --- a/src/maths/KLU/klu_tsolve.c +++ b/src/maths/KLU/klu_tsolve.c @@ -46,6 +46,10 @@ Int KLU_tsolve { return (FALSE) ; } + if (Common->status == KLU_EMPTY_MATRIX) + { + return (FALSE) ; + } if (Numeric == NULL || Symbolic == NULL || d < Symbolic->n || nrhs < 0 || B == NULL) { diff --git a/src/maths/KLU/klusmp.c b/src/maths/KLU/klusmp.c index aa7cb0a84..70c43e3ee 100644 --- a/src/maths/KLU/klusmp.c +++ b/src/maths/KLU/klusmp.c @@ -207,6 +207,11 @@ SMPcLUfac (SMPmatrix *Matrix, double PivTol) spSetComplex (Matrix->SPmatrix) ; ret = klu_z_refactor (Matrix->CKTkluAp, Matrix->CKTkluAi, Matrix->CKTkluAx_Complex, Matrix->CKTkluSymbolic, Matrix->CKTkluNumeric, Matrix->CKTkluCommon) ; + + if (Matrix->CKTkluCommon->status == KLU_EMPTY_MATRIX) + { + return 0 ; + } return (!ret) ; } else { spSetComplex (Matrix->SPmatrix) ; @@ -232,6 +237,11 @@ SMPluFac (SMPmatrix *Matrix, double PivTol, double Gmin) LoadGmin_CSC (Matrix->CKTdiag_CSC, Matrix->CKTkluN, Gmin) ; ret = klu_refactor (Matrix->CKTkluAp, Matrix->CKTkluAi, Matrix->CKTkluAx, Matrix->CKTkluSymbolic, Matrix->CKTkluNumeric, Matrix->CKTkluCommon) ; + + if (Matrix->CKTkluCommon->status == KLU_EMPTY_MATRIX) + { + return 0 ; + } return (!ret) ; // if (ret == 1) @@ -269,7 +279,13 @@ SMPcReorder (SMPmatrix *Matrix, double PivTol, double PivRel, int *NumSwaps) Matrix->CKTkluNumeric = klu_z_factor (Matrix->CKTkluAp, Matrix->CKTkluAi, Matrix->CKTkluAx_Complex, Matrix->CKTkluSymbolic, Matrix->CKTkluCommon) ; if (Matrix->CKTkluNumeric == NULL) + { + if (Matrix->CKTkluCommon->status == KLU_EMPTY_MATRIX) + { + return 0 ; + } return 1 ; + } else return 0 ; } else { @@ -299,7 +315,13 @@ SMPreorder (SMPmatrix *Matrix, double PivTol, double PivRel, double Gmin) Matrix->CKTkluNumeric = klu_factor (Matrix->CKTkluAp, Matrix->CKTkluAi, Matrix->CKTkluAx, Matrix->CKTkluSymbolic, Matrix->CKTkluCommon) ; if (Matrix->CKTkluNumeric == NULL) + { + if (Matrix->CKTkluCommon->status == KLU_EMPTY_MATRIX) + { + return 0 ; + } return 1 ; + } else return 0 ; } else { @@ -459,7 +481,16 @@ SMPpreOrder (SMPmatrix *Matrix) { Matrix->CKTkluSymbolic = klu_analyze (Matrix->CKTkluN, Matrix->CKTkluAp, Matrix->CKTkluAi, Matrix->CKTkluCommon) ; - return 0 ; + if (Matrix->CKTkluSymbolic == NULL) + { + if (Matrix->CKTkluCommon->status == KLU_EMPTY_MATRIX) + { + return 0 ; + } + return 1 ; + } else { + return 0 ; + } } else { spMNA_Preorder (Matrix->SPmatrix) ; return spError (Matrix->SPmatrix) ;