You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

183 lines
5.9 KiB

/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
Modified: Apr 2000 - Paolo Nenzi
**********/
#include "ngspice/ngspice.h"
#include "ngspice/const.h"
#include "resdefs.h"
#include "ngspice/ifsim.h"
#include "ngspice/cktdefs.h"
#include "ngspice/sperror.h"
/* TODO : there are "double" value compared with 0 (eg: vm == 0)
* Need to substitute this check with a suitable eps.
* PN 2003
*/
int
RESask(CKTcircuit *ckt, GENinstance *inst, int which, IFvalue *value,
IFvalue *select)
{
RESinstance *fast = (RESinstance *)inst;
double vr;
double vi;
double sr;
double si;
double vm;
static char *msg = "Current and power not available for ac analysis";
switch(which) {
case RES_TEMP:
value->rValue = fast->REStemp - CONSTCtoK;
return(OK);
case RES_DTEMP:
value->rValue = fast->RESdtemp;
return(OK);
case RES_CONDUCT:
value->rValue = fast->RESconduct;
value->rValue *= fast->RESm;
return(OK);
case RES_RESIST:
value->rValue = fast->RESresist;
value->rValue /= fast->RESm;
return(OK);
case RES_ACCONDUCT:
value->rValue = fast->RESacConduct;
value->rValue *= fast->RESm;
return (OK);
case RES_ACRESIST:
value->rValue = fast->RESacResist;
value->rValue /= fast->RESm;
return(OK);
case RES_LENGTH:
value->rValue = fast->RESlength;
return(OK);
case RES_WIDTH:
value->rValue = fast->RESwidth;
return(OK);
case RES_SCALE:
value->rValue = fast->RESscale;
return(OK);
case RES_M:
value->rValue = fast->RESm;
return(OK);
case RES_TC1:
value->rValue = fast->REStc1;
return(OK);
case RES_TC2:
value->rValue = fast->REStc2;
return(OK);
case RES_NOISY:
value->iValue = fast->RESnoisy;
return(OK);
case RES_QUEST_SENS_DC:
if (ckt->CKTsenInfo) {
value->rValue = *(ckt->CKTsenInfo->SEN_Sap[select->iValue + 1] +
fast->RESsenParmNo);
}
return(OK);
case RES_QUEST_SENS_REAL:
if (ckt->CKTsenInfo) {
value->rValue = *(ckt->CKTsenInfo->SEN_RHS[select->iValue + 1] +
fast->RESsenParmNo);
}
return(OK);
case RES_QUEST_SENS_IMAG:
if (ckt->CKTsenInfo) {
value->rValue = *(ckt->CKTsenInfo->SEN_iRHS[select->iValue + 1] +
fast->RESsenParmNo);
}
return(OK);
case RES_QUEST_SENS_MAG:
if (ckt->CKTsenInfo) {
vr = *(ckt->CKTrhsOld + select->iValue + 1);
vi = *(ckt->CKTirhsOld + select->iValue + 1);
vm = sqrt(vr*vr + vi*vi);
if (vm == 0) {
value->rValue = 0;
return(OK);
}
sr = *(ckt->CKTsenInfo->SEN_RHS[select->iValue + 1] +
fast->RESsenParmNo);
si = *(ckt->CKTsenInfo->SEN_iRHS[select->iValue + 1] +
fast->RESsenParmNo);
value->rValue = (vr * sr + vi * si) / vm;
}
return(OK);
case RES_QUEST_SENS_PH:
if (ckt->CKTsenInfo) {
vr = *(ckt->CKTrhsOld + select->iValue + 1);
vi = *(ckt->CKTirhsOld + select->iValue + 1);
vm = vr*vr + vi*vi;
if (vm == 0) {
value->rValue = 0;
return(OK);
}
sr = *(ckt->CKTsenInfo->SEN_RHS[select->iValue + 1] +
fast->RESsenParmNo);
si = *(ckt->CKTsenInfo->SEN_iRHS[select->iValue + 1] +
fast->RESsenParmNo);
value->rValue = (vr * si - vi * sr) / vm;
}
return(OK);
case RES_QUEST_SENS_CPLX:
if (ckt->CKTsenInfo) {
value->cValue.real=
*(ckt->CKTsenInfo->SEN_RHS[select->iValue + 1] +
fast->RESsenParmNo);
value->cValue.imag=
*(ckt->CKTsenInfo->SEN_iRHS[select->iValue + 1] +
fast->RESsenParmNo);
}
return(OK);
case RES_CURRENT:
if (ckt->CKTcurrentAnalysis & DOING_AC) {
errMsg = TMALLOC(char, strlen(msg) + 1);
errRtn = "RESask";
strcpy(errMsg, msg);
return(E_ASKCURRENT);
} else if (ckt->CKTrhsOld) {
value->rValue = (*(ckt->CKTrhsOld + fast->RESposNode) -
*(ckt->CKTrhsOld + fast->RESnegNode))
*fast->RESconduct;
value->rValue *= fast->RESm;
return(OK);
} else {
char msgloc[BSIZE_SP];
sprintf(msgloc, "No current values available for %s", fast->RESname);
errMsg = TMALLOC(char, strlen(msgloc) + 1);
errRtn = "RESask";
strcpy(errMsg, msgloc);
return(E_ASKCURRENT);
}
case RES_POWER:
if (ckt->CKTcurrentAnalysis & DOING_AC) {
errMsg = TMALLOC(char, strlen(msg) + 1);
errRtn = "RESask";
strcpy(errMsg, msg);
return(E_ASKPOWER);
} else if (ckt->CKTrhsOld) {
value->rValue = (*(ckt->CKTrhsOld + fast->RESposNode) -
*(ckt->CKTrhsOld + fast->RESnegNode)) *
fast->RESconduct *
(*(ckt->CKTrhsOld + fast->RESposNode) -
*(ckt->CKTrhsOld + fast->RESnegNode));
value->rValue *= fast->RESm;
return(OK);
} else {
char msgloc[BSIZE_SP];
sprintf(msgloc, "No power values available for %s", fast->RESname);
errMsg = TMALLOC(char, strlen(msgloc) + 1);
errRtn = "RESask";
strcpy(errMsg, msgloc);
return(E_ASKCURRENT);
}
default:
return(E_BADPARM);
}
/* NOTREACHED */
}