branch currents, res, cap, ind

This commit is contained in:
rlar 2015-04-14 19:01:12 +02:00
parent a11e4e2ac9
commit a2e3b7f0d4
23 changed files with 293 additions and 53 deletions

View File

@ -73,6 +73,8 @@ CKTsetup(CKTcircuit *ckt)
#ifdef HAS_PROGREP
SetAnalyse( "Device Setup", 0 );
#endif
// make sure asrc comes before res, cap, ind etc
// damit die findbranches durch sind ...
if ( DEVices[i] && DEVices[i]->DEVsetup && ckt->CKThead[i] ) {
error = DEVices[i]->DEVsetup (matrix, ckt->CKThead[i], ckt,
&ckt->CKTnumStates);

View File

@ -28,6 +28,7 @@ libcap_la_SOURCES = \
capsset.c \
capsupd.c \
captemp.c \
capfindbr.c \
captrunc.c

View File

@ -29,10 +29,17 @@ CAPacLoad(GENmodel *inModel, CKTcircuit *ckt)
val = ckt->CKTomega * here->CAPcapac;
*(here->CAPposPosptr +1) += m * val;
*(here->CAPnegNegptr +1) += m * val;
*(here->CAPposNegptr +1) -= m * val;
*(here->CAPnegPosptr +1) -= m * val;
*(here->CAP_posPrime_posPrime +1) += m * val;
*(here->CAP_neg_neg +1) += m * val;
*(here->CAP_posPrime_neg +1) -= m * val;
*(here->CAP_neg_PosPrime +1) -= m * val;
if (here->CAPbranch) {
*(here->CAP_pos_ibr) += 1.0;
*(here->CAP_posPrime_ibr) -= 1.0;
*(here->CAP_ibr_pos) += 1.0;
*(here->CAP_ibr_posPrime) -= 1.0;
}
}
}
return(OK);

View File

