diff --git a/src/spicelib/devices/numd2/Makefile.am b/src/spicelib/devices/numd2/Makefile.am index d4734642b..30f96bf0f 100644 --- a/src/spicelib/devices/numd2/Makefile.am +++ b/src/spicelib/devices/numd2/Makefile.am @@ -24,6 +24,17 @@ libnumd2_la_SOURCES = \ nud2trun.c +if KLU_WANTED +libnumd2_la_SOURCES += numd2bindCSC.c +endif + +if SuperLU_WANTED +libnumd2_la_SOURCES += numd2bindCSC.c +endif + +if UMFPACK_WANTED +libnumd2_la_SOURCES += numd2bindCSC.c +endif AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/src/include AM_CFLAGS = $(STATIC) diff --git a/src/spicelib/devices/numd2/numd2bindCSC.c b/src/spicelib/devices/numd2/numd2bindCSC.c new file mode 100644 index 000000000..88e1aecea --- /dev/null +++ b/src/spicelib/devices/numd2/numd2bindCSC.c @@ -0,0 +1,141 @@ +/********** +Author: 2013 Francesco Lannutti +**********/ + +#include "ngspice/ngspice.h" +#include "ngspice/cktdefs.h" +#include "numd2def.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 +NUMD2bindCSC (GENmodel *inModel, CKTcircuit *ckt) +{ + NUMD2model *model = (NUMD2model *)inModel ; + NUMD2instance *here ; + double *i ; + BindElement *matched, *BindStruct ; + size_t nz ; + + BindStruct = ckt->CKTmatrix->CKTbindStruct ; + nz = (size_t)ckt->CKTmatrix->CKTklunz ; + + /* loop through all the NUMD2 models */ + for ( ; model != NULL ; model = model->NUMD2nextModel) + { + /* loop through all the instances of the model */ + for (here = model->NUMD2instances ; here != NULL ; here = here->NUMD2nextInstance) + { + if ((here-> NUMD2posNode != 0) && (here-> NUMD2posNode != 0)) + { + i = here->NUMD2posPosPtr ; + matched = (BindElement *) bsearch (&i, BindStruct, nz, sizeof(BindElement), BindCompare) ; + here->NUMD2posPosStructPtr = matched ; + here->NUMD2posPosPtr = matched->CSC ; + } + + if ((here-> NUMD2negNode != 0) && (here-> NUMD2negNode != 0)) + { + i = here->NUMD2negNegPtr ; + matched = (BindElement *) bsearch (&i, BindStruct, nz, sizeof(BindElement), BindCompare) ; + here->NUMD2negNegStructPtr = matched ; + here->NUMD2negNegPtr = matched->CSC ; + } + + if ((here-> NUMD2negNode != 0) && (here-> NUMD2posNode != 0)) + { + i = here->NUMD2negPosPtr ; + matched = (BindElement *) bsearch (&i, BindStruct, nz, sizeof(BindElement), BindCompare) ; + here->NUMD2negPosStructPtr = matched ; + here->NUMD2negPosPtr = matched->CSC ; + } + + if ((here-> NUMD2posNode != 0) && (here-> NUMD2negNode != 0)) + { + i = here->NUMD2posNegPtr ; + matched = (BindElement *) bsearch (&i, BindStruct, nz, sizeof(BindElement), BindCompare) ; + here->NUMD2posNegStructPtr = matched ; + here->NUMD2posNegPtr = matched->CSC ; + } + + } + } + + return (OK) ; +} + +int +NUMD2bindCSCComplex (GENmodel *inModel, CKTcircuit *ckt) +{ + NUMD2model *model = (NUMD2model *)inModel ; + NUMD2instance *here ; + + NG_IGNORE (ckt) ; + + /* loop through all the NUMD2 models */ + for ( ; model != NULL ; model = model->NUMD2nextModel) + { + /* loop through all the instances of the model */ + for (here = model->NUMD2instances ; here != NULL ; here = here->NUMD2nextInstance) + { + if ((here-> NUMD2posNode != 0) && (here-> NUMD2posNode != 0)) + here->NUMD2posPosPtr = here->NUMD2posPosStructPtr->CSC_Complex ; + + if ((here-> NUMD2negNode != 0) && (here-> NUMD2negNode != 0)) + here->NUMD2negNegPtr = here->NUMD2negNegStructPtr->CSC_Complex ; + + if ((here-> NUMD2negNode != 0) && (here-> NUMD2posNode != 0)) + here->NUMD2negPosPtr = here->NUMD2negPosStructPtr->CSC_Complex ; + + if ((here-> NUMD2posNode != 0) && (here-> NUMD2negNode != 0)) + here->NUMD2posNegPtr = here->NUMD2posNegStructPtr->CSC_Complex ; + + } + } + + return (OK) ; +} + +int +NUMD2bindCSCComplexToReal (GENmodel *inModel, CKTcircuit *ckt) +{ + NUMD2model *model = (NUMD2model *)inModel ; + NUMD2instance *here ; + + NG_IGNORE (ckt) ; + + /* loop through all the NUMD2 models */ + for ( ; model != NULL ; model = model->NUMD2nextModel) + { + /* loop through all the instances of the model */ + for (here = model->NUMD2instances ; here != NULL ; here = here->NUMD2nextInstance) + { + if ((here-> NUMD2posNode != 0) && (here-> NUMD2posNode != 0)) + here->NUMD2posPosPtr = here->NUMD2posPosStructPtr->CSC ; + + if ((here-> NUMD2negNode != 0) && (here-> NUMD2negNode != 0)) + here->NUMD2negNegPtr = here->NUMD2negNegStructPtr->CSC ; + + if ((here-> NUMD2negNode != 0) && (here-> NUMD2posNode != 0)) + here->NUMD2negPosPtr = here->NUMD2negPosStructPtr->CSC ; + + if ((here-> NUMD2posNode != 0) && (here-> NUMD2negNode != 0)) + here->NUMD2posNegPtr = here->NUMD2posNegStructPtr->CSC ; + + } + } + + return (OK) ; +} diff --git a/src/spicelib/devices/numd2/numd2def.h b/src/spicelib/devices/numd2/numd2def.h index 75477d585..649615746 100644 --- a/src/spicelib/devices/numd2/numd2def.h +++ b/src/spicelib/devices/numd2/numd2def.h @@ -64,6 +64,14 @@ typedef struct sNUMD2instance { unsigned NUMD2icFileGiven:1; /* flag to indicate init. cond. file given */ unsigned NUMD2tempGiven:1; /* flag to indicate temp was specified */ unsigned NUMD2printGiven:1; /* flag to indicate if print was specified */ + +#ifdef KLU + BindElement *NUMD2posPosStructPtr ; + BindElement *NUMD2negNegStructPtr ; + BindElement *NUMD2negPosStructPtr ; + BindElement *NUMD2posNegStructPtr ; +#endif + } NUMD2instance;