diff --git a/ChangeLog b/ChangeLog index 9b3dfab03..f87446c2e 100644 --- a/ChangeLog +++ b/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 * 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 diff --git a/src/frontend/inpcom.c b/src/frontend/inpcom.c index ee1aaf2c9..5a3d85980 100644 --- a/src/frontend/inpcom.c +++ b/src/frontend/inpcom.c @@ -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: diff --git a/src/spicelib/devices/asrc/asrc.c b/src/spicelib/devices/asrc/asrc.c index 11404b229..cc13634ff 100644 --- a/src/spicelib/devices/asrc/asrc.c +++ b/src/spicelib/devices/asrc/asrc.c @@ -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"), diff --git a/src/spicelib/devices/asrc/asrcacld.c b/src/spicelib/devices/asrc/asrcacld.c index 5dea71624..40fa798ef 100644 --- a/src/spicelib/devices/asrc/asrcacld.c +++ b/src/spicelib/devices/asrc/asrcacld.c @@ -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 diff --git a/src/spicelib/devices/asrc/asrcdefs.h b/src/spicelib/devices/asrc/asrcdefs.h index a5419cc69..f50142b50 100644 --- a/src/spicelib/devices/asrc/asrcdefs.h +++ b/src/spicelib/devices/asrc/asrcdefs.h @@ -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 */ diff --git a/src/spicelib/devices/asrc/asrcload.c b/src/spicelib/devices/asrc/asrcload.c index 692b3abac..0bf7f4324 100644 --- a/src/spicelib/devices/asrc/asrcload.c +++ b/src/spicelib/devices/asrc/asrcload.c @@ -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 diff --git a/src/spicelib/devices/asrc/asrcpar.c b/src/spicelib/devices/asrc/asrcpar.c index e317830ad..3ac664ecb 100644 --- a/src/spicelib/devices/asrc/asrcpar.c +++ b/src/spicelib/devices/asrc/asrcpar.c @@ -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); } diff --git a/src/spicelib/devices/asrc/asrcpzld.c b/src/spicelib/devices/asrc/asrcpzld.c index 1f1a64155..395851058 100644 --- a/src/spicelib/devices/asrc/asrcpzld.c +++ b/src/spicelib/devices/asrc/asrcpzld.c @@ -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; diff --git a/src/spicelib/devices/asrc/asrcset.c b/src/spicelib/devices/asrc/asrcset.c index 5203dba9f..8f4fb22a0 100644 --- a/src/spicelib/devices/asrc/asrcset.c +++ b/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 ; 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;