Browse Source

Add reciprocal temperature behaviour for B sources

dwarning 14 years ago
parent
commit
70e9907415
  1. 6
      ChangeLog
  2. 102
      src/frontend/inpcom.c
  3. 1
      src/spicelib/devices/asrc/asrc.c
  4. 6
      src/spicelib/devices/asrc/asrcacld.c
  5. 4
      src/spicelib/devices/asrc/asrcdefs.h
  6. 6
      src/spicelib/devices/asrc/asrcload.c
  7. 4
      src/spicelib/devices/asrc/asrcpar.c
  8. 6
      src/spicelib/devices/asrc/asrcpzld.c
  9. 4
      src/spicelib/devices/asrc/asrcset.c

6
ChangeLog

@ -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 2012-02-19 Holger Vogt
* com_cdump.c, com_cdump.h, commands.c, smpdefs.h, spoutput.c, spsmp.c, * 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 command mrdump to dump the RHS of the matrix to stdout or to a file

102
src/frontend/inpcom.c

@ -3891,6 +3891,9 @@ static void inp_compat(struct line *deck)
struct line *card; struct line *card;
int skip_control = 0; 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) { for (card = deck; card; card = card->li_next) {
char *curr_line = card->li_line; 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); fprintf(stderr,"ERROR: mal formed R line: %s\n", curr_line);
controlled_exit(EXIT_FAILURE); 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);
}
if ((tc1_ptr == NULL) && (tc2_ptr == NULL)) {
xlen = strlen(title_tok) + strlen(node1) + strlen(node2) + xlen = strlen(title_tok) + strlen(node1) + strlen(node2) +
strlen(node1) + strlen(node2) + strlen(str_ptr) +
strlen(node1) + strlen(node2) + strlen(equation) +
28 - 6*2 + 1; 28 - 6*2 + 1;
xline = TMALLOC(char, xlen); xline = TMALLOC(char, xlen);
sprintf(xline, "b%s %s %s i = v(%s, %s)/(%s)", title_tok, node1, node2, sprintf(xline, "b%s %s %s i = v(%s, %s)/(%s)", title_tok, node1, node2,
node1, node2, str_ptr);
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 = alloc(struct line);
new_line->li_next = NULL; new_line->li_next = NULL;
new_line->li_error = 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); fprintf(stderr,"ERROR: mal formed C line: %s\n",curr_line);
controlled_exit(EXIT_FAILURE); 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 // Exxx n-aux 0 n1 n2 1
xlen = 2*strlen(title_tok) + strlen(node1) + strlen(node2) xlen = 2*strlen(title_tok) + strlen(node1) + strlen(node2)
+ 21 - 4*2 + 1; + 21 - 4*2 + 1;
@ -4349,12 +4392,27 @@ static void inp_compat(struct line *deck)
ckt_array[1] = TMALLOC(char, xlen); ckt_array[1] = TMALLOC(char, xlen);
sprintf(ckt_array[1], "c%s %s_int2 0 1", title_tok, title_tok); sprintf(ckt_array[1], "c%s %s_int2 0 1", title_tok, title_tok);
// Bxxx n2 n1 I = i(Exxx) * equation // Bxxx n2 n1 I = i(Exxx) * equation
if ((tc1_ptr == NULL) && (tc2_ptr == NULL)) {
xlen = 2*strlen(title_tok) + strlen(node2) + strlen(node1) xlen = 2*strlen(title_tok) + strlen(node2) + strlen(node1)
+ strlen(str_ptr) + 27 - 2*5 + 1;
+ strlen(equation) + 27 - 2*5 + 1;
ckt_array[2] = TMALLOC(char, xlen); ckt_array[2] = TMALLOC(char, xlen);
sprintf(ckt_array[2], "b%s %s %s i = i(e%s) * (%s)", sprintf(ckt_array[2], "b%s %s %s i = i(e%s) * (%s)",
title_tok, node2, node1, title_tok, str_ptr);
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 // insert new B source line immediately after current line
tmp_ptr = card->li_next; tmp_ptr = card->li_next;
for ( i = 0; i < 3; i++ ) { 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); fprintf(stderr,"ERROR: mal formed L line: %s\n", curr_line);
controlled_exit(EXIT_FAILURE); 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 // Fxxx n-aux 0 Bxxx 1
xlen = 3*strlen(title_tok) xlen = 3*strlen(title_tok)
+ 20 - 3*2 + 1; + 20 - 3*2 + 1;
@ -4414,12 +4483,27 @@ static void inp_compat(struct line *deck)
ckt_array[1] = TMALLOC(char, xlen); ckt_array[1] = TMALLOC(char, xlen);
sprintf(ckt_array[1], "l%s %s_int2 0 1", title_tok, title_tok); sprintf(ckt_array[1], "l%s %s_int2 0 1", title_tok, title_tok);
// Bxxx n1 n2 V = v(n-aux) * equation // Bxxx n1 n2 V = v(n-aux) * equation
if ((tc1_ptr == NULL) && (tc2_ptr == NULL)) {
xlen = 2*strlen(title_tok) + strlen(node2) + strlen(node1) xlen = 2*strlen(title_tok) + strlen(node2) + strlen(node1)
+ strlen(str_ptr) + 31 - 2*5 + 1;
+ strlen(equation) + 31 - 2*5 + 1;
ckt_array[2] = TMALLOC(char, xlen); ckt_array[2] = TMALLOC(char, xlen);
sprintf(ckt_array[2], "b%s %s %s v = v(%s_int2) * (%s)", sprintf(ckt_array[2], "b%s %s %s v = v(%s_int2) * (%s)",
title_tok, node1, node2, title_tok, str_ptr);
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 // insert new B source line immediately after current line
tmp_ptr = card->li_next; tmp_ptr = card->li_next;
for ( i = 0; i < 3; i++ ) { 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") if ((*str_ptr == '(') || cieq(buf, "hertz") || cieq(buf, "temper")
|| cieq(buf, "time") || cieq(buf, "pi") || cieq(buf, "e") || cieq(buf, "time") || cieq(buf, "pi") || cieq(buf, "e")
|| cieq(buf, "pwl") || 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: /* special handling of pwl lines:
Put braces around tokens and around expressions, use ',' Put braces around tokens and around expressions, use ','
as separator like: as separator like:

1
src/spicelib/devices/asrc/asrc.c

@ -18,6 +18,7 @@ IFparm ASRCpTable[] = { /* parameters */
"Instance temperature difference with the rest of the circuit"), "Instance temperature difference with the rest of the circuit"),
IOPU( "tc1", ASRC_TC1, IF_REAL, "First order temp. coefficient"), IOPU( "tc1", ASRC_TC1, IF_REAL, "First order temp. coefficient"),
IOPU( "tc2", ASRC_TC2, IF_REAL, "Second 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( "i", ASRC_OUTPUTCURRENT, IF_REAL, "Current through source"),
OP( "v", ASRC_OUTPUTVOLTAGE, IF_REAL, "Voltage across source"), OP( "v", ASRC_OUTPUTVOLTAGE, IF_REAL, "Voltage across source"),
OP( "pos_node", ASRC_POS_NODE, IF_INTEGER, "Positive Node"), OP( "pos_node", ASRC_POS_NODE, IF_INTEGER, "Positive Node"),

6
src/spicelib/devices/asrc/asrcacld.c

@ -44,12 +44,12 @@ ASRCacLoad(GENmodel *inModel, CKTcircuit *ckt)
if (here->ASRCowner != ARCHme) if (here->ASRCowner != ARCHme)
continue; continue;
if(!here->ASRCtc1Given) here->ASRCtc1 = 0.0;
if(!here->ASRCtc2Given) here->ASRCtc2 = 0.0;
difference = (here->ASRCtemp + here->ASRCdtemp) - 300.15; difference = (here->ASRCtemp + here->ASRCdtemp) - 300.15;
factor = 1.0 + (here->ASRCtc1)*difference + 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 * Get the function and its derivatives from the

4
src/spicelib/devices/asrc/asrcdefs.h

@ -32,6 +32,7 @@ typedef struct sASRCinstance {
double ASRCdtemp; /* delta-temperature of a particular instance */ double ASRCdtemp; /* delta-temperature of a particular instance */
double ASRCtc1; /* first temperature coefficient of resistors */ double ASRCtc1; /* first temperature coefficient of resistors */
double ASRCtc2; /* second 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 double **ASRCposptr; /* pointer to pointers of the elements
* in the sparce matrix */ * in the sparce matrix */
double ASRCprev_value; /* Previous value for the convergence test */ double ASRCprev_value; /* Previous value for the convergence test */
@ -41,7 +42,7 @@ typedef struct sASRCinstance {
unsigned ASRCdtempGiven : 1; /* indicates delta-temp specified */ unsigned ASRCdtempGiven : 1; /* indicates delta-temp specified */
unsigned ASRCtc1Given : 1; /* indicates tc1 parameter specified */ unsigned ASRCtc1Given : 1; /* indicates tc1 parameter specified */
unsigned ASRCtc2Given : 1; /* indicates tc2 parameter specified */ unsigned ASRCtc2Given : 1; /* indicates tc2 parameter specified */
unsigned ASRCreciproctcGiven : 1; /* indicates reciproctc flag parameter specified */
} ASRCinstance ; } ASRCinstance ;
#define ASRCvOld ASRCstates #define ASRCvOld ASRCstates
@ -70,6 +71,7 @@ typedef struct sASRCmodel { /* model structure for a source */
#define ASRC_DTEMP 9 #define ASRC_DTEMP 9
#define ASRC_TC1 10 #define ASRC_TC1 10
#define ASRC_TC2 11 #define ASRC_TC2 11
#define ASRC_RTC 12
/* module-wide variables */ /* module-wide variables */

6
src/spicelib/devices/asrc/asrcload.c

@ -41,11 +41,11 @@ ASRCload(GENmodel *inModel, CKTcircuit *ckt)
if (here->ASRCowner != ARCHme) if (here->ASRCowner != ARCHme)
continue; continue;
if(!here->ASRCtc1Given) here->ASRCtc1 = 0.0;
if(!here->ASRCtc2Given) here->ASRCtc2 = 0.0;
difference = (here->ASRCtemp + here->ASRCdtemp) - 300.15; difference = (here->ASRCtemp + here->ASRCdtemp) - 300.15;
factor = 1.0 + (here->ASRCtc1)*difference + (here->ASRCtc2)*difference*difference; factor = 1.0 + (here->ASRCtc1)*difference + (here->ASRCtc2)*difference*difference;
if(here->ASRCreciproctc == 1) {
factor = 1/factor;
}
/* /*
* Get the function and its derivatives evaluated * Get the function and its derivatives evaluated

4
src/spicelib/devices/asrc/asrcpar.c

@ -38,6 +38,10 @@ ASRCparam(int param, IFvalue *value, GENinstance *fast, IFvalue *select)
here->ASRCtc2 = value->rValue; here->ASRCtc2 = value->rValue;
here->ASRCtc2Given = TRUE; here->ASRCtc2Given = TRUE;
break; break;
case ASRC_RTC:
here->ASRCreciproctc = value->iValue;
here->ASRCreciproctcGiven = TRUE;
break;
default: default:
return(E_BADPARM); return(E_BADPARM);
} }

6
src/spicelib/devices/asrc/asrcpzld.c

@ -37,12 +37,12 @@ ASRCpzLoad(GENmodel *inModel, CKTcircuit *ckt, SPcomplex *s)
if (here->ASRCowner != ARCHme) if (here->ASRCowner != ARCHme)
continue; continue;
if(!here->ASRCtc1Given) here->ASRCtc1 = 0.0;
if(!here->ASRCtc2Given) here->ASRCtc2 = 0.0;
difference = (here->ASRCtemp + here->ASRCdtemp) - 300.15; difference = (here->ASRCtemp + here->ASRCdtemp) - 300.15;
factor = 1.0 + (here->ASRCtc1)*difference + factor = 1.0 + (here->ASRCtc1)*difference +
(here->ASRCtc2)*difference*difference; (here->ASRCtc2)*difference*difference;
if(here->ASRCreciproctc == 1) {
factor = 1/factor;
}
j = 0; j = 0;

4
src/spicelib/devices/asrc/asrcset.c

@ -36,6 +36,10 @@ ASRCsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states)
for (here = model->ASRCinstances; here != NULL ; for (here = model->ASRCinstances; here != NULL ;
here=here->ASRCnextInstance) { 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; here->ASRCposptr = NULL;
j=0; /*strchr of the array holding ptrs to SMP */ j=0; /*strchr of the array holding ptrs to SMP */
v_first = 1; v_first = 1;

Loading…
Cancel
Save