From 73ec1b72c131a8e6b39bf2717d3c272ff7ad5163 Mon Sep 17 00:00:00 2001 From: Pascal Kuthe Date: Sat, 13 May 2023 15:30:17 +0200 Subject: [PATCH 1/3] integrate OSDI with KLU --- compile_linux_klu.sh | 4 +- src/include/ngspice/osdiitf.h | 4 ++ src/osdi/osdidefs.h | 12 +++- src/osdi/osdiext.h | 8 ++- src/osdi/osdiinit.c | 7 +- src/osdi/osdiregistry.c | 39 +++++++++-- src/osdi/osdisetup.c | 121 ++++++++++++++++++++++++++++++++++ 7 files changed, 182 insertions(+), 13 deletions(-) diff --git a/compile_linux_klu.sh b/compile_linux_klu.sh index 1c726dede..cc848778b 100755 --- a/compile_linux_klu.sh +++ b/compile_linux_klu.sh @@ -43,13 +43,13 @@ if test "$1" = "d"; then if [ $? -ne 0 ]; then echo "cd debug failed"; exit 1 ; fi echo "configuring for 64 bit debug" echo - ../configure --with-x --enable-cider --with-readline=yes --enable-openmp --enable-xspice --enable-klu CFLAGS="-g -m64 -O0 -Wall -Wno-unused-but-set-variable" LDFLAGS="-m64 -g" + ../configure --with-x --enable-cider --with-readline=yes --enable-openmp --enable-xspice --enable-klu --enable-predictor --enable-osdi CFLAGS="-g -m64 -O0 -Wall -Wno-unused-but-set-variable" LDFLAGS="-m64 -g" else cd release if [ $? -ne 0 ]; then echo "cd release failed"; exit 1 ; fi echo "configuring for 64 bit release" echo - ../configure --with-x --enable-cider --with-readline=yes --enable-openmp --enable-xspice --enable-klu --disable-debug CFLAGS="-m64 -O2" LDFLAGS="-m64 -s" + ../configure --with-x --enable-cider --with-readline=yes --enable-openmp --enable-xspice --enable-klu --enable-predictor --enable-osdi --disable-debug CFLAGS="-m64 -O2" LDFLAGS="-m64 -s" fi if [ $? -ne 0 ]; then echo "../configure failed"; exit 1 ; fi diff --git a/src/include/ngspice/osdiitf.h b/src/include/ngspice/osdiitf.h index 5c84ed0ad..91e940a18 100644 --- a/src/include/ngspice/osdiitf.h +++ b/src/include/ngspice/osdiitf.h @@ -11,6 +11,7 @@ #pragma once +#include "ngspice/config.h" #include "ngspice/devdefs.h" #include @@ -19,6 +20,9 @@ typedef struct OsdiRegistryEntry { uint32_t inst_offset; uint32_t dt; uint32_t temp; +#ifdef KLU + uint32_t matrix_ptr_offset; +#endif } OsdiRegistryEntry; typedef struct OsdiObjectFile { diff --git a/src/osdi/osdidefs.h b/src/osdi/osdidefs.h index 6130482ad..775e87744 100644 --- a/src/osdi/osdidefs.h +++ b/src/osdi/osdidefs.h @@ -72,9 +72,15 @@ typedef struct OsdiModelData { } OsdiModelData; extern size_t osdi_instance_data_off(const OsdiRegistryEntry *entry); -extern void *osdi_instance_data(const OsdiRegistryEntry *entry, GENinstance *inst); -extern OsdiExtraInstData *osdi_extra_instance_data(const OsdiRegistryEntry *entry, - GENinstance *inst); +extern void *osdi_instance_data(const OsdiRegistryEntry *entry, + GENinstance *inst); +#ifdef KLU +extern size_t osdi_instance_matrix_ptr_off(const OsdiRegistryEntry *entry); +extern double **osdi_instance_matrix_ptr(const OsdiRegistryEntry *entry, + GENinstance *inst); +#endif +extern OsdiExtraInstData * +osdi_extra_instance_data(const OsdiRegistryEntry *entry, GENinstance *inst); extern size_t osdi_model_data_off(void); extern void *osdi_model_data(GENmodel *model); extern void *osdi_model_data_from_inst(GENinstance *inst); diff --git a/src/osdi/osdiext.h b/src/osdi/osdiext.h index d61c8c488..89a8fae87 100644 --- a/src/osdi/osdiext.h +++ b/src/osdi/osdiext.h @@ -26,7 +26,13 @@ extern int OSDIload(GENmodel *, CKTcircuit *); extern int OSDItemp(GENmodel *, CKTcircuit *); extern int OSDIacLoad(GENmodel *, CKTcircuit *); extern int OSDItrunc(GENmodel *, CKTcircuit *, double *); -extern int OSDIpzLoad(GENmodel*, CKTcircuit*, SPcomplex*); +extern int OSDIpzLoad(GENmodel *, CKTcircuit *, SPcomplex *); + +#ifdef KLU +extern int OSDIbindCSC(GENmodel *inModel, CKTcircuit *ckt); +extern int OSDIbindCSCComplexToReal(GENmodel *inModel, CKTcircuit *ckt); +extern int OSDIbindCSCComplex(GENmodel *inModel, CKTcircuit *ckt); +#endif /* extern int OSDIconvTest(GENmodel*,CKTcircuit*); */ /* extern int OSDImDelete(GENmodel*); */ diff --git a/src/osdi/osdiinit.c b/src/osdi/osdiinit.c index 7d83b5dfe..d7edacfc8 100644 --- a/src/osdi/osdiinit.c +++ b/src/osdi/osdiinit.c @@ -180,8 +180,11 @@ extern SPICEdev *osdi_create_spicedev(const OsdiRegistryEntry *entry) { OSDIinfo->DEVacLoad = OSDIacLoad; OSDIinfo->DEVpzLoad = OSDIpzLoad; OSDIinfo->DEVtrunc = OSDItrunc; - - + #ifdef KLU + OSDIinfo->DEVbindCSC = OSDIbindCSC; + OSDIinfo->DEVbindCSCComplex = OSDIbindCSCComplex; + OSDIinfo->DEVbindCSCComplexToReal = OSDIbindCSCComplexToReal; + #endif return OSDIinfo; } diff --git a/src/osdi/osdiregistry.c b/src/osdi/osdiregistry.c index e3362fa38..64415b953 100644 --- a/src/osdi/osdiregistry.c +++ b/src/osdi/osdiregistry.c @@ -9,11 +9,13 @@ * Author: Pascal Kuthe */ +#include "ngspice/config.h" #include "ngspice/hash.h" #include "ngspice/memory.h" #include "ngspice/stringutil.h" #include "osdidefs.h" +#include #include #include "osdi.h" @@ -199,6 +201,13 @@ static char *resolve_input_path(const char *name) { return NULL; } /* end of function inp_pathresolve_at */ +static size_t pad_to_align(size_t alignment, size_t size) { + size_t padding = alignment - size % alignment; + if (padding == alignment) { + return 0; + } + return padding + size; +} /** * Calculates the offset that the OSDI instance data has from the beginning of * the instance data allocated by ngspice. This offset is non trivial because @@ -209,13 +218,21 @@ static char *resolve_input_path(const char *name) { static size_t calc_osdi_instance_data_off(const OsdiDescriptor *descr) { size_t res = sizeof(GENinstance) /* generic data */ + descr->num_terminals * sizeof(int); - size_t padding = sizeof(max_align_t) - res % sizeof(max_align_t); - if (padding == sizeof(max_align_t)) { - padding = 0; - } - return res + padding; +#ifdef KLU + res = pad_to_align(alignof(double *), res); + res += ((size_t)descr->num_jacobian_entries) * 2 * sizeof(double *); +#endif + return pad_to_align(alignof(max_align_t), res); } +#ifdef KLU +static size_t calc_osdi_instance_matrix_off(const OsdiDescriptor *descr) { + size_t res = sizeof(GENinstance) /* generic data */ + + descr->num_terminals * sizeof(int); + return pad_to_align(alignof(double *), res); +} +#endif + #define INVALID_OBJECT \ (OsdiObjectFile) { .num_entries = -1 } @@ -382,6 +399,9 @@ extern OsdiObjectFile load_object_file(const char *input) { .inst_offset = (uint32_t)inst_off, .dt = dt, .temp = temp, +#ifdef KLU + .matrix_ptr_offset = (uint32_t)calc_osdi_instance_matrix_off(descr), +#endif }; } @@ -395,6 +415,15 @@ extern OsdiObjectFile load_object_file(const char *input) { inline size_t osdi_instance_data_off(const OsdiRegistryEntry *entry) { return entry->inst_offset; } +#ifdef KLU +inline size_t osdi_instance_matrix_ptr_off(const OsdiRegistryEntry *entry) { + return entry->matrix_ptr_offset; +} +inline double **osdi_instance_matrix_ptr(const OsdiRegistryEntry *entry, + GENinstance *inst) { + return (double **)(((char *)inst) + osdi_instance_matrix_ptr_off(entry)); +} +#endif inline void *osdi_instance_data(const OsdiRegistryEntry *entry, GENinstance *inst) { diff --git a/src/osdi/osdisetup.c b/src/osdi/osdisetup.c index c3504cc38..08bae9942 100644 --- a/src/osdi/osdisetup.c +++ b/src/osdi/osdisetup.c @@ -10,6 +10,7 @@ */ #include "ngspice/iferrmsg.h" +#include "ngspice/klu.h" #include "ngspice/memory.h" #include "ngspice/ngspice.h" #include "ngspice/typedefs.h" @@ -408,3 +409,123 @@ extern int OSDIunsetup(GENmodel *inModel, CKTcircuit *ckt) { } return (OK); } +#ifdef KLU +#include "ngspice/klu-binding.h" +static int init_matrix_klu(SMPmatrix *matrix, const OsdiDescriptor *descr, + void *inst, double **inst_matrix_ptrs) { + BindElement tmp; + BindElement *matched; + BindElement *bindings = matrix->SMPkluMatrix->KLUmatrixBindStructCOO; + size_t nz = (size_t)matrix->SMPkluMatrix->KLUmatrixLinkedListNZ; + uint32_t *node_mapping = + (uint32_t *)(((char *)inst) + descr->node_mapping_offset); + double **jacobian_ptr_resist = + (double **)(((char *)inst) + descr->jacobian_ptr_resist_offset); + + for (uint32_t i = 0; i < descr->num_jacobian_entries; i++) { + uint32_t equation = descr->jacobian_entries[i].nodes.node_1; + uint32_t unkown = descr->jacobian_entries[i].nodes.node_2; + equation = node_mapping[equation]; + unkown = node_mapping[unkown]; + if (equation != 0 && unkown != 0) { + tmp.COO = jacobian_ptr_resist[i]; + tmp.CSC = NULL; + tmp.CSC_Complex = NULL; + matched = (BindElement *)bsearch(&tmp, bindings, nz, sizeof(BindElement), + BindCompare); + if (matched == NULL) { + printf("Ptr %p not found in BindStruct Table\n", + jacobian_ptr_resist[i]); + return (E_PANIC); + } + uint32_t react_off = descr->jacobian_entries[i].react_ptr_off; + // complex number for ac analysis + if (react_off != UINT32_MAX) { + double **jacobian_ptr_react = (double **)(((char *)inst) + react_off); + *jacobian_ptr_react = matched->CSC_Complex + 1; + } + jacobian_ptr_resist[i] = matched->CSC; + inst_matrix_ptrs[2 * i] = matched->CSC; + inst_matrix_ptrs[2 * i + 1] = matched->CSC_Complex; + } + } + return (OK); +} + +static int update_matrix_klu(const OsdiDescriptor *descr, void *inst, + double **inst_matrix_ptrs, bool complex) { + uint32_t *node_mapping = + (uint32_t *)(((char *)inst) + descr->node_mapping_offset); + double **jacobian_ptr_resist = + (double **)(((char *)inst) + descr->jacobian_ptr_resist_offset); + + for (uint32_t i = 0; i < descr->num_jacobian_entries; i++) { + uint32_t equation = descr->jacobian_entries[i].nodes.node_1; + uint32_t unkown = descr->jacobian_entries[i].nodes.node_2; + equation = node_mapping[equation]; + unkown = node_mapping[unkown]; + if (equation != 0 && unkown != 0) { + jacobian_ptr_resist[i] = inst_matrix_ptrs[2 * i + complex]; + } + } + return (OK); +} + +int OSDIbindCSC(GENmodel *inModel, CKTcircuit *ckt) { + + OsdiRegistryEntry *entry = osdi_reg_entry_model(inModel); + const OsdiDescriptor *descr = entry->descriptor; + GENmodel *gen_model; + GENinstance *gen_inst; + + /* setup a temporary buffer */ + uint32_t *node_ids = TMALLOC(uint32_t, descr->num_nodes); + + for (gen_model = inModel; gen_model; gen_model = gen_model->GENnextModel) { + void *model = osdi_model_data(gen_model); + for (gen_inst = gen_model->GENinstances; gen_inst; + gen_inst = gen_inst->GENnextInstance) { + void *inst = osdi_instance_data(entry, gen_inst); + double **matrix_ptrs = osdi_instance_matrix_ptr(entry, gen_inst); + int err = init_matrix_klu(ckt->CKTmatrix, descr, inst, matrix_ptrs); + if (err != (OK)) { + return err; + } + } + } + + return (OK); +} +int OSDIupdateCSC(GENmodel *inModel, CKTcircuit *ckt, bool complex) { + + OsdiRegistryEntry *entry = osdi_reg_entry_model(inModel); + const OsdiDescriptor *descr = entry->descriptor; + GENmodel *gen_model; + GENinstance *gen_inst; + + /* setup a temporary buffer */ + uint32_t *node_ids = TMALLOC(uint32_t, descr->num_nodes); + + for (gen_model = inModel; gen_model; gen_model = gen_model->GENnextModel) { + void *model = osdi_model_data(gen_model); + for (gen_inst = gen_model->GENinstances; gen_inst; + gen_inst = gen_inst->GENnextInstance) { + void *inst = osdi_instance_data(entry, gen_inst); + double **matrix_ptrs = osdi_instance_matrix_ptr(entry, gen_inst); + int err = update_matrix_klu(descr, inst, matrix_ptrs, complex); + if (err != (OK)) { + return err; + } + } + } + + return (OK); +} +int OSDIbindCSCComplexToReal(GENmodel *inModel, CKTcircuit *ckt) { + OSDIupdateCSC(inModel, ckt, false); +} + +int OSDIbindCSCComplex(GENmodel *inModel, CKTcircuit *ckt) { + OSDIupdateCSC(inModel, ckt, true); +} +#endif From c8c423bdf9a39172fe3af8d5ed7354e248d267eb Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sat, 13 May 2023 23:41:08 +0200 Subject: [PATCH 2/3] Enable compilation with MSVC (alignof seems to be available only for C++) --- src/osdi/osdidefs.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/osdi/osdidefs.h b/src/osdi/osdidefs.h index 775e87744..bf3cfb21d 100644 --- a/src/osdi/osdidefs.h +++ b/src/osdi/osdidefs.h @@ -46,6 +46,7 @@ typedef struct { #ifdef _MSC_VER #define MAX_ALIGN 8 +#define alignof sizeof #else #define MAX_ALIGN alignof(max_align_t) #endif From 6a431250fc4f07f62c670174a1e0d751b6b96c1b Mon Sep 17 00:00:00 2001 From: Francesco Lannutti Date: Fri, 19 May 2023 23:28:31 +0200 Subject: [PATCH 3/3] Added the case of VSRCport to VSRC model for KLU --- src/maths/ni/niaciter.c | 16 ++++++ src/spicelib/devices/vsrc/vsrcbindCSC.c | 71 +++++++++++++++++++++++++ src/spicelib/devices/vsrc/vsrcdefs.h | 7 +++ src/spicelib/devices/vsrc/vsrcload.c | 2 +- 4 files changed, 95 insertions(+), 1 deletion(-) diff --git a/src/maths/ni/niaciter.c b/src/maths/ni/niaciter.c index eccac93a0..0b14ddd08 100644 --- a/src/maths/ni/niaciter.c +++ b/src/maths/ni/niaciter.c @@ -47,6 +47,14 @@ retry: /* either singular equations or no memory, in either case, * let caller handle problem */ + + int i, j ; + SMPgetError(ckt->CKTmatrix, &i, &j); + if(eq(NODENAME(ckt, i), NODENAME(ckt, j))) + SPfrontEnd->IFerrorf(ERR_WARNING, "singular matrix: check node %s\n", NODENAME(ckt, i)); + else + SPfrontEnd->IFerrorf(ERR_WARNING, "singular matrix: check nodes %s and %s\n", NODENAME(ckt, i), NODENAME(ckt, j)); + return(error); } } @@ -61,6 +69,14 @@ retry: * current LU factorization. Maybe if we reload and * try to reorder again it will help... */ + + int i, j ; + SMPgetError(ckt->CKTmatrix, &i, &j); + if(eq(NODENAME(ckt, i), NODENAME(ckt, j))) + SPfrontEnd->IFerrorf(ERR_WARNING, "singular matrix: check node %s\n", NODENAME(ckt, i)); + else + SPfrontEnd->IFerrorf(ERR_WARNING, "singular matrix: check nodes %s and %s\n", NODENAME(ckt, i), NODENAME(ckt, j)); + ckt->CKTniState |= NIACSHOULDREORDER; goto retry; } diff --git a/src/spicelib/devices/vsrc/vsrcbindCSC.c b/src/spicelib/devices/vsrc/vsrcbindCSC.c index 38c122f8a..142f0b6a8 100644 --- a/src/spicelib/devices/vsrc/vsrcbindCSC.c +++ b/src/spicelib/devices/vsrc/vsrcbindCSC.c @@ -25,10 +25,33 @@ VSRCbindCSC (GENmodel *inModel, CKTcircuit *ckt) /* loop through all the instances of the model */ for (here = VSRCinstances(model); here != NULL ; here = VSRCnextInstance(here)) { + +#ifdef RFSPICE + if (here->VSRCisPort) + { + CREATE_KLU_BINDING_TABLE(VSRCposPosPtr, VSRCposPosBinding, VSRCposNode, VSRCposNode); + CREATE_KLU_BINDING_TABLE(VSRCnegNegPtr, VSRCresResBinding, VSRCresNode, VSRCresNode); + CREATE_KLU_BINDING_TABLE(VSRCposNegPtr, VSRCposResBinding, VSRCposNode, VSRCresNode); + CREATE_KLU_BINDING_TABLE(VSRCnegPosPtr, VSRCresPosBinding, VSRCresNode, VSRCposNode); + + CREATE_KLU_BINDING_TABLE(VSRCposIbrPtr, VSRCposIbrBinding, VSRCresNode, VSRCbranch); + CREATE_KLU_BINDING_TABLE(VSRCnegIbrPtr, VSRCnegIbrBinding, VSRCnegNode, VSRCbranch); + CREATE_KLU_BINDING_TABLE(VSRCibrNegPtr, VSRCibrNegBinding, VSRCbranch, VSRCnegNode); + CREATE_KLU_BINDING_TABLE(VSRCibrPosPtr, VSRCibrPosBinding, VSRCbranch, VSRCresNode); + } + else + { + CREATE_KLU_BINDING_TABLE(VSRCposIbrPtr, VSRCposIbrBinding, VSRCposNode, VSRCbranch); + CREATE_KLU_BINDING_TABLE(VSRCnegIbrPtr, VSRCnegIbrBinding, VSRCnegNode, VSRCbranch); + CREATE_KLU_BINDING_TABLE(VSRCibrNegPtr, VSRCibrNegBinding, VSRCbranch, VSRCnegNode); + CREATE_KLU_BINDING_TABLE(VSRCibrPosPtr, VSRCibrPosBinding, VSRCbranch, VSRCposNode); + } +#else CREATE_KLU_BINDING_TABLE(VSRCposIbrPtr, VSRCposIbrBinding, VSRCposNode, VSRCbranch); CREATE_KLU_BINDING_TABLE(VSRCnegIbrPtr, VSRCnegIbrBinding, VSRCnegNode, VSRCbranch); CREATE_KLU_BINDING_TABLE(VSRCibrNegPtr, VSRCibrNegBinding, VSRCbranch, VSRCnegNode); CREATE_KLU_BINDING_TABLE(VSRCibrPosPtr, VSRCibrPosBinding, VSRCbranch, VSRCposNode); +#endif /* Pole-Zero Analysis */ if (here->VSRCibrIbrPtr) @@ -63,10 +86,34 @@ VSRCbindCSCComplex (GENmodel *inModel, CKTcircuit *ckt) /* loop through all the instances of the model */ for (here = VSRCinstances(model); here != NULL ; here = VSRCnextInstance(here)) { + +#ifdef RFSPICE + if (here->VSRCisPort) + { + CONVERT_KLU_BINDING_TABLE_TO_COMPLEX(VSRCposPosPtr, VSRCposPosBinding, VSRCposNode, VSRCposNode); + CONVERT_KLU_BINDING_TABLE_TO_COMPLEX(VSRCnegNegPtr, VSRCresResBinding, VSRCresNode, VSRCresNode); + CONVERT_KLU_BINDING_TABLE_TO_COMPLEX(VSRCposNegPtr, VSRCposResBinding, VSRCposNode, VSRCresNode); + CONVERT_KLU_BINDING_TABLE_TO_COMPLEX(VSRCnegPosPtr, VSRCresPosBinding, VSRCresNode, VSRCposNode); + + CONVERT_KLU_BINDING_TABLE_TO_COMPLEX(VSRCposIbrPtr, VSRCposIbrBinding, VSRCresNode, VSRCbranch); + 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, VSRCresNode); + } + else + { + CONVERT_KLU_BINDING_TABLE_TO_COMPLEX(VSRCposIbrPtr, VSRCposIbrBinding, VSRCposNode, VSRCbranch); + 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); + } +#else CONVERT_KLU_BINDING_TABLE_TO_COMPLEX(VSRCposIbrPtr, VSRCposIbrBinding, VSRCposNode, VSRCbranch); 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); +#endif + /* Pole-Zero Analysis */ if ((here-> VSRCbranch != 0) && (here-> VSRCbranch != 0)) { @@ -95,10 +142,34 @@ VSRCbindCSCComplexToReal (GENmodel *inModel, CKTcircuit *ckt) /* loop through all the instances of the model */ for (here = VSRCinstances(model); here != NULL ; here = VSRCnextInstance(here)) { + +#ifdef RFSPICE + if (here->VSRCisPort) + { + CONVERT_KLU_BINDING_TABLE_TO_REAL(VSRCposPosPtr, VSRCposPosBinding, VSRCposNode, VSRCposNode); + CONVERT_KLU_BINDING_TABLE_TO_REAL(VSRCnegNegPtr, VSRCresResBinding, VSRCresNode, VSRCresNode); + CONVERT_KLU_BINDING_TABLE_TO_REAL(VSRCposNegPtr, VSRCposResBinding, VSRCposNode, VSRCresNode); + CONVERT_KLU_BINDING_TABLE_TO_REAL(VSRCnegPosPtr, VSRCresPosBinding, VSRCresNode, VSRCposNode); + + CONVERT_KLU_BINDING_TABLE_TO_REAL(VSRCposIbrPtr, VSRCposIbrBinding, VSRCresNode, VSRCbranch); + 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, VSRCresNode); + } + else + { + CONVERT_KLU_BINDING_TABLE_TO_REAL(VSRCposIbrPtr, VSRCposIbrBinding, VSRCposNode, VSRCbranch); + 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); + } +#else CONVERT_KLU_BINDING_TABLE_TO_REAL(VSRCposIbrPtr, VSRCposIbrBinding, VSRCposNode, VSRCbranch); 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); +#endif + /* Pole-Zero Analysis */ if ((here-> VSRCbranch != 0) && (here-> VSRCbranch != 0)) { diff --git a/src/spicelib/devices/vsrc/vsrcdefs.h b/src/spicelib/devices/vsrc/vsrcdefs.h index 2ab796fe5..9f5786c1d 100644 --- a/src/spicelib/devices/vsrc/vsrcdefs.h +++ b/src/spicelib/devices/vsrc/vsrcdefs.h @@ -117,6 +117,13 @@ typedef struct sVSRCinstance { BindElement *VSRCibrNegBinding ; BindElement *VSRCibrPosBinding ; BindElement *VSRCibrIbrBinding ; + +#ifdef RFSPICE + BindElement *VSRCposPosBinding ; + BindElement *VSRCresResBinding ; + BindElement *VSRCposResBinding ; + BindElement *VSRCresPosBinding ; +#endif #endif } VSRCinstance ; diff --git a/src/spicelib/devices/vsrc/vsrcload.c b/src/spicelib/devices/vsrc/vsrcload.c index 099daac4f..3119a89ac 100644 --- a/src/spicelib/devices/vsrc/vsrcload.c +++ b/src/spicelib/devices/vsrc/vsrcload.c @@ -42,7 +42,7 @@ VSRCload(GENmodel *inModel, CKTcircuit *ckt) here=VSRCnextInstance(here)) { #ifndef RFSPICE - * (here->VSRCposIbrPtr) += 1.0; + *(here->VSRCposIbrPtr) += 1.0; *(here->VSRCnegIbrPtr) -= 1.0; *(here->VSRCibrPosPtr) += 1.0; *(here->VSRCibrNegPtr) -= 1.0;