ngspice/src/frontend/shyu.c

361 lines
12 KiB
C
Raw Normal View History

2000-04-27 22:03:57 +02:00
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
**********/
/* Do a run of the circuit, of the given type. Type "resume" is special --
* it means to resume whatever simulation that was in progress. The
* return value of this routine is 0 if the exit was ok, and 1 if there was
* a reason to interrupt the circuit (interrupt typed at the keyboard,
* error in the simulation, etc). args should be the entire command line,
* e.g. "tran 1 10 20 uic"
*/
#include "ngspice/ngspice.h"
#include "ngspice/cpdefs.h"
#include "ngspice/ftedefs.h"
#include "ngspice/fteinp.h"
#include "ngspice/sim.h"
#include "ngspice/devdefs.h"
#include "ngspice/inpdefs.h"
#include "ngspice/iferrmsg.h"
#include "ngspice/ifsim.h"
src/Makefile.am src/help.c src/main.c src/circuit/Makefile.am src/circuit/ifnewuid.c src/frontend/Makefile.am src/frontend/aspice.c src/frontend/circuits.h src/frontend/com_display.c src/frontend/com_hardcopy.c src/frontend/commands.c src/frontend/commands.h src/frontend/cpitf.c src/frontend/debugcom.c src/frontend/device.c src/frontend/diff.c src/frontend/display.c src/frontend/dotcards.c src/frontend/fourier.c src/frontend/inp.c src/frontend/inpcom.c src/frontend/linear.c src/frontend/misccoms.c src/frontend/mw_coms.c src/frontend/nutinp.c src/frontend/options.c src/frontend/outitf.c src/frontend/parse.c src/frontend/postcoms.c src/frontend/postsc.c src/frontend/rawfile.c src/frontend/resource.c src/frontend/runcoms.c src/frontend/runcoms2.c src/frontend/shyu.c src/frontend/spec.c src/frontend/spiceif.c src/frontend/subckt.c src/frontend/vectors.c src/frontend/where.c src/frontend/plotting/Makefile.am src/frontend/plotting/agraf.c src/frontend/plotting/graf.c src/frontend/plotting/plotcurv.c src/frontend/plotting/plotit.c src/frontend/plotting/x11.c src/frontend/plotting/xgraph.c src/include/Makefile.am src/maths/cmaths/cmath4.c src/misc/terminal.c src/misc/terminal.h src/parser/cshpar.c src/parser/front.c src/parser/front.h src/parser/history.c src/parser/history.h src/parser/modify.c src/parser/var2.c src/parser/var2.h src/parser/variable.c: Refactoring of frontend code. * src/include/ftehelp.h src/include/variable.h: Moved into frontend directory. * src/include/cpdefs.h src/include/cpextern.h src/include/ftedefs.h src/include/plot.h: Updates.
2000-06-27 18:09:02 +02:00
#include "circuits.h"
2000-04-27 22:03:57 +02:00
#include "shyu.h"
int
2011-05-08 14:52:58 +02:00
if_sens_run(CKTcircuit *ckt, wordlist *args, INPtables *tab)
2000-04-27 22:03:57 +02:00
{
JOB *senseJob;
JOB *opJob;
2000-04-27 22:03:57 +02:00
card *current;
IFvalue ptemp;
IFvalue *parm;
char buf[BSIZE_SP];
int err;
char *token;
char *steptype;
char *name;
char *line;
2011-08-07 12:00:45 +02:00
card deck;
2000-04-27 22:03:57 +02:00
int error;
int save;
2000-04-27 22:03:57 +02:00
int flag = 0;
int which = -1;
(void) sprintf(buf, ".%s", wl_flatten(args));
2011-08-07 12:00:45 +02:00
2012-08-15 19:00:31 +02:00
deck.nextcard = NULL;
deck.actualLine = NULL;
deck.error = NULL;
deck.linenum = 0;
deck.linenum_orig = 0;
deck.line = buf;
2000-04-27 22:03:57 +02:00
2004-08-16 23:05:42 +02:00
current = (card *) &deck;
2000-04-27 22:03:57 +02:00
line = current->line;
2012-08-15 19:00:31 +02:00
INPgetTok(&line, &token, 1);
2000-04-27 22:03:57 +02:00
2012-08-15 19:00:31 +02:00
if (ft_curckt->ci_specTask) {
err = ft_sim->deleteTask (ft_curckt->ci_ckt, ft_curckt->ci_specTask);
if (err) {
ft_sperror(err, "deleteTask");
return (0); /* temporary */
2000-04-27 22:03:57 +02:00
}
}
2012-08-15 19:00:31 +02:00
err = ft_sim->newTask (ft_curckt->ci_ckt, &(ft_curckt->ci_specTask),
"special", & (ft_curckt->ci_defTask));
if (err) {
ft_sperror(err, "newTask");
return (0); /* temporary */
2000-04-27 22:03:57 +02:00
}
2012-08-15 19:00:31 +02:00
which = ft_find_analysis("options");
2012-08-15 19:00:31 +02:00
if (which == -1) {
/* in DEEP trouble */
ft_sperror(err, "in DEEP trouble");
return (0); /* temporary */
}
2012-08-15 19:00:31 +02:00
err = ft_sim->newAnalysis (ft_curckt->ci_ckt, which, "options",
2012-08-15 19:00:31 +02:00
& (ft_curckt->ci_specOpt), ft_curckt->ci_specTask);
if (err) {
ft_sperror(err, "createOptions");
return (0); /* temporary */
2000-04-27 22:03:57 +02:00
}
2012-08-15 19:00:31 +02:00
ft_curckt->ci_curOpt = ft_curckt->ci_specOpt;
2000-04-27 22:03:57 +02:00
ft_curckt->ci_curTask = ft_curckt->ci_specTask;
2012-08-15 19:00:31 +02:00
which = ft_find_analysis("SEN");
2012-08-15 19:00:31 +02:00
if (which == -1) {
current->error = INPerrCat(
current->error,
INPmkTemp("sensetivity analysis unsupported\n"));
return (0);
2000-04-27 22:03:57 +02:00
}
2012-08-15 19:00:31 +02:00
err = ft_sim->newAnalysis (ft_curckt->ci_ckt, which, "sense",
& senseJob, ft_curckt->ci_specTask);
2012-08-15 19:00:31 +02:00
if (err) {
ft_sperror(err, "createSense");
return (0); /* temporary */
}
2012-08-15 19:00:31 +02:00
2000-04-27 22:03:57 +02:00
save = which;
2012-08-15 19:00:31 +02:00
INPgetTok(&line, &token, 1);
if (strcmp(token, "ac") == 0) {
JOB *acJob;
which = ft_find_analysis("AC");
2012-08-15 19:00:31 +02:00
if (which == -1) {
current->error = INPerrCat
(current->error,
INPmkTemp("ac analysis unsupported\n"));
return (0); /* temporary */
}
err = ft_sim->newAnalysis (ft_curckt->ci_ckt, which, "acan",
& acJob, ft_curckt->ci_specTask);
2012-08-15 19:00:31 +02:00
if (err) {
ft_sperror(err, "createAC"); /* or similar error message */
return (0); /* temporary */
2000-04-27 22:03:57 +02:00
}
2012-08-15 19:00:31 +02:00
INPgetTok(&line, &steptype, 1); /* get DEC, OCT, or LIN */
ptemp.iValue = 1;
error = INPapName(ckt, which, acJob, steptype, &ptemp);
if (error)
current->error = INPerrCat(current->error, INPerror(error));
parm = INPgetValue(ckt, &line, IF_INTEGER, tab);/* number of points*/
error = INPapName(ckt, which, acJob, "numsteps", parm);
if (error)
current->error = INPerrCat(current->error, INPerror(error));
parm = INPgetValue(ckt, &line, IF_REAL, tab); /* fstart */
error = INPapName(ckt, which, acJob, "start", parm);
if (error)
current->error = INPerrCat(current->error, INPerror(error));
parm = INPgetValue(ckt, &line, IF_REAL, tab); /* fstop */
error = INPapName(ckt, which, acJob, "stop", parm);
if (error)
current->error = INPerrCat(current->error, INPerror(error));
2000-04-27 22:03:57 +02:00
}
2012-08-15 19:00:31 +02:00
if (strcmp(token, "op") == 0) {
which = ft_find_analysis("DCOP");
2012-08-15 19:00:31 +02:00
if (which == -1) {
current->error = INPerrCat
(current->error,
INPmkTemp("DC operating point analysis unsupported\n"));
return (0); /* temporary */
2000-04-27 22:03:57 +02:00
}
err = ft_sim->newAnalysis (ft_curckt->ci_ckt, which, "dcop",
& opJob, ft_curckt->ci_specTask);
2012-08-15 19:00:31 +02:00
if (err) {
ft_sperror(err, "createOP"); /* or similar error message */
return (0);
2000-04-27 22:03:57 +02:00
}
}
2012-08-15 19:00:31 +02:00
if (strcmp(token, "dc") == 0) {
JOB *dcJob;
2000-04-27 22:03:57 +02:00
/* .dc SRC1NAME Vstart1 Vstop1 Vinc1 [SRC2NAME Vstart2 */
/* Vstop2 Vinc2 */
which = ft_find_analysis("DCTransfer");
2012-08-15 19:00:31 +02:00
if (which == -1) {
current->error = INPerrCat
(current->error,
INPmkTemp("DC transfer curve analysis unsupported\n"));
return (0); /* temporary */
2000-04-27 22:03:57 +02:00
}
2011-04-27 20:30:15 +02:00
err = ft_sim->newAnalysis (ft_curckt->ci_ckt, which, "DCtransfer",
2012-08-15 19:00:31 +02:00
& dcJob, ft_curckt->ci_specTask);
if (err) {
ft_sperror(err, "createOP"); /* or similar error message */
return (0);
2000-04-27 22:03:57 +02:00
}
2012-08-15 19:00:31 +02:00
INPgetTok(&line, &name, 1);
INPinsert(&name, tab);
ptemp.uValue = name;
error = INPapName(ckt, which, dcJob, "name1", &ptemp);
if (error)
current->error = INPerrCat(current->error, INPerror(error));
parm = INPgetValue(ckt, &line, IF_REAL, tab); /* vstart1 */
error = INPapName(ckt, which, dcJob, "start1", parm);
if (error)
current->error = INPerrCat(current->error, INPerror(error));
parm = INPgetValue(ckt, &line, IF_REAL, tab); /* vstop1 */
error = INPapName(ckt, which, dcJob, "stop1", parm);
if (error)
current->error = INPerrCat(current->error, INPerror(error));
parm = INPgetValue(ckt, &line, IF_REAL, tab); /* vinc1 */
error = INPapName(ckt, which, dcJob, "step1", parm);
if (error)
current->error = INPerrCat(current->error, INPerror(error));
if (*line) {
if (*line == 'd')
goto next;
INPgetTok(&line, &name, 1);
INPinsert(&name, tab);
ptemp.uValue = name;
error = INPapName(ckt, which, dcJob, "name2", &ptemp);
if (error)
current->error = INPerrCat(current->error, INPerror(error));
parm = INPgetValue(ckt, &line, IF_REAL, tab); /* vstart1 */
error = INPapName(ckt, which, dcJob, "start2", parm);
if (error)
current->error = INPerrCat(current->error, INPerror(error));
parm = INPgetValue(ckt, &line, IF_REAL, tab); /* vstop1 */
error = INPapName(ckt, which, dcJob, "stop2", parm);
if (error)
current->error = INPerrCat(current->error, INPerror(error));
parm = INPgetValue(ckt, &line, IF_REAL, tab); /* vinc1 */
error = INPapName(ckt, which, dcJob, "step2", parm);
if (error)
current->error = INPerrCat(current->error, INPerror(error));
2000-04-27 22:03:57 +02:00
}
}
2012-08-15 19:00:31 +02:00
if (strcmp(token, "tran") == 0) {
JOB *tranJob;
which = ft_find_analysis("TRAN");
2012-08-15 19:00:31 +02:00
if (which == -1) {
current->error = INPerrCat
(current->error,
INPmkTemp("transient analysis unsupported\n"));
return (0); /* temporary */
}
err = ft_sim->newAnalysis (ft_curckt->ci_ckt, which, "tranan",
& tranJob, ft_curckt->ci_specTask);
2012-08-15 19:00:31 +02:00
if (err) {
ft_sperror(err, "createTRAN");
return (0);
2000-04-27 22:03:57 +02:00
}
2012-08-15 19:00:31 +02:00
parm = INPgetValue(ckt, &line, IF_REAL, tab); /* Tstep */
error = INPapName(ckt, which, tranJob, "tstep", parm);
if (error)
current->error = INPerrCat(current->error, INPerror(error));
parm = INPgetValue(ckt, &line, IF_REAL, tab); /* Tstop*/
error = INPapName(ckt, which, tranJob, "tstop", parm);
if (error)
current->error = INPerrCat(current->error, INPerror(error));
if (*line) {
if (*line == 'd')
goto next;
if (*line == 'u')
goto uic;
parm = INPgetValue(ckt, &line, IF_REAL, tab); /* Tstart */
error = INPapName(ckt, which, tranJob, "tstart", parm);
if (error)
current->error = INPerrCat(current->error, INPerror(error));
if (*line == 'u')
goto uic;
parm = INPgetValue(ckt, &line, IF_REAL, tab); /* Tmax */
error = INPapName(ckt, which, tranJob, "tmax", parm);
if (error)
current->error = INPerrCat(current->error, INPerror(error));
uic:
if (*line == 'u') {
INPgetTok(&line, &name, 1);
if (strcmp(name, "uic") == 0) {
2000-04-27 22:03:57 +02:00
ptemp.iValue = 1;
2012-08-15 19:00:31 +02:00
error = INPapName(ckt, which, tranJob, "tstart", &ptemp);
if (error)
current->error = INPerrCat(current->error, INPerror(error));
2000-04-27 22:03:57 +02:00
}
}
}
}
#ifdef WITH_PSS
/* *********************** */
/* PSS - Spertica - 100910 */
/* *********************** */
if (strcmp(token, "pss") == 0) {
JOB *pssJob;
which = ft_find_analysis("PSS");
if (which == -1) {
current->error = INPerrCat
(current->error,
INPmkTemp("periodic steady state analysis unsupported\n"));
return (0); /* temporary */
}
err = ft_sim->newAnalysis (ft_curckt->ci_ckt, which, "pssan",
& pssJob, ft_curckt->ci_specTask);
if (err) {
ft_sperror(err, "createPSS");
return (0);
}
parm = INPgetValue(ckt, &line, IF_REAL, tab); /* Guessed Frequency */
error = INPapName(ckt, which, pssJob, "fguess", parm);
if (error)
current->error = INPerrCat(current->error, INPerror(error));
parm = INPgetValue(ckt, &line, IF_REAL, tab); /* Stabilization time */
error = INPapName(ckt, which, pssJob, "stabtime", parm);
if (error)
current->error = INPerrCat(current->error, INPerror(error));
parm = INPgetValue(ckt, &line, IF_INTEGER, tab); /* PSS points */
error = INPapName(ckt, which, pssJob, "points", parm);
if (error)
current->error = INPerrCat(current->error, INPerror(error));
parm = INPgetValue(ckt, &line, IF_INTEGER, tab); /* PSS points */
error = INPapName(ckt, which, pssJob, "harmonics", parm);
if (error)
current->error = INPerrCat(current->error, INPerror(error));
}
#endif
2012-08-15 19:00:31 +02:00
next:
while (*line) { /* read the entire line */
IFparm *if_parm;
2012-08-15 19:00:31 +02:00
if (flag)
INPgetTok(&line, &token, 1);
else
2000-04-27 22:03:57 +02:00
flag = 1;
2012-08-15 19:00:31 +02:00
if_parm = ft_find_analysis_parm(save, token);
if (!if_parm) {
/* didn't find it! */
current->error = INPerrCat
(current->error,
INPmkTemp(" Error: unknown parameter on .sens - ignored \n"));
continue;
}
2013-07-28 15:06:41 +02:00
/* found it, analysis which, parameter i */
if (if_parm->dataType & IF_FLAG) {
/* one of the keywords! */
ptemp.iValue = 1;
error = ft_sim->setAnalysisParm (ckt, senseJob,
if_parm->id, &ptemp, NULL);
if (error)
current->error = INPerrCat(current->error, INPerror(error));
} else {
parm = INPgetValue (ckt, &line, if_parm->dataType, tab);
error = ft_sim->setAnalysisParm (ckt, senseJob,
if_parm->id, parm, NULL);
if (error)
current->error = INPerrCat(current->error, INPerror(error));
}
2000-04-27 22:03:57 +02:00
}
2012-08-15 19:00:31 +02:00
if ((err = ft_sim->doAnalyses (ckt, 1, ft_curckt->ci_curTask)) != OK) {
2000-04-27 22:03:57 +02:00
ft_sperror(err, "doAnalyses");
return (0); /* temporary */
2000-04-27 22:03:57 +02:00
}
2012-08-15 19:00:31 +02:00
return (0);
2000-04-27 22:03:57 +02:00
}