file B4TERMS_OF_USE was added on branch TCLSPICE on 2006-08-31 18:11:35 +0000
This commit is contained in:
parent
978f1c32a2
commit
589b6eb665
1051
man/man1/nutmeg.1
1051
man/man1/nutmeg.1
File diff suppressed because it is too large
Load Diff
|
|
@ -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.
|
||||
|
||||
325
man/man1/spice.1
325
man/man1/spice.1
|
|
@ -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.
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
|
||||
|
||||
|
||||
207
notes/mac_port
207
notes/mac_port
|
|
@ -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.
|
||||
237
notes/porting
237
notes/porting
|
|
@ -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 */
|
||||
15
notes/spice2
15
notes/spice2
|
|
@ -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).
|
||||
|
||||
|
|
@ -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.
|
||||
|
|
@ -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
|
||||
|
|
@ -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 */
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
@ -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
|
||||
};
|
||||
|
|
@ -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*/
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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));
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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*/
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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");
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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 */
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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) );
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
};
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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 */
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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
|
||||
};
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
@ -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 */
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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
|
||||
};
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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) */
|
||||
}
|
||||
|
||||
|
|
@ -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
|
||||
};
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
@ -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;
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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
|
||||
};
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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
Loading…
Reference in New Issue