mhx: a first attempt to access branch current of rlc devices
This commit is contained in:
parent
153c0cf729
commit
ba80b314e7
|
|
@ -28,6 +28,7 @@ libcap_la_SOURCES = \
|
||||||
capsset.c \
|
capsset.c \
|
||||||
capsupd.c \
|
capsupd.c \
|
||||||
captemp.c \
|
captemp.c \
|
||||||
|
capfindbr.c \
|
||||||
captrunc.c
|
captrunc.c
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ typedef struct sCAPinstance {
|
||||||
int CAPstate; /* pointer to start of capacitor state vector */
|
int CAPstate; /* pointer to start of capacitor state vector */
|
||||||
int CAPposNode; /* number of positive node of capacitor */
|
int CAPposNode; /* number of positive node of capacitor */
|
||||||
int CAPnegNode; /* number of negative 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 CAPtemp; /* temperature at which this capacitor operates */
|
||||||
double CAPdtemp; /* delta-temperature of this instance */
|
double CAPdtemp; /* delta-temperature of this instance */
|
||||||
|
|
@ -47,6 +48,7 @@ typedef struct sCAPinstance {
|
||||||
* (positive,negative) */
|
* (positive,negative) */
|
||||||
double *CAPnegPosptr; /* pointer to sparse matrix offdiagonal at
|
double *CAPnegPosptr; /* pointer to sparse matrix offdiagonal at
|
||||||
* (negative,positive) */
|
* (negative,positive) */
|
||||||
|
double *CAPbrptr; /* mhx: to get I(Cx), pointer to sparse matrix diagonal */
|
||||||
unsigned CAPcapGiven : 1; /* flag to indicate capacitance was specified */
|
unsigned CAPcapGiven : 1; /* flag to indicate capacitance was specified */
|
||||||
unsigned CAPicGiven : 1; /* flag to indicate init. cond. was specified */
|
unsigned CAPicGiven : 1; /* flag to indicate init. cond. was specified */
|
||||||
unsigned CAPwidthGiven : 1; /* flag to indicate capacitor width given */
|
unsigned CAPwidthGiven : 1; /* flag to indicate capacitor width given */
|
||||||
|
|
|
||||||
|
|
@ -23,4 +23,5 @@ extern int CAPsetup(SMPmatrix*,GENmodel*,CKTcircuit*,int*);
|
||||||
extern int CAPtemp(GENmodel*,CKTcircuit*);
|
extern int CAPtemp(GENmodel*,CKTcircuit*);
|
||||||
extern int CAPtrunc(GENmodel*,CKTcircuit*,double*);
|
extern int CAPtrunc(GENmodel*,CKTcircuit*,double*);
|
||||||
extern int CAPsoaCheck(CKTcircuit *, GENmodel *);
|
extern int CAPsoaCheck(CKTcircuit *, GENmodel *);
|
||||||
|
extern int CAPfindBr(CKTcircuit*, GENmodel*, IFuid);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
@ -47,7 +47,7 @@ SPICEdev CAPinfo = {
|
||||||
/* DEVpzSetup */ CAPsetup,
|
/* DEVpzSetup */ CAPsetup,
|
||||||
/* DEVtemperature*/ CAPtemp,
|
/* DEVtemperature*/ CAPtemp,
|
||||||
/* DEVtrunc */ CAPtrunc,
|
/* DEVtrunc */ CAPtrunc,
|
||||||
/* DEVfindBranch */ NULL,
|
/* DEVfindBranch */ CAPfindBr,
|
||||||
/* DEVacLoad */ CAPacLoad,
|
/* DEVacLoad */ CAPacLoad,
|
||||||
/* DEVaccept */ NULL,
|
/* DEVaccept */ NULL,
|
||||||
/* DEVdestroy */ CAPdestroy,
|
/* DEVdestroy */ CAPdestroy,
|
||||||
|
|
|
||||||
|
|
@ -77,6 +77,11 @@ CAPload(GENmodel *inModel, CKTcircuit *ckt)
|
||||||
*(here->CAPnegPosptr) -= m * geq;
|
*(here->CAPnegPosptr) -= m * geq;
|
||||||
*(ckt->CKTrhs+here->CAPposNode) -= m * ceq;
|
*(ckt->CKTrhs+here->CAPposNode) -= m * ceq;
|
||||||
*(ckt->CKTrhs+here->CAPnegNode) += 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
|
} else
|
||||||
*(ckt->CKTstate0+here->CAPqcap) = here->CAPcapac * vcap;
|
*(ckt->CKTstate0+here->CAPqcap) = here->CAPcapac * vcap;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -115,6 +115,8 @@ do { if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\
|
||||||
TSTALLOC(CAPnegNegptr,CAPnegNode,CAPnegNode);
|
TSTALLOC(CAPnegNegptr,CAPnegNode,CAPnegNode);
|
||||||
TSTALLOC(CAPposNegptr,CAPposNode,CAPnegNode);
|
TSTALLOC(CAPposNegptr,CAPposNode,CAPnegNode);
|
||||||
TSTALLOC(CAPnegPosptr,CAPnegNode,CAPposNode);
|
TSTALLOC(CAPnegPosptr,CAPnegNode,CAPposNode);
|
||||||
|
if (here->CAPbrEq & (here->CAPbrptr == NULL))
|
||||||
|
TSTALLOC(CAPbrptr, CAPbrEq, CAPbrEq); /* mhx: to access I(Cx) */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return(OK);
|
return(OK);
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ libind_la_SOURCES = \
|
||||||
indsacl.c \
|
indsacl.c \
|
||||||
indsetup.c \
|
indsetup.c \
|
||||||
indsload.c \
|
indsload.c \
|
||||||
|
indfindbr.c \
|
||||||
indsprt.c \
|
indsprt.c \
|
||||||
indsset.c \
|
indsset.c \
|
||||||
indsupd.c \
|
indsupd.c \
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ extern int INDsetup(SMPmatrix*,GENmodel*,CKTcircuit*,int*);
|
||||||
extern int INDunsetup(GENmodel*,CKTcircuit*);
|
extern int INDunsetup(GENmodel*,CKTcircuit*);
|
||||||
extern int INDtemp(GENmodel*, CKTcircuit*);
|
extern int INDtemp(GENmodel*, CKTcircuit*);
|
||||||
extern int INDtrunc(GENmodel*,CKTcircuit*,double*);
|
extern int INDtrunc(GENmodel*,CKTcircuit*,double*);
|
||||||
|
extern int INDfindBr(CKTcircuit*, GENmodel*, IFuid); // mhx: find inductor branch
|
||||||
|
|
||||||
extern int MUTacLoad(GENmodel*,CKTcircuit*);
|
extern int MUTacLoad(GENmodel*,CKTcircuit*);
|
||||||
extern int MUTask(CKTcircuit*,GENinstance*,int,IFvalue*,IFvalue*);
|
extern int MUTask(CKTcircuit*,GENinstance*,int,IFvalue*,IFvalue*);
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
@ -47,7 +47,7 @@ SPICEdev INDinfo = {
|
||||||
/* DEVpzSetup */ INDsetup,
|
/* DEVpzSetup */ INDsetup,
|
||||||
/* DEVtemperature*/ INDtemp,
|
/* DEVtemperature*/ INDtemp,
|
||||||
/* DEVtrunc */ INDtrunc,
|
/* DEVtrunc */ INDtrunc,
|
||||||
/* DEVfindBranch */ NULL,
|
/* DEVfindBranch */ INDfindBr, // mhx
|
||||||
/* DEVacLoad */ INDacLoad,
|
/* DEVacLoad */ INDacLoad,
|
||||||
/* DEVaccept */ NULL,
|
/* DEVaccept */ NULL,
|
||||||
/* DEVdestroy */ INDdestroy,
|
/* DEVdestroy */ INDdestroy,
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ libres_la_SOURCES = \
|
||||||
ressload.c \
|
ressload.c \
|
||||||
ressprt.c \
|
ressprt.c \
|
||||||
ressset.c \
|
ressset.c \
|
||||||
|
resfindbr.c \
|
||||||
restemp.c
|
restemp.c
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ typedef struct sRESinstance {
|
||||||
int RESstate; /* not used but needed for sructure consistency */
|
int RESstate; /* not used but needed for sructure consistency */
|
||||||
int RESposNode; /* number of positive node of resistor */
|
int RESposNode; /* number of positive node of resistor */
|
||||||
int RESnegNode; /* number of negative 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 REStemp; /* temperature at which this resistor operates */
|
||||||
double RESdtemp; /* delta-temperature of a particular instance */
|
double RESdtemp; /* delta-temperature of a particular instance */
|
||||||
|
|
@ -53,6 +54,7 @@ typedef struct sRESinstance {
|
||||||
* (positive,negative) */
|
* (positive,negative) */
|
||||||
double *RESnegPosptr; /* pointer to sparse matrix offdiagonal at
|
double *RESnegPosptr; /* pointer to sparse matrix offdiagonal at
|
||||||
* (negative,positive) */
|
* (negative,positive) */
|
||||||
|
double *RESbrptr; /* mhx: to get I(Rx), pointer to sparse matrix diagonal */
|
||||||
unsigned RESresGiven : 1; /* flag to indicate resistance was specified */
|
unsigned RESresGiven : 1; /* flag to indicate resistance was specified */
|
||||||
unsigned RESwidthGiven : 1; /* flag to indicate width given */
|
unsigned RESwidthGiven : 1; /* flag to indicate width given */
|
||||||
unsigned RESlengthGiven : 1; /* flag to indicate length given */
|
unsigned RESlengthGiven : 1; /* flag to indicate length given */
|
||||||
|
|
|
||||||
|
|
@ -21,3 +21,4 @@ extern int RESsetup(SMPmatrix*,GENmodel*,CKTcircuit*,int*);
|
||||||
extern int REStemp(GENmodel*,CKTcircuit*);
|
extern int REStemp(GENmodel*,CKTcircuit*);
|
||||||
extern int RESnoise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*);
|
extern int RESnoise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*);
|
||||||
extern int RESsoaCheck(CKTcircuit *, GENmodel *);
|
extern int RESsoaCheck(CKTcircuit *, GENmodel *);
|
||||||
|
extern int RESfindBr(CKTcircuit*, GENmodel*, IFuid); // mhx
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
@ -48,7 +48,7 @@ SPICEdev RESinfo = {
|
||||||
/* DEVpzSetup */ RESsetup,
|
/* DEVpzSetup */ RESsetup,
|
||||||
/* DEVtemperature*/ REStemp,
|
/* DEVtemperature*/ REStemp,
|
||||||
/* DEVtrunc */ NULL,
|
/* DEVtrunc */ NULL,
|
||||||
/* DEVfindBranch */ NULL,
|
/* DEVfindBranch */ RESfindBr,
|
||||||
/* DEVacLoad */ RESacload, /* ac load and normal load are identical */
|
/* DEVacLoad */ RESacload, /* ac load and normal load are identical */
|
||||||
/* DEVaccept */ NULL,
|
/* DEVaccept */ NULL,
|
||||||
/* DEVdestroy */ RESdestroy,
|
/* DEVdestroy */ RESdestroy,
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,12 @@ RESload(GENmodel *inModel, CKTcircuit *ckt)
|
||||||
|
|
||||||
m = (here->RESm);
|
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->RESposPosptr) += m * here->RESconduct;
|
||||||
*(here->RESnegNegptr) += m * here->RESconduct;
|
*(here->RESnegNegptr) += m * here->RESconduct;
|
||||||
*(here->RESposNegptr) -= m * here->RESconduct;
|
*(here->RESposNegptr) -= m * here->RESconduct;
|
||||||
|
|
|
||||||
|
|
@ -86,6 +86,8 @@ do { if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\
|
||||||
TSTALLOC(RESnegNegptr, RESnegNode, RESnegNode);
|
TSTALLOC(RESnegNegptr, RESnegNode, RESnegNode);
|
||||||
TSTALLOC(RESposNegptr, RESposNode, RESnegNode);
|
TSTALLOC(RESposNegptr, RESposNode, RESnegNode);
|
||||||
TSTALLOC(RESnegPosptr, RESnegNode, RESposNode);
|
TSTALLOC(RESnegPosptr, RESnegNode, RESposNode);
|
||||||
|
if (here->RESbrEq & (here->RESbrptr == NULL))
|
||||||
|
TSTALLOC(RESbrptr, RESbrEq, RESbrEq);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return(OK);
|
return(OK);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue