file B4TERMS_OF_USE was added on branch TCLSPICE on 2006-08-31 18:11:35 +0000

This commit is contained in:
stefanjones 2000-04-27 20:04:00 +00:00
parent 978f1c32a2
commit 589b6eb665
300 changed files with 0 additions and 39201 deletions

View File

@ -1 +0,0 @@
This file will contain a list of implemented analyses.

File diff suppressed because it is too large Load Diff

View File

@ -1,127 +0,0 @@
.\" RCS Info: $Revision$ on $Date$
.\" $Source$
.\" Copyright (c) 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
.TH SCONVERT 1 "20 March 1986"
.UC 4
.SH NAME
sconvert \- convert spice formats
.SH SYNOPSIS
.B sconvert fromtype fromfile totype tofile
.br
.B sconvert fromtype totype
.br
.B sconvert
.br
.SH DESCRIPTION
.B Sconvert
translates spice output files among three formats: the old
binary format, a new binary format, and a new ascii format.
The formats are specified by the
.B fromtype
and
.B totype
arguments: `o' for the old format, `b' for the new binary format,
and `a' for the new ascii format.
.B Fromtype
specifies the format to be read, and
.B totype
specifies the format to be written.
If
.B fromfile
and
.B tofile
are given, then they are used as the input and output, otherwise
standard input and output are used. (Note that this second option is
only available on \s-2UNIX\s+2 systems \- on VMS and other systems you must
supply the filenames.)
If no arguments are given, the parameters are prompted for.
.PP
Binary format is the preferred format for general use, as it is
the most economical in terms of space and speed of access, and ascii is
provided to make it easy to modify data files and transfer them
between machines with different floating-point formats.
The old format is provided only
for backward compatibility. The three formats are as follows:
.br
.nf
.B Old:
What Size in Bytes
title 80
date 8
time 8
numoutputs 2
the integer 4 2
variable names --
char[numoutputs][8] numoutputs * 8
types of output numoutputs * 2
node index numoutputs * 2
plot title numoutputs * 24
the actual data numpoints * numoutputs * 8
.B Ascii:
Title: \fITitle Card String\fR
Date: \fIDate\fR
[ Plotname: \fIPlot Name\fR
Flags: \fIcomplex\fR or \fIreal\fR
No. Variables: \fInumoutputs\fR
No. Points: \fInumpoints\fR
Command: \fInutmeg command\fR
Variables: 0 \fIvarname1\fR \fItypename1\fR
1 \fIvarname2\fR \fItypename2\fR
etc...
Values:
0 n n n n ...
1 n n n n ...
And so forth...
] repeated one or more times
.PP
If one of the flags is \fIcomplex\fR, the points look like r,i where r and i
are floating point (in %e format). Otherwise they are in %e format.
Only one of \fIreal\fR and \fIcomplex\fR should appear.
.PP
The lines are guaranteed to be less than 80 columns wide (unless the
plot title or variable names are very long), so this format is safe
to mail between systems like CMS.
.PP
Any number of \fBCommand:\fR lines may appear between the \fBNo. Points:\fR
and the \fBVariables:\fR lines, and whenever the plot is loaded into
\fBnutmeg\fR they will be executed.
.nf
.B Binary:
\fITitle Card\fR (a NULL terminated string)
\fIDate, Time\fR (a NULL terminated string)
[
\fIPlot title\fR (a NULL terminated string)
\fINumber of variables\fR (an int)
\fINumber of data points\fR (an int)
\fIflags\fR (a short)
\fIvariable header struct\fR (repeated numoutputs times)
\fIvariable name\fR (a NULL terminated string)
\fIvariable type\fR (an int)
\fIset of outputs\fR (repeated numpoints times)
] repeated one or more times.
.PP
A set of outputs is a vector of doubles of length numoutputs, or
a vector of real-imaginary pairs of doubles if the data is complex.
.SH "SEE ALSO"
nutmeg(1), spice(1), writedata(3)
.SH AUTHOR
Wayne Christopher (faustus@cad.berkeley.edu)
.SH BUGS
If variable names and the title
and plotname strings have trailing
blanks in them they will be stripped off when the file is read, if
it is in ascii format.
.PP
If a plot title begins with "Title:" \fBnutmeg\fR will be fooled into thinking
that this is an ascii format file. \fBSconvert\fR always requires the
type to be specified, however.

View File

@ -1,325 +0,0 @@
.\" RCS Info: $Revision$ on $Date$
.\" $Source$
.\" Copyright (c) 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
.TH SPICE 1 "20 March 1986"
.ds S \s-2SPICE\s+2\&3
.UC 4
.SH NAME
spice \- circuit simulator
.SH SYNOPSIS
\fBspice [ -n ] [ -t term ] [ -r rawfile] [ -b ]
[ -i ] [ input file ... ]\fR
.SH DESCRIPTION
This manual page describes the commands available for interactive
use of \*S. For details of circuit descriptions and the
process of simulating a circuit, see the \*S User's Manual.
The commands available are a superset of those available for
\fBnutmeg\fR \- only the additional commands available in \*S
are described here. You should be familiar with the manual page for
\fBnutmeg(1)\fR before reading this manual page.
.PP
Arguments are:
.TP
\fB-n\fR (or \fB-N\fR)
Don't try to source the file ".spiceinit" upon startup. Normally \*S
tries to find the file in the current directory, and if it is not found then
in the user's home directory.
.TP
\fB-t term\fR (or \fB-T term\fR)
The program is being run on a terminal with \fImfb\fR name \fBterm\fR.
.TP
\fB-b\fR (or \fB-B\fR)
Run in batch mode. \*S will read the standard input or the specified
input file and do the simulation. Note that if the standard input
is not a terminal, \*S will default to batch mode, unless the
-i flag is given.
.TP
\fB-s\fR (or \fB-S\fR)
Run in server mode. This is like batch mode, except that a temporary
rawfile is used and then written to the standard output, preceded by
a line with a single "@", after the simulation is done. This mode
is used by the spice daemon.
.TP
\fB-i\fR (or \fB-I\fR)
Run in interactive mode. This is useful if the standard input is
not a terminal but interactive mode is desired. Command completion is
not available unless the standard input is a terminal, however.
.TP
\fB-r rawfile\fR (or \fB-R rawfile\fR)
Use \fBrawfile\fR as the default file into which the results of
the simulation are saved.
.PP
Further arguments are taken to be \*S input decks, which are read
and saved. (If batch mode is requested then they are run immediately.)
.PP
\*S will accept any \s-2SPICE\s+2\&2 input decks, and output
ascii plots, fourier analyses, and node printouts as specified
in .plot, .four, and .print cards. If a \fBout\fR parameter
is given on a .width card, the effect is the same as \fBset width = ...\fR.
Since \*S ascii plots do not use multiple ranges, however, if vectors
together on a .plot card have different ranges they will not provide
as much information as they would in \s-2SPICE\s+2\&2. The output
of \*S is also much less verbose than \s-2SPICE\s+2\&2, in that the only
data printed is that requested by the above cards.
.PP
Vector names are the same as in \fBnutmeg\fR, with this addition:
a name such as \fB@name[param]\fR, where \fBname\fR is either
the name of a device instance or model, denotes the value of the
\fBparam\fR parameter of the device or model. See the \*S User's
Manual for details of what parameters are available. The value is a
vector of length 1. This function is also available with the
\fBshow\fR command, and is available with variables for convenience for
command scripts.
.PP
\*S
commands are as follows (these are only those commands not also
available in \fBnutmeg\fR \- consult the \fBnutmeg\fR manual page for
more commands):
.TP
\fBsetcirc [circuit name]\fR
Change the current circuit. The current circuit is the one that is
used for the simulation commands below. When a circuit is loaded
with the \fIsource\fR command (see below) it becomes the
current circuit.
.TP
\fBop [.op card args]\fR
Do an operating point analysis.
.TP
\fBtran [.tran card args]\fR
Do a transient analysis.
.TP
\fBac [.ac card args]\fR
Do an ac analysis.
.TP
\fBdc [.dc card args]\fR
Do a dc transfer curve analysis.
.TP
\fBlisting [logical] [physical] [deck] [expand]\fR
Print a listing of the current circuit. If the \fBlogical\fR argument
is given, the listing is with all continuation lines collapsed
into one line, and if the \fBphysical\fR
argument is given the lines are printed out as they were found in
the file. The default is \fBlogical\fR. A \fBdeck\fR listing is just like
the \fBphysical\fR listing, except without the line numbers it recreates
the input file verbatim (except that it does not preserve case).
If the word \fBexpand\fR is present, the circuit will be printed with all
subcircuits expanded.
.TP
\fBedit [file]\fR
Print the current \*S deck into a file, call up the editor on that file
and allow the user to modify it, and then read it back in, replacing
the origonal deck. If a \fBfilename\fR is given, then edit that file
and load it, making the circuit the current one.
.TP
\fBresume\fR
Resume a simulation after a stop.
.TP
\fBshow \fR
Show a device parameter.
.TP
\fBalter \fR
Alter a device parameter.
.TP
\fBstate\fR
Print the state of the circuit. (This command is largely unimplemented.)
.TP
\fBsave [all] [output ...]\fR or \fB.save [all] [output ...]\fR
Save a set of outputs, discarding the rest. If a node has been mentioned
in a \fBsave\fR command, it will appear in the working plot after
a run has completed, or in the rawfile if spice is run in batch
mode. If a node is traced or plotted (see below) it will
also be saved. For backward compatibility, if there are \fBno\fR save
commands given, all outputs are saved.
.TP
\fBstop [ after n] [ when something cond something ] ... \fR
Set a breakpoint. The argument \fBafter n\fR means stop after \fBn\fR
iteration number \fBn\fR, and the argument
\fBwhen something cond something\fR means
stop when the first \fBsomething\fR is in the given relation with
the second \fBsomething\fR, the possible relations being
\fBeq\fR or = (equal to),
\fBne\fR or <> (not equal to),
\fBgt\fR or > (greater than),
\fBlt\fR or < (less than),
\fBge\fR or >= (greater than or equal to), and
\fBle\fR or <= (less than or equal to).
IO redirection is disabled for the \fBstop\fR command, since the relational
operations conflict with it (it doesn't produce any output anyway).
The \fBsomething\fR\&s above may be node names in
the running circuit, or real values.
If more than one condition is given, e.g.
\fBstop after 4 when v(1) > 4 when v(2) < 2\fR, the conjunction of
the conditions is implied.
.TP
\fBtrace [ node ...]\fR
Trace nodes. Every iteration the value of the node is printed to the
standard output.
.TP
\fBiplot [ node ...]\fR
Incrementally plot the values of the nodes while \*S runs.
.TP
\fBstep [number]\fR
Iterate \fBnumber\fR times, or once, and then stop.
.TP
\fBstatus\fR
Display all of the traces and breakpoints currently in effect.
.TP
\fBdelete [debug number ...]\fR
Delete the specified breakpoints and traces. The \fBdebug numbers\fR
are those shown by the \fBstatus\fR command. (Unless you do
\fBstatus > file\fR, in which case the debug numbers aren't printed.)
.TP
\fBreset\fR
Throw out any intermediate data in the circuit (e.g, after a breakpoint
or after one or more analyses have been done already), and re-parse
the deck. The circuit can then be re-run. (\fBNote\fR: this command
used to be \fBend\fR in \s-2SPICE\s+2 3a5 and earlier versions -- \fBend\fR
is now used for control structures.) The \fBrun\fR command will take
care of this automatically, so this command should not be necessary...
.TP
\fBrun [rawfile]\fR
Run the simulation as specified in the input file. If there were any
of the control cards .ac, .op, .tran, or .dc, they are executed. The output
is put in \fBrawfile\fR if it was given, in addition to being available
interactively.
.TP
\fBsource file\fR
Read the \*S input file \fBfile\fR. \fBNutmeg\fR and \*S commands may be
included in the file, and must be enclosed between the lines
\fI.control\fR and \fI.endc\fR. These commands
are executed immediately after the circuit is loaded, so a control line
of \fIac ...\fR will work the same as the corresponding \fI.ac\fR card.
The first line in any input file is considered a title
line and not parsed but kept as the name of the circuit. The
exception to this rule is the file \fI.spiceinit\fR.
Thus, a \*S command script must begin with a blank line and then with
a \fI.control\fR line.
Also, any line beginning with the characters *# is considered a control
line. This makes it possible to imbed commands in \*S input files
that will be ignored by earlier versions of \s-2SPICE\s+2.
\fINote:\fR in spice3a7 and before, the \fI.control\fR and \fI.endc\fR
lines were not needed, and any line beginning with the name of a front-end
command would be executed.
.TP
\fBlinearize vec ...\fR
Create a new plot with all of the vectors in the current plot, or
only those mentioned if arguments are given. The new vectors
will be interpolated onto a linear time scale, which is determined
by the values of \fBtstep, tstart,\fR and \fBtstop\fR in the
currently active transient analysis. The currently loaded deck
must include a transient analysis (a \fBtran\fR command may be run
interactively before the last \fBreset\fR, alternately), and the
current plot must be from this transient analysis. This command
is needed because \s-2SPICE\s+2\&3 doesn't output the results
from a transient analysis in the same manner that \s-2SPICE\s+2\&2 did.
.PP
There are several \fBset\fR variables that \*S uses but \fBnutmeg\fR
does not. They are:
.IP "" 16
\fBeditor\fR
.br
The editor to use for the \fBedit\fR command.
.IP
\fBmodelcard\fR
.br
The name of the model card (normally \fB.model\fR).
.IP
\fBnoaskquit\fR
.br
Do not check to make sure that there are no circuits suspended and
no plots unsaved. Normally \*S will warn the user when he tries to
quit if this is the case.
.IP
\fBnobjthack\fR
.br
Assume that BJT's have 4 nodes.
.IP
\fBnoparse\fR
.br
Don't attempt to parse decks when they are read in (useful for
debugging). Of course, they
cannot be run if they are not parsed.
.IP
\fBnosubckt\fR
.br
Don't expand subcircuits.
.IP
\fBrenumber\fR
.br
Renumber input lines when a deck has \fB.include\fR's.
.IP
\fBsubend\fR
.br
The card to end subcircuits (normally \fB.ends\fR).
.IP
\fBsubinvoke\fR
.br
The prefix to invoke subcircuits (normally \fBx\fR).
.IP
\fBsubstart\fR
.br
The card to begin subcircuits (normally \fB.subckt\fR).
.PP
There are a number of \fBrusage\fR parameters available, in addition
to the ones available in \fBnutmeg\fR:
.IP "" 16
.PP
If there are subcircuits in the input file, \*S expands instances of them.
A subcircuit is delimited by the cards
.B .subckt
and
.B .ends,
or whatever the value of the variables
.B substart
and
.B subend
is, respectively. An instance of a subcircuit is created by specifying
a device with type 'x' \- the device line is written
.IP
\fBxname node1 node2 ... subcktname\fR
.LP
where the nodes are the node names that replace the formal parameters
on the \fB.subckt\fR line. All nodes that are not formal parameters
are prepended with the name given to the instance and a ':', as are
the names of the devices in the subcircuit. If there are several nested
subcircuits, node and device names look like \fBsubckt1:subckt2:...:name\fR.
If the variable \fBsubinvoke\fR is set, then it is used as the prefix
that specifies instances of subcircuits, instead of 'x'.
.SH "VMS NOTES"
The standard suffix for rawspice files in VMS is ".raw".
.PP
You may have to redefine the value EDITOR if you wish to use the \fBedit\fR
command, since the default for VMS is "vi".
.SH "SEE ALSO"
nutmeg(1), sconvert(1), spice(1), mfb(3), writedata(3)
\*S User's Guide
.SH AUTHORS
\*S: Tom Quarles (quarles@cad.berkeley.edu)
.br
\fBnutmeg\fR / User interface: Wayne Christopher (faustus@cad.berkeley.edu)
.SH BUGS
.PP
\*S will recognise all the notations used in \s-2SPICE\s+2\&2 \fB.plot\fR
cards, and will translate \fBvp(1)\fR into \fBph(v(1))\fR, and so
forth. However, if there are spaces in these names it won't work. Hence
\fBv(1, 2)\fR and \fB(-.5, .5)\fR aren't recognised.
.PP
BJT's can have either 3 or 4 nodes, which makes it difficult for the subcircuit
expansion routines to decide what to rename. If the fourth parameter has
been declared as a model name, then it is assumed that there are 3 nodes,
otherwise it is considered a node. To disable this kludge, you can set
the variable "nobjthack", which will force BJT's to have 4 nodes (for the
purposes of subcircuit expansion, at least).
.PP
The \fB@name[param]\fR notation might not work with \fBtrace, iplot,\fR etc.
yet.
.PP
The first line of a command file (except for the \fI.spiceinit\fR file)
should be a comment. Otherwise \s-2SPICE\s+2 may create an empty circuit
structure.
.SH CAVEATS
.PP
\*S files specified on the command line are read in before the\fB .spiceinit\fR
file is read. Thus if you define aliases there that you call in a
\*S source file mentioned on the command line, they won't be recognised.

View File

@ -1,164 +0,0 @@
So, this is third version of Spice3f5 for RedHat Linux 2.6. I took re-ported
version of spice3f5 and made changes to fix some bugs. If someone want to help,
please send me "newer" versions wtih more bugs fixed.
I hope that those who wnat to have good spice under Linux (no more Win95)
will find this port useful and maybe help each other to improve it.
There was a lot of bugs in previus versions, generally in command parsiong routines.
I copy all original files to *.orig and marked all my changes with /* MW. ... */
I changed cp/bquote.c and cp/var2.c to handle some special situations
and commands like $foo, `foo`. Also problems with 'gets()' (in sconvert and
inp.c) function are fixed. I chnaget it to fgets(buf, BSIZE_SP, stdin) for
safe use.
Globing ('[]{}?*') didn't work at all. Now it is removed (form cp/glob.c).
We don't need this features in spice.
Initial command parsing (cp_lexer() from cp/lexical.c) strip all commas from
strings. This was in conflict with aritchetic expressions.
com_let() in fte/postcoms.c caused core dump in some situations - fixed.
Editor problems. Com_edit() in fte/inp.c failed occasionally, when it
tryies to fclose() fp second time. Now inp_spsource() always closes fp, and
other calling functions do not. It seems to work right now.
vec_get() (fte/vectors.c) has some problems with devices parameters and
memory leaks. I hope that my changes fixed it at all.
I have to add INPinsertNofree() in inp/inpsymt.c. This is special case for
routines from fte/spiceif.c and fte/outitf.c - It does not do free() for
any pointers that it gets. This may cause small memory leaks, but I don't
know how to make it better.
com_alter_common() (fte/device.c) caused segmentation faults ocassionally,
due to double free the same pointers. It works right now.
cp_lexer() corretly gets ^V, ^D, and ESC. I have to #include ioctl.h file in
cp/lexical.c and cp/complete.c
There were problem with com_iplot() if it was called when X11 does not run.
I have to add additonal check to gr_pmsg() (from fte/graph.c) and now it
works fine.
Trace failed to display comlex data due to segmentation fault. Someone wants
to plot realdata even if given vector was complex. I changed gr_iplot()
(in fte/graf.c) and now it is fine.
There are some changes in os_linux.h and os_unix.h, but they are not mandatory,
I think. Also I have to add PI, and some other const. declarations in spice.h
They were needed somewhere. (why someone didn't used M_PI and so on instead ?)
In file fte/x11.c, was a prloblem with background color for plot windows. I
changed init_colors() and now we can use color0 variable.
Spice3f5 has a few memory leaks. I suppose that some vectors and maybe other
things are simple 'lost' somewhere. If you (just like me) trying to make this
program better, take care about this also.
Generally I didn't do much with graphisc interface, because it seems to work
quite good. Only problem is core dump, when cliking mouse on help screen.
Manuals are sometimes in error. Vector creation by [ el. el. ...] is not
supported I think. For indexing we must use [low , hi]. For setting 'list'
variables - ( el. el. ... ). Indexing also doesn't work with let xx[...] = yy.
Someone should change these f... manuals.
And now for those who think about makeing this program better. There is a big
problem with memory, when you run a few simulations. Destroy commad does not
free much memory, and after some time you can see that spice uses 3MB, when
you just clean all vectros. Also I don't know how to unload a circuit -
spice hold all sourced files in the "deck" list and there is no way to free
it from command line (or maybe I didn't find any).
Unfortunatelly I am sure that these are not all off the problems
with this program, but now I can use it quite effectively. If anyone will
know anything about bugs-free, good, commannd driven simulator for Linux
__PLEASE__ let me know.
For easer use I made special debug file (conf/debug). I used it for makeing
"debug" version of spice with efence library and -g option. Executable files
from this are located in spice3f5/objdbg/bin, when you do 'util/build linux debug'.
I am an electronic designer, so I really need a good working simulator...
Original readme file is given below.
Michael Widlok (widlok@uci.agh.edu.pl)
Uniersity of Mining and Metallurgy
Krakow, Poland.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This is my (re-)port of Spice3f4 to Linux version 2 (I am not the same
person who ported it before). It also wraps in the latest official
pre-3f5 patches from Berkeley I could find (found in
sp3f4.patch.tar.Z). Support for the MFB interface using the Linux
termcap library and some various Linux features have been ported.
This was not done for the hell of it, but it seemed that something
broke due to some Linux/system/library changes, so I decided to try
porting it from scratch. In fact, if you don't have any problems with
the previous port, your probably fine then. However, if you do have
problems (e.g. exiting Spice leaves you in uppercase mode), or want
MFB for some reason, then try this. It seems to work here.
Basically, I started out with sp3f4.kit.tar.Z. Then, I applied the
most recent patches contained in sp3f4.patch.tar.Z and wrote new Linux
build files: "linux" and "os_linux.h" (some minor mods to the source
were also necessary, protected with linux conditionals).
Since the previous spice3f4.tar.gz port file was generally available,
there was no point in duplicating source, so I just diffed from the
spice3f4.tar.gz tree to freshly ported tree and edited or removed a
few of the diffs. A few of the changes made in spice3f4.tar.gz have
been reverted to the distribution defaults, but one notable change is
that performing the install step will install the necessary files into
/usr/local/spice. You'll need to add /usr/local/spice/bin to your
shell path. See the file conf/linux to change the installation
location (this location gets hard-coded in the spice binaries).
This is a patched file of the original readme.Linux from
spice3f4.tar.gz, and the previous contents by Jeff@EE.Ryerson.Ca is
given below. Just follow the below instructions, so you should be
able to safely do:
./util/build linux
./util/build linux install
You should then find the spice binaries and library files
in e.g. /usr/local/spice. Example files and the man pages
are not installed, so you might want to copy them by hand.
Andrew Veliath (veliaa@rpi.edu)
January 25, 1997
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This is my port of Spice3f4 to Linux. It required a few more changes
than the porting document indicated would be necessary, mostly to do
with supported/unsupported functions in Linux libc & libm.
I've tried to make these changes in as as portable a way as possible,
so it should build cleanly on other Unicies, however I've removed the
MS-DOS support so the tarred and gziped source fits on one disk.
To build spice3, first have a look in the file readme, but you should
be able to just do...
./util/build linux
./util/build install linux
Note that there is a modifyer "gcc" you can try if you have trouble, but
it claims to work around some obscure bug in gcc that I'm positive got
fixed eons ago. To use it anyway, do ./util/build linux gcc.
I found this source through archie, (look for spice3f3.tar.Z, and then
patched it to 3f4 with patches from ic.berkeley.edu), I assume that the
ftp site I got it from has read thier license from Berkeley, which if
it's the same as the 3e2 license states that the holder can distribute
copies free of charge provided it does not fall into hands unfriendly
to the U.S. So... I guess if that's you, please destroy all copies of this
you might have!
Jeff@EE.Ryerson.Ca

View File

@ -1,7 +0,0 @@
A note when using dbx (under unix-type operating systems) to debug spice3:
To avoid a segmentation fault in the initial run, use the following command
in dbx:
setenv SPICE_NO_DATASEG_CHECK "1"
Or, the comparable command in your shell before running dbx. This
disable accurate tracking of how much memory is used.

View File

@ -1,98 +0,0 @@
Internal Changes from 3e2
The device structure has changed: The state counter in all device
structures has been moved to correspond to GENstates in the
GENinstance structure.
Also, a new per-device-type function has been added: XXXunsetup,
which deallocates nodes and other resources created in the
XXXsetup function. ("XXX" is the device abbreviation.)
Internal Changes from 3d2
FILE NAMES:
Of the changes to spice3 between 3d2 and 3e1, the
the most obvious is the new filenames. All filesnames
have been converted to lowercase and are at most eight
characters plus an optional dot and three character extension.
This change was made to accomodate MS-DOS and other operating
systems which limit the maximum file name length.
ORGANIZATION
The top level directory contains the installation "readme" file
and a "makedefs" files used by the "build" command.
"src/" contains all of the C source code. This used to be named
"spice3" or "spice3d2" in previous releases.
"src/lib" is the library or "toolkit" portion of Spice3. Within
it are the following subdirectories:
ckt/ All of the analysis code.
ni/ Numerical algorithms (used by ckt routines).
sparse/ Sparse matrix package (used by ckt and ni).
misc/ Miscellaneous utility and portability routines.
dev/ All of the device specific code, with a subdir for
each device implementation.
inp/ Input parsing; could be much smaller.
fte/ The front end. Really bad.
cp/ More front end -- "C shell".
hlp/ The windowed help system.
mfb/ Terminal independant graphics package.
mfbpc/ MFB interface for the IBM PC.
"src/bin" contains the source for all executable programs (the
location for "main( )"). "main.c" is used by spice, nutmeg,
bspice, and cspice (the latter two for MS-DOS). The function
of "main.c" is altered by defining the pre-processor symbols
SIMULATOR (for either spice, bspice, or cspice), BATCH for
bspice, and BATCH and SPICE2 for cspice (no special defines
give nutmeg). Each variant of the simulator uses "conf.c" (or
"bconf.c" or "cconf.c", or "nconf.c" for nutmeg), which is
automatically generated from "config.c". "config.c" is a
template used to select devices and analyses. "tune.c"
("tunepc.c") contains the compiled in pathnames.
"examples/" contains several spice input files.
"lib/" contains standard data files for spice, such as the help
files and MFB capability files.
"man/" contains UNIX style manual pages (ala "man(1)").
"util/" contains utility scripts, such as "build" for running the
recursive "make" and "delall.bat" for deleting the distribution on
MS-DOS systems.
All "Makefile"s have been replaced with "makedefs" (and optionally
"depend" and "makeops"). "makedefs" is combined with other
make definition files with the "build" script.
SOURCE LEVEL CHANGES
(Added features are listed in the "README" file).
DEVICES: The interface to devices has, once again, changed.
The change is small from 3d2. Table size values in the device
information struction are now pointers to integers containing
the table sizes. Per-analyses functions have been surrounded
with "#ifdef AN_xx"/"#else"/"#endif" lines. Note that the
"itf.h" files are stored only in the "include/" subdirectory.
Adding devices to the master list is done in the file
"src/bin/config.c", instead of "FTE/SPIinit.c".
SPARSE MATRIX PACKAGE: the sparse matrix package in Spice3e1
and later is a more efficient implementation than in earlier releases.
The interface is the same.

View File

@ -1,207 +0,0 @@
Compiling spice with Think C on a Macintosh.
A 68020 (Mac II) with co-processor is required.
The src directory from the spice distribution should be moved into
the C folder.
**** recompile think c libraries ****
Both the ANSI and unix libraries must be recompiled with the
following additional compiler settings:
Generate 68020 instructions
Generate 68881 instructions
4-bytes ints
Native floating-point format
The "console.c" file must be edited and should be removed from
the ANSI project. I actually recompiled copies of the ANSI and
unix libraries that I called ANSI.68881 and unix.68881.
Copy the "console.c" source (a THINK C file) to a suitable
location so that it can be included in the spice project. (See
the next section for details of how "consol.c" must be modified.)
**** creating the project ****
Create a new project and set the Options as follows:
Laguage Settings
Turn on the following options
Define #__STDC__
Recognize trigraphs
enums are always ints
Check pointer types
Language Extension
THINK C
Compiler Settings
Turn on the following options
Generate 68020 instructions
Generate 68881 instructions
4-bytes ints
Native floating-point format
Code Optimization
Turn on all options
Prefix
make sure there is no prefix (remove
default #include <macheaders>)
Note: The Language setting 'Strict Prototype Enforcement' must be
turned off.
Set the project type to application with at least 1024k partition
and turn on the 'Far DATA' option.
*** Adding the code to the project ***
Start Adding the code to the project. The code must be divided
into segments that are less that 32K each when compiled. The
following division has been used:
Segment 1: the ANSI.68881 and unix.68881 libraries.
Segment 2: all *.c files in /src/sparse
Segment 3: all *.c files in /src/lib/ni
Segment 4: all *.c files in /src/lib/misc
Segment 5: files /src/lib/inp/inp2dot.c
and /src/lib/inp/inptree.c
Segment 6: all other *.c files in /src/inp
Segment 7: all *.c files in /src/lib/hlp
Segment 8: all *.c files in /src/lib/cp
except /src/lib/cp/input.c
Segment 9: file /src/lib/ckt/dloadfns.c
Segment 10: files /src/lib/ckt/cktpzstr.c,
/src/lib/ckt/cktsens.c, /src/lib/ckt/dctran.c,
and /src/lib/ckt/distoan.c
Segment 11: all other *.c files in /src/lib/ckt
Segment 12: cmath*.c files in /src/lib/fte
Segment 13: files agraf.c, clip.c, display.c, graf.c,
graphdb.c, plot5.c, plotcurv.c and
postsc.c in /src/lib/fte
Segment 14: files evaluate.c, parse.c, postcoms.c,
and subckt.c in /src/lib/fte
Segment 15: files breakp.c, device.c, doplot.c,
grid.c and shyu.c in /src/lib/fte
Segment 16: files dotcards.c, inp.c, outif.c, rawfile.c,
spiceif.c and vectors.c in /src/lib/fte
Segment 17: all other *.c files in /src/lib/fte
except nutmegif.c
Segment 18: all *.c files in /src/lib/fte/vsrc
and /src/lib/fte/isrc
Segment 19: all *.c files in /src/lib/fte/jfet
Segment 20: all *.c files in /src/lib/fte/vccs,
/src/lib/fte/vcvs, /src/lib/fte/cccs,
and /src/lib/fte/ccvs
Segment 21: all *.c files in /src/lib/fte/asrc
and /src/lib/fte/urc
Segment 22: all *.c files in /src/lib/fte/cap,
/src/lib/fte/ind, and /src/lib/fte/res
Segment 23: all *.c files in /src/lib/fte/csw,
/src/lib/fte/sw, and /src/lib/fte/tra
Segment 24: all *.c files in /src/lib/fte/mos6
Segment 25: all *.c files in /src/lib/fte/mes
Segment 26: all *.c files in /src/lib/fte/ltra
Segment 27: file mos3load.c in /src/lib/fte/mos3
Segment 28: files mos3dist.c, mos3dset.c,
and mos3sld.c in /src/lib/fte/mos3
Segment 29: remaining *.c files in /src/lib/fte/mos3
Segment 30: all *.c files in /src/lib/fte/dio
Segment 31: file mos1load.c in /src/lib/fte/mos1
Segment 32: files mos1dist.c, mos1dset.c,
and mos1sld.c in /src/lib/fte/mos1
Segment 33: remaining *.c files in /src/lib/fte/mos1
Segment 34: file bjtload.c in /src/lib/fte/bjt
Segment 35: files bjtdisto.c, bjtdset.c,
and bjtsload.c in /src/lib/fte/bjt
Segment 36: remaining *.c files in /src/lib/fte/bjt
Segment 37: file mos2load.c in /src/lib/fte/mos2
Segment 38: file mos2dset.c in /src/lib/fte/mos2
Segment 39: files mos2dist.c, and mos2sld.c
in /src/lib/fte/mos2
Segment 40: remaining *.c files in /src/lib/fte/mos2
Segment 41: files b1dset.c, and b1ld.c in /src/lib/fte/bsim1
Segment 42: files b1disto.c, and b1eval.c in /src/lib/fte/bsim1
Segment 43: remaining *.c files in /src/lib/fte/bsim1
Segment 44: files b2eval.c, and b2ld.c in /src/lib/fte/bsim2
Segment 45: remaining *.c files in /src/lib/fte/bsim2
Segment 46: all *.c files in /src/lib/dev/disto,
and devsup.c in /src/lib/dev
Segment 47 all *.c files in /src/lib/mac,
and file /src/bin/main.c
Note that the following files are not included:
/src/lib/cp/input.c
/src/lib/fte/nutmegif.c
Add "console.c" (the copy made as described above) and make the
following alterations to it:
1. The lines:
static char console_environment, noPrint, interrupted;
static short console_refnum;
static MenuHandle appleMenu;
static WindowPeek theConsole;
must be changed to make console_environment and
appleMenu external:
extern char console_environment, noPrint, interrupted;
static char noPrint, interrupted;
static short console_refnum;
extern MenuHandle appleMenu;
static WindowPeek theConsole;
2. Alter the function ProcessEvent() to add a default switch
case. The altered section appears following a doEvent label as
(note: this code fragment has 4-space tabs and long lines
broken to fit an 80-column page; these changes do not affect
the code):
doEvent:
if (event.what == mouseDown) {
switch (FindWindow(event.where, &wp)) {
case inMenuBar:
InitCursor();
choice = MenuSelect(event.where);
goto doMenu;
case inSysWindow:
SystemClick(&event, wp);
break;
default: /* For spice to pass mouse
events to graphs */
if ((WindowPtr) wp != FrontWindow()) {
SelectWindow(wp);
in.cnt = 0;
} /* in.cnt=0 forces console to
return to application */
}
}
Compilation takes about 3 to 4 hours on a 25MHz mac. Set the cache
to at least 256k to eliminate a lot of disk access.
**** makeindx ****
Create a project with the same option settings decribed above.
Add src/bin/makeidx.c, ANSI.68881 and an unmodified version of
"console.c".
Build the makeindex application.
Move the application into lib/helpdir directory of the the spice
distribution. Run it and add the names of the files to be indexed
(nutmeg.txt spice.txt) to the command line and hit return.
**** proc2mod ****
Create a project with the same option settings decribed above.
Add src/bin/proc2mod.c, src/lib/misc/alloc.c, src/lib/misc/string.c
src/lib/inp/inpcfix.c, src/lib/inp/inpeval.c,
src/lib/inp/inpgtok.c, ANSI.68881 and an unmodified
version of console.c.
Build the proc2mod application.

View File

@ -1,237 +0,0 @@
(ER - 7/08/99)
These are a few notes on the autoconf porting that is being done.
Autoconf automaticcaly provides #defines (in config.h) that describe
the system that ng-spice is being compiled on. Thus, all the os_xxx.h
files should no longer be necessary.
Here is a (as complete as possible) list of new #defines and their
corresponding #defines in the old build system:
#define HAS_VAX_FPERRORS - unused (should remove the code)
#define MAXPOSINT 4294967295 - don't know about that one
#define MAX_EXP_ARG 87.0 - same
---------- Operating System (os_xxx.h) parameters:
----- Enabling flags
#define AVAIL_MFB -DWANT_MFB passed to cpp
#define AVAIL_X11 X_DISPLAY_MISSING (reversed)
----- String or character constants
#define DIR_CWD "." now in spice.h
#define DIR_PATHSEP "/" now in spice;h
#define DIR_TERM '/' now in spice.h
On Unix, I don't think that there are other possibilities.
We should get rid of those.
----- sprintf( ) format strings
#define TEMPFORMAT "/tmp/%s%d" /* sprintf format for creating temp files */
#define SYSTEM_MAIL "mail -s \"%s (%s) Bug Report\" %s" /* mail command */
#define SYSTEM_PLOT5LPR "lpr -P%s -g %s" /* For printing Unix plot(5) files */
#define SYSTEM_PSLPR "lpr -P%s %s" /* For printing postscript files */
Same for these I guess...
----- System capabilities
#define HAS_ACCESS HAVE_ACCES
#define HAS_ASCII not handled yet
#define HAS_ATRIGH HAVE_ATANH HAVE_ACOSH HAVE_ASINH
#define HAS_BCOPY HAVE_BCOPY
#define HAS_BSDDIRS HAVE_DIR_H
#define HAS_BSDRANDOM unused
#define HAS_BSDRLIMIT HAVE_GETRLIMIT
#define HAS_BSDRUSAGE HAVE_GETRUSAGE
#define HAS_BSDSOCKETS unused
#define HAS_BSDTIME HAVE_GETTIMEOFDAY
#define HAS_BSDTTY HAVE_SGTTY_H
#define HAS_CHDIR removed
#define HAS_CLEARERR removed
#define HAS_CTYPE HAVE_CTYPE_H
#define HAS_DOSDIRS dos only - should remove code
#define HAS_DUP2 HAVE_DUP2
#define HAS_ENVIRON removed
#define HAS_EXIT1 vms only - should remove the code
#define HAS_FCNTL HAVE_FCNTL_H
#define HAS_FTIME HAVE_FTIME
#define HAS_GETCWD HAVE_GETCWD
#define HAS_GETPID removed
#define HAS_GETPW HAVE_PWD_H
#define HAS_GETWD HAVE_GETWD
#define HAS_INDEX HAVE_INDEX
#define HAS_NO_IEEE_LOGB HAVE_LOGB HAVE_SCALB HAVE_SCALBN
#define HAS_NO_IEEE_LOGB_DECL removed
#define HAS_ISATTY HAVE_ISATTY
#define HAS_LONGJUMP removed
#define HAS_MINDATA dos only? - should remove code if so
#define HAS_NOINLINE dos only? - should remove code if so
#define HAS_NOVM dos only? - should remove code if so
#define HAS_NO_ATRIGH_DECL removed
#define HAS_PCTERM dos only - should remove code
#define HAS_POPEN HAVE_POPEN
#define HAS_QSORT HAVE_QSORT
#define HAS_SHORTMACRO dos only - should remove code
#define HAS_STAT STAT_MACROS_BROKEN (reversed)
#define HAS_STDLIB STDC_HEADERS
#define HAS_STRCHR HAVE_STRCHR
#define HAS_STRINGS STDC_HEADERS (reversed) not sure about that one!
#define HAS_SYSTEM removed
#define HAS_SYSVDIRS HAVE_DIRENT_H
#define HAS_SYSVRLIMIT HAVE_ULIMIT
#define HAS_SYSVRUSAGE HAVE_UTIME
#define HAS_SYSVTIME HAVE_TIME
#define HAS_SYSVTTY HAVE_TERMIO_H
#define HAS_TERMCAP HAVE_TERMCAP
#define HAS_TERMREAD don't know what to do with this one
#define HAS_UNIX_SIGS removed
#define HAS_UNLINK removed
#define HAS_VFORK HAVE_VFORK_H
#define HAS_VMSHACK vms only - should remove the code
#define HAS_VPERROR removed
#define HAS_WAIT HAVE_WAIT
plus a few others:
#define HAS_MEMAVL dos only - should remove code
#define HAS_FLAT_INCLUDES macos only - should remove code
#define HAS_BATCHSIM dos only - should remove code
----------------------------------------------------------------------------
PORTING SPICE3e1
Porting Spice3 to a new operating system usually consists of listing
the capabilities of that operating system in a new '.h' file and
including this '.h' file in the standard portability sequence. This
also needs to be done separately for the numerical capabilities of the
system hardware (this consist of only two parameters at present).
For each operating system there is a file in the "include/" directory
named "os_xxx.h", where xxx identifies the given operating system (ex.
"os_bsd.h", "os_aix.h"). These files are selectively #include-d by
"include/port.h". For a new operating system, you should add the
appropriate "#include" line to "include/port.h". Be sure to guard
the new "#include" line with "#ifdef/#endif", as is done with the other
operating system capability files. The same may also need to be done
for your hardware (for the file "hw_xxx.h"), though there is typically
very little difference in hardware.
Note that operating system which are a derivative of another supported
system can '#include' the "os_xxx.h" file from the other system. For
example, "os_aix.h" includes "os_sysv.h", which in turn includes
"os_unix.h".
The entries that can go into a "os_xxx.h" file are described below;
most are simple flags (e.g. HAS_xxxx). To turn on a flag, insert the
"#define" line for that flag; to turn off the flag, simply leave the
"#define" line out. Other entries are strings, others single-quoted
characters or numbers. Be sure to use the same type as the example
values shown.
There are always exceptions to the rule. Some incompatibilities
have not yet been dealt with cleanly; review the other "os_xxx.h"
files, the file "capabil.h", and the file "suffix.h" to understand
how some problems have been handled (note especially the lines like
"#define index strchr"). After trying to compile, you may yet find
non-portable code that is not guarded by one of the following
options. You are encouraged to alter the source code (".c" or ".h"
files) in the style of the current portability scheme.
Note: to enable X11 or MFB, the flag AVAIL_X11 or AVAIL_MFB,
respectively, must be included in the "os_xxx.h" file; this _was_ to
simplify the problems of forgetting to re-edit the "config.h" file,
but this is no longer necessary.
---------- Machine architecture numerics (hw_xxx.h) parameters:
(In the future this will be more complete and will be used for
tuning the accuracy or performance of the numerical algorithms)
#define HAS_VAX_FPERRORS /* Only for Vax */
#define MAXPOSINT 4294967295 /* == 2^32 - 1, maximum positive integer */
#define MAX_EXP_ARG 87.0 /* Approximate largest arg to exp() */
---------- Operating System (os_xxx.h) parameters:
----- Enabling flags
#define AVAIL_MFB /* If the MFB package can work on this system */
#define AVAIL_X11 /* If the X11 Window System can work */
----- String or character constants
#define DIR_CWD "." /* Current working directory */
#define DIR_PATHSEP "/" /* subdirectory separator */
#define DIR_TERM '/' /* Subdirectory component terminator */
----- sprintf( ) format strings
#define TEMPFORMAT "/tmp/%s%d" /* sprintf format for creating temp files */
#define SYSTEM_MAIL "mail -s \"%s (%s) Bug Report\" %s" /* mail command */
#define SYSTEM_PLOT5LPR "lpr -P%s -g %s" /* For printing Unix plot(5) files */
#define SYSTEM_PSLPR "lpr -P%s %s" /* For printing postscript files */
----- System capabilities
#define HAS_ACCESS /* access( ) */
#define HAS_ASCII /* eighth bit of a character is not used */
#define HAS_ATRIGH /* acosh( ), asinh( ), atanh( ) */
#define HAS_BCOPY /* bcopy( ), bzero( ) */
#define HAS_BSDDIRS /* <sys/dir.h> */
#define HAS_BSDRANDOM /* srandom( ) and random( ) */
#define HAS_BSDRLIMIT /* getrlimit( ) returns proc limits */
#define HAS_BSDRUSAGE /* getrusage( ) returns cpu usage */
#define HAS_BSDSOCKETS /* <net/inet.h>, socket( ), etc. */
#define HAS_BSDTIME /* gettimeofday( ) return time */
#define HAS_BSDTTY /* <sgtty.h> */
#define HAS_CHDIR /* for tree filesystems, chdir( ) */
#define HAS_CLEARERR /* clearerr( ), should be in stdio */
#define HAS_CTYPE /* <ctype.h>, iswhite( ), etc. */
#define HAS_DOSDIRS /* Emulate opendir, etc. */
#define HAS_DUP2 /* dup2(a, b) for shifting file descrs. */
#define HAS_ENVIRON /* getenv( ) */
#define HAS_EXIT1 /* If exit status of 1 is normal for procs */
#define HAS_FCNTL /* acosh( ), asinh( ), atanh( ) */
#define HAS_FTIME /* ftime( ), <times.h> */
#define HAS_GETCWD /* getcwd(buf, size) */
#define HAS_GETPID /* getpid( ) to identify processes */
#define HAS_GETPW /* getpwuid( ), etc. */
#define HAS_GETWD /* getwd(buf) */
#define HAS_INDEX /* index( ) instead of strchr( ) */
#define HAS_NO_IEEE_LOGB /* no logb( ) and scalb( ) functions */
#define HAS_NO_IEEE_LOGB_DECL /* logb( ) and scalb( ) not in math.h */
#define HAS_ISATTY /* isatty( ) */
#define HAS_LONGJUMP /* setjmp( ), longjmp( ) */
#define HAS_MINDATA /* Machine has limited data area */
#define HAS_NOINLINE /* Machine has limited data area */
#define HAS_NOVM /* Machine has limited data area */
#define HAS_NO_ATRIGH_DECL /* if asinh( ) is not in math.h */
#define HAS_PCTERM /* For MS-DOS, use PC graphics for MFB */
#define HAS_POPEN /* popen( ), pipe through shell command */
#define HAS_QSORT /* qsort( ) exists */
#define HAS_SHORTMACRO /* If the compiler can't handle long macros */
#define HAS_STAT /* stat( ) returns info on files */
#define HAS_STDLIB /* #include <stdlib.h> for libc defs */
#define HAS_STRCHR /* strchr( ) instead of index( ) */
#define HAS_STRINGS /* #include <strings.h> (else <string.h>) */
#define HAS_SYSTEM /* system( ), execute system command */
#define HAS_SYSVDIRS /* <dirent.h> */
#define HAS_SYSVRLIMIT /* ulimit( ) reports on proc size limit */
#define HAS_SYSVRUSAGE /* utimes( ) reports on cpu usage */
#define HAS_SYSVTIME /* time( ) returns seconds from 1970 */
#define HAS_SYSVTTY /* <termio.h> */
#define HAS_TERMCAP /* tgetxxx( ) */
#define HAS_TERMREAD /* Has "read" syscall from terminals */
#define HAS_UNIX_SIGS /* signal( ), kill( ) */
#define HAS_UNLINK /* unlink( ), for removing files */
#define HAS_VFORK /* BSD-ism, should not be necessary */
#define HAS_VMSHACK /* Stand on your head for VMS */
#define HAS_VPERROR /* perror( ) defined by standard '.h's */
#define HAS_WAIT /* wait( ) wait for processes */

View File

@ -1,15 +0,0 @@
Incompatibilities between spice3 and spice2
The output format of spice3 is slightly different for .print and .plot lines.
Most notably, different traces on plots are not scaled independently. This
is most noticeable on phase/magnitude plots from an AC analysis (also,
phase is displayed in radians). Finally, frequency for ".PRINT AC" lines
is displayed as a complex quantity with an all-zero imaginary component.
For input, "POLY( )" sources are not supported (the non-linear dependent
source provides a more general replacement). Also, the ".ALTER" line
is not supported. The Spice3 parser may be slightly different
on subtle points of reading input (lines need not start at column 1
for instance).

View File

@ -1,60 +0,0 @@
2000-04-04 Paolo Nenzi <p.nenzi@ieee.or
* noisean.c: Merged the previous code with the new one included in
bsim4 distribution. This code originated from Weidong Lu
(bsim group).
1999-12-20 Paolo Nenzi <p.nenzi@ieee.org>
* noisean.c:
Bug: he ac noise analysis in Spice3f4 has a serious bug. In interactive mode,
it fails to reproduce frequency dependence known to exist. In batch (Spice2)
mode, it works only if a corresponding ac analysis has been run first.
Fix: This bug is fixed by providing a call to CKTload() in noisean.c as shown
by the source code patch which is attached below.
1999-09-08 Emmanuel Rouat <emmanuel.rouat@wanadoo.fr>
* ckt.h: created (and included in Makefile.am)
1999-09-07 Arno <A.W.Peters@ieee.org>
* cktpzstr.c: reformatted and corrected(?) complex if condition.
1999-08-28 Emmanuel Rouat <emmanuel.rouat@wanadoo.fr>
* Removed all #includes of misc.h and util.h (now in spice.h)
1999-08-27 Paolo Nenzi <pnenzi@ieee.ing.uniroma1.it>
* Removed GENERIC and #include "suffix.h" from all the files.
GENERIC has been replaced by void. ANSIfied all functions with
protoize.
1999-08-26 Paolo Nenzi <pnenzi@ieee.ing.uniroma1.it>
* cktacct.c: added #include "spmatrix.h" to avoid implicit declaration
warning at compile time.
* dctran.c: ansified and substituted void with void.
* tranasq.c: same as before.
* traninit.c: same as before.
* transetp.c: same as before.
1999-08-08 Emmanuel Rouat <emmanuel.rouat@wanadoo.fr>
* Removed all HAS_SHORTMACRO and HAS_FLATINCLUDES code in directory
* cktdest.c (and other files): changed HAS_SENSE2 in WANT_SENSE2
1999-08-04 Paolo Nenzi <pnenzi@ieee.ing.uniroma1.it>
* changed dctrcurv.c: added code for temperature sweeps and
resistance sweeps. Now you can execute .dc temp <start> <stop>
<increment> to do a temp sweep, temp is the keyword for temp
sweeps (The code comes from a patch supplied by Serban-Mihai
Popescu <serbanp@ix.netcom.com>. To do a resitance sweep just
insert resistor name to the .cd line:.dc vin -5 5 1 rin 100 1000 10.
Resistance and temperature sweeps can be nested.

View File

@ -1,106 +0,0 @@
## Process this file with automake to produce Makefile.in
noinst_LIBRARIES = libckt.a
libckt_a_SOURCES = \
acan.c \
acaskq.c \
acsetp.c \
cktaccpt.c \
cktacct.c \
cktacdum.c \
cktask.c \
cktaskaq.c \
cktasknq.c \
cktbindn.c \
cktbkdum.c \
cktclrbk.c \
cktcrte.c \
cktdelt.c \
cktdest.c \
cktdisto.c \
cktdlti.c \
cktdltm.c \
cktdltn.c \
cktdojob.c \
cktdump.c \
cktfbran.c \
cktfdev.c \
cktfnda.c \
cktfndm.c \
cktfnode.c \
cktftask.c \
cktgrnd.c \
ckti2nod.c \
cktic.c \
cktinit.c \
cktlnkeq.c \
cktload.c \
cktmapn.c \
cktmask.c \
cktmcrt.c \
cktmkcur.c \
cktmknod.c \
cktmkvol.c \
cktmpar.c \
cktnames.c \
cktnewan.c \
cktneweq.c \
cktnewn.c \
cktnodn.c \
cktnoise.c \
cktntask.c \
cktnum2n.c \
cktop.c \
cktparam.c \
cktpartn.c \
cktpmnam.c \
cktpname.c \
cktpzld.c \
cktpzset.c \
cktpzstr.c \
cktsens.c \
cktsetap.c \
cktsetbk.c \
cktsetnp.c \
cktsetup.c \
cktsgen.c \
cktsopt.c \
ckttemp.c \
cktterr.c \
ckttroub.c \
ckttrunc.c \
ckttyplk.c \
daskq.c \
dcoaskq.c \
dcop.c \
dcosetp.c \
dctaskq.c \
dctran.c \
dctrcurv.c \
dctsetp.c \
distoan.c \
dkerproc.c \
dloadfns.c \
dsetparm.c \
naskq.c \
nevalsrc.c \
ninteg.c \
noisean.c \
nsetparm.c \
pzan.c \
pzaskq.c \
pzsetp.c \
sensaskq.c \
senssetp.c \
tfanal.c \
tfaskq.c \
tfsetp.c \
tranaskq.c \
traninit.c \
transetp.c \
ckt.h
INCLUDES = -I$(top_srcdir)/src/include -I$(top_srcdir)/src/devices
MAINTAINERCLEANFILES = Makefile.in

View File

@ -1,277 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
#include "ngspice.h"
#include <stdio.h>
#include "cktdefs.h"
#include "acdefs.h"
#include "devdefs.h"
#include "sperror.h"
int
ACan(CKTcircuit *ckt, int restart)
{
double freq;
double freqTol; /* tolerence parameter for finding final frequency */
double startdTime;
double startsTime;
double startlTime;
double startcTime;
double startkTime;
double startTime;
int error;
int numNames;
IFuid *nameList;
IFuid freqUid;
static void *acPlot;
void *plot;
if(((ACAN*)ckt->CKTcurJob)->ACsaveFreq == 0 || restart) {
/* start at beginning */
if (((ACAN*)ckt->CKTcurJob)->ACnumberSteps < 1)
((ACAN*)ckt->CKTcurJob)->ACnumberSteps = 1;
switch(((ACAN*)ckt->CKTcurJob)->ACstepType) {
case DECADE:
((ACAN*)ckt->CKTcurJob)->ACfreqDelta =
exp(log(10.0)/((ACAN*)ckt->CKTcurJob)->ACnumberSteps);
break;
case OCTAVE:
((ACAN*)ckt->CKTcurJob)->ACfreqDelta =
exp(log(2.0)/((ACAN*)ckt->CKTcurJob)->ACnumberSteps);
break;
case LINEAR:
if (((ACAN*)ckt->CKTcurJob)->ACnumberSteps-1 > 1)
((ACAN*)ckt->CKTcurJob)->ACfreqDelta =
(((ACAN*)ckt->CKTcurJob)->ACstopFreq -
((ACAN*)ckt->CKTcurJob)->ACstartFreq)/
(((ACAN*)ckt->CKTcurJob)->ACnumberSteps-1);
else
((ACAN*)ckt->CKTcurJob)->ACfreqDelta = HUGE;
break;
default:
return(E_BADPARM);
}
error = CKTop(ckt,
(ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITJCT,
(ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITFLOAT,
ckt->CKTdcMaxIter);
if(error) return(error);
ckt->CKTmode = (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITSMSIG;
error = CKTload(ckt);
if(error) return(error);
error = CKTnames(ckt,&numNames,&nameList);
if(error) return(error);
if (ckt->CKTkeepOpInfo) {
/* Dump operating point. */
error = (*(SPfrontEnd->OUTpBeginPlot))((void *)ckt,
(void*)ckt->CKTcurJob, "AC Operating Point",
(IFuid)NULL,IF_REAL,numNames,nameList, IF_REAL,&plot);
if(error) return(error);
CKTdump(ckt,(double)0,plot);
(*(SPfrontEnd->OUTendPlot))(plot);
}
(*(SPfrontEnd->IFnewUid))((void *)ckt,&freqUid,(IFuid)NULL,
"frequency", UID_OTHER,(void **)NULL);
error = (*(SPfrontEnd->OUTpBeginPlot))((void *)ckt,
(void*)ckt->CKTcurJob,
ckt->CKTcurJob->JOBname,freqUid,IF_REAL,numNames,nameList,
IF_COMPLEX,&acPlot);
if(error) return(error);
if (((ACAN*)ckt->CKTcurJob)->ACstepType != LINEAR) {
(*(SPfrontEnd->OUTattributes))((void *)acPlot,NULL,
OUT_SCALE_LOG, NULL);
}
freq = ((ACAN*)ckt->CKTcurJob)->ACstartFreq;
} else { /* continue previous analysis */
freq = ((ACAN*)ckt->CKTcurJob)->ACsaveFreq;
((ACAN*)ckt->CKTcurJob)->ACsaveFreq = 0; /* clear the 'old' frequency */
}
switch(((ACAN*)ckt->CKTcurJob)->ACstepType) {
case DECADE:
case OCTAVE:
freqTol = ((ACAN*)ckt->CKTcurJob)->ACfreqDelta *
((ACAN*)ckt->CKTcurJob)->ACstopFreq * ckt->CKTreltol;
break;
case LINEAR:
freqTol = ((ACAN*)ckt->CKTcurJob)->ACfreqDelta * ckt->CKTreltol;
break;
default:
return(E_BADPARM);
}
startTime = SPfrontEnd->IFseconds();
startdTime = ckt->CKTstat->STATdecompTime;
startsTime = ckt->CKTstat->STATsolveTime;
startlTime = ckt->CKTstat->STATloadTime;
startcTime = ckt->CKTstat->STATcombineTime;
startkTime = ckt->CKTstat->STATsyncTime;
while(freq <= ((ACAN*)ckt->CKTcurJob)->ACstopFreq+freqTol) {
if( (*(SPfrontEnd->IFpauseTest))() ) {
/* user asked us to pause via an interrupt */
((ACAN*)ckt->CKTcurJob)->ACsaveFreq = freq;
return(E_PAUSE);
}
ckt->CKTomega = 2.0 * M_PI *freq;
ckt->CKTmode = (ckt->CKTmode&MODEUIC) | MODEAC;
error = NIacIter(ckt);
if (error) {
ckt->CKTcurrentAnalysis = DOING_AC;
ckt->CKTstat->STATacTime += SPfrontEnd->IFseconds() - startTime;
ckt->CKTstat->STATacDecompTime += ckt->CKTstat->STATdecompTime -
startdTime;
ckt->CKTstat->STATacSolveTime += ckt->CKTstat->STATsolveTime -
startsTime;
ckt->CKTstat->STATacLoadTime += ckt->CKTstat->STATloadTime -
startlTime;
ckt->CKTstat->STATacCombTime += ckt->CKTstat->STATcombineTime -
startcTime;
ckt->CKTstat->STATacSyncTime += ckt->CKTstat->STATsyncTime -
startkTime;
return(error);
}
#ifdef WANT_SENSE2
if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode&ACSEN) ){
save = ckt->CKTmode;
ckt->CKTmode=(ckt->CKTmode&MODEUIC)|MODEDCOP|MODEINITSMSIG;
save1 = ckt->CKTsenInfo->SENmode;
ckt->CKTsenInfo->SENmode = ACSEN;
if(freq == ((ACAN*)ckt->CKTcurJob)->ACstartFreq){
ckt->CKTsenInfo->SENacpertflag = 1;
}
else{
ckt->CKTsenInfo->SENacpertflag = 0;
}
if(error = CKTsenAC(ckt)) return (error);
ckt->CKTmode = save;
ckt->CKTsenInfo->SENmode = save1;
}
#endif
error = CKTacDump(ckt,freq,acPlot);
if (error) {
ckt->CKTcurrentAnalysis = DOING_AC;
ckt->CKTstat->STATacTime += SPfrontEnd->IFseconds() - startTime;
ckt->CKTstat->STATacDecompTime += ckt->CKTstat->STATdecompTime -
startdTime;
ckt->CKTstat->STATacSolveTime += ckt->CKTstat->STATsolveTime -
startsTime;
ckt->CKTstat->STATacLoadTime += ckt->CKTstat->STATloadTime -
startlTime;
ckt->CKTstat->STATacCombTime += ckt->CKTstat->STATcombineTime -
startcTime;
ckt->CKTstat->STATacSyncTime += ckt->CKTstat->STATsyncTime -
startkTime;
return(error);
}
/* increment frequency */
switch(((ACAN*)ckt->CKTcurJob)->ACstepType) {
case DECADE:
case OCTAVE:
freq *= ((ACAN*)ckt->CKTcurJob)->ACfreqDelta;
if(((ACAN*)ckt->CKTcurJob)->ACfreqDelta==1) goto endsweep;
break;
case LINEAR:
freq += ((ACAN*)ckt->CKTcurJob)->ACfreqDelta;
if(((ACAN*)ckt->CKTcurJob)->ACfreqDelta==0) goto endsweep;
break;
default:
return(E_INTERN);
}
}
endsweep:
(*(SPfrontEnd->OUTendPlot))(acPlot);
ckt->CKTcurrentAnalysis = 0;
ckt->CKTstat->STATacTime += SPfrontEnd->IFseconds() - startTime;
ckt->CKTstat->STATacDecompTime += ckt->CKTstat->STATdecompTime -
startdTime;
ckt->CKTstat->STATacSolveTime += ckt->CKTstat->STATsolveTime -
startsTime;
ckt->CKTstat->STATacLoadTime += ckt->CKTstat->STATloadTime -
startlTime;
ckt->CKTstat->STATacCombTime += ckt->CKTstat->STATcombineTime -
startcTime;
ckt->CKTstat->STATacSyncTime += ckt->CKTstat->STATsyncTime -
startkTime;
return(0);
}
/* CKTacLoad(ckt)
* this is a driver program to iterate through all the various
* ac load functions provided for the circuit elements in the
* given circuit
*/
int
CKTacLoad(register CKTcircuit *ckt)
{
extern SPICEdev *DEVices[];
register int i;
register int size;
int error;
#ifdef PARALLEL_ARCH
long type = MT_ACLOAD, length = 1;
#endif /* PARALLEL_ARCH */
double startTime;
startTime = SPfrontEnd->IFseconds();
size = SMPmatSize(ckt->CKTmatrix);
for (i=0;i<=size;i++) {
*(ckt->CKTrhs+i)=0;
*(ckt->CKTirhs+i)=0;
}
SMPcClear(ckt->CKTmatrix);
for (i=0;i<DEVmaxnum;i++) {
if ( ((*DEVices[i]).DEVacLoad != NULL) && (ckt->CKThead[i] != NULL) ){
error = (*((*DEVices[i]).DEVacLoad))(ckt->CKThead[i],ckt);
#ifdef PARALLEL_ARCH
if (error) goto combine;
#else
if(error) return(error);
#endif /* PARALLEL_ARCH */
}
}
#ifdef PARALLEL_ARCH
combine:
ckt->CKTstat->STATloadTime += SPfrontEnd->IFseconds() - startTime;
startTime = SPfrontEnd->IFseconds();
/* See if any of the DEVload functions bailed. If not, proceed. */
IGOP_( &type, &error, &length, "max" );
ckt->CKTstat->STATsyncTime += SPfrontEnd->IFseconds() - startTime;
if (error == OK) {
startTime = SPfrontEnd->IFseconds();
SMPcCombine( ckt->CKTmatrix, ckt->CKTrhs, ckt->CKTrhsSpare,
ckt->CKTirhs, ckt->CKTirhsSpare );
ckt->CKTstat->STATcombineTime += SPfrontEnd->IFseconds() - startTime;
return(OK);
} else {
return(error);
}
#else
ckt->CKTstat->STATloadTime += SPfrontEnd->IFseconds() - startTime;
return(OK);
#endif /* PARALLEL_ARCH */
}

View File

@ -1,63 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/*
*/
#include "ngspice.h"
#include <stdio.h>
#include "ifsim.h"
#include "iferrmsg.h"
#include "acdefs.h"
#include "cktdefs.h"
/* ARGSUSED */
int
ACaskQuest(CKTcircuit *ckt, void *anal, int which, IFvalue *value)
{
switch(which) {
case AC_START:
value->rValue = ((ACAN*)anal)->ACstartFreq;
break;
case AC_STOP:
value->rValue = ((ACAN*)anal)->ACstopFreq ;
break;
case AC_STEPS:
value->iValue = ((ACAN*)anal)->ACnumberSteps;
break;
case AC_DEC:
if(((ACAN*)anal)->ACstepType == DECADE) {
value->iValue=1;
} else {
value->iValue=0;
}
break;
case AC_OCT:
if(((ACAN*)anal)->ACstepType == OCTAVE) {
value->iValue=1;
} else {
value->iValue=0;
}
break;
case AC_LIN:
if(((ACAN*)anal)->ACstepType == LINEAR) {
value->iValue=1;
} else {
value->iValue=0;
}
break;
default:
return(E_BADPARM);
}
return(OK);
}

View File

@ -1,105 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
#include "ngspice.h"
#include <stdio.h>
#include "ifsim.h"
#include "iferrmsg.h"
#include "acdefs.h"
#include "cktdefs.h"
/* ARGSUSED */
int
ACsetParm(CKTcircuit *ckt, void *anal, int which, IFvalue *value)
{
switch(which) {
case AC_START:
if (value->rValue <= 0.0) {
errMsg = copy("Frequency of 0 is invalid");
((ACAN*)anal)->ACstartFreq = 1.0;
return(E_PARMVAL);
}
((ACAN*)anal)->ACstartFreq = value->rValue;
break;
case AC_STOP:
if (value->rValue <= 0.0) {
errMsg = copy("Frequency of 0 is invalid");
((ACAN*)anal)->ACstartFreq = 1.0;
return(E_PARMVAL);
}
((ACAN*)anal)->ACstopFreq = value->rValue;
break;
case AC_STEPS:
((ACAN*)anal)->ACnumberSteps = value->iValue;
break;
case AC_DEC:
if(value->iValue) {
((ACAN*)anal)->ACstepType = DECADE;
} else {
if( ((ACAN*)anal)->ACstepType == DECADE) {
((ACAN*)anal)->ACstepType = 0;
}
}
break;
case AC_OCT:
if(value->iValue) {
((ACAN*)anal)->ACstepType = OCTAVE;
} else {
if( ((ACAN*)anal)->ACstepType == OCTAVE) {
((ACAN*)anal)->ACstepType = 0;
}
}
break;
case AC_LIN:
if(value->iValue) {
((ACAN*)anal)->ACstepType = LINEAR;
} else {
if( ((ACAN*)anal)->ACstepType == LINEAR) {
((ACAN*)anal)->ACstepType = 0;
}
}
break;
default:
return(E_BADPARM);
}
return(OK);
}
static IFparm ACparms[] = {
{ "start", AC_START, IF_SET|IF_ASK|IF_REAL, "starting frequency" },
{ "stop", AC_STOP, IF_SET|IF_ASK|IF_REAL, "ending frequency" },
{ "numsteps", AC_STEPS,IF_SET|IF_ASK|IF_INTEGER, "number of frequencies"},
{ "dec", AC_DEC, IF_SET|IF_FLAG, "step by decades" },
{ "oct", AC_OCT, IF_SET|IF_FLAG, "step by octaves" },
{ "lin", AC_LIN, IF_SET|IF_FLAG, "step linearly" }
};
SPICEanalysis ACinfo = {
{
"AC",
"A.C. Small signal analysis",
sizeof(ACparms)/sizeof(IFparm),
ACparms
},
sizeof(ACAN),
FREQUENCYDOMAIN,
1,
ACsetParm,
ACaskQuest,
NULL,
ACan
};

View File

@ -1,130 +0,0 @@
/*
* Copyright (c) 1985 Thomas L. Quarles
* Modified 1999 Paolo Nenzi - Removed non STDC definitions
* Kept only prototypes (structs defined in struct.h) ER
*/
#ifndef CKT_H_INCLUDED
#define CKT_H_INCLUDED
/* function prototypes */
int ACan( CKTcircuit *, int );
int ACaskQuest( CKTcircuit *, void *, int , IFvalue *);
int ACsetParm( CKTcircuit *, void *, int , IFvalue *);
int CKTacDump( CKTcircuit *, double , void *);
int CKTacLoad( CKTcircuit *);
int CKTaccept( CKTcircuit *);
int CKTacct( CKTcircuit *, void *, int , IFvalue *);
int CKTask( void *, void *, int , IFvalue *, IFvalue *);
int CKTaskAnalQ( void *, void *, int , IFvalue *, IFvalue *);
int CKTaskNodQst( void *, void *, int , IFvalue *, IFvalue *);
int CKTbindNode( void *, void *, int , void *);
void CKTbreakDump( CKTcircuit *);
int CKTclrBreak( CKTcircuit *);
int CKTconvTest( CKTcircuit *);
int CKTcrtElt( void *, void *, void **, IFuid );
int CKTdelTask( void *, void *);
int CKTdestroy( void *);
int CKTdltAnal( void *, void *, void *);
int CKTdltInst( void *, void *);
int CKTdltMod( void *, void *);
int CKTdltNod( void *, void *);
int CKTdoJob( void *, int , void *);
void CKTdump( CKTcircuit *, double, void *);
int CKTfndAnal( void *, int *, void **, IFuid , void *, IFuid );
int CKTfndBranch( CKTcircuit *, IFuid);
int CKTfndDev( void *, int *, void **, IFuid , void *, IFuid );
int CKTfndMod( void *, int *, void **, IFuid );
int CKTfndNode( void *, void **, IFuid );
int CKTfndTask( void *, void **, IFuid );
int CKTground( void *, void **, IFuid );
int CKTic( CKTcircuit *);
int CKTinit( void **);
int CKTinst2Node( void *, void *, int , void **, IFuid *);
int CKTlinkEq(CKTcircuit*,CKTnode*);
int CKTload( CKTcircuit *);
int CKTmapNode( void *, void **, IFuid );
int CKTmkCur( CKTcircuit *, CKTnode **, IFuid , char *);
int CKTmkNode(CKTcircuit*,CKTnode**);
int CKTmkVolt( CKTcircuit *, CKTnode **, IFuid , char *);
int CKTmodAsk( void *, void *, int , IFvalue *, IFvalue *);
int CKTmodCrt( void *, int , void **, IFuid );
int CKTmodParam( void *, void *, int , IFvalue *, IFvalue *);
int CKTnames(CKTcircuit *, int *, IFuid **);
int CKTnewAnal( void *, int , IFuid , void **, void *);
int CKTnewEq( void *, void **, IFuid );
int CKTnewNode( void *, void **, IFuid );
int CKTnewTask( void *, void **, IFuid );
IFuid CKTnodName( CKTcircuit *, int );
void CKTnodOut( CKTcircuit *);
CKTnode * CKTnum2nod( CKTcircuit *, int );
int CKTop(CKTcircuit *, long, long, int );
int CKTpModName( char *, IFvalue *, CKTcircuit *, int , IFuid , GENmodel **);
int CKTpName( char *, IFvalue *, CKTcircuit *, int , char *, GENinstance **);
int CKTparam( void *, void *, int , IFvalue *, IFvalue *);
int CKTpzFindZeros( CKTcircuit *, PZtrial **, int * );
int CKTpzLoad( CKTcircuit *, SPcomplex * );
int CKTpzSetup( CKTcircuit *, int);
int CKTsenAC( CKTcircuit *);
int CKTsenComp( CKTcircuit *);
int CKTsenDCtran( CKTcircuit *);
int CKTsenLoad( CKTcircuit *);
void CKTsenPrint( CKTcircuit *);
int CKTsenSetup( CKTcircuit *);
int CKTsenUpdate( CKTcircuit *);
int CKTsetAnalPm( void *, void *, int , IFvalue *, IFvalue *);
int CKTsetBreak( CKTcircuit *, double );
int CKTsetNodPm( void *, void *, int , IFvalue *, IFvalue *);
int CKTsetOpt( void *, void *, int , IFvalue *);
int CKTsetup( CKTcircuit *);
int CKTunsetup(CKTcircuit *ckt);
int CKTtemp( CKTcircuit *);
char *CKTtrouble(void *, char *);
void CKTterr( int , CKTcircuit *, double *);
int CKTtrunc( CKTcircuit *, double *);
int CKTtypelook( char *);
int DCOaskQuest( CKTcircuit *, void *, int , IFvalue *);
int DCOsetParm( CKTcircuit *, void *, int , IFvalue *);
int DCTaskQuest( CKTcircuit *, void *, int , IFvalue *);
int DCTsetParm( CKTcircuit *, void *, int , IFvalue *);
int DCop( CKTcircuit *);
int DCtrCurv( CKTcircuit *, int );
int DCtran( CKTcircuit *, int );
int DISTOan(CKTcircuit *, int);
int NOISEan(CKTcircuit *, int);
int PZan( CKTcircuit *, int );
int PZinit( CKTcircuit * );
int PZpost( CKTcircuit * );
int PZaskQuest( CKTcircuit *, void *, int , IFvalue *);
int PZsetParm( CKTcircuit *, void *, int , IFvalue *);
int SENaskQuest( CKTcircuit *, void *, int , IFvalue *);
void SENdestroy( SENstruct *);
int SENsetParm( CKTcircuit *, void *, int , IFvalue *);
int SENstartup( CKTcircuit *);
int SPIinit( IFfrontEnd *, IFsimulator **);
char * SPerror( int );
int TFanal( CKTcircuit *, int );
int TFaskQuest( CKTcircuit *, void *, int , IFvalue *);
int TFsetParm( CKTcircuit *, void *, int , IFvalue *);
int TRANaskQuest( CKTcircuit *, void *, int , IFvalue *);
int TRANsetParm( CKTcircuit *, void *, int , IFvalue *);
int TRANinit(CKTcircuit *, JOB *);
int NIacIter( CKTcircuit * );
int NIcomCof( CKTcircuit * );
int NIconvTest(CKTcircuit * );
void NIdestroy(CKTcircuit * );
int NIinit( CKTcircuit * );
int NIintegrate( CKTcircuit *, double *, double *, double , int );
int NIiter( CKTcircuit * , int );
int NIpzMuller(PZtrial **, PZtrial *);
int NIpzComplex(PZtrial **, PZtrial *);
int NIpzSym(PZtrial **, PZtrial *);
int NIpzSym2(PZtrial **, PZtrial *);
int NIreinit( CKTcircuit *);
int NIsenReinit( CKTcircuit *);
IFfrontEnd *SPfrontEnd;
#endif /*CKT*/

View File

@ -1,47 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/* CKTaccept(ckt)
* this is a driver program to iterate through all the various
* accept functions provided for the circuit elements in the
* given circuit
*/
#include "ngspice.h"
#include <stdio.h>
#include "smpdefs.h"
#include "cktdefs.h"
#include "devdefs.h"
#include "sperror.h"
int
CKTaccept(register CKTcircuit *ckt)
{
extern SPICEdev *DEVices[];
register int i;
int error;
for (i=0;i<DEVmaxnum;i++) {
if ( ((*DEVices[i]).DEVaccept != NULL) && (ckt->CKThead[i] != NULL) ){
error = (*((*DEVices[i]).DEVaccept))(ckt,ckt->CKThead[i]);
if(error) return(error);
}
}
#ifdef PREDICTOR
/* now, move the sols vectors around */
temp = ckt->CKTsols[7];
for ( i=7;i>0;i--) {
ckt->CKTsols[i] = ckt->CKTsols[i-1];
}
ckt->CKTsols[0]=temp;
size = SMPmatSize(ckt->CKTmatrix);
for(i=0;i<=size;i++) {
ckt->CKTsols[0][i]=ckt->CKTrhs[i];
}
#endif /* PREDICTOR */
return(OK);
}

View File

@ -1,142 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/*
*/
/*
* CKTacct
* get the specified accounting item into 'value' in the
* given circuit 'ckt'.
*/
#include "ngspice.h"
#include "const.h"
#include "optdefs.h"
#include "ifsim.h"
#include <stdio.h>
#include "cktdefs.h"
#include "spmatrix.h"
/* ARGSUSED */
int
CKTacct(CKTcircuit *ckt, void *anal, int which, IFvalue *val)
{
switch(which) {
case OPT_EQNS:
val->iValue = ckt->CKTmaxEqNum;
break;
case OPT_ORIGNZ:
if ( ckt->CKTmatrix != NULL ) {
val->iValue = spOriginalCount((char *)ckt->CKTmatrix);
} else {
val->iValue = 0;
}
break;
case OPT_FILLNZ:
if ( ckt->CKTmatrix != NULL ) {
val->iValue = spFillinCount((char *)ckt->CKTmatrix);
} else {
val->iValue = 0;
}
break;
case OPT_TOTALNZ:
if ( ckt->CKTmatrix != NULL ) {
val->iValue = spElementCount((char *)ckt->CKTmatrix);
} else {
val->iValue = 0;
}
break;
case OPT_ITERS:
val->iValue = ckt->CKTstat->STATnumIter;
break;
case OPT_TRANIT:
val->iValue = ckt->CKTstat->STATtranIter;
break;
case OPT_TRANCURITER:
val->iValue = ckt->CKTstat->STATnumIter - ckt->CKTstat->STAToldIter;
break;
case OPT_TRANPTS:
val->iValue = ckt->CKTstat->STATtimePts;
break;
case OPT_TRANACCPT:
val->iValue = ckt->CKTstat->STATaccepted;
break;
case OPT_TRANRJCT:
val->iValue = ckt->CKTstat->STATrejected;
break;
case OPT_TOTANALTIME:
val->rValue = ckt->CKTstat->STATtotAnalTime;
break;
case OPT_TRANTIME:
val->rValue = ckt->CKTstat->STATtranTime;
break;
case OPT_ACTIME:
val->rValue = ckt->CKTstat->STATacTime;
break;
case OPT_LOADTIME:
val->rValue = ckt->CKTstat->STATloadTime;
break;
case OPT_SYNCTIME:
val->rValue = ckt->CKTstat->STATsyncTime;
break;
case OPT_COMBTIME:
val->rValue = ckt->CKTstat->STATcombineTime;
break;
case OPT_REORDTIME:
val->rValue = ckt->CKTstat->STATreorderTime;
break;
case OPT_DECOMP:
val->rValue = ckt->CKTstat->STATdecompTime;
break;
case OPT_SOLVE:
val->rValue = ckt->CKTstat->STATsolveTime;
break;
case OPT_TRANLOAD:
val->rValue = ckt->CKTstat->STATtranLoadTime;
break;
case OPT_TRANSYNC:
val->rValue = ckt->CKTstat->STATtranSyncTime;
break;
case OPT_TRANCOMB:
val->rValue = ckt->CKTstat->STATtranCombTime;
break;
case OPT_TRANDECOMP:
val->rValue = ckt->CKTstat->STATtranDecompTime;
break;
case OPT_TRANSOLVE:
val->rValue = ckt->CKTstat->STATtranSolveTime;
break;
case OPT_TRANTRUNC:
val->rValue = ckt->CKTstat->STATtranTruncTime;
break;
case OPT_ACLOAD:
val->rValue = ckt->CKTstat->STATacLoadTime;
break;
case OPT_ACSYNC:
val->rValue = ckt->CKTstat->STATacSyncTime;
break;
case OPT_ACCOMB:
val->rValue = ckt->CKTstat->STATacCombTime;
break;
case OPT_ACDECOMP:
val->rValue = ckt->CKTstat->STATacDecompTime;
break;
case OPT_ACSOLVE:
val->rValue = ckt->CKTstat->STATacSolveTime;
break;
case OPT_TEMP:
val->rValue = ckt->CKTtemp - CONSTCtoK;
break;
case OPT_TNOM:
val->rValue = ckt->CKTnomTemp - CONSTCtoK;
break;
default:
return(-1);
}
return(0);
}

View File

@ -1,43 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/* CKTacDump(ckt,freq,file)
* this is a simple program to dump the complex rhs vector
* into the rawfile.
*/
#include "ngspice.h"
#include <stdio.h>
#include "smpdefs.h"
#include "cktdefs.h"
#include "iferrmsg.h"
#include "ifsim.h"
int
CKTacDump(register CKTcircuit *ckt, double freq, void *plot)
{
register double *rhsold;
register double *irhsold;
register int i;
register IFcomplex *data;
IFvalue freqData;
IFvalue valueData;
rhsold = ckt->CKTrhsOld;
irhsold = ckt->CKTirhsOld;
freqData.rValue = freq;
valueData.v.numValue = ckt->CKTmaxEqNum-1;
data = (IFcomplex *) MALLOC((ckt->CKTmaxEqNum-1)*sizeof(IFcomplex));
valueData.v.vec.cVec = data;
for (i=0;i<ckt->CKTmaxEqNum-1;i++) {
data[i].real = rhsold[i+1];
data[i].imag = irhsold[i+1];
}
(*(SPfrontEnd->OUTpData))(plot,&freqData,&valueData);
FREE(data);
return(OK);
}

View File

@ -1,45 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/* CKTask
* Ask questions about a specified device.
*/
#include "ngspice.h"
#include <stdio.h>
#include "cktdefs.h"
#include "ifsim.h"
#include "devdefs.h"
#include "sperror.h"
extern SPICEdev *DEVices[];
int
CKTask(void *ckt, void *fast, int which, IFvalue *value, IFvalue *selector)
{
register int type = ((GENinstance *)fast)->GENmodPtr->GENmodType;
int error;
#ifdef PARALLEL_ARCH
long msgtype, length;
long from = ((GENinstance *)fast)->GENowner;
#endif /* PARALLEL_ARCH */
if((*DEVices[type]).DEVask) {
error = DEVices[type]->DEVask((CKTcircuit *)ckt,
(GENinstance *)fast,which,value,selector);
} else {
error = E_BADPARM;
}
#ifdef PARALLEL_ARCH
msgtype = MT_ASK;
length = sizeof(IFvalue);
BRDCST_(&msgtype, (char *)value, &length, &from);
msgtype++;
length = sizeof(int);
BRDCST_(&msgtype, (char *)&error, &length, &from);
#endif /* PARALLEL_ARCH */
return(error);
}

View File

@ -1,25 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
#include "ngspice.h"
#include <stdio.h>
#include "tskdefs.h"
#include "jobdefs.h"
#include "cktdefs.h"
#include "ifsim.h"
#include "iferrmsg.h"
extern SPICEanalysis *analInfo[];
/* ARGSUSED */
int
CKTaskAnalQ(void *ckt, void *analPtr, int parm, IFvalue *value, IFvalue *selector)
{
register int type = ((JOB *)analPtr)->JOBtype;
if((analInfo[type]->askQuest) == NULL) return(E_BADPARM);
return( (*(analInfo[type]->askQuest))((CKTcircuit*)ckt,analPtr,parm,value));
}

View File

@ -1,43 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/*
*CKTaskNodQst
*
* ask about a parameter on a node.
*/
#include "ngspice.h"
#include <stdio.h>
#include "ifsim.h"
#include "iferrmsg.h"
#include "cktdefs.h"
/* ARGSUSED */
int
CKTaskNodQst(void *ckt, void *node, int parm, IFvalue *value, IFvalue *selector)
{
if(!node) return(E_BADPARM);
switch(parm) {
case PARM_NS:
value->rValue = ((CKTnode *)node)->nodeset;
break;
case PARM_IC:
value->rValue = ((CKTnode *)node)->ic;
break;
case PARM_NODETYPE:
value->iValue = ((CKTnode *)node)->type;
break;
default:
return(E_BADPARM);
}
return(OK);
}

View File

@ -1,54 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/* CKTbindNode
* bind a node of the specified device of the given type to its place
* in the specified circuit.
*/
#include "ngspice.h"
#include <stdio.h>
#include "ifsim.h"
#include "smpdefs.h"
#include "cktdefs.h"
#include "devdefs.h"
#include "sperror.h"
extern SPICEdev *DEVices[];
/*ARGSUSED*/
int
CKTbindNode(void *ckt, void *fast, int term, void *node)
{
int mappednode;
register int type = ((GENinstance *)fast)->GENmodPtr->GENmodType;
mappednode = ((CKTnode *)node)->number;
if(*((*DEVices[type]).DEVpublic.terms) >= term && term >0 ) {
switch(term) {
default: return(E_NOTERM);
case 1:
((GENinstance *)fast)->GENnode1 = mappednode;
break;
case 2:
((GENinstance *)fast)->GENnode2 = mappednode;
break;
case 3:
((GENinstance *)fast)->GENnode3 = mappednode;
break;
case 4:
((GENinstance *)fast)->GENnode4 = mappednode;
break;
case 5:
((GENinstance *)fast)->GENnode5 = mappednode;
break;
}
return(OK);
} else {
return(E_NOTERM);
}
}

View File

@ -1,25 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/*
*/
/* CKTbreakDump(ckt) - dump the breakpoint table associated with
* the given circuit
*/
#include "ngspice.h"
#include <stdio.h>
#include "cktdefs.h"
void
CKTbreakDump(CKTcircuit *ckt)
{
register int i;
for(i=0;i<ckt->CKTbreakSize;i++) {
(void)printf("breakpoint table entry %d is %g\n",i,*(ckt->CKTbreaks+i));
}
}

View File

@ -1,39 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/*
*/
/* CKTclrBreak(ckt)
* delete the first time from the breakpoint table for the given circuit
*/
#include "ngspice.h"
#include <stdio.h>
#include "cktdefs.h"
#include "sperror.h"
int
CKTclrBreak(register CKTcircuit *ckt)
{
double *tmp;
register int j;
if(ckt->CKTbreakSize >2) {
tmp = (double *)MALLOC((ckt->CKTbreakSize-1)*sizeof(double));
if(tmp == (double *)NULL) return(E_NOMEM);
for(j=1;j<ckt->CKTbreakSize;j++) {
*(tmp+j-1) = *(ckt->CKTbreaks+j);
}
FREE(ckt->CKTbreaks);
ckt->CKTbreakSize--;
ckt->CKTbreaks=tmp;
} else {
*(ckt->CKTbreaks)= *(ckt->CKTbreaks+1);
*(ckt->CKTbreaks+1) = ckt->CKTfinalTime;
}
return(OK);
}

View File

@ -1,47 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/*
*/
/* CKTcrtElement(ckt,type,inModPtr,inInstPtr,name,subname)
* Create a device of the specified type, with the given name, using
* the specified model in the named circuit.
*/
#include "ngspice.h"
#include <stdio.h>
#include "ifsim.h"
#include "cktdefs.h"
#include "devdefs.h"
#include "sperror.h"
/*ARGSUSED*/
int
CKTcrtElt(void *ckt, void *inModPtr, void **inInstPtr, IFuid name)
{
GENinstance *instPtr = NULL;
GENmodel *modPtr=(GENmodel*)inModPtr;
extern SPICEdev *DEVices[];
int error;
int type;
if((GENmodel *)modPtr==(GENmodel*)NULL) return(E_NOMOD);
type = ((GENmodel*)modPtr)->GENmodType;
error =CKTfndDev(ckt,&type,(void**)&instPtr,name,inModPtr,(char *)NULL );
if (error== OK) {
if(inInstPtr) *inInstPtr=(void *)instPtr;
return(E_EXISTS);
} else if (error != E_NODEV) return(error);
instPtr = (GENinstance *)MALLOC(*DEVices[type]->DEVinstSize);
if(instPtr == (GENinstance *)NULL) return(E_NOMEM);
instPtr->GENname = name;
instPtr->GENmodPtr = modPtr;
instPtr->GENnextInstance = modPtr->GENinstances;
modPtr->GENinstances = instPtr;
if(inInstPtr != NULL) *inInstPtr = (void *)instPtr;
return(OK);
}

View File

@ -1,27 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
#include "ngspice.h"
#include <stdio.h>
#include "tskdefs.h"
#include "jobdefs.h"
#include "ifsim.h"
#include "iferrmsg.h"
/* ARGSUSED */
int
CKTdelTask(void *ckt, void *task)
{
JOB *job;
JOB *old=NULL;
for(job = ((TSKtask*)task)->jobs; job; job=job->JOBnextJob){
if(old) FREE(old);
old=job;
}
if(old)FREE(old);
FREE(task);
return(OK);
}

View File

@ -1,61 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/*
*/
/* CKTdestroy(ckt)
* this is a driver program to iterate through all the various
* destroy functions provided for the circuit elements in the
* given circuit
*/
#include "ngspice.h"
#include <stdio.h>
#include "cktdefs.h"
#include "devdefs.h"
#include "ifsim.h"
#include "sperror.h"
extern SPICEdev *DEVices[];
int
CKTdestroy(void *inCkt)
{
register CKTcircuit *ckt = (CKTcircuit *)inCkt;
register int i;
register CKTnode *node;
register CKTnode *nnode;
#ifdef WANT_SENSE2
if(ckt->CKTsenInfo){
if(ckt->CKTrhsOp) FREE(ckt->CKTrhsOp);
if(ckt->CKTsenRhs) FREE(ckt->CKTsenRhs);
if(ckt->CKTseniRhs) FREE(ckt->CKTseniRhs);
SENdestroy(ckt->CKTsenInfo);
}
#endif
for (i=0;i<DEVmaxnum;i++) {
if ( ((*DEVices[i]).DEVdestroy != NULL) && (ckt->CKThead[i] != NULL) ){
(*((*DEVices[i]).DEVdestroy))(&(ckt->CKThead[i]));
}
}
for(i=0;i<=ckt->CKTmaxOrder+1;i++){
FREE(ckt->CKTstates[i]);
}
if(ckt->CKTmatrix) SMPdestroy(ckt->CKTmatrix);
if(ckt->CKTbreaks) FREE(ckt->CKTbreaks);
for(node = ckt->CKTnodes; node; ) {
nnode = node->next;
FREE(node);
node = nnode;
}
ckt->CKTnodes = (CKTnode *)NULL;
ckt->CKTlastNode = (CKTnode *)NULL;
FREE(ckt);
return(OK);
}

View File

@ -1,177 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1988 Jaijeet S Roychowdhury
**********/
/*
* CKTdisto (ckt, mode)
*/
#include "ngspice.h"
#include "cktdefs.h"
#include "devdefs.h"
#include "vsrc/vsrcdefs.h"
#include "isrc/isrcdefs.h"
#include "fteconst.h"
#include "iferrmsg.h"
#include "distodef.h"
#include "sperror.h"
#include <stdio.h>
int
CKTdisto (register CKTcircuit *ckt, int mode)
{
extern SPICEdev *DEVices[];
register DISTOAN* cv = (DISTOAN*) (ckt->CKTcurJob);
register int i;
int error=0;
int size;
switch(mode) {
case D_SETUP:
for (i=0;i<DEVmaxnum;i++) {
if ( ((*DEVices[i]).DEVdisto != NULL) && (ckt->CKThead[i] != NULL) ){
error = (*((*DEVices[i]).DEVdisto))(mode,ckt->CKThead[i],ckt);
if(error) return(error);
}
}
break;
case D_TWOF1:
case D_THRF1:
case D_F1PF2:
case D_F1MF2:
case D_2F1MF2:
size = SMPmatSize(ckt->CKTmatrix);
for (i=1; i<=size; i++)
{
ckt->CKTrhs[i] = 0.0;
ckt->CKTirhs[i] = 0.0;
}
for (i=0;i<DEVmaxnum;i++) {
if ( ((*DEVices[i]).DEVdisto != NULL) && (ckt->CKThead[i] != NULL) ){
error = (*((*DEVices[i]).DEVdisto))(mode,ckt->CKThead[i],ckt);
if(error) return(error);
}
}
break;
case D_RHSF1:
cv->Df2given = 0; /* will change if any F2 source is found */
case D_RHSF2:
{
int vcode;
int icode;
double mag=0.0;
double phase=0.0;
int size;
size = SMPmatSize(ckt->CKTmatrix);
for (i=0;i<=size;i++) {
*(ckt->CKTrhs+i)=0;
*(ckt->CKTirhs+i)=0;
}
vcode = CKTtypelook("Vsource");
icode = CKTtypelook("Isource");
if(vcode >= 0) {
/* voltage sources are in this version, so use them */
register VSRCinstance *here;
register VSRCmodel *model;
for(model = (VSRCmodel *)ckt->CKThead[vcode];model != NULL;
model=model->VSRCnextModel){
for(here=model->VSRCinstances;here!=NULL;
here=here->VSRCnextInstance) {
/* check if the source has a distortion input*/
if (here->VSRCdGiven) {
if (here->VSRCdF2given) cv->Df2given = 1;
if ((here->VSRCdF1given) && (mode == D_RHSF1)) {
mag = here->VSRCdF1mag;
phase = here->VSRCdF1phase;
}
else if ((here->VSRCdF2given) && (mode == D_RHSF2)) {
mag = here->VSRCdF2mag;
phase = here->VSRCdF2phase;
}
if (((here->VSRCdF1given) && (mode == D_RHSF1)) ||
((here->VSRCdF2given) && (mode == D_RHSF2))) {
*(ckt->CKTrhs + here->VSRCbranch) = 0.5*mag* cos(M_PI*phase/180.0);
*(ckt->CKTirhs + here->VSRCbranch) = 0.5*mag*sin(M_PI*phase/180.0);
}
}
}
}
}
if(icode >= 0 ) {
/* current sources are in this version, so use them */
register ISRCinstance *here;
register ISRCmodel *model;
for(model= (ISRCmodel *)ckt->CKThead[icode];model != NULL;
model=model->ISRCnextModel){
for(here=model->ISRCinstances;here!=NULL;
here=here->ISRCnextInstance) {
/* check if the source has a distortion input*/
if (here->ISRCdGiven) {
if (here->ISRCdF2given) cv->Df2given = 1;
if ((here->ISRCdF1given) && (mode == D_RHSF1)) {
mag = here->ISRCdF1mag;
phase = here->ISRCdF1phase;
}
else if ((here->ISRCdF2given) && (mode == D_RHSF2)) {
mag = here->ISRCdF2mag;
phase = here->ISRCdF2phase;
}
if (((here->ISRCdF1given) && (mode == D_RHSF1)) ||
((here->ISRCdF2given) && (mode == D_RHSF2))) {
*(ckt->CKTrhs + here->ISRCposNode) = - 0.5 * mag
* cos(M_PI*phase/180.0);
*(ckt->CKTrhs + here->ISRCnegNode) = 0.5 * mag * cos(
M_PI*phase/180.0);
*(ckt->CKTirhs + here->ISRCposNode) = - 0.5 * mag * sin(
M_PI*phase/180.0);
*(ckt->CKTirhs + here->ISRCnegNode) = 0.5 * mag * sin(
M_PI*phase/180.0);
}
}
}
}
}
}
error = 0;
break;
default:
error = E_BADPARM;
break;
}
return(error);
}

View File

@ -1,25 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/*
*/
/* CKTdltInst
* delete the specified instance - not yet supported in spice
*/
#include "ngspice.h"
#include <stdio.h>
#include "cktdefs.h"
#include "ifsim.h"
#include "sperror.h"
/* ARGSUSED */
int
CKTdltInst(void *ckt, void *instance)
{
return(E_UNSUPP);
}

View File

@ -1,45 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/* CKTdltMod
* delete the specified model - not yet supported in spice
*/
#include "ngspice.h"
#include <stdio.h>
#include "cktdefs.h"
#include "ifsim.h"
#include "sperror.h"
/* ARGSUSED */
int
CKTdltMod(void *cktp, void *modPtr)
{
CKTcircuit *ckt = (CKTcircuit *) cktp;
GENmodel *m = (GENmodel *) modPtr, *mod, **prevp;
GENinstance *h, *next_i;
int error;
prevp = &ckt->CKThead[m->GENmodType];
for (mod = *prevp; m && mod != m; mod = mod->GENnextModel)
prevp = &mod->GENnextModel;
if (!mod)
return OK;
*prevp = m->GENnextModel;
for (h = m->GENinstances; h; h = next_i) {
next_i = h->GENnextInstance;
error = (*(SPfrontEnd->IFdelUid))((void *)ckt,h->GENname,
UID_INSTANCE);
tfree(h);
}
error = (*(SPfrontEnd->IFdelUid))((void *)ckt,m->GENmodName, UID_MODEL);
tfree(m);
return(OK);
}

View File

@ -1,59 +0,0 @@
/**********
Copyright 1992 Regents of the University of California. All rights reserved.
**********/
/* CKTdltNod
*/
#include "ngspice.h"
#include <stdio.h>
#include "cktdefs.h"
#include "ifsim.h"
#include "sperror.h"
int CKTdltNNum(void *cktp, int num);
/* ARGSUSED */
int
CKTdltNod(void *ckt, void *node)
{
return CKTdltNNum(ckt, ((CKTnode *) node)->number);
}
int
CKTdltNNum(void *cktp, int num)
{
CKTcircuit *ckt = (CKTcircuit *) cktp;
CKTnode *n, *prev, *node, *sprev;
int error;
prev = NULL;
node = NULL;
sprev = NULL;
for (n = ckt->CKTnodes; n; n = n->next) {
if (n->number == num) {
node = n;
sprev = prev;
}
prev = n;
}
if (!node)
return OK;
ckt->CKTmaxEqNum -= 1;
if (!sprev) {
ckt->CKTnodes = node->next;
} else {
sprev->next = node->next;
}
if (node == ckt->CKTlastNode)
ckt->CKTlastNode = sprev;
error = (*(SPfrontEnd->IFdelUid))((void *)ckt,node->name, UID_SIGNAL);
tfree(node);
return error;
}

View File

@ -1,146 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
#include "ngspice.h"
#include "cktdefs.h"
#include <stdio.h>
#include "sperror.h"
#include "trandefs.h"
extern SPICEanalysis *analInfo[];
extern int ANALmaxnum;
int
CKTdoJob(void *inCkt, int reset, void *inTask)
{
CKTcircuit *ckt = (CKTcircuit *)inCkt;
TSKtask *task = (TSKtask *)inTask;
JOB *job;
double startTime;
int error, i, error2;
#ifdef WANT_SENSE2
int senflag;
static int sens_num = -1;
/* Sensitivity is special */
if (sens_num < 0) {
for (i = 0; i < ANALmaxnum; i++)
if (!strcmp("SENS2", analInfo[i]->public.name))
break;
sens_num = i;
}
#endif
startTime = (*(SPfrontEnd->IFseconds))( );
ckt->CKTtemp = task->TSKtemp;
ckt->CKTnomTemp = task->TSKnomTemp;
ckt->CKTmaxOrder = task->TSKmaxOrder;
ckt->CKTintegrateMethod = task->TSKintegrateMethod;
ckt->CKTbypass = task->TSKbypass;
ckt->CKTdcMaxIter = task->TSKdcMaxIter;
ckt->CKTdcTrcvMaxIter = task->TSKdcTrcvMaxIter;
ckt->CKTtranMaxIter = task->TSKtranMaxIter;
ckt->CKTnumSrcSteps = task->TSKnumSrcSteps;
ckt->CKTnumGminSteps = task->TSKnumGminSteps;
ckt->CKTminBreak = task->TSKminBreak;
ckt->CKTabstol = task->TSKabstol;
ckt->CKTpivotAbsTol = task->TSKpivotAbsTol;
ckt->CKTpivotRelTol = task->TSKpivotRelTol;
ckt->CKTreltol = task->TSKreltol;
ckt->CKTchgtol = task->TSKchgtol;
ckt->CKTvoltTol = task->TSKvoltTol;
ckt->CKTgmin = task->TSKgmin;
ckt->CKTdelmin = task->TSKdelmin;
ckt->CKTtrtol = task->TSKtrtol;
ckt->CKTdefaultMosL = task->TSKdefaultMosL;
ckt->CKTdefaultMosW = task->TSKdefaultMosW;
ckt->CKTdefaultMosAD = task->TSKdefaultMosAD;
ckt->CKTdefaultMosAS = task->TSKdefaultMosAS;
ckt->CKTfixLimit = task->TSKfixLimit;
ckt->CKTnoOpIter = task->TSKnoOpIter;
ckt->CKTtryToCompact = task->TSKtryToCompact;
ckt->CKTbadMos3 = task->TSKbadMos3;
ckt->CKTkeepOpInfo = task->TSKkeepOpInfo;
ckt->CKTtroubleNode = 0;
ckt->CKTtroubleElt = NULL;
#ifdef NEWTRUNC
ckt->CKTlteReltol = task->TSKlteReltol;
ckt->CKTlteAbstol = task->TSKlteAbstol;
#endif /* NEWTRUNC */
error = 0;
if (reset) {
ckt->CKTdelta = 0.0;
ckt->CKTtime = 0.0;
ckt->CKTcurrentAnalysis = 0;
#ifdef WANT_SENSE2
senflag = 0;
if (sens_num < ANALmaxnum)
for (job = task->jobs; !error && job; job = job->JOBnextJob) {
if (job->JOBtype == sens_num) {
senflag = 1;
ckt->CKTcurJob = job;
ckt->CKTsenInfo = (SENstruct *) job;
error = (*(analInfo[sens_num]->an_func))(ckt, reset);
}
}
if (ckt->CKTsenInfo && (!senflag || error))
FREE(ckt->CKTsenInfo);
#endif
/* normal reset */
if (!error)
error = CKTunsetup(ckt);
if (!error)
error = CKTsetup(ckt);
if (!error)
error = CKTtemp(ckt);
if (error)
return error;
}
error2 = OK;
/* Analysis order is important */
for (i = 0; i < ANALmaxnum; i++) {
#ifdef WANT_SENSE2
if (i == sens_num)
continue;
#endif
for (job = task->jobs; job; job = job->JOBnextJob) {
if (job->JOBtype == i) {
ckt->CKTcurJob=job;
error = OK;
if (analInfo[i]->an_init)
error = (*(analInfo[i]->an_init))(ckt, job);
if (!error && analInfo[i]->do_ic)
error = CKTic(ckt);
if (!error)
error = (*(analInfo[i]->an_func))(ckt, reset);
if (error)
error2 = error;
}
}
}
ckt->CKTstat->STATtotAnalTime += (*(SPfrontEnd->IFseconds))( ) - startTime;
#ifdef WANT_SENSE2
if (ckt->CKTsenInfo)
SENdestroy(ckt->CKTsenInfo);
#endif
return(error2);
}

View File

@ -1,29 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/*
*/
/* CKTdump(ckt)
* this is a simple program to dump the rhs vector to stdout
*/
#include "ngspice.h"
#include <stdio.h>
#include "smpdefs.h"
#include "cktdefs.h"
void
CKTdump(register CKTcircuit *ckt, double ref, void *plot)
{
IFvalue refData;
IFvalue valData;
refData.rValue = ref;
valData.v.numValue = ckt->CKTmaxEqNum-1;
valData.v.vec.rVec = ckt->CKTrhsOld+1;
(*(SPfrontEnd->OUTpData))(plot,&refData,&valData);
}

View File

@ -1,36 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/*
*/
/* CKTfndBranch(ckt,name)
* this is a driver program to iterate through all the various
* findBranch functions provided for the circuit elements in the
* given circuit
*/
#include "ngspice.h"
#include <stdio.h>
#include "cktdefs.h"
#include "devdefs.h"
int
CKTfndBranch(register CKTcircuit *ckt, IFuid name)
{
extern SPICEdev *DEVices[];
register int i;
int j;
for (i=0;i<DEVmaxnum;i++) {
if ((*DEVices[i]).DEVfindBranch != NULL && ckt->CKThead[i] != NULL) {
j = (*((*DEVices[i]).DEVfindBranch))(ckt,ckt->CKThead[i],name);
if(j != 0) return(j);
}
}
return(0);
}

View File

@ -1,86 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
#include "ngspice.h"
#include <stdio.h>
#include "ifsim.h"
#include "cktdefs.h"
#include "sperror.h"
int
CKTfndDev(void *Ckt, int *type, void **fast, IFuid name, void *modfast, IFuid modname)
{
register CKTcircuit *ckt=(CKTcircuit *)Ckt;
register GENinstance *here;
register GENmodel *mods;
if((GENinstance **)fast != (GENinstance **)NULL &&
*(GENinstance **)fast != (GENinstance *)NULL) {
/* already have fast, so nothing much to do */
/* just get & set type */
if(type) *type = (*((GENinstance**)fast))->GENmodPtr->GENmodType;
return(OK);
}
if(modfast) {
/* have model, just need device */
mods = (GENmodel*)modfast;
for(here = mods->GENinstances ; here != NULL;
here = here->GENnextInstance) {
if (here->GENname == name) {
if(fast != NULL) *(GENinstance **)fast = here;
if(type) *type = mods->GENmodType;
return(OK);
}
}
return(E_NODEV);
}
if(*type >=0 && *type < DEVmaxnum) {
/* have device type, need to find model & device */
/* look through all models */
for(mods=(GENmodel *)ckt->CKThead[*type]; mods != NULL ;
mods = mods->GENnextModel) {
/* and all instances */
if(modname == (char *)NULL || mods->GENmodName == modname) {
for(here = mods->GENinstances ; here != NULL;
here = here->GENnextInstance) {
if (here->GENname == name) {
if(fast != 0) *(GENinstance **)fast = here;
return(OK);
}
}
if(mods->GENmodName == modname) {
return(E_NODEV);
}
}
}
return(E_NOMOD);
} else if(*type == -1) {
/* look through all types (UGH - worst case - take forever) */
for(*type = 0;*type <DEVmaxnum;(*type)++) {
/* need to find model & device */
/* look through all models */
for(mods=(GENmodel *)ckt->CKThead[*type];mods!=NULL;
mods = mods->GENnextModel) {
/* and all instances */
if(modname == (char *)NULL || mods->GENmodName == modname) {
for(here = mods->GENinstances ; here != NULL;
here = here->GENnextInstance) {
if (here->GENname == name) {
if(fast != 0) *(GENinstance **)fast = here;
return(OK);
}
}
if(mods->GENmodName == modname) {
return(E_NODEV);
}
}
}
}
*type = -1;
return(E_NODEV);
} else return(E_BADPARM);
}

View File

@ -1,36 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/*
*/
/* CKTfndAnal
* find the given Analysis given its name and return the Analysis pointer
*/
#include "ngspice.h"
#include <stdio.h>
#include "ifsim.h"
#include "jobdefs.h"
#include "tskdefs.h"
#include "sperror.h"
#include "cktdefs.h"
/* ARGSUSED */
int
CKTfndAnal(void *ckt, int *analIndex, void **anal, IFuid name, void *inTask, IFuid taskName)
{
TSKtask *task = (TSKtask *)inTask;
register JOB *here;
for (here = ((TSKtask *)task)->jobs;here;here = here->JOBnextJob) {
if(strcmp(here->JOBname,name)==0) {
if(anal) *anal = (void *)here;
return(OK);
}
}
return(E_NOTFOUND);
}

View File

@ -1,53 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/*
*/
#include "ngspice.h"
#include <stdio.h>
#include "cktdefs.h"
#include "ifsim.h"
#include "sperror.h"
int
CKTfndMod(void *ckt, int *type, void **modfast, IFuid modname)
{
register GENmodel *mods;
if(modfast != NULL && *(GENmodel **)modfast != NULL) {
/* already have modfast, so nothing to do */
if(type) *type = (*(GENmodel **)modfast)->GENmodType;
return(OK);
}
if(*type >=0 && *type < DEVmaxnum) {
/* have device type, need to find model */
/* look through all models */
for(mods=((CKTcircuit *)ckt)->CKThead[*type]; mods != NULL ;
mods = mods->GENnextModel) {
if(mods->GENmodName == modname) {
*modfast = (char *)mods;
return(OK);
}
}
return(E_NOMOD);
} else if(*type == -1) {
/* look through all types (UGH - worst case - take forever) */
for(*type = 0;*type <DEVmaxnum;(*type)++) {
/* need to find model & device */
/* look through all models */
for(mods=((CKTcircuit *)ckt)->CKThead[*type];mods!=NULL;
mods = mods->GENnextModel) {
if(mods->GENmodName == modname) {
*modfast = (char *)mods;
return(OK);
}
}
}
*type = -1;
return(E_NOMOD);
} else return(E_BADPARM);
}

View File

@ -1,33 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/*
*/
/* CKTfndNode
* find the given node given its name and return the node pointer
*/
#include "ngspice.h"
#include <stdio.h>
#include "ifsim.h"
#include "sperror.h"
#include "cktdefs.h"
/* ARGSUSED */
int
CKTfndNode(void *ckt, void **node, IFuid name)
{
register CKTnode *here;
for (here = ((CKTcircuit *)ckt)->CKTnodes; here; here = here->next) {
if(here->name == name) {
if(node) *node = (char *)here;
return(OK);
}
}
return(E_NOTFOUND);
}

View File

@ -1,25 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/*
*/
/* CKTfndTask
* find the specified task - not yet supported in spice
*/
#include "ngspice.h"
#include <stdio.h>
#include "cktdefs.h"
#include "ifsim.h"
#include "sperror.h"
/* ARGSUSED */
int
CKTfndTask(void *ckt, void **taskPtr, IFuid taskName)
{
return(E_UNSUPP);
}

View File

@ -1,46 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/*
*/
/* CKTground(ckt,node)
* specify the node to be the ground node of the given circuit
*/
#include "ngspice.h"
#include <stdio.h>
#include "cktdefs.h"
#include "ifsim.h"
#include "sperror.h"
int
CKTground(void *inCkt, void **node, IFuid name)
{
register CKTcircuit *ckt = (CKTcircuit *)inCkt;
if(ckt->CKTnodes) {
if(ckt->CKTnodes->name) {
/*already exists - keep old name, but return it */
if(node)*node = (char *)ckt->CKTnodes;
return(E_EXISTS);
}
ckt->CKTnodes->name = name;
ckt->CKTnodes->type = SP_VOLTAGE;
ckt->CKTnodes->number = 0;
} else {
ckt->CKTnodes = (CKTnode *)MALLOC(sizeof(CKTnode));
if(ckt->CKTnodes == NULL) return(E_NOMEM);
ckt->CKTnodes->name = name;
ckt->CKTnodes->type = SP_VOLTAGE;
ckt->CKTnodes->number = 0;
ckt->CKTnodes->next = (CKTnode *)NULL;
ckt->CKTlastNode = ckt->CKTnodes;
}
if(node)*node = (char *)ckt->CKTnodes;
return(OK);
}

View File

@ -1,66 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/*
*/
/* CKTinst2Node
* get the name and node pointer for a node given a device it is
* bound to and the terminal of the device.
*/
#include "ngspice.h"
#include <stdio.h>
#include "ifsim.h"
#include "sperror.h"
#include "cktdefs.h"
#include "gendefs.h"
#include "devdefs.h"
extern SPICEdev *DEVices[];
int
CKTinst2Node(void *ckt, void *instPtr, int terminal, void **node, IFuid *nodeName)
{
int nodenum;
register int type;
CKTnode *here;
type = ((GENinstance *)instPtr)->GENmodPtr->GENmodType;
if(*((*DEVices[type]).DEVpublic.terms) >= terminal && terminal >0 ) {
switch(terminal) {
default: return(E_NOTERM);
case 1:
nodenum = ((GENinstance *)instPtr)->GENnode1;
break;
case 2:
nodenum = ((GENinstance *)instPtr)->GENnode2;
break;
case 3:
nodenum = ((GENinstance *)instPtr)->GENnode3;
break;
case 4:
nodenum = ((GENinstance *)instPtr)->GENnode4;
break;
case 5:
nodenum = ((GENinstance *)instPtr)->GENnode5;
break;
}
/* ok, now we know its number, so we just have to find it.*/
for(here = ((CKTcircuit*)ckt)->CKTnodes;here;here = here->next) {
if(here->number == nodenum) {
/* found it */
*node = (void*) here;
*nodeName = here->name;
return(OK);
}
}
return(E_NOTFOUND);
} else {
return(E_NOTERM);
}
}

View File

@ -1,57 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
#include "ngspice.h"
#include <stdio.h>
#include "cktdefs.h"
#include "smpdefs.h"
#include "sperror.h"
#include "devdefs.h"
extern SPICEdev *DEVices[];
int
CKTic(CKTcircuit *ckt)
{
int error;
int size;
int i;
CKTnode *node;
size = SMPmatSize(ckt->CKTmatrix);
for (i=0;i<=size;i++) {
*(ckt->CKTrhs+i)=0;
}
for(node = ckt->CKTnodes;node != NULL; node = node->next) {
if(node->nsGiven) {
node->ptr = SMPmakeElt(ckt->CKTmatrix,node->number,node->number);
if(node->ptr == (double *)NULL) return(E_NOMEM);
ckt->CKThadNodeset = 1;
*(ckt->CKTrhs+node->number) = node->nodeset;
}
if(node->icGiven) {
if(! ( node->ptr)) {
node->ptr = SMPmakeElt(ckt->CKTmatrix,node->number,
node->number);
if(node->ptr == (double *)NULL) return(E_NOMEM);
}
*(ckt->CKTrhs+node->number) = node->ic;
}
}
if(ckt->CKTmode & MODEUIC) {
for (i=0;i<DEVmaxnum;i++) {
if( ((*DEVices[i]).DEVsetic != NULL) && (ckt->CKThead[i] != NULL) ){
error = (*((*DEVices[i]).DEVsetic))(ckt->CKThead[i],ckt);
if(error) return(error);
}
}
}
return(OK);
}

View File

@ -1,66 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
#include "ngspice.h"
#include <stdio.h>
#include "ifsim.h"
#include "cktdefs.h"
#include "const.h"
#include "sperror.h"
int
CKTinit(void **ckt)
/* new circuit to create */
{
register int i;
register CKTcircuit *sckt;
sckt = (CKTcircuit *)( *ckt = (char *)MALLOC(sizeof(CKTcircuit)) );
if(sckt == NULL) return(E_NOMEM);
for (i=0;i<DEVmaxnum;i++) {
(sckt)->CKThead[i] = (GENmodel *) NULL;
}
(sckt)->CKTmaxEqNum = 1;
(sckt)->CKTnodes = (CKTnode *)NULL;
(sckt)->CKTlastNode = (CKTnode *)NULL;
sckt->CKTmatrix = NULL;
#ifdef notdef
error = NIinit(sckt);
if(error) return(error);
#endif
(sckt)->CKTgmin = 1e-12;
(sckt)->CKTabstol = 1e-12;
(sckt)->CKTreltol = 1e-3;
(sckt)->CKTchgtol = 1e-14;
(sckt)->CKTvoltTol = 1e-6;
(sckt)->CKTtrtol = 7;
(sckt)->CKTbypass = 1;
(sckt)->CKTisSetup = 0;
(sckt)->CKTtranMaxIter = 10;
(sckt)->CKTdcMaxIter = 100;
(sckt)->CKTdcTrcvMaxIter = 50;
(sckt)->CKTintegrateMethod = TRAPEZOIDAL;
(sckt)->CKTorder = 1;
(sckt)->CKTmaxOrder = 2;
(sckt)->CKTpivotAbsTol = 1e-13;
(sckt)->CKTpivotRelTol = 1e-3;
(sckt)->CKTtemp = 300.15;
(sckt)->CKTnomTemp = 300.15;
(sckt)->CKTdefaultMosL = 1e-4;
(sckt)->CKTdefaultMosW = 1e-4;
(sckt)->CKTdefaultMosAD = 0;
(sckt)->CKTdefaultMosAS = 0;
(sckt)->CKTsrcFact=1;
(sckt)->CKTdiagGmin=0;
(sckt)->CKTstat = (STATistics *)MALLOC(sizeof(STATistics));
(sckt)->CKTtroubleNode = 0;
(sckt)->CKTtroubleElt = NULL;
(sckt)->CKTtimePoints = NULL;
if( (sckt)->CKTstat == (STATistics *)NULL) return(E_NOMEM);
return(OK);
}

View File

@ -1,36 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/*
*CKTlinkEq
* Link an already allocated node into the necessary structure
*/
#include "ngspice.h"
#include <stdio.h>
#include "ifsim.h"
#include "iferrmsg.h"
#include "smpdefs.h"
#include "cktdefs.h"
int
CKTlinkEq(CKTcircuit *ckt, CKTnode *node)
{
if(!(ckt->CKTnodes)) { /* starting the list - allocate both ground and 1 */
ckt->CKTnodes = (CKTnode *) MALLOC(sizeof(CKTnode));
if(ckt->CKTnodes == (CKTnode *)NULL) return(E_NOMEM);
ckt->CKTnodes->name = (char *)NULL;
ckt->CKTnodes->type = SP_VOLTAGE;
ckt->CKTnodes->number = 0;
ckt->CKTlastNode = ckt->CKTnodes;
}
if(node == (CKTnode *)NULL) return(E_BADPARM);
ckt->CKTlastNode->next = node;
ckt->CKTlastNode = ckt->CKTlastNode->next;
ckt->CKTlastNode->number = ckt->CKTmaxEqNum++;
ckt->CKTlastNode->next = (CKTnode *)NULL;
return(OK);
}

View File

@ -1,166 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/*
*/
/* CKTload(ckt)
* this is a driver program to iterate through all the various
* load functions provided for the circuit elements in the
* given circuit
*/
#include "ngspice.h"
#include <stdio.h>
#include "smpdefs.h"
#include "cktdefs.h"
#include "devdefs.h"
#include "sperror.h"
static int ZeroNoncurRow(SMPmatrix *matrix, CKTnode *nodes, int rownum);
int
CKTload(register CKTcircuit *ckt)
{
extern SPICEdev *DEVices[];
register int i;
register int size;
double startTime;
CKTnode *node;
int error;
#ifdef PARALLEL_ARCH
int ibuf[2];
long type = MT_LOAD, length = 2;
#endif /* PARALLEL_ARCH */
#ifdef STEPDEBUG
int noncon;
#endif /* STEPDEBUG */
startTime = (*(SPfrontEnd->IFseconds))();
size = SMPmatSize(ckt->CKTmatrix);
for (i=0;i<=size;i++) {
*(ckt->CKTrhs+i)=0;
}
SMPclear(ckt->CKTmatrix);
#ifdef STEPDEBUG
noncon = ckt->CKTnoncon;
#endif /* STEPDEBUG */
for (i=0;i<DEVmaxnum;i++) {
if ( ((*DEVices[i]).DEVload != NULL) && (ckt->CKThead[i] != NULL) ){
error = (*((*DEVices[i]).DEVload))(ckt->CKThead[i],ckt);
if (ckt->CKTnoncon)
ckt->CKTtroubleNode = 0;
#ifdef STEPDEBUG
if(noncon != ckt->CKTnoncon) {
printf("device type %s nonconvergence\n",
(*DEVices[i]).DEVpublic.name);
noncon = ckt->CKTnoncon;
}
#endif /* STEPDEBUG */
#ifdef PARALLEL_ARCH
if (error) goto combine;
#else
if(error) return(error);
#endif /* PARALLEL_ARCH */
}
}
if(ckt->CKTmode & MODEDC) {
/* consider doing nodeset & ic assignments */
if(ckt->CKTmode & (MODEINITJCT | MODEINITFIX)) {
/* do nodesets */
for(node=ckt->CKTnodes;node;node=node->next) {
if(node->nsGiven) {
if (ZeroNoncurRow(ckt->CKTmatrix, ckt->CKTnodes,
node->number))
{
*(ckt->CKTrhs+node->number) = 1.0e10 * node->nodeset;
*(node->ptr) = 1e10;
} else {
*(ckt->CKTrhs+node->number) = node->nodeset;
*(node->ptr) = 1;
}
/* DAG: Original CIDER fix. If above fix doesn't work,
* revert to this.
*/
/*
*(ckt->CKTrhs+node->number) += 1.0e10 * node->nodeset;
*(node->ptr) += 1.0e10;
*/
}
}
}
if( (ckt->CKTmode & MODETRANOP) && (!(ckt->CKTmode & MODEUIC))) {
for(node=ckt->CKTnodes;node;node=node->next) {
if(node->icGiven) {
if (ZeroNoncurRow(ckt->CKTmatrix, ckt->CKTnodes,
node->number))
{
*(ckt->CKTrhs+node->number) += 1.0e10 * node->ic;
*(node->ptr) += 1.0e10;
} else {
*(ckt->CKTrhs+node->number) = node->ic;
*(node->ptr) = 1;
}
/* DAG: Original CIDER fix. If above fix doesn't work,
* revert to this.
*/
/*
*(ckt->CKTrhs+node->number) += 1.0e10 * node->ic;
*(node->ptr) += 1.0e10;
*/
}
}
}
}
/* SMPprint(ckt->CKTmatrix, stdout); if you want to debug, this is a
good place to start ... */
#ifdef PARALLEL_ARCH
combine:
ckt->CKTstat->STATloadTime += SPfrontEnd->IFseconds() - startTime;
startTime = SPfrontEnd->IFseconds();
/* See if any of the DEVload functions bailed. If not, proceed. */
ibuf[0] = error;
ibuf[1] = ckt->CKTnoncon;
IGOP_( &type, ibuf, &length, "+" );
ckt->CKTnoncon = ibuf[1];
ckt->CKTstat->STATsyncTime += SPfrontEnd->IFseconds() - startTime;
if (ibuf[0] == OK) {
startTime = SPfrontEnd->IFseconds();
SMPcombine( ckt->CKTmatrix, ckt->CKTrhs, ckt->CKTrhsSpare );
ckt->CKTstat->STATcombineTime += SPfrontEnd->IFseconds() - startTime;
return(OK);
} else {
if ( ibuf[0] != error ) {
error = E_MULTIERR;
}
return(error);
}
#else
ckt->CKTstat->STATloadTime += SPfrontEnd->IFseconds()-startTime;
return(OK);
#endif /* PARALLEL_ARCH */
}
static int
ZeroNoncurRow(SMPmatrix *matrix, CKTnode *nodes, int rownum)
{
CKTnode *n;
double *x;
int currents;
currents = 0;
for (n = nodes; n; n = n->next) {
x = (double *) SMPfindElt(matrix, rownum, n->number, 0);
if (x) {
if (n->type == SP_CURRENT)
currents = 1;
else
*x = 0.0;
}
}
return currents;
}

View File

@ -1,51 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/*
*/
/* CKTmapNode(ckt,node)
* map the given node to the compact node numbering set of the
* specified circuit
*/
#include "ngspice.h"
#include <stdio.h>
#include "ifsim.h"
#include "sperror.h"
#include "cktdefs.h"
/* ARGSUSED */
int
CKTmapNode(void *ckt, void **node, IFuid name)
{
register CKTnode *here;
int error;
IFuid uid;
CKTnode *mynode;
for (here = ((CKTcircuit *)ckt)->CKTnodes; here; here = here->next) {
if(here->name == name) {
if(node) *node = (char *)here;
return(E_EXISTS);
}
}
/* not found, so must be a new one */
error = CKTmkNode((CKTcircuit*)ckt,&mynode); /*allocate the node*/
if(error) return(error);
error = (*(SPfrontEnd->IFnewUid))((void *)ckt,
&uid,
(IFuid) NULL,
name,
UID_SIGNAL,
(void**)mynode); /* get a uid for it */
if(error) return(error);
mynode->name = uid; /* set the info we have */
mynode->type = SP_VOLTAGE;
error = CKTlinkEq((CKTcircuit*)ckt,mynode); /* and link it in */
if(node) *node = (void *)mynode; /* and finally, return it */
return(OK);
}

View File

@ -1,30 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/* CKTmodAsk
* Ask questions about a specified device.
*/
#include "ngspice.h"
#include <stdio.h>
#include "cktdefs.h"
#include "ifsim.h"
#include "devdefs.h"
#include "sperror.h"
extern SPICEdev *DEVices[];
/* ARGSUSED */
int
CKTmodAsk(void *ckt, void *modfast, int which, IFvalue *value, IFvalue *selector)
{
int type = ((GENmodel *)modfast)->GENmodType;
if((*DEVices[type]).DEVmodAsk) {
return( (*((*DEVices[type]).DEVmodAsk)) ((CKTcircuit *)ckt,
(GENmodel *)modfast,which,value) );
}
return(E_BADPARM);
}

View File

@ -1,45 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/*
*/
/* CKTmodCrt(type,name,ckt,fast)
* Create a device model of the specified type, with the given name
* in the named circuit.
*/
#include "ngspice.h"
#include <stdio.h>
#include "devdefs.h"
#include "cktdefs.h"
#include "sperror.h"
int
CKTmodCrt(void *ckt, int type, void **modfast, IFuid name)
{
extern SPICEdev *DEVices[];
GENmodel *mymodfast = NULL;
int error;
error = CKTfndMod(ckt,&type,(void**)&mymodfast,name);
if(error == E_NOMOD) {
mymodfast = (GENmodel *)MALLOC(*DEVices[type]->DEVmodSize);
if(mymodfast == (GENmodel *)NULL) return(E_NOMEM);
mymodfast->GENmodType = type;
mymodfast->GENmodName = name;
mymodfast->GENnextModel =(GENmodel *)((CKTcircuit *)ckt)->CKThead[type];
((CKTcircuit *)ckt)->CKThead[type]=(GENmodel *)mymodfast;
if(modfast) *modfast=(void *)mymodfast;
return(OK);
} else if (error==0) {
if(modfast) *modfast=(void *)mymodfast;
return(E_EXISTS);
} else {
return(error);
}
/*NOTREACHED*/
}

View File

@ -1,45 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/*
*/
/* CKTmkCur
* make the given name a 'node' of type current in the
* specified circuit
*/
#include "ngspice.h"
#include <stdio.h>
#include "ifsim.h"
#include "sperror.h"
#include "cktdefs.h"
/* ARGSUSED */
int
CKTmkCur(CKTcircuit *ckt, CKTnode **node, IFuid basename, char *suffix)
{
IFuid uid;
int error;
CKTnode *mynode;
CKTnode *checknode;
error = CKTmkNode(ckt,&mynode);
if(error) return(error);
checknode = mynode;
error = (*(SPfrontEnd->IFnewUid))((void *)ckt,&uid,basename,
suffix,UID_SIGNAL,(void**)&checknode);
if(error) {
FREE(mynode);
if(node) *node = checknode;
return(error);
}
mynode->name = uid;
mynode->type = SP_CURRENT;
if(node) *node = mynode;
error = CKTlinkEq(ckt,mynode);
return(error);
}

View File

@ -1,32 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/*
*CKTmkNode(ckt,node)
* Tentatively allocate a new circuit equation structure
*/
#include "ngspice.h"
#include <stdio.h>
#include "ifsim.h"
#include "iferrmsg.h"
#include "smpdefs.h"
#include "cktdefs.h"
/* ARGSUSED */
int
CKTmkNode(CKTcircuit *ckt, CKTnode **node)
{
CKTnode *mynode;
mynode = (CKTnode *)MALLOC(sizeof(CKTnode));
if(mynode == (CKTnode *)NULL) return(E_NOMEM);
mynode->next = (CKTnode *)NULL;
mynode->name = (IFuid) 0;
if(node) *node = mynode;
return(OK);
}

View File

@ -1,43 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/* CKTmkVolt
* make the given name a 'node' of type current in the
* specified circuit
*/
#include "ngspice.h"
#include <stdio.h>
#include "ifsim.h"
#include "sperror.h"
#include "cktdefs.h"
/* ARGSUSED */
int
CKTmkVolt(CKTcircuit *ckt, CKTnode **node, IFuid basename, char *suffix)
{
IFuid uid;
int error;
CKTnode *mynode;
CKTnode *checknode;
error = CKTmkNode(ckt,&mynode);
if(error) return(error);
checknode = mynode;
error = (*(SPfrontEnd->IFnewUid))((void *)ckt,&uid,basename,
suffix,UID_SIGNAL,(void**)&checknode);
if(error) {
FREE(mynode);
if(node) *node = checknode;
return(error);
}
mynode->name = uid;
mynode->type = SP_VOLTAGE;
if(node) *node = mynode;
error = CKTlinkEq(ckt,mynode);
return(error);
}

View File

@ -1,32 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/* CKTmodParam
* attach the given parameter to the specified model in the given circuit
*/
#include "ngspice.h"
#include <stdio.h>
#include "cktdefs.h"
#include "ifsim.h"
#include "devdefs.h"
#include "sperror.h"
extern SPICEdev *DEVices[];
/* ARGSUSED */
int
CKTmodParam(void *ckt, void *modfast, int param, IFvalue *val, IFvalue *selector)
{
register int type = ((GENmodel *)modfast)->GENmodType;
if (((*DEVices[type]).DEVmodParam)) {
return(((*((*DEVices[type]).DEVmodParam)) (param,val,
(GENmodel *)modfast)));
} else {
return(E_BADPARM);
}
}

View File

@ -1,45 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1988 Thomas L. Quarles
**********/
/*
* CKTnames(ckt)
* output information on all circuit nodes/equations
*
*/
#include "ngspice.h"
#include <stdio.h>
#include "cktdefs.h"
#include "ifsim.h"
#include "iferrmsg.h"
int
CKTnames(register CKTcircuit *ckt, int *numNames, register IFuid **nameList)
{
register CKTnode *here;
register int i;
*numNames = ckt->CKTmaxEqNum-1;
*nameList = (IFuid *)MALLOC(*numNames * sizeof(IFuid ));
if ((*nameList) == (IFuid *)NULL) return(E_NOMEM);
i=0;
for (here = ckt->CKTnodes->next; here; here = here->next) {
*((*nameList)+i++) = here->name;
}
return(OK);
}
int
CKTdnames(CKTcircuit *ckt)
{
CKTnode *here;
register int i;
i=0;
for (here = ckt->CKTnodes->next; here; here = here->next) {
printf("%03d: %s\n", here->number, (char *)here->name);
}
return(OK);
}

View File

@ -1,34 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
#include "ngspice.h"
#include <stdio.h>
#include "tskdefs.h"
#include "jobdefs.h"
#include "ifsim.h"
#include "iferrmsg.h"
extern SPICEanalysis *analInfo[];
/* ARGSUSED */
int
CKTnewAnal(void *ckt, int type, IFuid name, void **analPtr, void *taskPtr)
{
if(type==0) {
/* special case for analysis type 0 == option card */
*analPtr=taskPtr; /* pointer to the task itself */
(*(JOB **)analPtr)->JOBname = name;
(*(JOB **)analPtr)->JOBtype = type;
return(OK); /* doesn't need to be created */
}
*analPtr = (void *)MALLOC(analInfo[type]->size);
if(*analPtr==NULL) return(E_NOMEM);
(*(JOB **)analPtr)->JOBname = name;
(*(JOB **)analPtr)->JOBtype = type;
(*(JOB **)analPtr)->JOBnextJob = ((TSKtask *)taskPtr)->jobs;
((TSKtask *)taskPtr)->jobs = (JOB *)*analPtr;
return(OK);
}

View File

@ -1,38 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/*
*CKTnewEq(ckt,node,name)
* Allocate a new circuit equation number (returned) in the specified
* circuit to contain a new equation or node
* returns -1 for failure to allocate a node number
*
*/
#include "ngspice.h"
#include <stdio.h>
#include "ifsim.h"
#include "iferrmsg.h"
#include "smpdefs.h"
#include "cktdefs.h"
int
CKTnewEq(void *inCkt, void **node, IFuid name)
{
CKTnode *mynode;
register CKTcircuit *ckt = (CKTcircuit *)inCkt;
int error;
error = CKTmkNode(ckt,&mynode);
if(error) return(error);
if(node) *node = (void *)mynode;
mynode->name = name;
error = CKTlinkEq(ckt,mynode);
return(error);
}

View File

@ -1,45 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/*
*CKTnewNode(ckt,node,name)
* Allocate a new circuit equation number (returned) in the specified
* circuit to contain a new equation or node
* returns -1 for failure to allocate a node number
*
*/
#include "ngspice.h"
#include <stdio.h>
#include "ifsim.h"
#include "iferrmsg.h"
#include "smpdefs.h"
#include "cktdefs.h"
/* should just call CKTnewEQ and set node type afterwards */
int
CKTnewNode(void *inCkt, void **node, IFuid name)
{
register CKTcircuit *ckt = (CKTcircuit *)inCkt;
if(!(ckt->CKTnodes)) { /* starting the list - allocate both ground and 1 */
ckt->CKTnodes = (CKTnode *) MALLOC(sizeof(CKTnode));
if(ckt->CKTnodes == (CKTnode *)NULL) return(E_NOMEM);
ckt->CKTnodes->name = (char *)NULL;
ckt->CKTnodes->type = SP_VOLTAGE;
ckt->CKTnodes->number = 0;
ckt->CKTlastNode = ckt->CKTnodes;
}
ckt->CKTlastNode->next = (CKTnode *)MALLOC(sizeof(CKTnode));
if(ckt->CKTlastNode->next == (CKTnode *)NULL) return(E_NOMEM);
ckt->CKTlastNode = ckt->CKTlastNode->next;
ckt->CKTlastNode->name = name;
ckt->CKTlastNode->number = ckt->CKTmaxEqNum++;
ckt->CKTlastNode->type = SP_VOLTAGE;
ckt->CKTlastNode->next = (CKTnode *)NULL;
if(node) *node = (void *)ckt->CKTlastNode;
return(OK);
}

View File

@ -1,33 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/*
*/
/*
*CKTnodName(ckt)
* output information on all circuit nodes/equations
*
*/
#include "ngspice.h"
#include <stdio.h>
#include "cktdefs.h"
IFuid
CKTnodName(CKTcircuit *ckt, register int nodenum)
{
register CKTnode *here;
for(here = ckt->CKTnodes;here; here = here->next) {
if(here->number == nodenum) {
/* found it */
return(here->name);
}
}
/* doesn't exist - do something */
return("UNKNOWN NODE");
}

View File

@ -1,140 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1987 Gary W. Ng
**********/
/*
* CKTnoise (ckt, mode, operation, data)
*
* This routine is responsible for naming and evaluating all of the
* noise sources in the circuit. It uses a series of subroutines to
* name and evaluate the sources associated with each model, and then
* it evaluates the noise for the entire circuit.
*/
#include "ngspice.h"
#include <stdio.h>
#include "cktdefs.h"
#include "devdefs.h"
#include "fteconst.h"
#include "iferrmsg.h"
#include "noisedef.h"
#include "sperror.h"
int
CKTnoise (CKTcircuit *ckt, int mode, int operation, Ndata *data)
{
double outNdens;
int i;
extern SPICEdev *DEVices[];
IFvalue outData; /* output variable (points to list of outputs)*/
IFvalue refVal; /* reference variable (always 0)*/
int error;
outNdens = 0.0;
/* let each device decide how many and what type of noise sources it has */
for (i=0; i < DEVmaxnum; i++) {
if ( ((*DEVices[i]).DEVnoise != NULL) && (ckt->CKThead[i] != NULL) ) {
error = (*((*DEVices[i]).DEVnoise))(mode,operation,ckt->CKThead[i],
ckt,data, &outNdens);
if (error) return (error);
}
}
switch (operation) {
case N_OPEN:
/* take care of the noise for the circuit as a whole */
switch (mode) {
case N_DENS:
data->namelist = (IFuid *)trealloc((char *)data->namelist,
(data->numPlots + 1)*sizeof(IFuid));
(*(SPfrontEnd->IFnewUid))(ckt, &(data->namelist[data->numPlots++]),
(IFuid)NULL,"onoise_spectrum",UID_OTHER,(void **)NULL);
data->namelist = (IFuid *)trealloc((char *)data->namelist,
(data->numPlots + 1)*sizeof(IFuid));
(*(SPfrontEnd->IFnewUid))(ckt, &(data->namelist[data->numPlots++]),
(IFuid)NULL,"inoise_spectrum",UID_OTHER,(void **)NULL);
/* we've added two more plots */
data->outpVector =
(double *)MALLOC(data->numPlots * sizeof(double));
break;
case INT_NOIZ:
data->namelist = (IFuid *)trealloc((char *)data->namelist,
(data->numPlots + 1)*sizeof(IFuid));
(*(SPfrontEnd->IFnewUid))(ckt, &(data->namelist[data->numPlots++]),
(IFuid)NULL,"onoise_total",UID_OTHER,(void **)NULL);
data->namelist = (IFuid *)trealloc((char *)data->namelist,
(data->numPlots + 1)*sizeof(IFuid));
(*(SPfrontEnd->IFnewUid))(ckt, &(data->namelist[data->numPlots++]),
(IFuid)NULL,"inoise_total",UID_OTHER,(void **)NULL);
/* we've added two more plots */
data->outpVector =
(double *) MALLOC(data->numPlots * sizeof(double));
break;
default:
return (E_INTERN);
}
break;
case N_CALC:
switch (mode) {
case N_DENS:
if ((((NOISEAN*)ckt->CKTcurJob)->NStpsSm == 0)
|| data->prtSummary)
{
data->outpVector[data->outNumber++] = outNdens;
data->outpVector[data->outNumber++] =
(outNdens * data->GainSqInv);
refVal.rValue = data->freq; /* the reference is the freq */
outData.v.numValue = data->outNumber; /* vector number */
outData.v.vec.rVec = data->outpVector; /* vector of outputs */
(*(SPfrontEnd->OUTpData))(data->NplotPtr,&refVal,&outData);
}
break;
case INT_NOIZ:
data->outpVector[data->outNumber++] = data->outNoiz;
data->outpVector[data->outNumber++] = data->inNoise;
outData.v.vec.rVec = data->outpVector; /* vector of outputs */
outData.v.numValue = data->outNumber; /* vector number */
(*(SPfrontEnd->OUTpData))(data->NplotPtr,&refVal,&outData);
break;
default:
return (E_INTERN);
}
break;
case N_CLOSE:
(*(SPfrontEnd->OUTendPlot))(data->NplotPtr);
FREE(data->namelist);
FREE(data->outpVector);
break;
default:
return (E_INTERN);
}
return (OK);
}

View File

@ -1,56 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/*
*/
#include "ngspice.h"
#include <stdio.h>
#include "tskdefs.h"
#include "ifsim.h"
#include "cktdefs.h"
#include "iferrmsg.h"
/* ARGSUSED */
int
CKTnewTask(void *ckt, void **taskPtr, IFuid taskName)
{
register TSKtask *tsk;
*taskPtr = (void *)MALLOC(sizeof(TSKtask));
if(*taskPtr==NULL) return(E_NOMEM);
tsk = *(TSKtask **)taskPtr;
tsk->TSKname = taskName;
tsk->TSKgmin = 1e-12;
tsk->TSKabstol = 1e-12;
tsk->TSKreltol = 1e-3;
tsk->TSKchgtol = 1e-14;
tsk->TSKvoltTol = 1e-6;
#ifdef NEWTRUNC
tsk->TSKlteReltol = 1e-3;
tsk->TSKlteAbstol = 1e-6;
#endif /* NEWTRUNC */
tsk->TSKtrtol = 7;
tsk->TSKbypass = 1;
tsk->TSKtranMaxIter = 10;
tsk->TSKdcMaxIter = 100;
tsk->TSKdcTrcvMaxIter = 50;
tsk->TSKintegrateMethod = TRAPEZOIDAL;
tsk->TSKmaxOrder = 2;
tsk->TSKnumSrcSteps = 10;
tsk->TSKnumGminSteps = 10;
tsk->TSKpivotAbsTol = 1e-13;
tsk->TSKpivotRelTol = 1e-3;
tsk->TSKtemp = 300.15;
tsk->TSKnomTemp = 300.15;
tsk->TSKdefaultMosL = 1e-4;
tsk->TSKdefaultMosW = 1e-4;
tsk->TSKdefaultMosAD = 0;
tsk->TSKdefaultMosAS = 0;
tsk->TSKnoOpIter=0;
tsk->TSKtryToCompact=0;
tsk->TSKbadMos3=0;
tsk->TSKkeepOpInfo=0;
return(OK);
}

View File

@ -1,32 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/*
*/
/* CKTnum2nod
* find the given node given its name and return the node pointer
*/
#include "ngspice.h"
#include <stdio.h>
#include "ifsim.h"
#include "sperror.h"
#include "cktdefs.h"
/* ARGSUSED */
CKTnode *
CKTnum2nod(CKTcircuit *ckt, int node)
{
register CKTnode *here;
for (here = ((CKTcircuit *)ckt)->CKTnodes; here; here = here->next) {
if(here->number == node) {
return(here);
}
}
return((CKTnode *)NULL);
}

View File

@ -1,146 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
#include "ngspice.h"
#include <stdio.h>
#include "cktdefs.h"
#include "devdefs.h"
#include "sperror.h"
int
CKTop(CKTcircuit *ckt, long int firstmode, long int continuemode, int iterlim)
{
int converged;
int i;
ckt->CKTmode = firstmode;
if(!ckt->CKTnoOpIter) {
converged = NIiter(ckt,iterlim);
} else {
converged = 1; /* the 'go directly to gmin stepping' option */
}
if(converged != 0) {
/* no convergence on the first try, so we do something else */
/* first, check if we should try gmin stepping */
/* note that no path out of this code allows ckt->CKTdiagGmin to be
* anything but 0.000000000
*/
if(ckt->CKTnumGminSteps >1) {
ckt->CKTmode = firstmode;
(*(SPfrontEnd->IFerror))(ERR_INFO,
"starting Gmin stepping",(IFuid *)NULL);
ckt->CKTdiagGmin = ckt->CKTgmin;
for(i=0;i<ckt->CKTnumGminSteps;i++) {
ckt->CKTdiagGmin *= 10;
}
for(i=0;i<=ckt->CKTnumGminSteps;i++) {
ckt->CKTnoncon =1;
converged = NIiter(ckt,iterlim);
if(converged != 0) {
ckt->CKTdiagGmin = 0;
(*(SPfrontEnd->IFerror))(ERR_WARNING,
"Gmin step failed",(IFuid *)NULL);
break;
}
ckt->CKTdiagGmin /= 10;
ckt->CKTmode=continuemode;
(*(SPfrontEnd->IFerror))(ERR_INFO,
"One successful Gmin step",(IFuid *)NULL);
}
ckt->CKTdiagGmin = 0;
converged = NIiter(ckt,iterlim);
if(converged == 0) {
(*(SPfrontEnd->IFerror))(ERR_INFO,
"Gmin stepping completed",(IFuid *)NULL);
return(0);
}
(*(SPfrontEnd->IFerror))(ERR_WARNING,
"Gmin stepping failed",(IFuid *)NULL);
}
/* now, we'll try source stepping - we scale the sources
* to 0, converge, then start stepping them up until they
* are at their normal values
*
* note that no path out of this code allows ckt->CKTsrcFact to be
* anything but 1.000000000
*/
if(ckt->CKTnumSrcSteps >1) {
ckt->CKTmode = firstmode;
(*(SPfrontEnd->IFerror))(ERR_INFO,
"starting source stepping",(IFuid *)NULL);
for(i=0;i<=ckt->CKTnumSrcSteps;i++) {
ckt->CKTsrcFact = ((double)i)/((double)ckt->CKTnumSrcSteps);
converged = NIiter(ckt,iterlim);
ckt->CKTmode = continuemode;
if(converged != 0) {
ckt->CKTsrcFact = 1;
ckt->CKTcurrentAnalysis = DOING_TRAN;
(*(SPfrontEnd->IFerror))(ERR_WARNING,
"source stepping failed",(IFuid *)NULL);
return(converged);
}
(*(SPfrontEnd->IFerror))(ERR_INFO,
"One successful source step",(IFuid *)NULL);
}
(*(SPfrontEnd->IFerror))(ERR_INFO,
"Source stepping completed",(IFuid *)NULL);
ckt->CKTsrcFact = 1;
return(0);
} else {
return(converged);
}
}
return(0);
}
/* CKTconvTest(ckt)
* this is a driver program to iterate through all the various
* convTest functions provided for the circuit elements in the
* given circuit
*/
int
CKTconvTest(register CKTcircuit *ckt)
{
extern SPICEdev *DEVices[];
register int i;
int error = OK;
#ifdef PARALLEL_ARCH
int ibuf[2];
long type = MT_CONV, length = 2;
#endif /* PARALLEL_ARCH */
for (i=0;i<DEVmaxnum;i++) {
if (((*DEVices[i]).DEVconvTest != NULL) && (ckt->CKThead[i] != NULL)) {
error = (*((*DEVices[i]).DEVconvTest))(ckt->CKThead[i],ckt);
}
#ifdef PARALLEL_ARCH
if (error || ckt->CKTnoncon) goto combine;
#else
if (error) return(error);
if (ckt->CKTnoncon) {
/* printf("convTest: device %s failed\n",
(*DEVices[i]).DEVpublic.name); */
return(OK);
}
#endif /* PARALLEL_ARCH */
}
#ifdef PARALLEL_ARCH
combine:
/* See if any of the DEVconvTest functions bailed. If not, proceed. */
ibuf[0] = error;
ibuf[1] = ckt->CKTnoncon;
IGOP_( &type, ibuf, &length, "+" );
ckt->CKTnoncon = ibuf[1];
if ( ibuf[0] != error ) {
error = E_MULTIERR;
}
return (error);
#else
return(OK);
#endif /* PARALLEL_ARCH */
}

View File

@ -1,33 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/* CKTparam
* attach the given parameter to the specified device in the given circuit
*/
#include "ngspice.h"
#include <stdio.h>
#include "cktdefs.h"
#include "ifsim.h"
#include "devdefs.h"
#include "sperror.h"
extern SPICEdev *DEVices[];
/* ARGSUSED */
int
CKTparam(void *ckt, void *fast, int param, IFvalue *val, IFvalue *selector)
{
register int type;
GENinstance *myfast = (GENinstance *)fast;
type = myfast->GENmodPtr->GENmodType;
if(((*DEVices[type]).DEVparam)) {
return(((*((*DEVices[type]).DEVparam)) (param,val,myfast,selector)));
} else {
return(E_BADPARM);
}
}

View File

@ -1,42 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1992 David A. Gates, UC Berkeley CADgroup
**********/
/* CKTpartition(ckt)
* this labels each instance of a circuit as belonging to a
* particular processor in a multiprocessor computer.
*/
#include "ngspice.h"
#include <stdio.h>
#include "smpdefs.h"
#include "cktdefs.h"
#include "const.h"
#include "devdefs.h"
#include "sperror.h"
extern SPICEdev *DEVices[];
int
CKTpartition(register CKTcircuit *ckt)
{
register int i, instNum = 0;
register GENmodel *model;
register GENinstance *inst;
for (i=0;i<DEVmaxnum;i++) {
if ( (ckt->CKThead[i] != NULL) ) {
for (model = ckt->CKThead[i]; model; model = model->GENnextModel) {
for (inst = model->GENinstances; inst;
inst = inst->GENnextInstance) {
inst->GENowner = instNum % ARCHsize;
instNum++;
}
}
}
}
return(OK);
}

View File

@ -1,51 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/*
* CKTpModName()
*
* Take a parameter by Name and set it on the specified model
*/
#include "ngspice.h"
#include <stdio.h>
#include "ifsim.h"
#include "devdefs.h"
#include "cktdefs.h"
#include "gendefs.h"
#include "sperror.h"
extern SPICEdev *DEVices[];
/* ARGSUSED */
int
CKTpModName(char *parm, IFvalue *val, CKTcircuit *ckt, int type, IFuid name, GENmodel **modfast)
/* the name of the parameter to set */
/* the parameter union containing the value to set */
/* the circuit this model is a member of */
/* the device type code to the model being parsed */
/* the name of the model being parsed */
/* direct pointer to model being parsed */
{
int error; /* int to store evaluate error return codes in */
int i;
for(i=0;i<(*(*DEVices[type]).DEVpublic.numModelParms);i++) {
if(strcmp(parm,((*DEVices[type]).DEVpublic.modelParms[i].keyword))==0){
error = CKTmodParam((void *)ckt,(void *)*modfast,
(*DEVices[type]).DEVpublic.modelParms[i].id,val,
(IFvalue*)NULL);
if(error) return(error);
break;
}
}
if(i==(*(*DEVices[type]).DEVpublic.numModelParms)) {
return(E_BADPARM);
}
return(OK);
}

View File

@ -1,54 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/*
*/
/*
* CKTpName()
*
* Take a parameter by Name and set it on the specified device
*/
#include "ngspice.h"
#include <stdio.h>
#include "ifsim.h"
#include "devdefs.h"
#include "cktdefs.h"
#include "gendefs.h"
#include "sperror.h"
extern SPICEdev *DEVices[];
/* ARGSUSED */
int
CKTpName(char *parm, IFvalue *val, CKTcircuit *ckt, int dev, char *name, GENinstance **fast)
/* the name of the parameter to set */
/* the parameter union containing the value to set */
/* the circuit this device is a member of */
/* the device type code to the device being parsed */
/* the name of the device being parsed */
/* direct pointer to device being parsed */
{
int error; /* int to store evaluate error return codes in */
int i;
for(i=0;i<(*(*DEVices[dev]).DEVpublic.numInstanceParms);i++) {
if(strcmp(parm,
((*DEVices[dev]).DEVpublic.instanceParms[i].keyword))==0) {
error = CKTparam((void*)ckt,(void *)*fast,
(*DEVices[dev]).DEVpublic.instanceParms[i].id,val,
(IFvalue *)NULL);
if(error) return(error);
break;
}
}
if(i==(*(*DEVices[dev]).DEVpublic.numInstanceParms)) {
return(E_BADPARM);
}
return(OK);
}

View File

@ -1,81 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
**********/
#include "ngspice.h"
#include <stdio.h>
#include "pzdefs.h"
#include "smpdefs.h"
#include "cktdefs.h"
#include "complex.h"
#include "devdefs.h"
#include "sperror.h"
extern SPICEdev *DEVices[];
int
CKTpzLoad(CKTcircuit *ckt, SPcomplex *s)
{
PZAN *pzan = (PZAN *) (ckt->CKTcurJob);
int error;
int i;
#ifdef PARALLEL_ARCH
long type = MT_PZLOAD, length = 1;
#endif /* PARALLEL_ARCH */
for (i = 0; i <= SMPmatSize(ckt->CKTmatrix); i++) {
ckt->CKTrhs[i] = 0.0;
ckt->CKTirhs[i] = 0.0;
}
SMPcClear(ckt->CKTmatrix);
for (i = 0; i < DEVmaxnum; i++) {
if (DEVices[i]->DEVpzLoad != NULL && ckt->CKThead[i] != NULL) {
error = (*DEVices[i]->DEVpzLoad)(ckt->CKThead[i], ckt, s);
#ifdef PARALLEL_ARCH
if (error) goto combine;
#else
if(error) return(error);
#endif /* PARALLEL_ARCH */
}
}
#ifdef PARALLEL_ARCH
combine:
/* See if any of the DEVload functions bailed. If not, proceed. */
IGOP_( &type, &error, &length, "max" );
if (error == OK) {
SMPcCombine( ckt->CKTmatrix, ckt->CKTrhs, ckt->CKTrhsSpare,
ckt->CKTirhs, ckt->CKTirhsSpare );
} else {
return(error);
}
#endif /* PARALLEL_ARCH */
#ifdef notdef
printf("*** Before PZ adjustments *\n");
SMPprint(ckt->CKTmatrix, stdout);
#endif
if (pzan->PZbalance_col && pzan->PZsolution_col) {
SMPcAddCol(ckt->CKTmatrix, pzan->PZbalance_col, pzan->PZsolution_col);
/* AC sources ?? XXX */
}
if (pzan->PZsolution_col) {
SMPcZeroCol(ckt->CKTmatrix, pzan->PZsolution_col);
}
/* Driving function (current source) */
if (pzan->PZdrive_pptr)
*pzan->PZdrive_pptr = 1.0;
if (pzan->PZdrive_nptr)
*pzan->PZdrive_nptr = -1.0;
#ifdef notdef
printf("*** After PZ adjustments *\n");
SMPprint(ckt->CKTmatrix, stdout);
#endif
return(OK);
}

View File

@ -1,105 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
**********/
/* CKTpzSetup(ckt)
* iterate through all the various
* pzSetup functions provided for the circuit elements in the
* given circuit, setup ...
*/
#include "ngspice.h"
#include <stdio.h>
#include "smpdefs.h"
#include "cktdefs.h"
#include "devdefs.h"
#include "sperror.h"
#define CKALLOC(var,size,type) \
if(size && (!(var =(type *)MALLOC((size)*sizeof(type))))){\
return(E_NOMEM);\
}
int
CKTpzSetup(register CKTcircuit *ckt, int type)
{
extern SPICEdev *DEVices[];
PZAN *pzan = (PZAN *) ckt->CKTcurJob;
SMPmatrix *matrix;
int error;
int i, temp, solution_col, balance_col;
int input_pos, input_neg, output_pos, output_neg;
NIdestroy(ckt);
error = NIinit(ckt);
if (error)
return(error);
matrix = ckt->CKTmatrix;
/* Really awful . . . */
ckt->CKTnumStates = 0;
for (i = 0; i < DEVmaxnum; i++) {
if (DEVices[i]->DEVpzSetup != NULL && ckt->CKThead[i] != NULL) {
error = (*DEVices[i]->DEVpzSetup)(matrix, ckt->CKThead[i],
ckt, &ckt->CKTnumStates);
if (error != OK)
return(error);
}
}
solution_col = 0;
balance_col = 0;
input_pos = pzan->PZin_pos;
input_neg = pzan->PZin_neg;
if (type == PZ_DO_ZEROS) {
/* Vo/Ii in Y */
output_pos = pzan->PZout_pos;
output_neg = pzan->PZout_neg;
} else if (pzan->PZinput_type == PZ_IN_VOL) {
/* Vi/Ii in Y */
output_pos = pzan->PZin_pos;
output_neg = pzan->PZin_neg;
} else {
/* Denominator */
output_pos = 0;
output_neg = 0;
input_pos = 0;
input_neg = 0;
}
if (output_pos) {
solution_col = output_pos;
if (output_neg)
balance_col = output_neg;
} else {
solution_col = output_neg;
temp = input_pos;
input_pos = input_neg;
input_neg = temp;
}
if (input_pos)
pzan->PZdrive_pptr = SMPmakeElt(matrix, input_pos, solution_col);
else
pzan->PZdrive_pptr = NULL;
if (input_neg)
pzan->PZdrive_nptr = SMPmakeElt(matrix, input_neg, solution_col);
else
pzan->PZdrive_nptr = NULL;
pzan->PZsolution_col = solution_col;
pzan->PZbalance_col = balance_col;
pzan->PZnumswaps = 1;
error = NIreinit(ckt);
if (error)
return(error);
return OK;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,788 +0,0 @@
/**********
Copyright 1991 Regents of the University of California. All rights reserved.
**********/
#include "ngspice.h"
#include "ifsim.h"
#include "sperror.h"
#include "spmatrix.h"
#include "gendefs.h"
#include "devdefs.h"
#include "cktdefs.h"
#include "smpdefs.h"
#include "sensdefs.h"
#include "sensgen.h"
/* #define ASDEBUG */
#ifdef ASDEBUG
#define DEBUG(X) if ((X) < Sens_Debug)
int Sens_Debug = 0;
char SF1[] = "res";
char SF2[] = "dc";
char SF3[] = "bf";
#endif
char *Sfilter = NULL;
double Sens_Delta = 0.000001;
double Sens_Abs_Delta = 0.000001;
static int sens_setp(sgen *sg, CKTcircuit *ckt, IFvalue *val);
static int sens_load(sgen *sg, CKTcircuit *ckt, int is_dc);
static int sens_temp(sgen *sg, CKTcircuit *ckt);
static int count_steps(int type, double low, double high, int steps, double *stepsize);
static double inc_freq(double freq, int type, double step_size);
extern SPICEdev *DEVices[];
/*
* Procedure:
*
* Determine operating point (call CKTop)
*
* For each frequency point:
* (for AC) call NIacIter to get base node voltages
* For each element/parameter in the test list:
* construct the perturbation matrix
* Solve for the sensitivities:
* delta_E = Y^-1 (delta_Y E - delta_I)
* save results
*/
static int error;
int sens_sens(CKTcircuit *ckt, int restart)
{
SENS_AN *sen_info = ((SENS_AN *) ckt->CKTcurJob);
static int size;
static double *delta_I, *delta_iI,
*delta_I_delta_Y, *delta_iI_delta_Y;
sgen *sg;
static double freq;
static int nfreqs;
static int i;
static SMPmatrix *delta_Y = NULL, *Y;
static double step_size;
double *E, *iE;
IFvalue value, nvalue;
double *output_values;
IFcomplex *output_cvalues;
double delta_var;
int (*fn)( );
static int is_dc;
int k, j, n;
int num_vars, branch_eq;
char *sen_data;
char namebuf[513];
IFuid *output_names, freq_name;
int bypass;
int type;
#ifndef notdef
#ifdef notdef
for (sg = sgen_init(ckt, 0); sg; sgen_next(&sg)) {
if (sg->is_instparam)
printf("%s:%s:%s -> param %s\n",
DEVices[sg->dev]->DEVpublic.name,
sg->model->GENmodName,
sg->instance->GENname,
sg->ptable[sg->param].keyword);
else
printf("%s:%s:%s -> mparam %s\n",
DEVices[sg->dev]->DEVpublic.name,
sg->model->GENmodName,
sg->instance->GENname,
sg->ptable[sg->param].keyword);
}
#endif
#ifdef ASDEBUG
DEBUG(1)
printf(">>> restart : %d\n", restart);
#endif
/* get to work */
restart = 1;
if (restart) {
freq = 0.0;
is_dc = (sen_info->step_type == SENS_DC);
nfreqs = count_steps(sen_info->step_type, sen_info->start_freq,
sen_info->stop_freq, sen_info->n_freq_steps,
&step_size);
if (!is_dc)
freq = sen_info->start_freq;
error = CKTop(ckt,
(ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITJCT,
(ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITFLOAT,
ckt->CKTdcMaxIter);
#ifdef notdef
ckt->CKTmode = (ckt->CKTmode & MODEUIC)
| MODEDCOP | MODEINITSMSIG;
#endif
if (error)
return error;
size = spGetSize(ckt->CKTmatrix, 1);
/* Create the perturbation matrix */
/* XXX check error return, '1' is complex -- necessary?
* only in ac */
delta_Y = spCreate(size, !is_dc, &error);
size += 1;
/* Create an extra rhs */
delta_I = NEWN(double, size);
delta_iI = NEWN(double, size);
delta_I_delta_Y = NEWN(double, size);
delta_iI_delta_Y = NEWN(double, size);
num_vars = 0;
for (sg = sgen_init(ckt, is_dc); sg; sgen_next(&sg)) {
num_vars += 1;
}
if (!num_vars)
return OK; /* XXXX Should be E_ something */
k = 0;
output_names = NEWN(IFuid, num_vars);
for (sg = sgen_init(ckt, is_dc); sg; sgen_next(&sg)) {
if (!sg->is_instparam) {
sprintf(namebuf, "%s:%s",
sg->instance->GENname,
sg->ptable[sg->param].keyword);
} else if ((sg->ptable[sg->param].dataType
& IF_PRINCIPAL) && sg->is_principle == 1)
{
sprintf(namebuf, "%s", sg->instance->GENname);
} else {
sprintf(namebuf, "%s_%s",
sg->instance->GENname,
sg->ptable[sg->param].keyword);
}
(*SPfrontEnd->IFnewUid)((void *) ckt,
output_names + k, NULL,
namebuf, UID_OTHER, NULL);
k += 1;
}
if (is_dc) {
type = IF_REAL;
freq_name = NULL;
} else {
type = IF_COMPLEX;
(*SPfrontEnd->IFnewUid)((void *) ckt,
&freq_name, NULL,
"frequency", UID_OTHER, NULL);
}
error = (*SPfrontEnd->OUTpBeginPlot)((void *) ckt,
(void *) ckt->CKTcurJob,
ckt->CKTcurJob->JOBname, freq_name, IF_REAL, num_vars,
output_names, type, (void **) &sen_data);
if (error)
return error;
FREE(output_names);
if (is_dc) {
output_values = NEWN(double, num_vars);
output_cvalues = NULL;
} else {
output_values = NULL;
output_cvalues = NEWN(IFcomplex, num_vars);
if (sen_info->step_type != SENS_LINEAR)
(*(SPfrontEnd->OUTattributes))((void *)sen_data,
NULL, OUT_SCALE_LOG, NULL);
}
} else {
/*XXX Restore saved state */
}
#ifdef ASDEBUG
DEBUG(1)
printf("start: %f, num: %d, dc: %d\n", freq, nfreqs, is_dc);
#endif
if (!sen_info->output_volt)
branch_eq = CKTfndBranch(ckt, sen_info->output_src);
bypass = ckt->CKTbypass;
ckt->CKTbypass = 0;
/* The unknown vector of node voltages overwrites rhs */
E = ckt->CKTrhs;
iE = ckt->CKTirhs;
ckt->CKTrhsOld = E;
ckt->CKTirhsOld = iE;
Y = ckt->CKTmatrix;
#ifdef ASDEBUG
DEBUG(1) {
printf("Operating point:\n");
for (i = 0; i < size; i++)
printf(" E [%d] = %20.15g\n", i, E[i]);
}
#endif
#ifdef notdef
for (j = 0; j <= ckt->CKTmaxOrder + 1; j++) {
save_states[j] = ckt->CKTstates[j];
ckt->CKTstates[j] = NULL;
}
#endif
for (i = 0; i < nfreqs; i++) {
/* XXX handle restart */
n = 0;
if ((*SPfrontEnd->IFpauseTest)( )) {
/* XXX Save State */
return E_PAUSE;
}
for (j = 0; j < size; j++) {
delta_I[j] = 0.0;
delta_iI[j] = 0.0;
}
if (freq != 0.0) {
ckt->CKTrhs = E;
ckt->CKTirhs = iE;
ckt->CKTmatrix = Y;
/* This generates Y in LU form */
ckt->CKTomega = 2.0 * M_PI * freq;
/* Yes, all this has to be re-done */
/* XXX Free old states */
error = CKTunsetup(ckt);
if (error)
return error;
/* XXX ckt->CKTmatrix = Y; */
error = CKTsetup(ckt);
if (error)
return error;
E = ckt->CKTrhs;
iE = ckt->CKTirhs;
Y = ckt->CKTmatrix;
#ifdef notdef
for (j = 0; j <= ckt->CKTmaxOrder + 1; j++) {
/* XXX Free new states */
ckt->CKTstates[j] = save_states[j];
}
#endif
error = CKTtemp(ckt);
if (error)
return error;
error = CKTload(ckt); /* INITSMSIGS */
if (error)
return error;
error = NIacIter(ckt);
if (error)
return error;
#ifdef notdef
/* XXX Why? */
for (j = 0; j <= ckt->CKTmaxOrder + 1; j++) {
ckt->CKTstates[j] = NULL;
}
#endif
}
/* Use a different vector & matrix */
ckt->CKTrhs = delta_I;
ckt->CKTirhs = delta_iI;
ckt->CKTmatrix = delta_Y;
/* calc. effect of each param */
for (sg = sgen_init(ckt, is_dc /* sen_info->plist */);
sg; sgen_next(&sg))
{
#ifdef ASDEBUG
DEBUG(2) {
printf("E/iE: %x/%x; delta_I/iI: %x/%x\n",
E, iE, delta_I, delta_iI);
printf("cktrhs/irhs: %x/%x\n",
ckt->CKTrhs, ckt->CKTirhs);
if (sg->is_instparam)
printf("%s:%s:%s -> param %s\n",
DEVices[sg->dev]->DEVpublic.name,
sg->model->GENmodName,
sg->instance->GENname,
sg->ptable[sg->param].keyword);
else
printf("%s:%s:%s -> mparam %s\n",
DEVices[sg->dev]->DEVpublic.name,
sg->model->GENmodName,
sg->instance->GENname,
sg->ptable[sg->param].keyword);
}
#endif
spClear(delta_Y);
for (j = 0; j < size; j++) {
delta_I[j] = 0.0;
delta_iI[j] = 0.0;
}
/* ? should this just call CKTsetup
* ? but then CKThead would have to get fiddled with */
ckt->CKTnumStates = sg->istate;
fn = DEVices[sg->dev]->DEVsetup;
if (fn)
(*fn)(delta_Y, sg->model, ckt,
/* XXXX insert old state base here ?? */
&ckt->CKTnumStates);
/* ? CKTsetup would call NIreinit instead */
ckt->CKTniState = NISHOULDREORDER | NIACSHOULDREORDER;
/* XXX instead of calling temp here, just swap
* back to the original states */
(void) sens_temp(sg, ckt);
/* XXX Leave original E until here!! so that temp reads
* the right node voltages */
if (sens_load(sg, ckt, is_dc)) {
if (error && error != E_BADPARM)
return error; /* XXX */
continue;
}
/* Alter the parameter */
#ifdef ASDEBUG
DEBUG(1) printf("Original value: %g\n", sg->value);
#endif
#ifdef ASDEBUG
DEBUG(2) {
printf("Effect of device:\n");
spPrint(delta_Y, 0, 1, 1);
printf("LHS:\n");
for (j = 0; j < size; j++)
printf("%d: %g, %g\n", j,
delta_I[j], delta_iI[j]);
}
#endif
if (sg->value != 0.0)
delta_var = sg->value * Sens_Delta;
else
delta_var = Sens_Abs_Delta;
nvalue.rValue = sg->value + delta_var;
#ifdef ASDEBUG
DEBUG(1)
printf("New value: %g\n", nvalue.rValue);
#endif
sens_setp(sg, ckt, &nvalue);
if (error && error != E_BADPARM)
return error;
spConstMult(delta_Y, -1.0);
for (j = 0; j < size; j++) {
delta_I[j] *= -1.0;
delta_iI[j] *= -1.0;
}
#ifdef ASDEBUG
DEBUG(2) {
printf("Effect of negating matrix:\n");
spPrint(delta_Y, 0, 1, 1);
for (j = 0; j < size; j++)
printf("%d: %g, %g\n", j,
delta_I[j], delta_iI[j]);
}
#endif
/* XXX swap back to temp states ?? Naw ... */
(void) sens_temp(sg, ckt);
#ifdef ASDEBUG
DEBUG(1) {
if (sens_getp(sg, ckt, &value)) {
continue;
}
printf("New value in device: %g\n",
value.rValue);
}
#endif
sens_load(sg, ckt, is_dc);
#ifdef ASDEBUG
DEBUG(2) {
printf("Effect of changing the parameter:\n");
spPrint(delta_Y, 0, 1, 1);
for (j = 0; j < size; j++)
printf("%d: %g, %g\n", j,
delta_I[j], delta_iI[j]);
}
#endif
/* Set the perturbed variable back to it's
* original value
*/
value.rValue = sg->value;
sens_setp(sg, ckt, &value);
(void) sens_temp(sg, ckt); /* XXX is this necessary? */
/* Back to business . . . */
#ifdef ASDEBUG
DEBUG(2)
for (j = 0; j < size; j++)
printf(" E [%d] = %20.15g\n",
j, E[j]);
#endif
/* delta_Y E */
spMultiply(delta_Y, delta_I_delta_Y, E,
delta_iI_delta_Y, iE);
#ifdef ASDEBUG
DEBUG(2)
for (j = 0; j < size; j++)
printf("delta_Y * E [%d] = %20.15g\n",
j, delta_I_delta_Y[j]);
#endif
/* delta_I - delta_Y E */
for (j = 0; j < size; j++) {
delta_I[j] -= delta_I_delta_Y[j];
delta_iI[j] -= delta_iI_delta_Y[j];
}
#ifdef ASDEBUG
DEBUG(2) {
printf(">>> Y:\n");
spPrint(Y, 0, 1, 1);
for (j = 0; j < size; j++)
printf("%d: %g, %g\n", j,
delta_I[j], delta_iI[j]);
}
#endif
/* Solve; Y already factored */
spSolve(Y, delta_I, delta_I, delta_iI, delta_iI);
#ifdef ASDEBUG
DEBUG(2) {
for (j = 1; j < size; j++) {
if (sg->is_instparam)
printf("%d/%s.%s = %g, %g\n",
j,
sg->instance->GENname,
sg->ptable[sg->param].keyword,
delta_I[j], delta_iI[j]);
else
printf("%d/%s:%s = %g, %g\n",
j,
sg->instance->GENname,
sg->ptable[sg->param].keyword,
delta_I[j], delta_iI[j]);
}
}
#endif
/* delta_I is now equal to delta_E */
if (is_dc) {
if (sen_info->output_volt)
output_values[n] = delta_I
[sen_info->output_pos->number]
- delta_I
[sen_info->output_neg->number];
else {
output_values[n] = delta_I[branch_eq];
}
output_values[n] /= delta_var;
} else {
if (sen_info->output_volt) {
output_cvalues[n].real = delta_I
[sen_info->output_pos->number]
- delta_I
[sen_info->output_neg->number];
output_cvalues[n].imag = delta_iI
[sen_info->output_pos->number]
- delta_iI
[sen_info->output_neg->number];
} else {
output_cvalues[n].real =
delta_I[branch_eq];
output_cvalues[n].imag =
delta_iI[branch_eq];
}
output_cvalues[n].real /= delta_var;
output_cvalues[n].imag /= delta_var;
}
n += 1;
}
if (is_dc)
nvalue.v.vec.rVec = output_values;
else
nvalue.v.vec.cVec = output_cvalues;
value.rValue = freq;
OUTpData(sen_data, &value, &nvalue);
freq = inc_freq(freq, sen_info->step_type, step_size);
}
(*SPfrontEnd->OUTendPlot)((void *) sen_data);
if (is_dc) {
FREE(output_values); /* XXX free various vectors */
} else {
FREE(output_cvalues); /* XXX free various vectors */
}
spDestroy(delta_Y);
FREE(delta_I);
FREE(delta_iI);
ckt->CKTrhs = E;
ckt->CKTirhs = iE;
ckt->CKTmatrix = Y;
ckt->CKTbypass = bypass;
#ifdef notdef
for (j = 0; j <= ckt->CKTmaxOrder + 1; j++) {
if (ckt->CKTstates[j])
FREE(ckt->CKTstates[j]);
ckt->CKTstates[j] = save_states[j];
}
#endif
#endif
return OK;
}
double
inc_freq(double freq, int type, double step_size)
{
if (type != LINEAR)
freq *= step_size;
else
freq += step_size;
return freq;
}
double
next_freq(int type, double freq, double stepsize)
{
double s;
switch (type) {
case SENS_DC:
s = 0;
break;
case SENS_LINEAR:
s = freq + stepsize;
break;
case SENS_DECADE:
case SENS_OCTAVE:
s = freq * stepsize;
break;
}
return s;
}
int
count_steps(int type, double low, double high, int steps, double *stepsize)
{
double s;
int n;
if (steps < 1)
steps = 1;
switch (type) {
default:
case SENS_DC:
n = 0;
s = 0;
break;
case SENS_LINEAR:
n = steps;
s = (high - low) / steps;
break;
case SENS_DECADE:
if (low <= 0.0)
low = 1e-3;
if (high <= low)
high = 10.0 * low;
n = steps * log10(high/low) + 1.01;
s = pow(10.0, 1.0 / steps);
break;
case SENS_OCTAVE:
if (low <= 0.0)
low = 1e-3;
if (high <= low)
high = 2.0 * low;
n = steps * log(high/low) / M_LOG2E + 1.01;
s = pow(2.0, 1.0 / steps);
break;
}
if (n <= 0)
n = 1;
*stepsize = s;
return n;
}
static int
sens_load(sgen *sg, CKTcircuit *ckt, int is_dc)
{
int (*fn)( );
error = 0;
if (!is_dc)
fn = DEVices[sg->dev]->DEVacLoad;
else
fn = DEVices[sg->dev]->DEVload;
if (fn)
error = (*fn)(sg->model, ckt);
else
return 1;
return error;
}
static int
sens_temp(sgen *sg, CKTcircuit *ckt)
{
int (*fn)( );
error = 0;
fn = DEVices[sg->dev]->DEVtemperature;
if (fn)
error = (*fn)(sg->model, ckt);
else
return 1;
return error;
}
/* Get parameter value */
int
sens_getp(sgen *sg, CKTcircuit *ckt, IFvalue *val)
{
int (*fn)( );
int pid;
error = 0;
if (sg->is_instparam) {
fn = DEVices[sg->dev]->DEVask;
pid = DEVices[sg->dev]->DEVpublic.instanceParms[sg->param].id;
if (fn)
error = (*fn)(ckt, sg->instance, pid, val, NULL);
else
return 1;
} else {
fn = DEVices[sg->dev]->DEVmodAsk;
pid = DEVices[sg->dev]->DEVpublic.modelParms[sg->param].id;
if (fn)
error = (*fn)(ckt, sg->model, pid, val, NULL);
else
return 1;
}
if (error) {
if (sg->is_instparam)
printf("GET ERROR: %s:%s:%s -> param %s (%d)\n",
DEVices[sg->dev]->DEVpublic.name,
sg->model->GENmodName,
sg->instance->GENname,
sg->ptable[sg->param].keyword, pid);
else
printf("GET ERROR: %s:%s:%s -> mparam %s (%d)\n",
DEVices[sg->dev]->DEVpublic.name,
sg->model->GENmodName,
sg->instance->GENname,
sg->ptable[sg->param].keyword, pid);
}
return error;
}
/* Get parameter value */
int
sens_setp(sgen *sg, CKTcircuit *ckt, IFvalue *val)
{
int (*fn)( );
int pid;
error = 0;
if (sg->is_instparam) {
fn = DEVices[sg->dev]->DEVparam;
pid = DEVices[sg->dev]->DEVpublic.instanceParms[sg->param].id;
if (fn)
error = (*fn)(pid, val, sg->instance, NULL);
else
return 1;
} else {
fn = DEVices[sg->dev]->DEVmodParam;
pid = DEVices[sg->dev]->DEVpublic.modelParms[sg->param].id;
if (fn)
error = (*fn)(pid, val, sg->model);
else
return 1;
}
if (error) {
if (sg->is_instparam)
printf("SET ERROR: %s:%s:%s -> param %s (%d)\n",
DEVices[sg->dev]->DEVpublic.name,
sg->model->GENmodName,
sg->instance->GENname,
sg->ptable[sg->param].keyword, pid);
else
printf("SET ERROR: %s:%s:%s -> mparam %s (%d)\n",
DEVices[sg->dev]->DEVpublic.name,
sg->model->GENmodName,
sg->instance->GENname,
sg->ptable[sg->param].keyword, pid);
}
return error;
}

View File

@ -1,24 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
#include "ngspice.h"
#include <stdio.h>
#include "tskdefs.h"
#include "jobdefs.h"
#include "ifsim.h"
#include "iferrmsg.h"
#include "cktdefs.h"
extern SPICEanalysis *analInfo[];
/* ARGSUSED */
int
CKTsetAnalPm(void *ckt, void *analPtr, int parm, IFvalue *value, IFvalue *selector)
{
register int type = ((JOB *)analPtr)->JOBtype;
if((analInfo[type]->setParm)==NULL) return(E_BADPARM);
return( (*(analInfo[type]->setParm))(ckt,analPtr,parm,value) );
}

View File

@ -1,69 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/*
*/
/* CKTsetBreak(ckt,time)
* add the given time to the breakpoint table for the given circuit
*/
#include "ngspice.h"
#include <stdio.h>
#include "cktdefs.h"
#include "ifsim.h"
#include "sperror.h"
int
CKTsetBreak(register CKTcircuit *ckt, double time)
{
double *tmp;
register int i,j;
if(ckt->CKTtime > time) {
(*(SPfrontEnd->IFerror))(ERR_PANIC,"breakpoint in the past - HELP!",
(IFuid *)NULL);
return(E_INTERN);
}
for(i=0;i<ckt->CKTbreakSize;i++) {
if(*(ckt->CKTbreaks+i)>time) { /* passed */
if((*(ckt->CKTbreaks+i)-time) <= ckt->CKTminBreak) {
/* very close together - take earlier point */
*(ckt->CKTbreaks+i) = time;
return(OK);
}
if(time-*(ckt->CKTbreaks+i-1) <= ckt->CKTminBreak) {
/* very close together, but after, so skip */
return(OK);
}
/* fits in middle - new array & insert */
tmp = (double *)MALLOC((ckt->CKTbreakSize+1)*sizeof(double));
if(tmp == (double *)NULL) return(E_NOMEM);
for(j=0;j<i;j++) {
*(tmp+j) = *(ckt->CKTbreaks+j);
}
*(tmp+i)=time;
for(j=i;j<ckt->CKTbreakSize;j++) {
*(tmp+j+1) = *(ckt->CKTbreaks+j);
}
FREE(ckt->CKTbreaks);
ckt->CKTbreakSize++;
ckt->CKTbreaks=tmp;
return(OK);
}
}
/* never found it - beyond end of time - extend out idea of time */
if(time-ckt->CKTbreaks[ckt->CKTbreakSize-1]<=ckt->CKTminBreak) {
/* very close tegether - keep earlier, throw out new point */
return(OK);
}
/* fits at end - grow array & add on */
ckt->CKTbreaks = (double *)REALLOC(ckt->CKTbreaks,
(ckt->CKTbreakSize+1)*sizeof(double));
ckt->CKTbreakSize++;
ckt->CKTbreaks[ckt->CKTbreakSize-1]=time;
return(OK);
}

View File

@ -1,45 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/*
*CKTsetNodPm
*
* set a parameter on a node.
*/
#include "ngspice.h"
#include <stdio.h>
#include "ifsim.h"
#include "iferrmsg.h"
#include "cktdefs.h"
/* ARGSUSED */
int
CKTsetNodPm(void *ckt, void *node, int parm, IFvalue *value, IFvalue *selector)
{
if(!node) return(E_BADPARM);
switch(parm) {
case PARM_NS:
((CKTnode *)node)->nodeset = value->rValue;
((CKTnode *)node)->nsGiven = 1;
break;
case PARM_IC:
((CKTnode *)node)->ic = value->rValue;
((CKTnode *)node)->icGiven = 1;
break;
case PARM_NODETYPE:
((CKTnode *)node)->type = value->iValue;
break;
default:
return(E_BADPARM);
}
return(OK);
}

View File

@ -1,112 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/* CKTsetup(ckt)
* this is a driver program to iterate through all the various
* setup functions provided for the circuit elements in the
* given circuit
*/
#include "ngspice.h"
#include <stdio.h>
#include "smpdefs.h"
#include "cktdefs.h"
#include "devdefs.h"
#include "sperror.h"
#define CKALLOC(var,size,type) \
if(size && (!(var =(type *)MALLOC((size)*sizeof(type))))){\
return(E_NOMEM);\
}
extern SPICEdev *DEVices[];
int
CKTsetup(register CKTcircuit *ckt)
{
register int i;
int error;
register SMPmatrix *matrix;
ckt->CKTnumStates=0;
#ifdef WANT_SENSE2
if(ckt->CKTsenInfo){
if (error = CKTsenSetup(ckt)) return(error);
}
#endif
if (ckt->CKTisSetup)
return E_NOCHANGE;
CKTpartition(ckt);
error = NIinit(ckt);
if (error) return(error);
ckt->CKTisSetup = 1;
matrix = ckt->CKTmatrix;
for (i=0;i<DEVmaxnum;i++) {
if ( ((*DEVices[i]).DEVsetup != NULL) && (ckt->CKThead[i] != NULL) ){
error = (*((*DEVices[i]).DEVsetup))(matrix,ckt->CKThead[i],ckt,
&ckt->CKTnumStates);
if(error) return(error);
}
}
for(i=0;i<=ckt->CKTmaxOrder+1;i++) {
CKALLOC(ckt->CKTstates[i],ckt->CKTnumStates,double);
}
#ifdef WANT_SENSE2
if(ckt->CKTsenInfo){
/* to allocate memory to sensitivity structures if
* it is not done before */
error = NIsenReinit(ckt);
if(error) return(error);
}
#endif
if(ckt->CKTniState & NIUNINITIALIZED) {
error = NIreinit(ckt);
if(error) return(error);
}
return(OK);
}
int
CKTunsetup(CKTcircuit *ckt)
{
int i, error, e2;
error = OK;
if (!ckt->CKTisSetup)
return OK;
for(i=0;i<=ckt->CKTmaxOrder+1;i++) {
tfree(ckt->CKTstates[i]);
}
for (i=0;i<DEVmaxnum;i++) {
if ( ((*DEVices[i]).DEVunsetup != NULL) && (ckt->CKThead[i] != NULL) ){
e2 = (*((*DEVices[i]).DEVunsetup))(ckt->CKThead[i],ckt);
if (!error && e2)
error = e2;
}
}
ckt->CKTisSetup = 0;
if(error) return(error);
NIdestroy(ckt);
/*
if (ckt->CKTmatrix)
SMPdestroy(ckt->CKTmatrix);
ckt->CKTmatrix = NULL;
*/
return OK;
}

View File

@ -1,250 +0,0 @@
/**********
Copyright 1991 Regents of the University of California. All rights reserved.
**********/
#include "ngspice.h"
#include "gendefs.h"
#include "devdefs.h"
#include "cktdefs.h"
#include "ifsim.h"
#include "sensgen.h"
#include <stdio.h>
extern SPICEdev *DEVices[]; /* XXX */
extern char *Sfilter;
sgen *
sgen_init(CKTcircuit *ckt, int is_dc)
{
sgen *sg;
sg = NEW(sgen);
sg->param = 99999;
sg->is_instparam = 0;
sg->dev = -1;
sg->istate = 0;
sg->ckt = ckt;
sg->devlist = ckt->CKThead;
sg->instance = sg->first_instance = sg->next_instance = NULL;
sg->model = sg->next_model = NULL;
sg->ptable = NULL;
sg->is_dc = is_dc;
sg->is_principle = 0;
sg->is_q = 0;
sg->is_zerook = 0;
sg->value = 0.0;
sgen_next(&sg); /* get the ball rolling XXX check return val? */
return sg;
}
int
sgen_next(sgen **xsg)
{
sgen *sg = *xsg;
int good, done;
int i;
done = 0;
i = sg->dev;
do {
if (sg->instance) {
if (sg->ptable) {
do {
sg->param += 1;
} while (sg->param < sg->max_param
&& !set_param(sg));
} else {
sg->max_param = -1;
}
if (sg->param < sg->max_param) {
done = 1;
} else if (!sg->is_instparam) {
/* Try instance parameters now */
sg->is_instparam = 1;
sg->param = -1;
sg->max_param =
*DEVices[i]->DEVpublic.numInstanceParms;
sg->ptable =
DEVices[i]->DEVpublic.instanceParms;
} else {
sg->is_principle = 0;
sg->instance->GENnextInstance =
sg->next_instance;
sg->instance->GENstate = sg->istate;
sg->instance = NULL;
}
} else if (sg->model) {
/* Find the first/next good instance for this model */
for (good = 0; !good && sg->next_instance;
good = set_inst(sg))
{
sg->instance = sg->next_instance;
sg->next_instance =
sg->instance->GENnextInstance;
}
if (good) {
sg->is_principle = 0;
sg->istate = sg->instance->GENstate;
sg->instance->GENnextInstance = NULL;
sg->model->GENinstances = sg->instance;
if (DEVices[i]->DEVpublic.modelParms) {
sg->max_param =
*DEVices[i]->DEVpublic.
numModelParms;
sg->ptable =
DEVices[i]->DEVpublic.
modelParms;
} else {
sg->ptable = NULL;
}
sg->param = -1;
sg->is_instparam = 0;
} else {
/* No good instances of this model */
sg->model->GENinstances = sg->first_instance;
sg->model->GENnextModel = sg->next_model;
sg->model = NULL;
}
} else if (i >= 0) {
/* Find the first/next good model for this device */
for (good = 0; !good && sg->next_model;
good = set_model(sg))
{
sg->model = sg->next_model;
sg->next_model = sg->model->GENnextModel;
}
if (good) {
sg->model->GENnextModel = NULL;
sg->devlist[i] = sg->model;
if (DEVices[i]->DEVpublic.modelParms) {
sg->max_param =
*DEVices[i]->DEVpublic.
numModelParms;
sg->ptable =
DEVices[i]->DEVpublic.
modelParms;
} else {
sg->ptable = NULL;
}
sg->next_instance = sg->first_instance
= sg->model->GENinstances;
} else {
/* No more good models for this device */
sg->devlist[i] = sg->first_model;
i = -1; /* Try the next good device */
}
} else if (i < DEVmaxnum && sg->dev < DEVmaxnum) {
/* Find the next good device in this circuit */
do
sg->dev++;
while (sg->dev < DEVmaxnum && sg->devlist[sg->dev]
&& !set_dev(sg));
i = sg->dev;
if (i > DEVmaxnum)
done = 1;
sg->first_model = sg->next_model = sg->devlist[i];
} else {
done = 1;
}
} while (!done);
if (sg->dev >= DEVmaxnum) {
FREE(sg);
*xsg = NULL;
}
return 1;
}
int set_inst(sgen *sg)
{
return 1;
}
int set_model(sgen *sg)
{
return 1;
}
int set_dev(sgen *sg)
{
return 1;
}
int set_param(sgen *sg)
{
IFvalue ifval;
if (!sg->ptable[sg->param].keyword)
return 0;
if (Sfilter && strncmp(sg->ptable[sg->param].keyword, Sfilter,
strlen(Sfilter)))
return 0;
if ((sg->ptable[sg->param].dataType &
(IF_SET|IF_ASK|IF_REAL|IF_VECTOR|IF_REDUNDANT|IF_NONSENSE))
!= (IF_SET|IF_ASK|IF_REAL))
return 0;
if (sg->is_dc &&
(sg->ptable[sg->param].dataType & (IF_AC | IF_AC_ONLY)))
return 0;
if ((sg->ptable[sg->param].dataType & IF_CHKQUERY) && !sg->is_q)
return 0;
if (sens_getp(sg, sg->ckt, &ifval))
return 0;
if (fabs(ifval.rValue) < 1e-30) {
if (sg->ptable[sg->param].dataType & IF_SETQUERY)
sg->is_q = 0;
if (!sg->is_zerook
&& !(sg->ptable[sg->param].dataType & IF_PRINCIPAL))
return 0;
} else if (sg->ptable[sg->param].dataType & (IF_SETQUERY|IF_ORQUERY))
sg->is_q = 1;
if (sg->ptable[sg->param].dataType & IF_PRINCIPAL)
sg->is_principle += 1;
sg->value = ifval.rValue;
return 1;
}
#ifdef notdef
sgen_suspend(sg)
sgen *sg;
{
sg->devlist[sg->dev] = sg->first_model;
sg->model->GENnextModel = sg->next_model;
sg->instance->GENnextInstance = sg->next_instance;
sg->model->GENinstances = sg->first_instance;
}
sgen_restore(sg)
sgen *sg;
{
sg->devlist[sg->dev] = sg->model;
sg->model->GENnextModel = NULL;
sg->instance->GENnextInstance = NULL;
sg->model->GENinstances = sg->instance;
}
#endif

View File

@ -1,223 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/*
* CKTsetOpt(ckt,opt,value)
* set the specified 'opt' to have value 'value' in the
* given circuit 'ckt'.
*/
#include "ngspice.h"
#include <stdio.h>
#include "const.h"
#include "optdefs.h"
#include "tskdefs.h"
#include "ifsim.h"
#include "cktdefs.h"
#include "sperror.h"
/* ARGSUSED */
int
CKTsetOpt(void *ckt, void *anal, int opt, IFvalue *val)
{
register TSKtask *task = (TSKtask *)anal;
switch(opt) {
case OPT_NOOPITER:
task->TSKnoOpIter = val->iValue;
break;
case OPT_GMIN:
task->TSKgmin = val->rValue;
break;
case OPT_RELTOL:
task->TSKreltol = val->rValue;
break;
case OPT_ABSTOL:
task->TSKabstol = val->rValue;
break;
case OPT_VNTOL:
task->TSKvoltTol = val->rValue;
break;
case OPT_TRTOL:
task->TSKtrtol = val->rValue;
break;
case OPT_CHGTOL:
task->TSKchgtol = val->rValue;
break;
case OPT_PIVTOL:
task->TSKpivotAbsTol = val->rValue;
break;
case OPT_PIVREL:
task->TSKpivotRelTol = val->rValue;
break;
case OPT_TNOM:
task->TSKnomTemp = val->rValue + CONSTCtoK; /* Centegrade to Kelvin */
break;
case OPT_TEMP:
task->TSKtemp = val->rValue + CONSTCtoK; /* Centegrade to Kelvin */
break;
case OPT_ITL1:
task->TSKdcMaxIter = val->iValue;
break;
case OPT_ITL2:
task->TSKdcTrcvMaxIter = val->iValue;
break;
case OPT_ITL3:
break;
case OPT_ITL4:
task->TSKtranMaxIter = val->iValue;
break;
case OPT_ITL5:
break;
case OPT_SRCSTEPS:
task->TSKnumSrcSteps = val->iValue;
break;
case OPT_GMINSTEPS:
task->TSKnumGminSteps = val->iValue;
break;
case OPT_DEFL:
task->TSKdefaultMosL = val->rValue;
break;
case OPT_DEFW:
task->TSKdefaultMosW = val->rValue;
break;
case OPT_DEFAD:
task->TSKdefaultMosAD = val->rValue;
break;
case OPT_DEFAS:
task->TSKdefaultMosAD = val->rValue;
break;
case OPT_BYPASS:
task->TSKbypass = val->iValue;
break;
case OPT_MAXORD:
task->TSKmaxOrder = val->iValue;
break;
case OPT_OLDLIMIT:
task->TSKfixLimit = val->iValue;
break;
case OPT_MINBREAK:
task->TSKminBreak = val->rValue;
break;
case OPT_METHOD:
if(strncmp(val->sValue,"trap", 4)==0)
task->TSKintegrateMethod=TRAPEZOIDAL;
else if (strcmp(val->sValue,"gear")==0)
task->TSKintegrateMethod=GEAR;
else return(E_METHOD);
break;
case OPT_TRYTOCOMPACT:
task->TSKtryToCompact = val->iValue;
break;
case OPT_BADMOS3:
task->TSKbadMos3 = val->iValue;
break;
case OPT_KEEPOPINFO:
task->TSKkeepOpInfo = val->iValue;
break;
default:
return(-1);
}
return(0);
}
static IFparm OPTtbl[] = {
{ "noopiter", OPT_NOOPITER,IF_SET|IF_FLAG,"Go directly to gmin stepping" },
{ "gmin", OPT_GMIN,IF_SET|IF_REAL,"Minimum conductance" },
{ "reltol", OPT_RELTOL,IF_SET|IF_REAL ,"Relative error tolerence"},
{ "abstol", OPT_ABSTOL,IF_SET|IF_REAL,"Absolute error tolerence" },
{ "vntol", OPT_VNTOL,IF_SET|IF_REAL,"Voltage error tolerence" },
{ "trtol", OPT_TRTOL,IF_SET|IF_REAL,"Truncation error overestimation factor" },
{ "chgtol", OPT_CHGTOL,IF_SET|IF_REAL, "Charge error tolerence" },
{ "pivtol", OPT_PIVTOL,IF_SET|IF_REAL, "Minimum acceptable pivot" },
{ "pivrel", OPT_PIVREL,IF_SET|IF_REAL, "Minimum acceptable ratio of pivot" },
{ "tnom", OPT_TNOM,IF_SET|IF_ASK|IF_REAL, "Nominal temperature" },
{ "temp", OPT_TEMP,IF_SET|IF_ASK|IF_REAL, "Operating temperature" },
{ "itl1", OPT_ITL1,IF_SET|IF_INTEGER,"DC iteration limit" },
{ "itl2", OPT_ITL2,IF_SET|IF_INTEGER,"DC transfer curve iteration limit" },
{ "itl3", OPT_ITL3, IF_INTEGER,"Lower transient iteration limit"},
{ "itl4", OPT_ITL4,IF_SET|IF_INTEGER,"Upper transient iteration limit" },
{ "itl5", OPT_ITL5, IF_INTEGER,"Total transient iteration limit"},
{ "itl6", OPT_SRCSTEPS, IF_SET|IF_INTEGER,"number of source steps"},
{ "srcsteps", OPT_SRCSTEPS, IF_SET|IF_INTEGER,"number of source steps"},
{ "gminsteps", OPT_GMINSTEPS, IF_SET|IF_INTEGER,"number of Gmin steps"},
{ "acct", 0, IF_FLAG ,"Print accounting"},
{ "list", 0, IF_FLAG, "Print a listing" },
{ "nomod", 0, IF_FLAG, "Don't print a model summary" },
{ "nopage", 0, IF_FLAG, "Don't insert page breaks" },
{ "node", 0, IF_FLAG,"Print a node connection summary" },
{ "opts", 0, IF_FLAG, "Print a list of the options" },
{ "oldlimit", OPT_OLDLIMIT, IF_SET|IF_FLAG, "use SPICE2 MOSfet limiting" },
{ "numdgt", 0, IF_INTEGER, "Set number of digits printed"},
{ "cptime", 0, IF_REAL, "Total cpu time in seconds" },
{ "limtim", 0, IF_INTEGER, "Time to reserve for output" },
{ "limpts", 0,IF_INTEGER,"Maximum points per analysis"},
{ "lvlcod", 0, IF_INTEGER,"Generate machine code" },
{ "lvltim", 0, IF_INTEGER,"Type of timestep control" },
{ "method", OPT_METHOD, IF_SET|IF_STRING,"Integration method" },
{ "maxord", OPT_MAXORD, IF_SET|IF_INTEGER,"Maximum integration order" },
{ "defl", OPT_DEFL,IF_SET|IF_REAL,"Default MOSfet length" },
{ "defw", OPT_DEFW,IF_SET|IF_REAL,"Default MOSfet width" },
{ "minbreak", OPT_MINBREAK,IF_SET|IF_REAL,"Minimum time between breakpoints" },
{ "defad", OPT_DEFAD,IF_SET|IF_REAL,"Default MOSfet area of drain" },
{ "defas", OPT_DEFAS,IF_SET|IF_REAL,"Default MOSfet area of source" },
{ "bypass",OPT_BYPASS,IF_SET|IF_INTEGER,"Allow bypass of unchanging elements"},
{ "totiter", OPT_ITERS, IF_ASK|IF_INTEGER,"Total iterations" },
{ "traniter", OPT_TRANIT, IF_ASK|IF_INTEGER ,"Transient iterations"},
{ "equations", OPT_EQNS, IF_ASK|IF_INTEGER,"Circuit Equations" },
{ "originalnz", OPT_ORIGNZ, IF_ASK|IF_INTEGER,"Circuit original non-zeroes" },
{ "fillinnz", OPT_FILLNZ, IF_ASK|IF_INTEGER,"Circuit fill-in non-zeroes" },
{ "totalnz", OPT_TOTALNZ, IF_ASK|IF_INTEGER,"Circuit total non-zeroes" },
{ "tranpoints", OPT_TRANPTS, IF_ASK|IF_INTEGER,"Transient timepoints" },
{ "accept", OPT_TRANACCPT, IF_ASK|IF_INTEGER,"Accepted timepoints" },
{ "rejected", OPT_TRANRJCT, IF_ASK|IF_INTEGER,"Rejected timepoints" },
{ "time", OPT_TOTANALTIME, IF_ASK|IF_REAL,"Total analysis time" },
{ "loadtime", OPT_LOADTIME, IF_ASK|IF_REAL,"Matrix load time" },
{ "synctime", OPT_SYNCTIME, IF_ASK|IF_REAL,"Matrix synchronize time" },
{ "combinetime", OPT_COMBTIME, IF_ASK|IF_REAL,"Matrix combine time" },
{ "reordertime", OPT_REORDTIME, IF_ASK|IF_REAL,"Matrix reorder time" },
{ "factortime", OPT_DECOMP, IF_ASK|IF_REAL,"Matrix factor time" },
{ "solvetime", OPT_SOLVE, IF_ASK|IF_REAL,"Matrix solve time" },
{ "trantime", OPT_TRANTIME, IF_ASK|IF_REAL,"Transient analysis time" },
{ "tranloadtime", OPT_TRANLOAD, IF_ASK|IF_REAL,"Transient load time" },
{ "transynctime", OPT_TRANSYNC, IF_ASK|IF_REAL,"Transient sync time" },
{ "trancombinetime", OPT_TRANCOMB, IF_ASK|IF_REAL,"Transient combine time" },
{ "tranfactortime", OPT_TRANDECOMP,IF_ASK|IF_REAL,"Transient factor time" },
{ "transolvetime", OPT_TRANSOLVE, IF_ASK|IF_REAL,"Transient solve time" },
{ "trantrunctime", OPT_TRANTRUNC, IF_ASK|IF_REAL,"Transient trunc time" },
{ "trancuriters", OPT_TRANCURITER, IF_ASK|IF_INTEGER,
"Transient iters per point" },
{ "actime", OPT_ACTIME, IF_ASK|IF_REAL,"AC analysis time" },
{ "acloadtime", OPT_ACLOAD, IF_ASK|IF_REAL,"AC load time" },
{ "acsynctime", OPT_ACSYNC, IF_ASK|IF_REAL,"AC sync time" },
{ "accombinetime", OPT_ACCOMB, IF_ASK|IF_REAL,"AC combine time" },
{ "acfactortime", OPT_ACDECOMP,IF_ASK|IF_REAL,"AC factor time" },
{ "acsolvetime", OPT_ACSOLVE, IF_ASK|IF_REAL,"AC solve time" },
{ "trytocompact", OPT_TRYTOCOMPACT, IF_SET|IF_FLAG,
"Try compaction for LTRA lines" },
{ "badmos3", OPT_BADMOS3, IF_SET|IF_FLAG,
"use old mos3 model (discontinuous with respect to kappa)" },
{ "keepopinfo", OPT_KEEPOPINFO, IF_SET|IF_FLAG,
"Record operating point for each small-signal analysis" }
};
int OPTcount = sizeof(OPTtbl)/sizeof(IFparm);
SPICEanalysis OPTinfo = {
{
"options",
"Task option selection",
sizeof(OPTtbl)/sizeof(IFparm),
OPTtbl
},
0, /* no size associated with options */
NODOMAIN,
0,
CKTsetOpt,
CKTacct,
NULL,
NULL
};

View File

@ -1,40 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/* CKTtemp(ckt)
* this is a driver program to iterate through all the various
* temperature dependency functions provided for the circuit
* elements in the given circuit
*/
#include "ngspice.h"
#include <stdio.h>
#include "smpdefs.h"
#include "cktdefs.h"
#include "const.h"
#include "devdefs.h"
#include "sperror.h"
extern SPICEdev *DEVices[];
int
CKTtemp(register CKTcircuit *ckt)
{
int error;
register int i;
ckt->CKTvt = CONSTKoverQ * ckt->CKTtemp;
for (i=0;i<DEVmaxnum;i++) {
if ( ((*DEVices[i]).DEVtemperature != NULL) &&
(ckt->CKThead[i] != NULL) ){
error = (*((*DEVices[i]).DEVtemperature))(ckt->CKThead[i],ckt);
if(error) return(error);
}
}
return(OK);
}

View File

@ -1,79 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
#include "ngspice.h"
#include <stdio.h>
#include "cktdefs.h"
#define ccap (qcap+1)
void
CKTterr(register int qcap, register CKTcircuit *ckt, register double *timeStep)
{
double volttol;
double chargetol;
double tol;
double del;
double diff[8];
double deltmp[8];
double factor;
register int i;
register int j;
static double gearCoeff[] = {
.5,
.2222222222,
.1363636364,
.096,
.07299270073,
.05830903790
};
static double trapCoeff[] = {
.5,
.08333333333
};
volttol = ckt->CKTabstol + ckt->CKTreltol *
MAX( fabs(*(ckt->CKTstate0+ccap)), fabs(*(ckt->CKTstate1+ccap)));
chargetol = MAX(fabs(*(ckt->CKTstate0 +qcap)),fabs(*(ckt->CKTstate1+qcap)));
chargetol = ckt->CKTreltol * MAX(chargetol,ckt->CKTchgtol)/ckt->CKTdelta;
tol = MAX(volttol,chargetol);
/* now divided differences */
for(i=ckt->CKTorder+1;i>=0;i--) {
diff[i] = *(ckt->CKTstates[i] + qcap);
}
for(i=0 ; i <= ckt->CKTorder ; i++) {
deltmp[i] = ckt->CKTdeltaOld[i];
}
j = ckt->CKTorder;
while(1) {
for(i=0;i <= j;i++) {
diff[i] = (diff[i] - diff[i+1])/deltmp[i];
}
if (--j < 0) break;
for(i=0;i <= j;i++) {
deltmp[i] = deltmp[i+1] + ckt->CKTdeltaOld[i];
}
}
switch(ckt->CKTintegrateMethod) {
case GEAR:
factor = gearCoeff[ckt->CKTorder-1];
break;
case TRAPEZOIDAL:
factor = trapCoeff[ckt->CKTorder - 1] ;
break;
}
del = ckt->CKTtrtol * tol/MAX(ckt->CKTabstol,factor * fabs(diff[0]));
if(ckt->CKTorder == 2) {
del = sqrt(del);
} else if (ckt->CKTorder > 2) {
del = exp(log(del)/ckt->CKTorder);
}
*timeStep = MIN(*timeStep,del);
return;
}

View File

@ -1,96 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
**********/
#include "ngspice.h"
#include <stdio.h>
#include "trandefs.h"
#include "cktdefs.h"
#include "devdefs.h"
#include "vsrc/vsrcdefs.h"
#include "isrc/isrcdefs.h"
#include "jobdefs.h"
extern SPICEdev *DEVices[];
extern SPICEanalysis *analInfo[];
char *
CKTtrouble(void *cktp, char *optmsg)
{
CKTcircuit *ckt = (CKTcircuit *) cktp;
char msg_buf[513];
char *emsg;
TRCV *cv;
int vcode, icode;
char *msg_p;
SPICEanalysis *an;
int i;
if (!ckt || !ckt->CKTcurJob)
return NULL;
an = analInfo[ckt->CKTcurJob->JOBtype];
if (optmsg && *optmsg) {
sprintf(msg_buf, "%s: %s; ", an->public.name, optmsg);
} else {
sprintf(msg_buf, "%s: ", an->public.name);
}
msg_p = msg_buf + strlen(msg_buf);
switch (an->domain) {
case TIMEDOMAIN:
if (ckt->CKTtime == 0.0)
sprintf(msg_p, "initial timepoint: ");
else
sprintf(msg_p, "time = %g, timestep = %g: ", ckt->CKTtime,
ckt->CKTdelta);
break;
case FREQUENCYDOMAIN:
sprintf(msg_p, "frequency = %g: ", ckt->CKTomega / (2.0 * M_PI));
break;
case SWEEPDOMAIN:
cv = (TRCV*) ckt->CKTcurJob;
vcode = CKTtypelook("Vsource");
icode = CKTtypelook("Isource");
for (i = 0; i <= cv->TRCVnestLevel; i++) {
msg_p += strlen(msg_p);
if(cv->TRCVvType[i]==vcode) { /* voltage source */
sprintf(msg_p, " %s = %g: ", cv->TRCVvName[i],
((VSRCinstance*)(cv->TRCVvElt[i]))->VSRCdcValue);
} else {
sprintf(msg_p, " %s = %g: ", cv->TRCVvName[i],
((ISRCinstance*)(cv->TRCVvElt[i]))->ISRCdcValue);
}
}
break;
case NODOMAIN:
default:
break;
}
msg_p += strlen(msg_p);
if (ckt->CKTtroubleNode) {
sprintf(msg_p, "trouble with node \"%s\"\n",
CKTnodName(ckt, ckt->CKTtroubleNode));
} else if (ckt->CKTtroubleElt) {
/* "-" for dop */
sprintf(msg_p, "trouble with %s-instance %s\n",
ckt->CKTtroubleElt->GENmodPtr->GENmodName,
ckt->CKTtroubleElt->GENname);
} else {
sprintf(msg_p, "cause unrecorded.\n");
}
emsg = MALLOC(strlen(msg_buf)+1);
strcpy(emsg,msg_buf);
return emsg;
}

View File

@ -1,201 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/* CKTtrunc(ckt)
* this is a driver program to iterate through all the various
* truncation error functions provided for the circuit elements in the
* given circuit
*/
#include "ngspice.h"
#include <stdio.h>
#include "cktdefs.h"
#include "smpdefs.h"
#include "devdefs.h"
#include "sperror.h"
extern SPICEdev *DEVices[];
int
CKTtrunc(register CKTcircuit *ckt, double *timeStep)
{
#ifndef NEWTRUNC
register int i;
double timetemp;
#ifdef PARALLEL_ARCH
long type = MT_TRUNC, length = 1;
#endif /* PARALLEL_ARCH */
#ifdef STEPDEBUG
double debugtemp;
#endif /* STEPDEBUG */
double startTime;
int error = OK;
startTime = SPfrontEnd->IFseconds();
timetemp = HUGE;
for (i=0;i<DEVmaxnum;i++) {
if ((*DEVices[i]).DEVtrunc != NULL && ckt->CKThead[i] != NULL) {
#ifdef STEPDEBUG
debugtemp = timetemp;
#endif /* STEPDEBUG */
error = (*((*DEVices[i]).DEVtrunc))(ckt->CKThead[i],ckt,&timetemp);
if(error) {
ckt->CKTstat->STATtranTruncTime += SPfrontEnd->IFseconds()
- startTime;
return(error);
}
#ifdef STEPDEBUG
if(debugtemp != timetemp) {
printf("timestep cut by device type %s from %g to %g\n",
(*DEVices[i]).DEVpublic.name, debugtemp,timetemp);
}
#endif /* STEPDEBUG */
}
}
*timeStep = MIN(2 * *timeStep,timetemp);
#ifdef PARALLEL_ARCH
DGOP_( &type, timeStep, &length, "min" );
#endif /* PARALLEL_ARCH */
ckt->CKTstat->STATtranTruncTime += SPfrontEnd->IFseconds() - startTime;
return(OK);
#else /* NEWTRUNC */
register int i;
register CKTnode *node;
double timetemp;
double tmp;
double diff;
double tol;
double startTime;
int size;
startTime = (*(SPfrontEnd->IFseconds))();
timetemp = HUGE;
size = SMPmatSize(ckt->CKTmatrix);
#ifdef STEPDEBUG
printf("at time %g, delta %g\n",ckt->CKTtime,ckt->CKTdeltaOld[0]);
#endif STEPDEBUG
node = ckt->CKTnodes;
switch(ckt->CKTintegrateMethod) {
case TRAPEZOIDAL:
switch(ckt->CKTorder) {
case 1:
for(i=1;i<size;i++) {
tol = MAX( fabs(ckt->CKTrhs[i]),fabs(ckt->CKTpred[i]))*
ckt->CKTlteReltol+ckt->CKTlteAbstol;
node = node->next;
if(node->type!= 3) continue;
diff = ckt->CKTrhs[i]-ckt->CKTpred[i];
#ifdef STEPDEBUG
printf("%s: cor=%g, pred=%g ",node->name,
ckt->CKTrhs[i],ckt->CKTpred[i]);
#endif
if(diff != 0) {
tmp = ckt->CKTtrtol * tol * 2 /diff;
tmp = ckt->CKTdeltaOld[0]*sqrt(fabs(tmp));
timetemp = MIN(timetemp,tmp);
#ifdef STEPDEBUG
printf("tol = %g, diff = %g, h->%g\n",tol,diff,tmp);
#endif
} else {
#ifdef STEPDEBUG
printf("diff is 0\n");
#endif
}
}
break;
case 2:
for(i=1;i<size;i++) {
tol = MAX( fabs(ckt->CKTrhs[i]),fabs(ckt->CKTpred[i]))*
ckt->CKTlteReltol+ckt->CKTlteAbstol;
node = node->next;
if(node->type!= 3) continue;
diff = ckt->CKTrhs[i]-ckt->CKTpred[i];
#ifdef STEPDEBUG
printf("%s: cor=%g, pred=%g ",node->name,ckt->CKTrhs[i],
ckt->CKTpred[i]);
#endif
if(diff != 0) {
tmp = ckt->CKTdeltaOld[0]*ckt->CKTtrtol * tol * 3 *
(ckt->CKTdeltaOld[0]+ckt->CKTdeltaOld[1])/diff;
tmp = fabs(tmp);
timetemp = MIN(timetemp,tmp);
#ifdef STEPDEBUG
printf("tol = %g, diff = %g, h->%g\n",tol,diff,tmp);
#endif
} else {
#ifdef STEPDEBUG
printf("diff is 0\n");
#endif
}
}
break;
default:
return(E_ORDER);
break;
}
break;
case GEAR: {
double delsum=0;
for(i=0;i<=ckt->CKTorder;i++) {
delsum += ckt->CKTdeltaOld[i];
}
for(i=1;i<size;i++) {
node = node->next;
if(node->type!= 3) continue;
tol = MAX( fabs(ckt->CKTrhs[i]),fabs(ckt->CKTpred[i]))*
ckt->CKTlteReltol+ckt->CKTlteAbstol;
diff = (ckt->CKTrhs[i]-ckt->CKTpred[i]);
#ifdef STEPDEBUG
printf("%s: cor=%g, pred=%g ",node->name,ckt->CKTrhs[i],
ckt->CKTpred[i]);
#endif
if(diff != 0) {
tmp = tol*ckt->CKTtrtol*delsum/(diff*ckt->CKTdelta);
tmp = fabs(tmp);
switch(ckt->CKTorder) {
case 0:
break;
case 1:
tmp = sqrt(tmp);
break;
default:
tmp = exp(log(tmp)/(ckt->CKTorder+1));
break;
}
tmp *= ckt->CKTdelta;
timetemp = MIN(timetemp,tmp);
#ifdef STEPDEBUG
printf("tol = %g, diff = %g, h->%g\n",tol,diff,tmp);
#endif
} else {
#ifdef STEPDEBUG
printf("diff is 0\n");
#endif
}
}
}
break;
default:
return(E_METHOD);
}
*timeStep = MIN(2 * *timeStep,timetemp);
#ifdef PARALLEL_ARCH
DGOP_( &type, timeStep, &length, "min" );
#endif /* PARALLEL_ARCH */
ckt->CKTstat->STATtranTruncTime += SPfrontEnd->IFseconds() - startTime;
return(OK);
#endif /* NEWTRUNC */
}

View File

@ -1,31 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/* look up the 'type' in the device description struct and return the
* appropriatestrchr for the device found, or -1 for not found
*/
#include "ngspice.h"
#include "cktdefs.h"
#include "devdefs.h"
extern SPICEdev *DEVices[];
int
CKTtypelook(char *type)
{
int i;
for(i=0;i<DEVmaxnum;i++) {
if(strcmp(type,(*DEVices[i]).DEVpublic.name)==0) {
/*found the device - return it */
return(i);
}
}
return(-1);
}

View File

@ -1,63 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1988 Jaijeet S Roychowdhury
**********/
#include <stdio.h>
#include "ifsim.h"
#include "iferrmsg.h"
#include "cktdefs.h"
#include "distodef.h"
/* ARGSUSED */
int
DaskQuest(CKTcircuit *ckt, void *anal, int which, IFvalue *value)
{
switch(which) {
case D_START:
value->rValue = ((DISTOAN*)anal)->DstartF1;
break;
case D_STOP:
value->rValue = ((DISTOAN*)anal)->DstopF1 ;
break;
case D_STEPS:
value->iValue = ((DISTOAN*)anal)->DnumSteps;
break;
case D_DEC:
if(((DISTOAN*)anal)->DstepType == DECADE) {
value->iValue=1;
} else {
value->iValue=0;
}
break;
case D_OCT:
if(((DISTOAN*)anal)->DstepType == OCTAVE) {
value->iValue=1;
} else {
value->iValue=0;
}
break;
case D_LIN:
if(((DISTOAN*)anal)->DstepType == LINEAR) {
value->iValue=1;
} else {
value->iValue=0;
}
break;
case D_F2OVRF1:
value->rValue = ((DISTOAN*)anal)->Df2ovrF1;
break;
default:
return(E_BADPARM);
}
return(OK);
}

View File

@ -1,20 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
#include "ngspice.h"
#include <stdio.h>
#include "ifsim.h"
#include "iferrmsg.h"
#include "opdefs.h"
#include "cktdefs.h"
/* ARGSUSED */
int
DCOaskQuest(CKTcircuit *ckt, void *anal, int which, IFvalue *value)
{
return(E_BADPARM);
}

View File

@ -1,63 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
#include "ngspice.h"
#include <stdio.h>
#include "cktdefs.h"
#include "sperror.h"
#include "ifsim.h"
int
DCop(CKTcircuit *ckt)
{
int CKTload(register CKTcircuit *ckt);
int converged;
int error;
IFuid *nameList;
int numNames;
void *plot;
error = CKTnames(ckt,&numNames,&nameList);
if(error) return(error);
error = (*(SPfrontEnd->OUTpBeginPlot))((void *)ckt,
(void*)ckt->CKTcurJob, ckt->CKTcurJob->JOBname,
(IFuid)NULL,IF_REAL,numNames,nameList, IF_REAL,&plot);
if(error) return(error);
converged = CKTop(ckt,
(ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITJCT,
(ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITFLOAT,
ckt->CKTdcMaxIter);
if(converged != 0) return(converged);
ckt->CKTmode = (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITSMSIG;
#ifdef WANT_SENSE2
if(ckt->CKTsenInfo && ((ckt->CKTsenInfo->SENmode&DCSEN) ||
(ckt->CKTsenInfo->SENmode&ACSEN)) ){
#ifdef SENSDEBUG
printf("\nDC Operating Point Sensitivity Results\n\n");
CKTsenPrint(ckt);
#endif /* SENSDEBUG */
senmode = ckt->CKTsenInfo->SENmode;
save = ckt->CKTmode;
ckt->CKTsenInfo->SENmode = DCSEN;
size = SMPmatSize(ckt->CKTmatrix);
for(i = 1; i<=size ; i++){
*(ckt->CKTrhsOp + i) = *(ckt->CKTrhsOld + i);
}
if(error = CKTsenDCtran(ckt)) return(error);
ckt->CKTmode = save;
ckt->CKTsenInfo->SENmode = senmode;
}
#endif
converged = CKTload(ckt);
CKTdump(ckt,(double)0,plot);
(*(SPfrontEnd->OUTendPlot))(plot);
return(converged);
}

View File

@ -1,42 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
#include "ngspice.h"
#include <stdio.h>
#include "ifsim.h"
#include "iferrmsg.h"
#include "cktdefs.h"
#include "opdefs.h"
/* ARGSUSED */
int
DCOsetParm(CKTcircuit *ckt, void *anal, int which, IFvalue *value)
{
switch(which) {
default:
break;
}
return(E_BADPARM);
}
SPICEanalysis DCOinfo = {
{
"OP",
"D.C. Operating point analysis",
0,
NULL,
},
sizeof(OP),
NODOMAIN,
1,
DCOsetParm,
DCOaskQuest,
NULL,
DCop
};

View File

@ -1,26 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
#include "ngspice.h"
#include <stdio.h>
#include "ifsim.h"
#include "iferrmsg.h"
#include "trcvdefs.h"
#include "cktdefs.h"
/* ARGSUSED */
int
DCTaskQuest(CKTcircuit *ckt, void *anal, int which, IFvalue *value)
{
switch(which) {
default:
break;
}
/* NOTREACHED */ /* TEMPORARY until cases get added */
return(E_BADPARM);
}

View File

@ -1,498 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/* subroutine to do DC TRANSIENT analysis
--- ONLY, unlike spice2 routine with the same name! */
#include "ngspice.h"
#include <stdio.h>
#include "trandefs.h"
#include "cktdefs.h"
#include "sperror.h"
int
DCtran(CKTcircuit *ckt, int restart)
/* restart: forced restart flag */
{
int i;
double olddelta;
double delta;
double new;
double *temp;
double startdTime;
double startsTime;
double startlTime;
double startcTime;
double startkTime;
double startTime;
int startIters;
int converged;
int firsttime;
int error;
#ifdef WANT_SENSE2
#ifdef SENSDEBUG
FILE *outsen;
#endif /* SENSDEBUG */
#endif
int save_order;
long save_mode;
IFuid timeUid;
IFuid *nameList;
int numNames;
double maxstepsize=0.0;
int ltra_num;
#ifdef PARALLEL_ARCH
long type = MT_TRANAN, length = 1;
#endif /* PARALLEL_ARCH */
if(restart || ckt->CKTtime == 0) {
delta=MIN(ckt->CKTfinalTime/50,ckt->CKTstep)/10;
/* begin LTRA code addition */
if (ckt->CKTtimePoints != NULL)
FREE(ckt->CKTtimePoints);
if (ckt->CKTstep >= ckt->CKTmaxStep)
maxstepsize = ckt->CKTstep;
else
maxstepsize = ckt->CKTmaxStep;
ckt->CKTsizeIncr = 10;
ckt->CKTtimeIndex = -1; /* before the DC soln has been stored */
ckt->CKTtimeListSize = ckt->CKTfinalTime / maxstepsize + 0.5;
ltra_num = CKTtypelook("LTRA");
if (ltra_num >= 0 && ckt->CKThead[ltra_num] != NULL)
ckt->CKTtimePoints = NEWN(double, ckt->CKTtimeListSize);
/* end LTRA code addition */
if(ckt->CKTbreaks) FREE(ckt->CKTbreaks);
ckt->CKTbreaks=(double *)MALLOC(2*sizeof(double));
if(ckt->CKTbreaks == (double *)NULL) return(E_NOMEM);
*(ckt->CKTbreaks)=0;
*(ckt->CKTbreaks+1)=ckt->CKTfinalTime;
ckt->CKTbreakSize=2;
if(ckt->CKTminBreak==0) ckt->CKTminBreak=ckt->CKTmaxStep*5e-5;
error = CKTnames(ckt,&numNames,&nameList);
if(error) return(error);
(*(SPfrontEnd->IFnewUid))((void *)ckt,&timeUid,(IFuid)NULL,
"time", UID_OTHER, (void **)NULL);
error = (*(SPfrontEnd->OUTpBeginPlot))((void *)ckt,
(void*)ckt->CKTcurJob,
ckt->CKTcurJob->JOBname,timeUid,IF_REAL,numNames,nameList,
IF_REAL,&(((TRANan*)ckt->CKTcurJob)->TRANplot));
if(error) return(error);
ckt->CKTtime = 0;
ckt->CKTdelta = 0;
ckt->CKTbreak=1;
firsttime = 1;
save_mode = (ckt->CKTmode&MODEUIC)|MODETRANOP | MODEINITJCT;
save_order = ckt->CKTorder;
converged = CKTop(ckt,
(ckt->CKTmode & MODEUIC)|MODETRANOP| MODEINITJCT,
(ckt->CKTmode & MODEUIC)|MODETRANOP| MODEINITFLOAT,
ckt->CKTdcMaxIter);
if(converged != 0) return(converged);
ckt->CKTstat->STATtimePts ++;
ckt->CKTorder=1;
for(i=0;i<7;i++) {
ckt->CKTdeltaOld[i]=ckt->CKTmaxStep;
}
ckt->CKTdelta = delta;
#ifdef STEPDEBUG
(void)printf("delta initialized to %g\n",ckt->CKTdelta);
#endif
ckt->CKTsaveDelta = ckt->CKTfinalTime/50;
#ifdef WANT_SENSE2
if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode & TRANSEN)){
#ifdef SENSDEBUG
printf("\nTransient Sensitivity Results\n\n");
CKTsenPrint(ckt);
#endif /* SENSDEBUG */
save = ckt->CKTsenInfo->SENmode;
ckt->CKTsenInfo->SENmode = TRANSEN;
save1 = ckt->CKTmode;
save2 = ckt->CKTorder;
ckt->CKTmode = save_mode;
ckt->CKTorder = save_order;
if(error = CKTsenDCtran(ckt)) return(error);
ckt->CKTmode = save1;
ckt->CKTorder = save2;
}
#endif
ckt->CKTmode = (ckt->CKTmode&MODEUIC)|MODETRAN | MODEINITTRAN;
/* modeinittran set here */
ckt->CKTag[0]=ckt->CKTag[1]=0;
bcopy((char *)ckt->CKTstate0,(char *)ckt->CKTstate1,
ckt->CKTnumStates*sizeof(double));
#ifdef WANT_SENSE2
if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode & TRANSEN)){
size = SMPmatSize(ckt->CKTmatrix);
for(i = 1; i<=size ; i++)
*(ckt->CKTrhsOp + i) = *(ckt->CKTrhsOld + i);
}
#endif
startTime=(*(SPfrontEnd->IFseconds))();
startIters = ckt->CKTstat->STATnumIter;
startdTime = ckt->CKTstat->STATdecompTime;
startsTime = ckt->CKTstat->STATsolveTime;
startlTime = ckt->CKTstat->STATloadTime;
startcTime = ckt->CKTstat->STATcombineTime;
startkTime = ckt->CKTstat->STATsyncTime;
} else {
startTime=(*(SPfrontEnd->IFseconds))();
startIters = ckt->CKTstat->STATnumIter;
startdTime = ckt->CKTstat->STATdecompTime;
startsTime = ckt->CKTstat->STATsolveTime;
startlTime = ckt->CKTstat->STATloadTime;
startcTime = ckt->CKTstat->STATcombineTime;
startkTime = ckt->CKTstat->STATsyncTime;
if(ckt->CKTminBreak==0) ckt->CKTminBreak=ckt->CKTmaxStep*5e-5;
firsttime=0;
goto resume;
}
/* 650 */
nextTime:
/* begin LTRA code addition */
if (ckt->CKTtimePoints) {
ckt->CKTtimeIndex++;
if (ckt->CKTtimeIndex >= ckt->CKTtimeListSize) {
/* need more space */
int need;
need = 0.5 + (ckt->CKTfinalTime - ckt->CKTtime) / maxstepsize;
if (need < ckt->CKTsizeIncr)
need = ckt->CKTsizeIncr;
ckt->CKTtimeListSize += need;
ckt->CKTtimePoints = (double *) REALLOC( (char *)
ckt->CKTtimePoints, sizeof(double) * ckt->CKTtimeListSize);
ckt->CKTsizeIncr *= 1.4;
}
*(ckt->CKTtimePoints + ckt->CKTtimeIndex) = ckt->CKTtime;
}
/* end LTRA code addition */
error = CKTaccept(ckt);
/* check if current breakpoint is outdated; if so, clear */
if (ckt->CKTtime > *(ckt->CKTbreaks)) CKTclrBreak(ckt);
/*
* Breakpoint handling scheme:
* When a timepoint t is accepted (by CKTaccept), clear all previous
* breakpoints, because they will never be needed again.
*
* t may itself be a breakpoint, or indistinguishably close. DON'T
* clear t itself; recognise it as a breakpoint and act accordingly
*
* if t is not a breakpoint, limit the timestep so that the next
* breakpoint is not crossed
*/
#ifdef STEPDEBUG
printf("accepted at %g\n",ckt->CKTtime);
#endif /* STEPDEBUG */
ckt->CKTstat->STATaccepted ++;
ckt->CKTbreak=0;
/* XXX Error will cause single process to bail. */
if(error) {
ckt->CKTcurrentAnalysis = DOING_TRAN;
ckt->CKTstat->STATtranTime += (*(SPfrontEnd->IFseconds))()-startTime;
ckt->CKTstat->STATtranIter += ckt->CKTstat->STATnumIter - startIters;
ckt->CKTstat->STATtranDecompTime += ckt->CKTstat->STATdecompTime -
startdTime;
ckt->CKTstat->STATtranSolveTime += ckt->CKTstat->STATsolveTime -
startsTime;
ckt->CKTstat->STATtranLoadTime += ckt->CKTstat->STATloadTime -
startlTime;
ckt->CKTstat->STATtranCombTime += ckt->CKTstat->STATcombineTime -
startcTime;
ckt->CKTstat->STATtranSyncTime += ckt->CKTstat->STATsyncTime -
startkTime;
return(error);
}
if(ckt->CKTtime >= ckt->CKTinitTime) CKTdump(ckt,ckt->CKTtime,
(((TRANan*)ckt->CKTcurJob)->TRANplot));
ckt->CKTstat->STAToldIter = ckt->CKTstat->STATnumIter;
if(fabs(ckt->CKTtime - ckt->CKTfinalTime) < ckt->CKTminBreak) {
/*printf(" done: time is %g, final time is %g, and tol is %g\n",*/
/*ckt->CKTtime,ckt->CKTfinalTime,ckt->CKTminBreak);*/
(*(SPfrontEnd->OUTendPlot))( (((TRANan*)ckt->CKTcurJob)->TRANplot));
ckt->CKTcurrentAnalysis = 0;
ckt->CKTstat->STATtranTime += (*(SPfrontEnd->IFseconds))()-startTime;
ckt->CKTstat->STATtranIter += ckt->CKTstat->STATnumIter - startIters;
ckt->CKTstat->STATtranDecompTime += ckt->CKTstat->STATdecompTime -
startdTime;
ckt->CKTstat->STATtranSolveTime += ckt->CKTstat->STATsolveTime -
startsTime;
ckt->CKTstat->STATtranLoadTime += ckt->CKTstat->STATloadTime -
startlTime;
ckt->CKTstat->STATtranCombTime += ckt->CKTstat->STATcombineTime -
startcTime;
ckt->CKTstat->STATtranSyncTime += ckt->CKTstat->STATsyncTime -
startkTime;
#ifdef WANT_SENSE2
if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode & TRANSEN)){
ckt->CKTsenInfo->SENmode = save;
#ifdef SENSDEBUG
fclose(outsen);
#endif /* SENSDEBUG */
}
#endif
return(OK);
}
if( (*(SPfrontEnd->IFpauseTest))() ) {
/* user requested pause... */
ckt->CKTcurrentAnalysis = DOING_TRAN;
ckt->CKTstat->STATtranTime += (*(SPfrontEnd->IFseconds))()-startTime;
ckt->CKTstat->STATtranIter += ckt->CKTstat->STATnumIter - startIters;
ckt->CKTstat->STATtranDecompTime += ckt->CKTstat->STATdecompTime -
startdTime;
ckt->CKTstat->STATtranSolveTime += ckt->CKTstat->STATsolveTime -
startsTime;
ckt->CKTstat->STATtranLoadTime += ckt->CKTstat->STATloadTime -
startlTime;
ckt->CKTstat->STATtranCombTime += ckt->CKTstat->STATcombineTime -
startcTime;
ckt->CKTstat->STATtranSyncTime += ckt->CKTstat->STATsyncTime -
startkTime;
return(E_PAUSE);
}
resume:
#ifdef STEPDEBUG
if( (ckt->CKTdelta <= ckt->CKTfinalTime/50) &&
(ckt->CKTdelta <= ckt->CKTmaxStep)) {
;
} else {
if(ckt->CKTfinalTime/50<ckt->CKTmaxStep) {
(void)printf("limited by Tstop/50\n");
} else {
(void)printf("limited by Tmax\n");
}
}
#endif
ckt->CKTdelta =
MIN(ckt->CKTdelta,ckt->CKTmaxStep);
/* are we at a breakpoint, or indistinguishably close? */
if ((ckt->CKTtime == *(ckt->CKTbreaks)) || (*(ckt->CKTbreaks) -
(ckt->CKTtime) <= ckt->CKTdelmin)) {
/* first timepoint after a breakpoint - cut integration order */
/* and limit timestep to .1 times minimum of time to next breakpoint,
* and previous timestep
*/
ckt->CKTorder = 1;
#ifdef STEPDEBUG
if( (ckt->CKTdelta >.1* ckt->CKTsaveDelta) ||
(ckt->CKTdelta > .1*(*(ckt->CKTbreaks+1)-*(ckt->CKTbreaks))) ) {
if(ckt->CKTsaveDelta < (*(ckt->CKTbreaks+1)-*(ckt->CKTbreaks))) {
(void)printf("limited by pre-breakpoint delta\n");
} else {
(void)printf("limited by next breakpoint\n");
}
}
#endif
ckt->CKTdelta = MIN(ckt->CKTdelta, .1 * MIN(ckt->CKTsaveDelta,
*(ckt->CKTbreaks+1)-*(ckt->CKTbreaks)));
if(firsttime) {
ckt->CKTdelta /= 10;
#ifdef STEPDEBUG
(void)printf("delta cut for initial timepoint\n");
#endif
}
/* don't want to get below delmin for no reason */
ckt->CKTdelta = MAX(ckt->CKTdelta, ckt->CKTdelmin*2.0);
}
else if(ckt->CKTtime + ckt->CKTdelta >= *(ckt->CKTbreaks)) {
ckt->CKTsaveDelta = ckt->CKTdelta;
ckt->CKTdelta = *(ckt->CKTbreaks) - ckt->CKTtime;
#ifdef STEPDEBUG
(void)printf("delta cut to hit breakpoint\n");
#endif
ckt->CKTbreak = 1; /* why? the current pt. is not a bkpt. */
}
#ifdef PARALLEL_ARCH
DGOP_( &type, &(ckt->CKTdelta), &length, "min" );
#endif /* PARALLEL_ARCH */
for(i=5;i>=0;i--) {
ckt->CKTdeltaOld[i+1]=ckt->CKTdeltaOld[i];
}
ckt->CKTdeltaOld[0]=ckt->CKTdelta;
temp = ckt->CKTstates[ckt->CKTmaxOrder+1];
for(i=ckt->CKTmaxOrder;i>=0;i--) {
ckt->CKTstates[i+1] = ckt->CKTstates[i];
}
ckt->CKTstates[0] = temp;
/* 600 */
while (1) {
olddelta=ckt->CKTdelta;
/* time abort? */
ckt->CKTtime += ckt->CKTdelta;
ckt->CKTdeltaOld[0]=ckt->CKTdelta;
NIcomCof(ckt);
#ifdef PREDICTOR
error = NIpred(ckt);
#endif /* PREDICTOR */
save_mode = ckt->CKTmode;
save_order = ckt->CKTorder;
converged = NIiter(ckt,ckt->CKTtranMaxIter);
ckt->CKTstat->STATtimePts ++;
ckt->CKTmode = (ckt->CKTmode&MODEUIC)|MODETRAN | MODEINITPRED;
if(firsttime) {
for(i=0;i<ckt->CKTnumStates;i++) {
*(ckt->CKTstate2+i) = *(ckt->CKTstate1+i);
*(ckt->CKTstate3+i) = *(ckt->CKTstate1+i);
}
}
if(converged != 0) {
ckt->CKTtime = ckt->CKTtime -ckt->CKTdelta;
ckt->CKTstat->STATrejected ++;
ckt->CKTdelta = ckt->CKTdelta/8;
#ifdef STEPDEBUG
(void)printf("delta cut for non-convergence\n");
#endif
if(firsttime) {
ckt->CKTmode = (ckt->CKTmode&MODEUIC)|MODETRAN | MODEINITTRAN;
}
ckt->CKTorder = 1;
} else {
if (firsttime) {
#ifdef WANT_SENSE2
if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode & TRANSEN)){
save1 = ckt->CKTmode;
save2 = ckt->CKTorder;
ckt->CKTmode = save_mode;
ckt->CKTorder = save_order;
if(error = CKTsenDCtran(ckt)) return(error);
ckt->CKTmode = save1;
ckt->CKTorder = save2;
}
#endif
firsttime =0;
goto nextTime; /* no check on
* first time point
*/
}
new = ckt->CKTdelta;
error = CKTtrunc(ckt,&new);
if(error) {
ckt->CKTcurrentAnalysis = DOING_TRAN;
ckt->CKTstat->STATtranTime +=
(*(SPfrontEnd->IFseconds))()-startTime;
ckt->CKTstat->STATtranIter +=
ckt->CKTstat->STATnumIter - startIters;
ckt->CKTstat->STATtranDecompTime += ckt->CKTstat->STATdecompTime
- startdTime;
ckt->CKTstat->STATtranSolveTime += ckt->CKTstat->STATsolveTime
- startsTime;
ckt->CKTstat->STATtranLoadTime += ckt->CKTstat->STATloadTime
- startlTime;
ckt->CKTstat->STATtranCombTime += ckt->CKTstat->STATcombineTime
- startcTime;
ckt->CKTstat->STATtranSyncTime += ckt->CKTstat->STATsyncTime
- startkTime;
return(error);
}
if(new>.9 * ckt->CKTdelta) {
if(ckt->CKTorder == 1) {
new = ckt->CKTdelta;
ckt->CKTorder = 2;
error = CKTtrunc(ckt,&new);
if(error) {
ckt->CKTcurrentAnalysis = DOING_TRAN;
ckt->CKTstat->STATtranTime +=
(*(SPfrontEnd->IFseconds))()-startTime;
ckt->CKTstat->STATtranIter +=
ckt->CKTstat->STATnumIter - startIters;
ckt->CKTstat->STATtranDecompTime +=
ckt->CKTstat->STATdecompTime - startdTime;
ckt->CKTstat->STATtranSolveTime +=
ckt->CKTstat->STATsolveTime - startsTime;
ckt->CKTstat->STATtranLoadTime +=
ckt->CKTstat->STATloadTime - startlTime;
ckt->CKTstat->STATtranCombTime +=
ckt->CKTstat->STATcombineTime - startcTime;
ckt->CKTstat->STATtranSyncTime +=
ckt->CKTstat->STATsyncTime - startkTime;
return(error);
}
if(new <= 1.05 * ckt->CKTdelta) {
ckt->CKTorder = 1;
}
}
/* time point OK - 630*/
ckt->CKTdelta = new;
#ifdef STEPDEBUG
(void)printf(
"delta set to truncation error result:point accepted\n");
#endif
#ifdef WANT_SENSE2
if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode & TRANSEN)){
save1 = ckt->CKTmode;
save2 = ckt->CKTorder;
ckt->CKTmode = save_mode;
ckt->CKTorder = save_order;
if(error = CKTsenDCtran(ckt)) return(error);
ckt->CKTmode = save1;
ckt->CKTorder = save2;
}
#endif
/* go to 650 - trapezoidal */
goto nextTime;
} else {
ckt->CKTtime = ckt->CKTtime -ckt->CKTdelta;
ckt->CKTstat->STATrejected ++;
ckt->CKTdelta = new;
#ifdef STEPDEBUG
(void)printf(
"delta set to truncation error result:point rejected\n");
#endif
}
}
#ifdef PARALLEL_ARCH
DGOP_( &type, &(ckt->CKTdelta), &length, "min" );
#endif /* PARALLEL_ARCH */
if (ckt->CKTdelta <= ckt->CKTdelmin) {
if (olddelta > ckt->CKTdelmin) {
ckt->CKTdelta = ckt->CKTdelmin;
#ifdef STEPDEBUG
(void)printf("delta at delmin\n");
#endif
} else {
ckt->CKTcurrentAnalysis = DOING_TRAN;
ckt->CKTstat->STATtranTime +=
(*(SPfrontEnd->IFseconds))()-startTime;
ckt->CKTstat->STATtranIter +=
ckt->CKTstat->STATnumIter - startIters;
ckt->CKTstat->STATtranDecompTime +=
ckt->CKTstat->STATdecompTime - startdTime;
ckt->CKTstat->STATtranSolveTime +=
ckt->CKTstat->STATsolveTime - startsTime;
ckt->CKTstat->STATtranLoadTime +=
ckt->CKTstat->STATloadTime - startlTime;
ckt->CKTstat->STATtranCombTime +=
ckt->CKTstat->STATcombineTime - startcTime;
ckt->CKTstat->STATtranSyncTime +=
ckt->CKTstat->STATsyncTime - startkTime;
errMsg = CKTtrouble((void *) ckt, "Timestep too small");
return(E_TIMESTEP);
}
}
}
/* NOTREACHED */
}

View File

@ -1,403 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
Modified: 1999 Paolo Nenzi
**********/
#include "ngspice.h"
#include <stdio.h>
#include "vsrc/vsrcdefs.h"
#include "isrc/isrcdefs.h"
#include "res/resdefs.h"
#include "cktdefs.h"
#include "const.h"
#include "sperror.h"
int
DCtrCurv(CKTcircuit *ckt, int restart)
/* forced restart flag */
{
register TRCV* cv = (TRCV*)ckt->CKTcurJob; /* Where we get the job to do */
int i;
double *temp;
int converged;
int rcode;
int vcode;
int icode;
int j;
int error;
IFuid varUid;
IFuid *nameList;
int numNames;
int firstTime=1;
static void *plot;
#ifdef WANT_SENSE2
#ifdef SENSDEBUG
if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode&DCSEN) ){
printf("\nDC Sensitivity Results\n\n");
CKTsenPrint(ckt);
}
#endif /* SENSDEBUG */
#endif
rcode = CKTtypelook("Resistor");
vcode = CKTtypelook("Vsource");
icode = CKTtypelook("Isource");
if(!restart && cv->TRCVnestState >= 0) {
/* continuing */
i = cv->TRCVnestState;
goto resume;
}
ckt->CKTtime = 0;
ckt->CKTdelta = cv->TRCVvStep[0];
ckt->CKTmode = (ckt->CKTmode & MODEUIC) | MODEDCTRANCURVE | MODEINITJCT ;
ckt->CKTorder=1;
/* Save the state of the circuit */
for(i=0;i<7;i++) {
ckt->CKTdeltaOld[i]=ckt->CKTdelta;
}
for(i=0;i<=cv->TRCVnestLevel;i++) {
if(rcode >= 0) {
/* resistances are in this version, so use them */
register RESinstance *here;
register RESmodel *model;
for(model = (RESmodel *)ckt->CKThead[rcode];model != NULL;
model=model->RESnextModel){
for(here=model->RESinstances;here!=NULL;
here=here->RESnextInstance) {
if(here->RESname == cv->TRCVvName[i]) {
cv->TRCVvElt[i] = (GENinstance *)here;
cv->TRCVvSave[i] = here->RESresist;
cv->TRCVgSave[i] = here->RESresGiven;
cv->TRCVvType[i] = rcode;
here->RESresist = cv->TRCVvStart[i];
here->RESresGiven = 1;
printf("** Resistor sweep is highly alpha code\n**Results may not be accurate.\n");
goto found;
}
}
}
}
if(vcode >= 0) {
/* voltage sources are in this version, so use them */
register VSRCinstance *here;
register VSRCmodel *model;
for(model = (VSRCmodel *)ckt->CKThead[vcode];model != NULL;
model=model->VSRCnextModel){
for(here=model->VSRCinstances;here!=NULL;
here=here->VSRCnextInstance) {
if(here->VSRCname == cv->TRCVvName[i]) {
cv->TRCVvElt[i] = (GENinstance *)here;
cv->TRCVvSave[i] = here->VSRCdcValue;
cv->TRCVgSave[i] = here->VSRCdcGiven;
cv->TRCVvType[i] = vcode;
here->VSRCdcValue = cv->TRCVvStart[i];
here->VSRCdcGiven = 1;
goto found;
}
}
}
}
if(icode >= 0 ) {
/* current sources are in this version, so use them */
register ISRCinstance *here;
register ISRCmodel *model;
for(model= (ISRCmodel *)ckt->CKThead[icode];model != NULL;
model=model->ISRCnextModel){
for(here=model->ISRCinstances;here!=NULL;
here=here->ISRCnextInstance) {
if(here->ISRCname == cv->TRCVvName[i]) {
cv->TRCVvElt[i] = (GENinstance *)here;
cv->TRCVvSave[i] = here->ISRCdcValue;
cv->TRCVgSave[i] = here->ISRCdcGiven;
cv->TRCVvType[i] = icode;
here->ISRCdcValue = cv->TRCVvStart[i];
here->ISRCdcGiven = 1;
goto found;
}
}
}
}
if(!strcmp(cv->TRCVvName[i], "temp"))
{
cv->TRCVvSave[i]=ckt->CKTtemp; /* Saves the old circuit temperature */
cv->TRCVvType[i]=TEMP_CODE; /* Set the sweep type code */
ckt->CKTtemp = cv->TRCVvStart[i] + CONSTCtoK; /* Set the new circuit temp */
printf("Temperature sweep is alpha code\nresults may not be accurate\n");
goto found;
}
(*(SPfrontEnd->IFerror))(ERR_FATAL,
"DCtrCurv: source / resistor %s not in circuit", &(cv->TRCVvName[i]));
return(E_NODEV);
found:;
}
i--; /* PN: This seems to do nothing ??? */
error = CKTnames(ckt,&numNames,&nameList);
if(error) return(error);
if (cv->TRCVvType[i]==vcode)
(*(SPfrontEnd->IFnewUid))((void *)ckt,&varUid,(IFuid )NULL,
"v-sweep", UID_OTHER, (void **)NULL);
else if (cv->TRCVvType[i]==icode)
(*(SPfrontEnd->IFnewUid))((void *)ckt,&varUid,(IFuid )NULL,
"i-sweep", UID_OTHER, (void **)NULL);
else if (cv->TRCVvType[i]==TEMP_CODE)
(*(SPfrontEnd->IFnewUid))((void *)ckt,&varUid,(IFuid )NULL,
"temp-sweep", UID_OTHER, (void **)NULL);
/* PN Resistance Sweep */
else if (cv->TRCVvType[i]==rcode)
(*(SPfrontEnd->IFnewUid))((void *)ckt,&varUid,(IFuid )NULL,
"res-sweep", UID_OTHER, (void **)NULL);
else
(*(SPfrontEnd->IFnewUid))((void *)ckt,&varUid,(IFuid )NULL,
"?-sweep", UID_OTHER, (void **)NULL);
error = (*(SPfrontEnd->OUTpBeginPlot))((void *)ckt,
(void*)ckt->CKTcurJob, ckt->CKTcurJob->JOBname,
varUid,IF_REAL,numNames,nameList, IF_REAL,&plot);
if(error) return(error);
/* now have finished the initialization - can start doing hard part */
i = 0;
resume:
for(;;) {
if(cv->TRCVvType[i]==vcode) { /* voltage source */
if((((VSRCinstance*)(cv->TRCVvElt[i]))->VSRCdcValue)*
SIGN(1.,cv->TRCVvStep[i]) -
SIGN(1.,cv->TRCVvStep[i]) * cv->TRCVvStop[i] >
0.5 * fabs(cv->TRCVvStep[i]))
{
i++ ;
firstTime=1;
ckt->CKTmode = (ckt->CKTmode & MODEUIC) |
MODEDCTRANCURVE | MODEINITJCT ;
if (i > cv->TRCVnestLevel ) break ;
goto nextstep;
}
} else if(cv->TRCVvType[i]==icode) { /* current source */
if((((ISRCinstance*)(cv->TRCVvElt[i]))->ISRCdcValue)*
SIGN(1.,cv->TRCVvStep[i]) -
SIGN(1.,cv->TRCVvStep[i]) * cv->TRCVvStop[i] >
0.5 * fabs(cv->TRCVvStep[i]))
{
i++ ;
firstTime=1;
ckt->CKTmode = (ckt->CKTmode & MODEUIC) |
MODEDCTRANCURVE | MODEINITJCT ;
if (i > cv->TRCVnestLevel ) break ;
goto nextstep;
}
} else if(cv->TRCVvType[i]==rcode) { /* resistance */
if((((RESinstance*)(cv->TRCVvElt[i]))->RESresist)*
SIGN(1.,cv->TRCVvStep[i]) -
SIGN(1.,cv->TRCVvStep[i]) * cv->TRCVvStop[i] >
0.5 * fabs(cv->TRCVvStep[i]))
{
i++ ;
firstTime=1;
ckt->CKTmode = (ckt->CKTmode & MODEUIC) |
MODEDCTRANCURVE | MODEINITJCT ;
if (i > cv->TRCVnestLevel ) break ;
goto nextstep;
}
} else if(cv->TRCVvType[i]==TEMP_CODE) { /* temp sweep */
if(((ckt->CKTtemp) - CONSTCtoK) * SIGN(1.,cv->TRCVvStep[i]) -
SIGN(1.,cv->TRCVvStep[i]) * cv->TRCVvStop[i] >
0.5 * fabs(cv->TRCVvStep[i]))
{
i++ ;
firstTime=1;
ckt->CKTmode = (ckt->CKTmode & MODEUIC) |
MODEDCTRANCURVE | MODEINITJCT ;
if (i > cv->TRCVnestLevel ) break ;
goto nextstep;
}
} /* else not possible */
while (i > 0) {
/* init(i); */
i--;
if(cv->TRCVvType[i]==vcode) { /* voltage source */
((VSRCinstance *)(cv->TRCVvElt[i]))->VSRCdcValue =
cv->TRCVvStart[i];
} else if(cv->TRCVvType[i]==icode) { /* current source */
((ISRCinstance *)(cv->TRCVvElt[i]))->ISRCdcValue =
cv->TRCVvStart[i];
} else if(cv->TRCVvType[i]==TEMP_CODE) {
ckt->CKTtemp = cv->TRCVvStart[i] + CONSTCtoK;
CKTtemp(ckt);
} else if(cv->TRCVvType[i]==rcode) {
((RESinstance *)(cv->TRCVvElt[i]))->RESresist =
cv->TRCVvStart[i];
((RESinstance *)(cv->TRCVvElt[i]))->RESconduct =
1/(((RESinstance *)(cv->TRCVvElt[i]))->RESresist);
/* Note: changing the resistance does nothing */
/* changing the conductance 1/r instead */
RESload((GENmodel*)(cv->TRCVvElt[i]->GENmodPtr),ckt);
} /* else not possible */
}
/* Rotate state vectors. */
temp = ckt->CKTstates[ckt->CKTmaxOrder+1];
for(j=ckt->CKTmaxOrder;j>=0;j--) {
ckt->CKTstates[j+1] = ckt->CKTstates[j];
}
ckt->CKTstate0 = temp;
/* do operation */
converged = NIiter(ckt,ckt->CKTdcTrcvMaxIter);
if(converged != 0) {
converged = CKTop(ckt,
(ckt->CKTmode&MODEUIC)|MODEDCTRANCURVE | MODEINITJCT,
(ckt->CKTmode&MODEUIC)|MODEDCTRANCURVE | MODEINITFLOAT,
ckt->CKTdcMaxIter);
if(converged != 0) {
return(converged);
}
}
ckt->CKTmode = (ckt->CKTmode&MODEUIC) | MODEDCTRANCURVE | MODEINITPRED ;
if(cv->TRCVvType[0] == vcode) {
ckt->CKTtime = ((VSRCinstance *)(cv->TRCVvElt[i]))
->VSRCdcValue ;
} else if(cv->TRCVvType[0] == icode) {
ckt->CKTtime = ((ISRCinstance *)(cv->TRCVvElt[i]))
->ISRCdcValue ;
} else if(cv->TRCVvType[0] == rcode) {
ckt->CKTtime = ((RESinstance *)(cv->TRCVvElt[i]))
->RESresist;
}
/* PN Temp sweep */
else
{
ckt->CKTtime = ckt->CKTtemp - CONSTCtoK ;
}
#ifdef WANT_SENSE2
/*
if(!ckt->CKTsenInfo) printf("sensitivity structure does not exist\n");
*/
if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode&DCSEN) ){
int senmode;
#ifdef SENSDEBUG
if(cv->TRCVvType[i]==vcode) { /* voltage source */
printf("Voltage Source Value : %.5e V\n",
((VSRCinstance*) (cv->TRCVvElt[i]))->VSRCdcValue);
}
if(cv->TRCVvType[i]==icode) { /* current source */
printf("Current Source Value : %.5e A\n",
((ISRCinstance*)(cv->TRCVvElt[i]))->ISRCdcValue);
}
if(cv->TRCVvType[i]==rcode) { /* resistance */
printf("Current Resistance Value : %.5e Ohm\n",
((RESinstance*)(cv->TRCVvElt[i]->GENmodPtr))->RESresist);
}
if(cv->TRCVvType[i]==TEMP_CODE) { /* Temperature */
printf("Current Circuit Temperature : %.5e C\n",
ckt-CKTtime - CONSTCtoK);
}
#endif /* SENSDEBUG */
senmode = ckt->CKTsenInfo->SENmode;
save = ckt->CKTmode;
ckt->CKTsenInfo->SENmode = DCSEN;
if(error = CKTsenDCtran(ckt)) return (error);
ckt->CKTmode = save;
ckt->CKTsenInfo->SENmode = senmode;
}
#endif
CKTdump(ckt,ckt->CKTtime,plot);
if(firstTime) {
firstTime=0;
bcopy((char *)ckt->CKTstate0,(char *)ckt->CKTstate1,
ckt->CKTnumStates*sizeof(double));
}
nextstep:;
if(cv->TRCVvType[i]==vcode) { /* voltage source */
((VSRCinstance*)(cv->TRCVvElt[i]))->VSRCdcValue +=
cv->TRCVvStep[i];
} else if(cv->TRCVvType[i]==icode) { /* current source */
((ISRCinstance*)(cv->TRCVvElt[i]))->ISRCdcValue +=
cv->TRCVvStep[i];
} else if(cv->TRCVvType[i]==rcode) { /* resistance */
((RESinstance*)(cv->TRCVvElt[i]))->RESresist +=
cv->TRCVvStep[i];
/* This code should update resistance and conductance */
((RESinstance*)(cv->TRCVvElt[i]))->RESconduct =
1/(((RESinstance*)(cv->TRCVvElt[i]))->RESresist);
RESload((GENmodel*)(cv->TRCVvElt[i]->GENmodPtr),ckt);
}
/* PN Temp Sweep - serban */
else if (cv->TRCVvType[i]==TEMP_CODE)
{
ckt->CKTtemp += cv->TRCVvStep[i];
CKTtemp(ckt);
} /* else not possible */
if( (*(SPfrontEnd->IFpauseTest))() ) {
/* user asked us to pause, so save state */
cv->TRCVnestState = i;
return(E_PAUSE);
}
}
/* all done, lets put everything back */
for(i=0;i<=cv->TRCVnestLevel;i++) {
if(cv->TRCVvType[i] == vcode) { /* voltage source */
((VSRCinstance*)(cv->TRCVvElt[i]))->VSRCdcValue =
cv->TRCVvSave[i];
((VSRCinstance*)(cv->TRCVvElt[i]))->VSRCdcGiven = cv->TRCVgSave[i];
} else if(cv->TRCVvType[i] == icode) /*current source */ {
((ISRCinstance*)(cv->TRCVvElt[i]))->ISRCdcValue =
cv->TRCVvSave[i];
((ISRCinstance*)(cv->TRCVvElt[i]))->ISRCdcGiven = cv->TRCVgSave[i];
} else if(cv->TRCVvType[i] == rcode) /* Resistance */ {
((RESinstance*)(cv->TRCVvElt[i]))->RESresist =
cv->TRCVvSave[i];
/* We restore both resistance and conductance */
((RESinstance*)(cv->TRCVvElt[i]))->RESconduct =
1/(((RESinstance*)(cv->TRCVvElt[i]))->RESresist);
((RESinstance*)(cv->TRCVvElt[i]))->RESresGiven = cv->TRCVgSave[i];
RESload((GENmodel*)(cv->TRCVvElt[i]->GENmodPtr),ckt);
}
else if(cv->TRCVvType[i] == TEMP_CODE) {
ckt->CKTtemp = cv->TRCVvSave[i];
CKTtemp(ckt);
} /* else not possible */
}
(*(SPfrontEnd->OUTendPlot))(plot);
return(OK);
}

View File

@ -1,116 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
#include "ngspice.h"
#include <stdio.h>
#include "ifsim.h"
#include "iferrmsg.h"
#include "trcvdefs.h"
#include "cktdefs.h"
/* ARGSUSED */
int
DCTsetParm(CKTcircuit *ckt, void *anal, int which, IFvalue *value)
{
register TRCV* cv= (TRCV*)anal;
switch(which) {
case DCT_START1:
cv->TRCVvStart[0] = value->rValue;
cv->TRCVnestLevel = MAX(0,cv->TRCVnestLevel);
cv->TRCVset[0]=TRUE;
break;
case DCT_STOP1:
cv->TRCVvStop[0] = value->rValue;
cv->TRCVnestLevel = MAX(0,cv->TRCVnestLevel);
cv->TRCVset[0]=TRUE;
break;
case DCT_STEP1:
cv->TRCVvStep[0] = value->rValue;
cv->TRCVnestLevel = MAX(0,cv->TRCVnestLevel);
cv->TRCVset[0]=TRUE;
break;
case DCT_START2:
cv->TRCVvStart[1] = value->rValue;
cv->TRCVnestLevel = MAX(1,cv->TRCVnestLevel);
cv->TRCVset[1]=TRUE;
break;
case DCT_STOP2:
cv->TRCVvStop[1] = value->rValue;
cv->TRCVnestLevel = MAX(1,cv->TRCVnestLevel);
cv->TRCVset[1]=TRUE;
break;
case DCT_STEP2:
cv->TRCVvStep[1] = value->rValue;
cv->TRCVnestLevel = MAX(1,cv->TRCVnestLevel);
cv->TRCVset[1]=TRUE;
break;
case DCT_NAME1:
cv->TRCVvName[0] = value->uValue;
cv->TRCVnestLevel = MAX(0,cv->TRCVnestLevel);
cv->TRCVset[0]=TRUE;
break;
case DCT_NAME2:
cv->TRCVvName[1] = value->uValue;
cv->TRCVnestLevel = MAX(1,cv->TRCVnestLevel);
cv->TRCVset[1]=TRUE;
break;
case DCT_TYPE1:
cv->TRCVvType[0] = value->iValue;
cv->TRCVnestLevel = MAX(0,cv->TRCVnestLevel);
cv->TRCVset[0]=TRUE;
break;
case DCT_TYPE2:
cv->TRCVvType[1] = value->iValue;
cv->TRCVnestLevel = MAX(1,cv->TRCVnestLevel);
cv->TRCVset[1]=TRUE;
break;
default:
return(E_BADPARM);
}
return(OK);
}
static IFparm DCTparms[] = {
{ "start1", DCT_START1, IF_SET|IF_REAL, "starting voltage/current"},
{ "stop1", DCT_STOP1, IF_SET|IF_REAL, "ending voltage/current" },
{ "step1", DCT_STEP1, IF_SET|IF_REAL, "voltage/current step" },
{ "start2", DCT_START2, IF_SET|IF_REAL, "starting voltage/current"},
{ "stop2", DCT_STOP2, IF_SET|IF_REAL, "ending voltage/current" },
{ "step2", DCT_STEP2, IF_SET|IF_REAL, "voltage/current step" },
{ "name1", DCT_NAME1, IF_SET|IF_INSTANCE, "name of source to step" },
{ "name2", DCT_NAME2, IF_SET|IF_INSTANCE, "name of source to step" },
{ "type1", DCT_TYPE1, IF_SET|IF_INTEGER, "type of source to step" },
{ "type2", DCT_TYPE2, IF_SET|IF_INTEGER, "type of source to step" }
};
SPICEanalysis DCTinfo = {
{
"DC",
"D.C. Transfer curve analysis",
sizeof(DCTparms)/sizeof(IFparm),
DCTparms
},
sizeof(TRCV),
SWEEPDOMAIN,
1,
DCTsetParm,
DCTaskQuest,
NULL,
DCtrCurv
};

View File

@ -1,668 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1988 Jaijeet S Roychowdhury
**********/
#include "ngspice.h"
#include <stdio.h>
#include "cktdefs.h"
#include "distodef.h"
#include "sperror.h"
void
DISswap(double **a, double **b)
{
double *c;
c = *a;
*a = *b;
*b = c;
}
void
DmemAlloc(double **a, int size)
{
*a = (double *) MALLOC( sizeof(double) * size + 1);
}
void
DstorAlloc(double ***header, int size)
{
*header = (double **) MALLOC( sizeof(double *)*size);
}
#ifdef STDC
extern int CKTdisto(CKTcircuit*, int);
extern int DkerProc(int,double*,double*,int,DISTOan*);
#else
extern int CKTdisto(register CKTcircuit *ckt, int mode);
extern int DkerProc(int type, double *rPtr, double *iPtr, int size, DISTOAN *job);
#endif
int
DISTOan(CKTcircuit *ckt, int restart)
{
double freq;
static double freqTol; /* tolerence parameter for finding final frequency */
static int NoOfPoints;
static int size;
static int displacement;
int error;
int i;
int numNames;
IFuid *nameList;
IFuid freqUid;
void *acPlot;
register DISTOAN* job = (DISTOAN *) (ckt->CKTcurJob);
static char *nof2src = "No source with f2 distortion input";
#ifdef DISTODEBUG
double time,time1;
#endif
/* start at beginning */
#ifdef D_DBG_BLOCKTIMES
time1 = (*(SPfrontEnd->IFseconds))();
#endif
switch(job->DstepType) {
case DECADE:
job->DfreqDelta =
exp(log(10.0)/job->DnumSteps);
freqTol = job->DfreqDelta *
job->DstopF1 * ckt->CKTreltol;
NoOfPoints = 1 + floor ((job->DnumSteps) / log(10.0) * log((job->DstopF1+freqTol)/(job->DstartF1)));
break;
case OCTAVE:
job->DfreqDelta =
exp(log(2.0)/job->DnumSteps);
freqTol = job->DfreqDelta *
job->DstopF1 * ckt->CKTreltol;
NoOfPoints = 1 + floor ((job->DnumSteps) / log(2.0) * log((job->DstopF1+freqTol)/(job->DstartF1)));
break;
case LINEAR:
job->DfreqDelta =
(job->DstopF1 -
job->DstartF1)/
(job->DnumSteps+1);
freqTol = job->DfreqDelta * ckt->CKTreltol;
NoOfPoints = job->DnumSteps+1+ floor(freqTol/(job->DfreqDelta));
break;
default:
return(E_BADPARM);
}
error = CKTop(ckt,
(ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITJCT,
(ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITFLOAT,
ckt->CKTdcMaxIter);
if(error) return(error);
ckt->CKTmode = (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITSMSIG;
error = CKTload(ckt);
if(error) return(error);
error = CKTnames(ckt,&numNames,&nameList);
if(error) return(error);
if (ckt->CKTkeepOpInfo) {
/* Dump operating point. */
error = (*(SPfrontEnd->OUTpBeginPlot))((void *)ckt,
(void*)ckt->CKTcurJob, "Distortion Operating Point",
(IFuid)NULL,IF_REAL,numNames,nameList, IF_REAL,&acPlot);
if(error) return(error);
CKTdump(ckt,(double)0,acPlot);
(*(SPfrontEnd->OUTendPlot))(acPlot);
}
#ifdef D_DBG_BLOCKTIMES
time1 = (*(SPfrontEnd->IFseconds))() - time1;
printf("Time for initial work (including op. pt.): %g seconds \n", time1);
#endif
#ifdef D_DBG_BLOCKTIMES
time1 = (*(SPfrontEnd->IFseconds))();
#endif
error = CKTdisto(ckt,D_SETUP);
#ifdef D_DBG_BLOCKTIMES
time1 = (*(SPfrontEnd->IFseconds))() - time1;
printf("Time outside D_SETUP: %g seconds \n", time1);
#endif
if (error) return(error);
displacement = 0;
#ifdef D_DBG_BLOCKTIMES
time1 = (*(SPfrontEnd->IFseconds))();
#endif
freq = job->DstartF1;
if (job->Df2wanted) {
/*
omegadelta = 2.0 * M_PI * freq *(1. - job->Df2ovrF1);
*/
/* keeping f2 const to be compatible with spectre */
job->Domega2 = 2.0 * M_PI * freq * job->Df2ovrF1;
}
DstorAlloc( &(job->r1H1stor),NoOfPoints+2);
DstorAlloc( &(job->r2H11stor),NoOfPoints+2);
DstorAlloc( &(job->i1H1stor),NoOfPoints+2);
DstorAlloc( &(job->i2H11stor),NoOfPoints+2);
size = SMPmatSize(ckt->CKTmatrix);
if (! job->r1H1ptr)
{
DmemAlloc( &(job->r1H1ptr) , size+2);
if (! job->r1H1ptr) return (E_NOMEM);
}
if (! job->r2H11ptr)
{
DmemAlloc( &(job->r2H11ptr) , size+2);
if (! job->r2H11ptr) return (E_NOMEM);
}
if (! job->i1H1ptr)
{
DmemAlloc( &(job->i1H1ptr) , size+2);
if (! job->i1H1ptr) return (E_NOMEM);
}
if (! job->i2H11ptr)
{
DmemAlloc( &(job->i2H11ptr) , size+2);
if (! job->i2H11ptr) return (E_NOMEM);
}
if (! (job->Df2wanted))
{
DstorAlloc( &(job->r3H11stor),NoOfPoints+2);
DstorAlloc( &(job->i3H11stor),NoOfPoints+2);
if (! job->r3H11ptr)
{
DmemAlloc( &(job->r3H11ptr) , size+2);
if (! job->r3H11ptr) return (E_NOMEM);
}
if (! job->i3H11ptr)
{
DmemAlloc( &(job->i3H11ptr) , size+2);
if (! job->i3H11ptr) return (E_NOMEM);
}
} else {
DstorAlloc ( &(job->r1H2stor),NoOfPoints+2);
DstorAlloc ( &(job->i1H2stor),NoOfPoints+2);
DstorAlloc ( &(job->r2H12stor),NoOfPoints+2);
DstorAlloc ( &(job->i2H12stor),NoOfPoints+2);
DstorAlloc ( &(job->r2H1m2stor),NoOfPoints+2);
DstorAlloc ( &(job->i2H1m2stor),NoOfPoints+2);
DstorAlloc ( &(job->r3H1m2stor),NoOfPoints+2);
DstorAlloc ( &(job->i3H1m2stor),NoOfPoints+2);
if (! job->r1H2ptr)
{
DmemAlloc( &(job->r1H2ptr) , size+2);
if (! job->r1H2ptr) return (E_NOMEM);
}
if (! job->r2H12ptr)
{
DmemAlloc( &(job->r2H12ptr) , size+2);
if (! job->r2H12ptr) return (E_NOMEM);
}
if (! job->r2H1m2ptr)
{
DmemAlloc( &(job->r2H1m2ptr) , size+2);
if (! job->r2H1m2ptr) return (E_NOMEM);
}
if (! job->r3H1m2ptr)
{
DmemAlloc( &(job->r3H1m2ptr) , size+2);
if (! job->r3H1m2ptr) return (E_NOMEM);
}
if (! job->i1H2ptr)
{
DmemAlloc( &(job->i1H2ptr) , size+2);
if (! job->i1H2ptr) return (E_NOMEM);
}
if (! job->i2H12ptr)
{
DmemAlloc( &(job->i2H12ptr) , size+2);
if (! job->i2H12ptr) return (E_NOMEM);
}
if (! job->i2H1m2ptr)
{
DmemAlloc( &(job->i2H1m2ptr) , size+2);
if (! job->i2H1m2ptr) return (E_NOMEM);
}
if (! job->i3H1m2ptr)
{
DmemAlloc( &(job->i3H1m2ptr) , size+2);
if (! job->i3H1m2ptr) return (E_NOMEM);
}
}
#ifdef D_DBG_BLOCKTIMES
time1 = (*(SPfrontEnd->IFseconds))() - time1;
printf("Time for other setup (storage allocation etc.): %g seconds \n", time1);
#endif
#ifdef D_DBG_BLOCKTIMES
time1 = (*(SPfrontEnd->IFseconds))();
#endif
while(freq <= job->DstopF1+freqTol) {
/*
if( (*(SPfrontEnd->IFpauseTest))() ) {
job->DsaveF1 = freq;
return(E_PAUSE);
}
*/
ckt->CKTomega = 2.0 * M_PI *freq;
job->Domega1 = ckt->CKTomega;
ckt->CKTmode = (ckt->CKTmode&MODEUIC) | MODEAC;
#ifdef D_DBG_SMALLTIMES
time = (*(SPfrontEnd->IFseconds))();
#endif
error = CKTacLoad(ckt);
#ifdef D_DBG_SMALLTIMES
time = (*(SPfrontEnd->IFseconds))() - time;
printf("Time for CKTacLoad: %g seconds \n", time);
#endif
if (error) return(error);
#ifdef D_DBG_SMALLTIMES
time = (*(SPfrontEnd->IFseconds))();
#endif
error = CKTdisto(ckt,D_RHSF1); /* sets up the RHS vector
for all inputs corresponding to F1 */
#ifdef D_DBG_SMALLTIMES
time = (*(SPfrontEnd->IFseconds))() - time;
printf("Time outside DISTO_RHSFIX: %g seconds \n", time);
#endif
if (error) return(error);
#ifdef D_DBG_SMALLTIMES
time = (*(SPfrontEnd->IFseconds))();
#endif
error = NIdIter(ckt);
#ifdef D_DBG_SMALLTIMES
time = (*(SPfrontEnd->IFseconds))() - time;
printf("Time for NIdIter: %g seconds \n", time);
#endif
if (error) return(error);
DISswap(&(ckt->CKTrhsOld),&(job->r1H1ptr));
DISswap(&(ckt->CKTirhsOld),&(job->i1H1ptr));
ckt->CKTomega *= 2;
error = CKTacLoad(ckt);
if (error) return(error);
#ifdef D_DBG_SMALLTIMES
time = (*(SPfrontEnd->IFseconds))();
#endif
error = CKTdisto(ckt,D_TWOF1);
#ifdef D_DBG_SMALLTIMES
time = (*(SPfrontEnd->IFseconds))() - time;
printf("Time outside D_TWOF1: %g seconds \n", time);
#endif
if (error) return(error);
error = NIdIter(ckt);
if (error) return(error);
DISswap(&(ckt->CKTrhsOld),&(job->r2H11ptr));
DISswap(&(ckt->CKTirhsOld),&(job->i2H11ptr));
if (! (job->Df2wanted ))
{
ckt->CKTomega = 3 * job->Domega1;
error = CKTacLoad(ckt);
if (error) return(error);
#ifdef D_DBG_SMALLTIMES
time = (*(SPfrontEnd->IFseconds))();
#endif
error = CKTdisto(ckt,D_THRF1);
#ifdef D_DBG_SMALLTIMES
time = (*(SPfrontEnd->IFseconds))() - time;
printf("Time outside D_THRF1: %g seconds \n", time);
#endif
if (error) return(error);
error = NIdIter(ckt);
if (error) return(error);
DISswap(&(ckt->CKTrhsOld),&(job->r3H11ptr));
DISswap(&(ckt->CKTirhsOld),&(job->i3H11ptr));
}
else if (job->Df2given)
{
/*
ckt->CKTomega = job->Domega1 - omegadelta;
job->Domega2 = ckt->CKTomega;
*/
ckt->CKTomega = job->Domega2;
error = CKTacLoad(ckt);
if (error) return(error);
#ifdef D_DBG_SMALLTIMES
time = (*(SPfrontEnd->IFseconds))();
#endif
error = CKTdisto(ckt,D_RHSF2);
#ifdef D_DBG_SMALLTIMES
time = (*(SPfrontEnd->IFseconds))() - time;
printf("Time outside DISTO_RHSFIX: %g seconds \n", time);
#endif
if (error) return(error);
error = NIdIter(ckt);
if (error) return(error);
DISswap(&(ckt->CKTrhsOld),&(job->r1H2ptr));
DISswap(&(ckt->CKTirhsOld),&(job->i1H2ptr));
ckt->CKTomega = job->Domega1 +
job->Domega2;
error = CKTacLoad(ckt);
if (error) return(error);
#ifdef D_DBG_SMALLTIMES
time = (*(SPfrontEnd->IFseconds))();
#endif
error = CKTdisto(ckt,D_F1PF2);
#ifdef D_DBG_SMALLTIMES
time = (*(SPfrontEnd->IFseconds))() - time;
printf("Time outside D_F1PF2: %g seconds \n", time);
#endif
if (error) return(error);
error = NIdIter(ckt);
if (error) return(error);
DISswap(&(ckt->CKTrhsOld),&(job->r2H12ptr));
DISswap(&(ckt->CKTirhsOld),&(job->i2H12ptr));
ckt->CKTomega = job->Domega1 -
job->Domega2;
error = CKTacLoad(ckt);
if (error) return(error);
#ifdef D_DBG_SMALLTIMES
time = (*(SPfrontEnd->IFseconds))();
#endif
error = CKTdisto(ckt,D_F1MF2);
#ifdef D_DBG_SMALLTIMES
time = (*(SPfrontEnd->IFseconds))() - time;
printf("Time outside D_F1MF2: %g seconds \n", time);
#endif
if (error) return(error);
error = NIdIter(ckt);
if (error) return(error);
DISswap(&(ckt->CKTrhsOld),&(job->r2H1m2ptr));
DISswap(&(ckt->CKTirhsOld),&(job->i2H1m2ptr));
ckt->CKTomega = 2*job->Domega1 -
job->Domega2;
error = CKTacLoad(ckt);
if (error) return(error);
#ifdef D_DBG_SMALLTIMES
time = (*(SPfrontEnd->IFseconds))();
#endif
error = CKTdisto(ckt,D_2F1MF2);
#ifdef D_DBG_SMALLTIMES
time = (*(SPfrontEnd->IFseconds))() - time;
printf("Time outside D_2F1MF2: %g seconds \n", time);
#endif
if (error) return(error);
error = NIdIter(ckt);
if (error) return(error);
DISswap(&(ckt->CKTrhsOld),&(job->r3H1m2ptr));
DISswap(&(ckt->CKTirhsOld),&(job->i3H1m2ptr));
}
else
{
errMsg = MALLOC(strlen(nof2src)+1);
strcpy(errMsg,nof2src);
return(E_NOF2SRC);
}
DmemAlloc( &(job->r1H1stor[displacement]),size);
DISswap(&(job->r1H1stor[displacement]),&(job->r1H1ptr));
job->r1H1stor[displacement][0]=freq;
DmemAlloc( &(job->r2H11stor[displacement]),size);
DISswap(&(job->r2H11stor[displacement]),&((job->r2H11ptr)));
job->r2H11stor[displacement][0]=freq;
DmemAlloc( &(job->i1H1stor[displacement]),size);
DISswap(&(job->i1H1stor[displacement]),&((job->i1H1ptr)));
job->i1H1stor[displacement][0]=0.0;
DmemAlloc( &(job->i2H11stor[displacement]),size);
DISswap(&(job->i2H11stor[displacement]),&((job->i2H11ptr)));
job->i2H11stor[displacement][0]=0.0;
if (! (job->Df2wanted))
{
DmemAlloc( &(job->r3H11stor[displacement]),size);
DISswap(&(job->r3H11stor[displacement]),&((job->r3H11ptr)));
job->r3H11stor[displacement][0]=freq;
DmemAlloc( &(job->i3H11stor[displacement]),size);
DISswap(&(job->i3H11stor[displacement]),&((job->i3H11ptr)));
job->i3H11stor[displacement][0]=0.0;
} else {
DmemAlloc( &(job->r1H2stor[displacement]),size);
DISswap(&(job->r1H2stor[displacement]),&((job->r1H2ptr)));
job->r1H2stor[displacement][0]=freq;
DmemAlloc( &(job->r2H12stor[displacement]),size);
DISswap(&(job->r2H12stor[displacement]),&((job->r2H12ptr)));
job->r2H12stor[displacement][0]=freq;
DmemAlloc( &(job->r2H1m2stor[displacement]),size);
DISswap(&(job->r2H1m2stor[displacement]),&((job->r2H1m2ptr)));
job->r2H1m2stor[displacement][0]=freq;
DmemAlloc( &(job->r3H1m2stor[displacement]),size);
DISswap(&(job->r3H1m2stor[displacement]),&((job->r3H1m2ptr)));
job->r3H1m2stor[displacement][0]=freq;
DmemAlloc( &(job->i1H2stor[displacement]),size);
DISswap(&(job->i1H2stor[displacement]),&((job->i1H2ptr)));
job->i1H2stor[displacement][0]=0.0;
DmemAlloc( &(job->i2H12stor[displacement]),size);
DISswap(&(job->i2H12stor[displacement]),&((job->i2H12ptr)));
job->i2H12stor[displacement][0]=0.0;
DmemAlloc( &(job->i2H1m2stor[displacement]),size);
DISswap(&(job->i2H1m2stor[displacement]),&((job->i2H1m2ptr)));
job->i2H1m2stor[displacement][0]=0.0;
DmemAlloc( &(job->i3H1m2stor[displacement]),size);
DISswap(&(job->i3H1m2stor[displacement]),&((job->i3H1m2ptr)));
job->i3H1m2stor[displacement][0]=0.0;
}
displacement++;
switch(job->DstepType) {
case DECADE:
case OCTAVE:
freq *= job->DfreqDelta;
if(job->DfreqDelta==1) goto endsweep;
break;
case LINEAR:
freq += job->DfreqDelta;
if(job->DfreqDelta==0) goto endsweep;
break;
default:
return(E_INTERN);
}
}
#ifdef D_DBG_BLOCKTIMES
time1 = (*(SPfrontEnd->IFseconds))() - time1;
printf("Time inside frequency loop: %g seconds \n", time1);
#endif
endsweep:
/* output routines to process the H's and output actual ckt variable
values */
#ifdef D_DBG_BLOCKTIMES
time1 = (*(SPfrontEnd->IFseconds))();
#endif
if (! job->Df2wanted) {
error = CKTnames(ckt,&numNames,&nameList);
if(error) return(error);
(*(SPfrontEnd->IFnewUid))((void *)ckt,&freqUid,(IFuid)NULL,
"frequency", UID_OTHER,(void **)NULL);
(*(SPfrontEnd->OUTpBeginPlot))((void *)ckt,
(void*)ckt->CKTcurJob,"DISTORTION - 2nd harmonic",
freqUid,IF_REAL, numNames,nameList,IF_COMPLEX,&acPlot);
if (job->DstepType != LINEAR) {
(*(SPfrontEnd->OUTattributes))((void *)acPlot,NULL,
OUT_SCALE_LOG, NULL);
}
for (i=0; i< displacement ; i++)
{
DkerProc(D_TWOF1,*(job->r2H11stor + i),
*(job->i2H11stor + i),
size, job);
ckt->CKTrhsOld = *((job->r2H11stor) + i);
ckt->CKTirhsOld = *((job->i2H11stor) + i);
error = CKTacDump(ckt,ckt->CKTrhsOld[0],acPlot);
if(error) return(error);
}
(*(SPfrontEnd->OUTendPlot))(acPlot);
error = CKTnames(ckt,&numNames,&nameList);
if(error) return(error);
(*(SPfrontEnd->IFnewUid))((void *)ckt,&freqUid,(IFuid)NULL,
"frequency", UID_OTHER,(void **)NULL);
(*(SPfrontEnd->OUTpBeginPlot))((void *)ckt,
(void*)ckt->CKTcurJob,"DISTORTION - 3rd harmonic",freqUid,IF_REAL,
numNames,nameList,IF_COMPLEX,&acPlot);
for (i=0; i< displacement ; i++)
{
DkerProc(D_THRF1,*(job->r3H11stor + i),
*(job->i3H11stor + i),
size, job);
ckt->CKTrhsOld = *((job->r3H11stor) + i);
ckt->CKTirhsOld = *((job->i3H11stor) + i);
error = CKTacDump(ckt,ckt->CKTrhsOld[0],acPlot);
}
(*(SPfrontEnd->OUTendPlot))(acPlot);
} else {
error = CKTnames(ckt,&numNames,&nameList);
if(error) return(error);
(*(SPfrontEnd->IFnewUid))((void *)ckt,&freqUid,(IFuid)NULL,
"frequency", UID_OTHER,(void **)NULL);
(*(SPfrontEnd->OUTpBeginPlot))((void *)ckt,
(void*)ckt->CKTcurJob,"DISTORTION - IM: f1+f2",freqUid,IF_REAL,
numNames,nameList,IF_COMPLEX,&acPlot);
for (i=0; i< displacement ; i++)
{
DkerProc(D_F1PF2,*(job->r2H12stor + i),
*(job->i2H12stor + i),
size, job);
ckt->CKTrhsOld = *((job->r2H12stor) + i);
ckt->CKTirhsOld = *((job->i2H12stor) + i);
error = CKTacDump(ckt,ckt->CKTrhsOld[0],acPlot);
if(error) return(error);
}
(*(SPfrontEnd->OUTendPlot))(acPlot);
error = CKTnames(ckt,&numNames,&nameList);
if(error) return(error);
(*(SPfrontEnd->IFnewUid))((void *)ckt,&freqUid,(IFuid)NULL,
"frequency", UID_OTHER,(void **)NULL);
(*(SPfrontEnd->OUTpBeginPlot))((void *)ckt,
(void*)ckt->CKTcurJob,"DISTORTION - IM: f1-f2",freqUid,IF_REAL,
numNames,nameList,IF_COMPLEX,&acPlot);
for (i=0; i< displacement ; i++)
{
DkerProc(D_F1MF2,
*(job->r2H1m2stor + i),
*(job->i2H1m2stor + i),
size, job);
ckt->CKTrhsOld = *((job->r2H1m2stor) + i);
ckt->CKTirhsOld = *((job->i2H1m2stor) + i);
error = CKTacDump(ckt,ckt->CKTrhsOld[0],acPlot);
if(error) return(error);
}
(*(SPfrontEnd->OUTendPlot))(acPlot);
error = CKTnames(ckt,&numNames,&nameList);
if(error) return(error);
(*(SPfrontEnd->IFnewUid))((void *)ckt,&freqUid,(IFuid)NULL,
"frequency", UID_OTHER,(void **)NULL);
(*(SPfrontEnd->OUTpBeginPlot))((void *)ckt,
(void*)ckt->CKTcurJob,"DISTORTION - IM: 2f1-f2",freqUid,IF_REAL,
numNames,nameList,IF_COMPLEX,&acPlot);
for (i=0; i< displacement ; i++)
{
DkerProc(D_2F1MF2,
*(job->r3H1m2stor + i),
*(job->i3H1m2stor + i),
size, job);
ckt->CKTrhsOld = *((job->r3H1m2stor) + i);
ckt->CKTirhsOld = *((job->i3H1m2stor) + i);
error = CKTacDump(ckt,ckt->CKTrhsOld[0],acPlot);
if(error) return(error);
}
(*(SPfrontEnd->OUTendPlot))(acPlot);
}
FREE(job->r1H1ptr);
FREE(job->i1H1ptr);
FREE(job->r2H11ptr);
FREE(job->i2H11ptr);
FREE(job->r1H1stor);
FREE(job->i1H1stor);
FREE(job->r2H11stor);
FREE(job->i2H11stor);
if (! (job->Df2wanted))
{
FREE(job->r3H11ptr);
FREE(job->i3H11ptr);
FREE(job->i3H11stor);
FREE(job->r3H11stor);
}
else {
FREE(job->r2H1m2ptr);
FREE(job->r3H1m2ptr);
FREE(job->r1H2ptr);
FREE(job->i1H2ptr);
FREE(job->r2H12ptr);
FREE(job->i2H12ptr);
FREE(job->i2H1m2ptr);
FREE(job->i3H1m2ptr);
FREE(job->r1H2stor);
FREE(job->r2H12stor);
FREE(job->r2H1m2stor);
FREE(job->r3H1m2stor);
FREE(job->i1H2stor);
FREE(job->i2H12stor);
FREE(job->i2H1m2stor);
FREE(job->i3H1m2stor);
}
#ifdef D_DBG_BLOCKTIMES
time1 = (*(SPfrontEnd->IFseconds))() - time1;
printf("Time for output and deallocation: %g seconds \n", time1);
#endif
return(OK);
}

View File

@ -1,102 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1988 Jaijeet S Roychowdhury
**********/
#include "ngspice.h"
#include "cktdefs.h"
#include "sperror.h"
#include "distodef.h"
int
DkerProc(int type, double *rPtr, double *iPtr, int size, DISTOAN *job)
{
int i;
switch(type) {
case D_F1:
for (i=1;i<=size;i++)
{
iPtr[i] *= 2.0; /* convert to sinusoid amplitude */
rPtr[i] *= 2.0;
}
break;
case D_F2:
for (i=1;i<=size;i++)
{
rPtr[i] *= 2.0;
iPtr[i] *= 2.0;
}
break;
case D_TWOF1:
for (i=1;i<=size;i++)
{
iPtr[i] *= 2.0;
rPtr[i] *= 2.0;
}
break;
case D_THRF1:
for (i=1;i<=size;i++)
{
iPtr[i] *= 2.0;
rPtr[i] *= 2.0;
}
break;
case D_F1PF2:
for (i=1;i<=size;i++)
{
iPtr[i] *= 4.0;
rPtr[i] *= 4.0;
}
break;
case D_F1MF2:
for (i=1;i<=size;i++)
{
iPtr[i] *= 4.0;
rPtr[i] *= 4.0;
}
break;
case D_2F1MF2:
for (i=1;i<=size;i++)
{
iPtr[i] *= 6.0;
rPtr[i] *= 6.0;
}
break;
default:
return(E_BADPARM);
}
return(OK);
}

View File

@ -1,673 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1988 Jaijeet S Roychowdhury
**********/
#include "ngspice.h"
#include "distodef.h"
/*
* all subFns are local to this file so they need not be renamed to
* the awful 7 letter standard; however, for reasons of uniformity,
* they are being renamed, losing all readability in the process.
* the renaming convention is as follows:
* example: 3v3F1m2
* 3v => 3 variable term xyz
* 2F1m2 => Two F1 minus F2
* therefore the old name would be : S3v3F1minusF2
* for the imaginary sub functions, the v is replaced by an i
*
*/
double
S2v2F1(double cxy, double r1h1x, double i1h1x, double r1h1y, double i1h1y)
/* 5 arguments */
{
return(cxy*(r1h1x*r1h1y - i1h1x*i1h1y));
}
double
S2i2F1(double cxy, double r1h1x, double i1h1x, double r1h1y, double i1h1y)
/* 5 arguments */
{
return(cxy*(r1h1x*i1h1y + i1h1x*r1h1y));
}
double
S2v3F1(double cxy, double r1h1x, double i1h1x, double r1h1y, double i1h1y, double r2h11x, double i2h11x, double r2h11y, double i2h11y)
/* 9 arguments */
{
return(cxy*(r1h1x*r2h11y - i1h1x*i2h11y + r1h1y*r2h11x - i1h1y*
i2h11x));
}
double
S2i3F1(double cxy, double r1h1x, double i1h1x, double r1h1y, double i1h1y, double r2h11x, double i2h11x, double r2h11y, double i2h11y)
/* 9 arguments */
{
return(cxy*(r1h1x*i2h11y + i1h1x*r2h11y + r1h1y*i2h11x + i1h1y*
r2h11x));
}
double
S2vF12(double cxy, double r1h1x, double i1h1x, double r1h1y, double i1h1y, double r1h2x, double i1h2x, double r1h2y, double i1h2y)
/* 9 arguments */
{
return(cxy*(r1h1x*r1h2y - i1h1x*i1h2y + r1h1y*r1h2x - i1h1y*i1h2x));
}
double
S2iF12(double cxy, double r1h1x, double i1h1x, double r1h1y, double i1h1y, double r1h2x, double i1h2x, double r1h2y, double i1h2y)
/* 9 arguments */
{
return(cxy*(r1h1x*i1h2y + i1h1x*r1h2y + r1h1y*i1h2x + i1h1y*r1h2x));
}
double
S2v2F12(double cxy, double r1h1x, double i1h1x, double r1h1y, double i1h1y, double r1h2x, double i1h2x, double r1h2y, double i1h2y, double r2h11x, double i2h11x, double r2h11y, double i2h11y, double h2f1f2x, double ih2f1f2x, double h2f1f2y, double ih2f1f2y)
/* 17 arguments */
{
return ( cxy * (
2*(r1h1x*h2f1f2y - i1h1x*ih2f1f2y
+r1h1y*h2f1f2x - i1h1y*ih2f1f2x)
+ r1h2x*r2h11y - i1h2x*i2h11y
+ r1h2y*r2h11x - i1h2y*i2h11x
));
}
double
S2i2F12(double cxy, double r1h1x, double i1h1x, double r1h1y, double i1h1y, double r1h2x, double i1h2x, double r1h2y, double i1h2y, double r2h11x, double i2h11x, double r2h11y, double i2h11y, double h2f1f2x, double ih2f1f2x, double h2f1f2y, double ih2f1f2y)
/* 17 arguments */
{
return ( cxy * (
2*(r1h1x*ih2f1f2y + i1h1x*h2f1f2y
+r1h1y*ih2f1f2x + i1h1y*h2f1f2x)
+ r1h2x*i2h11y + i1h2x*r2h11y
+ r1h2y*i2h11x + i1h2y*r2h11x
));
}
double
S3v3F1(double cxyz, double r1h1x, double i1h1x, double r1h1y, double i1h1y, double r1h1z, double i1h1z)
/* 7 arguments */
{
return( cxyz * (
(r1h1x*r1h1y - i1h1x*i1h1y)*r1h1z - (i1h1x*r1h1y + r1h1x*i1h1y)*i1h1z
));
}
double
S3i3F1(double cxyz, double r1h1x, double i1h1x, double r1h1y, double i1h1y, double r1h1z, double i1h1z)
/* 7 arguments */
{
return( cxyz * (
(r1h1x*r1h1y - i1h1x*i1h1y)*i1h1z + (i1h1x*r1h1y + r1h1x*i1h1y)*r1h1z
));
}
double
S3v2F12(double cxyz, double r1h1x, double i1h1x, double r1h1y, double i1h1y, double r1h1z, double i1h1z, double r1h2x, double i1h2x, double r1h2y, double i1h2y, double r1h2z, double i1h2z)
/* 13 arguments */
{
return ( cxyz * (
(r1h1x*r1h1y - i1h1x*i1h1y)*r1h2z - (i1h1x*r1h1y + r1h1x*i1h1y)*i1h2z
+
(r1h1x*r1h1z - i1h1x*i1h1z)*r1h2y - (i1h1x*r1h1z + r1h1x*i1h1z)*i1h2y
+
(r1h1z*r1h1y - i1h1z*i1h1y)*r1h2x - (i1h1z*r1h1y + r1h1z*i1h1y)*i1h2x
));
}
double
S3i2F12(double cxyz, double r1h1x, double i1h1x, double r1h1y, double i1h1y, double r1h1z, double i1h1z, double r1h2x, double i1h2x, double r1h2y, double i1h2y, double r1h2z, double i1h2z)
/* 13 arguments */
{
return ( cxyz * (
(r1h1x*r1h1y - i1h1x*i1h1y)*i1h2z + (i1h1x*r1h1y + r1h1x*i1h1y)*r1h2z
+
(r1h1x*r1h1z - i1h1x*i1h1z)*i1h2y + (i1h1x*r1h1z + r1h1x*i1h1z)*r1h2y
+
(r1h1z*r1h1y - i1h1z*i1h1y)*i1h2x + (i1h1z*r1h1y + r1h1z*i1h1y)*r1h2x
));
}
/* the load functions */
/* also renamed... */
double
DFn2F1(double cxx, double cyy, double czz, double cxy, double cyz, double cxz, double r1h1x, double i1h1x, double r1h1y, double i1h1y, double r1h1z, double i1h1z)
/* 12 variables */
{
double temp;
temp = S2v2F1(cxx,r1h1x,i1h1x,r1h1x,i1h1x) +
S2v2F1(cyy,r1h1y,i1h1y,r1h1y,i1h1y) +
S2v2F1(czz,r1h1z,i1h1z,r1h1z,i1h1z) +
S2v2F1(cxy,r1h1x,i1h1x,r1h1y,i1h1y) +
S2v2F1(cyz,r1h1y,i1h1y,r1h1z,i1h1z) +
S2v2F1(cxz,r1h1x,i1h1x,r1h1z,i1h1z);
return(temp);
}
double
DFi2F1(double cxx, double cyy, double czz, double cxy, double cyz, double cxz, double r1h1x, double i1h1x, double r1h1y, double i1h1y, double r1h1z, double i1h1z)
/* 12 variables */
{
double temp;
temp = S2i2F1(cxx,r1h1x,i1h1x,r1h1x,i1h1x) +
S2i2F1(cyy,r1h1y,i1h1y,r1h1y,i1h1y) +
S2i2F1(czz,r1h1z,i1h1z,r1h1z,i1h1z) +
S2i2F1(cxy,r1h1x,i1h1x,r1h1y,i1h1y) +
S2i2F1(cyz,r1h1y,i1h1y,r1h1z,i1h1z) +
S2i2F1(cxz,r1h1x,i1h1x,r1h1z,i1h1z);
return(temp);
}
double
DFn3F1(double cxx, double cyy, double czz, double cxy, double cyz, double cxz, double cxxx, double cyyy, double czzz, double cxxy, double cxxz, double cxyy, double cyyz, double cxzz, double cyzz, double cxyz, double r1h1x, double i1h1x, double r1h1y, double i1h1y, double r1h1z, double i1h1z, double r2h11x, double i2h11x, double r2h11y, double i2h11y, double r2h11z, double i2h11z)
/* 28 args - 16 + 6 + 6 */
{
double temp;
temp = S2v3F1(cxx,r1h1x,i1h1x,r1h1x,i1h1x,r2h11x,i2h11x,r2h11x,i2h11x)
+S2v3F1(cyy,r1h1y,i1h1y,r1h1y,i1h1y,r2h11y,i2h11y,r2h11y,i2h11y)
+S2v3F1(czz,r1h1z,i1h1z,r1h1z,i1h1z,r2h11z,i2h11z,r2h11z,i2h11z);
temp +=
S2v3F1(cxy,r1h1x,i1h1x,r1h1y,i1h1y,r2h11x,i2h11x,r2h11y,i2h11y)
+S2v3F1(cyz,r1h1y,i1h1y,r1h1z,i1h1z,r2h11y,i2h11y,r2h11z,i2h11z)
+S2v3F1(cxz,r1h1x,i1h1x,r1h1z,i1h1z,r2h11x,i2h11x,r2h11z,i2h11z)
+S3v3F1(cxxx,r1h1x,i1h1x,r1h1x,i1h1x,r1h1x,i1h1x);
temp +=
S3v3F1(cyyy,r1h1y,i1h1y,r1h1y,i1h1y,r1h1y,i1h1y)
+S3v3F1(czzz,r1h1z,i1h1z,r1h1z,i1h1z,r1h1z,i1h1z)
+S3v3F1(cxxy,r1h1x,i1h1x,r1h1x,i1h1x,r1h1y,i1h1y)
+S3v3F1(cxxz,r1h1x,i1h1x,r1h1x,i1h1x,r1h1z,i1h1z)
+S3v3F1(cxyy,r1h1x,i1h1x,r1h1y,i1h1y,r1h1y,i1h1y);
temp +=
S3v3F1(cyyz,r1h1y,i1h1y,r1h1y,i1h1y,r1h1z,i1h1z)
+S3v3F1(cxzz,r1h1x,i1h1x,r1h1z,i1h1z,r1h1z,i1h1z)
+S3v3F1(cyzz,r1h1y,i1h1y,r1h1z,i1h1z,r1h1z,i1h1z)
+S3v3F1(cxyz,r1h1x,i1h1x,r1h1y,i1h1y,r1h1z,i1h1z);
return(temp);
}
double
DFi3F1(double cxx, double cyy, double czz, double cxy, double cyz, double cxz, double cxxx, double cyyy, double czzz, double cxxy, double cxxz, double cxyy, double cyyz, double cxzz, double cyzz, double cxyz, double r1h1x, double i1h1x, double r1h1y, double i1h1y, double r1h1z, double i1h1z, double r2h11x, double i2h11x, double r2h11y, double i2h11y, double r2h11z, double i2h11z)
/* 28 args - 10 + 6 + 6 */
{
double temp;
temp = S2i3F1(cxx,r1h1x,i1h1x,r1h1x,i1h1x,r2h11x,i2h11x,r2h11x,i2h11x)
+S2i3F1(cyy,r1h1y,i1h1y,r1h1y,i1h1y,r2h11y,i2h11y,r2h11y,i2h11y)
+S2i3F1(czz,r1h1z,i1h1z,r1h1z,i1h1z,r2h11z,i2h11z,r2h11z,i2h11z)
+S2i3F1(cxy,r1h1x,i1h1x,r1h1y,i1h1y,r2h11x,i2h11x,r2h11y,i2h11y);
temp +=
S2i3F1(cyz,r1h1y,i1h1y,r1h1z,i1h1z,r2h11y,i2h11y,r2h11z,i2h11z)
+S2i3F1(cxz,r1h1x,i1h1x,r1h1z,i1h1z,r2h11x,i2h11x,r2h11z,i2h11z)
+S3i3F1(cxxx,r1h1x,i1h1x,r1h1x,i1h1x,r1h1x,i1h1x)
+S3i3F1(cyyy,r1h1y,i1h1y,r1h1y,i1h1y,r1h1y,i1h1y);
temp +=
S3i3F1(czzz,r1h1z,i1h1z,r1h1z,i1h1z,r1h1z,i1h1z)
+S3i3F1(cxxy,r1h1x,i1h1x,r1h1x,i1h1x,r1h1y,i1h1y)
+S3i3F1(cxxz,r1h1x,i1h1x,r1h1x,i1h1x,r1h1z,i1h1z)
+S3i3F1(cxyy,r1h1x,i1h1x,r1h1y,i1h1y,r1h1y,i1h1y);
temp +=
S3i3F1(cyyz,r1h1y,i1h1y,r1h1y,i1h1y,r1h1z,i1h1z)
+S3i3F1(cxzz,r1h1x,i1h1x,r1h1z,i1h1z,r1h1z,i1h1z)
+S3i3F1(cyzz,r1h1y,i1h1y,r1h1z,i1h1z,r1h1z,i1h1z)
+S3i3F1(cxyz,r1h1x,i1h1x,r1h1y,i1h1y,r1h1z,i1h1z);
return(temp);
}
double
DFnF12(double cxx, double cyy, double czz, double cxy, double cyz, double cxz, double r1h1x, double i1h1x, double r1h1y, double i1h1y, double r1h1z, double i1h1z, double r1h2x, double i1h2x, double r1h2y, double i1h2y, double r1h2z, double i1h2z)
/* 18 args - 6 + 6 + 6 */
{
double temp;
temp = S2vF12(cxx,r1h1x,i1h1x,r1h1x,i1h1x,r1h2x,i1h2x,r1h2x,i1h2x)
+S2vF12(cyy,r1h1y,i1h1y,r1h1y,i1h1y,r1h2y,i1h2y,r1h2y,i1h2y)
+S2vF12(czz,r1h1z,i1h1z,r1h1z,i1h1z,r1h2z,i1h2z,r1h2z,i1h2z);
temp +=
S2vF12(cxy,r1h1x,i1h1x,r1h1y,i1h1y,r1h2x,i1h2x,r1h2y,i1h2y)
+S2vF12(cyz,r1h1y,i1h1y,r1h1z,i1h1z,r1h2y,i1h2y,r1h2z,i1h2z)
+S2vF12(cxz,r1h1x,i1h1x,r1h1z,i1h1z,r1h2x,i1h2x,r1h2z,i1h2z);
return(0.5*temp);
}
double
DFiF12(double cxx, double cyy, double czz, double cxy, double cyz, double cxz, double r1h1x, double i1h1x, double r1h1y, double i1h1y, double r1h1z, double i1h1z, double r1h2x, double i1h2x, double r1h2y, double i1h2y, double r1h2z, double i1h2z)
/* 18 args - 6 + 6 + 6 */
{
double temp;
temp = S2iF12(cxx,r1h1x,i1h1x,r1h1x,i1h1x,r1h2x,i1h2x,r1h2x,i1h2x)
+S2iF12(cyy,r1h1y,i1h1y,r1h1y,i1h1y,r1h2y,i1h2y,r1h2y,i1h2y)
+S2iF12(czz,r1h1z,i1h1z,r1h1z,i1h1z,r1h2z,i1h2z,r1h2z,i1h2z);
temp +=
S2iF12(cxy,r1h1x,i1h1x,r1h1y,i1h1y,r1h2x,i1h2x,r1h2y,i1h2y)
+S2iF12(cyz,r1h1y,i1h1y,r1h1z,i1h1z,r1h2y,i1h2y,r1h2z,i1h2z)
+S2iF12(cxz,r1h1x,i1h1x,r1h1z,i1h1z,r1h2x,i1h2x,r1h2z,i1h2z);
return(temp*0.5); /* divided by two to scale down */
}
double
DFn2F12(DpassStr *p)
/* 40 vars - 16 + 6 + 6 + 6 + 6 */
/*
* a structure because a standard C compiler can handle only
* 32 variables.
*
*/
{
double temp;
temp = S2v2F12(p->cxx,p->r1h1x,p->i1h1x,
p->r1h1x,p->i1h1x,
p->r1h2x,p->i1h2x,
p->r1h2x,p->i1h2x,
p->r2h11x,p->i2h11x,
p->r2h11x,p->i2h11x,
p->h2f1f2x,p->ih2f1f2x,
p->h2f1f2x,p->ih2f1f2x);
temp +=
S2v2F12(p->cyy,p->r1h1y,p->i1h1y,
p->r1h1y,p->i1h1y,
p->r1h2y,p->i1h2y,
p->r1h2y,p->i1h2y,
p->r2h11y,p->i2h11y,
p->r2h11y,p->i2h11y,
p->h2f1f2y,p->ih2f1f2y,
p->h2f1f2y,p->ih2f1f2y);
temp +=
S2v2F12(p->czz,p->r1h1z,p->i1h1z,
p->r1h1z,p->i1h1z,
p->r1h2z,p->i1h2z,
p->r1h2z,p->i1h2z,
p->r2h11z,p->i2h11z,
p->r2h11z,p->i2h11z,
p->h2f1f2z,p->ih2f1f2z,
p->h2f1f2z,p->ih2f1f2z);
temp +=
S2v2F12(p->cxy,p->r1h1x,p->i1h1x,
p->r1h1y,p->i1h1y,
p->r1h2x,p->i1h2x,
p->r1h2y,p->i1h2y,
p->r2h11x,p->i2h11x,
p->r2h11y,p->i2h11y,
p->h2f1f2x,p->ih2f1f2x,
p->h2f1f2y,p->ih2f1f2y);
temp +=
S2v2F12(p->cyz,p->r1h1y,p->i1h1y,
p->r1h1z,p->i1h1z,
p->r1h2y,p->i1h2y,
p->r1h2z,p->i1h2z,
p->r2h11y,p->i2h11y,
p->r2h11z,p->i2h11z,
p->h2f1f2y,p->ih2f1f2y,
p->h2f1f2z,p->ih2f1f2z);
temp +=
S2v2F12(p->cxz,p->r1h1x,p->i1h1x,
p->r1h1z,p->i1h1z,
p->r1h2x,p->i1h2x,
p->r1h2z,p->i1h2z,
p->r2h11x,p->i2h11x,
p->r2h11z,p->i2h11z,
p->h2f1f2x,p->ih2f1f2x,
p->h2f1f2z,p->ih2f1f2z);
temp +=
S3v2F12(p->cxxx,p->r1h1x,
p->i1h1x,p->r1h1x,p->i1h1x,p->r1h1x,p->i1h1x,
p->r1h2x,p->i1h2x,
p->r1h2x,p->i1h2x,p->r1h2x,p->i1h2x)
+S3v2F12(p->cyyy,p->r1h1y,
p->i1h1y,p->r1h1y,p->i1h1y,p->r1h1y,p->i1h1y,
p->r1h2y,p->i1h2y,
p->r1h2y,p->i1h2y,p->r1h2y,p->i1h2y);
temp +=
S3v2F12(p->czzz,p->r1h1z,
p->i1h1z,p->r1h1z,p->i1h1z,p->r1h1z,p->i1h1z,
p->r1h2z,p->i1h2z,
p->r1h2z,p->i1h2z,p->r1h2z,p->i1h2z)
+S3v2F12(p->cxxy,p->r1h1x,
p->i1h1x,p->r1h1x,p->i1h1x,p->r1h1y,p->i1h1y,
p->r1h2x,p->i1h2x,
p->r1h2x,p->i1h2x,p->r1h2y,p->i1h2y);
temp +=
S3v2F12(p->cxxz,p->r1h1x,
p->i1h1x,p->r1h1x,p->i1h1x,p->r1h1z,p->i1h1z,
p->r1h2x,p->i1h2x,
p->r1h2x,p->i1h2x,p->r1h2z,p->i1h2z)
+S3v2F12(p->cxyy,p->r1h1x,
p->i1h1x,p->r1h1y,p->i1h1y,p->r1h1y,p->i1h1y,
p->r1h2x,p->i1h2x,
p->r1h2y,p->i1h2y,p->r1h2y,p->i1h2y);
temp +=
S3v2F12(p->cyyz,p->r1h1y,
p->i1h1y,p->r1h1y,p->i1h1y,p->r1h1z,p->i1h1z,
p->r1h2y,p->i1h2y,
p->r1h2y,p->i1h2y,p->r1h2z,p->i1h2z)
+S3v2F12(p->cxzz,p->r1h1x,
p->i1h1x,p->r1h1z,p->i1h1z,p->r1h1z,p->i1h1z,
p->r1h2x,p->i1h2x,
p->r1h2z,p->i1h2z,p->r1h2z,p->i1h2z);
temp +=
S3v2F12(p->cyzz,p->r1h1y,
p->i1h1y,p->r1h1z,p->i1h1z,p->r1h1z,p->i1h1z,
p->r1h2y,p->i1h2y,
p->r1h2z,p->i1h2z,p->r1h2z,p->i1h2z)
+S3v2F12(p->cxyz,p->r1h1x,
p->i1h1x,p->r1h1y,p->i1h1y,p->r1h1z,p->i1h1z,
p->r1h2x,p->i1h2x,
p->r1h2y,p->i1h2y,p->r1h2z,p->i1h2z);
return(temp/3.); /* divided by 3 to get kernel (otherwise we get 3*kernel) */
}
double
DFi2F12(DpassStr *p)
/* 40 vars - 16 + 6 + 6 + 6 + 6 */
{
double temp;
temp = S2i2F12(p->cxx,p->r1h1x,p->i1h1x,
p->r1h1x,p->i1h1x,
p->r1h2x,p->i1h2x,
p->r1h2x,p->i1h2x,
p->r2h11x,p->i2h11x,
p->r2h11x,p->i2h11x,
p->h2f1f2x,p->ih2f1f2x,
p->h2f1f2x,p->ih2f1f2x);
temp +=
S2i2F12(p->cyy,p->r1h1y,p->i1h1y,
p->r1h1y,p->i1h1y,
p->r1h2y,p->i1h2y,
p->r1h2y,p->i1h2y,
p->r2h11y,p->i2h11y,
p->r2h11y,p->i2h11y,
p->h2f1f2y,p->ih2f1f2y,
p->h2f1f2y,p->ih2f1f2y);
temp +=
S2i2F12(p->czz,p->r1h1z,p->i1h1z,
p->r1h1z,p->i1h1z,
p->r1h2z,p->i1h2z,
p->r1h2z,p->i1h2z,
p->r2h11z,p->i2h11z,
p->r2h11z,p->i2h11z,
p->h2f1f2z,p->ih2f1f2z,
p->h2f1f2z,p->ih2f1f2z);
temp +=
S2i2F12(p->cxy,p->r1h1x,p->i1h1x,
p->r1h1y,p->i1h1y,
p->r1h2x,p->i1h2x,
p->r1h2y,p->i1h2y,
p->r2h11x,p->i2h11x,
p->r2h11y,p->i2h11y,
p->h2f1f2x,p->ih2f1f2x,
p->h2f1f2y,p->ih2f1f2y);
temp +=
S2i2F12(p->cyz,p->r1h1y,p->i1h1y,
p->r1h1z,p->i1h1z,
p->r1h2y,p->i1h2y,
p->r1h2z,p->i1h2z,
p->r2h11y,p->i2h11y,
p->r2h11z,p->i2h11z,
p->h2f1f2y,p->ih2f1f2y,
p->h2f1f2z,p->ih2f1f2z);
temp +=
S2i2F12(p->cxz,p->r1h1x,p->i1h1x,
p->r1h1z,p->i1h1z,
p->r1h2x,p->i1h2x,
p->r1h2z,p->i1h2z,
p->r2h11x,p->i2h11x,
p->r2h11z,p->i2h11z,
p->h2f1f2x,p->ih2f1f2x,
p->h2f1f2z,p->ih2f1f2z);
temp +=
S3i2F12(p->cxxx,p->r1h1x,
p->i1h1x,p->r1h1x,p->i1h1x,p->r1h1x,p->i1h1x,
p->r1h2x,p->i1h2x,
p->r1h2x,p->i1h2x,p->r1h2x,p->i1h2x);
temp +=
S3i2F12(p->cyyy,p->r1h1y,
p->i1h1y,p->r1h1y,p->i1h1y,p->r1h1y,p->i1h1y,
p->r1h2y,p->i1h2y,
p->r1h2y,p->i1h2y,p->r1h2y,p->i1h2y)
+S3i2F12(p->czzz,p->r1h1z,
p->i1h1z,p->r1h1z,p->i1h1z,p->r1h1z,p->i1h1z,
p->r1h2z,p->i1h2z,
p->r1h2z,p->i1h2z,p->r1h2z,p->i1h2z);
temp +=
S3i2F12(p->cxxy,p->r1h1x,
p->i1h1x,p->r1h1x,p->i1h1x,p->r1h1y,p->i1h1y,
p->r1h2x,p->i1h2x,
p->r1h2x,p->i1h2x,p->r1h2y,p->i1h2y)
+S3i2F12(p->cxxz,p->r1h1x,
p->i1h1x,p->r1h1x,p->i1h1x,p->r1h1z,p->i1h1z,
p->r1h2x,p->i1h2x,
p->r1h2x,p->i1h2x,p->r1h2z,p->i1h2z);
temp +=
S3i2F12(p->cxyy,p->r1h1x,
p->i1h1x,p->r1h1y,p->i1h1y,p->r1h1y,p->i1h1y,
p->r1h2x,p->i1h2x,
p->r1h2y,p->i1h2y,p->r1h2y,p->i1h2y)
+S3i2F12(p->cyyz,p->r1h1y,
p->i1h1y,p->r1h1y,p->i1h1y,p->r1h1z,p->i1h1z,
p->r1h2y,p->i1h2y,
p->r1h2y,p->i1h2y,p->r1h2z,p->i1h2z);
temp +=
S3i2F12(p->cxzz,p->r1h1x,
p->i1h1x,p->r1h1z,p->i1h1z,p->r1h1z,p->i1h1z,
p->r1h2x,p->i1h2x,
p->r1h2z,p->i1h2z,p->r1h2z,p->i1h2z);
temp += S3i2F12(p->cyzz,p->r1h1y,
p->i1h1y,p->r1h1z,p->i1h1z,p->r1h1z,p->i1h1z,
p->r1h2y,p->i1h2y,
p->r1h2z,p->i1h2z,p->r1h2z,p->i1h2z)
+S3i2F12(p->cxyz,p->r1h1x,
p->i1h1x,p->r1h1y,p->i1h1y,p->r1h1z,p->i1h1z,
p->r1h2x,p->i1h2x,
p->r1h2y,p->i1h2y,p->r1h2z,p->i1h2z);
return(temp/3.); /* divided by 3 to get kernel (otherwise we get 3*kernel) */
}
double
D1n2F1(double cxx, double r1h1x, double i1h1x)
/* 12 variables */
{
double temp;
temp = S2v2F1(cxx,r1h1x,i1h1x,r1h1x,i1h1x);
return(temp);
}
double
D1n3F1(double cxx, double cxxx, double r1h1x, double i1h1x, double r2h11x, double i2h11x)
{
double temp;
temp = S2v3F1(cxx,r1h1x,i1h1x,r1h1x,i1h1x,r2h11x,i2h11x,r2h11x,i2h11x)
+S3v3F1(cxxx,r1h1x,i1h1x,r1h1x,i1h1x,r1h1x,i1h1x);
return(temp);
}
double
D1nF12(double cxx, double r1h1x, double i1h1x, double r1h2x, double i1h2x)
/* 18 args - 6 + 6 + 6 */
{
double temp;
temp = S2vF12(cxx,r1h1x,i1h1x,r1h1x,i1h1x,r1h2x,i1h2x,r1h2x,i1h2x);
return(0.5*temp);
}
double
D1n2F12(double cxx, double cxxx, double r1h1x, double i1h1x, double r1h2x, double i1h2x, double r2h11x, double i2h11x, double h2f1f2x, double ih2f1f2x)
/* 40 vars - 16 + 6 + 6 + 6 + 6 */
{
double temp;
temp = S2v2F12(cxx,r1h1x,i1h1x,r1h1x,i1h1x,
r1h2x,i1h2x,r1h2x,i1h2x,
r2h11x,i2h11x,r2h11x,i2h11x,
h2f1f2x,ih2f1f2x,h2f1f2x,ih2f1f2x)
+S3v2F12(cxxx,r1h1x,i1h1x,r1h1x,i1h1x,r1h1x,i1h1x,
r1h2x,i1h2x,r1h2x,i1h2x,r1h2x,i1h2x);
return(temp/3.); /* divided by 3 to get kernel (otherwise we get 3*kernel) */
}
double
D1i2F1(double cxx, double r1h1x, double i1h1x)
/* 12 variables */
{
double temp;
temp = S2i2F1(cxx,r1h1x,i1h1x,r1h1x,i1h1x);
return(temp);
}
double
D1i3F1(double cxx, double cxxx, double r1h1x, double i1h1x, double r2h11x, double i2h11x)
{
double temp;
temp = S2i3F1(cxx,r1h1x,i1h1x,r1h1x,i1h1x,r2h11x,i2h11x,r2h11x,i2h11x)
+S3i3F1(cxxx,r1h1x,i1h1x,r1h1x,i1h1x,r1h1x,i1h1x);
return(temp);
}
double
D1iF12(double cxx, double r1h1x, double i1h1x, double r1h2x, double i1h2x)
/* 18 args - 6 + 6 + 6 */
{
double temp;
temp = S2iF12(cxx,r1h1x,i1h1x,r1h1x,i1h1x,r1h2x,i1h2x,r1h2x,i1h2x);
return(0.5*temp);
}
double
D1i2F12(double cxx, double cxxx, double r1h1x, double i1h1x, double r1h2x, double i1h2x, double r2h11x, double i2h11x, double h2f1f2x, double ih2f1f2x)
/* 40 vars - 16 + 6 + 6 + 6 + 6 */
{
double temp;
temp = S2i2F12(cxx,r1h1x,i1h1x,r1h1x,i1h1x,
r1h2x,i1h2x,r1h2x,i1h2x,
r2h11x,i2h11x,r2h11x,i2h11x,
h2f1f2x,ih2f1f2x,h2f1f2x,ih2f1f2x)
+S3i2F12(cxxx,r1h1x,i1h1x,r1h1x,i1h1x,r1h1x,i1h1x,
r1h2x,i1h2x,r1h2x,i1h2x,r1h2x,i1h2x);
return(temp/3.); /* divided by 3 to get kernel (otherwise we get 3*kernel) */
}

View File

@ -1,93 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1988 Jaijeet S Roychowdhury
**********/
#include "ngspice.h"
#include <stdio.h>
#include "ifsim.h"
#include "iferrmsg.h"
#include "cktdefs.h"
#include "distodef.h"
/* ARGSUSED */
int
DsetParm(CKTcircuit *ckt, void *anal, int which, IFvalue *value)
{
switch(which) {
case D_START:
if (value->rValue <= 0.0) {
errMsg = copy("Frequency of 0 is invalid");
((DISTOAN*)anal)->DstartF1 = 1.0;
return(E_PARMVAL);
}
((DISTOAN*)anal)->DstartF1 = value->rValue;
break;
case D_STOP:
if (value->rValue <= 0.0) {
errMsg = copy("Frequency of 0 is invalid");
((DISTOAN*)anal)->DstartF1 = 1.0;
return(E_PARMVAL);
}
((DISTOAN*)anal)->DstopF1 = value->rValue;
break;
case D_STEPS:
((DISTOAN*)anal)->DnumSteps = value->iValue;
break;
case D_DEC:
((DISTOAN*)anal)->DstepType = DECADE;
break;
case D_OCT:
((DISTOAN*)anal)->DstepType = OCTAVE;
break;
case D_LIN:
((DISTOAN*)anal)->DstepType = LINEAR;
break;
case D_F2OVRF1:
((DISTOAN*)anal)->Df2ovrF1 = value->rValue;
((DISTOAN*)anal)->Df2wanted = 1;
break;
default:
return(E_BADPARM);
}
return(OK);
}
static IFparm Dparms[] = {
{ "start", D_START, IF_SET|IF_REAL, "starting frequency" },
{ "stop", D_STOP, IF_SET|IF_REAL, "ending frequency" },
{ "numsteps", D_STEPS, IF_SET|IF_INTEGER, "number of frequencies" },
{ "dec", D_DEC, IF_SET|IF_FLAG, "step by decades" },
{ "oct", D_OCT, IF_SET|IF_FLAG, "step by octaves" },
{ "lin", D_LIN, IF_SET|IF_FLAG, "step linearly" },
{ "f2overf1", D_F2OVRF1, IF_SET|IF_REAL, "ratio of F2 to F1" },
};
SPICEanalysis DISTOinfo = {
{
"DISTO",
"Small signal distortion analysis",
sizeof(Dparms)/sizeof(IFparm),
Dparms
},
sizeof(DISTOAN),
FREQUENCYDOMAIN,
1,
DsetParm,
DaskQuest,
NULL,
DISTOan
};

View File

@ -1,76 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1987 Gary W. Ng
**********/
#include "ngspice.h"
#include <stdio.h>
#include "cktdefs.h"
#include "ifsim.h"
#include "iferrmsg.h"
#include "noisedef.h"
int
NaskQuest(CKTcircuit *ckt, void *anal, int which, IFvalue *value)
{
switch(which) {
case N_OUTPUT:
value->nValue = ((NOISEAN*)anal)->output;
break;
case N_OUTREF:
value->nValue = ((NOISEAN*)anal)->outputRef;
break;
case N_INPUT:
value->uValue = ((NOISEAN*)anal)->input;
break;
case N_DEC:
if(((NOISEAN*)anal)->NstpType == DECADE) {
value->iValue=1;
} else {
value->iValue=0;
}
break;
case N_OCT:
if(((NOISEAN*)anal)->NstpType == OCTAVE) {
value->iValue=1;
} else {
value->iValue=0;
}
break;
case N_LIN:
if(((NOISEAN*)anal)->NstpType == LINEAR) {
value->iValue=1;
} else {
value->iValue=0;
}
break;
case N_STEPS:
value->iValue = ((NOISEAN*)anal)->NnumSteps;
break;
case N_START:
value->rValue = ((NOISEAN*)anal)->NstartFreq;
break;
case N_STOP:
value->rValue = ((NOISEAN*)anal)->NstopFreq;
break;
case N_PTSPERSUM:
value->iValue = ((NOISEAN*)anal)->NStpsSm;
break;
default:
return(E_BADPARM);
}
return(OK);
}

View File

@ -1,51 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1987 Gary W. Ng
**********/
/*
* NevalSrc (noise, lnNoise, ckt, type, node1, node2, param)
* This routine evaluates the noise due to different physical
* phenomena. This includes the "shot" noise associated with dc
* currents in semiconductors and the "thermal" noise associated with
* resistance. Although semiconductors also display "flicker" (1/f)
* noise, the lack of a unified model requires us to handle it on a
* "case by case" basis. What we CAN provide, though, is the noise
* gain associated with the 1/f source.
*/
#include "ngspice.h"
#include "cktdefs.h"
#include "const.h"
#include "noisedef.h"
void
NevalSrc (double *noise, double *lnNoise, CKTcircuit *ckt, int type, int node1, int node2, double param)
{
double realVal;
double imagVal;
double gain;
realVal = *((ckt->CKTrhs) + node1) - *((ckt->CKTrhs) + node2);
imagVal = *((ckt->CKTirhs) + node1) - *((ckt->CKTirhs) + node2);
gain = (realVal*realVal) + (imagVal*imagVal);
switch (type) {
case SHOTNOISE:
*noise = gain * 2 * CHARGE * fabs(param); /* param is the dc current in a semiconductor */
*lnNoise = log( MAX(*noise,N_MINLOG) );
break;
case THERMNOISE:
*noise = gain * 4 * CONSTboltz * ckt->CKTtemp * param; /* param is the conductance of a resistor */
*lnNoise = log( MAX(*noise,N_MINLOG) );
break;
case N_GAIN:
*noise = gain;
break;
}
}

View File

@ -1,45 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1987 Gary W. Ng
**********/
/*
* Nintegrate.c (noizDens, lnNdens, lnNlstDens, data)
*
* This subroutine evaluates the integral of the function
*
* EXPONENT
* NOISE = a * (FREQUENCY)
*
* given two points from the curve. If EXPONENT is relatively close
* to 0, the noise is simply multiplied by the change in frequency.
* If it isn't, a more complicated expression must be used. Note that
* EXPONENT = -1 gives a different equation than EXPONENT <> -1.
* Hence, the reason for the constant 'N_INTUSELOG'.
*/
#include <stdio.h>
#include "ngspice.h"
#include "noisedef.h"
double
Nintegrate (double noizDens, double lnNdens, double lnNlstDens, register Ndata *data)
{
double exponent;
double a;
exponent = (lnNdens - lnNlstDens) / data->delLnFreq;
if ( fabs(exponent) < N_INTFTHRESH ) {
return (noizDens * data->delFreq);
} else {
a = exp(lnNdens - exponent*data->lnFreq);
exponent += 1.0;
if (fabs(exponent) < N_INTUSELOG) {
return (a * (data->lnFreq - data->lnLastFreq));
} else {
return (a * ((exp(exponent * data->lnFreq) - exp(exponent * data->lnLastFreq)) /
exponent));
}
}
}

View File

@ -1,286 +0,0 @@
/* Patch to noisean.c by Richard D. McRoberts.
* Patched with modifications from Weidong Lu (2000)
* There is a strange #ifdef near the end of the file.
*/
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1987 Gary W. Ng
**********/
#define INT_NOISE /* Inserted to compile the ifdef'd code */
#include "ngspice.h"
#include <stdio.h>
#include "acdefs.h"
#include "cktdefs.h"
#include "fteconst.h"
#include "iferrmsg.h"
#include "noisedef.h"
#include "sperror.h"
#include "vsrc/vsrcdefs.h"
#include "isrc/isrcdefs.h"
int
NOISEan (CKTcircuit *ckt, int restart)
{
register Ndata *data;
double realVal;
double imagVal;
int error;
int posOutNode;
int negOutNode;
int code;
int step;
/* register CKTnode *node; WL but not used ???? */
IFuid freqUid;
void *inst; /* PN fixes incompatible pointer type warning */
double freqTol; /* tolerence parameter for finding final frequency; hack */
register NOISEAN *job = (NOISEAN*) (ckt->CKTcurJob);
static char *noacinput = "noise input source has no AC value";
posOutNode = ((CKTnode*) (job->output))->number;
negOutNode = ((CKTnode*) (job->outputRef))->number;
/* see if the source specified is AC */
inst = NULL;
code = CKTtypelook("Vsource");
if (code != -1) {
error = CKTfndDev((void *)ckt,&code,&inst,
job->input, (void *)NULL, (IFuid)NULL);
if (!error && !((VSRCinstance *)inst)->VSRCacGiven) {
errMsg = MALLOC(strlen(noacinput)+1);
strcpy(errMsg,noacinput);
return (E_NOACINPUT);
}
}
code = CKTtypelook("Isource");
if (code != -1 && inst==NULL) {
error = CKTfndDev((void *)ckt,&code,&inst,
job->input, (void *)NULL,(IFuid)NULL);
if (error) {
/* XXX ??? */
(*(SPfrontEnd->IFerror))(ERR_WARNING,
"Noise input source %s not in circuit",
&job->input);
return (E_NOTFOUND);
}
if (!((ISRCinstance *)inst)->ISRCacGiven) {
errMsg = MALLOC(strlen(noacinput)+1);
strcpy(errMsg,noacinput);
return (E_NOACINPUT);
}
}
if ( (job->NsavFstp == 0) || restart) {
switch (job->NstpType) {
case DECADE:
job->NfreqDelta = exp(log(10.0)/
job->NnumSteps);
break;
case OCTAVE:
job->NfreqDelta = exp(log(2.0)/
job->NnumSteps);
break;
case LINEAR:
job->NfreqDelta = (job->NstopFreq -
job->NstartFreq)/
(job->NnumSteps+1);
break;
default:
return(E_BADPARM);
}
/* error = DCop(ckt); */
error = CKTop(ckt, (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITJCT,
(ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITFLOAT,
ckt->CKTdcMaxIter);
if (error) return(error);
ckt->CKTmode = (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITSMSIG;
error = CKTload(ckt);
if (error) return(error);
data = (Ndata*)MALLOC(sizeof(Ndata));
step = 0;
data->freq = job->NstartFreq;
data->outNoiz = 0.0;
data->inNoise = 0.0;
/* the current front-end needs the namelist to be fully
declared before an OUTpBeginplot */
(*(SPfrontEnd->IFnewUid))((void *)ckt,&freqUid,(IFuid)NULL,
"frequency", UID_OTHER,(void **)NULL);
data->numPlots = 0; /* we don't have any plots yet */
error = CKTnoise(ckt,N_DENS,N_OPEN,data);
if (error) return(error);
/*
* all names in the namelist have been declared. now start the
* plot
*/
error = (*(SPfrontEnd->OUTpBeginPlot))(ckt,(void *)(ckt->CKTcurJob),
"Noise Spectral Density Curves - (V^2 or A^2)/Hz",
freqUid,IF_REAL,data->numPlots,data->namelist,IF_REAL,
&(data->NplotPtr));
if (error) return(error);
if (job->NstpType != LINEAR) {
(*(SPfrontEnd->OUTattributes))((void *)data->NplotPtr,NULL,
OUT_SCALE_LOG, NULL);
}
} else { /* we must have paused before. pick up where we left off */
step = job->NsavFstp;
switch (job->NstpType) {
case DECADE:
case OCTAVE:
data->freq = job->NstartFreq * exp (step *
log (job->NfreqDelta));
break;
case LINEAR:
data->freq = job->NstartFreq + step *
job->NfreqDelta;
break;
default:
return(E_BADPARM);
}
job->NsavFstp = 0;
data->outNoiz = job->NsavOnoise;
data->inNoise = job->NsavInoise;
}
switch (job->NstpType) {
case DECADE:
case OCTAVE:
freqTol = job->NfreqDelta * job->NstopFreq * ckt->CKTreltol;
break;
case LINEAR:
freqTol = job->NfreqDelta * ckt->CKTreltol;
break;
default:
return(E_BADPARM);
}
data->lstFreq = data->freq;
/* do the noise analysis over all frequencies */
while (data->freq <= job->NstopFreq + freqTol) {
if( (*(SPfrontEnd->IFpauseTest))() ) {
job->NsavFstp = step; /* save our results */
job->NsavOnoise = data->outNoiz; /* up until now */
job->NsavInoise = data->inNoise;
return (E_PAUSE);
}
ckt->CKTomega = 2.0 * M_PI * data->freq;
ckt->CKTmode = (ckt->CKTmode & MODEUIC) | MODEAC;
/*
* solve the original AC system to get the transfer
* function between the input and output
*/
NIacIter(ckt);
realVal = *((ckt->CKTrhsOld) + posOutNode)
- *((ckt->CKTrhsOld) + negOutNode);
imagVal = *((ckt->CKTirhsOld) + posOutNode)
- *((ckt->CKTirhsOld) + negOutNode);
data->GainSqInv = 1.0 / MAX(((realVal*realVal)
+ (imagVal*imagVal)),N_MINGAIN);
data->lnGainInv = log(data->GainSqInv);
/* set up a block of "common" data so we don't have to
* recalculate it for every device
*/
data->delFreq = data->freq - data->lstFreq;
data->lnFreq = log(MAX(data->freq,N_MINLOG));
data->lnLastFreq = log(MAX(data->lstFreq,N_MINLOG));
data->delLnFreq = data->lnFreq - data->lnLastFreq;
if ((job->NStpsSm != 0) && ((step % (job->NStpsSm)) == 0)) {
data->prtSummary = TRUE;
} else {
data->prtSummary = FALSE;
}
/*
data->outNumber = 1;
*/
data->outNumber = 0;
/* the frequency will NOT be stored in array[0] as before; instead,
* it will be given in refVal.rValue (see later)
*/
NInzIter(ckt,posOutNode,negOutNode); /* solve the adjoint system */
/* now we use the adjoint system to calculate the noise
* contributions of each generator in the circuit
*/
error = CKTnoise(ckt,N_DENS,N_CALC,data);
if (error) return(error);
data->lstFreq = data->freq;
/* update the frequency */
switch (job->NstpType) {
case DECADE:
case OCTAVE:
data->freq *= job->NfreqDelta;
break;
case LINEAR:
data->freq += job->NfreqDelta;
break;
default:
return(E_INTERN);
}
step++;
}
error = CKTnoise(ckt,N_DENS,N_CLOSE,data);
if (error) return(error);
#ifdef INT_NOISE /* WL */
data->numPlots = 0;
data->outNumber = 0;
if (job->NstartFreq != job->NstopFreq) {
error = CKTnoise(ckt,INT_NOIZ,N_OPEN,data);
if (error) return(error);
(*(SPfrontEnd->OUTpBeginPlot))(ckt,(void *)(ckt->CKTcurJob),
"Integrated Noise - V^2 or A^2",
(IFuid)NULL,(int)0,data->numPlots,data->namelist,IF_REAL,
&(data->NplotPtr));
error = CKTnoise(ckt,INT_NOIZ,N_CALC,data);
if (error) return(error);
error = CKTnoise(ckt,INT_NOIZ,N_CLOSE,data);
if (error) return(error);
}
#endif
FREE(data);
return(OK);
}

View File

@ -1,106 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1987 Gary W. Ng
**********/
#include "ngspice.h"
#include <stdio.h>
#include "cktdefs.h"
#include "ifsim.h"
#include "iferrmsg.h"
#include "noisedef.h"
int
NsetParm(CKTcircuit *ckt, void *anal, int which, IFvalue *value)
{
switch(which) {
case N_OUTPUT:
((NOISEAN*)anal)->output = value->nValue;
break;
case N_OUTREF:
((NOISEAN*)anal)->outputRef = value->nValue;
break;
case N_INPUT:
((NOISEAN*)anal)->input = value->uValue;
break;
case N_DEC:
((NOISEAN*)anal)->NstpType = DECADE;
break;
case N_OCT:
((NOISEAN*)anal)->NstpType = OCTAVE;
break;
case N_LIN:
((NOISEAN*)anal)->NstpType = LINEAR;
break;
case N_STEPS:
((NOISEAN*)anal)->NnumSteps = value->iValue;
break;
case N_START:
if (value->rValue <= 0.0) {
errMsg = copy("Frequency of 0 is invalid");
((NOISEAN*)anal)->NstartFreq = 1.0;
return(E_PARMVAL);
}
((NOISEAN*)anal)->NstartFreq = value->rValue;
break;
case N_STOP:
if (value->rValue <= 0.0) {
errMsg = copy("Frequency of 0 is invalid");
((NOISEAN*)anal)->NstartFreq = 1.0;
return(E_PARMVAL);
}
((NOISEAN*)anal)->NstopFreq = value->rValue;
break;
case N_PTSPERSUM:
((NOISEAN*)anal)->NStpsSm = value->iValue;
break;
default:
return(E_BADPARM);
}
return(OK);
}
static IFparm Nparms[] = {
{ "output", N_OUTPUT, IF_SET|IF_STRING, "output noise summation node" },
{ "outputref", N_OUTREF, IF_SET|IF_STRING, "output noise reference node" },
{ "input", N_INPUT, IF_SET|IF_STRING, "input noise source" },
{ "dec", N_DEC, IF_SET|IF_FLAG, "step by decades" },
{ "oct", N_OCT, IF_SET|IF_FLAG, "step by octaves" },
{ "lin", N_LIN, IF_SET|IF_FLAG, "step linearly" },
{ "numsteps", N_STEPS, IF_SET|IF_INTEGER, "number of frequencies" },
{ "start", N_START, IF_SET|IF_REAL, "starting frequency" },
{ "stop", N_STOP, IF_SET|IF_REAL, "ending frequency" },
{ "ptspersum", N_PTSPERSUM, IF_SET|IF_INTEGER, "frequency points per summary report" }
};
SPICEanalysis NOISEinfo = {
{
"NOISE",
"Noise analysis",
sizeof(Nparms)/sizeof(IFparm),
Nparms
},
sizeof(NOISEAN),
FREQUENCYDOMAIN,
1,
NsetParm,
NaskQuest,
NULL,
NOISEan
};

View File

@ -1,197 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
**********/
#include "ngspice.h"
#include <stdio.h>
#include "complex.h"
#include "cktdefs.h"
#include "smpdefs.h"
#include "pzdefs.h"
#include "trandefs.h" /* only to get the 'mode' definitions */
#include "sperror.h"
#define DEBUG if (0)
/* ARGSUSED */
int
PZan(CKTcircuit *ckt, int reset)
{
PZAN *pzan = (PZAN *) ckt->CKTcurJob;
int error;
int numNames;
IFuid *nameList;
void *plot;
error = PZinit(ckt);
if (error != OK) return error;
/* Calculate small signal parameters at the operating point */
error = CKTop(ckt, (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITJCT,
(ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITFLOAT,
ckt->CKTdcMaxIter);
if (error)
return(error);
ckt->CKTmode = (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITSMSIG;
error = CKTload(ckt); /* Make sure that all small signal params are
* set */
if (error)
return(error);
if (ckt->CKTkeepOpInfo) {
/* Dump operating point. */
error = CKTnames(ckt,&numNames,&nameList);
if(error) return(error);
error = (*(SPfrontEnd->OUTpBeginPlot))((void *)ckt,
(void*)ckt->CKTcurJob, "Distortion Operating Point",
(IFuid)NULL,IF_REAL,numNames,nameList, IF_REAL,&plot);
if(error) return(error);
CKTdump(ckt,(double)0,plot);
(*(SPfrontEnd->OUTendPlot))(plot);
}
if (pzan->PZwhich & PZ_DO_POLES) {
error = CKTpzSetup(ckt, PZ_DO_POLES);
if (error != OK)
return error;
error = CKTpzFindZeros(ckt, &pzan->PZpoleList, &pzan->PZnPoles);
if (error != OK)
return(error);
}
if (pzan->PZwhich & PZ_DO_ZEROS) {
error = CKTpzSetup(ckt, PZ_DO_ZEROS);
if (error != OK)
return error;
error = CKTpzFindZeros(ckt, &pzan->PZzeroList, &pzan->PZnZeros);
if (error != OK)
return(error);
}
return PZpost(ckt);
}
/*
* Perform error checking
*/
int
PZinit(CKTcircuit *ckt)
{
PZAN *pzan = (PZAN *) ckt->CKTcurJob;
int i;
i = CKTtypelook("transmission line");
if (i == -1) {
i = CKTtypelook("Tranline");
if (i == -1)
i = CKTtypelook("LTRA");
}
if (i != -1 && ckt->CKThead[i] != NULL)
ERROR(E_XMISSIONLINE, "Transmission lines not supported")
pzan->PZpoleList = (PZtrial *) NULL;
pzan->PZzeroList = (PZtrial *) NULL;
pzan->PZnPoles = 0;
pzan->PZnZeros = 0;
if (pzan->PZin_pos == pzan->PZin_neg)
ERROR(E_SHORT, "Input is shorted")
if (pzan->PZout_pos == pzan->PZout_neg)
ERROR(E_SHORT, "Output is shorted")
if (pzan->PZin_pos == pzan->PZout_pos
&& pzan->PZin_neg == pzan->PZout_neg
&& pzan->PZinput_type == PZ_IN_VOL)
ERROR(E_INISOUT, "Transfer function is unity")
else if (pzan->PZin_pos == pzan->PZout_neg
&& pzan->PZin_neg == pzan->PZout_pos
&& pzan->PZinput_type == PZ_IN_VOL)
ERROR(E_INISOUT, "Transfer function is -1")
return(OK);
}
/*
* PZpost Post-processing of the pole-zero analysis results
*/
int
PZpost(CKTcircuit *ckt)
{
PZAN *pzan = (PZAN *) ckt->CKTcurJob;
void *pzPlotPtr; /* the plot pointer for front end */
IFcomplex *out_list;
IFvalue outData; /* output variable (points to out_list) */
IFuid *namelist;
PZtrial *root;
char name[50];
int i, j;
namelist = (IFuid *) MALLOC((pzan->PZnPoles
+ pzan->PZnZeros)*sizeof(IFuid));
out_list = (IFcomplex *)MALLOC((pzan->PZnPoles
+ pzan->PZnZeros)*sizeof(IFcomplex));
j = 0;
for (i = 0; i < pzan->PZnPoles; i++) {
sprintf(name, "pole(%-u)", i+1);
(*(SPfrontEnd->IFnewUid))(ckt,&(namelist[j++]),(IFuid)NULL,
name,UID_OTHER,(void **)NULL);
}
for (i = 0; i < pzan->PZnZeros; i++) {
sprintf(name, "zero(%-u)", i+1);
(*(SPfrontEnd->IFnewUid))(ckt,&(namelist[j++]),(IFuid)NULL,
name,UID_OTHER,(void **)NULL);
}
(*SPfrontEnd->OUTpBeginPlot)(ckt, (void *)pzan, pzan->JOBname,
(IFuid)NULL, (int)0, pzan->PZnPoles + pzan->PZnZeros, namelist,
IF_COMPLEX, &pzPlotPtr);
j = 0;
if (pzan->PZnPoles > 0) {
for (root = pzan->PZpoleList; root != NULL; root = root->next) {
for (i = 0; i < root->multiplicity; i++) {
out_list[j].real = root->s.real;
out_list[j].imag = root->s.imag;
j += 1;
if (root->s.imag != 0.0) {
out_list[j].real = root->s.real;
out_list[j].imag = -root->s.imag;
j += 1;
}
}
DEBUG printf("LIST pole: (%g,%g) x %d\n",
root->s.real, root->s.imag, root->multiplicity);
}
}
if (pzan->PZnZeros > 0) {
for (root = pzan->PZzeroList; root != NULL; root = root->next) {
for (i = 0; i < root->multiplicity; i++) {
out_list[j].real = root->s.real;
out_list[j].imag = root->s.imag;
j += 1;
if (root->s.imag != 0.0) {
out_list[j].real = root->s.real;
out_list[j].imag = -root->s.imag;
j += 1;
}
}
DEBUG printf("LIST zero: (%g,%g) x %d\n",
root->s.real, root->s.imag, root->multiplicity);
}
}
outData.v.numValue = pzan->PZnPoles + pzan->PZnZeros;
outData.v.vec.cVec = out_list;
(*SPfrontEnd->OUTpData)(pzPlotPtr, (IFvalue *) 0, &outData);
(*(SPfrontEnd->OUTendPlot))(pzPlotPtr);
return(OK);
}

View File

@ -1,80 +0,0 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
#include <stdio.h>
#include "ifsim.h"
#include "iferrmsg.h"
#include "pzdefs.h"
#include "cktdefs.h"
/* ARGSUSED */
int
PZaskQuest(CKTcircuit *ckt, void *anal, int which, IFvalue *value)
{
switch(which) {
case PZ_NODEI:
value->nValue = (IFnode)CKTnum2nod(ckt,((PZAN*)anal)->PZin_pos);
break;
case PZ_NODEG:
value->nValue = (IFnode)CKTnum2nod(ckt,((PZAN*)anal)->PZin_neg);
break;
case PZ_NODEJ:
value->nValue = (IFnode)CKTnum2nod(ckt,((PZAN*)anal)->PZout_pos);
break;
case PZ_NODEK:
value->nValue = (IFnode)CKTnum2nod(ckt,((PZAN*)anal)->PZout_neg);
break;
case PZ_V:
if( ((PZAN*)anal)->PZinput_type == PZ_IN_VOL) {
value->iValue=1;
} else {
value->iValue=0;
}
break;
case PZ_I:
if( ((PZAN*)anal)->PZinput_type == PZ_IN_CUR) {
value->iValue=1;
} else {
value->iValue=0;
}
break;
case PZ_POL:
if( ((PZAN*)anal)->PZwhich == PZ_DO_POLES) {
value->iValue=1;
} else {
value->iValue=0;
}
break;
case PZ_ZER:
if( ((PZAN*)anal)->PZwhich == PZ_DO_ZEROS) {
value->iValue=1;
} else {
value->iValue=0;
}
break;
case PZ_PZ:
if( ((PZAN*)anal)->PZwhich == (PZ_DO_POLES | PZ_DO_ZEROS)) {
value->iValue=1;
} else {
value->iValue=0;
}
break;
default:
return(E_BADPARM);
}
return(OK);
}

Some files were not shown because too many files have changed in this diff Show More