@ -26,6 +26,8 @@ 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 CAPposPrimeNode; /* number of positive prime node of capacitor */
int CAPbranch; /* number of vprobe branch current node */
double CAPtemp; /* temperature at which this capacitor operates */
double CAPdtemp; /* delta-temperature of this instance */
@ -39,14 +41,19 @@ typedef struct sCAPinstance {
double CAPtc2; /* second temperature coefficient of capacitors */
double CAPbv_max; /* Maximum capacitor voltage */
double *CAPposPosptr; /* pointer to sparse matrix diagonal at
double *CAP_posPrime_posPrime; /* pointer to sparse matrix diagonal at
* (positive,positive) */
double *CAPnegNegptr; /* pointer to sparse matrix diagonal at
double *CAP_neg_neg; /* pointer to sparse matrix diagonal at
* (negative,negative) */
double *CAPposNegptr; /* pointer to sparse matrix offdiagonal at
double *CAP_posPrime_neg; /* pointer to sparse matrix offdiagonal at
* (positive,negative) */
double *CAPnegPosptr; /* pointer to sparse matrix offdiagonal at
double *CAP_neg_PosPrime; /* pointer to sparse matrix offdiagonal at
* (negative,positive) */
double *CAP_pos_ibr;
double *CAP_posPrime_ibr;
double *CAP_ibr_posPrime;
double *CAP_ibr_pos;
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 */

View File

@ -20,7 +20,9 @@ extern void CAPsPrint(GENmodel*,CKTcircuit*);
extern int CAPsSetup(SENstruct *,GENmodel*);
extern int CAPsUpdate(GENmodel*,CKTcircuit*);
extern int CAPsetup(SMPmatrix*,GENmodel*,CKTcircuit*,int*);
extern int CAPunsetup(GENmodel*,CKTcircuit*);
extern int CAPtemp(GENmodel*,CKTcircuit*);
extern int CAPtrunc(GENmodel*,CKTcircuit*,double*);
extern int CAPsoaCheck(CKTcircuit *, GENmodel *);
extern int CAPfindBr(CKTcircuit*,GENmodel*,IFuid);

View File

@ -0,0 +1,41 @@
/***********************************
* Author: Marcel Hendrix, Feb 2015 *
***********************************/
#include "ngspice/ngspice.h"
#include "ngspice/cktdefs.h"
#include "capdefs.h"
#include "ngspice/sperror.h"
#include "ngspice/suffix.h"
int
CAPfindBr (CKTcircuit *ckt, GENmodel *inModel, IFuid name)
{
CAPmodel *model = (CAPmodel *) inModel;
CAPinstance *here;
for (; model; model = model->CAPnextModel)
for (here = model->CAPinstances; here; here = here->CAPnextInstance)
if (here->CAPname == name) {
if (here->CAPbranch == 0) {
CKTnode *tmp;
int error;
error = CKTmkCur(ckt, &tmp, here->CAPname, "branch");
if (error)
return error;
here->CAPbranch = tmp->number;
error = CKTmkVolt(ckt, &tmp, here->CAPname, "aux");
if (error)
return error;
here->CAPposPrimeNode = tmp->number;
}
return here->CAPbranch;
}
return 0;
}

View File

@ -43,11 +43,11 @@ SPICEdev CAPinfo = {
/* DEVmodParam */ CAPmParam,
/* DEVload */ CAPload,
/* DEVsetup */ CAPsetup,
/* DEVunsetup */ NULL,
/* DEVunsetup */ CAPunsetup,
/* DEVpzSetup */ CAPsetup,
/* DEVtemperature*/ CAPtemp,
/* DEVtrunc */ CAPtrunc,
/* DEVfindBranch */ NULL,
/* DEVfindBranch */ CAPfindBr,
/* DEVacLoad */ CAPacLoad,
/* DEVaccept */ NULL,
/* DEVdestroy */ CAPdestroy,

View File

@ -42,7 +42,7 @@ CAPload(GENmodel *inModel, CKTcircuit *ckt)
if(cond1) {
vcap = here->CAPinitCond;
} else {
vcap = *(ckt->CKTrhsOld+here->CAPposNode) -
vcap = *(ckt->CKTrhsOld+here->CAPposPrimeNode) -
*(ckt->CKTrhsOld+here->CAPnegNode) ;
}
if(ckt->CKTmode & (MODETRAN | MODEAC)) {
@ -67,15 +67,22 @@ CAPload(GENmodel *inModel, CKTcircuit *ckt)
*(ckt->CKTstate1+here->CAPccap) =
*(ckt->CKTstate0+here->CAPccap);
}
*(here->CAPposPosptr) += m * geq;
*(here->CAPnegNegptr) += m * geq;
*(here->CAPposNegptr) -= m * geq;
*(here->CAPnegPosptr) -= m * geq;
*(ckt->CKTrhs+here->CAPposNode) -= m * ceq;
*(ckt->CKTrhs+here->CAPnegNode) += m * ceq;
*(here->CAP_posPrime_posPrime) += m * geq;
*(here->CAP_neg_neg) += m * geq;
*(here->CAP_posPrime_neg) -= m * geq;
*(here->CAP_neg_PosPrime) -= m * geq;
ckt->CKTrhs[here->CAPposPrimeNode] -= m * ceq;
ckt->CKTrhs[here->CAPnegNode] += m * ceq;
} else
if (ckt->CKTmode & MODETRANOP) {
*(ckt->CKTstate0+here->CAPqcap) = here->CAPcapac * vcap;
}
if (here->CAPbranch) {
*(here->CAP_pos_ibr) += 1.0;
*(here->CAP_posPrime_ibr) -= 1.0;
*(here->CAP_ibr_pos) += 1.0;
*(here->CAP_ibr_posPrime) -= 1.0;
}
}
}

View File

