ngspice/src/frontend/shyu.c

361 lines
12 KiB
C

/**********
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"
#include "circuits.h"
#include "shyu.h"
int
if_sens_run(CKTcircuit *ckt, wordlist *args, INPtables *tab)
{
JOB *senseJob;
JOB *opJob;
card *current;
IFvalue ptemp;
IFvalue *parm;
char buf[BSIZE_SP];
int err;
char *token;
char *steptype;
char *name;
char *line;
card deck;
int error;
int save;
int flag = 0;
int which = -1;
(void) sprintf(buf, ".%s", wl_flatten(args));
deck.nextcard = NULL;
deck.actualLine = NULL;
deck.error = NULL;
deck.linenum = 0;
deck.linenum_orig = 0;
deck.line = buf;
current = (card *) &deck;
line = current->line;
INPgetTok(&line, &token, 1);
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 */
}
}
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 */
}
which = ft_find_analysis("options");
if (which == -1) {
/* in DEEP trouble */
ft_sperror(err, "in DEEP trouble");
return (0); /* temporary */
}
err = ft_sim->newAnalysis (ft_curckt->ci_ckt, which, "options",
& (ft_curckt->ci_specOpt), ft_curckt->ci_specTask);
if (err) {
ft_sperror(err, "createOptions");
return (0); /* temporary */
}
ft_curckt->ci_curOpt = ft_curckt->ci_specOpt;
ft_curckt->ci_curTask = ft_curckt->ci_specTask;
which = ft_find_analysis("SEN");
if (which == -1) {
current->error = INPerrCat(
current->error,
INPmkTemp("sensetivity analysis unsupported\n"));
return (0);
}
err = ft_sim->newAnalysis (ft_curckt->ci_ckt, which, "sense",
& senseJob, ft_curckt->ci_specTask);
if (err) {
ft_sperror(err, "createSense");
return (0); /* temporary */
}
save = which;
INPgetTok(&line, &token, 1);
if (strcmp(token, "ac") == 0) {
JOB *acJob;
which = ft_find_analysis("AC");
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);
if (err) {
ft_sperror(err, "createAC"); /* or similar error message */
return (0); /* temporary */
}
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));
}
if (strcmp(token, "op") == 0) {
which = ft_find_analysis("DCOP");
if (which == -1) {
current->error = INPerrCat
(current->error,
INPmkTemp("DC operating point analysis unsupported\n"));
return (0); /* temporary */
}
err = ft_sim->newAnalysis (ft_curckt->ci_ckt, which, "dcop",
& opJob, ft_curckt->ci_specTask);
if (err) {
ft_sperror(err, "createOP"); /* or similar error message */
return (0);
}
}
if (strcmp(token, "dc") == 0) {
JOB *dcJob;
/* .dc SRC1NAME Vstart1 Vstop1 Vinc1 [SRC2NAME Vstart2 */
/* Vstop2 Vinc2 */
which = ft_find_analysis("DCTransfer");
if (which == -1) {
current->error = INPerrCat
(current->error,
INPmkTemp("DC transfer curve analysis unsupported\n"));
return (0); /* temporary */
}
err = ft_sim->newAnalysis (ft_curckt->ci_ckt, which, "DCtransfer",
& dcJob, ft_curckt->ci_specTask);
if (err) {
ft_sperror(err, "createOP"); /* or similar error message */
return (0);
}
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));
}
}
if (strcmp(token, "tran") == 0) {
JOB *tranJob;
which = ft_find_analysis("TRAN");
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);
if (err) {
ft_sperror(err, "createTRAN");
return (0);
}
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) {
ptemp.iValue = 1;
error = INPapName(ckt, which, tranJob, "tstart", &ptemp);
if (error)
current->error = INPerrCat(current->error, INPerror(error));
}
}
}
}
#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
next:
while (*line) { /* read the entire line */
IFparm *if_parm;
if (flag)
INPgetTok(&line, &token, 1);
else
flag = 1;
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;
}
/* 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));
}
}
if ((err = ft_sim->doAnalyses (ckt, 1, ft_curckt->ci_curTask)) != OK) {
ft_sperror(err, "doAnalyses");
return (0); /* temporary */
}
return (0);
}