From 8b80a4454a34c689c423d43f654d2b1a9b2e5a6b Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Wed, 10 Dec 2025 22:00:36 +0100 Subject: [PATCH] Add and fill hbnumfreqs[10] as integer array for up to 10 numbers of frequencies for HB --- src/frontend/options.c | 32 +++++++++++++++++++++++++++++++- src/frontend/spiceif.c | 2 ++ src/include/ngspice/optdefs.h | 4 ++++ src/spicelib/analysis/cktsopt.c | 25 +++++++++++++++++++++++++ 4 files changed, 62 insertions(+), 1 deletion(-) diff --git a/src/frontend/options.c b/src/frontend/options.c index 7dfe6f97a..093f62b84 100644 --- a/src/frontend/options.c +++ b/src/frontend/options.c @@ -26,6 +26,8 @@ bool ft_nodesprint = FALSE, ft_optsprint = FALSE, ft_noinitprint = FALSE; bool ft_norefprint = FALSE, ft_skywaterpdk = FALSE; bool ft_ngdebug = FALSE, ft_nginfo = FALSE, ft_stricterror = FALSE, ft_spiniterror = FALSE; +int hbnumfreqs[10]; + static void setdb(char *str); static struct variable *cp_enqvec_as_var(const char *vec_name, int *p_f_found); @@ -397,8 +399,36 @@ cp_usrset(struct variable *var, bool isset) return (US_DONTRECORD); } else if (eq(var->va_name, "plots")) { return (US_READONLY); - } + /* Fill in hbnumfreqs[10] by reading from + 'set hbnumfreq = 7' or 'set hbnumfreq = ( 7, 9 ) + */ +#ifdef WITH_HB + } else if (eq(var->va_name, "hbnumfreq")) { + if (var->va_type == CP_NUM) { + hbnumfreqs[0] = var->va_num; + for (int ii = 1; ii < 10; ii++) + hbnumfreqs[ii] = 0; + } + else if (var->va_type == CP_LIST) { + int ii = 0; + for (tv = var->va_vlist; tv; tv = tv->va_next) + if (tv->va_type == CP_NUM) { + if (ii > 9) { + fprintf(stderr, "Warning: too many frequencies (> 10), ignored\n"); + break; + } + hbnumfreqs[ii] = tv->va_num; + ii++; + } + else + fprintf(cp_err, "Error: bad syntax for hbnumfreq\n"); + for (int jj = ii; jj < 10; jj++) + hbnumfreqs[jj] = 0; + } + return (US_OK); + } +#endif if (plot_cur) for (tv = plot_cur->pl_env; tv; tv = tv->va_next) if (eq(tv->va_name, var->va_name)) diff --git a/src/frontend/spiceif.c b/src/frontend/spiceif.c index 9697d7298..5b9689344 100644 --- a/src/frontend/spiceif.c +++ b/src/frontend/spiceif.c @@ -467,6 +467,8 @@ if_option(CKTcircuit *ckt, char *name, enum cp_types type, void *value) } else if (eq(name, "nomod")) { ft_nomod = TRUE; return 0; + } else if (eq(name, "hbnumfreq")) { + return 0; } which = ft_find_analysis("options"); diff --git a/src/include/ngspice/optdefs.h b/src/include/ngspice/optdefs.h index 3455a2454..14d60ed4f 100644 --- a/src/include/ngspice/optdefs.h +++ b/src/include/ngspice/optdefs.h @@ -126,6 +126,10 @@ enum { OPT_EPSMIN, OPT_CSHUNT, +#ifdef WITH_HB + OPT_HBNF, +#endif + #ifdef KLU OPT_SPARSE, OPT_KLU, diff --git a/src/spicelib/analysis/cktsopt.c b/src/spicelib/analysis/cktsopt.c index 0c1f723e1..9da0a6835 100644 --- a/src/spicelib/analysis/cktsopt.c +++ b/src/spicelib/analysis/cktsopt.c @@ -28,6 +28,10 @@ Modified: 2000 AlansFixes /* gtri - end - wbk - add includes */ #endif +#ifdef WITH_HB +extern int hbnumfreqs[10]; +#endif + /* ARGSUSED */ int CKTsetOpt(CKTcircuit *ckt, JOB *anal, int opt, IFvalue *val) @@ -188,6 +192,22 @@ CKTsetOpt(CKTcircuit *ckt, JOB *anal, int opt, IFvalue *val) break; #endif +#ifdef WITH_HB + /* called here from .options with parameters only */ + case OPT_HBNF: + { + int* inf = val->v.vec.iVec; + if (hbnumfreqs[0] == 0) { + /* not yet set, cannot overwrite */ + for (int ii = 0; ii < val->v.numValue && ii < 10; ii++) { + hbnumfreqs[ii] = inf[ii]; + } + } + + break; + } +#endif + /* gtri - begin - wbk - add new options */ #ifdef XSPICE case OPT_EVT_MAX_OP_ALTER: @@ -347,6 +367,11 @@ static IFparm OPTtbl[] = { { "epsmin", OPT_EPSMIN, IF_SET|IF_REAL, "Minimum value for log" }, +#ifdef WITH_HB + { "hbnumfreq", OPT_HBNF, IF_SET|IF_INTVEC, + "Number of harmonics for HB" }, +#endif + #ifdef KLU { "sparse", OPT_SPARSE, IF_SET|IF_FLAG, "Set SPARSE 1.3 as Direct Linear Solver" },