@ -33,14 +33,21 @@ CAPpzLoad(GENmodel *inModel, CKTcircuit *ckt, SPcomplex *s)
val = here->CAPcapac;
m = here->CAPm;
*(here->CAPposPosptr ) += m * val * s->real;
*(here->CAPposPosptr +1) += m * val * s->imag;
*(here->CAPnegNegptr ) += m * val * s->real;
*(here->CAPnegNegptr +1) += m * val * s->imag;
*(here->CAPposNegptr ) -= m * val * s->real;
*(here->CAPposNegptr +1) -= m * val * s->imag;
*(here->CAPnegPosptr ) -= m * val * s->real;
*(here->CAPnegPosptr +1) -= m * val * s->imag;
*(here->CAP_posPrime_posPrime ) += m * val * s->real;
*(here->CAP_posPrime_posPrime +1) += m * val * s->imag;
*(here->CAP_neg_neg ) += m * val * s->real;
*(here->CAP_neg_neg +1) += m * val * s->imag;
*(here->CAP_posPrime_neg ) -= m * val * s->real;
*(here->CAP_posPrime_neg +1) -= m * val * s->imag;
*(here->CAP_neg_PosPrime ) -= m * val * s->real;
*(here->CAP_neg_PosPrime +1) -= m * val * s->imag;
if (here->CAPbranch) {
*(here->CAP_pos_ibr) += 1.0;
*(here->CAP_posPrime_ibr) -= 1.0;
*(here->CAP_ibr_pos) += 1.0;
*(here->CAP_ibr_posPrime) -= 1.0;
}
}
}
return(OK);

View File

@ -111,12 +111,39 @@ do { if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\
return(E_NOMEM);\
} } while(0)
TSTALLOC(CAPposPosptr,CAPposNode,CAPposNode);
TSTALLOC(CAPnegNegptr,CAPnegNode,CAPnegNode);
TSTALLOC(CAPposNegptr,CAPposNode,CAPnegNode);
TSTALLOC(CAPnegPosptr,CAPnegNode,CAPposNode);
if (here->CAPbranch == 0) {
here->CAPposPrimeNode = here->CAPposNode;
} else {
TSTALLOC(CAP_pos_ibr, CAPposNode, CAPbranch);
TSTALLOC(CAP_posPrime_ibr, CAPposPrimeNode, CAPbranch);
TSTALLOC(CAP_ibr_posPrime, CAPbranch, CAPposPrimeNode);
TSTALLOC(CAP_ibr_pos, CAPbranch, CAPposNode);
}
TSTALLOC(CAP_posPrime_posPrime, CAPposPrimeNode, CAPposPrimeNode);
TSTALLOC(CAP_neg_neg, CAPnegNode, CAPnegNode);
TSTALLOC(CAP_posPrime_neg, CAPposPrimeNode, CAPnegNode);
TSTALLOC(CAP_neg_PosPrime, CAPnegNode, CAPposPrimeNode);
}
}
return(OK);
}
int
CAPunsetup(GENmodel *inModel, CKTcircuit *ckt)
{
CAPmodel *model = (CAPmodel *) inModel;
CAPinstance *here;
for (; model; model = model->CAPnextModel)
for (here = model->CAPinstances; here; here = here->CAPnextInstance)
if (here->CAPbranch) {
CKTdltNNum(ckt, here->CAPbranch);
here->CAPbranch = 0;
CKTdltNNum(ckt, here->CAPposPrimeNode);
here->CAPposPrimeNode = 0;
}
return OK;
}

View File

@ -141,7 +141,7 @@ int add_udn(int,Evt_Udn_Info_t **);
static SPICEdev *(*static_devices[])(void) = {
/* URC device MUST precede both resistors and capacitors */
get_urc_info,
get_asrc_info,
get_asrc_info, /* asrc must precede res, cap, ind and dio */
get_bjt_info,
get_bsim1_info,
get_bsim2_info,

View File

@ -22,6 +22,7 @@ libind_la_SOURCES = \
indsacl.c \
indsetup.c \
indsload.c \
indfindbr.c \
indsprt.c \
indsset.c \
indsupd.c \

View File

@ -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);
extern int MUTacLoad(GENmodel*,CKTcircuit*);
extern int MUTask(CKTcircuit*,GENinstance*,int,IFvalue*,IFvalue*);

View File

@ -0,0 +1,36 @@
/***********************************
* 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;
for (; model; model = model->INDnextModel)
for (here = model->INDinstances; here; here = here->INDnextInstance)
if (here->INDname == name) {
if (here->INDbrEq == 0) {
CKTnode *tmp;
int error;
error = CKTmkCur(ckt, &tmp, here->INDname, "branch");
if (error)
return error;
here->INDbrEq = tmp->number;
}
return here->INDbrEq;
}
return 0;
}

View File

@ -47,7 +47,7 @@ SPICEdev INDinfo = {
/* DEVpzSetup */ INDsetup,
/* DEVtemperature*/ INDtemp,
/* DEVtrunc */ INDtrunc,
/* DEVfindBranch */ NULL,
/* DEVfindBranch */ INDfindBr,
/* DEVacLoad */ INDacLoad,
/* DEVaccept */ NULL,
/* DEVdestroy */ INDdestroy,

