From ba80b314e7fefbbff1ca2ab70f0ff2ff0db669ab Mon Sep 17 00:00:00 2001 From: dwarning Date: Wed, 1 Apr 2015 22:38:31 +0200 Subject: [PATCH] mhx: a first attempt to access branch current of rlc devices --- src/spicelib/devices/cap/Makefile.am | 1 + src/spicelib/devices/cap/capdefs.h | 2 ++ src/spicelib/devices/cap/capext.h | 1 + src/spicelib/devices/cap/capfindbr.c | 43 ++++++++++++++++++++++++++++ src/spicelib/devices/cap/capinit.c | 2 +- src/spicelib/devices/cap/capload.c | 5 ++++ src/spicelib/devices/cap/capsetup.c | 2 ++ src/spicelib/devices/ind/Makefile.am | 1 + src/spicelib/devices/ind/indext.h | 1 + src/spicelib/devices/ind/indfindbr.c | 33 +++++++++++++++++++++ src/spicelib/devices/ind/indinit.c | 2 +- src/spicelib/devices/res/Makefile.am | 1 + src/spicelib/devices/res/resdefs.h | 2 ++ src/spicelib/devices/res/resext.h | 1 + src/spicelib/devices/res/resfindbr.c | 43 ++++++++++++++++++++++++++++ src/spicelib/devices/res/resinit.c | 2 +- src/spicelib/devices/res/resload.c | 6 ++++ src/spicelib/devices/res/ressetup.c | 2 ++ 18 files changed, 147 insertions(+), 3 deletions(-) create mode 100644 src/spicelib/devices/cap/capfindbr.c create mode 100644 src/spicelib/devices/ind/indfindbr.c create mode 100644 src/spicelib/devices/res/resfindbr.c diff --git a/src/spicelib/devices/cap/Makefile.am b/src/spicelib/devices/cap/Makefile.am index 4205040ae..2ad748d9d 100644 --- a/src/spicelib/devices/cap/Makefile.am +++ b/src/spicelib/devices/cap/Makefile.am @@ -28,6 +28,7 @@ libcap_la_SOURCES = \ capsset.c \ capsupd.c \ captemp.c \ + capfindbr.c \ captrunc.c diff --git a/src/spicelib/devices/cap/capdefs.h b/src/spicelib/devices/cap/capdefs.h index fbf860f9a..b5affc6fc 100644 --- a/src/spicelib/devices/cap/capdefs.h +++ b/src/spicelib/devices/cap/capdefs.h @@ -26,6 +26,7 @@ typedef struct sCAPinstance { int CAPstate; /* pointer to start of capacitor state vector */ int CAPposNode; /* number of positive node of capacitor */ int CAPnegNode; /* number of negative node of capacitor */ + int CAPbrEq; /* mhx: store node number */ double CAPtemp; /* temperature at which this capacitor operates */ double CAPdtemp; /* delta-temperature of this instance */ @@ -47,6 +48,7 @@ typedef struct sCAPinstance { * (positive,negative) */ double *CAPnegPosptr; /* pointer to sparse matrix offdiagonal at * (negative,positive) */ + double *CAPbrptr; /* mhx: to get I(Cx), pointer to sparse matrix diagonal */ unsigned CAPcapGiven : 1; /* flag to indicate capacitance was specified */ unsigned CAPicGiven : 1; /* flag to indicate init. cond. was specified */ unsigned CAPwidthGiven : 1; /* flag to indicate capacitor width given */ diff --git a/src/spicelib/devices/cap/capext.h b/src/spicelib/devices/cap/capext.h index d128959c4..c4af5cdab 100644 --- a/src/spicelib/devices/cap/capext.h +++ b/src/spicelib/devices/cap/capext.h @@ -23,4 +23,5 @@ extern int CAPsetup(SMPmatrix*,GENmodel*,CKTcircuit*,int*); extern int CAPtemp(GENmodel*,CKTcircuit*); extern int CAPtrunc(GENmodel*,CKTcircuit*,double*); extern int CAPsoaCheck(CKTcircuit *, GENmodel *); +extern int CAPfindBr(CKTcircuit*, GENmodel*, IFuid); diff --git a/src/spicelib/devices/cap/capfindbr.c b/src/spicelib/devices/cap/capfindbr.c new file mode 100644 index 000000000..8e7c20328 --- /dev/null +++ b/src/spicelib/devices/cap/capfindbr.c @@ -0,0 +1,43 @@ +/*********************************** +* Author: Marcel Hendrix, Feb 2015 * +***********************************/ + +#include "ngspice/ngspice.h" +#include "ngspice/cktdefs.h" +#include "capdefs.h" +#include "ngspice/sperror.h" +#include "ngspice/suffix.h" + +/* macro to make elements with built-in test for out of memory */ +#define TSTALLOC(matrix, ptr, row, col) \ + do { \ + if ((ptr = SMPmakeElt(matrix, row, col)) == NULL) \ + return E_NOMEM; \ + } while(0) + + +int +CAPfindBr (CKTcircuit *ckt, GENmodel *inModel, IFuid name) +{ + CAPmodel *model = (CAPmodel *) inModel; + CAPinstance *here; + int error; + CKTnode *tmp; + + for (; model != NULL; model = model->CAPnextModel) + for (here = model->CAPinstances; here != NULL; here = here->CAPnextInstance) { + if (here->CAPname == name) { + if (here->CAPbrptr == NULL) { + error = CKTmkCur(ckt, &tmp, here->CAPname, "branch"); + if (error) + return error; + here->CAPbrEq = tmp->number; + if (ckt->CKTmatrix != NULL) + TSTALLOC(ckt->CKTmatrix, here->CAPbrptr, here->CAPbrEq, here->CAPbrEq); + } + return here->CAPbrEq; + } + } + + return 0; +} diff --git a/src/spicelib/devices/cap/capinit.c b/src/spicelib/devices/cap/capinit.c index 1c8bb5126..3a122bc3e 100644 --- a/src/spicelib/devices/cap/capinit.c +++ b/src/spicelib/devices/cap/capinit.c @@ -47,7 +47,7 @@ SPICEdev CAPinfo = { /* DEVpzSetup */ CAPsetup, /* DEVtemperature*/ CAPtemp, /* DEVtrunc */ CAPtrunc, - /* DEVfindBranch */ NULL, + /* DEVfindBranch */ CAPfindBr, /* DEVacLoad */ CAPacLoad, /* DEVaccept */ NULL, /* DEVdestroy */ CAPdestroy, diff --git a/src/spicelib/devices/cap/capload.c b/src/spicelib/devices/cap/capload.c index d6796d5b2..b341ac422 100644 --- a/src/spicelib/devices/cap/capload.c +++ b/src/spicelib/devices/cap/capload.c @@ -77,6 +77,11 @@ CAPload(GENmodel *inModel, CKTcircuit *ckt) *(here->CAPnegPosptr) -= m * geq; *(ckt->CKTrhs+here->CAPposNode) -= m * ceq; *(ckt->CKTrhs+here->CAPnegNode) += m * ceq; + /* mhx: to access I(Cx) */ + if (here->CAPbrptr != NULL) { + *(ckt->CKTrhs + here->CAPbrEq) = *(ckt->CKTstate0 + here->CAPccap); + *(here->CAPbrptr) += 1.0; + } } else *(ckt->CKTstate0+here->CAPqcap) = here->CAPcapac * vcap; } diff --git a/src/spicelib/devices/cap/capsetup.c b/src/spicelib/devices/cap/capsetup.c index 6d2bbdc55..4cff404ce 100644 --- a/src/spicelib/devices/cap/capsetup.c +++ b/src/spicelib/devices/cap/capsetup.c @@ -115,6 +115,8 @@ do { if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\ TSTALLOC(CAPnegNegptr,CAPnegNode,CAPnegNode); TSTALLOC(CAPposNegptr,CAPposNode,CAPnegNode); TSTALLOC(CAPnegPosptr,CAPnegNode,CAPposNode); + if (here->CAPbrEq & (here->CAPbrptr == NULL)) + TSTALLOC(CAPbrptr, CAPbrEq, CAPbrEq); /* mhx: to access I(Cx) */ } } return(OK); diff --git a/src/spicelib/devices/ind/Makefile.am b/src/spicelib/devices/ind/Makefile.am index 5a05ee97b..102fa0e31 100644 --- a/src/spicelib/devices/ind/Makefile.am +++ b/src/spicelib/devices/ind/Makefile.am @@ -22,6 +22,7 @@ libind_la_SOURCES = \ indsacl.c \ indsetup.c \ indsload.c \ + indfindbr.c \ indsprt.c \ indsset.c \ indsupd.c \ diff --git a/src/spicelib/devices/ind/indext.h b/src/spicelib/devices/ind/indext.h index 8d2fa035c..c924136d0 100644 --- a/src/spicelib/devices/ind/indext.h +++ b/src/spicelib/devices/ind/indext.h @@ -24,6 +24,7 @@ extern int INDsetup(SMPmatrix*,GENmodel*,CKTcircuit*,int*); extern int INDunsetup(GENmodel*,CKTcircuit*); extern int INDtemp(GENmodel*, CKTcircuit*); extern int INDtrunc(GENmodel*,CKTcircuit*,double*); +extern int INDfindBr(CKTcircuit*, GENmodel*, IFuid); // mhx: find inductor branch extern int MUTacLoad(GENmodel*,CKTcircuit*); extern int MUTask(CKTcircuit*,GENinstance*,int,IFvalue*,IFvalue*); diff --git a/src/spicelib/devices/ind/indfindbr.c b/src/spicelib/devices/ind/indfindbr.c new file mode 100644 index 000000000..f7af59549 --- /dev/null +++ b/src/spicelib/devices/ind/indfindbr.c @@ -0,0 +1,33 @@ +/*********************************** +* Author: Marcel Hendrix, Feb 2015 * +***********************************/ + +#include "ngspice/ngspice.h" +#include "ngspice/cktdefs.h" +#include "inddefs.h" +#include "ngspice/sperror.h" +#include "ngspice/suffix.h" + +int +INDfindBr (CKTcircuit *ckt, GENmodel *inModel, IFuid name) +{ + INDmodel *model = (INDmodel *) inModel; + INDinstance *here; + int error; + CKTnode *tmp; + + for (; model != NULL; model = model->INDnextModel) + for (here = model->INDinstances; here != NULL; here = here->INDnextInstance) { + if (here->INDname == name) { + if (here->INDbrEq == 0) { + error = CKTmkCur(ckt, &tmp, here->INDname, "branch"); + if (error) + return error; + here->INDbrEq = tmp->number; + } + return here->INDbrEq; + } + } + + return 0; +} diff --git a/src/spicelib/devices/ind/indinit.c b/src/spicelib/devices/ind/indinit.c index 8148abde8..2900dd244 100644 --- a/src/spicelib/devices/ind/indinit.c +++ b/src/spicelib/devices/ind/indinit.c @@ -47,7 +47,7 @@ SPICEdev INDinfo = { /* DEVpzSetup */ INDsetup, /* DEVtemperature*/ INDtemp, /* DEVtrunc */ INDtrunc, - /* DEVfindBranch */ NULL, + /* DEVfindBranch */ INDfindBr, // mhx /* DEVacLoad */ INDacLoad, /* DEVaccept */ NULL, /* DEVdestroy */ INDdestroy, diff --git a/src/spicelib/devices/res/Makefile.am b/src/spicelib/devices/res/Makefile.am index ab746263d..9b5e75959 100644 --- a/src/spicelib/devices/res/Makefile.am +++ b/src/spicelib/devices/res/Makefile.am @@ -25,6 +25,7 @@ libres_la_SOURCES = \ ressload.c \ ressprt.c \ ressset.c \ + resfindbr.c \ restemp.c diff --git a/src/spicelib/devices/res/resdefs.h b/src/spicelib/devices/res/resdefs.h index a8f0578a2..6789590b9 100644 --- a/src/spicelib/devices/res/resdefs.h +++ b/src/spicelib/devices/res/resdefs.h @@ -27,6 +27,7 @@ typedef struct sRESinstance { int RESstate; /* not used but needed for sructure consistency */ int RESposNode; /* number of positive node of resistor */ int RESnegNode; /* number of negative node of resistor */ + int RESbrEq; /* mhx: number of the node that stores I(Rx) */ double REStemp; /* temperature at which this resistor operates */ double RESdtemp; /* delta-temperature of a particular instance */ @@ -53,6 +54,7 @@ typedef struct sRESinstance { * (positive,negative) */ double *RESnegPosptr; /* pointer to sparse matrix offdiagonal at * (negative,positive) */ + double *RESbrptr; /* mhx: to get I(Rx), pointer to sparse matrix diagonal */ unsigned RESresGiven : 1; /* flag to indicate resistance was specified */ unsigned RESwidthGiven : 1; /* flag to indicate width given */ unsigned RESlengthGiven : 1; /* flag to indicate length given */ diff --git a/src/spicelib/devices/res/resext.h b/src/spicelib/devices/res/resext.h index 148d1d222..5a4e636ca 100644 --- a/src/spicelib/devices/res/resext.h +++ b/src/spicelib/devices/res/resext.h @@ -21,3 +21,4 @@ extern int RESsetup(SMPmatrix*,GENmodel*,CKTcircuit*,int*); extern int REStemp(GENmodel*,CKTcircuit*); extern int RESnoise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*); extern int RESsoaCheck(CKTcircuit *, GENmodel *); +extern int RESfindBr(CKTcircuit*, GENmodel*, IFuid); // mhx diff --git a/src/spicelib/devices/res/resfindbr.c b/src/spicelib/devices/res/resfindbr.c new file mode 100644 index 000000000..ced72ff75 --- /dev/null +++ b/src/spicelib/devices/res/resfindbr.c @@ -0,0 +1,43 @@ +/*********************************** +* Author: Marcel Hendrix, Feb 2015 * +***********************************/ + +#include "ngspice/ngspice.h" +#include "ngspice/cktdefs.h" +#include "resdefs.h" +#include "ngspice/sperror.h" +#include "ngspice/suffix.h" + +/* macro to make elements with built-in test for out of memory */ +#define TSTALLOC(matrix, ptr, row, col) \ + do { \ + if((ptr = SMPmakeElt(matrix, row, col)) == NULL) \ + return E_NOMEM; \ + } while(0) + + +int +RESfindBr (CKTcircuit *ckt, GENmodel *inModel, IFuid name) +{ + RESmodel *model = (RESmodel *) inModel; + RESinstance *here; + int error; + CKTnode *tmp; + + for (; model != NULL; model = model->RESnextModel) + for (here = model->RESinstances; here != NULL; here = here->RESnextInstance) { + if (here->RESname == name) { + if (here->RESbrptr == NULL) { + error = CKTmkCur(ckt, &tmp, here->RESname, "branch"); + if (error) + return error; + here->RESbrEq = tmp->number; + if (ckt->CKTmatrix != NULL) + TSTALLOC(ckt->CKTmatrix, here->RESbrptr, here->RESbrEq, here->RESbrEq); + } + return here->RESbrEq; + } + } + + return 0; +} diff --git a/src/spicelib/devices/res/resinit.c b/src/spicelib/devices/res/resinit.c index d4096de8d..bf87369e4 100644 --- a/src/spicelib/devices/res/resinit.c +++ b/src/spicelib/devices/res/resinit.c @@ -48,7 +48,7 @@ SPICEdev RESinfo = { /* DEVpzSetup */ RESsetup, /* DEVtemperature*/ REStemp, /* DEVtrunc */ NULL, - /* DEVfindBranch */ NULL, + /* DEVfindBranch */ RESfindBr, /* DEVacLoad */ RESacload, /* ac load and normal load are identical */ /* DEVaccept */ NULL, /* DEVdestroy */ RESdestroy, diff --git a/src/spicelib/devices/res/resload.c b/src/spicelib/devices/res/resload.c index ff6e5d66f..a3737c461 100644 --- a/src/spicelib/devices/res/resload.c +++ b/src/spicelib/devices/res/resload.c @@ -31,6 +31,12 @@ RESload(GENmodel *inModel, CKTcircuit *ckt) m = (here->RESm); + /* mhx: access current like I(Rx) */ + if (here->RESbrptr != NULL) { + *(ckt->CKTrhs + here->RESbrEq) = m * here->REScurrent; + *(here->RESbrptr) += 1.0; + } + *(here->RESposPosptr) += m * here->RESconduct; *(here->RESnegNegptr) += m * here->RESconduct; *(here->RESposNegptr) -= m * here->RESconduct; diff --git a/src/spicelib/devices/res/ressetup.c b/src/spicelib/devices/res/ressetup.c index 44c75ea5f..88149d13b 100644 --- a/src/spicelib/devices/res/ressetup.c +++ b/src/spicelib/devices/res/ressetup.c @@ -86,6 +86,8 @@ do { if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\ TSTALLOC(RESnegNegptr, RESnegNode, RESnegNode); TSTALLOC(RESposNegptr, RESposNode, RESnegNode); TSTALLOC(RESnegPosptr, RESnegNode, RESposNode); + if (here->RESbrEq & (here->RESbrptr == NULL)) + TSTALLOC(RESbrptr, RESbrEq, RESbrEq); } } return(OK);