More on the frame for HB

Enable for gcc
Set two params f1 and f2 for .HB
Some fixes
This commit is contained in:
Holger Vogt 2025-12-05 17:13:25 +01:00
parent c5891f137c
commit a8d23dc199
7 changed files with 53 additions and 118 deletions

View File

@ -158,6 +158,10 @@ AC_ARG_ENABLE([pss],
AC_ARG_ENABLE([sp],
[AS_HELP_STRING([--disable-sp], [Disable S parameter Analysis])])
# --disable-hb: disable Harmonic Balance Analysis
AC_ARG_ENABLE([hb],
[AS_HELP_STRING([--disable-hb], [Disable Harmonic Balance Analysis])])
# --enable-relpath: Relative path for binary and data. Default is "no".
# ngspice shared may want relative paths for spinit etc.
AC_ARG_ENABLE([relpath],
@ -1226,6 +1230,18 @@ fi
AM_CONDITIONAL([SP_WANTED], [test "x$has_sp" = xtrue])
# Add harmonic balance analysis to ngspice.
if test "x$enable_hb" = xno; then
AC_MSG_RESULT([Harmonic Balance analysis disabled])
has_hb=false
else
AC_MSG_RESULT([Harmonic Balance analysis enabled])
AC_DEFINE([WITH_HB], [1], [HB analysis])
has_hb=true
fi
AM_CONDITIONAL([HB_WANTED], [test "x$has_hb" = xtrue])
AM_CONDITIONAL([CIDER_WANTED], [test "x$enable_cider" = xyes])
AM_CONDITIONAL([NUMDEV_WANTED], [test "x$enable_cider" = xyes])

View File

@ -15,16 +15,8 @@ typedef struct {
int JOBtype;
JOB *JOBnextJob; /* pointer to next thing to do */
char *JOBname; /* name of this job */
double SPstartFreq;
double SPstopFreq;
double SPfreqDelta; /* multiplier for decade/octave stepping, */
/* step for linear steps. */
double SPsaveFreq; /* frequency at which we left off last time*/
int SPstepType; /* values described below */
int SPnumberSteps;
unsigned SPdoNoise : 1; /* Flag to indicate if SP noise must be calculated*/
double HBFreq1;
double HBFreq2;
int SPnoiseInput;
int SPnoiseOutput;
} HBAN;
@ -39,13 +31,8 @@ enum {
#endif
enum {
SP_DEC = 1,
SP_OCT,
SP_LIN,
SP_START,
SP_STOP,
SP_STEPS,
SP_DONOISE,
HB_F1 = 1,
HB_F2
};
#endif
#endif

View File

@ -18,13 +18,12 @@ extern SPICEanalysis SENSinfo;
#ifdef RFSPICE
extern SPICEanalysis SPinfo;
#endif
#ifdef WITH_HB
extern SPICEanalysis HBinfo;
#endif
#endif
#ifdef WITH_PSS
extern SPICEanalysis PSSinfo;
#endif

View File

@ -373,7 +373,7 @@ HBan(CKTcircuit* ckt, int restart)
// Noise analysis is performed at each freq of the SP Analysis
// A temporary dummy job is therefore created
#if(0)
/* variable must be static, for continuation of interrupted (Ctrl-C),
longer lasting noise anlysis */
static Ndata* data = NULL;
@ -769,10 +769,10 @@ HBan(CKTcircuit* ckt, int restart)
return (E_NOMOD);
ckt->CKTVSRCid = vsrcRoot;
#if (0)
// Now that we have found the model, we may init the Zref and Gn ports
VSRCspinit(ckt->CKThead[vsrcRoot], ckt, zref, gn, gninv);
#endif
}
else
vsrcRoot = ckt->CKTVSRCid;
@ -982,6 +982,9 @@ endsweep:
ckt->CKTmatrix->SMPkluMatrix->KLUmatrixIsComplex = KLUmatrixReal;
}
#endif
#endif
return(0);
}

View File