View File

@ -25,6 +25,7 @@ libres_la_SOURCES = \
ressload.c \
ressprt.c \
ressset.c \
resfindbr.c \
restemp.c

View File

@ -27,6 +27,8 @@ 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 RESposPrimeNode; /* number of node between resistor and vprobe */
int RESbranch; /* number of vprobe branch current node */
double REStemp; /* temperature at which this resistor operates */
double RESdtemp; /* delta-temperature of a particular instance */
@ -45,14 +47,19 @@ typedef struct sRESinstance {
double RESbv_max; /* Maximum resistor voltage */
int RESnoisy; /* Set if the resistor generates noise */
double RESeffNoiseArea; /* effective resistor area for noise calculation */
double *RESposPosptr; /* pointer to sparse matrix diagonal at
double *RES_posPrime_posPrime; /* pointer to sparse matrix diagonal at
* (positive,positive) */
double *RESnegNegptr; /* pointer to sparse matrix diagonal at
double *RES_neg_neg; /* pointer to sparse matrix diagonal at
* (negative,negative) */
double *RESposNegptr; /* pointer to sparse matrix offdiagonal at
double *RES_posPrime_neg; /* pointer to sparse matrix offdiagonal at
* (positive,negative) */
double *RESnegPosptr; /* pointer to sparse matrix offdiagonal at
double *RES_neg_PosPrime; /* pointer to sparse matrix offdiagonal at
* (negative,positive) */
double *RES_pos_ibr;
double *RES_posPrime_ibr;
double *RES_ibr_posPrime;
double *RES_ibr_pos;
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 */

View File

@ -18,6 +18,8 @@ extern int RESsLoad(GENmodel*,CKTcircuit*);
extern int RESsSetup(SENstruct*,GENmodel*);
extern void RESsPrint(GENmodel*,CKTcircuit*);
extern int RESsetup(SMPmatrix*,GENmodel*,CKTcircuit*,int*);
extern int RESunsetup(GENmodel*, CKTcircuit*);
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);

View File

@ -0,0 +1,41 @@
/***********************************
* Author: Marcel Hendrix, Feb 2015 *
***********************************/
#include "ngspice/ngspice.h"
#include "ngspice/cktdefs.h"
#include "resdefs.h"
#include "ngspice/sperror.h"
#include "ngspice/suffix.h"
int
RESfindBr (CKTcircuit *ckt, GENmodel *inModel, IFuid name)
{
RESmodel *model = (RESmodel *) inModel;
RESinstance *here;
for (; model; model = model->RESnextModel)
for (here = model->RESinstances; here; here = here->RESnextInstance)
if (here->RESname == name) {
if (!here->RESbranch) {
CKTnode *tmp;
int error;
error = CKTmkCur(ckt, &tmp, here->RESname, "branch");
if (error)
return error;
here->RESbranch = tmp->number;
error = CKTmkVolt(ckt, &tmp, here->RESname, "aux");
if (error)
return error;
here->RESposPrimeNode = tmp->number;
}
return here->RESbranch;
}
return 0;
}

View File

