diff --git a/src/spicelib/devices/asrc/Makefile.am b/src/spicelib/devices/asrc/Makefile.am index 01f292d21..e97fa7cdd 100644 --- a/src/spicelib/devices/asrc/Makefile.am +++ b/src/spicelib/devices/asrc/Makefile.am @@ -23,6 +23,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..8f2d3b483 --- /dev/null +++ b/src/spicelib/devices/asrc/asrcbindCSC.c @@ -0,0 +1,262 @@ +/********** +Author: 2015 Francesco Lannutti +**********/ + +#include "ngspice/ngspice.h" +#include "ngspice/cktdefs.h" +#include "asrcdefs.h" +#include "ngspice/sperror.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 = model->ASRCnextModel) + { + /* loop through all the instances of the model */ + for (here = model->ASRCinstances ; here != NULL ; here = here->ASRCnextInstance) + { + j = 0 ; + if (here->ASRCtype == ASRC_VOLTAGE) + { + if ((here->ASRCposNode != 0) && (here->ASRCbranch != 0)) + { + i = here->ASRCposptr [j] ; + matched = (BindElement *) bsearch (&i, BindStruct, nz, sizeof(BindElement), BindCompare) ; + here->ASRCposptrStructPtr [j] = matched ; + here->ASRCposptr [j] = matched->CSC ; + } + j++ ; + + if ((here->ASRCnegNode != 0) && (here->ASRCbranch != 0)) + { + i = here->ASRCposptr [j] ; + matched = (BindElement *) bsearch (&i, BindStruct, nz, sizeof(BindElement), BindCompare) ; + here->ASRCposptrStructPtr [j] = matched ; + here->ASRCposptr [j] = matched->CSC ; + } + j++ ; + + if ((here->ASRCbranch != 0) && (here->ASRCnegNode != 0)) + { + i = here->ASRCposptr [j] ; + matched = (BindElement *) bsearch (&i, BindStruct, nz, sizeof(BindElement), BindCompare) ; + here->ASRCposptrStructPtr [j] = matched ; + here->ASRCposptr [j] = matched->CSC ; + } + j++ ; + + if ((here->ASRCbranch != 0) && (here->ASRCposNode != 0)) + { + i = here->ASRCposptr [j] ; + matched = (BindElement *) bsearch (&i, BindStruct, nz, sizeof(BindElement), BindCompare) ; + here->ASRCposptrStructPtr [j] = matched ; + here->ASRCposptr [j] = matched->CSC ; + } + j++ ; + } + + for (k = 0 ; k < here->ASRCtree->numVars ; k++) + { + if (here->ASRCtype == ASRC_VOLTAGE) + { + if ((here->ASRCbranch != 0) && (here->ASRCvars [k] != 0)) + { + i = here->ASRCposptr [j] ; + matched = (BindElement *) bsearch (&i, BindStruct, nz, sizeof(BindElement), BindCompare) ; + here->ASRCposptrStructPtr [j] = matched ; + here->ASRCposptr [j] = matched->CSC ; + } + j++ ; + } else { + if ((here->ASRCposNode != 0) && (here->ASRCvars [k] != 0)) + { + i = here->ASRCposptr [j] ; + matched = (BindElement *) bsearch (&i, BindStruct, nz, sizeof(BindElement), BindCompare) ; + here->ASRCposptrStructPtr [j] = matched ; + here->ASRCposptr [j] = matched->CSC ; + } + j++ ; + + if ((here->ASRCnegNode != 0) && (here->ASRCvars [k] != 0)) + { + i = here->ASRCposptr [j] ; + matched = (BindElement *) bsearch (&i, BindStruct, nz, sizeof(BindElement), BindCompare) ; + here->ASRCposptrStructPtr [j] = matched ; + here->ASRCposptr [j] = matched->CSC ; + } + 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 = model->ASRCnextModel) + { + /* loop through all the instances of the model */ + for (here = model->ASRCinstances ; here != NULL ; here = here->ASRCnextInstance) + { + j = 0 ; + if (here->ASRCtype == ASRC_VOLTAGE) + { + if ((here->ASRCposNode != 0) && (here->ASRCbranch != 0)) + { + here->ASRCposptr [j] = here->ASRCposptrStructPtr [j]->CSC_Complex ; + } + j++ ; + + if ((here->ASRCnegNode != 0) && (here->ASRCbranch != 0)) + { + here->ASRCposptr [j] = here->ASRCposptrStructPtr [j]->CSC_Complex ; + } + j++ ; + + if ((here->ASRCbranch != 0) && (here->ASRCnegNode != 0)) + { + here->ASRCposptr [j] = here->ASRCposptrStructPtr [j]->CSC_Complex ; + } + j++ ; + + if ((here->ASRCbranch != 0) && (here->ASRCposNode != 0)) + { + here->ASRCposptr [j] = here->ASRCposptrStructPtr [j]->CSC_Complex ; + } + j++ ; + } + + for (k = 0 ; k < here->ASRCtree->numVars ; k++) + { + if (here->ASRCtype == ASRC_VOLTAGE) + { + if ((here->ASRCbranch != 0) && (here->ASRCvars [k] != 0)) + { + here->ASRCposptr [j] = here->ASRCposptrStructPtr [j]->CSC_Complex ; + } + j++ ; + } else { + if ((here->ASRCposNode != 0) && (here->ASRCvars [k] != 0)) + { + here->ASRCposptr [j] = here->ASRCposptrStructPtr [j]->CSC_Complex ; + } + j++ ; + + if ((here->ASRCnegNode != 0) && (here->ASRCvars [k] != 0)) + { + here->ASRCposptr [j] = here->ASRCposptrStructPtr [j]->CSC_Complex ; + } + 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 = model->ASRCnextModel) + { + /* loop through all the instances of the model */ + for (here = model->ASRCinstances ; here != NULL ; here = here->ASRCnextInstance) + { + j = 0 ; + if (here->ASRCtype == ASRC_VOLTAGE) + { + if ((here->ASRCposNode != 0) && (here->ASRCbranch != 0)) + { + here->ASRCposptr [j] = here->ASRCposptrStructPtr [j]->CSC ; + } + j++ ; + + if ((here->ASRCnegNode != 0) && (here->ASRCbranch != 0)) + { + here->ASRCposptr [j] = here->ASRCposptrStructPtr [j]->CSC ; + } + j++ ; + + if ((here->ASRCbranch != 0) && (here->ASRCnegNode != 0)) + { + here->ASRCposptr [j] = here->ASRCposptrStructPtr [j]->CSC ; + } + j++ ; + + if ((here->ASRCbranch != 0) && (here->ASRCposNode != 0)) + { + here->ASRCposptr [j] = here->ASRCposptrStructPtr [j]->CSC ; + } + j++ ; + } + + for (k = 0 ; k < here->ASRCtree->numVars ; k++) + { + if (here->ASRCtype == ASRC_VOLTAGE) + { + if ((here->ASRCbranch != 0) && (here->ASRCvars [k] != 0)) + { + here->ASRCposptr [j] = here->ASRCposptrStructPtr [j]->CSC ; + } + j++ ; + } else { + if ((here->ASRCposNode != 0) && (here->ASRCvars [k] != 0)) + { + here->ASRCposptr [j] = here->ASRCposptrStructPtr [j]->CSC ; + } + j++ ; + + if ((here->ASRCnegNode != 0) && (here->ASRCvars [k] != 0)) + { + here->ASRCposptr [j] = here->ASRCposptrStructPtr [j]->CSC ; + } + j++ ; + } + } + } + } + + return (OK) ; +} diff --git a/src/spicelib/devices/asrc/asrcdefs.h b/src/spicelib/devices/asrc/asrcdefs.h index 93bdef553..1d2f18454 100644 --- a/src/spicelib/devices/asrc/asrcdefs.h +++ b/src/spicelib/devices/asrc/asrcdefs.h @@ -47,6 +47,10 @@ typedef struct sASRCinstance { unsigned ASRCtc2Given : 1; /* indicates tc2 parameter specified */ unsigned ASRCreciproctcGiven : 1; /* indicates reciproctc flag parameter specified */ +#ifdef KLU + BindElement **ASRCposptrStructPtr ; +#endif + } ASRCinstance; diff --git a/src/spicelib/devices/asrc/asrcext.h b/src/spicelib/devices/asrc/asrcext.h index 14218c685..d3df52e3a 100644 --- a/src/spicelib/devices/asrc/asrcext.h +++ b/src/spicelib/devices/asrc/asrcext.h @@ -16,3 +16,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 89518c8ce..36d226903 100644 --- a/src/spicelib/devices/asrc/asrcinit.c +++ b/src/spicelib/devices/asrc/asrcinit.c @@ -77,9 +77,9 @@ SPICEdev ASRCinfo = { /* DEVmodSize */ &ASRCmSize, #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 8ff3b122b..ba6cef852 100644 --- a/src/spicelib/devices/asrc/asrcset.c +++ b/src/spicelib/devices/asrc/asrcset.c @@ -65,6 +65,10 @@ ASRCsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states) here->ASRCvars = TMALLOC(int, here->ASRCtree->numVars); here->ASRCacValues = TMALLOC(double, here->ASRCtree->numVars + 1); +#ifdef KLU + here->ASRCposptrStructPtr = TMALLOC (BindElement *, j) ; +#endif + /* For each controlling variable set the entries in the vector of the positions of the SMP */