inp.c: agauss in MC with prof. libraries, second part: after subcircuit expansion, replace all agauss occurrencies in b-lines by their respective return value of fcn agauss()

This commit is contained in:
h_vogt 2016-03-11 18:35:47 +01:00 committed by rlar
parent 3bea80a1e4
commit fb61915e1f
1 changed files with 89 additions and 0 deletions

View File

@ -58,6 +58,8 @@ static void dotifeval(struct line *deck);
static wordlist *inp_savecurrents(struct line *deck, struct line *options, wordlist *wl, wordlist *controls);
static void eval_agauss_bsource(struct line *deck);
void line_free_x(struct line *deck, bool recurse);
void create_circbyline(char *line);
@ -671,6 +673,9 @@ inp_spsource(FILE *fp, bool comfile, char *filename, bool intfile)
if (expr_w_temper)
inp_parse_temper(deck, &modtlist, &devtlist);
/* replace agauss(x,y,z) in each b-line by suitable value */
eval_agauss_bsource(deck);
/* If user wants all currents saved (.options savecurrents), add .save
to wl_first with all terminal currents available on selected devices */
wl_first = inp_savecurrents(deck, options, wl_first, controls);
@ -1853,3 +1858,87 @@ inp_savecurrents(struct line *deck, struct line *options, wordlist *wl, wordlist
return wl_append(wl, wl_reverse(p));
}
static double
agauss(double nominal_val, double abs_variation, double sigma)
{
double stdvar;
stdvar = abs_variation / sigma;
return (nominal_val + stdvar * gauss0());
}
/* Second step to enable agauss in professional parameter decks:
* agauss has been preserved by replacement operation of .func
* (function inp_fix_agauss_in_param() in inpcom.c).
* After subcircuit expansion, agauss may be still existing in b-lines,
* however agauss does not exist in the B source parser, and it would
* not make sense in adding it there, because in each time step a different
* return form agauss would result.
* So we have to do the following in each B-line:
* check for agauss(x,y,z), and replace it by a suitable return value
* of agauss()
*/
static void
eval_agauss_bsource(struct line *deck)
{
struct line *card;
double x, y, z, val;
card = deck;
for (; card; card = card->li_next) {
int skip_control = 0;
char *ap, *curr_line = card->li_line;
/* exclude any command inside .control ... .endc */
if (ciprefix(".control", curr_line)) {
skip_control++;
continue;
}
else if (ciprefix(".endc", curr_line)) {
skip_control--;
continue;
}
else if (skip_control > 0) {
continue;
}
if (*curr_line != 'b')
continue;
while ((ap = search_identifier(curr_line, "agauss", curr_line)) != NULL) {
char *lparen, *rparen, *begstr, *contstr = NULL, *new_line, *midstr;
char *tmp1str, *tmp2str, *delstr;
int nerror;
begstr = copy_substring(curr_line, ap);
lparen = strchr(ap, '(');
rparen = strchr(ap, ')');
tmp1str = midstr = copy_substring(lparen + 1, rparen);
if (rparen + 1)
contstr = copy(rparen + 1);
/* find the parameters */
delstr = tmp2str = gettok(&tmp1str);
x = INPevaluate(&tmp2str, &nerror, 1);
tfree(delstr);
delstr = tmp2str = gettok(&tmp1str);
y = INPevaluate(&tmp2str, &nerror, 1);
tfree(delstr);
delstr = tmp2str = gettok(&tmp1str);
z = INPevaluate(&tmp2str, &nerror, 1);
tfree(delstr);
val = agauss(x, y, z);
new_line = tprintf("%s%g%s", begstr, val, contstr);
tfree(card->li_line);
curr_line = card->li_line = new_line;
tfree(begstr);
tfree(contstr);
tfree(midstr);
}
}
}