From ff9af114d419604bdd0f57f0ee166b53d6b39354 Mon Sep 17 00:00:00 2001 From: Francesco Lannutti Date: Sun, 19 Jun 2016 01:21:46 +0200 Subject: [PATCH] klu_extract_Udiag, Fixed the PZ Analysis for KLU - Added a missing KLU node in VSRC which exists only in case of PZ Analysis - Other fixes --- src/include/ngspice/klu.h | 40 +++++++++++ src/maths/KLU/klu_extract.c | 139 ++++++++++++++++++++++++++++++++++++ src/maths/KLU/klu_version.h | 2 + 3 files changed, 181 insertions(+) diff --git a/src/include/ngspice/klu.h b/src/include/ngspice/klu.h index 1d4ed1eb1..d46679ad9 100644 --- a/src/include/ngspice/klu.h +++ b/src/include/ngspice/klu.h @@ -707,6 +707,26 @@ int klu_extract /* returns TRUE if successful, FALSE otherwise */ ) ; +/* Francesco - Extract only Udiag */ +int klu_extract_Udiag /* returns TRUE if successful, FALSE otherwise */ +( + /* inputs: */ + klu_numeric *Numeric, + klu_symbolic *Symbolic, + + /* outputs, all of which must be allocated on input */ + + /* U */ + double *Ux, /* size nnz(U) */ + + int *P, + int *Q, + double *Rs, + + klu_common *Common +) ; + + int klu_z_extract /* returns TRUE if successful, FALSE otherwise */ ( /* inputs: */ @@ -748,6 +768,26 @@ int klu_z_extract /* returns TRUE if successful, FALSE otherwise */ klu_common *Common ) ; +/* Francesco - Extract only Udiag */ +int klu_z_extract_Udiag /* returns TRUE if successful, FALSE otherwise */ +( + /* inputs: */ + klu_numeric *Numeric, + klu_symbolic *Symbolic, + + /* outputs, all of which must be allocated on input */ + + /* U */ + double *Ux, /* size nnz(U) */ + double *Uz, /* size nnz(U) for the complex case, ignored if real */ + + int *P, + int *Q, + double *Rs, + + klu_common *Common +) ; + UF_long klu_l_extract (klu_l_numeric *, klu_l_symbolic *, UF_long *, UF_long *, double *, UF_long *, UF_long *, double *, diff --git a/src/maths/KLU/klu_extract.c b/src/maths/KLU/klu_extract.c index b009828a7..394f0db4d 100644 --- a/src/maths/KLU/klu_extract.c +++ b/src/maths/KLU/klu_extract.c @@ -288,3 +288,142 @@ Int KLU_extract /* returns TRUE if successful, FALSE otherwise */ return (TRUE) ; } + +/* Francesco - Extract only Udiag */ +Int KLU_extract_Udiag /* returns TRUE if successful, FALSE otherwise */ +( + /* inputs: */ + KLU_numeric *Numeric, + KLU_symbolic *Symbolic, + + /* outputs, all of which must be allocated on input */ + + /* U */ + double *Ux, /* size nnz(U) */ +#ifdef COMPLEX + double *Uz, /* size nnz(U) for the complex case, ignored if real */ +#endif + + Int *P, + Int *Q, + double *Rs, + + KLU_common *Common +) +{ + Entry *Ukk ; + Int block, k1, k2, kk, i, n, nk, nblocks, nz ; + + if (Common == NULL) + { + return (FALSE) ; + } + + if (Common->status == KLU_EMPTY_MATRIX) + { + return (FALSE) ; + } + + if (Symbolic == NULL || Numeric == NULL) + { + Common->status = KLU_INVALID ; + return (FALSE) ; + } + + Common->status = KLU_OK ; + n = Symbolic->n ; + nblocks = Symbolic->nblocks ; + + /* ---------------------------------------------------------------------- */ + /* extract scale factors */ + /* ---------------------------------------------------------------------- */ + + if (Rs != NULL) + { + if (Numeric->Rs != NULL) + { + for (i = 0 ; i < n ; i++) + { + Rs [i] = Numeric->Rs [i] ; + } + } + else + { + /* no scaling */ + for (i = 0 ; i < n ; i++) + { + Rs [i] = 1 ; + } + } + } + + /* ---------------------------------------------------------------------- */ + /* extract final row permutation */ + /* ---------------------------------------------------------------------- */ + + if (P != NULL) + { + for (i = 0 ; i < n ; i++) + { + P [i] = Numeric->Pnum [i] ; + } + } + + /* ---------------------------------------------------------------------- */ + /* extract column permutation */ + /* ---------------------------------------------------------------------- */ + + if (Q != NULL) + { + for (i = 0 ; i < n ; i++) + { + Q [i] = Symbolic->Q [i] ; + } + } + + /* ---------------------------------------------------------------------- */ + /* extract each block of U */ + /* ---------------------------------------------------------------------- */ + + if (Ux != NULL +#ifdef COMPLEX + && Uz != NULL +#endif + ) + { + nz = 0 ; + for (block = 0 ; block < nblocks ; block++) + { + k1 = Symbolic->R [block] ; + k2 = Symbolic->R [block+1] ; + nk = k2 - k1 ; + Ukk = ((Entry *) Numeric->Udiag) + k1 ; + if (nk == 1) + { + /* singleton block */ + Ux [nz] = REAL (Ukk [0]) ; +#ifdef COMPLEX + Uz [nz] = IMAG (Ukk [0]) ; +#endif + nz++ ; + } + else + { + /* non-singleton block */ + for (kk = 0 ; kk < nk ; kk++) + { + /* add the diagonal entry */ + Ux [nz] = REAL (Ukk [kk]) ; +#ifdef COMPLEX + Uz [nz] = IMAG (Ukk [kk]) ; +#endif + nz++ ; + } + } + } + ASSERT (nz == Numeric->unz) ; + + } + + return (TRUE) ; +} diff --git a/src/maths/KLU/klu_version.h b/src/maths/KLU/klu_version.h index 71099c380..7ba68fb96 100644 --- a/src/maths/KLU/klu_version.h +++ b/src/maths/KLU/klu_version.h @@ -82,6 +82,7 @@ #define KLU_rgrowth klu_z_rgrowth #define KLU_rcond klu_z_rcond #define KLU_extract klu_z_extract +#define KLU_extract_Udiag klu_z_extract_Udiag #define KLU_condest klu_z_condest #define KLU_flops klu_z_flops @@ -132,6 +133,7 @@ #define KLU_rgrowth klu_rgrowth #define KLU_rcond klu_rcond #define KLU_extract klu_extract +#define KLU_extract_Udiag klu_extract_Udiag #define KLU_condest klu_condest #define KLU_flops klu_flops