diff --git a/src/spicelib/devices/asrc/Makefile.am b/src/spicelib/devices/asrc/Makefile.am index 11b2b2701..f733ed914 100644 --- a/src/spicelib/devices/asrc/Makefile.am +++ b/src/spicelib/devices/asrc/Makefile.am @@ -22,6 +22,10 @@ libasrc_la_SOURCES = \ asrctemp.c +if KLU_WANTED +libasrc_la_SOURCES += asrcbindCSC.c +endif + AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/src/include AM_CFLAGS = $(STATIC) MAINTAINERCLEANFILES = Makefile.in diff --git a/src/spicelib/devices/asrc/asrcbindCSC.c b/src/spicelib/devices/asrc/asrcbindCSC.c new file mode 100644 index 000000000..5b5165e33 --- /dev/null +++ b/src/spicelib/devices/asrc/asrcbindCSC.c @@ -0,0 +1,179 @@ +/********** +Author: 2015 Francesco Lannutti +**********/ + +#include "ngspice/ngspice.h" +#include "ngspice/cktdefs.h" +#include "asrcdefs.h" +#include "ngspice/sperror.h" +#include "ngspice/klu-binding.h" + +#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)) ; +} + +int +ASRCbindCSC (GENmodel *inModel, CKTcircuit *ckt) +{ + ASRCmodel *model = (ASRCmodel *)inModel ; + ASRCinstance *here ; + double *i ; + BindElement *matched, *BindStruct ; + size_t nz ; + int j, k ; + + BindStruct = ckt->CKTmatrix->CKTbindStruct ; + nz = (size_t)ckt->CKTmatrix->CKTklunz ; + + /* loop through all the ASRC models */ + for ( ; model != NULL ; model = ASRCnextModel(model)) + { + /* loop through all the instances of the model */ + for (here = ASRCinstances(model); here != NULL ; here = ASRCnextInstance(here)) + { + j = 0 ; + if (here->ASRCtype == ASRC_VOLTAGE) + { + CREATE_KLU_BINDING_TABLE(ASRCposPtr [j], ASRCposBinding [j], ASRCposNode, ASRCbranch); + j++ ; + + CREATE_KLU_BINDING_TABLE(ASRCposPtr [j], ASRCposBinding [j], ASRCnegNode, ASRCbranch); + j++ ; + + CREATE_KLU_BINDING_TABLE(ASRCposPtr [j], ASRCposBinding [j], ASRCbranch, ASRCnegNode); + j++ ; + + CREATE_KLU_BINDING_TABLE(ASRCposPtr [j], ASRCposBinding [j], ASRCbranch, ASRCposNode); + j++ ; + } + + for (k = 0 ; k < here->ASRCtree->numVars ; k++) + { + if (here->ASRCtype == ASRC_VOLTAGE) + { + CREATE_KLU_BINDING_TABLE(ASRCposPtr [j], ASRCposBinding [j], ASRCbranch, ASRCvars [k]); + j++ ; + } else { + CREATE_KLU_BINDING_TABLE(ASRCposPtr [j], ASRCposBinding [j], ASRCposNode, ASRCvars [k]); + j++ ; + + CREATE_KLU_BINDING_TABLE(ASRCposPtr [j], ASRCposBinding [j], ASRCnegNode, ASRCvars [k]); + j++ ; + } + } + } + } + + return (OK) ; +} + +int +ASRCbindCSCComplex (GENmodel *inModel, CKTcircuit *ckt) +{ + ASRCmodel *model = (ASRCmodel *)inModel ; + ASRCinstance *here ; + int j, k ; + + NG_IGNORE (ckt) ; + + /* loop through all the ASRC models */ + for ( ; model != NULL ; model = ASRCnextModel(model)) + { + /* loop through all the instances of the model */ + for (here = ASRCinstances(model); here != NULL ; here = ASRCnextInstance(here)) + { + j = 0 ; + if (here->ASRCtype == ASRC_VOLTAGE) + { + CONVERT_KLU_BINDING_TABLE_TO_COMPLEX(ASRCposPtr [j], ASRCposBinding [j], ASRCposNode, ASRCbranch); + j++ ; + + CONVERT_KLU_BINDING_TABLE_TO_COMPLEX(ASRCposPtr [j], ASRCposBinding [j], ASRCnegNode, ASRCbranch); + j++ ; + + CONVERT_KLU_BINDING_TABLE_TO_COMPLEX(ASRCposPtr [j], ASRCposBinding [j], ASRCbranch, ASRCnegNode); + j++ ; + + CONVERT_KLU_BINDING_TABLE_TO_COMPLEX(ASRCposPtr [j], ASRCposBinding [j], ASRCbranch, ASRCposNode); + j++ ; + } + + for (k = 0 ; k < here->ASRCtree->numVars ; k++) + { + if (here->ASRCtype == ASRC_VOLTAGE) + { + CONVERT_KLU_BINDING_TABLE_TO_COMPLEX(ASRCposPtr [j], ASRCposBinding [j], ASRCbranch, ASRCvars [k]); + j++ ; + } else { + CONVERT_KLU_BINDING_TABLE_TO_COMPLEX(ASRCposPtr [j], ASRCposBinding [j], ASRCposNode, ASRCvars [k]); + j++ ; + + CONVERT_KLU_BINDING_TABLE_TO_COMPLEX(ASRCposPtr [j], ASRCposBinding [j], ASRCnegNode, ASRCvars [k]); + j++ ; + } + } + } + } + + return (OK) ; +} + +int +ASRCbindCSCComplexToReal (GENmodel *inModel, CKTcircuit *ckt) +{ + ASRCmodel *model = (ASRCmodel *)inModel ; + ASRCinstance *here ; + int j, k ; + + NG_IGNORE (ckt) ; + + /* loop through all the ASRC models */ + for ( ; model != NULL ; model = ASRCnextModel(model)) + { + /* loop through all the instances of the model */ + for (here = ASRCinstances(model); here != NULL ; here = ASRCnextInstance(here)) + { + j = 0 ; + if (here->ASRCtype == ASRC_VOLTAGE) + { + CONVERT_KLU_BINDING_TABLE_TO_REAL(ASRCposPtr [j], ASRCposBinding [j], ASRCposNode, ASRCbranch); + j++ ; + + CONVERT_KLU_BINDING_TABLE_TO_REAL(ASRCposPtr [j], ASRCposBinding [j], ASRCnegNode, ASRCbranch); + j++ ; + + CONVERT_KLU_BINDING_TABLE_TO_REAL(ASRCposPtr [j], ASRCposBinding [j], ASRCbranch, ASRCnegNode); + j++ ; + + CONVERT_KLU_BINDING_TABLE_TO_REAL(ASRCposPtr [j], ASRCposBinding [j], ASRCbranch, ASRCposNode); + j++ ; + } + + for (k = 0 ; k < here->ASRCtree->numVars ; k++) + { + if (here->ASRCtype == ASRC_VOLTAGE) + { + CONVERT_KLU_BINDING_TABLE_TO_REAL(ASRCposPtr [j], ASRCposBinding [j], ASRCbranch, ASRCvars [k]); + j++ ; + } else { + CONVERT_KLU_BINDING_TABLE_TO_REAL(ASRCposPtr [j], ASRCposBinding [j], ASRCposNode, ASRCvars [k]); + j++ ; + + CONVERT_KLU_BINDING_TABLE_TO_REAL(ASRCposPtr [j], ASRCposBinding [j], ASRCnegNode, ASRCvars [k]); + j++ ; + } + } + } + } + + return (OK) ; +} diff --git a/src/spicelib/devices/asrc/asrcdefs.h b/src/spicelib/devices/asrc/asrcdefs.h index ddf17cc63..463e74fb1 100644 --- a/src/spicelib/devices/asrc/asrcdefs.h +++ b/src/spicelib/devices/asrc/asrcdefs.h @@ -54,6 +54,10 @@ typedef struct sASRCinstance { unsigned ASRCreciproctcGiven : 1; /* indicates reciproctc flag parameter specified */ unsigned ASRCreciprocmGiven : 1; /* indicates reciprocm flag parameter specified */ +#ifdef KLU + BindElement **ASRCposBinding ; +#endif + } ASRCinstance; diff --git a/src/spicelib/devices/asrc/asrcext.h b/src/spicelib/devices/asrc/asrcext.h index 70e430b4c..77b401388 100644 --- a/src/spicelib/devices/asrc/asrcext.h +++ b/src/spicelib/devices/asrc/asrcext.h @@ -15,3 +15,9 @@ extern int ASRCacLoad(GENmodel *, CKTcircuit *); extern int ASRCsetup(SMPmatrix *, GENmodel *, CKTcircuit *, int *); extern int ASRCunsetup(GENmodel *, CKTcircuit *); extern int ASRCtemp(GENmodel *, CKTcircuit *); + +#ifdef KLU +extern int ASRCbindCSC (GENmodel *, CKTcircuit *) ; +extern int ASRCbindCSCComplex (GENmodel *, CKTcircuit *) ; +extern int ASRCbindCSCComplexToReal (GENmodel *, CKTcircuit *) ; +#endif diff --git a/src/spicelib/devices/asrc/asrcinit.c b/src/spicelib/devices/asrc/asrcinit.c index fa565465c..7312d9662 100644 --- a/src/spicelib/devices/asrc/asrcinit.c +++ b/src/spicelib/devices/asrc/asrcinit.c @@ -70,9 +70,9 @@ SPICEdev ASRCinfo = { #endif #ifdef KLU - .DEVbindCSC = NULL, - .DEVbindCSCComplex = NULL, - .DEVbindCSCComplexToReal = NULL, + .DEVbindCSC = ASRCbindCSC, + .DEVbindCSCComplex = ASRCbindCSCComplex, + .DEVbindCSCComplexToReal = ASRCbindCSCComplexToReal, #endif }; diff --git a/src/spicelib/devices/asrc/asrcset.c b/src/spicelib/devices/asrc/asrcset.c index 3873129ea..e88b04dd5 100644 --- a/src/spicelib/devices/asrc/asrcset.c +++ b/src/spicelib/devices/asrc/asrcset.c @@ -69,6 +69,10 @@ int ASRCsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, here->ASRCvars = TMALLOC(int, here->ASRCtree->numVars); here->ASRCacValues = TMALLOC(double, here->ASRCtree->numVars + 1); +#ifdef KLU + here->ASRCposBinding = TMALLOC (BindElement *, j) ; +#endif + /* For each controlling variable set the entries in the vector of the positions of the SMP */