a first attempt to access branch current of rlc devices

This commit is contained in:
dwarning 2015-04-01 22:21:27 +02:00
parent 000b23cc52
commit 9c8766f65b
19 changed files with 136 additions and 60 deletions

View File

@ -83,7 +83,7 @@ int fixme_inoise_type = SV_NOTYPE;
static clock_t lastclock, currclock;
static double *rowbuf;
static size_t column, rowbuflen;
static size_t column, rowbuflen, doornroosje = 0;
static bool shouldstop = FALSE; /* Tell simulator to stop next time it asks. */
@ -175,6 +175,7 @@ beginPlot(JOB *analysisPtr, CKTcircuit *circuitPtr, char *cktName, char *analNam
run->type = copy(analName);
run->windowed = windowed;
run->numData = 0;
run->spindex = -1; // mhx
an_name = spice_analysis_get_name(analysisPtr->JOBtype);
ft_curckt->ci_last_an = an_name;
@ -508,13 +509,14 @@ OUTpData(runDesc *plotPtr, IFvalue *refValue, IFvalue *valuePtr)
every quarter of a second, to give some feedback without using
too much CPU time */
#ifndef HAS_WINGUI
if (!orflag) {
if (!orflag && (doornroosje == 0)) {
currclock = clock();
if ((currclock-lastclock) > (0.25*CLOCKS_PER_SEC)) {
fprintf(stderr, " Reference value : % 12.5e\r",
refValue->cValue.real);
lastclock = currclock;
}
else doornroosje--;
}
#endif
} else {
@ -523,7 +525,7 @@ OUTpData(runDesc *plotPtr, IFvalue *refValue, IFvalue *valuePtr)
fileAddRealValue(run->fp, run->binary, refValue->rValue);
#ifndef HAS_WINGUI
if (!orflag) {
if (!orflag && (doornroosje == 0)) {
currclock = clock();
if ((currclock-lastclock) > (0.25*CLOCKS_PER_SEC)) {
fprintf(stderr, " Reference value : % 12.5e\r",
@ -531,6 +533,7 @@ OUTpData(runDesc *plotPtr, IFvalue *refValue, IFvalue *valuePtr)
lastclock = currclock;
}
}
else doornroosje--;
#endif
}
}
@ -606,7 +609,7 @@ OUTpData(runDesc *plotPtr, IFvalue *refValue, IFvalue *valuePtr)
variable just the same */
#ifndef HAS_WINGUI
if (!orflag) {
if (!orflag && (doornroosje == 0)) {
currclock = clock();
if ((currclock-lastclock) > (0.25*CLOCKS_PER_SEC)) {
if (run->isComplex) {
@ -619,6 +622,7 @@ OUTpData(runDesc *plotPtr, IFvalue *refValue, IFvalue *valuePtr)
lastclock = currclock;
}
}
else doornroosje--;
#endif
for (i = 0; i < run->numData; i++) {
@ -942,7 +946,7 @@ fileStartPoint(FILE *fp, bool bin, int num)
column = 0;
}
/* This code is used when one does RUN aap.raw but *not* when doing RUN. */
static void
fileAddRealValue(FILE *fp, bool bin, double value)
{
@ -1056,6 +1060,8 @@ plotInit(runDesc *run)
}
}
/* mhx: minimize the number of REALLOCs */
#define OUTSIZE (256*4096)
static void
plotAddRealValue(dataDesc *desc, double value)
@ -1063,11 +1069,11 @@ plotAddRealValue(dataDesc *desc, double value)
struct dvec *v = desc->vec;
if (isreal(v)) {
v->v_realdata = TREALLOC(double, v->v_realdata, v->v_length + 1);
if ((v->v_dims[0] & (OUTSIZE - 1)) == 0) v->v_realdata = TREALLOC(double, v->v_realdata, v->v_length + OUTSIZE);
v->v_realdata[v->v_length] = value;
} else {
/* a real parading as a VF_COMPLEX */
v->v_compdata = TREALLOC(ngcomplex_t, v->v_compdata, v->v_length + 1);
if ((v->v_dims[0] & (OUTSIZE - 1)) == 0) v->v_compdata = TREALLOC(ngcomplex_t, v->v_compdata, v->v_length + OUTSIZE);
v->v_compdata[v->v_length].cx_real = value;
v->v_compdata[v->v_length].cx_imag = 0.0;
}
@ -1082,7 +1088,7 @@ plotAddComplexValue(dataDesc *desc, IFcomplex value)
{
struct dvec *v = desc->vec;
v->v_compdata = TREALLOC(ngcomplex_t, v->v_compdata, v->v_length + 1);
if ((v->v_dims[0] & (OUTSIZE - 1)) == 0) v->v_compdata = TREALLOC(ngcomplex_t, v->v_compdata, v->v_length + OUTSIZE);
v->v_compdata[v->v_length].cx_real = value.real;
v->v_compdata[v->v_length].cx_imag = value.imag;

View File

@ -8,7 +8,6 @@
#include "ngspice/typedefs.h"
typedef struct dataDesc {
char *name; /* The name of the vector. */
int type; /* The type. */
@ -24,7 +23,6 @@ typedef struct dataDesc {
struct dvec *vec;
} dataDesc;
struct runDesc {
void *analysis;
CKTcircuit *circuit;
@ -38,13 +36,13 @@ struct runDesc {
bool binary;
struct plot *runPlot;
FILE *fp;
long pointPos; /* where to write pointCount */
long pointPos; /* where to write pointCount */
int pointCount;
int isComplex;
int windowCount;
int spindex; /* mhx */
};
int OUTpBeginPlot(CKTcircuit *circuitPtr, JOB *analysisPtr,
IFuid analName,
IFuid refName, int refType,
@ -64,11 +62,4 @@ int OUTattributes(runDesc *plotPtr, IFuid varName, int param, IFvalue *value);
int OUTstopnow(void);
void OUTerror(int flags, char *format, IFuid *names);
#ifdef __GNUC__
void OUTerrorf(int, const char *fmt, ...) __attribute__ ((format (__printf__, 2, 3)));
#else
void OUTerrorf(int, const char *fmt, ...);
#endif
#endif

View File

@ -89,6 +89,7 @@ int IFnewUid(CKTcircuit *, IFuid *, IFuid, char *, int, CKTnode **);
int IFdelUid(CKTcircuit *, IFuid, int);
int INPaName(char *, IFvalue *, CKTcircuit *, int *, char *, GENinstance **, IFsimulator *, int *,
IFvalue *);
int INPaSpecName(char *, IFvalue *, CKTcircuit *, int *, char *, GENinstance **, IFsimulator *, int *, IFvalue *, int *);
int INPapName(CKTcircuit *, int, JOB *, char *, IFvalue *);
void INPcaseFix(char *);
char *INPdevParse(char **, CKTcircuit *, int, GENinstance *, double *, int *, INPtables *);

View File

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

View File

@ -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 */

View File

@ -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);

View File

@ -47,7 +47,7 @@ SPICEdev CAPinfo = {
/* DEVpzSetup */ CAPsetup,
/* DEVtemperature*/ CAPtemp,
/* DEVtrunc */ CAPtrunc,
/* DEVfindBranch */ NULL,
/* DEVfindBranch */ CAPfindBr,
/* DEVacLoad */ CAPacLoad,
/* DEVaccept */ NULL,
/* DEVdestroy */ CAPdestroy,

View File

@ -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;
}

View File

@ -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);

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,7 +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*);
extern int MUTdelete(GENmodel*,IFuid,GENinstance**);

View File

@ -47,7 +47,7 @@ SPICEdev INDinfo = {
/* DEVpzSetup */ INDsetup,
/* DEVtemperature*/ INDtemp,
/* DEVtrunc */ INDtrunc,
/* DEVfindBranch */ NULL,
/* DEVfindBranch */ INDfindBr, // mhx
/* 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,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 */

View File

@ -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

View File

@ -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,

View File

@ -10,9 +10,9 @@ Modified: Apr 2000 - Paolo Nenzi
#include "ngspice/sperror.h"
/* actually load the current resistance value into the sparse matrix
/* actually load the current resistance value into the sparse matrix
* previously provided */
int
int
RESload(GENmodel *inModel, CKTcircuit *ckt)
{
RESmodel *model = (RESmodel *)inModel;
@ -23,14 +23,20 @@ RESload(GENmodel *inModel, CKTcircuit *ckt)
RESinstance *here;
/* loop through all the instances of the model */
for (here = model->RESinstances; here != NULL ;
here = here->RESnextInstance) {
for (here = model->RESinstances; here != NULL ;
here = here->RESnextInstance) {
here->REScurrent = (*(ckt->CKTrhsOld+here->RESposNode) -
here->REScurrent = (*(ckt->CKTrhsOld+here->RESposNode) -
*(ckt->CKTrhsOld+here->RESnegNode)) * here->RESconduct;
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;
@ -41,10 +47,10 @@ RESload(GENmodel *inModel, CKTcircuit *ckt)
}
/* actually load the current resistance value into the sparse matrix
/* actually load the current resistance value into the sparse matrix
* previously provided */
int
RESacload(GENmodel *inModel, CKTcircuit *ckt)
int
RESacload(GENmodel *inModel, CKTcircuit *ckt)
{
RESmodel *model = (RESmodel *)inModel;
double m;
@ -56,7 +62,7 @@ RESacload(GENmodel *inModel, CKTcircuit *ckt)
RESinstance *here;
/* loop through all the instances of the model */
for (here = model->RESinstances; here != NULL ;
for (here = model->RESinstances; here != NULL ;
here = here->RESnextInstance) {
m = (here->RESm);

View File

@ -86,7 +86,9 @@ 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);
}

View File

@ -19,20 +19,18 @@ Author: 1985 Thomas L. Quarles
#include "ngspice/iferrmsg.h"
#include "inpxx.h"
int
INPaName(char *parm, IFvalue * val, CKTcircuit *ckt, int *dev, char *devnam,
GENinstance **fast, IFsimulator * sim, int *dataType, IFvalue * selector)
/* the name of the parameter to set */
/* the parameter union containing the value to set */
/* the circuit this device is a member of */
/* the device type code to the device being parsed */
/* the name of the device */
/* direct pointer to device being parsed */
/* the simulator data structure */
/* the datatype of the returned value structure */
/* data sub-selector for questions */
int
INPaName ( char *parm, // the name of the parameter to set,
IFvalue *val, // the parameter union containing the value to set,
CKTcircuit *ckt, // the circuit this device is a member of,
int *dev, // the device type code to the device being parsed,
char *devnam, // the name of the device,
GENinstance **fast, // direct pointer to device being parsed,
IFsimulator *sim, // the simulator data structure,
int *dataType, // the datatype of the returned value structure,
IFvalue *selector) // data sub-selector for questions.
{
int error; /* int to store evaluate error return codes in */
int error; /* int to store evaluate error return codes in */
int i;
/* find the instance - don't know about model, so use null there,
@ -43,7 +41,7 @@ INPaName(char *parm, IFvalue * val, CKTcircuit *ckt, int *dev, char *devnam,
if (*fast == NULL)
*fast = sim->findInstance (ckt, devnam);
if (*fast == NULL)
return (E_NODEV);
return (E_NODEV);
*dev = (*fast)->GENmodPtr->GENmodType;
@ -52,20 +50,76 @@ INPaName(char *parm, IFvalue * val, CKTcircuit *ckt, int *dev, char *devnam,
* parameter.
*/
for (i = 0; i < *(sim->devices[*dev]->numInstanceParms); i++) {
if (strcmp(parm, sim->devices[*dev]->instanceParms[i].keyword) == 0
&& (sim->devices[*dev]->instanceParms[i].dataType & IF_ASK)) {
/* found it, so we ask the question using the device info we got
* above and put the results in the IFvalue structure our caller
* gave us originally
*/
error = sim->askInstanceQuest (ckt, *fast,
if (strcmp(parm, sim->devices[*dev]->instanceParms[i].keyword) == 0
&& (sim->devices[*dev]->instanceParms[i].dataType & IF_ASK)) {
/* found it, so we ask the question using the device info we got
* above and put the results in the IFvalue structure our caller
* gave us originally
*/
error = sim->askInstanceQuest (ckt, *fast,
sim->devices[*dev]->instanceParms[i].id, val,
selector);
if (dataType)
*dataType =
sim->devices[*dev]->instanceParms[i].dataType;
return (error);
}
selector);
if (dataType)
*dataType =
sim->devices[*dev]->instanceParms[i].dataType;
return (error);
}
}
return (E_BADPARM);
}
// mhx: specialized (faster) version that directly returns/uses the index of the parameter we seek
int INPaSpecName (
char *parm, // the name of the parameter to set,
IFvalue *val, // the parameter union containing the value to set,
CKTcircuit *ckt, // the circuit this device is a member of,
int *dev, // the device type code to the device being parsed,
char *devnam, // the name of the device,
GENinstance **fast, // direct pointer to device being parsed,
IFsimulator *sim, // the simulator data structure,
int *dataType, // the datatype of the returned value structure,
IFvalue *selector, // data sub-selector for questions.
int *spindex) // special index
{
int error; // int to store evaluate error return codes in
int i;
/*
* find the instance - don't know about model, so use null there,
* otherwise pass on as much info as we have about the device
* (name, type, direct pointer) - the type and direct pointer
* WILL be set on return unless error is not OK
*/
if (*fast == NULL)
*fast = sim->findInstance(ckt, devnam);
if (*fast == NULL)
return (E_NODEV);
*dev = (*fast)->GENmodPtr->GENmodType;
/* now find the parameter - hunt through the parameter tables for
* this device type and look for a name match of an 'ask'able
* parameter.
*/
if (*spindex != -1) { // mhx: shortcut for repeated question
error = sim->askInstanceQuest(ckt, *fast, sim->devices[*dev]->instanceParms[*spindex].id, val, selector);
if (dataType) *dataType = sim->devices[*dev]->instanceParms[*spindex].dataType;
return error;
}
for (i = 0; i < *(sim->devices[*dev]->numInstanceParms); i++) {
if (strcmp(parm, sim->devices[*dev]->instanceParms[i].keyword) == 0
&& (sim->devices[*dev]->instanceParms[i].dataType & IF_ASK)) {
/*
* found it, so we ask the question using the device info we got
* above and put the results in the IFvalue structure our caller gave us originally
*/
*spindex = i; /* mhx: shortcut for repeated questioning */
error = sim->askInstanceQuest(ckt, *fast, sim->devices[*dev]->instanceParms[i].id, val, selector);
if (dataType)
*dataType = sim->devices[*dev]->instanceParms[i].dataType; // probably double
return error;
}
}
return E_BADPARM;
}