diff --git a/src/spicelib/analysis/cktpzset.c b/src/spicelib/analysis/cktpzset.c index 5d9a58a0b..3762cbef2 100644 --- a/src/spicelib/analysis/cktpzset.c +++ b/src/spicelib/analysis/cktpzset.c @@ -14,6 +14,20 @@ Copyright 1990 Regents of the University of California. All rights reserved. #include "ngspice/devdefs.h" #include "ngspice/sperror.h" +#ifdef KLU +#include + +static +int +BindCompare (const void *a, const void *b) +{ + BindElement *A, *B ; + A = (BindElement *)a ; + B = (BindElement *)b ; + + return ((int)(A->Sparse - B->Sparse)) ; +} +#endif int CKTpzSetup(CKTcircuit *ckt, int type) @@ -89,6 +103,77 @@ CKTpzSetup(CKTcircuit *ckt, int type) job->PZnumswaps = 1; +#ifdef KLU + if (ckt->CKTmatrix->CKTkluMODE) + { + fprintf (stderr, "Using KLU as Direct Linear Solver\n") ; + + int i ; + int n = SMPmatSize (ckt->CKTmatrix) ; + ckt->CKTmatrix->CKTkluN = n ; + + SMPnnz (ckt->CKTmatrix) ; + int nz = ckt->CKTmatrix->CKTklunz ; + + ckt->CKTmatrix->CKTkluAp = TMALLOC (int, n + 1) ; + ckt->CKTmatrix->CKTkluAi = TMALLOC (int, nz) ; + ckt->CKTmatrix->CKTkluAx = TMALLOC (double, nz) ; + ckt->CKTmatrix->CKTkluIntermediate = TMALLOC (double, n) ; + + ckt->CKTmatrix->CKTbindStruct = TMALLOC (BindElement, nz) ; + + ckt->CKTmatrix->CKTdiag_CSC = TMALLOC (double *, n) ; + + /* Complex Stuff needed for AC Analysis */ + ckt->CKTmatrix->CKTkluAx_Complex = TMALLOC (double, 2 * nz) ; + ckt->CKTmatrix->CKTkluIntermediate_Complex = TMALLOC (double, 2 * n) ; + + /* Binding Table from Sparse to CSC Format Creation */ + SMPmatrix_CSC (ckt->CKTmatrix) ; + + /* Binding Table Sorting */ + qsort (ckt->CKTmatrix->CKTbindStruct, (size_t)nz, sizeof(BindElement), BindCompare) ; + + /* KLU Pointers Assignment */ + for (i = 0 ; i < DEVmaxnum ; i++) + if (DEVices [i] && DEVices [i]->DEVbindCSC && ckt->CKThead [i]) + DEVices [i]->DEVbindCSC (ckt->CKThead [i], ckt) ; + + /* ReOrder */ + error = SMPpreOrder (ckt->CKTmatrix) ; + if (error) { + fprintf (stderr, "Error during ReOrdering\n") ; + } + + /* Conversion from Real Matrix to Complex Matrix */ + for (i = 0 ; i < DEVmaxnum ; i++) + if (DEVices [i] && DEVices [i]->DEVbindCSCComplex && ckt->CKThead [i]) + DEVices [i]->DEVbindCSCComplex (ckt->CKThead [i], ckt) ; + + ckt->CKTmatrix->CKTkluMatrixIsComplex = CKTkluMatrixComplex ; + + /* Input Pos */ + if ((input_pos != 0) && (solution_col != 0)) + { + double *j ; + + j = job->PZdrive_pptr ; + job->PZdrive_pptr = ((BindElement *) bsearch (&j, ckt->CKTmatrix->CKTbindStruct, (size_t)nz, sizeof(BindElement), BindCompare))->CSC_Complex ; + } + + /* Input Neg */ + if ((input_neg != 0) && (solution_col != 0)) + { + double *j ; + + j = job->PZdrive_nptr ; + job->PZdrive_nptr = ((BindElement *) bsearch (&j, ckt->CKTmatrix->CKTbindStruct, (size_t)nz, sizeof(BindElement), BindCompare))->CSC_Complex ; + } + } else { + fprintf (stderr, "Using SPARSE 1.3 as Direct Linear Solver\n") ; + } +#endif + error = NIreinit(ckt); if (error) return(error); diff --git a/src/spicelib/devices/vsrc/vsrcbindCSC.c b/src/spicelib/devices/vsrc/vsrcbindCSC.c index 8c1781395..dcff38d88 100644 --- a/src/spicelib/devices/vsrc/vsrcbindCSC.c +++ b/src/spicelib/devices/vsrc/vsrcbindCSC.c @@ -43,6 +43,17 @@ VSRCbindCSC (GENmodel *inModel, CKTcircuit *ckt) CREATE_KLU_BINDING_TABLE(VSRCnegIbrPtr, VSRCnegIbrBinding, VSRCnegNode, VSRCbranch); CREATE_KLU_BINDING_TABLE(VSRCibrNegPtr, VSRCibrNegBinding, VSRCbranch, VSRCnegNode); CREATE_KLU_BINDING_TABLE(VSRCibrPosPtr, VSRCibrPosBinding, VSRCbranch, VSRCposNode); + /* Pole-Zero Analysis */ + if ((here-> VSRCbranch != 0) && (here-> VSRCbranch != 0)) + { + i = here->VSRCibrIbrPtr ; + matched = (BindElement *) bsearch (&i, BindStruct, nz, sizeof(BindElement), BindCompare) ; + here->VSRCibrIbrBinding = matched ; + if (matched != NULL) + { + here->VSRCibrIbrPtr = matched->CSC ; + } + } } } @@ -67,6 +78,14 @@ VSRCbindCSCComplex (GENmodel *inModel, CKTcircuit *ckt) CONVERT_KLU_BINDING_TABLE_TO_COMPLEX(VSRCnegIbrPtr, VSRCnegIbrBinding, VSRCnegNode, VSRCbranch); CONVERT_KLU_BINDING_TABLE_TO_COMPLEX(VSRCibrNegPtr, VSRCibrNegBinding, VSRCbranch, VSRCnegNode); CONVERT_KLU_BINDING_TABLE_TO_COMPLEX(VSRCibrPosPtr, VSRCibrPosBinding, VSRCbranch, VSRCposNode); + /* Pole-Zero Analysis */ + if ((here-> VSRCbranch != 0) && (here-> VSRCbranch != 0)) + { + if (here->VSRCibrIbrBinding != NULL) + { + here->VSRCibrIbrPtr = here->VSRCibrIbrBinding->CSC_Complex ; + } + } } } @@ -91,6 +110,14 @@ VSRCbindCSCComplexToReal (GENmodel *inModel, CKTcircuit *ckt) CONVERT_KLU_BINDING_TABLE_TO_REAL(VSRCnegIbrPtr, VSRCnegIbrBinding, VSRCnegNode, VSRCbranch); CONVERT_KLU_BINDING_TABLE_TO_REAL(VSRCibrNegPtr, VSRCibrNegBinding, VSRCbranch, VSRCnegNode); CONVERT_KLU_BINDING_TABLE_TO_REAL(VSRCibrPosPtr, VSRCibrPosBinding, VSRCbranch, VSRCposNode); + /* Pole-Zero Analysis */ + if ((here-> VSRCbranch != 0) && (here-> VSRCbranch != 0)) + { + if (here->VSRCibrIbrBinding != NULL) + { + here->VSRCibrIbrPtr = here->VSRCibrIbrBinding->CSC ; + } + } } } diff --git a/src/spicelib/devices/vsrc/vsrcdefs.h b/src/spicelib/devices/vsrc/vsrcdefs.h index e3cb8d551..21cbee378 100644 --- a/src/spicelib/devices/vsrc/vsrcdefs.h +++ b/src/spicelib/devices/vsrc/vsrcdefs.h @@ -83,6 +83,7 @@ typedef struct sVSRCinstance { BindElement *VSRCnegIbrBinding ; BindElement *VSRCibrNegBinding ; BindElement *VSRCibrPosBinding ; + BindElement *VSRCibrIbrBinding ; #endif } VSRCinstance ; diff --git a/src/spicelib/devices/vsrc/vsrcset.c b/src/spicelib/devices/vsrc/vsrcset.c index 7511acc3c..6ec98db9c 100644 --- a/src/spicelib/devices/vsrc/vsrcset.c +++ b/src/spicelib/devices/vsrc/vsrcset.c @@ -53,6 +53,11 @@ do { if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\ TSTALLOC(VSRCnegIbrPtr, VSRCnegNode, VSRCbranch); TSTALLOC(VSRCibrNegPtr, VSRCbranch, VSRCnegNode); TSTALLOC(VSRCibrPosPtr, VSRCbranch, VSRCposNode); + +#ifdef KLU + here->VSRCibrIbrPtr = NULL ; +#endif + } } return(OK);