Browse Source

* commands.c: Use fourier.h.


			
			
				pre-master-46
			
			
		
arno 26 years ago
parent
commit
508fee7d4b
  1. 7
      src/frontend/ChangeLog
  2. 2
      src/frontend/commands.c
  3. 129
      src/frontend/dotcards.c
  4. 109
      src/frontend/fourier.c
  5. 3
      src/frontend/fourier.h

7
src/frontend/ChangeLog

@ -1,5 +1,12 @@
2000-09-09 Arno W. Peters <A.W.Peters@ieee.org>
* commands.c: Use fourier.h.
* dotcards.c: Update to prevent segfault.
* fourier.c, fourier.h: com_fourier is now calling fourier(), a
function with more parameters.
* dotcards.c: Added assertions to guard a double indirection, now
ngspice will bomb out on an assertion instead of a segfault.

2
src/frontend/commands.c

@ -47,7 +47,7 @@
#include "com_plot.h"
#include "com_setscale.h"
#include "com_xgraph.h"
#include "fourier.h"
/* FIXME: Integrate spcp_coms and nutcp_coms into one variable. */

129
src/frontend/dotcards.c

@ -20,19 +20,35 @@ Modified: 2000 AlansFixes
#include "circuits.h"
#include "dotcards.h"
#include "variable.h"
#include "fourier.h"
/* Extract all the .save lines */
static void fixdotplot(wordlist *wl);
static void fixdotprint(wordlist *wl);
static char * fixem(char *string);
static bool setcplot(char *name);
static wordlist * gettoks(char *s);
extern void com_save2 (wordlist *wl, char *name);
static struct plot *
setcplot(char *name)
{
struct plot *pl;
for (pl = plot_list; pl; pl = pl->pl_next) {
if (ciprefix(name, pl->pl_typename)) {
return pl;
}
}
return NULL;
}
void
ft_dotsaves(void)
{
@ -157,7 +173,9 @@ ft_cktcoms(bool terse)
if (!ft_curckt)
return 1;
if (!ft_curckt->ci_commands && !setcplot("op"))
plot_cur = setcplot("op");
if (!ft_curckt->ci_commands && !plot_cur)
goto nocmds;
coms = ft_curckt->ci_commands;
cp_interactive = FALSE;
@ -168,41 +186,43 @@ ft_cktcoms(bool terse)
fprintf(cp_err, ".options: no listing, rawfile was generated.\n");
else
inp_list(cp_out, ft_curckt->ci_deck, ft_curckt->ci_options,
LS_DECK);
LS_DECK);
}
/* If there was a .op line, then we have to do the .op output. */
assert(plot_cur != NULL);
assert(plot_cur->pl_dvecs != NULL);
if (setcplot("op") && (plot_cur->pl_dvecs->v_realdata!=NULL)) {
if (terse) {
fprintf(cp_out, "OP information in rawfile.\n");
} else {
fprintf(cp_out, "\t%-30s%15s\n", "Node", "Voltage");
fprintf(cp_out, "\t%-30s%15s\n", "----", "-------");
fprintf(cp_out, "\t----\t-------\n");
for (v = plot_cur->pl_dvecs; v; v = v->v_next) {
if (!isreal(v)) {
fprintf(cp_err,
"Internal error: op vector %s not real\n",
v->v_name);
continue;
plot_cur = setcplot("op");
if (plot_cur != NULL) {
assert(plot_cur->pl_dvecs != NULL);
if (plot_cur->pl_dvecs->v_realdata!=NULL) {
if (terse) {
fprintf(cp_out, "OP information in rawfile.\n");
} else {
fprintf(cp_out, "\t%-30s%15s\n", "Node", "Voltage");
fprintf(cp_out, "\t%-30s%15s\n", "----", "-------");
fprintf(cp_out, "\t----\t-------\n");
for (v = plot_cur->pl_dvecs; v; v = v->v_next) {
if (!isreal(v)) {
fprintf(cp_err,
"Internal error: op vector %s not real\n",
v->v_name);
continue;
}
if ((v->v_type == SV_VOLTAGE) && (*(v->v_name)!='@'))
fprintf(cp_out, "\t%-30s%15s\n", v->v_name,
printnum(v->v_realdata[0]));
}
if ((v->v_type == SV_VOLTAGE) && (*(v->v_name)!='@'))
fprintf(cp_out, "\t%-30s%15s\n", v->v_name,
printnum(v->v_realdata[0]));
fprintf(cp_out, "\n\tSource\tCurrent\n");
fprintf(cp_out, "\t------\t-------\n\n");
for (v = plot_cur->pl_dvecs; v; v = v->v_next)
if (v->v_type == SV_CURRENT)
fprintf(cp_out, "\t%-30s%15s\n", v->v_name,
printnum(v->v_realdata[0]));
fprintf(cp_out, "\n");
if (!ft_nomod)
com_showmod(&all);
com_show(&all);
}
fprintf(cp_out, "\n\tSource\tCurrent\n");
fprintf(cp_out, "\t------\t-------\n\n");
for (v = plot_cur->pl_dvecs; v; v = v->v_next)
if (v->v_type == SV_CURRENT)
fprintf(cp_out, "\t%-30s%15s\n", v->v_name,
printnum(v->v_realdata[0]));
fprintf(cp_out, "\n");
if (!ft_nomod)
com_showmod(&all);
com_show(&all);
}
}
@ -264,7 +284,7 @@ ft_cktcoms(bool terse)
}
if (!found)
fprintf(cp_err, "Error: .print: no %s analysis found.\n",
plottype);
plottype);
}
} else if (eq(command->wl_word, ".plot")) {
if (terse) {
@ -298,22 +318,27 @@ ft_cktcoms(bool terse)
if (terse) {
fprintf(cp_out,
".fourier line ignored since rawfile was produced.\n");
} else if (setcplot("tran")) {
com_fourier(command->wl_next);
fprintf(cp_out, "\n\n");
} else
fprintf(cp_err,
"No transient data available for fourier analysis");
} else {
int err;
plot_cur = setcplot("tran");
err = fourier(command->wl_next, plot_cur);
if (!err)
fprintf(cp_out, "\n\n");
else
fprintf(cp_err, "No transient data available for "
"fourier analysis");
}
} else if (!eq(command->wl_word, ".save")
&& !eq(command->wl_word, ".op")
&& !eq(command->wl_word, ".tf"))
&& !eq(command->wl_word, ".op")
&& !eq(command->wl_word, ".tf"))
{
goto bad;
}
coms = coms->wl_next;
}
nocmds:
nocmds:
/* Now the node table */
if (ft_nodesprint)
;
@ -335,7 +360,7 @@ nocmds:
putc('\n', cp_out);
return 0;
bad:
bad:
fprintf(cp_err, "Internal Error: ft_cktcoms: bad commands\n");
return 1;
}
@ -473,22 +498,6 @@ fixem(char *string)
return (string);
}
/* Don't bother with ccom strangeness here. */
static bool
setcplot(char *name)
{
struct plot *pl;
for (pl = plot_list; pl; pl = pl->pl_next) {
if (ciprefix(name, pl->pl_typename)) {
plot_cur = pl;
return (TRUE);
}
}
return (FALSE);
}
static wordlist *
gettoks(char *s)
{

109
src/frontend/fourier.c

@ -31,12 +31,15 @@ static int CKTfour(int ndata, int numFreq, double *thd, double *Time, double *Va
#define DEF_FOURGRIDSIZE 200
/* CKTfour(ndata,numFreq,thd,Time,Value,FundFreq,Freq,Mag,Phase,nMag,nPhase)
* len 10 ? inp inp inp out out out out out
*/
void
com_fourier(wordlist *wl)
/* FIXME: This function leaks memory due to non local exit bypassing
freeing of memory at the end of the function. */
int
fourier(wordlist *wl, struct plot *current_plot)
{
struct dvec *time, *vec;
struct pnode *names, *first_name;
@ -49,11 +52,14 @@ com_fourier(wordlist *wl)
char xbuf[20];
int shift;
if (!current_plot)
return 1;
sprintf(xbuf, "%1.1e", 0.0);
shift = strlen(xbuf) - 7;
if (!plot_cur || !plot_cur->pl_scale) {
if (!current_plot || !current_plot->pl_scale) {
fprintf(cp_err, "Error: no vectors loaded.\n");
return;
return 1;
}
if ((!cp_getvar("nfreqs", VT_NUM, (char *) &nfreqs)) || (nfreqs < 1))
@ -65,15 +71,15 @@ com_fourier(wordlist *wl)
(fourgridsize < 1))
fourgridsize = DEF_FOURGRIDSIZE;
time = plot_cur->pl_scale;
time = current_plot->pl_scale;
if (!isreal(time)) {
fprintf(cp_err, "Error: fourier needs real time scale\n");
return;
return 1;
}
s = wl->wl_word;
if (!(ff = ft_numparse(&s, FALSE)) || (*ff <= 0.0)) {
fprintf(cp_err, "Error: bad fund freq %s\n", wl->wl_word);
return;
return 1;
}
fundfreq = *ff;
@ -114,8 +120,8 @@ com_fourier(wordlist *wl)
d = 1 / fundfreq; /* The wavelength... */
if (dp[1] - dp[0] < d) {
fprintf(cp_err,
"Error: wavelength longer than time span\n");
return;
"Error: wavelength longer than time span\n");
return 1;
} else if (dp[1] - dp[0] > d) {
dp[0] = dp[1] - d;
}
@ -131,7 +137,7 @@ com_fourier(wordlist *wl)
polydegree)) {
fprintf(cp_err,
"Error: can't interpolate\n");
return;
return 1;
}
timescale = grid;
} else {
@ -145,7 +151,7 @@ com_fourier(wordlist *wl)
nphase);
if (err != OK) {
ft_sperror(err, "fourier");
return;
return 1;
}
fprintf(cp_out, "Fourier analysis for %s:\n",
@ -185,9 +191,18 @@ com_fourier(wordlist *wl)
tfree(phase);
tfree(nmag);
tfree(nphase);
return;
return 0;
}
void
com_fourier(wordlist *wl)
{
fourier(wl, plot_cur);
}
static char *
pn(double num)
{
@ -198,50 +213,54 @@ pn(double num)
i = 6;
if (num < 0.0)
(void) sprintf(buf, "%.*g", i - 1, num);
sprintf(buf, "%.*g", i - 1, num);
else
(void) sprintf(buf, "%.*g", i, num);
sprintf(buf, "%.*g", i, num);
return (copy(buf));
}
/*
* CKTfour() - perform fourier analysis of an output vector.
* Due to the construction of the program which places all the
* output data in the post-processor, the fourier analysis can not
* be done directly. This function allows the post processor to
* hand back vectors of time and data values to have the fourier analysis
* performed on them.
*
*/
/* CKTfour() - perform fourier analysis of an output vector.
*
* Due to the construction of the program which places all the output
* data in the post-processor, the fourier analysis can not be done
* directly. This function allows the post processor to hand back
* vectors of time and data values to have the fourier analysis
* performed on them. */
static int
CKTfour(int ndata, int numFreq, double *thd, double *Time, double *Value, double FundFreq, double *Freq, double *Mag, double *Phase, double *nMag, double *nPhase)
/* number of entries in the Time and Value arrays */
/* number of harmonics to calculate */
/* total harmonic distortion (percent) to be returned */
/* times at which the voltage/current values were measured*/
/* voltage or current vector whose transform is desired */
/* the fundamental frequency of the analysis */
/* the frequency value of the various harmonics */
/* the Magnitude of the fourier transform */
/* the Phase of the fourier transform */
/* the normalized magnitude of the transform: nMag(fund)=1*/
/* the normalized phase of the transform: Nphase(fund)=0 */
/* note we can consider these as a set of arrays: The sizes are:
* Time[ndata], Value[ndata]
* Freq[numFreq],Mag[numfreq],Phase[numfreq],nMag[numfreq],nPhase[numfreq]
CKTfour(int ndata, /* number of entries in the Time and
Value arrays */
int numFreq, /* number of harmonics to calculate */
double *thd, /* total harmonic distortion (percent)
to be returned */
double *Time, /* times at which the voltage/current
values were measured*/
double *Value, /* voltage or current vector whose
transform is desired */
double FundFreq, /* the fundamental frequency of the
analysis */
double *Freq, /* the frequency value of the various
harmonics */
double *Mag, /* the Magnitude of the fourier
transform */
double *Phase, /* the Phase of the fourier transform */
double *nMag, /* the normalized magnitude of the
transform: nMag(fund)=1*/
double *nPhase) /* the normalized phase of the
transform: Nphase(fund)=0 */
{
/* Note: we can consider these as a set of arrays. The sizes are:
* Time[ndata], Value[ndata], Freq[numFreq], Mag[numfreq],
* Phase[numfreq], nMag[numfreq], nPhase[numfreq]
*
* The arrays must all be allocated by the caller.
* The Time and Value array must be reasonably distributed over at
* least one full period of the fundamental Frequency for the
* fourier transform to be useful. The function will take the
* last period of the frequency as data for the transform.
*/
{
/* we are assuming that the caller has provided exactly one period
* of the fundamental frequency.
*/
*
* We are assuming that the caller has provided exactly one period
* of the fundamental frequency. */
int i;
int j;
double tmp;

3
src/frontend/fourier.h

@ -7,7 +7,6 @@
#define FOURIER_H_INCLUDED
void com_fourier(wordlist *wl);
int fourier(wordlist *wl, struct plot *current);
#endif
Loading…
Cancel
Save