Add reciprocal temperature behaviour for B sources
This commit is contained in:
parent
8f3f757813
commit
70e9907415
|
|
@ -1,3 +1,9 @@
|
|||
2012-02-19 Dietmar Warning
|
||||
* src/spicelib/devices/asrc/*.c,*.h
|
||||
* src/frontend/inpcom.c,
|
||||
Add reciprocal temperature behaviour for B sources used for nonlinear
|
||||
resistors, capacitors and inductors (the latter non-reciprocal)
|
||||
|
||||
2012-02-19 Holger Vogt
|
||||
* com_cdump.c, com_cdump.h, commands.c, smpdefs.h, spoutput.c, spsmp.c,
|
||||
command mrdump to dump the RHS of the matrix to stdout or to a file
|
||||
|
|
|
|||
|
|
@ -3891,6 +3891,9 @@ static void inp_compat(struct line *deck)
|
|||
struct line *card;
|
||||
int skip_control = 0;
|
||||
|
||||
char *equation, *tc1_ptr=NULL, *tc2_ptr=NULL;
|
||||
double tc1=0.0, tc2=0.0;
|
||||
|
||||
for (card = deck; card; card = card->li_next) {
|
||||
|
||||
char *curr_line = card->li_line;
|
||||
|
|
@ -4296,12 +4299,41 @@ static void inp_compat(struct line *deck)
|
|||
fprintf(stderr,"ERROR: mal formed R line: %s\n", curr_line);
|
||||
controlled_exit(EXIT_FAILURE);
|
||||
}
|
||||
xlen = strlen(title_tok) + strlen(node1) + strlen(node2) +
|
||||
strlen(node1) + strlen(node2) + strlen(str_ptr) +
|
||||
28 - 6*2 + 1;
|
||||
xline = TMALLOC(char, xlen);
|
||||
sprintf(xline, "b%s %s %s i = v(%s, %s)/(%s)", title_tok, node1, node2,
|
||||
node1, node2, str_ptr);
|
||||
equation = gettok(&str_ptr);
|
||||
str_ptr = strstr(cut_line, "tc1");
|
||||
if (str_ptr) {
|
||||
tc1_ptr = strstr(str_ptr, "=");
|
||||
tc1 = atof(tc1_ptr+1);
|
||||
}
|
||||
str_ptr = strstr(cut_line, "tc2");
|
||||
if (str_ptr) {
|
||||
tc2_ptr = strstr(str_ptr, "=");
|
||||
tc2 = atof(tc2_ptr+1);
|
||||
}
|
||||
if ((tc1_ptr == NULL) && (tc2_ptr == NULL)) {
|
||||
xlen = strlen(title_tok) + strlen(node1) + strlen(node2) +
|
||||
strlen(node1) + strlen(node2) + strlen(equation) +
|
||||
28 - 6*2 + 1;
|
||||
xline = TMALLOC(char, xlen);
|
||||
sprintf(xline, "b%s %s %s i = v(%s, %s)/(%s)", title_tok, node1, node2,
|
||||
node1, node2, equation);
|
||||
} else if (tc2_ptr == NULL) {
|
||||
xlen = strlen(title_tok) + strlen(node1) + strlen(node2) +
|
||||
strlen(node1) + strlen(node2) + strlen(equation) +
|
||||
28 - 6*2 + 1 + 21 + 13;
|
||||
xline = TMALLOC(char, xlen);
|
||||
sprintf(xline, "b%s %s %s i = v(%s, %s)/(%s) tc1=%15.8e reciproctc=1", title_tok, node1, node2,
|
||||
node1, node2, equation, tc1);
|
||||
} else {
|
||||
xlen = strlen(title_tok) + strlen(node1) + strlen(node2) +
|
||||
strlen(node1) + strlen(node2) + strlen(equation) +
|
||||
28 - 6*2 + 1 + 21 + 21 + 13;
|
||||
xline = TMALLOC(char, xlen);
|
||||
sprintf(xline, "b%s %s %s i = v(%s, %s)/(%s) tc1=%15.8e tc2=%15.8e reciproctc=1", title_tok, node1, node2,
|
||||
node1, node2, equation, tc1, tc2);
|
||||
}
|
||||
tc1_ptr = NULL;
|
||||
tc2_ptr = NULL;
|
||||
new_line = alloc(struct line);
|
||||
new_line->li_next = NULL;
|
||||
new_line->li_error = NULL;
|
||||
|
|
@ -4337,6 +4369,17 @@ static void inp_compat(struct line *deck)
|
|||
fprintf(stderr,"ERROR: mal formed C line: %s\n",curr_line);
|
||||
controlled_exit(EXIT_FAILURE);
|
||||
}
|
||||
equation = gettok(&str_ptr);
|
||||
str_ptr = strstr(cut_line, "tc1");
|
||||
if (str_ptr) {
|
||||
tc1_ptr = strstr(str_ptr, "=");
|
||||
tc1 = atof(tc1_ptr+1);
|
||||
}
|
||||
str_ptr = strstr(cut_line, "tc2");
|
||||
if (str_ptr) {
|
||||
tc2_ptr = strstr(str_ptr, "=");
|
||||
tc2 = atof(tc2_ptr+1);
|
||||
}
|
||||
// Exxx n-aux 0 n1 n2 1
|
||||
xlen = 2*strlen(title_tok) + strlen(node1) + strlen(node2)
|
||||
+ 21 - 4*2 + 1;
|
||||
|
|
@ -4349,12 +4392,27 @@ static void inp_compat(struct line *deck)
|
|||
ckt_array[1] = TMALLOC(char, xlen);
|
||||
sprintf(ckt_array[1], "c%s %s_int2 0 1", title_tok, title_tok);
|
||||
// Bxxx n2 n1 I = i(Exxx) * equation
|
||||
xlen = 2*strlen(title_tok) + strlen(node2) + strlen(node1)
|
||||
+ strlen(str_ptr) + 27 - 2*5 + 1;
|
||||
ckt_array[2] = TMALLOC(char, xlen);
|
||||
sprintf(ckt_array[2], "b%s %s %s i = i(e%s) * (%s)",
|
||||
title_tok, node2, node1, title_tok, str_ptr);
|
||||
|
||||
if ((tc1_ptr == NULL) && (tc2_ptr == NULL)) {
|
||||
xlen = 2*strlen(title_tok) + strlen(node2) + strlen(node1)
|
||||
+ strlen(equation) + 27 - 2*5 + 1;
|
||||
ckt_array[2] = TMALLOC(char, xlen);
|
||||
sprintf(ckt_array[2], "b%s %s %s i = i(e%s) * (%s)",
|
||||
title_tok, node2, node1, title_tok, equation);
|
||||
} else if (tc2_ptr == NULL) {
|
||||
xlen = 2*strlen(title_tok) + strlen(node2) + strlen(node1)
|
||||
+ strlen(equation) + 27 - 2*5 + 1 + 21 + 13;
|
||||
ckt_array[2] = TMALLOC(char, xlen);
|
||||
sprintf(ckt_array[2], "b%s %s %s i = i(e%s) * (%s) tc1=%15.8e reciproctc=1",
|
||||
title_tok, node2, node1, title_tok, equation, tc1);
|
||||
} else {
|
||||
xlen = 2*strlen(title_tok) + strlen(node2) + strlen(node1)
|
||||
+ strlen(equation) + 27 - 2*5 + 1 + 21 + 21 + 13;
|
||||
ckt_array[2] = TMALLOC(char, xlen);
|
||||
sprintf(ckt_array[2], "b%s %s %s i = i(e%s) * (%s) tc1=%15.8e tc2=%15.8e reciproctc=1",
|
||||
title_tok, node2, node1, title_tok, equation, tc1, tc2);
|
||||
}
|
||||
tc1_ptr = NULL;
|
||||
tc2_ptr = NULL;
|
||||
// insert new B source line immediately after current line
|
||||
tmp_ptr = card->li_next;
|
||||
for ( i = 0; i < 3; i++ ) {
|
||||
|
|
@ -4402,6 +4460,17 @@ static void inp_compat(struct line *deck)
|
|||
fprintf(stderr,"ERROR: mal formed L line: %s\n", curr_line);
|
||||
controlled_exit(EXIT_FAILURE);
|
||||
}
|
||||
equation = gettok(&str_ptr);
|
||||
str_ptr = strstr(cut_line, "tc1");
|
||||
if (str_ptr) {
|
||||
tc1_ptr = strstr(str_ptr, "=");
|
||||
tc1 = atof(tc1_ptr+1);
|
||||
}
|
||||
str_ptr = strstr(cut_line, "tc2");
|
||||
if (str_ptr) {
|
||||
tc2_ptr = strstr(str_ptr, "=");
|
||||
tc2 = atof(tc2_ptr+1);
|
||||
}
|
||||
// Fxxx n-aux 0 Bxxx 1
|
||||
xlen = 3*strlen(title_tok)
|
||||
+ 20 - 3*2 + 1;
|
||||
|
|
@ -4414,12 +4483,27 @@ static void inp_compat(struct line *deck)
|
|||
ckt_array[1] = TMALLOC(char, xlen);
|
||||
sprintf(ckt_array[1], "l%s %s_int2 0 1", title_tok, title_tok);
|
||||
// Bxxx n1 n2 V = v(n-aux) * equation
|
||||
xlen = 2*strlen(title_tok) + strlen(node2) + strlen(node1)
|
||||
+ strlen(str_ptr) + 31 - 2*5 + 1;
|
||||
ckt_array[2] = TMALLOC(char, xlen);
|
||||
sprintf(ckt_array[2], "b%s %s %s v = v(%s_int2) * (%s)",
|
||||
title_tok, node1, node2, title_tok, str_ptr);
|
||||
|
||||
if ((tc1_ptr == NULL) && (tc2_ptr == NULL)) {
|
||||
xlen = 2*strlen(title_tok) + strlen(node2) + strlen(node1)
|
||||
+ strlen(equation) + 31 - 2*5 + 1;
|
||||
ckt_array[2] = TMALLOC(char, xlen);
|
||||
sprintf(ckt_array[2], "b%s %s %s v = v(%s_int2) * (%s)",
|
||||
title_tok, node1, node2, title_tok, equation);
|
||||
} else if (tc2_ptr == NULL) {
|
||||
xlen = 2*strlen(title_tok) + strlen(node2) + strlen(node1)
|
||||
+ strlen(equation) + 31 - 2*5 + 1 + 21 + 13;
|
||||
ckt_array[2] = TMALLOC(char, xlen);
|
||||
sprintf(ckt_array[2], "b%s %s %s v = v(%s_int2) * (%s) tc1=%15.8e reciproctc=0",
|
||||
title_tok, node2, node1, title_tok, equation, tc1);
|
||||
} else {
|
||||
xlen = 2*strlen(title_tok) + strlen(node2) + strlen(node1)
|
||||
+ strlen(equation) + 31 - 2*5 + 1 + 21 + 21 + 13;
|
||||
ckt_array[2] = TMALLOC(char, xlen);
|
||||
sprintf(ckt_array[2], "b%s %s %s v = v(%s_int2) * (%s) tc1=%15.8e tc2=%15.8e reciproctc=0",
|
||||
title_tok, node2, node1, title_tok, equation, tc1, tc2);
|
||||
}
|
||||
tc1_ptr = NULL;
|
||||
tc2_ptr = NULL;
|
||||
// insert new B source line immediately after current line
|
||||
tmp_ptr = card->li_next;
|
||||
for ( i = 0; i < 3; i++ ) {
|
||||
|
|
@ -4875,7 +4959,7 @@ static void inp_bsource_compat(struct line *deck)
|
|||
if ((*str_ptr == '(') || cieq(buf, "hertz") || cieq(buf, "temper")
|
||||
|| cieq(buf, "time") || cieq(buf, "pi") || cieq(buf, "e")
|
||||
|| cieq(buf, "pwl")
|
||||
|| cieq(buf, "tc") || cieq(buf, "tc1") || cieq(buf, "tc2")) {
|
||||
|| cieq(buf, "tc1") || cieq(buf, "tc2") || cieq(buf, "reciproctc")) {
|
||||
/* special handling of pwl lines:
|
||||
Put braces around tokens and around expressions, use ','
|
||||
as separator like:
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ IFparm ASRCpTable[] = { /* parameters */
|
|||
"Instance temperature difference with the rest of the circuit"),
|
||||
IOPU( "tc1", ASRC_TC1, IF_REAL, "First order temp. coefficient"),
|
||||
IOPU( "tc2", ASRC_TC2, IF_REAL, "Second order temp. coefficient"),
|
||||
IOPU( "reciproctc", ASRC_RTC, IF_INTEGER, "Flag to calculate reciprocal temperature behaviour"),
|
||||
OP( "i", ASRC_OUTPUTCURRENT, IF_REAL, "Current through source"),
|
||||
OP( "v", ASRC_OUTPUTVOLTAGE, IF_REAL, "Voltage across source"),
|
||||
OP( "pos_node", ASRC_POS_NODE, IF_INTEGER, "Positive Node"),
|
||||
|
|
|
|||
|
|
@ -44,12 +44,12 @@ ASRCacLoad(GENmodel *inModel, CKTcircuit *ckt)
|
|||
if (here->ASRCowner != ARCHme)
|
||||
continue;
|
||||
|
||||
if(!here->ASRCtc1Given) here->ASRCtc1 = 0.0;
|
||||
if(!here->ASRCtc2Given) here->ASRCtc2 = 0.0;
|
||||
|
||||
difference = (here->ASRCtemp + here->ASRCdtemp) - 300.15;
|
||||
factor = 1.0 + (here->ASRCtc1)*difference +
|
||||
(here->ASRCtc2)*difference*difference;
|
||||
(here->ASRCtc2)*difference*difference;
|
||||
if(here->ASRCreciproctc == 1) {
|
||||
factor = 1/factor;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the function and its derivatives from the
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ typedef struct sASRCinstance {
|
|||
double ASRCdtemp; /* delta-temperature of a particular instance */
|
||||
double ASRCtc1; /* first temperature coefficient of resistors */
|
||||
double ASRCtc2; /* second temperature coefficient of resistors */
|
||||
int ASRCreciproctc; /* Flag to calculate reciprocal temperature behaviour */
|
||||
double **ASRCposptr; /* pointer to pointers of the elements
|
||||
* in the sparce matrix */
|
||||
double ASRCprev_value; /* Previous value for the convergence test */
|
||||
|
|
@ -41,7 +42,7 @@ typedef struct sASRCinstance {
|
|||
unsigned ASRCdtempGiven : 1; /* indicates delta-temp specified */
|
||||
unsigned ASRCtc1Given : 1; /* indicates tc1 parameter specified */
|
||||
unsigned ASRCtc2Given : 1; /* indicates tc2 parameter specified */
|
||||
|
||||
unsigned ASRCreciproctcGiven : 1; /* indicates reciproctc flag parameter specified */
|
||||
} ASRCinstance ;
|
||||
|
||||
#define ASRCvOld ASRCstates
|
||||
|
|
@ -70,6 +71,7 @@ typedef struct sASRCmodel { /* model structure for a source */
|
|||
#define ASRC_DTEMP 9
|
||||
#define ASRC_TC1 10
|
||||
#define ASRC_TC2 11
|
||||
#define ASRC_RTC 12
|
||||
|
||||
/* module-wide variables */
|
||||
|
||||
|
|
|
|||
|
|
@ -41,11 +41,11 @@ ASRCload(GENmodel *inModel, CKTcircuit *ckt)
|
|||
if (here->ASRCowner != ARCHme)
|
||||
continue;
|
||||
|
||||
if(!here->ASRCtc1Given) here->ASRCtc1 = 0.0;
|
||||
if(!here->ASRCtc2Given) here->ASRCtc2 = 0.0;
|
||||
|
||||
difference = (here->ASRCtemp + here->ASRCdtemp) - 300.15;
|
||||
factor = 1.0 + (here->ASRCtc1)*difference + (here->ASRCtc2)*difference*difference;
|
||||
if(here->ASRCreciproctc == 1) {
|
||||
factor = 1/factor;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the function and its derivatives evaluated
|
||||
|
|
|
|||
|
|
@ -38,6 +38,10 @@ ASRCparam(int param, IFvalue *value, GENinstance *fast, IFvalue *select)
|
|||
here->ASRCtc2 = value->rValue;
|
||||
here->ASRCtc2Given = TRUE;
|
||||
break;
|
||||
case ASRC_RTC:
|
||||
here->ASRCreciproctc = value->iValue;
|
||||
here->ASRCreciproctcGiven = TRUE;
|
||||
break;
|
||||
default:
|
||||
return(E_BADPARM);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,12 +37,12 @@ ASRCpzLoad(GENmodel *inModel, CKTcircuit *ckt, SPcomplex *s)
|
|||
if (here->ASRCowner != ARCHme)
|
||||
continue;
|
||||
|
||||
if(!here->ASRCtc1Given) here->ASRCtc1 = 0.0;
|
||||
if(!here->ASRCtc2Given) here->ASRCtc2 = 0.0;
|
||||
|
||||
difference = (here->ASRCtemp + here->ASRCdtemp) - 300.15;
|
||||
factor = 1.0 + (here->ASRCtc1)*difference +
|
||||
(here->ASRCtc2)*difference*difference;
|
||||
(here->ASRCtc2)*difference*difference;
|
||||
if(here->ASRCreciproctc == 1) {
|
||||
factor = 1/factor;
|
||||
}
|
||||
|
||||
j = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -36,6 +36,10 @@ ASRCsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states)
|
|||
for (here = model->ASRCinstances; here != NULL ;
|
||||
here=here->ASRCnextInstance) {
|
||||
|
||||
if(!here->ASRCtc1Given) here->ASRCtc1 = 0.0;
|
||||
if(!here->ASRCtc2Given) here->ASRCtc2 = 0.0;
|
||||
if(!here->ASRCreciproctcGiven) here->ASRCreciproctc = 0;
|
||||
|
||||
here->ASRCposptr = NULL;
|
||||
j=0; /*strchr of the array holding ptrs to SMP */
|
||||
v_first = 1;
|
||||
|
|
|
|||
Loading…
Reference in New Issue