@ -44,11 +44,11 @@ SPICEdev RESinfo = {
/* DEVmodParam */ RESmParam,
/* DEVload */ RESload,
/* DEVsetup */ RESsetup,
/* DEVunsetup */ NULL,
/* DEVunsetup */ RESunsetup,
/* DEVpzSetup */ RESsetup,
/* DEVtemperature*/ REStemp,
/* DEVtrunc */ NULL,
/* DEVfindBranch */ NULL,
/* DEVfindBranch */ RESfindBr,
/* DEVacLoad */ RESacload, /* ac load and normal load are identical */
/* DEVaccept */ NULL,
/* DEVdestroy */ RESdestroy,

View File

@ -31,10 +31,17 @@ RESload(GENmodel *inModel, CKTcircuit *ckt)
m = (here->RESm);
*(here->RESposPosptr) += m * here->RESconduct;
*(here->RESnegNegptr) += m * here->RESconduct;
*(here->RESposNegptr) -= m * here->RESconduct;
*(here->RESnegPosptr) -= m * here->RESconduct;
*(here->RES_posPrime_posPrime) += m * here->RESconduct;
*(here->RES_neg_neg) += m * here->RESconduct;
*(here->RES_posPrime_neg) -= m * here->RESconduct;
*(here->RES_neg_PosPrime) -= m * here->RESconduct;
if (here->RESbranch) {
*(here->RES_pos_ibr) += 1.0 ;
*(here->RES_posPrime_ibr) -= 1.0 ;
*(here->RES_ibr_pos) += 1.0 ;
*(here->RES_ibr_posPrime) -= 1.0 ;
}
}
}
return(OK);
@ -64,10 +71,17 @@ RESacload(GENmodel *inModel, CKTcircuit *ckt)
else
g = here->RESm * here->RESconduct;
*(here->RESposPosptr) += g;
*(here->RESnegNegptr) += g;
*(here->RESposNegptr) -= g;
*(here->RESnegPosptr) -= g;
*(here->RES_posPrime_posPrime) += g;
*(here->RES_neg_neg) += g;
*(here->RES_posPrime_neg) -= g;
*(here->RES_neg_PosPrime) -= g;
if (here->RESbranch) {
*(here->RES_pos_ibr) += 1.0 ;
*(here->RES_posPrime_ibr) -= 1.0 ;
*(here->RES_ibr_pos) += 1.0 ;
*(here->RES_ibr_posPrime) -= 1.0 ;
}
}
}
return(OK);

View File

@ -38,10 +38,17 @@ RESpzLoad(GENmodel *inModel, CKTcircuit *ckt, SPcomplex *s)
else
g = here->RESm * here->RESconduct;
*(here->RESposPosptr) += g;
*(here->RESnegNegptr) += g;
*(here->RESposNegptr) -= g;
*(here->RESnegPosptr) -= g;
*(here->RES_posPrime_posPrime) += g;
*(here->RES_neg_neg) += g;
*(here->RES_posPrime_neg) -= g;
*(here->RES_neg_PosPrime) -= g;
if (here->RESbranch) {
*(here->RES_pos_ibr) += 1.0;
*(here->RES_posPrime_ibr) -= 1.0;
*(here->RES_ibr_pos) += 1.0;
*(here->RES_ibr_posPrime) -= 1.0;
}
}
}
return(OK);

View File

@ -82,11 +82,40 @@ do { if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\
return(E_NOMEM);\
} } while(0)
TSTALLOC(RESposPosptr, RESposNode, RESposNode);
TSTALLOC(RESnegNegptr, RESnegNode, RESnegNode);
TSTALLOC(RESposNegptr, RESposNode, RESnegNode);
TSTALLOC(RESnegPosptr, RESnegNode, RESposNode);
if (here->RESbranch == 0) {
here->RESposPrimeNode = here->RESposNode;
} else {
TSTALLOC(RES_pos_ibr, RESposNode, RESbranch);
TSTALLOC(RES_posPrime_ibr, RESposPrimeNode, RESbranch);
TSTALLOC(RES_ibr_posPrime, RESbranch, RESposPrimeNode);
TSTALLOC(RES_ibr_pos, RESbranch, RESposNode);
}
TSTALLOC(RES_posPrime_posPrime, RESposPrimeNode, RESposPrimeNode);
TSTALLOC(RES_neg_neg, RESnegNode, RESnegNode);
TSTALLOC(RES_posPrime_neg, RESposPrimeNode, RESnegNode);
TSTALLOC(RES_neg_PosPrime, RESnegNode, RESposPrimeNode);
}
}
return(OK);
}
int
RESunsetup(GENmodel *inModel, CKTcircuit *ckt)
{
RESmodel *model = (RESmodel *) inModel;
RESinstance *here;
for (; model; model = model->RESnextModel)
for (here = model->RESinstances; here; here = here->RESnextInstance)
if (here->RESbranch) {
CKTdltNNum(ckt, here->RESbranch);
here->RESbranch = 0;
CKTdltNNum(ckt, here->RESposPrimeNode);
here->RESposPrimeNode = 0;
}
return OK;
}