From ab6224767bbdc687528f38c8c508afe358cb9f17 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sun, 24 May 2020 15:10:40 +0200 Subject: [PATCH] Add command 'optran' to set 6 flags for transient op --- src/frontend/commands.c | 5 ++++ src/spicelib/analysis/optran.c | 52 +++++++++++++++++++++++++++++++++- 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/src/frontend/commands.c b/src/frontend/commands.c index 1bae97fd2..15c1f1c33 100644 --- a/src/frontend/commands.c +++ b/src/frontend/commands.c @@ -83,6 +83,7 @@ #include "diff.h" #include "com_strcmp.h" #include "ngspice/randnumb.h" +#include "../spicelib/analysis/com_optran.h" #include "arg.h" @@ -609,6 +610,10 @@ struct comm spcp_coms[] = { { 0, 0, 0, 0 }, E_DEFHMASK, 0, 0, NULL, ": Print circuit inventory" }, + { "optran", com_optran, TRUE, FALSE, + { 0, 0, 0, 0 }, E_DEFHMASK, 6, 6, + NULL, + ": Prepare optran by setting 6 flags " }, #ifdef HAVE_TSEARCH { "check_ifparm", com_check_ifparm, TRUE, FALSE, { 0, 0, 0, 0 }, E_DEFHMASK, 0, 0, diff --git a/src/spicelib/analysis/optran.c b/src/spicelib/analysis/optran.c index 9c67f216b..a778bb068 100644 --- a/src/spicelib/analysis/optran.c +++ b/src/spicelib/analysis/optran.c @@ -13,6 +13,8 @@ Modified BSD license #include "ngspice/sperror.h" #include "ngspice/fteext.h" #include "ngspice/missing_math.h" +#include "com_optran.h" + /* for setting breakpoints required by dbs data base */ extern struct dbcomm *dbs; @@ -39,6 +41,54 @@ extern int ng_ident; /* for debugging */ static double *opbreaks; static int OPbreakSize; static double opfinaltime = 1e-6; +static double opstepsize = 1e-8; +static double opramptime = 0.; + +/* command to set the 6 optran flags */ +void com_optran(wordlist* wl) { + wordlist* wltmp = wl; + char* stpstr; + /* current circuit */ + CKTcircuit* cckt = ft_curckt->ci_ckt; + /* wordlist with 6 parameters */ + cckt->CKTnoOpIter = strtol(wltmp->wl_word, &stpstr, 10); + if ((errno == ERANGE) || (*stpstr != '\0')) + goto bugquit; + wltmp = wltmp->wl_next; + cckt->CKTnumGminSteps = strtol(wltmp->wl_word, &stpstr, 10); + if ((errno == ERANGE) || (*stpstr != '\0')) + goto bugquit; + wltmp = wltmp->wl_next; + cckt->CKTnumSrcSteps = strtol(wltmp->wl_word, &stpstr, 10); + if ((errno == ERANGE) || (*stpstr != '\0')) + goto bugquit; + wltmp = wltmp->wl_next; + opfinaltime = strtod(wltmp->wl_word, &stpstr); + if ((errno == ERANGE) || (*stpstr != '\0')) + goto bugquit; + wltmp = wltmp->wl_next; + opstepsize = strtod(wltmp->wl_word, &stpstr); + if ((errno == ERANGE) || (*stpstr != '\0')) + goto bugquit; + wltmp = wltmp->wl_next; + opramptime = strtod(wltmp->wl_word, &stpstr); + if ((errno == ERANGE) || (*stpstr != '\0')) + goto bugquit; + if (opstepsize > opfinaltime) { + fprintf(stderr, "Error: Step size larger than final time.\n"); + goto bugquit; + } + if (opstepsize < opfinaltime/50.) { + fprintf(stderr, "Warning: Step size potentially too small.\n"); + } + if (opramptime > opfinaltime) { + fprintf(stderr, "Error: Ramp time larger than final time.\n"); + goto bugquit; + } + return; +bugquit: + fprintf(stderr, "Error in command 'optran'\n"); +} int OPclrBreak(CKTcircuit *ckt) { @@ -598,8 +648,8 @@ resume: newdelta = ckt->CKTdelta; error = CKTtrunc(ckt,&newdelta); if(error) { - return(error); tfree(opbreaks); + return(error); } if (newdelta > .9 * ckt->CKTdelta) { if ((ckt->CKTorder == 1) && (ckt->CKTmaxOrder > 1)) { /* don't rise the order for backward Euler */