@ -23,47 +23,12 @@ HBaskQuest(CKTcircuit *ckt, JOB *anal, int which, IFvalue *value)
switch(which) {
case SP_START:
value->rValue = job->SPstartFreq;
case HB_F1:
value->rValue = job->HBFreq1;
break;
case SP_STOP:
value->rValue = job->SPstopFreq ;
break;
case SP_STEPS:
value->iValue = job->SPnumberSteps;
break;
case SP_DEC:
if (job->SPstepType == DECADE) {
value->iValue=1;
} else {
value->iValue=0;
}
break;
case SP_OCT:
if (job->SPstepType == OCTAVE) {
value->iValue=1;
} else {
value->iValue=0;
}
break;
case SP_LIN:
if (job->SPstepType == LINEAR) {
value->iValue=1;
} else {
value->iValue=0;
}
break;
case SP_DONOISE:
if (job->SPdoNoise)
value->iValue = 1;
else
value->iValue = 0;
case HB_F2:
value->rValue = job->HBFreq2;
break;
default:

View File

@ -11,7 +11,7 @@ Author: 1985 Thomas L. Quarles
#include "analysis.h"
#ifdef RFSPICE
#ifdef WITH_HB
/* ARGSUSED */
int
@ -23,63 +23,28 @@ HBsetParm(CKTcircuit *ckt, JOB *anal, int which, IFvalue *value)
switch(which) {
case SP_START:
if (value->rValue < 0.0) {
errMsg = copy("Frequency of < 0 is invalid for AC start");
job->SPstartFreq = 1.0;
return(E_PARMVAL);
}
job->SPstartFreq = value->rValue;
break;
case SP_STOP:
if (value->rValue < 0.0) {
errMsg = copy("Frequency of < 0 is invalid for AC stop");
job->SPstartFreq = 1.0;
return(E_PARMVAL);
}
job->SPstopFreq = value->rValue;
break;
case SP_STEPS:
job->SPnumberSteps = value->iValue;
break;
case SP_DEC:
if(value->iValue) {
job->SPstepType = DECADE;
} else {
if (job->SPstepType == DECADE) {
job->SPstepType = 0;
}
case HB_F1:
if (value->rValue < 0.0) {
errMsg = copy("Frequency 1 less than 0 is invalid for HB");
job->HBFreq1 = 1.0;
return(E_PARMVAL);
}
job->HBFreq1 = value->rValue;
break;
case SP_OCT:
if(value->iValue) {
job->SPstepType = OCTAVE;
} else {
if (job->SPstepType == OCTAVE) {
job->SPstepType = 0;
}
case HB_F2:
if (value->rValue < 0.0) {
errMsg = copy("Frequency 2 less than 0 is invalid for HB");
job->HBFreq2 = 1.0;
return(E_PARMVAL);
}
job->HBFreq2 = value->rValue;
break;
case SP_LIN:
if(value->iValue) {
job->SPstepType = LINEAR;
} else {
if (job->SPstepType == LINEAR) {
job->SPstepType = 0;
}
}
break;
case SP_DONOISE:
job->SPdoNoise = value->iValue == 1;
break;
default:
return(E_BADPARM);
@ -89,8 +54,8 @@ HBsetParm(CKTcircuit *ckt, JOB *anal, int which, IFvalue *value)
static IFparm HBparms[] = {
{ "f1", SP_START, IF_SET|IF_ASK|IF_REAL, "fundamental frequency" },
{ "f2", SP_STOP, IF_SET|IF_ASK|IF_REAL, "second frequency" }
{ "f1", HB_F1, IF_SET|IF_ASK|IF_REAL, "fundamental frequency" },
{ "f2", HB_F2, IF_SET|IF_ASK|IF_REAL, "second frequency" }
};
SPICEanalysis HBinfo = {

View File

@ -763,11 +763,11 @@ dot_hb(char* line, void* ckt, INPtables* tab, struct card* current,
}
IFC(newAnalysis, (ckt, which, "Harmonic Balance Analysis", &foo, task));
parm = INPgetValue(ckt, &line, IF_REALVEC, tab); /* Fguess */
GCA(INPapName, (ckt, which, foo, "freq1", parm));
parm = INPgetValue(ckt, &line, IF_REAL, tab); /* F1 */
GCA(INPapName, (ckt, which, foo, "f1", parm));
parm = INPgetValue(ckt, &line, IF_REALVEC, tab); /* Fguess */
GCA(INPapName, (ckt, which, foo, "freq2", parm));
parm = INPgetValue(ckt, &line, IF_REAL, tab); /* F2 */
GCA(INPapName, (ckt, which, foo, "f2", parm));
if (*line) {
fprintf(stderr, "Error: unknown parameter %s on .hb - ignored\n", word);