diff --git a/ANALYSES b/ANALYSES index 52dd83c69..d4d3a1623 100644 --- a/ANALYSES +++ b/ANALYSES @@ -1,5 +1,3 @@ -12345678901234567890123456789012345678901234567890123456789012345678901234567890 - ANALYSES ======== @@ -46,7 +44,9 @@ Table of Contents 2 Operating point analysis (OP) The operating point analysis determines the dc operating point of the - circuit with inductors shorted and capacitors opened. + circuit with inductors shorted and capacitors opened. If a simple matrix + solution fails, two versions of gmin stepping may be followed by source + stepping and finally an OP search by a transient simulation. 3 Operating point sweep Analysis (DC) diff --git a/AUTHORS b/AUTHORS index df0a4883f..72f545d33 100644 --- a/AUTHORS +++ b/AUTHORS @@ -15,6 +15,7 @@ Phil Barker, Steven Borley, Krzysztof Blaszkowski, Stuart Brorson, +Árpád Bűrmen, Alessio Cacciatori, Mansun Chan, Wayne A. Christopher, diff --git a/BUGS b/BUGS index b338848fb..8d37147a3 100644 --- a/BUGS +++ b/BUGS @@ -30,9 +30,3 @@ OPEN BUGS: algorithms, does not give correct results for all tested input files. The effort to correct that issue seems to be large. - -* voltage (and current) controlled switches need better timing - - The controlled switches (SW, CSW), which still stem from the original - spice3f5 implementation, sometimes lead to wrong results when on and off - ramp times differ considerably. diff --git a/DEVICES b/DEVICES index a64e2e4aa..c6d3e4236 100644 --- a/DEVICES +++ b/DEVICES @@ -827,16 +827,16 @@ will be updated every time the device specific code is altered or changed to ref 13.8 r2_cmc More models are available at https://github.com/dwarning/VA-Models, - user compiled models are possible as well (See ngspice manual, chapter 13). + user compiled models are possible as well (See ngspice manual, chapter 9). 14. XSpice code models - more than 100 models are available, please see ngspice manual chapt. 12 + more than 100 models are available, please see ngspice manual chapt. 8 15. Digital Building Blocks (U instances) U instances are digital primitives which may be used (in proper combination) to model digital devices, e.g. from the 74xx or 40xx families. ngspice maps them onto XSPICE models, which allows a fast event based simulation. Please see the - ngspice manual, chapter 14. + ngspice manual, chapter 10. diff --git a/FAQ b/FAQ index 0571cbb00..93576c300 100644 --- a/FAQ +++ b/FAQ @@ -96,7 +96,7 @@ from a tcl script and vector plotted or post processed using tcl. A small GUI may be built by the user to analyze a circuit or a set of circuits. Tclspice is obtained compiling ngspice activating an additional option. - This has not been used and tested for recently. + This has not been used and tested for some time now. 1.4 Why resurrecting Berkeley's Spice? @@ -135,7 +135,7 @@ most of the commercial simulators available tracked each other in netlist language, this should not be an impossible task. The most important goal here is to provide a reliable support for model libraries coming from - foundries. + foundries. Some compatibility switches are available. + Compact models: The interest in using ngspice is intimately connected to the available models. To provide the latest models available for @@ -256,7 +256,7 @@ The latest version released is: - ngspice-41 (released on Aug 13 2023) + ngspice-43 (released on July 14 2024) 2.2. What are the latest features in the current release? @@ -308,8 +308,8 @@ 3.1. What systems are supported? - Ngspice is written in C, and uses some GNU extensions. You may use - a GNU C compiler and a LINUX environment to compile it. Ngspice can + Ngspice is written in C, C++, and uses some GNU extensions. You may use + a GNU C/C++ compiler and a LINUX environment to compile it. Ngspice can be compiled under Windows using the mingw or cygwin environment as well as MS Visual Studio. It will readily compile on macOS. FreeBSD or Solaris will do, but are not officially supported. @@ -356,7 +356,7 @@ 4.4. Disclaimer and Copyright - Copyright: Holger Vogt, 2023 + Copyright: Holger Vogt, 2024 License: Creative Commons Attribution Share-Alike (CC-BY-SA) v4.0. This document is provided as is. The information in it is not warranted to be correct: you use it at your own risk. diff --git a/INSTALL b/INSTALL index 19866cfb1..c0f082586 100644 --- a/INSTALL +++ b/INSTALL @@ -56,7 +56,7 @@ This file describes the procedures to install ngspice from sources. library and ngspice as a tcl/tk library. Compilation to 64 bit is recommended and available per default in - the ./compile_linux.sh compule script. 32 bit might be possible, + the ./compile_linux_new.sh compile script. 32 bit might be possible, but is not tested. The following software must be installed in your system to compile @@ -64,7 +64,8 @@ This file describes the procedures to install ngspice from sources. output): bison, flex, X11 headers and libs, Xaw, Xmu, Xext, Xft, FontConfig, Xrender, freetype headers and readline. - Typically one needs the headers (e.g. libX11-devel) and the libs (e.g. libX11-6). + Typically one needs the headers (e.g. libX11-devel) and the libs (e.g. libX11-6) + of the packages mentioned above. ngspice as a shared library (no graphics and no command-line interfaces) will need bison and flex only. @@ -73,11 +74,11 @@ This file describes the procedures to install ngspice from sources. internal fft algorithms. If you want to compile the source from the git repository, or if you want to - use the compile script ./compile_linux.sh, you will need additional software: + use the compile script ./compile_linux_new.sh, you will need additional software: autoconf, automake, libtool. The following software may be needed when enabling additional features: - editline, tcl/tk. + editline (as a replacement for readline), tcl/tk (when compiling tclspice). Please have a look at the current ngspice manual, downloadable at http://ngspice.sourceforge.net/docs.html, which gives you much more @@ -86,20 +87,20 @@ This file describes the procedures to install ngspice from sources. For compiling ngspice as a shared library, see section 1.4. -1.2 Install from tarball (e.g. ngspice-41.tar.gz) +1.2 Install from tarball (e.g. ngspice-43.tar.gz) This covers installation from a release distribution (for example - ngspice-41.tar.gz, the so called tar ball). + ngspice-43.tar.gz, the so called tar ball). After downloading the tar ball to a local directory, unpack it by command: - $ tar -zxvf ngspice-41.tar.gz + $ tar -zxvf ngspice-43.tar.gz Now change directories in to the top-level source directory (where this INSTALL file can be found). The most comfortable way to compile ngspice is running the compile script - compile_linux.sh within the terminal window by ./compile_linux.sh. The + compile_linux.sh within the terminal window by ./compile_linux_new.sh. The script has to be declared as 'executable', and admin rights are required to allow the installation of ngspice. @@ -110,31 +111,27 @@ This file describes the procedures to install ngspice from sources. $ mkdir release $ cd release - $ ../configure --with-x --with-readline=yes --disable-debug + $ ../configure --with-x $ make $ sudo make install The default install directory for executables is /usr/local/bin, the XSPICE code models will be installed in /usr/local/lib/ngspice. Some distros use lib64 - instead. - - A simple ../configure might be sufficient for a basic ngspice, but the preferred - arguments to ../configure are - --with-x --with-readline=yes and --disable-debug - providing you with a comfortably working ngspice. - - See the section 1.5 titled 'Advanced Install' for instructions about additional arguments - that can be passed to ../configure to customise the build and installation. + instead. The following options are now included automatically: readline, openmp, + osdi, xspice. Only CIDER has to be selected as an extra option. A fully featured ngspice on LINUX may be obtained with the following commands: $ mkdir release $ cd release - $ ../configure --with-x --enable-xspice --disable-debug --enable-cider --with-readline=yes --enable-predictor --enable-osdi --enable-openmp + $ ../configure --with-x --enable-cider --enable-predictor $ make 2>&1 | tee make.log $ sudo make install To remove the executables and libraries from the install directory, you may call $ sudo make uninstall + + To disable one of the already inlcuded options, you may call --with-readline=no, or + --disable-openmp, --disable-osdi, --disable-xspice 1.3 Install from the git repository @@ -155,7 +152,7 @@ This file describes the procedures to install ngspice from sources. directory, so to e.g. maintain separate debug and release versions. The most comfortable way to compile ngspice is running the compile script - compile_linux.sh within the terminal window by ./compile_linux.sh. Admin + compile_linux_new.sh within the terminal window by ./compile_linux_new.sh. Admin rights are required to allow the installation included in the script. If you want to copile ngspice manually, you may run @@ -163,7 +160,7 @@ This file describes the procedures to install ngspice from sources. $ ./autogen.sh $ mkdir debug $ cd debug - $ ../configure --with-x --with-readline=yes + $ ../configure --with-x $ make $ sudo make install @@ -178,7 +175,7 @@ This file describes the procedures to install ngspice from sources. $ ./autogen.sh $ mkdir release $ cd release - $ ../configure --with-x --enable-xspice --disable-debug --enable-cider --with-readline=yes --enable-openmp --enable-predictor --enable-osdi + $ ../configure --with-x --enable-cider --enable-predictor $ make 2>&1 | tee make.log $ sudo make install @@ -189,7 +186,7 @@ This file describes the procedures to install ngspice from sources. 1.4 ngspice as a shared library The relevant configure options for the ngspice shared library are: - $ --with-ngshared --enable-xspice --disable-debug --enable-cider --enable-osdi --enable-openmp + $ --with-ngshared --enable-cider Typically the two aliases libngspice.so, libngspice.so.0 and the compiled library libngspice.so.0.0.1 are made. The install locations depend on @@ -217,15 +214,7 @@ This file describes the procedures to install ngspice from sources. 1.5.1 Most useful options: - --enable-osdi - Add the OSDI interface to ngspice. This interface allow to dynamically - load compiled Veriloag-A compact models. Compiling is done with - OpenVAF. Thus for the first time ngspice has access to modern - device models like BSOMBULK or BSIM_CMG. - - --enable-cider - Cider is a mixed-level simulator that couples Spice3 and DSIM - to simulate devices from their technological parameters. +(the following are already included) --enable-xspice Enable XSpice enhancements, @@ -240,11 +229,18 @@ This file describes the procedures to install ngspice from sources. Parallelization is done by OpenMP, for MOS models in BSIM3.3.0 BSIM4.6.0 and and BSOI4 only. See the ngspice manual for details. - --disable-debug - This option will remove the '-g' option passed to the compiler - and add -O2 optimization (instead of default O0). - This speeds up simulating significantly, and is recommended for - normal use. + --enable-osdi + Add the OSDI interface to ngspice. This interface allow to dynamically + load compiled Veriloag-A compact models. Compiling is done with + OpenVAF. Thus for the first time ngspice has access to modern + device models like BSOMBULK or BSIM_CMG. + + +(the following have to be selected to become available) + + --enable-cider + Cider is a mixed-level simulator that couples Spice3 and DSIM + to simulate devices from their technological parameters. --enable-oldapps The old apllications ngsconvert ngproc2mod ngmultidec and ngmakeidx @@ -254,11 +250,11 @@ This file describes the procedures to install ngspice from sources. Disable using fftw fast fourier transform library. Use internal fft instead. Default is 'yes'. - --with-editline=yes Enables the use of the BSD editline library (libedit) instead of readline. See https://www.thrysoee.dk/editline/ + (requires --with-readline=no) --enable-shortcheck Enables a 'make check' with strongly reduced runtime. Besides some @@ -494,7 +490,7 @@ This file describes the procedures to install ngspice from sources. automake, libtool, FLEX and BISON, all available with pacman in MSYSS2). Some links are given below which describe the procedures. - Installing from the tarball, e.g. ngspice-36.tar.gz, is simple: After + Installing from the tarball, e.g. ngspice-43.tar.gz, is simple: After expanding, you may just run ./compile_min.sh from the ngspice directory. The default installation location of ngspice is the Windows path @@ -517,16 +513,11 @@ This file describes the procedures to install ngspice from sources. $ make $ make install - The most useful options are: - --enable-xspice - --enable-cider - --disable-debug (-O2 optimization, no debug information) - A fully featured ngspice on Windows may be obtained with the following commands: $ ./autogen.sh $ mkdir release $ cd release - $ ../configure --with-wingui --enable-cider --disable-debug --enable-openmp --enable-xspice --enable-osdi + $ ../configure --with-wingui --enable-cider --disable-debug $ make install However, to compile code extracted from the git repository the procedure is diff --git a/Makefile.am b/Makefile.am index 3fda76704..b64977294 100644 --- a/Makefile.am +++ b/Makefile.am @@ -8,11 +8,12 @@ EXTRA_DIST = FAQ autogen.sh Stuarts_Poly_Notes \ DEVICES INTERNALS NEWS README README.tcl README.optran\ README.shared-xspice README.vdmos README_OSDI.md\ README_OSDI_howto README.cpl-gc README.utf8 \ - examples m4 visualc \ + examples m4 visualc Dockerfile \ cross-compile.sh cross-compile-shared.sh \ compile_min.sh compile_linux.sh compile_min_shared.sh \ compile_linux_shared.sh compile_cyg_make_short_check_64.sh \ - compile_macos_clang.sh compile_macos_gcc.sh \ + compile_macos_clang.sh compile_macos_gcc.sh compile_macos_shared.sh \ + compile_macos_clang_M2.sh compile_macos_clang_M2_shared.sh \ compile_linux_dist.sh ngspice.pc.in .gitignore MAINTAINERCLEANFILES = Makefile.in aclocal.m4 ar-lib compile config.guess \ diff --git a/NEWS b/NEWS index 4def20b82..ec99bfe49 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,45 @@ +Ngspice-43, July 14th, 2024 +============ +- New features: + + Compile on Apple M2 + + Update to VBIC model: Enable self-heating in AC sim, enable nqs. + + Enable single terminal n devices (Verilog-A modules) + + Add path or filepath (without file name) to variable sourcepath, + when calling command 'source' + + B source pwl, enable monotonic negative growth of abscissa values. + + Enable coupling of more than 2 inductots in a single line: + K1 L1 L2 L3 L4 L5 0.99 + + Enable reading library search paths from env. variables like + .lib "$ENVS1/$ENVS2/libraries/sky130_fd_pr/latest/models/sky130.lib.spice" tt + + Add '.save nosub' to suppress storing the node vectors from inside + of subcircuits. + + Transform nested braces {{}} into {()} also in .param statements + + Save path to .include file, add it to the search paths + for loading the next .include file. + + In ./configure, the following options are now standard: + non-debug, osdi, xspice, readline, klu, openmp + + in case of netlist errors, try identifying the file and line number + of its origin. + + Add diode model parameters, Level 3, for diode breakdown voltage + as used in sky130 PDK + + New environmental variable NGSPICE_OSDI_DIR may contain + a path for *.osdi files (compiled Verilog-A models) + + optran 0 0 0 0 0 uic may be used to load initial conditions (.ic=xxx + statements) without starting an op iteration. + + Add variable ps_scan_gates_optimize (default 1). If < 1, then turn off + the optimizations in scan_gates. + + new exported function ngSpice_nospinit() to set variable no_spinit + + Update to JFET model (add emission coefficient) + + MOS models 1...3: updated noise code + + Update to fft window functions, scaling etc. + + Add transformer model with params on the .subckt line + + timing .model statements at the global level for subckts with U* instances + + variable 'rsdiode' sets RS of a diode, if not given in the .model line. + + Update the AM voltage/current sources: enable amplitude + modulation, carrier suppression. + + Remove some ADMS remnants. + + Ngspice-42, Dec 24th, 2023 ============ - New features: @@ -27,7 +69,6 @@ Ngspice-42, Dec 24th, 2023 + Add scripts for running the paranoia tests in parallel on Linux with valgrind. - Ngspice-41, Aug 13th, 2023 ============ - New features: @@ -60,7 +101,8 @@ Ngspice-41, Aug 13th, 2023 + Several crash bugs (double delete, access NULL pointer etc) removed which have occurred mostly due to incomplete or faulty inputs. + Memory leaks for CIDER removed - + + Ngspice-40, Mar 31st, 2023 ============ - New features: @@ -153,7 +195,7 @@ Ngspice-38, Oct 30th, 2022 Ngspice-37, May 22nd, 2022 ============ - New features: - + Reduce XSPICE memory consumption dramatically + + Reduce XSPICE memory consumption dramatically (> factor of 10). + Add source stepping to B source + Add 'esave' command to save only specific event nodes. @@ -320,7 +362,7 @@ Ngspice-32, Apr 25th, 2020 - New features: + Add resource info on memory used and available for macOS + redesign of memory monitoring - + Replace B source pwl by XSPICE PWL Controlled Source that has smooth rounded and + + Replace B source pwl by XSPICE PWL Controlled Source that has smooth rounded and stepless differentiable corners. + Get a variable directly from an input file with i/o redirection + Make 64 bit compilation the standard diff --git a/README b/README index 665622acf..21b5955e0 100644 --- a/README +++ b/README @@ -5,16 +5,17 @@ Ngspice is a mixed-level/mixed-signal circuit simulator. Its code is based on three open source software packages: Spice3f5, Cider1b1 and Xspice. -Spice3 does not need any introduction, is the most popular circuit -simulator. In over 30 years of its life Spice3 has become a de-facto -standard for simulating circuits. +Spice3 does not need any introduction, it is the ancestor of many +commercial or open source circuit simulators. In over 30 years +since its existence it has set several de-facto standards for +simulating circuits. -Cider couples Spice3f5 circuit level simulator to a device simulator +Cider couples the Spice3 circuit level simulator to a device simulator to provide greater simulation accuracy of critical devices. So you may create device models for diodes, bipolar, JFet and MOSFETs derived from their cross-sectional structures and materials. -Xspice is an extension to Spice3C1 that provides code modelling support +Xspice is an extension to Spice3 that provides code modelling support and simulation of digital components through an embedded event driven algorithm. diff --git a/compile_cyg_make_short_check_64.sh b/compile_cyg_make_short_check_64.sh index 668fd5218..7dd1ce342 100644 --- a/compile_cyg_make_short_check_64.sh +++ b/compile_cyg_make_short_check_64.sh @@ -1,8 +1,8 @@ #!/bin/bash # ngspice build script for CYGWIN console (X11), release version, 64 bit -# compile_cyg_make_check.sh +# compile_cyg_make_short_check.sh -# short version, cd into release64_cyg, then call make, make install, make check +# short version, skipping several of the device checks #Procedure: # Install CYGWIN, plus bison, flex, auto tools, perl, libiconv, libintl @@ -11,8 +11,8 @@ # './compile_cyg_auto.sh' # Options: -# CIDER, XSPICE, OSDI, KLU, and OpenMP may be selected at will. -# --disable-debug will give O2 optimization (versus O0 for debug) and removes all debugging info. +# CIDER may be selected at will. +# XSPICE, OSDI, KLU, and OpenMP may be deselected if not require # --enable-oldapps will make ngnutmeg ngsconvert ngproc2mod ngmultidec ngmakeidx in addition to ngspice # --enable-shortcheck will provide a fast 'make check' by checking only BSIM3 and BSIM4 @@ -29,8 +29,7 @@ echo cd release64_cyg if [ $? -ne 0 ]; then echo "cd release64_cyg failed"; exit 1 ; fi echo -../configure --with-x=yes --with-readline=yes --disable-debug --enable-cider --enable-openmp --enable-xspice --enable-osdi --enable-klu --enable-predictor --enable-shortcheck CFLAGS="-O2 -m64" LDFLAGS="-s -m64" -#../configure --with-x=no --with-readline=yes --disable-debug --enable-xspice --enable-cider --enable-openmp +../configure --with-x=yes --enable-cider --enable-shortcheck CFLAGS="-O2 -m64" LDFLAGS="-s -m64" if [ $? -ne 0 ]; then echo "../configure failed"; exit 1 ; fi diff --git a/compile_linux.sh b/compile_linux.sh index 0181a08d4..a51fafe22 100755 --- a/compile_linux.sh +++ b/compile_linux.sh @@ -12,17 +12,10 @@ # CentOS users may need to add -std=c99 to the CFLAGS in the ../configure # statement. # Options: -# --enable-osdi will enable the OSDI interface, which, in conjuction with the -# external OpenVAF Verilig-A compiler, will allow access to advanced compact -# device models writen in Verilog-A. -# Please see the ngspice manual, chapt. 13, for more info on using OSDI/OpenVAF. -# --enable-klu will add the new matrix solver in addition to Sparse 1.3. -# CIDER, XSPICE, KLU, and OpenMP may be selected at will. -# --disable-debug will give O2 optimization (versus O0 for debug) and removes all debugging info. +# --enable-cider will enable the CIDER process simulator to construct devices +# in a semiconductor. +# XSPICE, KLU, OSDI, and OpenMP may be deselected if not required. -# ngspice as shared library: -# Replace --with-x by --with-ngshared in line ../configure ... . -# Add (optionally) --enable-relpath to avoid absolute paths when searching for code models. # It might be necessary to uncomment and run ./autogen.sh . SECONDS=0 @@ -49,13 +42,13 @@ if test "$1" = "d"; then if [ $? -ne 0 ]; then echo "cd debug failed"; exit 1 ; fi echo "configuring for 64 bit debug" echo - ../configure --with-x --enable-xspice --enable-cider --enable-predictor --enable-osdi --enable-klu --with-readline=yes --enable-openmp --prefix="/usr/local" --libdir="/usr/local/lib" CFLAGS="-g -m64 -O0 -Wall -Wno-unused-but-set-variable" LDFLAGS="-m64 -g" + ../configure --with-x --enable-cider --prefix="/usr/local" --libdir="/usr/local/lib" CFLAGS="-g -m64 -O0 -Wall -Wno-unused-but-set-variable" LDFLAGS="-m64 -g" else cd release if [ $? -ne 0 ]; then echo "cd release failed"; exit 1 ; fi echo "configuring for 64 bit release" echo - ../configure --with-x --enable-xspice --enable-cider --enable-predictor --enable-osdi --enable-klu --with-readline=yes --enable-openmp --disable-debug --prefix="/usr/local" --libdir="/usr/local/lib" CFLAGS="-m64 -O2" LDFLAGS="-m64 -s" + ../configure --with-x --enable-cider --prefix="/usr/local" --libdir="/usr/local/lib" CFLAGS="-m64 -O2" LDFLAGS="-m64 -s" fi if [ $? -ne 0 ]; then echo "../configure failed"; exit 1 ; fi diff --git a/compile_linux_dist.sh b/compile_linux_dist.sh index fb49f61c1..c84f34bc0 100755 --- a/compile_linux_dist.sh +++ b/compile_linux_dist.sh @@ -27,7 +27,7 @@ if [ $? -ne 0 ]; then echo "cd release failed"; exit 1 ; fi echo "configuring for 64 bit release" echo -../configure --with-x --enable-xspice --enable-cider --with-readline=yes --enable-openmp --enable-osdi --disable-debug CFLAGS="-m64 -O2" LDFLAGS="-m64 -s" +../configure --with-x --enable-cider CFLAGS="-m64 -O2" LDFLAGS="-m64 -s" if [ $? -ne 0 ]; then echo "../configure failed"; exit 1 ; fi diff --git a/compile_linux_shared.sh b/compile_linux_shared.sh index 02e3a0908..72fe12194 100755 --- a/compile_linux_shared.sh +++ b/compile_linux_shared.sh @@ -1,5 +1,6 @@ #!/bin/bash -# ngspice build script for Linux, release or debug version, 64 bit +# ngspice build script for Linux, to build ngspice as a shared library, release or +# debug version, 64 bit # compile_linux_shared.sh # Procedure: @@ -8,11 +9,9 @@ # Declare 'compile_linux_shared.sh' as being executable and start compiling with # './compile_linux_shared.sh' or './compile_linux_shared.sh d' from the ngspice directory. # Options: -# --enable-osdi will add the osdi interface which allows to dynamically load compiled Verilog-A -# compact models. Compiling the VA code of the models is done by the OpenVAF compiler. -# Please see the ngspice manual, chapt. 13, for more info on OSDI/OpenVAF. -# CIDER, XSPICE, KLU, and OpenMP may be selected at will. -# --disable-debug will give O2 optimization (versus O0 for debug) and removes all debugging info. +# --enable-cider will enable the CIDER process simulator to construct devices +# in a semiconductor. +# XSPICE, KLU, OSDI, and OpenMP may be deselected if not required. # Add (optionally) --enable-relpath to avoid absolute paths when searching for code models. # It might be necessary to uncomment and run ./autogen.sh especially if sources have been @@ -44,7 +43,7 @@ if test "$1" = "d"; then echo # The --prefix (and perhaps --libdir) may be used to determine a different install location # (depending on the Linux distribution, and on the calling programs search path). - ../configure --with-ngshared --enable-xspice --enable-cider --enable-openmp --enable-osdi --enable-klu --prefix=/usr CFLAGS="-g -m64 -O0 -Wall" LDFLAGS="-m64 -g" + ../configure --with-ngshared --enable-cider --prefix=/usr CFLAGS="-g -m64 -O0 -Wall" LDFLAGS="-m64 -g" else cd releasesh if [ $? -ne 0 ]; then echo "cd releasesh failed"; exit 1 ; fi @@ -52,7 +51,7 @@ else echo # The --prefix (and perhaps --libdir) may be used to determine a different install location # (depending on the Linux distribution, and on the calling programs search path). - ../configure --with-ngshared --enable-xspice --enable-cider --enable-openmp --enable-osdi --enable-klu --disable-debug --prefix=/usr CFLAGS="-m64 -O2" LDFLAGS="-m64 -s" + ../configure --with-ngshared --enable-cider --prefix=/usr CFLAGS="-m64 -O2" LDFLAGS="-m64 -s" fi if [ $? -ne 0 ]; then echo "../configure failed"; exit 1 ; fi diff --git a/compile_macos_clang.sh b/compile_macos_clang.sh index 491550f4f..0448471c2 100755 --- a/compile_macos_clang.sh +++ b/compile_macos_clang.sh @@ -1,18 +1,17 @@ #!/bin/bash # ngspice build script for macOS, release or debug version, 64 bit -# compile_macos.sh +# compile_macos_clang.sh +# tested with macOS BigSur 11.7.9, MacBook Air i5 +# OpenMP is not available! # Procedure: # Install gcc, bison, flex, libtool, autoconf, automake, # libx11 and libx11-dev (headers), libXaw and libXaw-dev, libreadline and dev -# Declare 'compile_linux.sh' executable and start compiling with -# './compile_macos.sh' or './compile_macos.sh d' from the ngspice directory. +# XCODE and commandline tools +# Declare 'compile_macos_clang.sh' executable and start compiling with +# './compile_macos_clang.sh' or './compile_macos_clang.sh d' from the ngspice directory. # Options: -# --adms and --enable-adms will install extra HICUM, EKV and MEXTRAM models via the -# adms interface. You need to download and install the *.va files via ng-adms-va.tgz -# Please see the ngspice manual, chapt. 13, for more info on adms. -# CIDER, XSPICE, and OpenMP may be selected at will. -# --disable-debug will give O2 optimization (versus O0 for debug) and removes all debugging info. +# KLU, OSDI, and XSPICE may be deselected at will. # ngspice as shared library: # Replace --with-x by --with-ngshared in line ../configure ... . @@ -37,29 +36,21 @@ fi ./autogen.sh if [ $? -ne 0 ]; then echo "./autogen.sh failed"; exit 1 ; fi -# Alternatively, if compiling sources from git, and want to add adms created devices, -# you may need to uncomment the following two lines (and don't forget to add adms option -# to the ../configure statement): -#./autogen.sh --adms -#if [ $? -ne 0 ]; then echo "./autogen.sh failed"; exit 1 ; fi - echo if test "$1" = "d"; then cd debug if [ $? -ne 0 ]; then echo "cd debug failed"; exit 1 ; fi echo "configuring for 64 bit debug" echo -# You may add --enable-adms to the following command for adding adms generated devices # Builtin readline is not compatible (Big Sur), readline via Homebrew required (in /usr/local/opt) # Standard clang does not support OpenMP - ../configure --with-x --enable-xspice --enable-cider --enable-predictor --enable-osdi --enable-klu --with-readline=/usr/local/opt/readline CFLAGS="-m64 -O0 -g -Wall -I/opt/X11/include/freetype2 -I/usr/local/opt/readline/include" LDFLAGS="-m64 -g -L/usr/local/opt/readline/lib -L/opt/X11/lib" + ../configure --with-x --enable-cider --disable-openmp --with-readline=/usr/local/opt/readline CFLAGS="-m64 -O0 -g -Wall -I/opt/X11/include/freetype2 -I/usr/local/opt/readline/include" LDFLAGS="-m64 -g -L/usr/local/opt/readline/lib -L/opt/X11/lib" else cd release if [ $? -ne 0 ]; then echo "cd release failed"; exit 1 ; fi echo "configuring for 64 bit release" echo -# You may add --enable-adms to the following command for adding adms generated devices - ../configure --with-x --enable-xspice --enable-cider --enable-predictor --enable-osdi --enable-klu --with-readline=/usr/local/opt/readline --disable-debug CFLAGS="-m64 -O2 -I/opt/X11/include/freetype2 -I/usr/local/opt/readline/include -I/usr/local/opt/ncurses/include" LDFLAGS="-m64 -L/usr/local/opt/readline/lib -L/usr/local/opt/ncurses/lib -L/opt/X11/lib" + ../configure --with-x --enable-cider --disable-openmp --with-readline=/usr/local/opt/readline CFLAGS="-m64 -O2 -I/opt/X11/include/freetype2 -I/usr/local/opt/readline/include -I/usr/local/opt/ncurses/include" LDFLAGS="-m64 -L/usr/local/opt/readline/lib -L/usr/local/opt/ncurses/lib -L/opt/X11/lib" fi if [ $? -ne 0 ]; then echo "../configure failed"; exit 1 ; fi diff --git a/compile_macos_clang_M2.sh b/compile_macos_clang_M2.sh new file mode 100644 index 000000000..0e8150baf --- /dev/null +++ b/compile_macos_clang_M2.sh @@ -0,0 +1,77 @@ +#!/bin/bash +# ngspice build script for macOS, release or debug version, 64 bit +# compile_macos_clang_M2.sh + +# Procedure: +# Install gcc, bison, flex, libtool, autoconf, automake, +# libx11 and libx11-dev (headers), libXaw and libXaw-dev, libreadline and dev +# XCODE, commandline tools +# Declare 'compile_macos_clang_M2.sh' executable and start compiling with +# './compile_macoss_clang_M2.sh' or './compile_macoss_clang_M2.sh d' from the ngspice directory. +# Options: +# CIDER may be selected at will. +# OpenMP has been installed from https://mac.r-project.org/openmp/ + +# ngspice as shared library: +# Replace --with-x by --with-ngshared in line ../configure ... . +# Add (optionally) --enable-relpath to avoid absolute paths when searching for code models. +# It might be necessary to uncomment and run ./autogen.sh . + +SECONDS=0 + +if test "$1" = "d"; then + if [ ! -d "debug" ]; then + mkdir debug + if [ $? -ne 0 ]; then echo "mkdir debug failed"; exit 1 ; fi + fi +else + if [ ! -d "release" ]; then + mkdir release + if [ $? -ne 0 ]; then echo "mkdir release failed"; exit 1 ; fi + fi +fi + +# If compiling sources from git, you may need to uncomment the following two lines: +./autogen.sh +if [ $? -ne 0 ]; then echo "./autogen.sh failed"; exit 1 ; fi + +echo +if test "$1" = "d"; then + cd debug + if [ $? -ne 0 ]; then echo "cd debug failed"; exit 1 ; fi + echo "configuring for 64 bit debug" + echo +# Builtin readline is not compatible (Big Sur), readline via Homebrew required (in /opt/homebrew/opt) +# Standard clang does not support OpenMP, uses https://mac.r-project.org/openmp/ + + ../configure --with-x --enable-cider --with-readline=/opt/homebrew/opt/readline --enable-debug CFLAGS="-m64 -O0 -g -Wall -I/opt/X11/include/freetype2 -I/opt/homebrew/opt/readline/include" LDFLAGS="-m64 -g -L/opt/homebrew/opt/readline/lib -L/opt/X11/lib -L/usr/local/lib -lomp" +else + cd release + if [ $? -ne 0 ]; then echo "cd release failed"; exit 1 ; fi + echo "configuring for 64 bit release" + echo + ../configure --with-x --enable-cider --with-readline=/opt/homebrew/opt/readline CFLAGS="-m64 -O2 -I/opt/X11/include/freetype2 -I/opt/homebrew/opt/readline/include -I/opt/homebrew/opt/ncurses/include" LDFLAGS="-m64 -L/opt/homebrew/opt/readline/lib -L/opt/homebrew/opt/ncurses/lib -L/opt/X11/lib -L/usr/local/lib -lomp" +fi +if [ $? -ne 0 ]; then echo "../configure failed"; exit 1 ; fi + +echo +# make clean is required for properly making the code models +echo "cleaning (see make_clean.log)" +make clean 2>&1 -j8 | tee make_clean.log +exitcode=${PIPESTATUS[0]} +if [ $exitcode -ne 0 ]; then echo "make clean failed"; exit 1 ; fi +echo "compiling (see make.log)" +make 2>&1 -j8 | tee make.log +exitcode=${PIPESTATUS[0]} +if [ $exitcode -ne 0 ]; then echo "make failed"; exit 1 ; fi +# Install to /usr/local +echo "installing (see make_install.log)" +make install 2>&1 | tee make_install.log +exitcode=${PIPESTATUS[0]} +if [ $exitcode -ne 0 ]; then echo "make install failed"; exit 1 ; fi + +ELAPSED="Elapsed compile time: $(($SECONDS / 3600))hrs $((($SECONDS / 60) % 60))min $(($SECONDS % 60))sec" +echo +echo $ELAPSED +echo "success" +exit 0 diff --git a/compile_macos_clang_M2_shared.sh b/compile_macos_clang_M2_shared.sh new file mode 100644 index 000000000..3ba0e1ef9 --- /dev/null +++ b/compile_macos_clang_M2_shared.sh @@ -0,0 +1,76 @@ +#!/bin/bash +# ngspice build script for macOS, release or debug version, 64 bit +# compile_macos_clang_M2.sh +# tested with Mac mini, Apple M2 + +# Procedure: +# Install gcc, bison, flex, libtool, autoconf, automake, +# libx11 and libx11-dev (headers), libXaw and libXaw-dev, libreadline and dev +# XCODE, commandline tools +# Declare 'compile_macos_clang_M2.sh' executable and start compiling with +# './compile_macoss_clang_M2.sh' or './compile_macoss_clang_M2.sh d' from the ngspice directory. +# Options: +# CIDER may be selected at will. +# OpenMP has been installed from https://mac.r-project.org/openmp/ + +# ngspice as shared library: +# Replace --with-x by --with-ngshared in line ../configure ... . +# Add (optionally) --enable-relpath to avoid absolute paths when searching for code models. +# It might be necessary to uncomment and run ./autogen.sh . + +SECONDS=0 + +if test "$1" = "d"; then + if [ ! -d "debug" ]; then + mkdir debug + if [ $? -ne 0 ]; then echo "mkdir debug failed"; exit 1 ; fi + fi +else + if [ ! -d "release" ]; then + mkdir release + if [ $? -ne 0 ]; then echo "mkdir release failed"; exit 1 ; fi + fi +fi + +# If compiling sources from git, you may need to uncomment the following two lines: +./autogen.sh +if [ $? -ne 0 ]; then echo "./autogen.sh failed"; exit 1 ; fi + +echo +if test "$1" = "d"; then + cd debug + if [ $? -ne 0 ]; then echo "cd debug failed"; exit 1 ; fi + echo "configuring for 64 bit debug" + echo + + ../configure --with-ngshared --enable-cider --with-readline=/opt/homebrew/opt/readline --enable-debug CFLAGS="-m64 -O0 -g -Wall -I/opt/X11/include/freetype2 -I/opt/homebrew/opt/readline/include" LDFLAGS="-m64 -g -L/opt/homebrew/opt/readline/lib -L/opt/X11/lib -L/usr/local/lib -lomp" +else + cd release + if [ $? -ne 0 ]; then echo "cd release failed"; exit 1 ; fi + echo "configuring for 64 bit release" + echo + ../configure --with-ngshared --enable-cider --with-readline=/opt/homebrew/opt/readline CFLAGS="-m64 -O2 -I/opt/X11/include/freetype2 -I/opt/homebrew/opt/readline/include -I/opt/homebrew/opt/ncurses/include" LDFLAGS="-m64 -L/opt/homebrew/opt/readline/lib -L/opt/homebrew/opt/ncurses/lib -L/opt/X11/lib -L/usr/local/lib -lomp" +fi +if [ $? -ne 0 ]; then echo "../configure failed"; exit 1 ; fi + +echo +# make clean is required for properly making the code models +echo "cleaning (see make_clean.log)" +make clean 2>&1 -j8 | tee make_clean.log +exitcode=${PIPESTATUS[0]} +if [ $exitcode -ne 0 ]; then echo "make clean failed"; exit 1 ; fi +echo "compiling (see make.log)" +make 2>&1 -j8 | tee make.log +exitcode=${PIPESTATUS[0]} +if [ $exitcode -ne 0 ]; then echo "make failed"; exit 1 ; fi +# Install to /usr/local +echo "installing (see make_install.log)" +make install 2>&1 | tee make_install.log +exitcode=${PIPESTATUS[0]} +if [ $exitcode -ne 0 ]; then echo "make install failed"; exit 1 ; fi + +ELAPSED="Elapsed compile time: $(($SECONDS / 3600))hrs $((($SECONDS / 60) % 60))min $(($SECONDS % 60))sec" +echo +echo $ELAPSED +echo "success" +exit 0 diff --git a/compile_macos_gcc.sh b/compile_macos_gcc.sh index f2272dab3..6bd1c0113 100755 --- a/compile_macos_gcc.sh +++ b/compile_macos_gcc.sh @@ -1,17 +1,16 @@ #!/bin/bash # ngspice build script for macOS, release or debug version, 64 bit # compile_macos.sh +# tested with macOS BigSur 11.7.9, MacBook Air i5 # Procedure: # Install gcc, bison, flex, libtool, autoconf, automake, # libx11 and libx11-dev (headers), libXaw and libXaw-dev, libreadline and dev -# Declare 'compile_linux.sh' executable and start compiling with +# XCODE and commandline tools +# Declare 'compile_macos_gcc.sh' executable and start compiling with # './compile_macos.sh' or './compile_macos.sh d' from the ngspice directory. # Options: -# --adms and --enable-adms will install extra HICUM, EKV and MEXTRAM models via the -# adms interface. You need to download and install the *.va files via ng-adms-va.tgz -# Please see the ngspice manual, chapt. 13, for more info on adms. -# CIDER, XSPICE, and OpenMP may be selected at will. +# KLU, OSDI, XSPICE, and OpenMP may be deselected at will. # --disable-debug will give O2 optimization (versus O0 for debug) and removes all debugging info. # ngspice as shared library: @@ -37,29 +36,21 @@ fi ./autogen.sh if [ $? -ne 0 ]; then echo "./autogen.sh failed"; exit 1 ; fi -# Alternatively, if compiling sources from git, and want to add adms created devices, -# you may need to uncomment the following two lines (and don't forget to add adms option -# to the ../configure statement): -#./autogen.sh --adms -#if [ $? -ne 0 ]; then echo "./autogen.sh failed"; exit 1 ; fi - echo if test "$1" = "d"; then cd debug if [ $? -ne 0 ]; then echo "cd debug failed"; exit 1 ; fi echo "configuring for 64 bit debug" echo -# You may add --enable-adms to the following command for adding adms generated devices # Builtin readline is not compatible (Big Sur), readline via Homebrew required (in /usr/local/opt) # Use gcc-11 from Homebrew to support OpenMP - ../configure --with-x --enable-xspice --enable-cider --enable-osdi --with-readline=/usr/local/opt/readline --enable-klu CC="gcc-11" CXX="g++-11" CFLAGS="-m64 -O0 -g -Wall -I/opt/X11/include/freetype2 -I/usr/local/opt/readline/include" LDFLAGS="-m64 -g -L/usr/local/opt/readline/lib -L/opt/X11/lib" + ../configure --with-x --enable-cider --with-readline=/usr/local/opt/readline CC="gcc-11" CXX="g++-11" CFLAGS="-m64 -O0 -g -Wall -I/opt/X11/include/freetype2 -I/usr/local/opt/readline/include" LDFLAGS="-m64 -g -L/usr/local/opt/readline/lib -L/opt/X11/lib" else cd release if [ $? -ne 0 ]; then echo "cd release failed"; exit 1 ; fi echo "configuring for 64 bit release" echo -# You may add --enable-adms to the following command for adding adms generated devices - ../configure --with-x --enable-xspice --enable-cider --enable-osdi --with-readline=/usr/local/opt/readline --disable-debug --enable-openmp --enable-klu CC="gcc-11" CXX="g++-11" CFLAGS="-m64 -O2 -I/opt/X11/include/freetype2 -I/usr/local/opt/readline/include -I/usr/local/opt/ncurses/include -I/usr/local/include" LDFLAGS="-m64 -L/usr/local/opt/readline/lib -L/usr/local/opt/ncurses/lib -L/opt/X11/lib -L/usr/local/lib" + ../configure --with-x --enable-cider --with-readline=/usr/local/opt/readline CC="gcc-11" CXX="g++-11" CFLAGS="-m64 -O2 -I/opt/X11/include/freetype2 -I/usr/local/opt/readline/include -I/usr/local/opt/ncurses/include -I/usr/local/include" LDFLAGS="-m64 -L/usr/local/opt/readline/lib -L/usr/local/opt/ncurses/lib -L/opt/X11/lib -L/usr/local/lib" fi if [ $? -ne 0 ]; then echo "../configure failed"; exit 1 ; fi diff --git a/compile_macos_shared.sh b/compile_macos_shared.sh index 35673abf7..9cd8664a0 100755 --- a/compile_macos_shared.sh +++ b/compile_macos_shared.sh @@ -1,21 +1,15 @@ #!/bin/bash # ngspice build script for MINGW in MSYS2, release or debug version, 64 bit # compile_min_shared.sh +# tested with macOS BigSur 11.7.9, MacBook Air i5 #Procedure: -# Install MSYS2, plus gcc 64 bit, bison, flex, autoconf, automake, libtool -# See https://github.com/orlp/dev-on-windows/wiki/Installing-GCC--&-MSYS2 # start compiling with -# './compile_min_shared.sh' for release or './compile_min_shared.sh d' +# './compile_macos_shared.sh' for release or './compile_macos_shared.sh d' # for debug version of shared ngspice # Options: -# --adms and --enable-adms will install extra HICUM, EKV and MEXTRAM models via the -# adms interface. -# Please see http://ngspice.sourceforge.net/admshowto.html for more info on adms. -# CIDER, XSPICE, and OpenMP may be selected at will. -# --disable-debug will give O2 optimization (versus O0 for debug) and removes all debugging info. -# To obtain a 32 bit executable, replace -m64 by -m32 ./configure lines. +# KLU, OSDI, XSPICE, and OpenMP may be deselected at will. # Add (optionally) --enable-relpath to avoid absolute paths when searching for code models. # It might be necessary to uncomment and run ./autogen.sh . @@ -38,28 +32,19 @@ fi ./autogen.sh if [ $? -ne 0 ]; then echo "./autogen.sh failed"; exit 1 ; fi -# Alternatively, if compiling sources from git, and want to add adms created devices, -# you may need to uncomment the following two lines (and don't forget to add adms option -# to the ../configure statement): -#./autogen.sh --adms -#if [ $? -ne 0 ]; then echo "./autogen.sh failed"; exit 1 ; fi - echo if test "$1" = "d"; then cd debug-sh if [ $? -ne 0 ]; then echo "cd debug-sh failed"; exit 1 ; fi echo "configuring for 64 bit debug" echo -# You may add --enable-adms to the following command for adding adms generated devices - ../configure --with-ngshared --enable-xspice --enable-cider --enable-openmp CFLAGS="-O0" LDFLAGS=" -lomp" + ../configure --with-ngshared --enable-cider CFLAGS="-O0" LDFLAGS=" -lomp" else cd release-sh if [ $? -ne 0 ]; then echo "cd release-sh failed"; exit 1 ; fi echo "configuring for 64 bit release" echo -# You may add --enable-adms to the following command for adding adms generated devices -# ../configure --with-ngshared --enable-xspice --enable-cider --enable-openmp --disable-debug CFLAGS="-O2" LDFLAGS="-lomp" - ../configure --with-ngshared --enable-xspice --enable-cider --disable-debug --enable-openmp CC="gcc-11" CXX="g++-11" CFLAGS="-m64 -O2 -I/usr/local/include" LDFLAGS="-m64 -L/usr/local/lib" + ../configure --with-ngshared --enable-cider CC="gcc-11" CXX="g++-11" CFLAGS="-m64 -O2 -I/usr/local/include" LDFLAGS="-m64 -L/usr/local/lib" fi if [ $? -ne 0 ]; then echo "../configure failed"; exit 1 ; fi diff --git a/compile_min.sh b/compile_min.sh index b26d5b7a3..6f030acc0 100755 --- a/compile_min.sh +++ b/compile_min.sh @@ -10,15 +10,18 @@ # './compile_min.sh' for release or './compile_min.sh d' for debug version. # Options: -# CIDER, XSPICE, OpenMP, OSDI, and KLU may be selected at will. -# --disable-debug will give O2 optimization (versus O0 for debug) and removes all debugging info. +# CIDER may be selected at will. +# XSPICE, OpenMP, OSDI, and KLU may be deselected. if not required. # --enable-oldapps will make ngnutmeg ngsconvert ngproc2mod ngmultidec ngmakeidx in addition to ngspice -# ngspice as shared library: -# Replace --with-wingui by --with-ngshared in line ../configure ... . -# Add (optionally) --enable-relpath to avoid absolute paths when searching for code models. +# ngspice as console app: +# Install readline, ncurses +# Remove --with-wingui in line ../configure ... . # It might be necessary to uncomment and run ./autogen.sh . +# ngspice as shared library: +# Use compile_min_shared.sh + SECONDS=0 if test "$1" = "d"; then @@ -43,13 +46,19 @@ if test "$1" = "d"; then if [ $? -ne 0 ]; then echo "cd debug failed"; exit 1 ; fi echo "configuring for 64 bit debug" echo - ../configure --with-wingui --enable-xspice --enable-cider --enable-klu --enable-openmp --enable-osdi --enable-predictor prefix="C:/Spice64d" CFLAGS="-g -m64 -O0 -Wall -Wno-unused-but-set-variable" LDFLAGS="-g -m64" +# executable with GUI + ../configure --with-wingui --enable-cider prefix="C:/Spice64d" CFLAGS="-g -m64 -O0 -Wall -Wno-unused-but-set-variable" LDFLAGS="-g -m64" +# console executable +# ../configure --enable-cider prefix="C:/Spice64d" CFLAGS="-g -m64 -O0 -Wall -Wno-unused-but-set-variable" LDFLAGS="-g -m64" else cd release if [ $? -ne 0 ]; then echo "cd release failed"; exit 1 ; fi echo "configuring for 64 bit release" echo - ../configure --with-wingui --enable-xspice --enable-cider --enable-klu --enable-openmp --enable-osdi --enable-predictor --disable-debug prefix="C:/Spice64" CFLAGS="-m64 -O2" LDFLAGS="-m64 -s" +# executable with GUI + ../configure --with-wingui --enable-cider prefix="C:/Spice64" CFLAGS="-m64 -O2" LDFLAGS="-m64 -s" +# console executable +# ../configure --with-wingui=no --enable-cider prefix="C:/Spice64" CFLAGS="-m64 -O2" LDFLAGS="-m64 -s" fi if [ $? -ne 0 ]; then echo "../configure failed"; exit 1 ; fi diff --git a/compile_min_shared.sh b/compile_min_shared.sh index 547306116..b8231c5f1 100644 --- a/compile_min_shared.sh +++ b/compile_min_shared.sh @@ -11,9 +11,9 @@ # Options: # Please see http://ngspice.sourceforge.net/admshowto.html for more info on adms. -# CIDER, XSPICE, KLU, and OpenMP may be selected at will. -# --disable-debug will give O2 optimization (versus O0 for debug) and removes all debugging info. -# To obtain a 32 bit executable, replace -m64 by -m32 ./configure lines. +# CIDER may be selected at will. +# XSPICE, KLU, and OpenMP may be deselected, if not required. +# To obtain a 32 bit executable, replace -m64 by -m32 ./configure lines (not tested). # Add (optionally) --enable-relpath to avoid absolute paths when searching for code models. # It might be necessary to uncomment and run ./autogen.sh . @@ -42,13 +42,13 @@ if test "$1" = "d"; then if [ $? -ne 0 ]; then echo "cd debug-sh failed"; exit 1 ; fi echo "configuring for 64 bit debug" echo - ../configure --with-ngshared --enable-xspice --enable-cider --enable-openmp --enable-osdi --enable-klu --enable-relpath prefix="C:/Spice64d" CFLAGS="-m64 -g -O0 -Wall" LDFLAGS="-m64" + ../configure --with-ngshared --enable-cider --enable-relpath prefix="C:/Spice64d" CFLAGS="-m64 -g -O0 -Wall" LDFLAGS="-m64" else cd release-sh if [ $? -ne 0 ]; then echo "cd release-sh failed"; exit 1 ; fi echo "configuring for 64 bit release" echo - ../configure --with-ngshared --enable-xspice --enable-cider --enable-openmp --enable-osdi --enable-klu --enable-relpath --disable-debug prefix="C:/Spice64" CFLAGS="-m64 -O2" LDFLAGS="-m64 -s" + ../configure --with-ngshared --enable-cider --enable-relpath --disable-debug prefix="C:/Spice64" CFLAGS="-m64 -O2" LDFLAGS="-m64 -s" fi if [ $? -ne 0 ]; then echo "../configure failed"; exit 1 ; fi diff --git a/configure.ac b/configure.ac index 6bd49a597..2fd124576 100644 --- a/configure.ac +++ b/configure.ac @@ -16,7 +16,7 @@ # problem to the user. AC_PREREQ([2.59]) -m4_define([ngspice_major_version], [42+]) +m4_define([ngspice_major_version], [43+]) m4_define([ngspice_minor_version], [0]) m4_define([ngspice_version], [ngspice_major_version]) @@ -117,7 +117,7 @@ LT_INIT([shared static]) # --> Set 'LT_NGSPICE_AGE' to 0. LT_NGSPICE_CURRENT=0 -LT_NGSPICE_REVISION=9 +LT_NGSPICE_REVISION=10 LT_NGSPICE_AGE=0 LIBNGSPICE_SO_VERSION=$LT_NGSPICE_CURRENT.$LT_NGSPICE_REVISION.$LT_NGSPICE_AGE @@ -409,12 +409,15 @@ fi #### ### check for operating system at compile time +AM_CONDITIONAL([DLIBS_FULLY_RESOLVED], false) case $host_os in *mingw* | *msys* ) AC_DEFINE([OS_COMPILED], [1], [MINGW for MS Windows]) + AM_CONDITIONAL([DLIBS_FULLY_RESOLVED], true) ;; *cygwin* ) AC_DEFINE([OS_COMPILED], [2], [Cygwin for MS Windows]) + AM_CONDITIONAL([DLIBS_FULLY_RESOLVED], true) ;; *freebsd* ) AC_DEFINE([OS_COMPILED], [3], [FreeBSD]) @@ -907,7 +910,7 @@ AC_CHECK_FUNCS([localtime]) AC_CHECK_FUNCS([ftime gettimeofday]) # Do not use time or getrusage function for CPU time measurement under OpenMP -if test "x$enable_openmp" != xyes; then +if test "x$enable_openmp" = xno; then AC_CHECK_FUNCS([time getrusage]) fi AC_CHECK_FUNCS([utimes]) @@ -989,10 +992,12 @@ AM_CONDITIONAL([RELPATH], [test "x$enable_relpath" = xyes]) if test "x$enable_relpath" = xyes; then AC_DEFINE_UNQUOTED([NGSPICEBINDIR], ["`echo ../bin`"], [Define the directory for executables]) AC_DEFINE_UNQUOTED([NGSPICEDATADIR], ["`echo ../share/ngspice`"], [Define the directory for architecture independent data files]) + AC_DEFINE_UNQUOTED([NGSPICELIBDIR], ["`echo ../lib/ngspice`"], [Define the directory for architecture-dependent libraries]) AC_DEFINE([HAS_RELPATH], [1], [rel. path of libraries and scripts]) else AC_DEFINE_UNQUOTED([NGSPICEBINDIR], ["`echo $dprefix/bin`"], [Define the directory for executables]) AC_DEFINE_UNQUOTED([NGSPICEDATADIR], ["`echo $dprefix/share/ngspice`"], [Define the directory for architecture independent data files]) +AC_DEFINE_UNQUOTED([NGSPICELIBDIR], ["`echo $dprefix/lib/ngspice`"], [Define the directory for architecture-dependent libraries]) fi # Create timestamp, may be overruled by setting env var SOURCE_DATE_EPOCH @@ -1252,63 +1257,68 @@ if test "x$enable_expdevices" = xyes; then fi # ---- Option to include GNU readline support in ngspice CLI ---- -# ---- Default: disabled. ---- +# ---- Default: enabled. ---- # ---- Hope to see in the future readline replacement. ---- -if test "x$with_readline" = xno ; then +if test "x$with_wingui" = xyes || test "x$with_ngshared" = xyes; then AC_MSG_RESULT([GNU readline disabled.]) -else - if test "x$with_readline" = x || test "x$with_readline" = xyes ; then - if test "x$with_tcl" = x || test "x$with_tcl" = xno ; then - AC_MSG_RESULT([Checking for readline:]) - AC_CHECK_HEADERS([readline/readline.h readline/history.h], - [AC_DEFINE([HAVE_GNUREADLINE], [], [Define if we have GNU readline])], - [AC_MSG_ERROR([Couldn't find GNU readline headers.])]) - AC_SEARCH_LIBS([tputs], [ncurses tinfo termcap], - [AC_DEFINE([HAVE_TERMCAP], [], [Define if we have ncurses/terminfo or termcap])], - [AC_MSG_ERROR([Found neither ncurses/terminfo or termcap])]) - AC_CHECK_LIB([readline], [readline], - [LIBS="$LIBS -lreadline"], - [AC_MSG_ERROR([Couldn't find readline libraries.])]) - fi - else -# Especially defined for macOS (Big Sur), with readline installed from Brew - for dir in \ - $with_readline - do - if test "x$with_tcl" = x || test "x$with_tcl" = xno ; then - AC_MSG_RESULT([Checking for readline:]) - AC_CHECK_HEADERS([$dir/include/readline/readline.h $dir/include/readline/history.h], - [AC_DEFINE([HAVE_GNUREADLINE], [], [Define if we have GNU readline])], - [AC_MSG_ERROR([Couldn't find GNU readline headers.])]) - AC_SEARCH_LIBS([tputs], [ncurses tinfo termcap], - [AC_DEFINE([HAVE_TERMCAP], [], [Define if we have ncurses/terminfo or termcap])], - [AC_MSG_ERROR([Found neither ncurses/terminfo or termcap])]) - AC_CHECK_LIB([readline], [readline], - [LIBS="$LIBS -lreadline"], - [AC_MSG_ERROR([Couldn't find readline libraries.])]) - fi - done - fi -fi - -# ---- Option to include BSD editline support in ngspice CLI ---- -# ---- Default: disabled. ---- - -if test "x$with_editline" != xyes; then AC_MSG_RESULT([BSD editline disabled.]) else - AC_MSG_RESULT([Checking for editline:]) - AC_CHECK_HEADERS([editline/readline.h], - [AC_DEFINE([HAVE_BSDEDITLINE], [1], [Define to enable BSD editline])], - [AC_MSG_ERROR([Couldn't find BSD editline headers.])]) - AC_SEARCH_LIBS([tputs], [ncurses tinfo termcap], - [AC_DEFINE([HAVE_TERMCAP], [], [Define if we have ncurses/terminfo or termcap])], - [AC_MSG_ERROR([Found neither ncurses/terminfo or termcap])]) - AC_CHECK_LIB([edit], [readline], - [LIBS="$LIBS -ledit"], - [AC_MSG_ERROR([Couldn't find editline libraries.])], - [-lncurses]) + if test "x$with_readline" = xno ; then + AC_MSG_RESULT([GNU readline disabled.]) + else + if test "x$with_readline" = x || test "x$with_readline" = xyes ; then + if test "x$with_tcl" = x || test "x$with_tcl" = xno ; then + AC_MSG_RESULT([Checking for readline:]) + AC_CHECK_HEADERS([readline/readline.h readline/history.h], + [AC_DEFINE([HAVE_GNUREADLINE], [], [Define if we have GNU readline])], + [AC_MSG_ERROR([Couldn't find GNU readline headers.])]) + AC_SEARCH_LIBS([tputs], [ncurses tinfo termcap], + [AC_DEFINE([HAVE_TERMCAP], [], [Define if we have ncurses/terminfo or termcap])], + [AC_MSG_ERROR([Found neither ncurses/terminfo or termcap])]) + AC_CHECK_LIB([readline], [readline], + [LIBS="$LIBS -lreadline"], + [AC_MSG_ERROR([Couldn't find readline libraries.])]) + fi + else + # Especially defined for macOS (Big Sur), with readline installed from Brew + for dir in \ + $with_readline + do + if test "x$with_tcl" = x || test "x$with_tcl" = xno ; then + AC_MSG_RESULT([Checking for readline:]) + AC_CHECK_HEADERS([$dir/include/readline/readline.h $dir/include/readline/history.h], + [AC_DEFINE([HAVE_GNUREADLINE], [], [Define if we have GNU readline])], + [AC_MSG_ERROR([Couldn't find GNU readline headers.])]) + AC_SEARCH_LIBS([tputs], [ncurses tinfo termcap], + [AC_DEFINE([HAVE_TERMCAP], [], [Define if we have ncurses/terminfo or termcap])], + [AC_MSG_ERROR([Found neither ncurses/terminfo or termcap])]) + AC_CHECK_LIB([readline], [readline], + [LIBS="$LIBS -lreadline"], + [AC_MSG_ERROR([Couldn't find readline libraries.])]) + fi + done + fi + fi + + # ---- Option to include BSD editline support in ngspice CLI ---- + # ---- Default: disabled. ---- + + if test "x$with_editline" != xyes; then + AC_MSG_RESULT([BSD editline disabled.]) + else + AC_MSG_RESULT([Checking for editline:]) + AC_CHECK_HEADERS([editline/readline.h], + [AC_DEFINE([HAVE_BSDEDITLINE], [1], [Define to enable BSD editline])], + [AC_MSG_ERROR([Couldn't find BSD editline headers.])]) + AC_SEARCH_LIBS([tputs], [ncurses tinfo termcap], + [AC_DEFINE([HAVE_TERMCAP], [], [Define if we have ncurses/terminfo or termcap])], + [AC_MSG_ERROR([Found neither ncurses/terminfo or termcap])]) + AC_CHECK_LIB([edit], [readline], + [LIBS="$LIBS -ledit"], + [AC_MSG_ERROR([Couldn't find editline libraries.])], + [-lncurses]) + fi fi # Use AC_CHECK_HEADERS so the HAVE_*_H symbol gets defined @@ -1436,6 +1446,7 @@ AC_CONFIG_FILES([Makefile src/xspice/enh/Makefile src/xspice/ipc/Makefile src/xspice/idn/Makefile + src/xspice/verilog/Makefile src/osdi/Makefile tests/Makefile tests/bsim1/Makefile diff --git a/examples/mos/nmos_out_BSIM330_plainwrite.sp b/examples/mos/nmos_out_BSIM330_plainwrite.sp index e86970dad..70dca02ca 100644 --- a/examples/mos/nmos_out_BSIM330_plainwrite.sp +++ b/examples/mos/nmos_out_BSIM330_plainwrite.sp @@ -15,7 +15,7 @@ vss2 +32 0 0 .options Temp=27.0 -* BSIM3v3.3.0 model with modified default parameters 0.18m +* BSIM3v3.3.0 model with modified default parameters 0.18µm .model n1 nmos level=49 version=3.3.0 tox=3.5n nch=2.4e17 nsub=5e16 vth0=0.15 .model p1 pmos level=49 version=3.3.0 tox=3.5n nch=2.5e17 nsub=5e16 vth0=-0.15 diff --git a/examples/mos/nmos_out_BSIM330_svg.sp b/examples/mos/nmos_out_BSIM330_svg.sp index a631265d0..c1d8a1762 100644 --- a/examples/mos/nmos_out_BSIM330_svg.sp +++ b/examples/mos/nmos_out_BSIM330_svg.sp @@ -14,7 +14,7 @@ vss2 32 0 0 .options Temp=27.0 -* BSIM3v3.3.0 model with modified default parameters 0.18m +* BSIM3v3.3.0 model with modified default parameters 0.18µm .model n1 nmos level=49 version=3.3.0 tox=3.5n nch=2.4e17 nsub=5e16 vth0=0.15 .model p1 pmos level=49 version=3.3.0 tox=3.5n nch=2.5e17 nsub=5e16 vth0=-0.15 diff --git a/examples/mos/nmos_pmos_BSIM330.sp b/examples/mos/nmos_pmos_BSIM330.sp index 6d8d21776..2c6632d86 100644 --- a/examples/mos/nmos_pmos_BSIM330.sp +++ b/examples/mos/nmos_pmos_BSIM330.sp @@ -12,7 +12,7 @@ vdsp 22 0 -0.1 vssp 33 0 0 vbsp 44 0 0 -* BSIM3v3.3.0 model with modified default parameters 0.18m +* BSIM3v3.3.0 model with modified default parameters 0.18µm .model n1 nmos level=49 version=3.3.0 tox=3.5n nch=2.4e17 nsub=5e16 vth0=0.15 .model p1 pmos level=49 version=3.3.0 tox=3.5n nch=2.5e17 nsub=5e16 vth0=-0.15 diff --git a/examples/mos/nmos_pmos_drainresistor.sp b/examples/mos/nmos_pmos_drainresistor.sp index 5501b0249..378214931 100644 --- a/examples/mos/nmos_pmos_drainresistor.sp +++ b/examples/mos/nmos_pmos_drainresistor.sp @@ -16,12 +16,12 @@ vbsp 44 0 0 .options Temp=27.0 -* BSIM3v3.3.0 model with modified default parameters 0.18m +* BSIM3v3.3.0 model with modified default parameters 0.18µm .model n1 nmos level=49 version=3.3.0 tox=3.5n nch=2.4e17 nsub=5e16 vth0=0.15 .model p1 pmos level=49 version=3.3.0 tox=3.5n nch=2.5e17 nsub=5e16 vth0=-0.15 -*.include ./Modelcards/modelcard.nmos $ Berkeley model cards limited to L >= 0.35m -*.include ./Modelcards/modelcard.pmos $ Berkeley model cards limited to L >= 0.35m +*.include ./Modelcards/modelcard.nmos $ Berkeley model cards limited to L >= 0.35µm +*.include ./Modelcards/modelcard.pmos $ Berkeley model cards limited to L >= 0.35µm * update of the default parameters required *.model n1 NMOS level=49 version=3.3.0 $ nearly no current due to VT > 2 V ? diff --git a/examples/mos/nmos_pmos_plotting.sp b/examples/mos/nmos_pmos_plotting.sp index 6870d7b99..ef69d486e 100644 --- a/examples/mos/nmos_pmos_plotting.sp +++ b/examples/mos/nmos_pmos_plotting.sp @@ -16,12 +16,12 @@ vbsp 44 0 0 .options Temp=27.0 -* BSIM3v3.3.0 model with modified default parameters 0.18m +* BSIM3v3.3.0 model with modified default parameters 0.18µm .model n1 nmos level=49 version=3.3.0 tox=3.5n nch=2.4e17 nsub=5e16 vth0=0.15 .model p1 pmos level=49 version=3.3.0 tox=3.5n nch=2.5e17 nsub=5e16 vth0=-0.15 -*.include ./Modelcards/modelcard.nmos $ Berkeley model cards limited to L >= 0.35m -*.include ./Modelcards/modelcard.pmos $ Berkeley model cards limited to L >= 0.35m +*.include ./Modelcards/modelcard.nmos $ Berkeley model cards limited to L >= 0.35µm +*.include ./Modelcards/modelcard.pmos $ Berkeley model cards limited to L >= 0.35µm * update of the default parameters required *.model n1 NMOS level=49 version=3.3.0 $ nearly no current due to VT > 2 V ? diff --git a/examples/svg/nmos_out_BSIM330_svg.sp b/examples/svg/nmos_out_BSIM330_svg.sp index a4b5da9a3..a543b3a98 100644 --- a/examples/svg/nmos_out_BSIM330_svg.sp +++ b/examples/svg/nmos_out_BSIM330_svg.sp @@ -14,7 +14,7 @@ vss2 32 0 0 .options Temp=27.0 -* BSIM3v3.3.0 model with modified default parameters 0.18m +* BSIM3v3.3.0 model with modified default parameters 0.18µm .model n1 nmos level=49 version=3.3.0 tox=3.5n nch=2.4e17 nsub=5e16 vth0=0.15 .model p1 pmos level=49 version=3.3.0 tox=3.5n nch=2.5e17 nsub=5e16 vth0=-0.15 diff --git a/examples/svg/nmos_out_BSIM330_various.sp b/examples/svg/nmos_out_BSIM330_various.sp index e9e56138b..15b73ecfd 100644 --- a/examples/svg/nmos_out_BSIM330_various.sp +++ b/examples/svg/nmos_out_BSIM330_various.sp @@ -14,7 +14,7 @@ vss2 32 0 0 .options Temp=27.0 -* BSIM3v3.3.0 model with modified default parameters 0.18m +* BSIM3v3.3.0 model with modified default parameters 0.18µm .model n1 nmos level=49 version=3.3.0 tox=3.5n nch=2.4e17 nsub=5e16 vth0=0.15 .model p1 pmos level=49 version=3.3.0 tox=3.5n nch=2.5e17 nsub=5e16 vth0=-0.15 diff --git a/examples/xspice/icarus_verilog/555.cir b/examples/xspice/icarus_verilog/555.cir new file mode 100644 index 000000000..165ceb2f8 --- /dev/null +++ b/examples/xspice/icarus_verilog/555.cir @@ -0,0 +1,10 @@ +Verilog-controlled simple timer. + +* This is the model for an RS flip-flop implemented by Icarus Verilog. + +.model vlog_ff d_cosim simulation="ivlng" sim_args=["555"] + +* The bulk of the circuit is in a shared file. + +.include ../verilator/555.shared +.end diff --git a/examples/xspice/icarus_verilog/README.txt b/examples/xspice/icarus_verilog/README.txt new file mode 100644 index 000000000..f61f9498b --- /dev/null +++ b/examples/xspice/icarus_verilog/README.txt @@ -0,0 +1,46 @@ +The circuits in this directory illustrate the use of the d_cosim +XSPICE code model as a container for a Verilog simulation using +Icarus Verilog. Icarus Verilog must be built with the --enable-libvvp option, +so that its simulation engine is available as a dynamic library. +The Verilog source code and included parts of the circuit definitions +can be found in the adjacent "verilator" directory. + +The example circuits are: + +555.cir: The probably familiar NE555 oscillator provides a minimal example +of combined simulation with SPICE and Verilog. +The digital part of the IC, a simple SR flip-flop, is expressed in Verilog. + +delay.v: A very simple example of using delays in Verilog to generate +waveform outputs. + +pwm.c: Verilog delays controlling a pulse-width modulated output generate +an approximate sine wave. + +adc.cir: Slightly more complex Verilog describes the controlling part +of a switched-capacitor ADC. + +Before a simulation can be run, the associated Verilog code must be compiled: + + iverilog -o 555 ../verilator/555.v + +Similar compilations are needed to prepare the other examples. + +The simulations require additional dynamic libraries, ivlng.so (or ivlng.DLL) +and ivlng.vpi: they are expected to be in the usual installation location. + +To use the versions in a built source tree that has not been installed, +the .model definitions in the circuit files must be changed to the ugly: + +.model vlog_ff d_cosim sim_args=["555"] ++ simulation = "../../../release/src/xspice/verilog/.libs/ivlng" ++ lib_args = [ "libvvp" ++ "../../../release/src/xspice/verilog/.libs/ivlngvpi.so" ] + +Or for Windows builds using MSVC: + +.model vlog_ff d_cosim sim_args=["555"] ++ simulation = "..\..\..\visualc\xspice\verilog\ivlng.DLL" ++ lib_args = [ "libvvp" ++ "..\..\..\visualc\xspice\verilog\shim.vpi" ] + diff --git a/examples/xspice/icarus_verilog/adc.cir b/examples/xspice/icarus_verilog/adc.cir new file mode 100644 index 000000000..b717c1439 --- /dev/null +++ b/examples/xspice/icarus_verilog/adc.cir @@ -0,0 +1,10 @@ +Simulation of a switched-capacitor SAR ADC with Verilator and d_cosim + +* Model line for the digital control implemented by Icarus Verilog. + +.model dut d_cosim simulation="ivlng" sim_args=["adc"] + +* The bulk of the circuit is in a shared file. + +.include ../verilator/adc.shared +.end diff --git a/examples/xspice/icarus_verilog/delay.cir b/examples/xspice/icarus_verilog/delay.cir new file mode 100644 index 000000000..efa0cdcee --- /dev/null +++ b/examples/xspice/icarus_verilog/delay.cir @@ -0,0 +1,10 @@ +* Waveform generation by Verilog delays + +adut null [ d4 d3 d2 d1 d0 ] ring +.model ring d_cosim simulation="ivlng" sim_args = [ "delay" ] + +.control +tran 20u 100u +plot d4 d3 d2 d1 d0 digitop +.endc +.end diff --git a/examples/xspice/icarus_verilog/pwm.cir b/examples/xspice/icarus_verilog/pwm.cir new file mode 100644 index 000000000..6de998c43 --- /dev/null +++ b/examples/xspice/icarus_verilog/pwm.cir @@ -0,0 +1,12 @@ +* Waveform generation by PWM in Verilog + +adut null [ out ] pwm_sin +.model pwm_sin d_cosim simulation="ivlng" sim_args = [ "pwm" ] + +r1 out smooth 100k +c1 smooth 0 1u +.control +tran 1m 2 +plot out-3.3 smooth +.endc +.end diff --git a/examples/xspice/verilator/555.cir b/examples/xspice/verilator/555.cir new file mode 100644 index 000000000..f8d408645 --- /dev/null +++ b/examples/xspice/verilator/555.cir @@ -0,0 +1,11 @@ +Verilog-controlled simple timer. + +* This is the model for an RS flip-flop implemented by Verilator. + +.model vlog_ff d_cosim simulation="./555" + +* The bulk of the circuit is in a shared file. + +.include 555.shared +.end + diff --git a/examples/xspice/verilator/555.shared b/examples/xspice/verilator/555.shared new file mode 100644 index 000000000..3c763675b --- /dev/null +++ b/examples/xspice/verilator/555.shared @@ -0,0 +1,60 @@ +* This file is not intended to be used directly, but by 555.cir. +* That allows it to be shared by different implemnetations. + +* This sub-circuit simulates the NE555 timer IC, with the very simple +* digital part as a Verilog module. + +.subckt NE555 trigger threshold reset control output discharge vcc ground + +* Resistor chain + +r1 vcc control 5k +r2 control trigger_ref 5k +r3 trigger_ref ground 5k + +* Two XSPICE ADC instances serve as comparators. + +.model comparator adc_bridge(in_low = -0.0001 in_high = 0.0001) +athresh_comparator [%vd threshold control] [over_threshold] comparator +atrigger_comparator [%vd trigger_ref trigger] [under_trigger] comparator + +* A tiny Verilog module supplies the flip-flop. +* The model is supplied by the outer circuit file. + +averilog [ under_trigger over_threshold reset ] [ output qbar ] vlog_ff + +* The discharge transistor and its base resistor. + +rbase qbar discharge_base 10k +qdischarge discharge discharge_base ground npn_transistor +.model npn_transistor npn + +.ends ; Ends subcircuit NE555 + + +* The usual 555 oscillator with threshold connected to discharge. + +.param vcc=12 + +X555 trigger_threshold trigger_threshold reset control output discharge vcc 0 ne555 + +r1 vcc discharge 10k +r2 discharge trigger_threshold 10k +Ct trigger_threshold 0 1uF ic=0 + +* A resistive load forces analog output. + +rload output 0 1k + +* A voltage source for power. + +Vcc vcc 0 {vcc} + +* Pulse the Reset signal low for 2uS each 51mS + +Vpulse reset 0 PULSE {vcc} 0.2 0 1u 1u 2u 51m + +.control +tran 10u 200m uic +plot trigger_threshold output x555.under_trigger-3 x555.over_threshold-1.5 +.endc diff --git a/examples/xspice/verilator/555.v b/examples/xspice/verilator/555.v new file mode 100644 index 000000000..acd7d6c91 --- /dev/null +++ b/examples/xspice/verilator/555.v @@ -0,0 +1,26 @@ +// Very simple logic for a 555 timer simulation + +`timescale 1us/100ns + +module VL555(Trigger, Threshold, Reset, Q, Qbar); + input wire Trigger, Threshold, Reset; // Reset is active low. + output reg Q; + output wire Qbar; + + wire ireset, go; + + assign Qbar = !Q; + + // The datasheet implies that Trigger overrides Threshold. + + assign go = Trigger & Reset; + assign ireset = (Threshold & !Trigger) | !Reset; + + initial begin + Q = 0; + end + + always @(posedge(go), posedge(ireset)) begin + Q = go; + end +endmodule diff --git a/examples/xspice/verilator/README.txt b/examples/xspice/verilator/README.txt index e919ceab5..a8e39ab63 100644 --- a/examples/xspice/verilator/README.txt +++ b/examples/xspice/verilator/README.txt @@ -1,10 +1,32 @@ -The circuit adc.cir in this directory illustrates the use of the d_cosim -XSPICE code model as a container for a Verilog simulation. Before the -simulation can be run, the Verilog code must be compiled by Verilator -using the command: +The circuits in this directory illustrate the use of the d_cosim +XSPICE code model as a container for a Verilog simulation, using the +Verilator compiler. The example circuits are: - ngspice vlnggen adc.v +555.cir: The probably familiar NE555 oscillator provides a minimal example +of combined simulation with SPICE and Verilog. The digital part of the IC, +a simple SR flip-flop, is expressed in Verilog. -That should create a shared library file, adc.so (or adc.DLL on Windows) +delay.v: A very simple example of using delays in Verilog to generate +waveform outputs. + +pwm.c: Verilog delays controlling a pulse-width modulated output generate +an approximate sine wave. + +adc.cir: Slightly more complex Verilog describes the controlling part +of a switched-capacitor ADC. + +Before a simulation can be run, the associated Verilog code must be compiled +by Verilator using a command script that is included with ngspice: + + ngspice vlnggen 555.v + +That should create a shared library file, 555.so (or 555.DLL on Windows) that will be loaded by the d_cosim code model. The compiled Verilog code that -it contains will be executed during simulation. +it contains will be executed during simulation. Similar compilations +are needed to prepare the other examples, but for Verilog with delays the +command looks like: + + ngspice vlnggen -- --timing delay.v + +(The "--" prevents "--timing" from being treated as a ngspice option, so it is +passed on to Verilator.) diff --git a/examples/xspice/verilator/adc.cir b/examples/xspice/verilator/adc.cir index 133a7dbf6..3ef5a433b 100644 --- a/examples/xspice/verilator/adc.cir +++ b/examples/xspice/verilator/adc.cir @@ -1,103 +1,10 @@ Simulation of a switched-capacitor SAR ADC with Verilator and d_cosim -.subckt sar_adc input vref start valid d5 d4 d3 d2 d1 d0 clk +* Model line for the digital control implemented by Verilator. -* A transmission gate connects the input to the capacitor set. +.model dut d_cosim simulation="./adc" -xsample input iin sample vref tgate -rin iin test_v 1k +* The bulk of the circuit is in a shared file. -* Capacitors and controlling inverters - -xb5 test_v vref d5 ccap c=1p -xb4 test_v vref d4 ccap c={1p / 2} -xb3 test_v vref d3 ccap c={1p / 4} -xb2 test_v vref d2 ccap c={1p / 8} -xb1 test_v vref d1 ccap c={1p / 16} -xb0 test_v vref d0 ccap c={1p / 32} -clast test_v 0 {1p / 32} - -* An XSPICE ADC bridge functions as a comparator. - -acomp [%vd(test_v vref)] [comp] comparator -.model comparator adc_bridge in_low=0 in_high=0 - -* The digital portion of the circuit is specified in compiled Verilog. -* Outputs inverted to cancel the inverter in subcircuit ccap, -* and produce the correct numerical output value. - -adut [ Clk Comp Start] [Sample Valid ~d5 ~d4 ~d3 ~d2 ~d1 ~d0] null dut -.model dut d_cosim simulation="./adc.so" -.ends // SUBCKT sar_adc - -* Some MOS transistors complete the circuit. -* Models from https://homepages.rpi.edu/~sawyes/AIMSPICE_TutorialManual.pdf - -.model p1 pmos -+ level=2 vto=-0.5 kp=8.5e-6 gamma=0.4 phi=0.65 lambda=0.05 xj=0.5e-6 -.model n1 nmos -+ level=2 vto=0.5 kp=24e-6 gamma=0.15 phi=0.65 lambda=0.015 xj=0.5e-6 - -* Use those for an inverter. - -.subckt ainv in out vdd -mn out in 0 0 n1 -mp out in vdd vdd p1 -.ends - -* A transmission gate modelled by a switch. - -.subckt mos_tgate a b ctl vdd -mn a ctl b b n1 -xinv ctl ictl vdd ainv -mp b ictl a a p1 -.ends - -.subckt tgate a b ctl vdd -switch a b ctl 0 tg -.model tg sw vt=1.5 ron=2k -.ends - -* The per-bit subcircuit in the adc - -.subckt ccap in vcc ctl c=10p -xinv ctl tail vcc ainv -cb in tail {c} -.ends - -**** End of the ADC and its subcircuits. Begin test circuit **** - -.param vcc=3.3 -vcc vcc 0 {vcc} - -* Digital clock signal - -aclock 0 clk clock -.model clock d_osc cntl_array=[-1 1] freq_array=[1Meg 1Meg] - -* A simple DAC so that the result may be compared to the input. - -r5 d5 sum 2 -r4 d4 sum 4 -r3 d3 sum 8 -r2 d2 sum 16 -r1 d1 sum 32 -r0 d0 sum 64 - -vamm sum 0 0 - -* Pulse the Start signal high for 1.3uS each 10uS - -Vpulse Start 0 PULSE 0 {vcc} 0.2u 10n 10n 1.3u 10u -Vtest input 0 PULSE 0 3 0 200u 200u 1u 401u - -* The ADC for testing - -xtest input vcc start valid d5 d4 d3 d2 d1 d0 clk sar_adc - - -.control -tran 100n 250u -plot input xtest.test_v vamm#branch clk/2 start/3 xtest.sample/3 valid -.endc +.include adc.shared .end diff --git a/examples/xspice/verilator/adc.shared b/examples/xspice/verilator/adc.shared new file mode 100644 index 000000000..0501f5dd3 --- /dev/null +++ b/examples/xspice/verilator/adc.shared @@ -0,0 +1,107 @@ +* This file is not intended to be used directly, but by adc.cir. +* That allows it to be shared by different implemnetations. + +* Simulation of a switched-capacitor SAR ADC with Verilator and d_cosim + +.subckt sar_adc input vref start valid d5 d4 d3 d2 d1 d0 clk + +* A transmission gate connects the input to the capacitor set. + +xsample input iin sample vref tgate +rin iin test_v 1k + +* Capacitors and controlling inverters + +xb5 test_v vref d5 ccap c=1p +xb4 test_v vref d4 ccap c={1p / 2} +xb3 test_v vref d3 ccap c={1p / 4} +xb2 test_v vref d2 ccap c={1p / 8} +xb1 test_v vref d1 ccap c={1p / 16} +xb0 test_v vref d0 ccap c={1p / 32} +clast test_v 0 {1p / 32} + +* An XSPICE ADC bridge functions as a comparator. + +acomp [%vd(test_v vref)] [comp] comparator +.model comparator adc_bridge in_low=0 in_high=0 + +* The digital portion of the circuit is specified in compiled Verilog. +* Outputs inverted to cancel the inverter in subcircuit ccap, +* and produce the correct numerical output value. The model definition +* is supplied by the calling circuit file. + +adut [ Clk Comp Start] [Sample Valid ~d5 ~d4 ~d3 ~d2 ~d1 ~d0] dut +.ends // SUBCKT sar_adc + +* Some MOS transistors complete the circuit. +* Models from https://homepages.rpi.edu/~sawyes/AIMSPICE_TutorialManual.pdf + +.model p1 pmos ++ level=2 vto=-0.5 kp=8.5e-6 gamma=0.4 phi=0.65 lambda=0.05 xj=0.5e-6 +.model n1 nmos ++ level=2 vto=0.5 kp=24e-6 gamma=0.15 phi=0.65 lambda=0.015 xj=0.5e-6 + +* Use those for an inverter. + +.subckt ainv in out vdd +mn out in 0 0 n1 +mp out in vdd vdd p1 +.ends + +* A transmission gate modelled by a switch. + +.subckt mos_tgate a b ctl vdd +mn a ctl b b n1 +xinv ctl ictl vdd ainv +mp b ictl a a p1 +.ends + +.subckt tgate a b ctl vdd +switch a b ctl 0 tg +.model tg sw vt=1.5 ron=2k +.ends + +* The per-bit subcircuit in the adc + +.subckt ccap in vcc ctl c=10p +xinv ctl tail vcc ainv +cb in tail {c} +.ends + +**** End of the ADC and its subcircuits. Begin test circuit **** + + +.param vcc=3.3 +vcc vcc 0 {vcc} + +* Digital clock signal + +aclock 0 clk clock +.model clock d_osc cntl_array=[-1 1] freq_array=[1Meg 1Meg] + +* A simple DAC so that the result may be compared to the input. + +r5 d5 sum 2 +r4 d4 sum 4 +r3 d3 sum 8 +r2 d2 sum 16 +r1 d1 sum 32 +r0 d0 sum 64 + +vamm sum 0 0 + +* Pulse the Start signal high for 1.3uS each 10uS + +Vpulse Start 0 PULSE 0 {vcc} 0.2u 10n 10n 1.3u 10u +Vtest input 0 PULSE 0 3 0 200u 200u 1u 401u + +* The ADC for testing + +xtest input vcc start valid d5 d4 d3 d2 d1 d0 clk sar_adc + + +.control +tran 100n 250u +plot input xtest.test_v vamm#branch clk/2 start/3 xtest.sample/3 valid +.endc +.end diff --git a/examples/xspice/verilator/adc.v b/examples/xspice/verilator/adc.v index 14bfcaccf..c063f1794 100644 --- a/examples/xspice/verilator/adc.v +++ b/examples/xspice/verilator/adc.v @@ -1,5 +1,7 @@ // Digital control for a successive approximation ADC with switched capacitors. +`timescale 100ns/100ns + module adc(Clk, Comp, Start, Sample, Done, Result); input wire Clk, Comp, Start; output reg Sample, Done; @@ -22,14 +24,12 @@ module adc(Clk, Comp, Start, Sample, Done, Result); if (Running) begin if (Sample) begin Sample <= 0; - SR[Bits - 1] = 1; - Result[Bits - 1] = 1; + SR[Bits - 1] <= 1; + Result[Bits - 1] <= 1; end else if (SR != 0) begin - if (Comp) - Result &= ~SR; - SR >>= 1; - Result |= SR; - if (SR == 0) begin + Result <= (Comp ? (Result & ~SR) : Result) | (SR >> 1); + SR <= SR >> 1; + if (SR == 1) begin Running <= 0; Done <= 1; end @@ -38,8 +38,8 @@ module adc(Clk, Comp, Start, Sample, Done, Result); Running <= 1; Sample <= 1; Done <= 0; - SR = 0; - Result = 0; + SR <= 0; + Result <= 0; end end endmodule diff --git a/examples/xspice/verilator/delay.cir b/examples/xspice/verilator/delay.cir new file mode 100644 index 000000000..d68ebaafb --- /dev/null +++ b/examples/xspice/verilator/delay.cir @@ -0,0 +1,11 @@ +* Waveform generation by Verilog delays +* + +adut null [ d4 d3 d2 d1 d0 ] ring +.model ring d_cosim simulation="./delay" + +.control +tran 20u 100u +plot d4 d3 d2 d1 d0 digitop +.endc +.end diff --git a/examples/xspice/verilator/delay.v b/examples/xspice/verilator/delay.v new file mode 100644 index 000000000..64fc68c80 --- /dev/null +++ b/examples/xspice/verilator/delay.v @@ -0,0 +1,14 @@ +`timescale 1us/100ns + +module delay(out); + output reg [4:0] out; + reg t; + + initial out = 0; + always begin + #1; + t = out[4]; + out <<= 1; + out[0] = ~t; + end +endmodule; // delay diff --git a/examples/xspice/verilator/pwm.cir b/examples/xspice/verilator/pwm.cir new file mode 100644 index 000000000..5f259d5ab --- /dev/null +++ b/examples/xspice/verilator/pwm.cir @@ -0,0 +1,12 @@ +* Waveform generation by PWM in Verilog + +adut null [ out ] pwm_sin +.model pwm_sin d_cosim simulation="./pwm" + +r1 out smooth 100k +c1 smooth 0 1u +.control +tran 1m 2 +plot out-3.3 smooth +.endc +.end diff --git a/examples/xspice/verilator/pwm.v b/examples/xspice/verilator/pwm.v new file mode 100644 index 000000000..5262a0c30 --- /dev/null +++ b/examples/xspice/verilator/pwm.v @@ -0,0 +1,34 @@ +`timescale 1us/100ns + +//`include "constants.vams" +`define M_TWO_PI 6.28318530717958647652 + +module pwm(out); + output reg out; + parameter Cycles = 1000, Samples = 1000; + integer i, j, width; + real sine; + + initial begin + i = 0; + j = 0; + width = Cycles / 2; + out = 0; + end + + always begin + #1; + ++i; + if (i == width) + out = 0; + if (i == Cycles) begin + i = 0; + ++j; + if (j == Samples) + j = 0; + sine = $sin(j * `M_TWO_PI / Samples); + width = $rtoi(Samples * (1.0 + sine) / 2.0); + out = (width == 0) ? 0 : 1; + end + end +endmodule // pwm diff --git a/src/frontend/com_ghelp.c b/src/frontend/com_ghelp.c index dfcddfde2..28c271644 100644 --- a/src/frontend/com_ghelp.c +++ b/src/frontend/com_ghelp.c @@ -30,7 +30,7 @@ void com_ghelp(wordlist *wl) "ngspice manual in PDF format at\n" " " BASE_HELP_URL "/ngspice-manual.pdf\n" "or in HTML format at\n" - " " BASE_HELP_URL "/ngspice-html-manual/manual.html\n\n"); + " " BASE_HELP_URL "/ngspice-html-manual/manual.xhtml\n\n"); return; #else diff --git a/src/frontend/inpc_probe.c b/src/frontend/inpc_probe.c index db7a87540..dd61de7af 100644 --- a/src/frontend/inpc_probe.c +++ b/src/frontend/inpc_probe.c @@ -1,5 +1,5 @@ /* ngspice file inpc_probe.c - Copyright Holger Vogt 2021 + Copyright Holger Vogt 2021-2024 License: BSD 3-clause */ diff --git a/src/frontend/inpcom.c b/src/frontend/inpcom.c index 2a29d5eef..be2cc078d 100644 --- a/src/frontend/inpcom.c +++ b/src/frontend/inpcom.c @@ -1288,7 +1288,7 @@ static struct inp_read_t inp_read(FILE* fp, int call_depth, const char* dir_name add_to_sourcepath(sourcelineinfo, NULL); } - wl_append_word(&sourceinfo, &sourceinfo, sourcelineinfo); + sourceinfo = wl_cons(sourcelineinfo, sourceinfo); /* First read in all lines & put them in the struct cc */ for (;;) { @@ -9504,7 +9504,7 @@ int add_to_sourcepath(const char* filepath, const char* path) /* if filepath, remove file entry */ if (path) - fpath = path; + fpath = copy(path); else fpath = ngdirname(filepath); @@ -9531,5 +9531,6 @@ int add_to_sourcepath(const char* filepath, const char* path) wl_free(wl); } + tfree(fpath); return 0; } diff --git a/src/frontend/misccoms.c b/src/frontend/misccoms.c index 1ac669039..67aafb128 100644 --- a/src/frontend/misccoms.c +++ b/src/frontend/misccoms.c @@ -196,7 +196,7 @@ com_version(wordlist *wl) "** The U. C. Berkeley CAD Group\n" "** Copyright 1985-1994, Regents of the University of California.\n" - "** Copyright 2001-2023, The ngspice team.\n" + "** Copyright 2001-2024, The ngspice team.\n" "** %s\n", ft_sim->simulator, ft_sim->version, ft_sim->description, Spice_Manual); if (*Spice_Notice != '\0') @@ -240,7 +240,7 @@ com_version(wordlist *wl) "** The U. C. Berkeley CAD Group\n" "** Copyright 1985-1994, Regents of the University of California.\n" - "** Copyright 2001-2023, The ngspice team.\n" + "** Copyright 2001-2024, The ngspice team.\n" "** %s\n", ft_sim->simulator, ft_sim->version, ft_sim->description, Spice_Manual); if (*Spice_Notice != '\0') diff --git a/src/frontend/parser/glob.c b/src/frontend/parser/glob.c index 2a1566cc3..f30bd7586 100644 --- a/src/frontend/parser/glob.c +++ b/src/frontend/parser/glob.c @@ -606,7 +606,8 @@ wordlist_l *wll_cons( if (opt & OPT_WLL_COPY_ALL) { char *p_dst = w->wl.wl_word = TMALLOC(char, n_elem_word_alloc); - (void) memcpy(p_dst, p_word, n_char_word); + if(p_word) + (void) memcpy(p_dst, p_word, n_char_word); p_dst += n_char_word; *p_dst = '\0'; } diff --git a/src/frontend/postcoms.c b/src/frontend/postcoms.c index 9b98f809f..1e6e51d71 100644 --- a/src/frontend/postcoms.c +++ b/src/frontend/postcoms.c @@ -965,6 +965,7 @@ static void killplot(struct plot *pl) /* delete the hash table entry for this plot */ if (pl->pl_lookup_table) { nghash_free(pl->pl_lookup_table, NULL, NULL); + pl->pl_lookup_table = NULL; } txfree(pl->pl_title); txfree(pl->pl_name); @@ -998,6 +999,7 @@ destroy_const_plot(void) /* delete the hash table entry for the const plot */ if (pl->pl_lookup_table) { nghash_free(pl->pl_lookup_table, NULL, NULL); + pl->pl_lookup_table = NULL; } wl_free(pl->pl_commands); if (pl->pl_ccom) /* va: also tfree (memory leak) */ diff --git a/src/frontend/subckt.c b/src/frontend/subckt.c index 1aaf2bede..94cf5e34e 100644 --- a/src/frontend/subckt.c +++ b/src/frontend/subckt.c @@ -1996,11 +1996,8 @@ devmodtranslate(struct card *s, char *subname, wordlist * const orig_modnames) s->line = copy(bxx_buffer(&buffer)); break; - /* 2 or 3 (temp) terminals for diode d, 2 or more for OSDI devices */ + /* 2 or 3 (temp) terminals for diode d */ case 'd': -#ifdef OSDI - case 'n': -#endif name = gettok(&t); /* get refdes */ bxx_printf(&buffer, "%s ", name); tfree(name); @@ -2039,8 +2036,48 @@ devmodtranslate(struct card *s, char *subname, wordlist * const orig_modnames) s->line = copy(bxx_buffer(&buffer)); break; +#ifdef OSDI + /* 1 or more terinals for OSDI devices*/ + case 'n': + name = gettok(&t); /* get refdes */ + bxx_printf(&buffer, "%s ", name); + tfree(name); + name = gettok_node(&t); /* get first attached netname */ + bxx_printf(&buffer, "%s ", name); + tfree(name); + name = gettok_node(&t); /* this can be either a model name or a node name. */ + if (name == NULL) { + name = copy(""); /* allow 'tfree' */ + } + else { + for (;;) { + wlsub = wl_find(name, orig_modnames); + if (wlsub) { + break; + } + else { + bxx_printf(&buffer, "%s ", name); + tfree(name); + name = gettok(&t); + if (name == NULL) { /* No token anymore - leave */ + name = copy(""); /* allow 'tfree' */ + break; + } + } + } /* while */ + } + + translate_mod_name(&buffer, name, subname, orig_modnames); + + tfree(name); + bxx_putc(&buffer, ' '); + bxx_put_cstring(&buffer, t); + tfree(s->line); + s->line = copy(bxx_buffer(&buffer)); + break; +#endif + /* 3 terminal devices */ case 'u': /* urc transmissionline */ - /* 3 terminal devices */ case 'w': /* current controlled switch */ case 'j': /* jfet */ case 'z': /* hfet, mesa */ diff --git a/src/frontend/terminal.c b/src/frontend/terminal.c index 98c58f8ed..709ff37c1 100644 --- a/src/frontend/terminal.c +++ b/src/frontend/terminal.c @@ -43,7 +43,7 @@ Author: 1986 Wayne A. Christopher, U. C. Berkeley CAD Group bool out_moremode = FALSE; bool out_isatty = TRUE; -#ifndef TCL_MODULE +#if !defined (TCL_MODULE) && !defined (SHARED_MODULE) #ifdef HAVE_TERMCAP static char *motion_chars; diff --git a/src/include/ngspice/cosim.h b/src/include/ngspice/cosim.h index dd6b97094..3d299a0e9 100644 --- a/src/include/ngspice/cosim.h +++ b/src/include/ngspice/cosim.h @@ -1,4 +1,6 @@ -/* Header file for the shim code between d_cosim and a co-simulator. */ +/* Header file for the shim code between XSPICE and a co-simulator + * attached by the d_cosim code model. + */ #if __cplusplus extern "C" { @@ -12,7 +14,7 @@ extern "C" { * so step() must be called after input. */ -typedef enum {Normal, After_input} Cosim_method; + typedef enum {Normal, After_input, Both} Cosim_method; /* Structure used by Cosim_setup() to pass and return * co-simulation interface information. @@ -26,7 +28,8 @@ struct co_info { unsigned int inout_count; /* The co-simulator may specify a function to be called just before - * it is unloaded at the end of a simulation run. + * it is unloaded at the end of a simulation run. It should not free + * this structure. */ void (*cleanup)(struct co_info *); @@ -59,8 +62,21 @@ struct co_info { void (*out_fn)(struct co_info *, unsigned int, Digital_t *); void *handle; // Co-simulator's private handle - double vtime; // Time in the co-simulation. + volatile double vtime; // Time in the co-simulation. Cosim_method method; // May be set in Cosim_setup; + + /* Arguments for the co-simulator shim and the simulation itself + * are taken from parameters in the .model card. + */ + + unsigned int lib_argc; + unsigned int sim_argc; + const char * const * const lib_argv; + const char * const * const sim_argv; + + /* Utility function for access to dynamic libraries. */ + + void *(*dlopen_fn)(const char *fn); }; extern void Cosim_setup(struct co_info *pinfo); // This must exist. diff --git a/src/include/ngspice/sharedspice.h b/src/include/ngspice/sharedspice.h index 111aaae9b..f97e0d8c6 100644 --- a/src/include/ngspice/sharedspice.h +++ b/src/include/ngspice/sharedspice.h @@ -96,6 +96,10 @@ Locking and unlocking the realloc of output vectors during simulation. May be se during reading output vectors in the primary thread, while the simulation in the background thread is moving on. +** +int ngSpice_Reset(void) +Reset ngspice as far as possible + ** Additional basics: No memory mallocing and freeing across the interface: @@ -111,7 +115,7 @@ are of type bool if sharedspice.h is used externally. */ #ifndef NGSPICE_PACKAGE_VERSION -#define NGSPICE_PACKAGE_VERSION "42+" +#define NGSPICE_PACKAGE_VERSION "43+" #endif /* we have NG_BOOL instead of BOOL */ #ifndef HAS_NG_BOOL diff --git a/src/maths/poly/interpolate.c b/src/maths/poly/interpolate.c index cbcd31bf8..3eecb823a 100644 --- a/src/maths/poly/interpolate.c +++ b/src/maths/poly/interpolate.c @@ -40,7 +40,7 @@ ft_interpolate(double *data, double *ndata, double *oscale, int olen, double *nscale, int nlen, int degree) { double *result, *scratch, *xdata, *ydata, diff; - int sign, lastone, i, l, middle, tdegree; + int sign = 1, lastone, i, l, middle, tdegree; if ((olen < 2) || (nlen < 2)) { fprintf(cp_err, "Error: lengths too small to interpolate.\n"); diff --git a/src/misc/string.c b/src/misc/string.c index 1374607da..97acd9c92 100644 --- a/src/misc/string.c +++ b/src/misc/string.c @@ -78,7 +78,7 @@ char *dup_string(const char *str, size_t n_char) char *p = TMALLOC(char, n_char + 1); if (p != NULL) { - (void) memcpy(p, str, n_char + 1); + (void) memcpy(p, str, n_char); p[n_char] = '\0'; } return p; diff --git a/src/osdi/osdicallbacks.c b/src/osdi/osdicallbacks.c index de7b1dc97..6669133b8 100644 --- a/src/osdi/osdicallbacks.c +++ b/src/osdi/osdicallbacks.c @@ -27,7 +27,7 @@ void osdi_log(void *handle_, char *msg, uint32_t lvl) { dst = stderr; break; default: - fprintf(stderr, "OSDI(unkown) %s", handle->name); + fprintf(stderr, "OSDI(unknown) %s", handle->name); break; } diff --git a/src/osdi/osdiregistry.c b/src/osdi/osdiregistry.c index cbab2624b..9a9dd114a 100644 --- a/src/osdi/osdiregistry.c +++ b/src/osdi/osdiregistry.c @@ -411,7 +411,7 @@ extern OsdiObjectFile load_object_file(const char *input) { IS_LIM_FUN("fetlim", 1, osdi_fetlim) IS_LIM_FUN("limitlog", 1, osdi_limitlog) if (expected_args == -1) { - printf("warning(osdi): unkown $limit function \"%s\"", lim_table[i].name); + printf("warning(osdi): unknown $limit function \"%s\"", lim_table[i].name); } else { printf("warning(osdi): unexpected number of arguments %i (expected %i) " "for \"%s\", ignoring...", diff --git a/src/osdi/osdisetup.c b/src/osdi/osdisetup.c index 77860e21f..4feb3ec90 100644 --- a/src/osdi/osdisetup.c +++ b/src/osdi/osdisetup.c @@ -162,10 +162,10 @@ static int init_matrix(SMPmatrix *matrix, const OsdiDescriptor *descr, for (uint32_t i = 0; i < descr->num_jacobian_entries; i++) { uint32_t equation = descr->jacobian_entries[i].nodes.node_1; - uint32_t unkown = descr->jacobian_entries[i].nodes.node_2; + uint32_t unknown = descr->jacobian_entries[i].nodes.node_2; equation = node_mapping[equation]; - unkown = node_mapping[unkown]; - double *ptr = SMPmakeElt(matrix, (int)equation, (int)unkown); + unknown = node_mapping[unknown]; + double *ptr = SMPmakeElt(matrix, (int)equation, (int)unknown); if (ptr == NULL) { return (E_NOMEM); @@ -424,10 +424,10 @@ static int init_matrix_klu(SMPmatrix *matrix, const OsdiDescriptor *descr, for (uint32_t i = 0; i < descr->num_jacobian_entries; i++) { uint32_t equation = descr->jacobian_entries[i].nodes.node_1; - uint32_t unkown = descr->jacobian_entries[i].nodes.node_2; + uint32_t unknown = descr->jacobian_entries[i].nodes.node_2; equation = node_mapping[equation]; - unkown = node_mapping[unkown]; - if (equation != 0 && unkown != 0) { + unknown = node_mapping[unknown]; + if (equation != 0 && unknown != 0) { tmp.COO = jacobian_ptr_resist[i]; tmp.CSC = NULL; tmp.CSC_Complex = NULL; @@ -461,10 +461,10 @@ static int update_matrix_klu(const OsdiDescriptor *descr, void *inst, for (uint32_t i = 0; i < descr->num_jacobian_entries; i++) { uint32_t equation = descr->jacobian_entries[i].nodes.node_1; - uint32_t unkown = descr->jacobian_entries[i].nodes.node_2; + uint32_t unknown = descr->jacobian_entries[i].nodes.node_2; equation = node_mapping[equation]; - unkown = node_mapping[unkown]; - if (equation != 0 && unkown != 0) { + unknown = node_mapping[unknown]; + if (equation != 0 && unknown != 0) { jacobian_ptr_resist[i] = inst_matrix_ptrs[2 * i + complex]; } } diff --git a/src/sharedspice.c b/src/sharedspice.c index 30680fed3..291f87070 100644 --- a/src/sharedspice.c +++ b/src/sharedspice.c @@ -352,6 +352,22 @@ static char* outstorage(char*, bool); static void printsend(void); #endif +extern wordlist* sourceinfo; + +static int totalreset(void); +extern void rem_controls(void); +extern void destroy_wallace(void); +extern void sh_delete_myvec(void); +extern IFsimulator SIMinfo; +extern void spice_destroy_devices(void); /* FIXME need a better place */ + +extern void destroy_const_plot(void); +extern void com_destroy(wordlist* wl); +extern void com_unalias(wordlist* wl); +extern void com_undefine(wordlist* wl); +extern void com_remcirc(wordlist* wl); +extern void unset_all(void); + #include "ngspice/sharedspice.h" static SendChar* pfcn; @@ -1083,6 +1099,10 @@ sh_delete_myvec(void) IMPEXP int ngSpice_Command(char* comexec) { + if (!is_initialized) { + return 1; + } + /* delete existing command memory */ if (comexec == NULL) { cp_resetcontrol(FALSE); @@ -1367,6 +1387,15 @@ int ngSpice_UnlockRealloc(void) return 1; } +/* Reset ngspice as far as possible */ +IMPEXP +int ngSpice_Reset(void) +{ + if (!is_initialized) + return 1; + fprintf(stdout, "Note: Resetting ngspice\n\n"); + return totalreset(); +} /* add the preliminary breakpoints to the list. called from dctran.c */ @@ -2034,12 +2063,12 @@ ATTRIBUTE_NORETURN void shared_exit(int status) hand this information over to caller */ if (status >= 1000) { coquit = TRUE; - fprintf(stdout, "\nNote: 'quit' asks for detaching ngspice.dll.\n"); + fprintf(stdout, "\nNote: 'quit' asks for resetting or detaching ngspice.dll.\n"); status -= 1000; } else { coquit = FALSE; - fprintf(stderr, "Error: ngspice.dll cannot recover and awaits to be detached\n"); + fprintf(stderr, "Error: ngspice.dll cannot recover and awaits to be reset or detached\n"); } #ifndef low_latency // set flag to stop the printsend thread @@ -2402,3 +2431,100 @@ void shared_send_dict(int index, int no_of_nodes, char* name, char*type) sendinitevt(index, no_of_nodes, name, type, ng_ident, euserptr); } #endif + +static int totalreset(void) +{ + + is_initialized = FALSE; + + // if we are in a worker thread, we exit it here + // detaching then has to be done explicitely by the caller + if (fl_running && !fl_exited) { + fl_exited = TRUE; + bgtr(fl_exited, ng_ident, userptr); + // finish and exit the worker thread +#ifdef HAVE_LIBPTHREAD + pthread_exit(NULL); +#elif defined _MSC_VER || defined __MINGW32__ + _endthreadex(1); +#endif + } + + /* start to clean up the mess */ + + noprintfwanted = FALSE; + nostatuswanted = FALSE; + nodatawanted = FALSE; + nodatainitwanted = FALSE; + nobgtrwanted = FALSE; + wantvdat = FALSE; + wantidat = FALSE; + wantsync = FALSE; + immediate = FALSE; + coquit = FALSE; + + wordlist all = { "all", NULL, NULL }; + wordlist star = { "*", NULL, NULL }; + + tfree(Infile_Path); + wl_free(sourceinfo); + sourceinfo = NULL; + + com_destroy(&all); + com_unalias(&star); + com_undefine(&star); + + cp_remvar("history"); + cp_remvar("noglob"); + cp_remvar("brief"); + cp_remvar("sourcepath"); + cp_remvar("program"); + cp_remvar("prompt"); + + destroy_wallace(); + + rem_controls(); + + while (ft_curckt) { + com_remcirc(NULL); + } + + cp_destroy_keywords(); + destroy_ivars(); + + tfree(errMsg); + + destroy_const_plot(); + spice_destroy_devices(); + unset_all(); + cp_resetcontrol(FALSE); + sh_delete_myvec(); + +#ifdef THREADS + /* Destroy the mutexes */ +#ifdef HAVE_LIBPTHREAD + pthread_mutex_destroy(&triggerMutex); + pthread_mutex_destroy(&allocMutex); + pthread_mutex_destroy(&fputsMutex); + pthread_mutex_destroy(&vecreallocMutex); + cont_condition = FALSE; +#else +#ifdef SRW + /* Do we need to remove the SWR locks? */ +// InitializeSRWLock(&triggerMutex); +// InitializeSRWLock(&allocMutex); +// InitializeSRWLock(&fputsMutex); +// InitializeSRWLock(&vecreallocMutex); +#else + DeleteCriticalSection(&triggerMutex); + DeleteCriticalSection(&allocMutex); + DeleteCriticalSection(&fputsMutex); + DeleteCriticalSection(&vecreallocMutex); +#endif +#endif + // Id of primary thread + main_id = 0; +#endif + + return 0; +}; diff --git a/src/spicelib/devices/bsim3/b3ld.c b/src/spicelib/devices/bsim3/b3ld.c index 6ed5f6ee4..b841f694e 100644 --- a/src/spicelib/devices/bsim3/b3ld.c +++ b/src/spicelib/devices/bsim3/b3ld.c @@ -3150,41 +3150,41 @@ void BSIM3LoadRhsMat(GENmodel *inModel, CKTcircuit *ckt) (*(ckt->CKTrhs + here->BSIM3qNode) += here->BSIM3rhsQ); /* Update A for Ax = b */ - (*(here->BSIM3DdPtr) += here->BSIM3DdPt); - (*(here->BSIM3GgPtr) += here->BSIM3GgPt); - (*(here->BSIM3SsPtr) += here->BSIM3SsPt); - (*(here->BSIM3BbPtr) += here->BSIM3BbPt); - (*(here->BSIM3DPdpPtr) += here->BSIM3DPdpPt); - (*(here->BSIM3SPspPtr) += here->BSIM3SPspPt); - (*(here->BSIM3DdpPtr) -= here->BSIM3DdpPt); - (*(here->BSIM3GbPtr) -= here->BSIM3GbPt); - (*(here->BSIM3GdpPtr) += here->BSIM3GdpPt); - (*(here->BSIM3GspPtr) += here->BSIM3GspPt); - (*(here->BSIM3SspPtr) -= here->BSIM3SspPt); - (*(here->BSIM3BgPtr) += here->BSIM3BgPt); - (*(here->BSIM3BdpPtr) += here->BSIM3BdpPt); - (*(here->BSIM3BspPtr) += here->BSIM3BspPt); - (*(here->BSIM3DPdPtr) -= here->BSIM3DPdPt); - (*(here->BSIM3DPgPtr) += here->BSIM3DPgPt); - (*(here->BSIM3DPbPtr) -= here->BSIM3DPbPt); - (*(here->BSIM3DPspPtr) -= here->BSIM3DPspPt); - (*(here->BSIM3SPgPtr) += here->BSIM3SPgPt); - (*(here->BSIM3SPsPtr) -= here->BSIM3SPsPt); - (*(here->BSIM3SPbPtr) -= here->BSIM3SPbPt); - (*(here->BSIM3SPdpPtr) -= here->BSIM3SPdpPt); + (*(here->BSIM3DdPtr) += here->BSIM3DdPt); + (*(here->BSIM3GgPtr) += here->BSIM3GgPt); + (*(here->BSIM3SsPtr) += here->BSIM3SsPt); + (*(here->BSIM3BbPtr) += here->BSIM3BbPt); + (*(here->BSIM3DPdpPtr) += here->BSIM3DPdpPt); + (*(here->BSIM3SPspPtr) += here->BSIM3SPspPt); + (*(here->BSIM3DdpPtr) -= here->BSIM3DdpPt); + (*(here->BSIM3GbPtr) -= here->BSIM3GbPt); + (*(here->BSIM3GdpPtr) += here->BSIM3GdpPt); + (*(here->BSIM3GspPtr) += here->BSIM3GspPt); + (*(here->BSIM3SspPtr) -= here->BSIM3SspPt); + (*(here->BSIM3BgPtr) += here->BSIM3BgPt); + (*(here->BSIM3BdpPtr) += here->BSIM3BdpPt); + (*(here->BSIM3BspPtr) += here->BSIM3BspPt); + (*(here->BSIM3DPdPtr) -= here->BSIM3DPdPt); + (*(here->BSIM3DPgPtr) += here->BSIM3DPgPt); + (*(here->BSIM3DPbPtr) -= here->BSIM3DPbPt); + (*(here->BSIM3DPspPtr) -= here->BSIM3DPspPt); + (*(here->BSIM3SPgPtr) += here->BSIM3SPgPt); + (*(here->BSIM3SPsPtr) -= here->BSIM3SPsPt); + (*(here->BSIM3SPbPtr) -= here->BSIM3SPbPt); + (*(here->BSIM3SPdpPtr) -= here->BSIM3SPdpPt); - if (here->BSIM3nqsMod) - { *(here->BSIM3QqPtr) += here->BSIM3QqPt; + if (here->BSIM3nqsMod) + { *(here->BSIM3QqPtr) += here->BSIM3QqPt; - *(here->BSIM3DPqPtr) += here->BSIM3DPqPt; - *(here->BSIM3SPqPtr) += here->BSIM3SPqPt; - *(here->BSIM3GqPtr) -= here->BSIM3GqPt; + *(here->BSIM3DPqPtr) += here->BSIM3DPqPt; + *(here->BSIM3SPqPtr) += here->BSIM3SPqPt; + *(here->BSIM3GqPtr) -= here->BSIM3GqPt; - *(here->BSIM3QgPtr) += here->BSIM3QgPt; - *(here->BSIM3QdpPtr) += here->BSIM3QdpPt; - *(here->BSIM3QspPtr) += here->BSIM3QspPt; - *(here->BSIM3QbPtr) += here->BSIM3QbPt; - } + *(here->BSIM3QgPtr) += here->BSIM3QgPt; + *(here->BSIM3QdpPtr) += here->BSIM3QdpPt; + *(here->BSIM3QspPtr) += here->BSIM3QspPt; + *(here->BSIM3QbPtr) += here->BSIM3QbPt; + } } } diff --git a/src/spicelib/devices/bsimsoi/b4soiset.c b/src/spicelib/devices/bsimsoi/b4soiset.c index 3523eae74..993d007ed 100644 --- a/src/spicelib/devices/bsimsoi/b4soiset.c +++ b/src/spicelib/devices/bsimsoi/b4soiset.c @@ -1732,7 +1732,7 @@ B4SOIinstance **InstArray; if (!model->B4SOIpfbjtiiGiven) model->B4SOIpfbjtii = 0.0; /*4.1 Iii model*/ - if (!model->B4SOIpebjtiiGiven) + if (!model->B4SOIpebjtiiGiven) model->B4SOIpebjtii = 0.0; if (!model->B4SOIpcbjtiiGiven) model->B4SOIpcbjtii = 0.0; @@ -1775,7 +1775,7 @@ B4SOIinstance **InstArray; if (!model->B4SOIpfgidlGiven) model->B4SOIpfgidl = 0.0; - if (!model->B4SOIpagislGiven) + if (!model->B4SOIpagislGiven) model->B4SOIpagisl = 0.0; if (!model->B4SOIpbgislGiven) model->B4SOIpbgisl = 0.0; diff --git a/src/spicelib/devices/dio/diotemp.c b/src/spicelib/devices/dio/diotemp.c index 697e9d1d6..b1caceb16 100644 --- a/src/spicelib/devices/dio/diotemp.c +++ b/src/spicelib/devices/dio/diotemp.c @@ -33,7 +33,7 @@ void DIOtempUpdate(DIOmodel *inModel, DIOinstance *here, double Temp, CKTcircuit double egfet1,arg1,fact1,pbfact1,pbo,gmaold,pboSW,gmaSWold; double fact2,pbfact,arg,egfet,gmanew,gmaSWnew; double arg1_dT, arg2, arg2_dT; - double lnTRatio, egfet_dT, arg0, vte_dT, vts_dT, vtt_dT, vtr_dT; + double lnTRatio, egfet_dT = 0.0, arg0, vte_dT, vts_dT, vtt_dT, vtr_dT; vt = CONSTKoverQ * Temp; vte = model->DIOemissionCoeff * vt; diff --git a/src/spicelib/devices/hicum2/hicum2.c b/src/spicelib/devices/hicum2/hicum2.c index b9e636f3c..aff42a1d8 100644 --- a/src/spicelib/devices/hicum2/hicum2.c +++ b/src/spicelib/devices/hicum2/hicum2.c @@ -1,7 +1,7 @@ /********** License : 3-clause BSD Spice3 Implementation: 2019-2020 Dietmar Warning, Markus Müller, Mario Krattenmacher -Model Author : 1990 Michael Schröter TU Dresden +Model Author : (Copyright 1993-2024) Michael Schroter **********/ /* diff --git a/src/spicelib/devices/hicum2/hicum2acld.c b/src/spicelib/devices/hicum2/hicum2acld.c index 66ee40e0a..f6a3ea3f4 100644 --- a/src/spicelib/devices/hicum2/hicum2acld.c +++ b/src/spicelib/devices/hicum2/hicum2acld.c @@ -1,7 +1,7 @@ /********** License : 3-clause BSD Spice3 Implementation: 2019-2020 Dietmar Warning, Markus Müller, Mario Krattenmacher -Model Author : 1990 Michael Schröter TU Dresden +Model Author : (Copyright 1993-2024) Michael Schroter **********/ /* diff --git a/src/spicelib/devices/hicum2/hicum2ask.c b/src/spicelib/devices/hicum2/hicum2ask.c index 4fb6d89d7..03f199dec 100644 --- a/src/spicelib/devices/hicum2/hicum2ask.c +++ b/src/spicelib/devices/hicum2/hicum2ask.c @@ -1,7 +1,7 @@ /********** License : 3-clause BSD Spice3 Implementation: 2019-2020 Dietmar Warning, Markus Müller, Mario Krattenmacher -Model Author : 1990 Michael Schröter TU Dresden +Model Author : (Copyright 1993-2024) Michael Schroter **********/ /* diff --git a/src/spicelib/devices/hicum2/hicum2conv.c b/src/spicelib/devices/hicum2/hicum2conv.c index 0be839408..ea78c91cc 100644 --- a/src/spicelib/devices/hicum2/hicum2conv.c +++ b/src/spicelib/devices/hicum2/hicum2conv.c @@ -1,7 +1,7 @@ /********** License : 3-clause BSD Spice3 Implementation: 2019-2020 Dietmar Warning, Markus Müller, Mario Krattenmacher -Model Author : 1990 Michael Schröter TU Dresden +Model Author : (Copyright 1993-2024) Michael Schroter **********/ /* diff --git a/src/spicelib/devices/hicum2/hicum2defs.h b/src/spicelib/devices/hicum2/hicum2defs.h index a839b62c6..1c928c2bf 100644 --- a/src/spicelib/devices/hicum2/hicum2defs.h +++ b/src/spicelib/devices/hicum2/hicum2defs.h @@ -1,7 +1,7 @@ /********** License : 3-clause BSD Spice3 Implementation: 2019-2020 Dietmar Warning, Markus Müller, Mario Krattenmacher -Model Author : 1990 Michael Schröter TU Dresden +Model Author : (Copyright 1993-2024) Michael Schroter **********/ #ifndef HICUM diff --git a/src/spicelib/devices/hicum2/hicum2ext.h b/src/spicelib/devices/hicum2/hicum2ext.h index 928ecb7b8..c3d92affb 100644 --- a/src/spicelib/devices/hicum2/hicum2ext.h +++ b/src/spicelib/devices/hicum2/hicum2ext.h @@ -1,7 +1,7 @@ /********** License : 3-clause BSD Spice3 Implementation: 2019-2020 Dietmar Warning, Markus Müller, Mario Krattenmacher -Model Author : 1990 Michael Schröter TU Dresden +Model Author : (Copyright 1993-2024) Michael Schroter **********/ #ifndef __HICUMEXT_H #define __HICUMEXT_H diff --git a/src/spicelib/devices/hicum2/hicum2getic.c b/src/spicelib/devices/hicum2/hicum2getic.c index ea36a6e62..06d9ce047 100644 --- a/src/spicelib/devices/hicum2/hicum2getic.c +++ b/src/spicelib/devices/hicum2/hicum2getic.c @@ -1,7 +1,7 @@ /********** License : 3-clause BSD Spice3 Implementation: 2019-2020 Dietmar Warning, Markus Müller, Mario Krattenmacher -Model Author : 1990 Michael Schröter TU Dresden +Model Author : (Copyright 1993-2024) Michael Schroter **********/ /* diff --git a/src/spicelib/devices/hicum2/hicum2init.c b/src/spicelib/devices/hicum2/hicum2init.c index 1c90cfe92..28854583e 100644 --- a/src/spicelib/devices/hicum2/hicum2init.c +++ b/src/spicelib/devices/hicum2/hicum2init.c @@ -1,7 +1,7 @@ /********** License : 3-clause BSD Spice3 Implementation: 2019-2020 Dietmar Warning, Markus Müller, Mario Krattenmacher -Model Author : 1990 Michael Schröter TU Dresden +Model Author : (Copyright 1993-2024) Michael Schroter **********/ diff --git a/src/spicelib/devices/hicum2/hicum2init.h b/src/spicelib/devices/hicum2/hicum2init.h index a4e8b73e1..39e1cb20b 100644 --- a/src/spicelib/devices/hicum2/hicum2init.h +++ b/src/spicelib/devices/hicum2/hicum2init.h @@ -1,7 +1,7 @@ /********** License : 3-clause BSD Spice3 Implementation: 2019-2020 Dietmar Warning, Markus Müller, Mario Krattenmacher -Model Author : 1990 Michael Schröter TU Dresden +Model Author : (Copyright 1993-2024) Michael Schroter **********/ diff --git a/src/spicelib/devices/hicum2/hicum2itf.h b/src/spicelib/devices/hicum2/hicum2itf.h index f351542a9..e1b1aec35 100644 --- a/src/spicelib/devices/hicum2/hicum2itf.h +++ b/src/spicelib/devices/hicum2/hicum2itf.h @@ -1,7 +1,7 @@ /********** License : 3-clause BSD Spice3 Implementation: 2019-2020 Dietmar Warning, Markus Müller, Mario Krattenmacher -Model Author : 1990 Michael Schröter TU Dresden +Model Author : (Copyright 1993-2024) Michael Schroter **********/ #ifndef DEV_HICUM #define DEV_HICUM diff --git a/src/spicelib/devices/hicum2/hicum2mask.c b/src/spicelib/devices/hicum2/hicum2mask.c index ba2f43e25..255c254c6 100644 --- a/src/spicelib/devices/hicum2/hicum2mask.c +++ b/src/spicelib/devices/hicum2/hicum2mask.c @@ -1,7 +1,7 @@ /********** License : 3-clause BSD Spice3 Implementation: 2019-2020 Dietmar Warning, Markus Müller, Mario Krattenmacher -Model Author : 1990 Michael Schröter TU Dresden +Model Author : (Copyright 1993-2024) Michael Schroter **********/ #include "ngspice/ngspice.h" diff --git a/src/spicelib/devices/hicum2/hicum2mpar.c b/src/spicelib/devices/hicum2/hicum2mpar.c index 2c436f3d2..35fc807b2 100644 --- a/src/spicelib/devices/hicum2/hicum2mpar.c +++ b/src/spicelib/devices/hicum2/hicum2mpar.c @@ -1,7 +1,7 @@ /********** License : 3-clause BSD Spice3 Implementation: 2019-2020 Dietmar Warning, Markus Müller, Mario Krattenmacher -Model Author : 1990 Michael Schröter TU Dresden +Model Author : (Copyright 1993-2024) Michael Schroter **********/ /* diff --git a/src/spicelib/devices/hicum2/hicum2noise.c b/src/spicelib/devices/hicum2/hicum2noise.c index d1532a561..bfc93bf2c 100644 --- a/src/spicelib/devices/hicum2/hicum2noise.c +++ b/src/spicelib/devices/hicum2/hicum2noise.c @@ -1,7 +1,7 @@ /********** License : 3-clause BSD Spice3 Implementation: 2019-2020 Dietmar Warning, Markus Müller, Mario Krattenmacher -Model Author : 1990 Michael Schröter TU Dresden +Model Author : (Copyright 1993-2024) Michael Schroter **********/ #include "ngspice/ngspice.h" diff --git a/src/spicelib/devices/hicum2/hicum2param.c b/src/spicelib/devices/hicum2/hicum2param.c index 8191e511e..ec2c32500 100644 --- a/src/spicelib/devices/hicum2/hicum2param.c +++ b/src/spicelib/devices/hicum2/hicum2param.c @@ -1,7 +1,7 @@ /********** License : 3-clause BSD Spice3 Implementation: 2019-2020 Dietmar Warning, Markus Müller, Mario Krattenmacher -Model Author : 1990 Michael Schröter TU Dresden +Model Author : (Copyright 1993-2024) Michael Schroter **********/ /* diff --git a/src/spicelib/devices/hicum2/hicum2pzld.c b/src/spicelib/devices/hicum2/hicum2pzld.c index ca76a982c..290de7567 100644 --- a/src/spicelib/devices/hicum2/hicum2pzld.c +++ b/src/spicelib/devices/hicum2/hicum2pzld.c @@ -1,7 +1,7 @@ /********** License : 3-clause BSD Spice3 Implementation: 2019-2020 Dietmar Warning, Markus Müller, Mario Krattenmacher -Model Author : 1990 Michael Schröter TU Dresden +Model Author : (Copyright 1993-2024) Michael Schroter **********/ diff --git a/src/spicelib/devices/hicum2/hicum2setup.c b/src/spicelib/devices/hicum2/hicum2setup.c index 24c7ccd58..dbd728ee8 100644 --- a/src/spicelib/devices/hicum2/hicum2setup.c +++ b/src/spicelib/devices/hicum2/hicum2setup.c @@ -1,7 +1,7 @@ /********** License : 3-clause BSD Spice3 Implementation: 2019-2020 Dietmar Warning, Markus Müller, Mario Krattenmacher -Model Author : 1990 Michael Schröter TU Dresden +Model Author : (Copyright 1993-2024) Michael Schroter **********/ /* diff --git a/src/spicelib/devices/hicum2/hicum2soachk.c b/src/spicelib/devices/hicum2/hicum2soachk.c index ac010e186..b03f9e8da 100644 --- a/src/spicelib/devices/hicum2/hicum2soachk.c +++ b/src/spicelib/devices/hicum2/hicum2soachk.c @@ -1,7 +1,7 @@ /********** License : 3-clause BSD Spice3 Implementation: 2019-2020 Dietmar Warning, Markus Müller, Mario Krattenmacher -Model Author : 1990 Michael Schröter TU Dresden +Model Author : (Copyright 1993-2024) Michael Schroter **********/ #include "ngspice/ngspice.h" diff --git a/src/spicelib/devices/hicum2/hicum2trunc.c b/src/spicelib/devices/hicum2/hicum2trunc.c index d59990668..9affd8564 100644 --- a/src/spicelib/devices/hicum2/hicum2trunc.c +++ b/src/spicelib/devices/hicum2/hicum2trunc.c @@ -1,7 +1,7 @@ /********** License : 3-clause BSD Spice3 Implementation: 2019-2020 Dietmar Warning, Markus Müller, Mario Krattenmacher -Model Author : 1990 Michael Schröter TU Dresden +Model Author : (Copyright 1993-2024) Michael Schroter **********/ /* diff --git a/src/spicelib/devices/hicum2/hicumL2.cpp b/src/spicelib/devices/hicum2/hicumL2.cpp index c1f835411..d2da2e46a 100644 --- a/src/spicelib/devices/hicum2/hicumL2.cpp +++ b/src/spicelib/devices/hicum2/hicumL2.cpp @@ -1,7 +1,7 @@ /********** License : 3-clause BSD Spice3 Implementation: 2019-2020 Dietmar Warning, Markus Müller, Mario Krattenmacher -Model Author : 1990 Michael Schröter TU Dresden +Model Author : (Copyright 1993-2024) Michael Schroter **********/ /* diff --git a/src/spicelib/devices/hicum2/hicumL2.hpp b/src/spicelib/devices/hicum2/hicumL2.hpp index 799e29856..bdcd1ae3e 100644 --- a/src/spicelib/devices/hicum2/hicumL2.hpp +++ b/src/spicelib/devices/hicum2/hicumL2.hpp @@ -1,7 +1,7 @@ /********** License : 3-clause BSD Spice3 Implementation: 2019-2020 Dietmar Warning, Markus Müller, Mario Krattenmacher -Model Author : 1990 Michael Schröter TU Dresden +Model Author : (Copyright 1993-2024) Michael Schroter **********/ #ifndef hicumL2_H #define hicumL2_H diff --git a/src/spicelib/devices/hicum2/hicumL2temp.cpp b/src/spicelib/devices/hicum2/hicumL2temp.cpp index 0318754aa..365690ec4 100644 --- a/src/spicelib/devices/hicum2/hicumL2temp.cpp +++ b/src/spicelib/devices/hicum2/hicumL2temp.cpp @@ -1,7 +1,7 @@ /********** License : 3-clause BSD Spice3 Implementation: 2019-2020 Dietmar Warning, Markus Müller, Mario Krattenmacher -Model Author : 1990 Michael Schröter TU Dresden +Model Author : (Copyright 1993-2024) Michael Schroter **********/ #include diff --git a/src/spicelib/devices/hicum2/hicumL2temp.hpp b/src/spicelib/devices/hicum2/hicumL2temp.hpp index 02a648d85..fd83dd742 100644 --- a/src/spicelib/devices/hicum2/hicumL2temp.hpp +++ b/src/spicelib/devices/hicum2/hicumL2temp.hpp @@ -1,7 +1,7 @@ /********** License : 3-clause BSD Spice3 Implementation: 2019-2020 Dietmar Warning, Markus Müller, Mario Krattenmacher -Model Author : 1990 Michael Schröter TU Dresden +Model Author : (Copyright 1993-2024) Michael Schroter **********/ #ifndef hicumL2_temp #define hicumL2_temp diff --git a/src/spicelib/devices/hisim2/hsm2eval.c b/src/spicelib/devices/hisim2/hsm2eval.c index 87fa9ce5e..e8a721938 100644 --- a/src/spicelib/devices/hisim2/hsm2eval.c +++ b/src/spicelib/devices/hisim2/hsm2eval.c @@ -3189,7 +3189,7 @@ while( START_OF_SCE_LOOP ) { /* Begin: 1st SCE LOOP */ * - Psa : Analytical solution of * Cox( Vgp - Psa ) = cnst0 * Qacc * where Qacc is the 3-degree series of (fdep)^{1/2}. - * The unkown is transformed to Chi=beta(Ps0-Vbs). + * The unknown is transformed to Chi=beta(Ps0-Vbs). * - Ps0_min : |Ps0_min| when Vbs=0. *-----------------*/ diff --git a/src/spicelib/devices/hisimhv1/hsmhveval.c b/src/spicelib/devices/hisimhv1/hsmhveval.c index 9c4df2feb..4f166b8eb 100644 --- a/src/spicelib/devices/hisimhv1/hsmhveval.c +++ b/src/spicelib/devices/hisimhv1/hsmhveval.c @@ -2137,7 +2137,7 @@ int HSMHVevaluate * - Psa : Analytical solution of * Cox( Vgp - Psa ) = cnst0 * Qacc * where Qacc is the 3-degree series of (fdep)^{1/2}. - * The unkown is transformed to Chi=beta(Ps0-Vbs). + * The unknown is transformed to Chi=beta(Ps0-Vbs). * - Ps0_min : |Ps0_min| when Vbs=0. *-----------------*/ Ps0_min = here->HSMHV_eg - Pb2 ; diff --git a/src/spicelib/devices/hisimhv2/hsmhv2eval.c b/src/spicelib/devices/hisimhv2/hsmhv2eval.c index cda4d0e88..1d050a60a 100644 --- a/src/spicelib/devices/hisimhv2/hsmhv2eval.c +++ b/src/spicelib/devices/hisimhv2/hsmhv2eval.c @@ -2067,7 +2067,7 @@ int HSMHV2evaluate * - Psa : Analytical solution of * Cox( Vgp - Psa ) = cnst0 * Qacc * where Qacc is the 3-degree series of (fdep)^{1/2}. - * The unkown is transformed to Chi=beta(Ps0-Vbs). + * The unknown is transformed to Chi=beta(Ps0-Vbs). * - Ps0_min : |Ps0_min| when Vbs=0. *-----------------*/ /* Ps0_min: approx. solution of Poisson equation at Vgs_min */ diff --git a/src/spicelib/devices/res/resparam.c b/src/spicelib/devices/res/resparam.c index a14c8af24..df11971af 100644 --- a/src/spicelib/devices/res/resparam.c +++ b/src/spicelib/devices/res/resparam.c @@ -12,6 +12,8 @@ Modified: Apr 2000 - Paolo Nenzi #include "ngspice/missing_math.h" #include "ngspice/fteext.h" +#define RESMIN 1e-6 + int RESparam(int param, IFvalue *value, GENinstance *inst, IFvalue *select) { @@ -37,7 +39,15 @@ RESparam(int param, IFvalue *value, GENinstance *inst, IFvalue *select) break; case RES_RESIST: /* 0 valued resistor causes ngspice to hang -- can't solve for initial voltage */ - if ( AlmostEqualUlps( value->rValue, 0, 3 ) ) value->rValue = 0.001; /* 0.001 should be sufficiently small */ +// if ( AlmostEqualUlps( value->rValue, 0, 3 ) ) value->rValue = 0.001; /* 0.001 should be sufficiently small */ + if (value->rValue >= 0 && value->rValue < RESMIN) { + fprintf(stderr, "Warning: Value of resistor %s is too small, set to %e\n", here->gen.GENname, RESMIN); + value->rValue = RESMIN; + } + else if (value->rValue < 0 && value->rValue > -RESMIN) { + fprintf(stderr, "Warning: Value of resistor %s is too small, set to %e\n", here->gen.GENname, -RESMIN); + value->rValue = -RESMIN; + } here->RESresist = value->rValue; here->RESresGiven = TRUE; break; diff --git a/src/spicelib/devices/vbic/vbicacld.c b/src/spicelib/devices/vbic/vbicacld.c index 3faed1866..c745cfb21 100644 --- a/src/spicelib/devices/vbic/vbicacld.c +++ b/src/spicelib/devices/vbic/vbicacld.c @@ -32,6 +32,17 @@ VBICacLoad(GENmodel *inModel, CKTcircuit *ckt) XQbcx_Vbcx, XQbep_Vbep, XQbep_Vbci, XQbcp_Vbcp, XQbeo_Vbe, XQbco_Vbc; + double Ibe_Vrth, Ibex_Vrth, Itzf_Vrth=0.0, Itzr_Vrth, Ibc_Vrth, Ibep_Vrth, + Ircx_Vrth, Irci_Vrth, Irbx_Vrth, Irbi_Vrth, Ire_Vrth, Irbp_Vrth, + Ibcp_Vrth, Iccp_Vrth, Irs_Vrth, Irth_Vrth, Ith_Vrth, + Ith_Vbei, Ith_Vbci, Ith_Vcei, Ith_Vbex, Ith_Vbep, Ith_Vbcp, Ith_Vcep, + Ith_Vrci, Ith_Vbcx, Ith_Vrbi, Ith_Vrbp, Ith_Vrcx, Ith_Vrbx, Ith_Vre, Ith_Vrs; + double XQcth_Vrth, XQbe_Vrth, XQbex_Vrth, XQbc_Vrth, XQbcx_Vrth, XQbep_Vrth, XQbcp_Vrth; + + //NQS + double Itxf_Vrxf, Ibc_Vrxf, Ith_Vrxf, Ixzf_Vrth, Ixxf_Vrxf, XQcxf_Vcxf; + double Ixzf_Vbei, Ixzf_Vbci, Xl; + /* loop through all the models */ for( ; model != NULL; model = VBICnextModel(model)) { @@ -83,17 +94,20 @@ c Stamp element: Ibex *(here->VBICbaseBXEmitEIPtr) += -Ibex_Vbex; *(here->VBICemitEIBaseBXPtr) += -Ibex_Vbex; *(here->VBICemitEIEmitEIPtr) += Ibex_Vbex; + + if (!here->VBIC_excessPhase) { /* c Stamp element: Itzf */ - *(here->VBICcollCIBaseBIPtr) += Itzf_Vbei; - *(here->VBICcollCIEmitEIPtr) += -Itzf_Vbei; - *(here->VBICcollCIBaseBIPtr) += Itzf_Vbci; - *(here->VBICcollCICollCIPtr) += -Itzf_Vbci; - *(here->VBICemitEIBaseBIPtr) += -Itzf_Vbei; - *(here->VBICemitEIEmitEIPtr) += Itzf_Vbei; - *(here->VBICemitEIBaseBIPtr) += -Itzf_Vbci; - *(here->VBICemitEICollCIPtr) += Itzf_Vbci; + *(here->VBICcollCIBaseBIPtr) += Itzf_Vbei; + *(here->VBICcollCIEmitEIPtr) += -Itzf_Vbei; + *(here->VBICcollCIBaseBIPtr) += Itzf_Vbci; + *(here->VBICcollCICollCIPtr) += -Itzf_Vbci; + *(here->VBICemitEIBaseBIPtr) += -Itzf_Vbei; + *(here->VBICemitEIEmitEIPtr) += Itzf_Vbei; + *(here->VBICemitEIBaseBIPtr) += -Itzf_Vbci; + *(here->VBICemitEICollCIPtr) += Itzf_Vbci; + } /* c Stamp element: Itzr */ @@ -218,6 +232,200 @@ c Stamp element: Rs *(here->VBICsubsSISubsSIPtr) += Irs_Vrs; *(here->VBICsubsSISubsPtr) += -Irs_Vrs; *(here->VBICsubsSubsSIPtr) += -Irs_Vrs; + + if (here->VBIC_selfheat) { + + Ibe_Vrth = here->VBICibe_Vrth; + Ibex_Vrth = here->VBICibex_Vrth; + if (!here->VBIC_excessPhase) + Itzf_Vrth = here->VBICitzf_vrth; + Itzr_Vrth = here->VBICitzr_Vrth; + Ibc_Vrth = here->VBICibc_Vrth; + Ibep_Vrth = here->VBICibep_Vrth; + Ircx_Vrth = here->VBICircx_Vrth; + Irci_Vrth = here->VBICirci_Vrth; + Irbx_Vrth = here->VBICirbx_Vrth; + Irbi_Vrth = here->VBICirbi_Vrth; + Ire_Vrth = here->VBICire_Vrth; + Irbp_Vrth = here->VBICirbp_Vrth; + Ibcp_Vrth = here->VBICibcp_Vrth; + Iccp_Vrth = here->VBICiccp_Vrth; + Irs_Vrth = here->VBICirs_Vrth; + Irth_Vrth = here->VBICirth_Vrth; + Ith_Vrth = here->VBICith_Vrth; + Ith_Vbei = here->VBICith_Vbei; + Ith_Vbci = here->VBICith_Vbci; + Ith_Vcei = here->VBICith_Vcei; + Ith_Vbex = here->VBICith_Vbex; + Ith_Vbep = here->VBICith_Vbep; + Ith_Vbcp = here->VBICith_Vbcp; + Ith_Vcep = here->VBICith_Vcep; + Ith_Vrci = here->VBICith_Vrci; + Ith_Vbcx = here->VBICith_Vbcx; + Ith_Vrbi = here->VBICith_Vrbi; + Ith_Vrbp = here->VBICith_Vrbp; + Ith_Vrcx = here->VBICith_Vrcx; + Ith_Vrbx = here->VBICith_Vrbx; + Ith_Vre = here->VBICith_Vre; + Ith_Vrs = here->VBICith_Vrs; + +/* +c Stamp element: Ibe +*/ + *(here->VBICbaseBItempPtr) += Ibe_Vrth; + *(here->VBICemitEItempPtr) += -Ibe_Vrth; +/* +c Stamp element: Ibex +*/ + *(here->VBICbaseBXtempPtr) += Ibex_Vrth; + *(here->VBICemitEItempPtr) += -Ibex_Vrth; + + if (!here->VBIC_excessPhase) { +/* +c Stamp element: Itzf +*/ + *(here->VBICcollCItempPtr) += Itzf_Vrth; + *(here->VBICemitEItempPtr) += -Itzf_Vrth; + } +/* +c Stamp element: Itzr +*/ + *(here->VBICemitEItempPtr) += Itzr_Vrth; + *(here->VBICcollCItempPtr) += -Itzr_Vrth; +/* +c Stamp element: Ibc +*/ + *(here->VBICbaseBItempPtr) += Ibc_Vrth; + *(here->VBICcollCItempPtr) += -Ibc_Vrth; +/* +c Stamp element: Ibep +*/ + *(here->VBICbaseBXtempPtr) += Ibep_Vrth; + *(here->VBICbaseBPtempPtr) += -Ibep_Vrth; +/* +c Stamp element: Rcx +*/ + *(here->VBICcollTempPtr) += Ircx_Vrth; + *(here->VBICcollCXtempPtr) += -Ircx_Vrth; +/* +c Stamp element: Irci +*/ + *(here->VBICcollCXtempPtr) += Irci_Vrth; + *(here->VBICcollCItempPtr) += -Irci_Vrth; +/* +c Stamp element: Rbx +*/ + *(here->VBICbaseTempPtr) += Irbx_Vrth; + *(here->VBICbaseBXtempPtr) += -Irbx_Vrth; +/* +c Stamp element: Irbi +*/ + *(here->VBICbaseBXtempPtr) += Irbi_Vrth; + *(here->VBICbaseBItempPtr) += -Irbi_Vrth; +/* +c Stamp element: Re +*/ + *(here->VBICemitTempPtr) += Ire_Vrth; + *(here->VBICemitEItempPtr) += -Ire_Vrth; +/* +c Stamp element: Irbp +*/ + *(here->VBICbaseBPtempPtr) += Irbp_Vrth; + *(here->VBICcollCXtempPtr) += -Irbp_Vrth; +/* +c Stamp element: Ibcp +*/ + *(here->VBICsubsSItempPtr) += Ibcp_Vrth; + *(here->VBICbaseBPtempPtr) += -Ibcp_Vrth; +/* +c Stamp element: Iccp +*/ + *(here->VBICbaseBXtempPtr) += Iccp_Vrth; + *(here->VBICsubsSItempPtr) += -Iccp_Vrth; +/* +c Stamp element: Rs +*/ + *(here->VBICsubsTempPtr) += Irs_Vrth; + *(here->VBICsubsSItempPtr) += -Irs_Vrth; +/* +c Stamp element: Rth +*/ + *(here->VBICtempTempPtr) += Irth_Vrth; +/* +c Stamp element: Ith +*/ + *(here->VBICtempTempPtr) += -Ith_Vrth; + + *(here->VBICtempBaseBIPtr) += -Ith_Vbei; + *(here->VBICtempEmitEIPtr) += +Ith_Vbei; + *(here->VBICtempBaseBIPtr) += -Ith_Vbci; + *(here->VBICtempCollCIPtr) += +Ith_Vbci; + *(here->VBICtempCollCIPtr) += -Ith_Vcei; + *(here->VBICtempEmitEIPtr) += +Ith_Vcei; + *(here->VBICtempBaseBXPtr) += -Ith_Vbex; + *(here->VBICtempEmitEIPtr) += +Ith_Vbex; + *(here->VBICtempBaseBXPtr) += -Ith_Vbep; + *(here->VBICtempBaseBPPtr) += +Ith_Vbep; + *(here->VBICtempSubsPtr) += -Ith_Vbcp; + *(here->VBICtempBaseBPPtr) += +Ith_Vbcp; + *(here->VBICtempBaseBXPtr) += -Ith_Vcep; + *(here->VBICtempSubsPtr) += +Ith_Vcep; + *(here->VBICtempCollCXPtr) += -Ith_Vrci; + *(here->VBICtempCollCIPtr) += +Ith_Vrci; + *(here->VBICtempBaseBIPtr) += -Ith_Vbcx; + *(here->VBICtempCollCXPtr) += +Ith_Vbcx; + *(here->VBICtempBaseBXPtr) += -Ith_Vrbi; + *(here->VBICtempBaseBIPtr) += +Ith_Vrbi; + *(here->VBICtempBaseBPPtr) += -Ith_Vrbp; + *(here->VBICtempCollCXPtr) += +Ith_Vrbp; + *(here->VBICtempCollPtr) += -Ith_Vrcx; + *(here->VBICtempCollCXPtr) += +Ith_Vrcx; + *(here->VBICtempBasePtr) += -Ith_Vrbx; + *(here->VBICtempBaseBXPtr) += +Ith_Vrbx; + *(here->VBICtempEmitPtr) += -Ith_Vre; + *(here->VBICtempEmitEIPtr) += +Ith_Vre; + *(here->VBICtempSubsPtr) += -Ith_Vrs; + *(here->VBICtempSubsSIPtr) += +Ith_Vrs; + if (here->VBIC_excessPhase) { + Ith_Vrxf = *(ckt->CKTstate0 + here->VBICith_Vrxf); + *(here->VBICtempXf2Ptr) += +Ith_Vrxf; + } + } + + if (here->VBIC_excessPhase) { + Itxf_Vrxf = *(ckt->CKTstate0 + here->VBICitxf_Vrxf); + Ibc_Vrxf = *(ckt->CKTstate0 + here->VBICibc_Vrxf); + Ixzf_Vbei = *(ckt->CKTstate0 + here->VBICixzf_Vbei); + Ixzf_Vbci = *(ckt->CKTstate0 + here->VBICixzf_Vbci); + Ixxf_Vrxf = *(ckt->CKTstate0 + here->VBICixxf_Vrxf); +/* +c Stamp element: Itxf +*/ + *(here->VBICcollCIXf2Ptr) += Itxf_Vrxf; + *(here->VBICemitEIXf2Ptr) += -Itxf_Vrxf; +/* +c Stamp element: Ibc +*/ + *(here->VBICbaseBIXf2Ptr) += Ibc_Vrxf; + *(here->VBICcollCIXf2Ptr) += -Ibc_Vrxf; +/* +c Stamp element: Ixzf, Branch: xf1-ground +*/ + *(here->VBICxf1BaseBIPtr) += +Ixzf_Vbei; + *(here->VBICxf1EmitEIPtr) += -Ixzf_Vbei; + *(here->VBICxf1BaseBIPtr) += +Ixzf_Vbci; + *(here->VBICxf1CollCIPtr) += -Ixzf_Vbci; + if (here->VBIC_selfheat) { + Ixzf_Vrth = *(ckt->CKTstate0 + here->VBICixzf_Vrth); + *(here->VBICxf1TempPtr) += Ixzf_Vrth; + } +/* +c Stamp element: Ixxf, Branch: xf2-ground +*/ + *(here->VBICxf2Xf2Ptr) += +Ixxf_Vrxf; + + } + /* c The complex part */ @@ -296,6 +504,48 @@ c Stamp element: Qbco *(here->VBICbaseCollPtr + 1) += -XQbco_Vbc; *(here->VBICcollBasePtr + 1) += -XQbco_Vbc; + if (here->VBIC_selfheat) { + XQcth_Vrth = here->VBICcapcth * ckt->CKTomega; + XQbe_Vrth = here->VBICcapqbeth * ckt->CKTomega; + XQbex_Vrth = here->VBICcapqbexth * ckt->CKTomega; + XQbc_Vrth = here->VBICcapqbcth * ckt->CKTomega; + XQbcx_Vrth = here->VBICcapqbcxth * ckt->CKTomega; + XQbep_Vrth = here->VBICcapqbepth * ckt->CKTomega; + XQbcp_Vrth = here->VBICcapqbcpth * ckt->CKTomega; + + *(here->VBICtempTempPtr + 1) += XQcth_Vrth; + + *(here->VBICbaseBItempPtr + 1) += XQbe_Vrth; + *(here->VBICemitEItempPtr + 1) += -XQbe_Vrth; + *(here->VBICbaseBXtempPtr + 1) += XQbex_Vrth; + *(here->VBICemitEItempPtr + 1) += -XQbex_Vrth; + *(here->VBICbaseBItempPtr + 1) += XQbc_Vrth; + *(here->VBICcollCItempPtr + 1) += -XQbc_Vrth; + *(here->VBICbaseBItempPtr + 1) += XQbcx_Vrth; + *(here->VBICcollCXtempPtr + 1) += -XQbcx_Vrth; + *(here->VBICbaseBXtempPtr + 1) += XQbep_Vrth; + *(here->VBICbaseBPtempPtr + 1) += -XQbep_Vrth; + *(here->VBICsubsSItempPtr + 1) += XQbcp_Vrth; + *(here->VBICbaseBPtempPtr + 1) += -XQbcp_Vrth; + } + if (here->VBIC_excessPhase) { +/* +c Stamp element: Qcxf +*/ + XQcxf_Vcxf = here->VBICcapQcxf * ckt->CKTomega; + *(here->VBICxf1Xf1Ptr + 1) += XQcxf_Vcxf; +/* +c Stamp element: L = TD/3 +*/ + Xl = here->VBICindInduct * ckt->CKTomega; + + *(here->VBICxf1IbrPtr) += 1; + *(here->VBICxf2IbrPtr) -= 1; + *(here->VBICibrXf1Ptr) += 1; + *(here->VBICibrXf2Ptr) -= 1; + *(here->VBICibrIbrPtr + 1) -= Xl; + + } } } diff --git a/src/spicelib/devices/vbic/vbicask.c b/src/spicelib/devices/vbic/vbicask.c index 877ed7a4f..bcd298f22 100644 --- a/src/spicelib/devices/vbic/vbicask.c +++ b/src/spicelib/devices/vbic/vbicask.c @@ -75,9 +75,14 @@ VBICask(CKTcircuit *ckt, GENinstance *instPtr, int which, IFvalue *value, IFvalu value->rValue = *(ckt->CKTstate0 + here->VBICvbci); return(OK); case VBIC_QUEST_CC: - value->rValue = *(ckt->CKTstate0 + here->VBICitzf) - - *(ckt->CKTstate0 + here->VBICitzr) - - *(ckt->CKTstate0 + here->VBICibc); + if (!here->VBIC_excessPhase) + value->rValue = *(ckt->CKTstate0 + here->VBICitzf) - + *(ckt->CKTstate0 + here->VBICitzr) - + *(ckt->CKTstate0 + here->VBICibc); + else + value->rValue = *(ckt->CKTstate0 + here->VBICitxf) - + *(ckt->CKTstate0 + here->VBICitzr) - + *(ckt->CKTstate0 + here->VBICibc); value->rValue *= VBICmodPtr(here)->VBICtype; return(OK); case VBIC_QUEST_CB: @@ -89,10 +94,16 @@ VBICask(CKTcircuit *ckt, GENinstance *instPtr, int which, IFvalue *value, IFvalu value->rValue *= VBICmodPtr(here)->VBICtype; return(OK); case VBIC_QUEST_CE: - value->rValue = - *(ckt->CKTstate0 + here->VBICibe) - - *(ckt->CKTstate0 + here->VBICibex) - - *(ckt->CKTstate0 + here->VBICitzf) + - *(ckt->CKTstate0 + here->VBICitzr); + if (!here->VBIC_excessPhase) + value->rValue = - *(ckt->CKTstate0 + here->VBICibe) - + *(ckt->CKTstate0 + here->VBICibex) - + *(ckt->CKTstate0 + here->VBICitzf) + + *(ckt->CKTstate0 + here->VBICitzr); + else + value->rValue = - *(ckt->CKTstate0 + here->VBICibe) - + *(ckt->CKTstate0 + here->VBICibex) - + *(ckt->CKTstate0 + here->VBICitxf) + + *(ckt->CKTstate0 + here->VBICitzr); value->rValue *= VBICmodPtr(here)->VBICtype; return(OK); case VBIC_QUEST_CS: @@ -105,21 +116,38 @@ VBICask(CKTcircuit *ckt, GENinstance *instPtr, int which, IFvalue *value, IFvalu VBICask(ckt, instPtr, VBIC_QUEST_CB, &IB, select); VBICask(ckt, instPtr, VBIC_QUEST_CE, &IE, select); VBICask(ckt, instPtr, VBIC_QUEST_CS, &IS, select); - value->rValue = fabs(*(ckt->CKTstate0 + here->VBICibe) * *(ckt->CKTstate0 + here->VBICvbei)) + - fabs(*(ckt->CKTstate0 + here->VBICibc) * *(ckt->CKTstate0 + here->VBICvbci)) + - fabs(*(ckt->CKTstate0 + here->VBICitzf) - *(ckt->CKTstate0 + here->VBICitzr)) - * fabs(*(ckt->CKTstate0 + here->VBICvbei) - *(ckt->CKTstate0 + here->VBICvbci)) + - fabs(*(ckt->CKTstate0 + here->VBICibex) * *(ckt->CKTstate0 + here->VBICvbex)) + - fabs(*(ckt->CKTstate0 + here->VBICibep) * *(ckt->CKTstate0 + here->VBICvbep)) + - fabs(*(ckt->CKTstate0 + here->VBICibcp) * *(ckt->CKTstate0 + here->VBICvbcp)) + - fabs(*(ckt->CKTstate0 + here->VBICiccp)) - * fabs(*(ckt->CKTstate0 + here->VBICvbep) - *(ckt->CKTstate0 + here->VBICvbcp)) + - fabs(IC.rValue * IC.rValue * here->VBICtextCollResist) + - fabs(IC.rValue * *(ckt->CKTstate0 + here->VBICvrci)) + - fabs(IB.rValue * IB.rValue * here->VBICtextBaseResist) + - fabs(IB.rValue * *(ckt->CKTstate0 + here->VBICvrbi)) + - fabs(IE.rValue * IE.rValue * here->VBICtemitterResist) + - fabs(IS.rValue * *(ckt->CKTstate0 + here->VBICvrbp)); + if (!here->VBIC_excessPhase) + value->rValue = fabs(*(ckt->CKTstate0 + here->VBICibe) * *(ckt->CKTstate0 + here->VBICvbei)) + + fabs(*(ckt->CKTstate0 + here->VBICibc) * *(ckt->CKTstate0 + here->VBICvbci)) + + fabs(*(ckt->CKTstate0 + here->VBICitzf) - *(ckt->CKTstate0 + here->VBICitzr)) + * fabs(*(ckt->CKTstate0 + here->VBICvbei) - *(ckt->CKTstate0 + here->VBICvbci)) + + fabs(*(ckt->CKTstate0 + here->VBICibex) * *(ckt->CKTstate0 + here->VBICvbex)) + + fabs(*(ckt->CKTstate0 + here->VBICibep) * *(ckt->CKTstate0 + here->VBICvbep)) + + fabs(*(ckt->CKTstate0 + here->VBICibcp) * *(ckt->CKTstate0 + here->VBICvbcp)) + + fabs(*(ckt->CKTstate0 + here->VBICiccp)) + * fabs(*(ckt->CKTstate0 + here->VBICvbep) - *(ckt->CKTstate0 + here->VBICvbcp)) + + fabs(IC.rValue * IC.rValue * here->VBICtextCollResist) + + fabs(IC.rValue * *(ckt->CKTstate0 + here->VBICvrci)) + + fabs(IB.rValue * IB.rValue * here->VBICtextBaseResist) + + fabs(IB.rValue * *(ckt->CKTstate0 + here->VBICvrbi)) + + fabs(IE.rValue * IE.rValue * here->VBICtemitterResist) + + fabs(IS.rValue * *(ckt->CKTstate0 + here->VBICvrbp)); + else + value->rValue = fabs(*(ckt->CKTstate0 + here->VBICibe) * *(ckt->CKTstate0 + here->VBICvbei)) + + fabs(*(ckt->CKTstate0 + here->VBICibc) * *(ckt->CKTstate0 + here->VBICvbci)) + + fabs(*(ckt->CKTstate0 + here->VBICitxf) - *(ckt->CKTstate0 + here->VBICitzr)) + * fabs(*(ckt->CKTstate0 + here->VBICvbei) - *(ckt->CKTstate0 + here->VBICvbci)) + + fabs(*(ckt->CKTstate0 + here->VBICibex) * *(ckt->CKTstate0 + here->VBICvbex)) + + fabs(*(ckt->CKTstate0 + here->VBICibep) * *(ckt->CKTstate0 + here->VBICvbep)) + + fabs(*(ckt->CKTstate0 + here->VBICibcp) * *(ckt->CKTstate0 + here->VBICvbcp)) + + fabs(*(ckt->CKTstate0 + here->VBICiccp)) + * fabs(*(ckt->CKTstate0 + here->VBICvbep) - *(ckt->CKTstate0 + here->VBICvbcp)) + + fabs(IC.rValue * IC.rValue * here->VBICtextCollResist) + + fabs(IC.rValue * *(ckt->CKTstate0 + here->VBICvrci)) + + fabs(IB.rValue * IB.rValue * here->VBICtextBaseResist) + + fabs(IB.rValue * *(ckt->CKTstate0 + here->VBICvrbi)) + + fabs(IE.rValue * IE.rValue * here->VBICtemitterResist) + + fabs(IS.rValue * *(ckt->CKTstate0 + here->VBICvrbp)); return(OK); case VBIC_QUEST_GM: value->rValue = *(ckt->CKTstate0 + here->VBICitzf_Vbei); diff --git a/src/spicelib/devices/vbic/vbicbindCSC.c b/src/spicelib/devices/vbic/vbicbindCSC.c index 72ee54c2b..90403845d 100644 --- a/src/spicelib/devices/vbic/vbicbindCSC.c +++ b/src/spicelib/devices/vbic/vbicbindCSC.c @@ -36,6 +36,7 @@ VBICbindCSC (GENmodel *inModel, CKTcircuit *ckt) CREATE_KLU_BINDING_TABLE(VBICemitEIEmitEIPtr, VBICemitEIEmitEIBinding, VBICemitEINode, VBICemitEINode); CREATE_KLU_BINDING_TABLE(VBICbaseBPBaseBPPtr, VBICbaseBPBaseBPBinding, VBICbaseBPNode, VBICbaseBPNode); CREATE_KLU_BINDING_TABLE(VBICsubsSISubsSIPtr, VBICsubsSISubsSIBinding, VBICsubsSINode, VBICsubsSINode); + CREATE_KLU_BINDING_TABLE(VBICbaseEmitPtr, VBICbaseEmitBinding, VBICbaseNode, VBICemitNode); CREATE_KLU_BINDING_TABLE(VBICemitBasePtr, VBICemitBaseBinding, VBICemitNode, VBICbaseNode); CREATE_KLU_BINDING_TABLE(VBICbaseCollPtr, VBICbaseCollBinding, VBICbaseNode, VBICcollNode); @@ -56,6 +57,7 @@ VBICbindCSC (GENmodel *inModel, CKTcircuit *ckt) CREATE_KLU_BINDING_TABLE(VBICbaseBXSubsSIPtr, VBICbaseBXSubsSIBinding, VBICbaseBXNode, VBICsubsSINode); CREATE_KLU_BINDING_TABLE(VBICbaseBIEmitEIPtr, VBICbaseBIEmitEIBinding, VBICbaseBINode, VBICemitEINode); CREATE_KLU_BINDING_TABLE(VBICbaseBPSubsSIPtr, VBICbaseBPSubsSIBinding, VBICbaseBPNode, VBICsubsSINode); + CREATE_KLU_BINDING_TABLE(VBICcollCXCollPtr, VBICcollCXCollBinding, VBICcollCXNode, VBICcollNode); CREATE_KLU_BINDING_TABLE(VBICbaseBXBasePtr, VBICbaseBXBaseBinding, VBICbaseBXNode, VBICbaseNode); CREATE_KLU_BINDING_TABLE(VBICemitEIEmitPtr, VBICemitEIEmitBinding, VBICemitEINode, VBICemitNode); @@ -101,7 +103,30 @@ VBICbindCSC (GENmodel *inModel, CKTcircuit *ckt) CREATE_KLU_BINDING_TABLE(VBICtempSubsPtr, VBICtempSubsBinding, VBICtempNode, VBICsubsNode); CREATE_KLU_BINDING_TABLE(VBICtempSubsSIPtr, VBICtempSubsSIBinding, VBICtempNode, VBICsubsSINode); CREATE_KLU_BINDING_TABLE(VBICtempTempPtr, VBICtempTempBinding, VBICtempNode, VBICtempNode); + if (here->VBIC_excessPhase) { + CREATE_KLU_BINDING_TABLE(VBICtempXf2Ptr, VBICtempXf2Binding, VBICtempNode, VBICxf2Node); + CREATE_KLU_BINDING_TABLE(VBICxf1TempPtr, VBICxf1TempBinding, VBICxf1Node ,VBICtempNode); + } } + + if (here->VBIC_excessPhase) { + CREATE_KLU_BINDING_TABLE(VBICxf1Xf1Ptr , VBICxf1Xf1Binding , VBICxf1Node , VBICxf1Node); + CREATE_KLU_BINDING_TABLE(VBICxf1Xf2Ptr , VBICxf1Xf2Binding , VBICxf1Node , VBICxf2Node); + CREATE_KLU_BINDING_TABLE(VBICxf1CollCIPtr, VBICxf1CollCIBinding, VBICxf1Node , VBICcollCINode); + CREATE_KLU_BINDING_TABLE(VBICxf1BaseBIPtr, VBICxf1BaseBIBinding, VBICxf1Node , VBICbaseBINode); + CREATE_KLU_BINDING_TABLE(VBICxf1EmitEIPtr, VBICxf1EmitEIBinding, VBICxf1Node , VBICemitEINode); + CREATE_KLU_BINDING_TABLE(VBICxf2Xf2Ptr , VBICxf2Xf2Binding , VBICxf2Node , VBICxf2Node); + CREATE_KLU_BINDING_TABLE(VBICxf2Xf1Ptr , VBICxf2Xf1Binding , VBICxf2Node , VBICxf1Node); + CREATE_KLU_BINDING_TABLE(VBICcollCIXf2Ptr, VBICcollCIXf2Binding, VBICcollCINode, VBICxf2Node); + CREATE_KLU_BINDING_TABLE(VBICbaseBIXf2Ptr, VBICbaseBIXf2Binding, VBICbaseBINode, VBICxf2Node); + CREATE_KLU_BINDING_TABLE(VBICemitEIXf2Ptr, VBICemitEIXf2Binding, VBICemitEINode, VBICxf2Node); + CREATE_KLU_BINDING_TABLE(VBICxf1IbrPtr , VBICxf1IbrBinding , VBICxf1Node , VBICbrEq); + CREATE_KLU_BINDING_TABLE(VBICxf2IbrPtr , VBICxf2IbrBinding , VBICxf2Node , VBICbrEq); + CREATE_KLU_BINDING_TABLE(VBICibrXf2Ptr , VBICibrXf2Binding , VBICbrEq , VBICxf2Node); + CREATE_KLU_BINDING_TABLE(VBICibrXf1Ptr , VBICibrXf1Binding , VBICbrEq , VBICxf1Node); + CREATE_KLU_BINDING_TABLE(VBICibrIbrPtr , VBICibrIbrBinding , VBICbrEq , VBICbrEq); + } + } } diff --git a/src/spicelib/devices/vbic/vbicdefs.h b/src/spicelib/devices/vbic/vbicdefs.h index efa83c933..4e6bcb4af 100644 --- a/src/spicelib/devices/vbic/vbicdefs.h +++ b/src/spicelib/devices/vbic/vbicdefs.h @@ -60,6 +60,9 @@ typedef struct sVBICinstance { int VBICemitEINode; /* number of internal emitter node of vbic */ int VBICbaseBPNode; /* number of internal base node of vbic */ int VBICsubsSINode; /* number of internal substrate node */ + int VBICxf1Node; /* number of internal excess phase 1 node itf */ + int VBICxf2Node; /* number of internal excess phase 2 node itf */ + int VBICbrEq; /* number of the branch equation added for current */ double VBICarea; /* area factor for the vbic */ double VBICicVBE; /* initial condition voltage B-E*/ @@ -125,6 +128,10 @@ typedef struct sVBICinstance { * (emitter prime,emitter prime) */ double *VBICsubsSISubsSIPtr; /* pointer to sparse matrix at * (substrate prime, substrate prime) */ + double *VBICemitEIXfPtr; /* pointer to sparse matrix at + * (emitter prime,xf) */ + double *VBICbaseBIXfPtr; /* pointer to sparse matrix at + * (base prime,xf) */ double *VBICbaseEmitPtr; /* pointer to sparse matrix at * (base,emit) */ @@ -233,6 +240,28 @@ typedef struct sVBICinstance { double *VBICtempSubsSIPtr; double *VBICtempTempPtr; + /* excess phase */ + double *VBICtempXf2Ptr; + double *VBICxf1TempPtr; + + double *VBICxf1Xf1Ptr; + double *VBICxf1Xf2Ptr; + double *VBICxf1CollCIPtr; + double *VBICxf1BaseBIPtr; + double *VBICxf1EmitEIPtr; + + double *VBICxf2Xf2Ptr; + double *VBICxf2Xf1Ptr; + double *VBICcollCIXf2Ptr; + double *VBICbaseBIXf2Ptr; + double *VBICemitEIXf2Ptr; + + double *VBICxf1IbrPtr; + double *VBICxf2IbrPtr; + double *VBICibrXf1Ptr; + double *VBICibrXf2Ptr; + double *VBICibrIbrPtr; + unsigned VBICareaGiven :1; /* flag to indicate area was specified */ unsigned VBICoff :1; /* 'off' flag for vbic */ unsigned VBICicVBEGiven :1; /* flag to indicate VBE init. cond. given */ @@ -249,7 +278,52 @@ typedef struct sVBICinstance { double VBICcapbcp; double VBICcapcth; - int VBIC_selfheat; /* self-heating enabled */ + double VBICcapqbeth; + double VBICcapqbexth; + double VBICcapqbcth; + double VBICcapqbcxth; + double VBICcapqbepth; + double VBICcapqbcpth; + + double VBICibe_Vrth; + double VBICibex_Vrth; + double VBICitzf_vrth; + double VBICitzr_Vrth; + double VBICibc_Vrth; + double VBICibep_Vrth; + double VBICircx_Vrth; + double VBICirci_Vrth; + double VBICirbx_Vrth; + double VBICirbi_Vrth; + double VBICire_Vrth; + double VBICirbp_Vrth; + double VBICibcp_Vrth; + double VBICiccp_Vrth; + double VBICirs_Vrth; + double VBICirth_Vrth; + double VBICith_Vrth; + + double VBICith_Vbei; + double VBICith_Vbci; + double VBICith_Vcei; + double VBICith_Vbex; + double VBICith_Vbep; + double VBICith_Vbcp; + double VBICith_Vcep; + double VBICith_Vrci; + double VBICith_Vbcx; + double VBICith_Vrbi; + double VBICith_Vrbp; + double VBICith_Vrcx; + double VBICith_Vrbx; + double VBICith_Vre; + double VBICith_Vrs; + + double VBICindInduct; + double VBICcapQcxf; + + int VBIC_selfheat; /* self-heating enabled */ + int VBIC_excessPhase; /* excess phase enabled */ #ifndef NONOISE double VBICnVar[NSTATVARS][VBICNSRCS]; @@ -270,6 +344,7 @@ typedef struct sVBICinstance { BindElement *VBICemitEIEmitEIBinding ; BindElement *VBICbaseBPBaseBPBinding ; BindElement *VBICsubsSISubsSIBinding ; + BindElement *VBICbaseEmitBinding ; BindElement *VBICemitBaseBinding ; BindElement *VBICbaseCollBinding ; @@ -290,6 +365,7 @@ typedef struct sVBICinstance { BindElement *VBICbaseBXSubsSIBinding ; BindElement *VBICbaseBIEmitEIBinding ; BindElement *VBICbaseBPSubsSIBinding ; + BindElement *VBICcollCXCollBinding ; BindElement *VBICbaseBXBaseBinding ; BindElement *VBICemitEIEmitBinding ; @@ -310,6 +386,7 @@ typedef struct sVBICinstance { BindElement *VBICsubsSICollCIBinding ; BindElement *VBICsubsSIBaseBIBinding ; BindElement *VBICsubsSIBaseBPBinding ; + BindElement *VBICcollTempBinding ; BindElement *VBICbaseTempBinding ; BindElement *VBICemitTempBinding ; @@ -333,107 +410,148 @@ typedef struct sVBICinstance { BindElement *VBICtempSubsBinding ; BindElement *VBICtempSubsSIBinding ; BindElement *VBICtempTempBinding ; + + BindElement *VBICtempXf2Binding ; + BindElement *VBICxf1TempBinding ; + + BindElement *VBICxf1Xf1Binding ; + BindElement *VBICxf1Xf2Binding ; + BindElement *VBICxf1CollCIBinding ; + BindElement *VBICxf1BaseBIBinding ; + BindElement *VBICxf1EmitEIBinding ; + BindElement *VBICxf2Xf2Binding ; + BindElement *VBICxf2Xf1Binding ; + BindElement *VBICcollCIXf2Binding ; + BindElement *VBICbaseBIXf2Binding ; + BindElement *VBICemitEIXf2Binding ; + BindElement *VBICxf1IbrBinding ; + BindElement *VBICxf2IbrBinding ; + BindElement *VBICibrXf2Binding ; + BindElement *VBICibrXf1Binding ; + BindElement *VBICibrIbrBinding ; #endif } VBICinstance ; /* entries in the state vector for vbic: */ -#define VBICvbei VBICstate -#define VBICvbex VBICstate+1 -#define VBICvbci VBICstate+2 -#define VBICvbcx VBICstate+3 -#define VBICvbep VBICstate+4 -#define VBICvrci VBICstate+5 -#define VBICvrbi VBICstate+6 -#define VBICvrbp VBICstate+7 -#define VBICvbcp VBICstate+8 +#define VBICvbei VBICstate +#define VBICvbex VBICstate+1 +#define VBICvbci VBICstate+2 +#define VBICvbcx VBICstate+3 +#define VBICvbep VBICstate+4 +#define VBICvrci VBICstate+5 +#define VBICvrbi VBICstate+6 +#define VBICvrbp VBICstate+7 +#define VBICvbcp VBICstate+8 -#define VBICibe VBICstate+9 -#define VBICibe_Vbei VBICstate+10 +#define VBICibe VBICstate+9 +#define VBICibe_Vbei VBICstate+10 -#define VBICibex VBICstate+11 +#define VBICibex VBICstate+11 #define VBICibex_Vbex VBICstate+12 -#define VBICitzf VBICstate+13 +#define VBICitzf VBICstate+13 #define VBICitzf_Vbei VBICstate+14 #define VBICitzf_Vbci VBICstate+15 +#define VBICitzf_Vrth VBICstate+16 -#define VBICitzr VBICstate+16 -#define VBICitzr_Vbci VBICstate+17 -#define VBICitzr_Vbei VBICstate+18 +#define VBICitzr VBICstate+17 +#define VBICitzr_Vbci VBICstate+18 +#define VBICitzr_Vbei VBICstate+19 -#define VBICibc VBICstate+19 -#define VBICibc_Vbci VBICstate+20 -#define VBICibc_Vbei VBICstate+21 +#define VBICibc VBICstate+20 +#define VBICibc_Vbci VBICstate+21 +#define VBICibc_Vbei VBICstate+22 -#define VBICibep VBICstate+22 -#define VBICibep_Vbep VBICstate+23 +#define VBICibep VBICstate+23 +#define VBICibep_Vbep VBICstate+24 -#define VBICirci VBICstate+24 -#define VBICirci_Vrci VBICstate+25 -#define VBICirci_Vbci VBICstate+26 -#define VBICirci_Vbcx VBICstate+27 +#define VBICirci VBICstate+25 +#define VBICirci_Vrci VBICstate+26 +#define VBICirci_Vbci VBICstate+27 +#define VBICirci_Vbcx VBICstate+28 -#define VBICirbi VBICstate+28 -#define VBICirbi_Vrbi VBICstate+29 -#define VBICirbi_Vbei VBICstate+30 -#define VBICirbi_Vbci VBICstate+31 +#define VBICirbi VBICstate+29 +#define VBICirbi_Vrbi VBICstate+30 +#define VBICirbi_Vbei VBICstate+31 +#define VBICirbi_Vbci VBICstate+32 -#define VBICirbp VBICstate+32 -#define VBICirbp_Vrbp VBICstate+33 -#define VBICirbp_Vbep VBICstate+34 -#define VBICirbp_Vbci VBICstate+35 +#define VBICirbp VBICstate+33 +#define VBICirbp_Vrbp VBICstate+34 +#define VBICirbp_Vbep VBICstate+35 +#define VBICirbp_Vbci VBICstate+36 -#define VBICqbe VBICstate+36 -#define VBICcqbe VBICstate+37 -#define VBICcqbeci VBICstate+38 +#define VBICqbe VBICstate+37 +#define VBICcqbe VBICstate+38 +#define VBICcqbeci VBICstate+39 -#define VBICqbex VBICstate+39 -#define VBICcqbex VBICstate+40 +#define VBICqbex VBICstate+40 +#define VBICcqbex VBICstate+41 -#define VBICqbc VBICstate+41 -#define VBICcqbc VBICstate+42 +#define VBICqbc VBICstate+42 +#define VBICcqbc VBICstate+43 -#define VBICqbcx VBICstate+43 -#define VBICcqbcx VBICstate+44 +#define VBICqbcx VBICstate+44 +#define VBICcqbcx VBICstate+45 -#define VBICqbep VBICstate+45 -#define VBICcqbep VBICstate+46 -#define VBICcqbepci VBICstate+47 +#define VBICqbep VBICstate+46 +#define VBICcqbep VBICstate+47 +#define VBICcqbepci VBICstate+48 -#define VBICqbeo VBICstate+48 -#define VBICcqbeo VBICstate+49 -#define VBICgqbeo VBICstate+50 +#define VBICqbeo VBICstate+49 +#define VBICcqbeo VBICstate+50 +#define VBICgqbeo VBICstate+51 -#define VBICqbco VBICstate+51 -#define VBICcqbco VBICstate+52 -#define VBICgqbco VBICstate+53 +#define VBICqbco VBICstate+52 +#define VBICcqbco VBICstate+53 +#define VBICgqbco VBICstate+54 -#define VBICibcp VBICstate+54 -#define VBICibcp_Vbcp VBICstate+55 +#define VBICibcp VBICstate+55 +#define VBICibcp_Vbcp VBICstate+56 -#define VBICiccp VBICstate+56 -#define VBICiccp_Vbep VBICstate+57 -#define VBICiccp_Vbci VBICstate+58 -#define VBICiccp_Vbcp VBICstate+59 +#define VBICiccp VBICstate+57 +#define VBICiccp_Vbep VBICstate+58 +#define VBICiccp_Vbci VBICstate+59 +#define VBICiccp_Vbcp VBICstate+60 -#define VBICqbcp VBICstate+60 -#define VBICcqbcp VBICstate+61 +#define VBICqbcp VBICstate+61 +#define VBICcqbcp VBICstate+62 -#define VBICircx_Vrcx VBICstate+62 -#define VBICirbx_Vrbx VBICstate+63 -#define VBICirs_Vrs VBICstate+64 -#define VBICire_Vre VBICstate+65 +#define VBICircx_Vrcx VBICstate+63 +#define VBICirbx_Vrbx VBICstate+64 +#define VBICirs_Vrs VBICstate+65 +#define VBICire_Vre VBICstate+66 -#define VBICqcth VBICstate+66 /* thermal capacitor charge */ -#define VBICcqcth VBICstate+67 /* thermal capacitor current */ +#define VBICqcth VBICstate+67 /* thermal capacitor charge */ +#define VBICcqcth VBICstate+68 /* thermal capacitor current */ -#define VBICvrth VBICstate+68 -#define VBICicth_Vrth VBICstate+69 +#define VBICvrth VBICstate+69 +#define VBICicth_Vrth VBICstate+70 -#define VBICnumStates 70 +#define VBICqcxf VBICstate+71 +#define VBICcqcxf VBICstate+72 +#define VBICgqcxf VBICstate+73 + +#define VBICibc_Vrxf VBICstate+74 + +#define VBICixzf VBICstate+75 +#define VBICixzf_Vbei VBICstate+76 +#define VBICixzf_Vbci VBICstate+77 +#define VBICixzf_Vrth VBICstate+78 + +#define VBICixxf VBICstate+79 +#define VBICixxf_Vrxf VBICstate+80 + +#define VBICitxf VBICstate+81 +#define VBICitxf_Vrxf VBICstate+82 +#define VBICith_Vrxf VBICstate+83 + +#define VBICindFlux VBICstate+84 +#define VBICindVolt VBICstate+85 + +#define VBICnumStates 86 /* per model data */ typedef struct sVBICmodel { /* model structure for a vbic */ diff --git a/src/spicelib/devices/vbic/vbicload.c b/src/spicelib/devices/vbic/vbicload.c index 622345c20..10052bdca 100644 --- a/src/spicelib/devices/vbic/vbicload.c +++ b/src/spicelib/devices/vbic/vbicload.c @@ -18,6 +18,18 @@ Spice3 Implementation: 2003 Dietmar Warning DAnalyse GmbH #include "ngspice/sperror.h" #include "ngspice/devdefs.h" +int vbic_4T_it_cf_fj( + double *,double *,double *,double *,double *,double *,double *, + double *,double *,double *,double *,double *,double *,double *, + double *,double *,double *,double *,double *,double *,double *, + double *,double *,double *,double *,double *,double *,double *, + double *,double *,double *,double *,double *,double *,double *, + double *,double *,double *,double *,double *,double *,double *, + double *,double *,double *,double *,double *,double *,double *, + double *,double *,double *,double *,double *,double *,double *, + double *,double *,double *,double *,double *,double *,double *, + double *,double *,double *,double *,double *,double *,double *, + double *,double *,double *,double *,double *,double *); int vbic_4T_et_cf_fj( double *,double *,double *,double *,double *,double *,double *, double *,double *,double *,double *,double *,double *,double *, @@ -37,7 +49,7 @@ int vbic_4T_et_cf_fj( double *,double *,double *,double *,double *,double *,double *, double *,double *,double *,double *,double *,double *,double *, double *,double *); -int vbic_4T_it_cf_fj( +int vbic_4T_et_xf_fj( double *,double *,double *,double *,double *,double *,double *, double *,double *,double *,double *,double *,double *,double *, double *,double *,double *,double *,double *,double *,double *, @@ -48,7 +60,15 @@ int vbic_4T_it_cf_fj( double *,double *,double *,double *,double *,double *,double *, double *,double *,double *,double *,double *,double *,double *, double *,double *,double *,double *,double *,double *,double *, - double *,double *,double *,double *,double *,double *); + double *,double *,double *,double *,double *,double *,double *, + double *,double *,double *,double *,double *,double *,double *, + double *,double *,double *,double *,double *,double *,double *, + double *,double *,double *,double *,double *,double *,double *, + double *,double *,double *,double *,double *,double *,double *, + double *,double *,double *,double *,double *,double *,double *, + double *,double *,double *,double *,double *,double *,double *, + double *,double *,double *,double *,double *,double *,double *, + double *,double *,double *,double *,double *,double *,double *); int VBICload(GENmodel *inModel, CKTcircuit *ckt) @@ -62,21 +82,26 @@ VBICload(GENmodel *inModel, CKTcircuit *ckt) ,Vrth=0.0,Vbei,Vbex,Vbci,Vbep,Vbcp ,Vrcx,Vbcx,Vrci,Vrbx,Vrbi,Vre,Vrbp ,Vrs,Vbe,Vbc,Vcei=0.0,Vcep=0.0,Ibe,Ibe_Vrth=0.0 - ,Ibe_Vbei,Ibex,Ibex_Vrth=0.0,Ibex_Vbex,Itzf,Itzf_Vrth=0.0,Itzf_Vbei - ,Itzf_Vbci,Itzr,Itzr_Vrth=0.0,Itzr_Vbci,Itzr_Vbei,Ibc,Ibc_Vrth=0.0 + ,Ibe_Vbei,Ibex,Ibex_Vrth=0.0,Ibex_Vbex,Itzf=0.0,Itzf_Vrth=0.0,Itzf_Vbei=0.0 + ,Itzf_Vbci=0.0,Itzr,Itzr_Vrth=0.0,Itzr_Vbci,Itzr_Vbei,Ibc,Ibc_Vrth=0.0 ,Ibc_Vbci,Ibc_Vbei,Ibep,Ibep_Vrth=0.0,Ibep_Vbep,Ircx,Ircx_Vrcx ,Ircx_Vrth=0.0,Irci,Irci_Vrci,Irci_Vrth=0.0,Irci_Vbci,Irci_Vbcx,Irbx ,Irbx_Vrbx,Irbx_Vrth=0.0,Irbi,Irbi_Vrbi,Irbi_Vrth=0.0,Irbi_Vbei,Irbi_Vbci ,Ire,Ire_Vre,Ire_Vrth=0.0,Irbp,Irbp_Vrbp,Irbp_Vrth=0.0,Irbp_Vbep - ,Irbp_Vbci,Qbe,Qbe_Vrth,Qbe_Vbei,Qbe_Vbci,Qbex,Qbex_Vrth - ,Qbex_Vbex,Qbc,Qbc_Vrth,Qbc_Vbci,Qbcx,Qbcx_Vrth,Qbcx_Vbcx - ,Qbep,Qbep_Vrth,Qbep_Vbep,Qbep_Vbci,Qbeo,Qbeo_Vbe,Qbco + ,Irbp_Vbci,Qbe,Qbe_Vrth=0.0,Qbe_Vbei,Qbe_Vbci,Qbex,Qbex_Vrth=0.0 + ,Qbex_Vbex,Qbc,Qbc_Vrth=0.0,Qbc_Vbci,Qbcx,Qbcx_Vrth=0.0,Qbcx_Vbcx + ,Qbep,Qbep_Vrth=0.0,Qbep_Vbep,Qbep_Vbci,Qbeo,Qbeo_Vbe,Qbco ,Qbco_Vbc,Ibcp,Ibcp_Vrth=0.0,Ibcp_Vbcp,Iccp,Iccp_Vrth=0.0,Iccp_Vbep - ,Iccp_Vbci,Iccp_Vbcp,Irs,Irs_Vrs,Irs_Vrth=0.0,Qbcp,Qbcp_Vrth + ,Iccp_Vbci,Iccp_Vbcp,Irs,Irs_Vrs,Irs_Vrth=0.0,Qbcp,Qbcp_Vrth=0.0 ,Qbcp_Vbcp,Irth,Irth_Vrth=0.0,Ith=0.0,Ith_Vrth=0.0,Ith_Vbei=0.0,Ith_Vbci=0.0 ,Ith_Vcei=0.0,Ith_Vbex=0.0,Ith_Vbep=0.0,Ith_Vrs=0.0,Ith_Vbcp=0.0,Ith_Vcep=0.0,Ith_Vrcx=0.0 ,Ith_Vrci=0.0,Ith_Vbcx=0.0,Ith_Vrbx=0.0,Ith_Vrbi=0.0,Ith_Vre=0.0,Ith_Vrbp=0.0,Qcth=0.0 ,Qcth_Vrth=0.0,SCALE; + //NQS + double Vrxf=0.0, Vcxf=0.0, Itxf=0.0, Itxf_Vrxf=0.0, Ibc_Vrxf=0.0, Ith_Vrxf=0.0, + Ixzf_Vrth=0.0, Ixxf_Vrxf=0.0, Qcxf=0.0, Qcxf_Vcxf=0.0, Flxf=0.0, Flxf_Vrxf; + double Vxf1xf2=0.0, Rxf1xf2=0.0, newmind, req, veq; + int iret; double vce; #ifndef PREDICTOR @@ -94,7 +119,8 @@ VBICload(GENmodel *inModel, CKTcircuit *ckt) double delvbcp; double ibehat; double ibexhat; - double itzfhat; + double itzfhat=0.0; + double ixzfhat=0.0; double itzrhat; double ibchat; double ibephat; @@ -109,6 +135,10 @@ VBICload(GENmodel *inModel, CKTcircuit *ckt) int error; double gqbeo, cqbeo, gqbco, cqbco, gbcx, cbcx; double Icth, Icth_Vrth; + //NQS + double Ixzf=0.0,Ixxf=0.0; + double Ixzf_Vbei=0.0, Ixzf_Vbci=0.0; + double Icxf, Icxf_Vcxf; /* loop through all the models */ for( ; model != NULL; model = VBICnextModel(model)) { @@ -126,6 +156,7 @@ VBICload(GENmodel *inModel, CKTcircuit *ckt) gqbco = 0.0; cqbco = 0.0; Icth = 0.0, Icth_Vrth = 0.0; + Icxf=0.0, Icxf_Vcxf=0.0; /* * model parameters */ @@ -172,6 +203,15 @@ VBICload(GENmodel *inModel, CKTcircuit *ckt) /* * initialization */ + if (here->VBIC_excessPhase) { + if(!(ckt->CKTmode & (MODEDC|MODEINITPRED))) { + if(ckt->CKTmode & MODEUIC && ckt->CKTmode & MODEINITTRAN) { + *(ckt->CKTstate0 + here->VBICindFlux) = here->VBICindInduct; // no init current available + } else { + *(ckt->CKTstate0 + here->VBICindFlux) = here->VBICindInduct * *(ckt->CKTrhsOld + here->VBICbrEq); + } + } + } icheck=1; if(ckt->CKTmode & MODEINITSMSIG) { Vbe = model->VBICtype*( @@ -203,6 +243,8 @@ VBICload(GENmodel *inModel, CKTcircuit *ckt) *(ckt->CKTrhsOld+here->VBICsubsSINode)); if (here->VBIC_selfheat) Vrth = *(ckt->CKTstate0 + here->VBICvrth); + Rxf1xf2 = 0.0; + Vxf1xf2 = 0.0; } else if(ckt->CKTmode & MODEINITTRAN) { Vbe = model->VBICtype*( *(ckt->CKTrhsOld+here->VBICbaseNode)- @@ -233,6 +275,8 @@ VBICload(GENmodel *inModel, CKTcircuit *ckt) *(ckt->CKTrhsOld+here->VBICsubsSINode)); if (here->VBIC_selfheat) Vrth = *(ckt->CKTstate1 + here->VBICvrth); + Rxf1xf2 = 0.0; + Vxf1xf2 = 0.0; } else if((ckt->CKTmode & MODEINITJCT) && (ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC)){ Vbe=model->VBICtype*here->VBICicVBE; @@ -244,6 +288,9 @@ VBICload(GENmodel *inModel, CKTcircuit *ckt) Vrci=Vrbi=Vrbp=0.0; Vrcx=Vrbx=Vre=Vrs=0.0; Vrth = 0.0, Icth = 0.0, Icth_Vrth = 0.0; + Icxf=0.0, Icxf_Vcxf=0.0; + Rxf1xf2 = 0.0; + Vxf1xf2 = 0.0; } else if((ckt->CKTmode & MODEINITJCT) && (here->VBICoff==0)) { Vbe=Vbei=Vbex=model->VBICtype*here->VBICtVcrit; Vbc=Vbcx=Vbep=0.0; @@ -252,6 +299,9 @@ VBICload(GENmodel *inModel, CKTcircuit *ckt) Vrci=Vrbi=Vrbp=0.0; Vrcx=Vrbx=Vre=Vrs=0.0; Vrth = 0.0, Icth = 0.0, Icth_Vrth = 0.0; + Icxf=0.0, Icxf_Vcxf=0.0; + Rxf1xf2 = 0.0; + Vxf1xf2 = 0.0; } else if((ckt->CKTmode & MODEINITJCT) || ( (ckt->CKTmode & MODEINITFIX) && (here->VBICoff!=0))) { Vbe=0.0; @@ -262,6 +312,9 @@ VBICload(GENmodel *inModel, CKTcircuit *ckt) Vrci=Vrbi=Vrbp=0.0; Vrcx=Vrbx=Vre=Vrs=0.0; Vrth = 0.0, Icth = 0.0, Icth_Vrth = 0.0; + Icxf=0.0, Icxf_Vcxf=0.0; + Rxf1xf2 = 0.0; + Vxf1xf2 = 0.0; } else { #ifndef PREDICTOR if(ckt->CKTmode & MODEINITPRED) { @@ -316,16 +369,18 @@ VBICload(GENmodel *inModel, CKTcircuit *ckt) *(ckt->CKTstate1 + here->VBICibex); *(ckt->CKTstate0 + here->VBICibex_Vbex) = *(ckt->CKTstate1 + here->VBICibex_Vbex); - *(ckt->CKTstate0 + here->VBICitzf) = - *(ckt->CKTstate1 + here->VBICitzf); - *(ckt->CKTstate0 + here->VBICitzf_Vbei) = - *(ckt->CKTstate1 + here->VBICitzf_Vbei); - *(ckt->CKTstate0 + here->VBICitzf_Vbci) = - *(ckt->CKTstate1 + here->VBICitzf_Vbci); + if (!here->VBIC_excessPhase) { + *(ckt->CKTstate0 + here->VBICitzf) = + *(ckt->CKTstate1 + here->VBICitzf); + *(ckt->CKTstate0 + here->VBICitzf_Vbei) = + *(ckt->CKTstate1 + here->VBICitzf_Vbei); + *(ckt->CKTstate0 + here->VBICitzf_Vbci) = + *(ckt->CKTstate1 + here->VBICitzf_Vbci); + } *(ckt->CKTstate0 + here->VBICitzr) = *(ckt->CKTstate1 + here->VBICitzr); *(ckt->CKTstate0 + here->VBICitzr_Vbei) = - *(ckt->CKTstate1 + here->VBICitzf_Vbei); + *(ckt->CKTstate1 + here->VBICitzr_Vbei); *(ckt->CKTstate0 + here->VBICitzr_Vbci) = *(ckt->CKTstate1 + here->VBICitzr_Vbci); *(ckt->CKTstate0 + here->VBICibc) = @@ -389,6 +444,24 @@ VBICload(GENmodel *inModel, CKTcircuit *ckt) if (here->VBIC_selfheat) *(ckt->CKTstate0 + here->VBICqcth) = *(ckt->CKTstate1 + here->VBICqcth); + if (here->VBIC_excessPhase) { + *(ckt->CKTstate0+here->VBICqcxf)=*(ckt->CKTstate1+here->VBICqcxf); + *(ckt->CKTstate0+here->VBICcqcxf)=*(ckt->CKTstate1+here->VBICcqcxf); + *(ckt->CKTstate0+here->VBICgqcxf)=*(ckt->CKTstate1+here->VBICgqcxf); + *(ckt->CKTstate0+here->VBICibc_Vrxf)=*(ckt->CKTstate1+here->VBICibc_Vrxf); + *(ckt->CKTstate0+here->VBICixzf)=*(ckt->CKTstate1+here->VBICixzf); + *(ckt->CKTstate0+here->VBICixzf_Vbei)=*(ckt->CKTstate1+here->VBICixzf_Vbei); + *(ckt->CKTstate0+here->VBICixzf_Vbci)=*(ckt->CKTstate1+here->VBICixzf_Vbci); + *(ckt->CKTstate0+here->VBICixxf)=*(ckt->CKTstate1+here->VBICixxf); + *(ckt->CKTstate0+here->VBICixxf_Vrxf)=*(ckt->CKTstate1+here->VBICixxf_Vrxf); + *(ckt->CKTstate0+here->VBICitxf)=*(ckt->CKTstate1+here->VBICitxf); + *(ckt->CKTstate0+here->VBICitxf_Vrxf)=*(ckt->CKTstate1+here->VBICitxf_Vrxf); + if (here->VBIC_selfheat) { + *(ckt->CKTstate0+here->VBICixzf_Vrth)=*(ckt->CKTstate1+here->VBICixzf_Vrth); + *(ckt->CKTstate0+here->VBICith_Vrxf)=*(ckt->CKTstate1+here->VBICith_Vrxf); + } + *(ckt->CKTstate0+here->VBICindFlux)=*(ckt->CKTstate1+here->VBICindFlux); + } } else { #endif /* PREDICTOR */ /* @@ -423,6 +496,13 @@ VBICload(GENmodel *inModel, CKTcircuit *ckt) *(ckt->CKTrhsOld+here->VBICbaseBPNode)); if (here->VBIC_selfheat) Vrth = *(ckt->CKTrhsOld + here->VBICtempNode); + if (here->VBIC_excessPhase) { + Vrxf = *(ckt->CKTrhsOld + here->VBICxf2Node); + if (ckt->CKTmode & MODEINITTRAN) { + *(ckt->CKTstate1 + here->VBICindFlux) = + *(ckt->CKTstate0 + here->VBICindFlux); + } + } #ifndef PREDICTOR } #endif /* PREDICTOR */ @@ -456,13 +536,22 @@ VBICload(GENmodel *inModel, CKTcircuit *ckt) *(ckt->CKTrhsOld+here->VBICsubsSINode)); if (here->VBIC_selfheat) Vrth = *(ckt->CKTrhsOld + here->VBICtempNode); + if (here->VBIC_excessPhase) + Vrxf = *(ckt->CKTrhsOld + here->VBICxf2Node); ibehat = *(ckt->CKTstate0 + here->VBICibe) + *(ckt->CKTstate0 + here->VBICibe_Vbei)*delvbei; ibexhat = *(ckt->CKTstate0 + here->VBICibex) + *(ckt->CKTstate0 + here->VBICibex_Vbex)*delvbex; - itzfhat = *(ckt->CKTstate0 + here->VBICitzf) + - *(ckt->CKTstate0 + here->VBICitzf_Vbei)*delvbei + *(ckt->CKTstate0 + here->VBICitzf_Vbci)*delvbci; + if (!here->VBIC_excessPhase) { + itzfhat = *(ckt->CKTstate0 + here->VBICitzf) + + *(ckt->CKTstate0 + here->VBICitzf_Vbei)*delvbei + + *(ckt->CKTstate0 + here->VBICitzf_Vbci)*delvbci; + } else { + ixzfhat = *(ckt->CKTstate0 + here->VBICixzf) + + *(ckt->CKTstate0 + here->VBICixzf_Vbei)*delvbei + + *(ckt->CKTstate0 + here->VBICixzf_Vbci)*delvbci; + } itzrhat = *(ckt->CKTstate0 + here->VBICitzr) + *(ckt->CKTstate0 + here->VBICitzr_Vbei)*delvbei + *(ckt->CKTstate0 + here->VBICitzr_Vbci)*delvbci; ibchat = *(ckt->CKTstate0 + here->VBICibc) + @@ -523,10 +612,16 @@ VBICload(GENmodel *inModel, CKTcircuit *ckt) ckt->CKTreltol* MAX(fabs(ibexhat), fabs(*(ckt->CKTstate0 + here->VBICibex)))+ ckt->CKTabstol) ) - if( (fabs(itzfhat-*(ckt->CKTstate0 + here->VBICitzf)) < - ckt->CKTreltol* MAX(fabs(itzfhat), - fabs(*(ckt->CKTstate0 + here->VBICitzf)))+ - ckt->CKTabstol) ) + if (!here->VBIC_excessPhase) + if( (fabs(itzfhat-*(ckt->CKTstate0 + here->VBICitzf)) < + ckt->CKTreltol* MAX(fabs(itzfhat), + fabs(*(ckt->CKTstate0 + here->VBICitzf)))+ + ckt->CKTabstol) ) + if (here->VBIC_excessPhase) + if( (fabs(ixzfhat-*(ckt->CKTstate0 + here->VBICixzf)) < + ckt->CKTreltol* MAX(fabs(ixzfhat), + fabs(*(ckt->CKTstate0 + here->VBICixzf)))+ + ckt->CKTabstol) ) if( (fabs(itzrhat-*(ckt->CKTstate0 + here->VBICitzr)) < ckt->CKTreltol* MAX(fabs(itzrhat), fabs(*(ckt->CKTstate0 + here->VBICitzr)))+ @@ -575,15 +670,19 @@ VBICload(GENmodel *inModel, CKTcircuit *ckt) Ibe_Vbei = *(ckt->CKTstate0 + here->VBICibe_Vbei); Ibex = *(ckt->CKTstate0 + here->VBICibex); Ibex_Vbex = *(ckt->CKTstate0 + here->VBICibex_Vbex); - Itzf = *(ckt->CKTstate0 + here->VBICitzf); - Itzf_Vbei = *(ckt->CKTstate0 + here->VBICitzf_Vbei); - Itzf_Vbci = *(ckt->CKTstate0 + here->VBICitzf_Vbci); + if (!here->VBIC_excessPhase) { + Itzf = *(ckt->CKTstate0 + here->VBICitzf); + Itzf_Vbei = *(ckt->CKTstate0 + here->VBICitzf_Vbei); + Itzf_Vbci = *(ckt->CKTstate0 + here->VBICitzf_Vbci); + Itzf_Vrth = *(ckt->CKTstate0 + here->VBICitzf_Vrth); + } Itzr = *(ckt->CKTstate0 + here->VBICitzr); Itzr_Vbci = *(ckt->CKTstate0 + here->VBICitzr_Vbci); Itzr_Vbei = *(ckt->CKTstate0 + here->VBICitzr_Vbei); Ibc = *(ckt->CKTstate0 + here->VBICibc); Ibc_Vbci = *(ckt->CKTstate0 + here->VBICibc_Vbci); Ibc_Vbei = *(ckt->CKTstate0 + here->VBICibc_Vbei); + Ibc_Vrxf = *(ckt->CKTstate0 + here->VBICibc_Vrxf); Ibep = *(ckt->CKTstate0 + here->VBICibep); Ibep_Vbep = *(ckt->CKTstate0 + here->VBICibep_Vbep); Irci = *(ckt->CKTstate0 + here->VBICirci); @@ -610,6 +709,25 @@ VBICload(GENmodel *inModel, CKTcircuit *ckt) Irbx_Vrbx = *(ckt->CKTstate0 + here->VBICirbx_Vrbx); Irs_Vrs = *(ckt->CKTstate0 + here->VBICirs_Vrs); Ire_Vre = *(ckt->CKTstate0 + here->VBICire_Vre); + if (here->VBIC_excessPhase) { + Itxf = *(ckt->CKTstate0 + here->VBICitxf); + Itxf_Vrxf = *(ckt->CKTstate0 + here->VBICitxf_Vrxf); + Ixxf = *(ckt->CKTstate0 + here->VBICixxf); + Ixxf_Vrxf = *(ckt->CKTstate0 + here->VBICixxf_Vrxf); + Qcxf = *(ckt->CKTstate0 + here->VBICqcxf); + Icxf = *(ckt->CKTstate0 + here->VBICcqcxf); + Icxf_Vcxf = *(ckt->CKTstate0 + here->VBICgqcxf); + Ibc_Vrxf = *(ckt->CKTstate0 + here->VBICibc_Vrxf); + Ixzf = *(ckt->CKTstate0 + here->VBICixzf); + Ixzf_Vbei = *(ckt->CKTstate0 + here->VBICixzf_Vbei); + Ixzf_Vbci = *(ckt->CKTstate0 + here->VBICixzf_Vbci); + Ixzf_Vrth = *(ckt->CKTstate0 + here->VBICixzf_Vrth); + if (here->VBIC_selfheat) { + Ixzf_Vrth = *(ckt->CKTstate0 + here->VBICixzf_Vrth); + Ith_Vrxf = *(ckt->CKTstate0 + here->VBICith_Vrxf); + } + Flxf = *(ckt->CKTstate0 + here->VBICindFlux); + } goto load; } /* @@ -640,7 +758,20 @@ VBICload(GENmodel *inModel, CKTcircuit *ckt) */ Vcei = Vbei - Vbci; Vcep = Vbep - Vbcp; - if (here->VBIC_selfheat) { + if ((!here->VBIC_selfheat) && (!here->VBIC_excessPhase)) { + iret = vbic_4T_it_cf_fj(p + ,&Vbei, &Vbex, &Vbci, &Vbep, &Vbcp, &Vrcx + ,&Vbcx, &Vrci, &Vrbx, &Vrbi, &Vre, &Vrbp, &Vrs + ,&Vbe, &Vbc, &Ibe, &Ibe_Vbei, &Ibex, &Ibex_Vbex, &Itzf + ,&Itzf_Vbei, &Itzf_Vbci, &Itzr, &Itzr_Vbci, &Itzr_Vbei, &Ibc, &Ibc_Vbci + ,&Ibc_Vbei, &Ibep, &Ibep_Vbep, &Ircx, &Ircx_Vrcx, &Irci, &Irci_Vrci + ,&Irci_Vbci, &Irci_Vbcx, &Irbx, &Irbx_Vrbx, &Irbi, &Irbi_Vrbi, &Irbi_Vbei + ,&Irbi_Vbci, &Ire, &Ire_Vre, &Irbp, &Irbp_Vrbp, &Irbp_Vbep, &Irbp_Vbci + ,&Qbe, &Qbe_Vbei, &Qbe_Vbci, &Qbex, &Qbex_Vbex, &Qbc, &Qbc_Vbci + ,&Qbcx, &Qbcx_Vbcx, &Qbep, &Qbep_Vbep, &Qbep_Vbci, &Qbeo, &Qbeo_Vbe + ,&Qbco, &Qbco_Vbc, &Ibcp, &Ibcp_Vbcp, &Iccp, &Iccp_Vbep, &Iccp_Vbci + ,&Iccp_Vbcp, &Irs, &Irs_Vrs, &Qbcp, &Qbcp_Vbcp, &SCALE); + } else if ((here->VBIC_selfheat) && (!here->VBIC_excessPhase)) { iret = vbic_4T_et_cf_fj(p ,&Vrth, &Vbei, &Vbex, &Vbci, &Vbep, &Vbcp ,&Vrcx, &Vbcx, &Vrci, &Vrbx, &Vrbi, &Vre, &Vrbp @@ -661,18 +792,26 @@ VBICload(GENmodel *inModel, CKTcircuit *ckt) ,&Ith_Vrci, &Ith_Vbcx, &Ith_Vrbx, &Ith_Vrbi, &Ith_Vre, &Ith_Vrbp, &Qcth ,&Qcth_Vrth, &SCALE); } else { - iret = vbic_4T_it_cf_fj(p - ,&Vbei, &Vbex, &Vbci, &Vbep, &Vbcp, &Vrcx - ,&Vbcx, &Vrci, &Vrbx, &Vrbi, &Vre, &Vrbp, &Vrs - ,&Vbe, &Vbc, &Ibe, &Ibe_Vbei, &Ibex, &Ibex_Vbex, &Itzf - ,&Itzf_Vbei, &Itzf_Vbci, &Itzr, &Itzr_Vbci, &Itzr_Vbei, &Ibc, &Ibc_Vbci - ,&Ibc_Vbei, &Ibep, &Ibep_Vbep, &Ircx, &Ircx_Vrcx, &Irci, &Irci_Vrci - ,&Irci_Vbci, &Irci_Vbcx, &Irbx, &Irbx_Vrbx, &Irbi, &Irbi_Vrbi, &Irbi_Vbei - ,&Irbi_Vbci, &Ire, &Ire_Vre, &Irbp, &Irbp_Vrbp, &Irbp_Vbep, &Irbp_Vbci - ,&Qbe, &Qbe_Vbei, &Qbe_Vbci, &Qbex, &Qbex_Vbex, &Qbc, &Qbc_Vbci - ,&Qbcx, &Qbcx_Vbcx, &Qbep, &Qbep_Vbep, &Qbep_Vbci, &Qbeo, &Qbeo_Vbe - ,&Qbco, &Qbco_Vbc, &Ibcp, &Ibcp_Vbcp, &Iccp, &Iccp_Vbep, &Iccp_Vbci - ,&Iccp_Vbcp, &Irs, &Irs_Vrs, &Qbcp, &Qbcp_Vbcp, &SCALE); + iret = vbic_4T_et_xf_fj(p + ,&Vrth,&Vbei,&Vbex,&Vbci,&Vbep,&Vbcp + ,&Vrxf,&Vrcx,&Vbcx,&Vrci,&Vrbx,&Vrbi,&Vre + ,&Vrbp,&Vrs,&Vbe,&Vbc,&Vcei,&Vcep,&Vcxf + ,&Ibe,&Ibe_Vrth,&Ibe_Vbei,&Ibex,&Ibex_Vrth,&Ibex_Vbex,&Itxf + ,&Itxf_Vrxf,&Itzr,&Itzr_Vrth,&Itzr_Vbci,&Itzr_Vbei,&Ibc,&Ibc_Vrth + ,&Ibc_Vbci,&Ibc_Vrxf,&Ibc_Vbei,&Ibep,&Ibep_Vrth,&Ibep_Vbep,&Ircx + ,&Ircx_Vrcx,&Ircx_Vrth,&Irci,&Irci_Vrci,&Irci_Vrth,&Irci_Vbci,&Irci_Vbcx + ,&Irbx,&Irbx_Vrbx,&Irbx_Vrth,&Irbi,&Irbi_Vrbi,&Irbi_Vrth,&Irbi_Vbei + ,&Irbi_Vbci,&Ire,&Ire_Vre,&Ire_Vrth,&Irbp,&Irbp_Vrbp,&Irbp_Vrth + ,&Irbp_Vbep,&Irbp_Vbci,&Qbe,&Qbe_Vrth,&Qbe_Vbei,&Qbe_Vbci,&Qbex + ,&Qbex_Vrth,&Qbex_Vbex,&Qbc,&Qbc_Vrth,&Qbc_Vbci,&Qbcx,&Qbcx_Vrth + ,&Qbcx_Vbcx,&Qbep,&Qbep_Vrth,&Qbep_Vbep,&Qbep_Vbci,&Qbeo,&Qbeo_Vbe + ,&Qbco,&Qbco_Vbc,&Ibcp,&Ibcp_Vrth,&Ibcp_Vbcp,&Iccp,&Iccp_Vrth + ,&Iccp_Vbep,&Iccp_Vbci,&Iccp_Vbcp,&Irs,&Irs_Vrs,&Irs_Vrth,&Qbcp + ,&Qbcp_Vrth,&Qbcp_Vbcp,&Irth,&Irth_Vrth,&Ith,&Ith_Vrth,&Ith_Vbei + ,&Ith_Vbci,&Ith_Vrxf,&Ith_Vcei,&Ith_Vbex,&Ith_Vbep,&Ith_Vrs,&Ith_Vbcp + ,&Ith_Vcep,&Ith_Vrcx,&Ith_Vrci,&Ith_Vbcx,&Ith_Vrbx,&Ith_Vrbi,&Ith_Vre + ,&Ith_Vrbp,&Qcth,&Qcth_Vrth,&Ixzf,&Ixzf_Vrth,&Ixzf_Vbei,&Ixzf_Vbci + ,&Ixxf,&Ixxf_Vrxf,&Qcxf,&Qcxf_Vcxf,&Flxf,&Flxf_Vrxf,&SCALE); } Ibe += ckt->CKTgmin*Vbei; Ibe_Vbei += ckt->CKTgmin; @@ -706,8 +845,13 @@ VBICload(GENmodel *inModel, CKTcircuit *ckt) *(ckt->CKTstate0 + here->VBICqbeo) = Qbeo; *(ckt->CKTstate0 + here->VBICqbco) = Qbco; *(ckt->CKTstate0 + here->VBICqbcp) = Qbcp; - if (here->VBIC_selfheat) + if (here->VBIC_selfheat) { *(ckt->CKTstate0 + here->VBICqcth) = Qcth; + } + if (here->VBIC_excessPhase) { + *(ckt->CKTstate0 + here->VBICqcxf) = Qcxf; + *(ckt->CKTstate0 + here->VBICindFlux) = Flxf; + } here->VBICcapbe = Qbe_Vbei; here->VBICcapbex = Qbex_Vbex; @@ -716,7 +860,7 @@ VBICload(GENmodel *inModel, CKTcircuit *ckt) here->VBICcapbep = Qbep_Vbep; here->VBICcapbcp = Qbcp_Vbcp; if (here->VBIC_selfheat) - here->VBICcapcth = Qcth_Vrth; + here->VBICcapcth = Qcth_Vrth; /* * store small-signal parameters @@ -734,8 +878,18 @@ VBICload(GENmodel *inModel, CKTcircuit *ckt) *(ckt->CKTstate0 + here->VBICcqbeo) = Qbeo_Vbe; *(ckt->CKTstate0 + here->VBICcqbco) = Qbco_Vbc; *(ckt->CKTstate0 + here->VBICcqbcp) = Qbcp_Vbcp; - if (here->VBIC_selfheat) - *(ckt->CKTstate0 + here->VBICcqcth) = Qcth_Vrth; + if (here->VBIC_selfheat) { + here->VBICcapcth = Qcth_Vrth; + here->VBICcapqbeth = Qbe_Vrth; + here->VBICcapqbexth = Qbex_Vrth; + here->VBICcapqbcth = Qbc_Vrth; + here->VBICcapqbcxth = Qbcx_Vrth; + here->VBICcapqbepth = Qbep_Vrth; + here->VBICcapqbcpth = Qbcp_Vrth; + } + if (here->VBIC_excessPhase) { + here->VBICcapQcxf = Qcxf_Vcxf; + } continue; /* go to 1000 */ } /* @@ -762,6 +916,12 @@ VBICload(GENmodel *inModel, CKTcircuit *ckt) if (here->VBIC_selfheat) *(ckt->CKTstate1 + here->VBICqcth) = *(ckt->CKTstate0 + here->VBICqcth) ; + if (here->VBIC_excessPhase) { + *(ckt->CKTstate1 + here->VBICqcxf) = + *(ckt->CKTstate0 + here->VBICqcxf) ; + *(ckt->CKTstate1 + here->VBICindFlux) = + *(ckt->CKTstate0 + here->VBICindFlux); + } } error = NIintegrate(ckt,&geq,&ceq,Qbe_Vbei,here->VBICqbe); if(error) return(error); @@ -800,6 +960,18 @@ VBICload(GENmodel *inModel, CKTcircuit *ckt) Icth_Vrth = geq; Icth = *(ckt->CKTstate0 + here->VBICcqcth); } + if (here->VBIC_excessPhase) { + error = NIintegrate(ckt,&geq,&ceq,Qcxf_Vcxf,here->VBICqcxf); + if(error) return(error); + Icxf_Vcxf = geq; + Icxf = *(ckt->CKTstate0 + here->VBICcqcxf); + + newmind = here->VBICindInduct/here->VBICm; + error = NIintegrate(ckt,&req,&veq,newmind,here->VBICindFlux); + if(error) return(error); + Rxf1xf2 = req; + Vxf1xf2 = *(ckt->CKTstate0 + here->VBICindVolt); + } if(ckt->CKTmode & MODEINITTRAN) { *(ckt->CKTstate1 + here->VBICcqbe) = @@ -817,6 +989,12 @@ VBICload(GENmodel *inModel, CKTcircuit *ckt) if (here->VBIC_selfheat) *(ckt->CKTstate1 + here->VBICcqcth) = *(ckt->CKTstate0 + here->VBICcqcth); + if (here->VBIC_excessPhase) { + *(ckt->CKTstate1 + here->VBICcqcxf) = + *(ckt->CKTstate0 + here->VBICcqcxf); + *(ckt->CKTstate1 + here->VBICindVolt) = + *(ckt->CKTstate0 + here->VBICindVolt); + } } } } @@ -847,6 +1025,7 @@ VBICload(GENmodel *inModel, CKTcircuit *ckt) } } + *(ckt->CKTstate0 + here->VBICvrth) = Vrth; *(ckt->CKTstate0 + here->VBICvbei) = Vbei; *(ckt->CKTstate0 + here->VBICvbex) = Vbex; *(ckt->CKTstate0 + here->VBICvbci) = Vbci; @@ -861,9 +1040,12 @@ VBICload(GENmodel *inModel, CKTcircuit *ckt) *(ckt->CKTstate0 + here->VBICibe_Vbei) = Ibe_Vbei; *(ckt->CKTstate0 + here->VBICibex) = Ibex; *(ckt->CKTstate0 + here->VBICibex_Vbex) = Ibex_Vbex; - *(ckt->CKTstate0 + here->VBICitzf) = Itzf; - *(ckt->CKTstate0 + here->VBICitzf_Vbei) = Itzf_Vbei; - *(ckt->CKTstate0 + here->VBICitzf_Vbci) = Itzf_Vbci; + if (!here->VBIC_excessPhase) { + *(ckt->CKTstate0 + here->VBICitzf) = Itzf; + *(ckt->CKTstate0 + here->VBICitzf_Vbei) = Itzf_Vbei; + *(ckt->CKTstate0 + here->VBICitzf_Vbci) = Itzf_Vbci; + *(ckt->CKTstate0 + here->VBICitzf_Vrth) = Itzf_Vrth; + } *(ckt->CKTstate0 + here->VBICitzr) = Itzr; *(ckt->CKTstate0 + here->VBICitzr_Vbci) = Itzr_Vbci; *(ckt->CKTstate0 + here->VBICitzr_Vbei) = Itzr_Vbei; @@ -900,7 +1082,60 @@ VBICload(GENmodel *inModel, CKTcircuit *ckt) { *(ckt->CKTstate0 + here->VBICcqcth) = Icth; *(ckt->CKTstate0 + here->VBICicth_Vrth) = Icth_Vrth; + + here->VBICibe_Vrth = Ibe_Vrth; + here->VBICibex_Vrth = Ibex_Vrth; + here->VBICitzf_vrth = Itzf_Vrth; + here->VBICitzr_Vrth = Itzr_Vrth; + here->VBICibc_Vrth = Ibc_Vrth; + here->VBICibep_Vrth = Ibep_Vrth; + here->VBICircx_Vrth = Ircx_Vrth; + here->VBICirci_Vrth = Irci_Vrth; + here->VBICirbx_Vrth = Irbx_Vrth; + here->VBICirbi_Vrth = Irbi_Vrth; + here->VBICire_Vrth = Ire_Vrth; + here->VBICirbp_Vrth = Irbp_Vrth; + here->VBICibcp_Vrth = Ibcp_Vrth; + here->VBICiccp_Vrth = Iccp_Vrth; + here->VBICirs_Vrth = Irs_Vrth; + here->VBICirth_Vrth = Irth_Vrth; + here->VBICith_Vrth = Ith_Vrth; + here->VBICith_Vbei = Ith_Vbei; + here->VBICith_Vbci = Ith_Vbci; + here->VBICith_Vcei = Ith_Vcei; + here->VBICith_Vbex = Ith_Vbex; + here->VBICith_Vbep = Ith_Vbep; + here->VBICith_Vbcp = Ith_Vbcp; + here->VBICith_Vcep = Ith_Vcep; + here->VBICith_Vrci = Ith_Vrci; + here->VBICith_Vbcx = Ith_Vbcx; + here->VBICith_Vrbi = Ith_Vrbi; + here->VBICith_Vrbp = Ith_Vrbp; + here->VBICith_Vrcx = Ith_Vrcx; + here->VBICith_Vrbx = Ith_Vrbx; + here->VBICith_Vre = Ith_Vre; + here->VBICith_Vrs = Ith_Vrs; + } + if (here->VBIC_excessPhase) { + *(ckt->CKTstate0 + here->VBICitxf) = Itxf; + *(ckt->CKTstate0 + here->VBICitxf_Vrxf) = Itxf_Vrxf; + *(ckt->CKTstate0 + here->VBICixxf) = Ixxf; + *(ckt->CKTstate0 + here->VBICixxf_Vrxf) = Ixxf_Vrxf; + *(ckt->CKTstate0 + here->VBICqcxf) = Qcxf; + *(ckt->CKTstate0 + here->VBICcqcxf) = Icxf; + *(ckt->CKTstate0 + here->VBICgqcxf) = Icxf_Vcxf; + *(ckt->CKTstate0 + here->VBICibc_Vrxf) = Ibc_Vrxf; + *(ckt->CKTstate0 + here->VBICixzf) = Ixzf; + *(ckt->CKTstate0 + here->VBICixzf_Vbei) = Ixzf_Vbei; + *(ckt->CKTstate0 + here->VBICixzf_Vbci) = Ixzf_Vbci; + if (here->VBIC_selfheat) { + *(ckt->CKTstate0 + here->VBICixzf_Vrth) = Ixzf_Vrth; + *(ckt->CKTstate0 + here->VBICith_Vrxf) = Ith_Vrxf; + } + *(ckt->CKTstate0 + here->VBICindFlux) = Flxf; + } + load: /* * load current excitation vector and matrix @@ -940,6 +1175,7 @@ c Stamp element: Ibe *(ckt->CKTrhs + here->VBICemitEINode) += rhs_current; *(here->VBICemitEIBaseBIPtr) += -Ibe_Vbei; *(here->VBICemitEIEmitEIPtr) += Ibe_Vbei; + /* c Stamp element: Ibex */ @@ -951,34 +1187,46 @@ c Stamp element: Ibex *(here->VBICemitEIBaseBXPtr) += -Ibex_Vbex; *(here->VBICemitEIEmitEIPtr) += Ibex_Vbex; + if (!here->VBIC_excessPhase) { /* c Stamp element: Itzf */ - rhs_current = model->VBICtype * (Itzf - Itzf_Vbei*Vbei - Itzf_Vbci*Vbci); - *(ckt->CKTrhs + here->VBICcollCINode) += -rhs_current; - *(here->VBICcollCIBaseBIPtr) += Itzf_Vbei; - *(here->VBICcollCIEmitEIPtr) += -Itzf_Vbei; - *(here->VBICcollCIBaseBIPtr) += Itzf_Vbci; - *(here->VBICcollCICollCIPtr) += -Itzf_Vbci; - *(ckt->CKTrhs + here->VBICemitEINode) += rhs_current; - *(here->VBICemitEIBaseBIPtr) += -Itzf_Vbei; - *(here->VBICemitEIEmitEIPtr) += Itzf_Vbei; - *(here->VBICemitEIBaseBIPtr) += -Itzf_Vbci; - *(here->VBICemitEICollCIPtr) += Itzf_Vbci; + rhs_current = model->VBICtype * (Itzf - Itzf_Vbei*Vbei - Itzf_Vbci*Vbci); + *(ckt->CKTrhs + here->VBICcollCINode) += -rhs_current; + *(here->VBICcollCIBaseBIPtr) += Itzf_Vbei; + *(here->VBICcollCIEmitEIPtr) += -Itzf_Vbei; + *(here->VBICcollCIBaseBIPtr) += Itzf_Vbci; + *(here->VBICcollCICollCIPtr) += -Itzf_Vbci; + *(ckt->CKTrhs + here->VBICemitEINode) += rhs_current; + *(here->VBICemitEIBaseBIPtr) += -Itzf_Vbei; + *(here->VBICemitEIEmitEIPtr) += Itzf_Vbei; + *(here->VBICemitEIBaseBIPtr) += -Itzf_Vbci; + *(here->VBICemitEICollCIPtr) += Itzf_Vbci; + } + if (here->VBIC_excessPhase) { +/* +c Stamp element: Itxf +*/ + rhs_current = model->VBICtype * (Itxf - Itxf_Vrxf*Vrxf); + *(ckt->CKTrhs + here->VBICcollCINode) += -rhs_current; + *(ckt->CKTrhs + here->VBICemitEINode) += rhs_current; + *(here->VBICcollCIXf2Ptr) += Itxf_Vrxf; + *(here->VBICemitEIXf2Ptr) += -Itxf_Vrxf; + } /* c Stamp element: Itzr */ rhs_current = model->VBICtype * (Itzr - Itzr_Vbei*Vbei - Itzr_Vbci*Vbci); *(ckt->CKTrhs + here->VBICemitEINode) += -rhs_current; - *(here->VBICemitEIBaseBIPtr) += Itzr_Vbei; - *(here->VBICemitEIEmitEIPtr) += -Itzr_Vbei; *(here->VBICemitEIBaseBIPtr) += Itzr_Vbci; *(here->VBICemitEICollCIPtr) += -Itzr_Vbci; + *(here->VBICemitEIBaseBIPtr) += Itzr_Vbei; + *(here->VBICemitEIEmitEIPtr) += -Itzr_Vbei; *(ckt->CKTrhs + here->VBICcollCINode) += rhs_current; - *(here->VBICcollCIBaseBIPtr) += -Itzr_Vbei; - *(here->VBICcollCIEmitEIPtr) += Itzr_Vbei; *(here->VBICcollCIBaseBIPtr) += -Itzr_Vbci; *(here->VBICcollCICollCIPtr) += Itzr_Vbci; + *(here->VBICcollCIBaseBIPtr) += -Itzr_Vbei; + *(here->VBICcollCIEmitEIPtr) += Itzr_Vbei; /* c Stamp element: Ibc */ @@ -993,6 +1241,13 @@ c Stamp element: Ibc *(here->VBICcollCICollCIPtr) += Ibc_Vbci; *(here->VBICcollCIBaseBIPtr) += -Ibc_Vbei; *(here->VBICcollCIEmitEIPtr) += Ibc_Vbei; + if (here->VBIC_excessPhase) { + rhs_current = model->VBICtype * -Ibc_Vrxf*Vrxf; + *(ckt->CKTrhs + here->VBICbaseBINode) += -rhs_current; + *(ckt->CKTrhs + here->VBICcollCINode) += rhs_current; + *(here->VBICbaseBIXf2Ptr) += Ibc_Vrxf; + *(here->VBICcollCIXf2Ptr) += -Ibc_Vrxf; + } /* c Stamp element: Ibep */ @@ -1132,14 +1387,17 @@ c Stamp element: Ibex *(here->VBICbaseBXtempPtr) += Ibex_Vrth; *(ckt->CKTrhs + here->VBICemitEINode) += rhs_current; *(here->VBICemitEItempPtr) += -Ibex_Vrth; + + if (!here->VBIC_excessPhase) { /* c Stamp element: Itzf */ - rhs_current = -Itzf_Vrth*Vrth; - *(ckt->CKTrhs + here->VBICcollCINode) += -rhs_current; - *(here->VBICcollCItempPtr) += Itzf_Vrth; - *(ckt->CKTrhs + here->VBICemitEINode) += rhs_current; - *(here->VBICemitEItempPtr) += -Itzf_Vrth; + rhs_current = -Itzf_Vrth*Vrth; + *(ckt->CKTrhs + here->VBICcollCINode) += -rhs_current; + *(here->VBICcollCItempPtr) += Itzf_Vrth; + *(ckt->CKTrhs + here->VBICemitEINode) += rhs_current; + *(here->VBICemitEItempPtr) += -Itzf_Vrth; + } /* c Stamp element: Itzr */ @@ -1290,6 +1548,48 @@ c Stamp element: Ith *(here->VBICtempEmitEIPtr) += +Ith_Vre; *(here->VBICtempSubsPtr) += -Ith_Vrs; *(here->VBICtempSubsSIPtr) += +Ith_Vrs; + if (here->VBIC_excessPhase) { + rhs_current = -Ith_Vrxf*Vrxf; + *(ckt->CKTrhs + here->VBICtempNode) += -rhs_current; + *(here->VBICtempXf2Ptr) += +Ith_Vrxf; + } + } + if (here->VBIC_excessPhase) { +/* +c Stamp element: Ixzf, Branch: xf1-ground +*/ + rhs_current = Ixzf - Ixzf_Vbci*Vbci - Ixzf_Vbei*Vbei; + *(ckt->CKTrhs + here->VBICxf1Node) += -rhs_current; // into xf1 node + *(here->VBICxf1BaseBIPtr) += +Ixzf_Vbei; + *(here->VBICxf1EmitEIPtr) += -Ixzf_Vbei; + *(here->VBICxf1BaseBIPtr) += +Ixzf_Vbci; + *(here->VBICxf1CollCIPtr) += -Ixzf_Vbci; + if (here->VBIC_selfheat) { + rhs_current = -Ixzf_Vrth*Vrth; + *(ckt->CKTrhs + here->VBICxf1Node) += -rhs_current; + *(here->VBICxf1TempPtr) += Ixzf_Vrth; + } +/* +c Stamp element: Ixxf, Branch: xf2-ground +*/ + rhs_current = Ixxf - Ixxf_Vrxf*Vrxf; + *(ckt->CKTrhs + here->VBICxf2Node) += -rhs_current; // into xf2 node + *(here->VBICxf2Xf2Ptr) += +Ixxf_Vrxf; +/* +c Stamp element: Qcxf +*/ + rhs_current = Icxf - Icxf_Vcxf*Vcxf; + *(ckt->CKTrhs + here->VBICxf1Node) += -rhs_current; + *(here->VBICxf1Xf1Ptr) += Icxf_Vcxf; +/* +c Stamp element: L = TD/3 +*/ + *(ckt->CKTrhs+here->VBICbrEq) += Vxf1xf2; + *(here->VBICxf1IbrPtr) += 1; + *(here->VBICxf2IbrPtr) -= 1; + *(here->VBICibrXf1Ptr) += 1; + *(here->VBICibrXf2Ptr) -= 1; + *(here->VBICibrIbrPtr) -= Rxf1xf2; } } @@ -1297,6 +1597,1183 @@ c Stamp element: Ith return(OK); } +int vbic_4T_it_cf_fj(double *p + ,double *Vbei, double *Vbex, double *Vbci, double *Vbep, double *Vbcp, double *Vrcx + ,double *Vbcx, double *Vrci, double *Vrbx, double *Vrbi, double *Vre, double *Vrbp, double *Vrs + ,double *Vbe, double *Vbc, double *Ibe, double *Ibe_Vbei, double *Ibex, double *Ibex_Vbex, double *Itzf + ,double *Itzf_Vbei, double *Itzf_Vbci, double *Itzr, double *Itzr_Vbci, double *Itzr_Vbei, double *Ibc, double *Ibc_Vbci + ,double *Ibc_Vbei, double *Ibep, double *Ibep_Vbep, double *Ircx, double *Ircx_Vrcx, double *Irci, double *Irci_Vrci + ,double *Irci_Vbci, double *Irci_Vbcx, double *Irbx, double *Irbx_Vrbx, double *Irbi, double *Irbi_Vrbi, double *Irbi_Vbei + ,double *Irbi_Vbci, double *Ire, double *Ire_Vre, double *Irbp, double *Irbp_Vrbp, double *Irbp_Vbep, double *Irbp_Vbci + ,double *Qbe, double *Qbe_Vbei, double *Qbe_Vbci, double *Qbex, double *Qbex_Vbex, double *Qbc, double *Qbc_Vbci + ,double *Qbcx, double *Qbcx_Vbcx, double *Qbep, double *Qbep_Vbep, double *Qbep_Vbci, double *Qbeo, double *Qbeo_Vbe + ,double *Qbco, double *Qbco_Vbc, double *Ibcp, double *Ibcp_Vbcp, double *Iccp, double *Iccp_Vbep, double *Iccp_Vbci + ,double *Iccp_Vbcp, double *Irs, double *Irs_Vrs, double *Qbcp, double *Qbcp_Vbcp, double *SCALE) +{ +double Vtv,IVEF,IVER,IIKF,IIKR,IIKP,IVO; +double IHRCF,IVTF,IITF,slTF,dv0,dvh,dvh_Vbei; +double xvar1,xvar2,pwq,qlo,qlo_Vbei,qhi,qhi_dvh; +double qhi_Vbei,xvar1_Vbei,xvar3,xvar3_xvar1,xvar3_Vbei,qlo_xvar3,qdbe; +double qdbe_qlo,qdbe_Vbei,qdbe_qhi,mv0,vl0,q0,dv; +double dv_Vbei,mv,mv_dv,mv_Vbei,vl,vl_dv,vl_Vbei; +double vl_mv,xvar1_vl,qdbe_vl,dvh_Vbex,qlo_Vbex,qhi_Vbex,xvar1_Vbex; +double xvar3_Vbex,qdbex,qdbex_qlo,qdbex_Vbex,qdbex_qhi,dv_Vbex,mv_Vbex; +double vl_Vbex,qdbex_vl,dvh_Vbci,qlo_Vbci,qhi_Vbci,xvar1_Vbci,xvar3_Vbci; +double qdbc,qdbc_qlo,qdbc_Vbci,qdbc_qhi,vn0,vnl0,qlo0; +double vn,vn_Vbci,vnl,vnl_vn,vnl_Vbci,vl_vnl,vl_Vbci; +double sel,sel_vnl,sel_Vbci,crt,cmx,cl,cl_sel; +double cl_Vbci,ql,ql_Vbci,ql_vl,ql_cl,qdbc_ql,dv_Vbci; +double mv_Vbci,qdbc_vl,dvh_Vbep,qlo_Vbep,qhi_Vbep,xvar1_Vbep,xvar3_Vbep; +double qdbep,qdbep_qlo,qdbep_Vbep,qdbep_qhi,vn_Vbep,vnl_Vbep,vl_Vbep; +double sel_Vbep,cl_Vbep,ql_Vbep,qdbep_ql,dv_Vbep,mv_Vbep,qdbep_vl; +double dvh_Vbcp,qlo_Vbcp,qhi_Vbcp,xvar1_Vbcp,xvar3_Vbcp,qdbcp,qdbcp_qlo; +double qdbcp_Vbcp,qdbcp_Vbep,qdbcp_qhi,dv_Vbcp,mv_Vbcp,vl_Vbcp,qdbcp_vl; +double argi,argi_Vbei,expi,expi_argi,expi_Vbei,Ifi,Ifi_expi; +double Ifi_Vbei,argi_Vbci,expi_Vbci,Iri,Iri_expi,Iri_Vbci,q1z; +double q1z_qdbe,q1z_Vbei,q1z_qdbc,q1z_Vbci,q1,q1_q1z,q1_Vbei; +double q1_Vbci,q2,q2_Ifi,q2_Vbei,q2_Iri,q2_Vbci,xvar3_q1; +double xvar1_xvar3,xvar1_q2,xvar4,xvar4_xvar1,xvar4_Vbei,xvar4_Vbci,qb; +double qb_q1,qb_Vbei,qb_Vbci,qb_xvar4,xvar2_xvar1,xvar2_Vbei,xvar2_Vbci; +double qb_xvar2,Itzr_Iri,Itzr_qb,Itzf_Ifi,Itzf_qb,argi_Vbep,expi_Vbep; +double argx,argx_Vbci,expx,expx_argx,expx_Vbci,Ifp,Ifp_expi; +double Ifp_Vbep,Ifp_expx,Ifp_Vbci,q2p,q2p_Ifp,q2p_Vbep,q2p_Vbci; +double qbp,qbp_q2p,qbp_Vbep,qbp_Vbci,argi_Vbcp,expi_Vbcp,Irp; +double Irp_expi,Irp_Vbcp,Iccp_Ifp,Iccp_Irp,Iccp_qbp,argn,argn_Vbei; +double expn,expn_argn,expn_Vbei,argx_Vbei,expx_Vbei,Ibe_expi,Ibe_expn; +double Ibe_expx,argi_Vbex,expi_Vbex,argn_Vbex,expn_Vbex,argx_Vbex,expx_Vbex; +double Ibex_expi,Ibex_expn,Ibex_expx,argn_Vbci,expn_Vbci,Ibcj,Ibcj_expi; +double Ibcj_Vbci,Ibcj_expn,argn_Vbep,expn_Vbep,Ibep_expi,Ibep_expn,xvar3_vl; +double avalf,avalf_vl,avalf_Vbci,avalf_xvar4,Igc,Igc_Itzf,Igc_Vbei; +double Igc_Vbci,Igc_Itzr,Igc_Ibcj,Igc_avalf,Ibc_Ibcj,Ibc_Igc,argx_Vbcx; +double expx_Vbcx,Kbci,Kbci_expi,Kbci_Vbci,Kbcx,Kbcx_expx,Kbcx_Vbcx; +double rKp1,rKp1_Kbci,rKp1_Vbci,rKp1_Kbcx,rKp1_Vbcx,xvar1_rKp1,xvar1_Vbcx; +double Iohm,Iohm_Vrci,Iohm_Kbci,Iohm_Vbci,Iohm_Kbcx,Iohm_Vbcx,Iohm_xvar1; +double derf,derf_Iohm,derf_Vrci,derf_Vbci,derf_Vbcx,Irci_Iohm,Irci_derf; +double Irbi_qb,Irbp_qbp,argn_Vbcp,expn_Vbcp,Ibcp_expi,Ibcp_expn,sgIf; +double rIf,rIf_Ifi,rIf_Vbei,mIf,mIf_rIf,mIf_Vbei,tff; +double tff_q1,tff_Vbei,tff_Vbci,tff_xvar2,tff_mIf,Qbe_qdbe,Qbe_tff; +double Qbe_Ifi,Qbe_qb,Qbex_qdbex,Qbc_qdbc,Qbc_Iri,Qbc_Kbci,Qbcx_Kbcx; +double Qbep_qdbep,Qbep_Ifp,Qbcp_qdbcp; + +/* Function and derivative code */ + + Vtv=1.380662e-23*(2.731500e+02+p[0])/1.602189e-19; + if(p[51]>0.0){ + IVEF=1.0/p[51]; + }else{ + IVEF=0.0; + } + if(p[52]>0.0){ + IVER=1.0/p[52]; + }else{ + IVER=0.0; + } + if(p[53]>0.0){ + IIKF=1.0/p[53]; + }else{ + IIKF=0.0; + } + if(p[54]>0.0){ + IIKR=1.0/p[54]; + }else{ + IIKR=0.0; + } + if(p[55]>0.0){ + IIKP=1.0/p[55]; + }else{ + IIKP=0.0; + } + if(p[3]>0.0){ + IVO=1.0/p[3]; + }else{ + IVO=0.0; + } + if(p[5]>0.0){ + IHRCF=1.0/p[5]; + }else{ + IHRCF=0.0; + } + if(p[59]>0.0){ + IVTF=1.0/p[59]; + }else{ + IVTF=0.0; + } + if(p[60]>0.0){ + IITF=1.0/p[60]; + }else{ + IITF=0.0; + } + if(p[60]>0.0){ + slTF=0.0; + }else{ + slTF=1.0; + } + dv0=-p[17]*p[14]; + if(p[19]<=0.0){ + dvh=(*Vbei)+dv0; + dvh_Vbei=1.0; + if(dvh>0.0){ + xvar1=(1.0-p[14]); + xvar2=(-1.0-p[18]); + pwq=pow(xvar1,xvar2); + qlo=p[17]*(1.0-pwq*(1.0-p[14])*(1.0-p[14]))/(1.0-p[18]); + qlo_Vbei=0.0; + qhi=dvh*(1.0-p[14]+0.5*p[18]*dvh/p[17])*pwq; + qhi_dvh=(0.5*dvh*p[18]/p[17]-p[14]+1.0)*pwq+0.5*dvh*p[18]*pwq/p[17]; + qhi_Vbei=qhi_dvh*dvh_Vbei; + }else{ + xvar1=(1.0-(*Vbei)/p[17]); + xvar1_Vbei=-1.0/p[17]; + xvar2=(1.0-p[18]); + xvar3=pow(xvar1,xvar2); + xvar3_xvar1=xvar3*xvar2/xvar1; + xvar3_Vbei=xvar3_xvar1*xvar1_Vbei; + qlo=p[17]*(1.0-xvar3)/(1.0-p[18]); + qlo_xvar3=-p[17]/(1.0-p[18]); + qlo_Vbei=qlo_xvar3*xvar3_Vbei; + qhi=0.0; + qhi_Vbei=0.0; + } + qdbe=qlo+qhi; + qdbe_qlo=1.0; + qdbe_qhi=1.0; + qdbe_Vbei=qdbe_qlo*qlo_Vbei; + qdbe_Vbei=qdbe_Vbei+qdbe_qhi*qhi_Vbei; + }else{ + mv0=sqrt(dv0*dv0+4.0*p[19]*p[19]); + vl0=-0.5*(dv0+mv0); + xvar1=(1.0-vl0/p[17]); + xvar2=(1.0-p[18]); + xvar3=pow(xvar1,xvar2); + q0=-p[17]*xvar3/(1.0-p[18]); + dv=(*Vbei)+dv0; + dv_Vbei=1.0; + mv=sqrt(dv*dv+4.0*p[19]*p[19]); + mv_dv=dv/sqrt((dv*dv)+4.0*(p[19]*p[19])); + mv_Vbei=mv_dv*dv_Vbei; + vl=0.5*(dv-mv)-dv0; + vl_dv=0.5; + vl_mv=-0.5; + vl_Vbei=vl_dv*dv_Vbei; + vl_Vbei=vl_Vbei+vl_mv*mv_Vbei; + xvar1=(1.0-vl/p[17]); + xvar1_vl=-1.0/p[17]; + xvar1_Vbei=xvar1_vl*vl_Vbei; + xvar2=(1.0-p[18]); + xvar3=pow(xvar1,xvar2); + xvar3_xvar1=xvar3*xvar2/xvar1; + xvar3_Vbei=xvar3_xvar1*xvar1_Vbei; + qlo=-p[17]*xvar3/(1.0-p[18]); + qlo_xvar3=-p[17]/(1.0-p[18]); + qlo_Vbei=qlo_xvar3*xvar3_Vbei; + xvar1=(1.0-p[14]); + xvar2=(-p[18]); + xvar3=pow(xvar1,xvar2); + qdbe=qlo+xvar3*((*Vbei)-vl+vl0)-q0; + qdbe_qlo=1.0; + qdbe_Vbei=xvar3; + qdbe_vl=-xvar3; + qdbe_Vbei=qdbe_Vbei+qdbe_qlo*qlo_Vbei; + qdbe_Vbei=qdbe_Vbei+qdbe_vl*vl_Vbei; + } + dv0=-p[17]*p[14]; + if(p[19]<=0.0){ + dvh=(*Vbex)+dv0; + dvh_Vbex=1.0; + if(dvh>0.0){ + xvar1=(1.0-p[14]); + xvar2=(-1.0-p[18]); + pwq=pow(xvar1,xvar2); + qlo=p[17]*(1.0-pwq*(1.0-p[14])*(1.0-p[14]))/(1.0-p[18]); + qlo_Vbex=0.0; + qhi=dvh*(1.0-p[14]+0.5*p[18]*dvh/p[17])*pwq; + qhi_dvh=(0.5*dvh*p[18]/p[17]-p[14]+1.0)*pwq+0.5*dvh*p[18]*pwq/p[17]; + qhi_Vbex=qhi_dvh*dvh_Vbex; + }else{ + xvar1=(1.0-(*Vbex)/p[17]); + xvar1_Vbex=-1.0/p[17]; + xvar2=(1.0-p[18]); + xvar3=pow(xvar1,xvar2); + xvar3_xvar1=xvar3*xvar2/xvar1; + xvar3_Vbex=xvar3_xvar1*xvar1_Vbex; + qlo=p[17]*(1.0-xvar3)/(1.0-p[18]); + qlo_xvar3=-p[17]/(1.0-p[18]); + qlo_Vbex=qlo_xvar3*xvar3_Vbex; + qhi=0.0; + qhi_Vbex=0.0; + } + qdbex=qlo+qhi; + qdbex_qlo=1.0; + qdbex_qhi=1.0; + qdbex_Vbex=qdbex_qlo*qlo_Vbex; + qdbex_Vbex=qdbex_Vbex+qdbex_qhi*qhi_Vbex; + }else{ + mv0=sqrt(dv0*dv0+4.0*p[19]*p[19]); + vl0=-0.5*(dv0+mv0); + xvar1=(1.0-vl0/p[17]); + xvar2=(1.0-p[18]); + xvar3=pow(xvar1,xvar2); + q0=-p[17]*xvar3/(1.0-p[18]); + dv=(*Vbex)+dv0; + dv_Vbex=1.0; + mv=sqrt(dv*dv+4.0*p[19]*p[19]); + mv_dv=dv/sqrt((dv*dv)+4.0*(p[19]*p[19])); + mv_Vbex=mv_dv*dv_Vbex; + vl=0.5*(dv-mv)-dv0; + vl_dv=0.5; + vl_mv=-0.5; + vl_Vbex=vl_dv*dv_Vbex; + vl_Vbex=vl_Vbex+vl_mv*mv_Vbex; + xvar1=(1.0-vl/p[17]); + xvar1_vl=-1.0/p[17]; + xvar1_Vbex=xvar1_vl*vl_Vbex; + xvar2=(1.0-p[18]); + xvar3=pow(xvar1,xvar2); + xvar3_xvar1=xvar3*xvar2/xvar1; + xvar3_Vbex=xvar3_xvar1*xvar1_Vbex; + qlo=-p[17]*xvar3/(1.0-p[18]); + qlo_xvar3=-p[17]/(1.0-p[18]); + qlo_Vbex=qlo_xvar3*xvar3_Vbex; + xvar1=(1.0-p[14]); + xvar2=(-p[18]); + xvar3=pow(xvar1,xvar2); + qdbex=qlo+xvar3*((*Vbex)-vl+vl0)-q0; + qdbex_qlo=1.0; + qdbex_Vbex=xvar3; + qdbex_vl=-xvar3; + qdbex_Vbex=qdbex_Vbex+qdbex_qlo*qlo_Vbex; + qdbex_Vbex=qdbex_Vbex+qdbex_vl*vl_Vbex; + } + dv0=-p[24]*p[14]; + if(p[26]<=0.0){ + dvh=(*Vbci)+dv0; + dvh_Vbci=1.0; + if(dvh>0.0){ + xvar1=(1.0-p[14]); + xvar2=(-1.0-p[25]); + pwq=pow(xvar1,xvar2); + qlo=p[24]*(1.0-pwq*(1.0-p[14])*(1.0-p[14]))/(1.0-p[25]); + qlo_Vbci=0.0; + qhi=dvh*(1.0-p[14]+0.5*p[25]*dvh/p[24])*pwq; + qhi_dvh=(0.5*dvh*p[25]/p[24]-p[14]+1.0)*pwq+0.5*dvh*p[25]*pwq/p[24]; + qhi_Vbci=qhi_dvh*dvh_Vbci; + }else{ + if((p[85]>0.0)&&((*Vbci)<-p[85])){ + xvar1=(1.0+p[85]/p[24]); + xvar2=(1.0-p[25]); + xvar3=pow(xvar1,xvar2); + qlo=p[24]*(1.0-xvar3*(1.0-((1.0-p[25])*((*Vbci)+p[85]))/(p[24]+p[85])))/(1.0-p[25]); + qlo_Vbci=p[24]*xvar3/(p[85]+p[24]); + }else{ + xvar1=(1.0-(*Vbci)/p[24]); + xvar1_Vbci=-1.0/p[24]; + xvar2=(1.0-p[25]); + xvar3=pow(xvar1,xvar2); + xvar3_xvar1=xvar3*xvar2/xvar1; + xvar3_Vbci=xvar3_xvar1*xvar1_Vbci; + qlo=p[24]*(1.0-xvar3)/(1.0-p[25]); + qlo_xvar3=-p[24]/(1.0-p[25]); + qlo_Vbci=qlo_xvar3*xvar3_Vbci; + } + qhi=0.0; + qhi_Vbci=0.0; + } + qdbc=qlo+qhi; + qdbc_qlo=1.0; + qdbc_qhi=1.0; + qdbc_Vbci=qdbc_qlo*qlo_Vbci; + qdbc_Vbci=qdbc_Vbci+qdbc_qhi*qhi_Vbci; + }else{ + if((p[85]>0.0)&&(p[86]>0.0)){ + vn0=(p[85]+dv0)/(p[85]-dv0); + vnl0=2.0*vn0/(sqrt((vn0-1.0)*(vn0-1.0)+4.0*p[26]*p[26])+sqrt((vn0+1.0)*(vn0+1.0)+4.0*p[86]*p[86])); + vl0=0.5*(vnl0*(p[85]-dv0)-p[85]-dv0); + xvar1=(1.0-vl0/p[24]); + xvar2=(1.0-p[25]); + xvar3=pow(xvar1,xvar2); + qlo0=p[24]*(1.0-xvar3)/(1.0-p[25]); + vn=(2.0*(*Vbci)+p[85]+dv0)/(p[85]-dv0); + vn_Vbci=2.0/(p[85]-dv0); + vnl=2.0*vn/(sqrt((vn-1.0)*(vn-1.0)+4.0*p[26]*p[26])+sqrt((vn+1.0)*(vn+1.0)+4.0*p[86]*p[86])); + vnl_vn=2.0/(sqrt(((vn+1.0)*(vn+1.0))+4.0*(p[86]*p[86]))+sqrt(((vn-1.0)*(vn-1.0))+4.0*(p[26]*p[26])))-2.0*vn*((vn+1.0)/sqrt(((vn+1.0)*(vn+1.0))+4.0*(p[86]*p[86]))+(vn-1.0)/sqrt(((vn-1.0)*(vn-1.0))+4.0*(p[26]*p[26])))/((sqrt(((vn+1.0)*(vn+1.0))+4.0*(p[86]*p[86]))+sqrt(((vn-1.0)*(vn-1.0))+4.0*(p[26]*p[26])))*(sqrt(((vn+1.0)*(vn+1.0))+4.0*(p[86]*p[86]))+sqrt(((vn-1.0)*(vn-1.0))+4.0*(p[26]*p[26])))); + vnl_Vbci=vnl_vn*vn_Vbci; + vl=0.5*(vnl*(p[85]-dv0)-p[85]-dv0); + vl_vnl=0.5*(p[85]-dv0); + vl_Vbci=vl_vnl*vnl_Vbci; + xvar1=(1.0-vl/p[24]); + xvar1_vl=-1.0/p[24]; + xvar1_Vbci=xvar1_vl*vl_Vbci; + xvar2=(1.0-p[25]); + xvar3=pow(xvar1,xvar2); + xvar3_xvar1=xvar3*xvar2/xvar1; + xvar3_Vbci=xvar3_xvar1*xvar1_Vbci; + qlo=p[24]*(1.0-xvar3)/(1.0-p[25]); + qlo_xvar3=-p[24]/(1.0-p[25]); + qlo_Vbci=qlo_xvar3*xvar3_Vbci; + sel=0.5*(vnl+1.0); + sel_vnl=0.5; + sel_Vbci=sel_vnl*vnl_Vbci; + xvar1=(1.0+p[85]/p[24]); + xvar2=(-p[25]); + crt=pow(xvar1,xvar2); + xvar1=(1.0+dv0/p[24]); + xvar2=(-p[25]); + cmx=pow(xvar1,xvar2); + cl=(1.0-sel)*crt+sel*cmx; + cl_sel=cmx-crt; + cl_Vbci=cl_sel*sel_Vbci; + ql=((*Vbci)-vl+vl0)*cl; + ql_Vbci=cl; + ql_vl=-cl; + ql_cl=vl0-vl+(*Vbci); + ql_Vbci=ql_Vbci+ql_vl*vl_Vbci; + ql_Vbci=ql_Vbci+ql_cl*cl_Vbci; + qdbc=ql+qlo-qlo0; + qdbc_ql=1.0; + qdbc_qlo=1.0; + qdbc_Vbci=qdbc_ql*ql_Vbci; + qdbc_Vbci=qdbc_Vbci+qdbc_qlo*qlo_Vbci; + }else{ + mv0=sqrt(dv0*dv0+4.0*p[26]*p[26]); + vl0=-0.5*(dv0+mv0); + xvar1=(1.0-vl0/p[24]); + xvar2=(1.0-p[25]); + xvar3=pow(xvar1,xvar2); + q0=-p[24]*xvar3/(1.0-p[25]); + dv=(*Vbci)+dv0; + dv_Vbci=1.0; + mv=sqrt(dv*dv+4.0*p[26]*p[26]); + mv_dv=dv/sqrt((dv*dv)+4.0*(p[26]*p[26])); + mv_Vbci=mv_dv*dv_Vbci; + vl=0.5*(dv-mv)-dv0; + vl_dv=0.5; + vl_mv=-0.5; + vl_Vbci=vl_dv*dv_Vbci; + vl_Vbci=vl_Vbci+vl_mv*mv_Vbci; + xvar1=(1.0-vl/p[24]); + xvar1_vl=-1.0/p[24]; + xvar1_Vbci=xvar1_vl*vl_Vbci; + xvar2=(1.0-p[25]); + xvar3=pow(xvar1,xvar2); + xvar3_xvar1=xvar3*xvar2/xvar1; + xvar3_Vbci=xvar3_xvar1*xvar1_Vbci; + qlo=-p[24]*xvar3/(1.0-p[25]); + qlo_xvar3=-p[24]/(1.0-p[25]); + qlo_Vbci=qlo_xvar3*xvar3_Vbci; + xvar1=(1.0-p[14]); + xvar2=(-p[25]); + xvar3=pow(xvar1,xvar2); + qdbc=qlo+xvar3*((*Vbci)-vl+vl0)-q0; + qdbc_qlo=1.0; + qdbc_Vbci=xvar3; + qdbc_vl=-xvar3; + qdbc_Vbci=qdbc_Vbci+qdbc_qlo*qlo_Vbci; + qdbc_Vbci=qdbc_Vbci+qdbc_vl*vl_Vbci; + } + } + dv0=-p[24]*p[14]; + if(p[26]<=0.0){ + dvh=(*Vbep)+dv0; + dvh_Vbep=1.0; + if(dvh>0.0){ + xvar1=(1.0-p[14]); + xvar2=(-1.0-p[25]); + pwq=pow(xvar1,xvar2); + qlo=p[24]*(1.0-pwq*(1.0-p[14])*(1.0-p[14]))/(1.0-p[25]); + qlo_Vbep=0.0; + qhi=dvh*(1.0-p[14]+0.5*p[25]*dvh/p[24])*pwq; + qhi_dvh=(0.5*dvh*p[25]/p[24]-p[14]+1.0)*pwq+0.5*dvh*p[25]*pwq/p[24]; + qhi_Vbep=qhi_dvh*dvh_Vbep; + }else{ + if((p[85]>0.0)&&((*Vbep)<-p[85])){ + xvar1=(1.0+p[85]/p[24]); + xvar2=(1.0-p[25]); + xvar3=pow(xvar1,xvar2); + qlo=p[24]*(1.0-xvar3*(1.0-((1.0-p[25])*((*Vbep)+p[85]))/(p[24]+p[85])))/(1.0-p[25]); + qlo_Vbep=p[24]*xvar3/(p[85]+p[24]); + }else{ + xvar1=(1.0-(*Vbep)/p[24]); + xvar1_Vbep=-1.0/p[24]; + xvar2=(1.0-p[25]); + xvar3=pow(xvar1,xvar2); + xvar3_xvar1=xvar3*xvar2/xvar1; + xvar3_Vbep=xvar3_xvar1*xvar1_Vbep; + qlo=p[24]*(1.0-xvar3)/(1.0-p[25]); + qlo_xvar3=-p[24]/(1.0-p[25]); + qlo_Vbep=qlo_xvar3*xvar3_Vbep; + } + qhi=0.0; + qhi_Vbep=0.0; + } + qdbep=qlo+qhi; + qdbep_qlo=1.0; + qdbep_qhi=1.0; + qdbep_Vbep=qdbep_qlo*qlo_Vbep; + qdbep_Vbep=qdbep_Vbep+qdbep_qhi*qhi_Vbep; + }else{ + if((p[85]>0.0)&&(p[86]>0.0)){ + vn0=(p[85]+dv0)/(p[85]-dv0); + vnl0=2.0*vn0/(sqrt((vn0-1.0)*(vn0-1.0)+4.0*p[26]*p[26])+sqrt((vn0+1.0)*(vn0+1.0)+4.0*p[86]*p[86])); + vl0=0.5*(vnl0*(p[85]-dv0)-p[85]-dv0); + xvar1=(1.0-vl0/p[24]); + xvar2=(1.0-p[25]); + xvar3=pow(xvar1,xvar2); + qlo0=p[24]*(1.0-xvar3)/(1.0-p[25]); + vn=(2.0*(*Vbep)+p[85]+dv0)/(p[85]-dv0); + vn_Vbep=2.0/(p[85]-dv0); + vnl=2.0*vn/(sqrt((vn-1.0)*(vn-1.0)+4.0*p[26]*p[26])+sqrt((vn+1.0)*(vn+1.0)+4.0*p[86]*p[86])); + vnl_vn=2.0/(sqrt(((vn+1.0)*(vn+1.0))+4.0*(p[86]*p[86]))+sqrt(((vn-1.0)*(vn-1.0))+4.0*(p[26]*p[26])))-2.0*vn*((vn+1.0)/sqrt(((vn+1.0)*(vn+1.0))+4.0*(p[86]*p[86]))+(vn-1.0)/sqrt(((vn-1.0)*(vn-1.0))+4.0*(p[26]*p[26])))/((sqrt(((vn+1.0)*(vn+1.0))+4.0*(p[86]*p[86]))+sqrt(((vn-1.0)*(vn-1.0))+4.0*(p[26]*p[26])))*(sqrt(((vn+1.0)*(vn+1.0))+4.0*(p[86]*p[86]))+sqrt(((vn-1.0)*(vn-1.0))+4.0*(p[26]*p[26])))); + vnl_Vbep=vnl_vn*vn_Vbep; + vl=0.5*(vnl*(p[85]-dv0)-p[85]-dv0); + vl_vnl=0.5*(p[85]-dv0); + vl_Vbep=vl_vnl*vnl_Vbep; + xvar1=(1.0-vl/p[24]); + xvar1_vl=-1.0/p[24]; + xvar1_Vbep=xvar1_vl*vl_Vbep; + xvar2=(1.0-p[25]); + xvar3=pow(xvar1,xvar2); + xvar3_xvar1=xvar3*xvar2/xvar1; + xvar3_Vbep=xvar3_xvar1*xvar1_Vbep; + qlo=p[24]*(1.0-xvar3)/(1.0-p[25]); + qlo_xvar3=-p[24]/(1.0-p[25]); + qlo_Vbep=qlo_xvar3*xvar3_Vbep; + sel=0.5*(vnl+1.0); + sel_vnl=0.5; + sel_Vbep=sel_vnl*vnl_Vbep; + xvar1=(1.0+p[85]/p[24]); + xvar2=(-p[25]); + crt=pow(xvar1,xvar2); + xvar1=(1.0+dv0/p[24]); + xvar2=(-p[25]); + cmx=pow(xvar1,xvar2); + cl=(1.0-sel)*crt+sel*cmx; + cl_sel=cmx-crt; + cl_Vbep=cl_sel*sel_Vbep; + ql=((*Vbep)-vl+vl0)*cl; + ql_Vbep=cl; + ql_vl=-cl; + ql_cl=vl0-vl+(*Vbep); + ql_Vbep=ql_Vbep+ql_vl*vl_Vbep; + ql_Vbep=ql_Vbep+ql_cl*cl_Vbep; + qdbep=ql+qlo-qlo0; + qdbep_ql=1.0; + qdbep_qlo=1.0; + qdbep_Vbep=qdbep_ql*ql_Vbep; + qdbep_Vbep=qdbep_Vbep+qdbep_qlo*qlo_Vbep; + }else{ + mv0=sqrt(dv0*dv0+4.0*p[26]*p[26]); + vl0=-0.5*(dv0+mv0); + xvar1=(1.0-vl0/p[24]); + xvar2=(1.0-p[25]); + xvar3=pow(xvar1,xvar2); + q0=-p[24]*xvar3/(1.0-p[25]); + dv=(*Vbep)+dv0; + dv_Vbep=1.0; + mv=sqrt(dv*dv+4.0*p[26]*p[26]); + mv_dv=dv/sqrt((dv*dv)+4.0*(p[26]*p[26])); + mv_Vbep=mv_dv*dv_Vbep; + vl=0.5*(dv-mv)-dv0; + vl_dv=0.5; + vl_mv=-0.5; + vl_Vbep=vl_dv*dv_Vbep; + vl_Vbep=vl_Vbep+vl_mv*mv_Vbep; + xvar1=(1.0-vl/p[24]); + xvar1_vl=-1.0/p[24]; + xvar1_Vbep=xvar1_vl*vl_Vbep; + xvar2=(1.0-p[25]); + xvar3=pow(xvar1,xvar2); + xvar3_xvar1=xvar3*xvar2/xvar1; + xvar3_Vbep=xvar3_xvar1*xvar1_Vbep; + qlo=-p[24]*xvar3/(1.0-p[25]); + qlo_xvar3=-p[24]/(1.0-p[25]); + qlo_Vbep=qlo_xvar3*xvar3_Vbep; + xvar1=(1.0-p[14]); + xvar2=(-p[25]); + xvar3=pow(xvar1,xvar2); + qdbep=qlo+xvar3*((*Vbep)-vl+vl0)-q0; + qdbep_qlo=1.0; + qdbep_Vbep=xvar3; + qdbep_vl=-xvar3; + qdbep_Vbep=qdbep_Vbep+qdbep_qlo*qlo_Vbep; + qdbep_Vbep=qdbep_Vbep+qdbep_vl*vl_Vbep; + } + } + if(p[27]>0.0){ + dv0=-p[28]*p[14]; + if(p[30]<=0.0){ + dvh=(*Vbcp)+dv0; + dvh_Vbcp=1.0; + if(dvh>0.0){ + xvar1=(1.0-p[14]); + xvar2=(-1.0-p[29]); + pwq=pow(xvar1,xvar2); + qlo=p[28]*(1.0-pwq*(1.0-p[14])*(1.0-p[14]))/(1.0-p[29]); + qlo_Vbep=0.0; + qlo_Vbcp=0.0; + qhi=dvh*(1.0-p[14]+0.5*p[29]*dvh/p[28])*pwq; + qhi_dvh=(0.5*dvh*p[29]/p[28]-p[14]+1.0)*pwq+0.5*dvh*p[29]*pwq/p[28]; + qhi_Vbep=0.0; + qhi_Vbcp=qhi_dvh*dvh_Vbcp; + }else{ + xvar1=(1.0-(*Vbcp)/p[28]); + xvar1_Vbcp=-1.0/p[28]; + xvar2=(1.0-p[29]); + xvar3=pow(xvar1,xvar2); + xvar3_xvar1=xvar3*xvar2/xvar1; + xvar3_Vbcp=xvar3_xvar1*xvar1_Vbcp; + qlo=p[28]*(1.0-xvar3)/(1.0-p[29]); + qlo_xvar3=-p[28]/(1.0-p[29]); + qlo_Vbep=0.0; + qlo_Vbcp=qlo_xvar3*xvar3_Vbcp; + qhi=0.0; + qhi_Vbep=0.0; + qhi_Vbcp=0.0; + } + qdbcp=qlo+qhi; + qdbcp_qlo=1.0; + qdbcp_qhi=1.0; + qdbcp_Vbcp=qdbcp_qlo*qlo_Vbcp; + qdbcp_Vbep=qdbcp_qlo*qlo_Vbep; + qdbcp_Vbep=qdbcp_Vbep+qdbcp_qhi*qhi_Vbep; + qdbcp_Vbcp=qdbcp_Vbcp+qdbcp_qhi*qhi_Vbcp; + }else{ + mv0=sqrt(dv0*dv0+4.0*p[30]*p[30]); + vl0=-0.5*(dv0+mv0); + xvar1=(1.0-vl0/p[28]); + xvar2=(1.0-p[29]); + xvar3=pow(xvar1,xvar2); + q0=-p[28]*xvar3/(1.0-p[29]); + dv=(*Vbcp)+dv0; + dv_Vbcp=1.0; + mv=sqrt(dv*dv+4.0*p[30]*p[30]); + mv_dv=dv/sqrt((dv*dv)+4.0*(p[30]*p[30])); + mv_Vbcp=mv_dv*dv_Vbcp; + vl=0.5*(dv-mv)-dv0; + vl_dv=0.5; + vl_mv=-0.5; + vl_Vbcp=vl_dv*dv_Vbcp; + vl_Vbcp=vl_Vbcp+vl_mv*mv_Vbcp; + xvar1=(1.0-vl/p[28]); + xvar1_vl=-1.0/p[28]; + xvar1_Vbcp=xvar1_vl*vl_Vbcp; + xvar2=(1.0-p[29]); + xvar3=pow(xvar1,xvar2); + xvar3_xvar1=xvar3*xvar2/xvar1; + xvar3_Vbcp=xvar3_xvar1*xvar1_Vbcp; + qlo=-p[28]*xvar3/(1.0-p[29]); + qlo_xvar3=-p[28]/(1.0-p[29]); + qlo_Vbep=0.0; + qlo_Vbcp=qlo_xvar3*xvar3_Vbcp; + xvar1=(1.0-p[14]); + xvar2=(-p[29]); + xvar3=pow(xvar1,xvar2); + qdbcp=qlo+xvar3*((*Vbcp)-vl+vl0)-q0; + qdbcp_qlo=1.0; + qdbcp_Vbcp=xvar3; + qdbcp_vl=-xvar3; + qdbcp_Vbcp=qdbcp_Vbcp+qdbcp_qlo*qlo_Vbcp; + qdbcp_Vbep=qdbcp_qlo*qlo_Vbep; + qdbcp_Vbcp=qdbcp_Vbcp+qdbcp_vl*vl_Vbcp; + } + }else{ + qdbcp=0.0; + qdbcp_Vbcp=0.0; + } + argi=(*Vbei)/(p[12]*Vtv); + argi_Vbei=1.0/(p[12]*Vtv); + expi=exp(argi); + expi_argi=expi; + expi_Vbei=expi_argi*argi_Vbei; + Ifi=p[11]*(expi-1.0); + Ifi_expi=p[11]; + Ifi_Vbei=Ifi_expi*expi_Vbei; + argi=(*Vbci)/(p[13]*Vtv); + argi_Vbci=1.0/(p[13]*Vtv); + expi=exp(argi); + expi_argi=expi; + expi_Vbci=expi_argi*argi_Vbci; + Iri=p[11]*p[94]*(expi-1.0); + Iri_expi=p[11]*p[94]; + Iri_Vbci=Iri_expi*expi_Vbci; + q1z=1.0+qdbe*IVER+qdbc*IVEF; + q1z_qdbe=IVER; + q1z_qdbc=IVEF; + q1z_Vbei=q1z_qdbe*qdbe_Vbei; + q1z_Vbci=q1z_qdbc*qdbc_Vbci; + q1=0.5*(sqrt((q1z-1.0e-4)*(q1z-1.0e-4)+1.0e-8)+q1z-1.0e-4)+1.0e-4; + q1_q1z=0.5*((q1z-1.0e-4)/sqrt(((q1z-1.0e-4)*(q1z-1.0e-4))+1.0e-8)+1.0); + q1_Vbei=q1_q1z*q1z_Vbei; + q1_Vbci=q1_q1z*q1z_Vbci; + q2=Ifi*IIKF+Iri*IIKR; + q2_Ifi=IIKF; + q2_Iri=IIKR; + q2_Vbei=q2_Ifi*Ifi_Vbei; + q2_Vbci=q2_Iri*Iri_Vbci; + if(p[88]<0.5){ + xvar2=1.0/p[89]; + xvar3=pow(q1,xvar2); + xvar3_q1=xvar3*xvar2/q1; + xvar3_Vbei=xvar3_q1*q1_Vbei; + xvar3_Vbci=xvar3_q1*q1_Vbci; + xvar1=(xvar3+4.0*q2); + xvar1_xvar3=1.0; + xvar1_q2=4.0; + xvar1_Vbei=xvar1_xvar3*xvar3_Vbei; + xvar1_Vbci=xvar1_xvar3*xvar3_Vbci; + xvar1_Vbei=xvar1_Vbei+xvar1_q2*q2_Vbei; + xvar1_Vbci=xvar1_Vbci+xvar1_q2*q2_Vbci; + xvar4=pow(xvar1,p[89]); + xvar4_xvar1=xvar4*p[89]/xvar1; + xvar4_Vbei=xvar4_xvar1*xvar1_Vbei; + xvar4_Vbci=xvar4_xvar1*xvar1_Vbci; + qb=0.5*(q1+xvar4); + qb_q1=0.5; + qb_xvar4=0.5; + qb_Vbei=qb_q1*q1_Vbei; + qb_Vbci=qb_q1*q1_Vbci; + qb_Vbei=qb_Vbei+qb_xvar4*xvar4_Vbei; + qb_Vbci=qb_Vbci+qb_xvar4*xvar4_Vbci; + }else{ + xvar1=(1.0+4.0*q2); + xvar1_q2=4.0; + xvar1_Vbei=xvar1_q2*q2_Vbei; + xvar1_Vbci=xvar1_q2*q2_Vbci; + xvar2=pow(xvar1,p[89]); + xvar2_xvar1=xvar2*p[89]/xvar1; + xvar2_Vbei=xvar2_xvar1*xvar1_Vbei; + xvar2_Vbci=xvar2_xvar1*xvar1_Vbci; + qb=0.5*q1*(1.0+xvar2); + qb_q1=0.5*(xvar2+1.0); + qb_xvar2=0.5*q1; + qb_Vbei=qb_q1*q1_Vbei; + qb_Vbci=qb_q1*q1_Vbci; + qb_Vbei=qb_Vbei+qb_xvar2*xvar2_Vbei; + qb_Vbci=qb_Vbci+qb_xvar2*xvar2_Vbci; + } + (*Itzr)=Iri/qb; + Itzr_Iri=1.0/qb; + Itzr_qb=-Iri/(qb*qb); + *Itzr_Vbci=Itzr_Iri*Iri_Vbci; + *Itzr_Vbei=Itzr_qb*qb_Vbei; + *Itzr_Vbci=(*Itzr_Vbci)+Itzr_qb*qb_Vbci; + (*Itzf)=Ifi/qb; + Itzf_Ifi=1.0/qb; + Itzf_qb=-Ifi/(qb*qb); + *Itzf_Vbei=Itzf_Ifi*Ifi_Vbei; + *Itzf_Vbei=(*Itzf_Vbei)+Itzf_qb*qb_Vbei; + *Itzf_Vbci=Itzf_qb*qb_Vbci; + if(p[42]>0.0){ + argi=(*Vbep)/(p[44]*Vtv); + argi_Vbep=1.0/(p[44]*Vtv); + expi=exp(argi); + expi_argi=expi; + expi_Vbep=expi_argi*argi_Vbep; + argx=(*Vbci)/(p[44]*Vtv); + argx_Vbci=1.0/(p[44]*Vtv); + expx=exp(argx); + expx_argx=expx; + expx_Vbci=expx_argx*argx_Vbci; + Ifp=p[42]*(p[43]*expi+(1.0-p[43])*expx-1.0); + Ifp_expi=p[42]*p[43]; + Ifp_expx=p[42]*(1.0-p[43]); + Ifp_Vbep=Ifp_expi*expi_Vbep; + Ifp_Vbci=Ifp_expx*expx_Vbci; + q2p=Ifp*IIKP; + q2p_Ifp=IIKP; + q2p_Vbep=q2p_Ifp*Ifp_Vbep; + q2p_Vbci=q2p_Ifp*Ifp_Vbci; + qbp=0.5*(1.0+sqrt(1.0+4.0*q2p)); + qbp_q2p=1.0/sqrt(4.0*q2p+1.0); + qbp_Vbep=qbp_q2p*q2p_Vbep; + qbp_Vbci=qbp_q2p*q2p_Vbci; + argi=(*Vbcp)/(p[44]*Vtv); + argi_Vbcp=1.0/(p[44]*Vtv); + expi=exp(argi); + expi_argi=expi; + expi_Vbcp=expi_argi*argi_Vbcp; + Irp=p[42]*(expi-1.0); + Irp_expi=p[42]; + Irp_Vbcp=Irp_expi*expi_Vbcp; + (*Iccp)=(Ifp-Irp)/qbp; + Iccp_Ifp=1.0/qbp; + Iccp_Irp=-1.0/qbp; + Iccp_qbp=-(Ifp-Irp)/(qbp*qbp); + *Iccp_Vbep=Iccp_Ifp*Ifp_Vbep; + *Iccp_Vbci=Iccp_Ifp*Ifp_Vbci; + *Iccp_Vbcp=Iccp_Irp*Irp_Vbcp; + *Iccp_Vbep=(*Iccp_Vbep)+Iccp_qbp*qbp_Vbep; + *Iccp_Vbci=(*Iccp_Vbci)+Iccp_qbp*qbp_Vbci; + }else{ + Ifp=0.0; + Ifp_Vbep=0.0; + Ifp_Vbci=0.0; + qbp=1.0; + qbp_Vbep=0.0; + qbp_Vbci=0.0; + (*Iccp)=0.0; + *Iccp_Vbep=0.0; + *Iccp_Vbci=0.0; + *Iccp_Vbcp=0.0; + } + if(p[32]==1.0){ + argi=(*Vbei)/(p[33]*Vtv); + argi_Vbei=1.0/(p[33]*Vtv); + expi=exp(argi); + expi_argi=expi; + expi_Vbei=expi_argi*argi_Vbei; + argn=(*Vbei)/(p[35]*Vtv); + argn_Vbei=1.0/(p[35]*Vtv); + expn=exp(argn); + expn_argn=expn; + expn_Vbei=expn_argn*argn_Vbei; + if(p[98]>0.0){ + argx=(-p[98]-(*Vbei))/(p[99]*Vtv); + argx_Vbei=-1.0/(p[99]*Vtv); + expx=exp(argx); + expx_argx=expx; + expx_Vbei=expx_argx*argx_Vbei; + (*Ibe)=p[31]*(expi-1.0)+p[34]*(expn-1.0)-p[100]*(expx-p[104]); + Ibe_expi=p[31]; + Ibe_expn=p[34]; + Ibe_expx=-p[100]; + *Ibe_Vbei=Ibe_expi*expi_Vbei; + *Ibe_Vbei=(*Ibe_Vbei)+Ibe_expn*expn_Vbei; + *Ibe_Vbei=(*Ibe_Vbei)+Ibe_expx*expx_Vbei; + }else{ + (*Ibe)=p[31]*(expi-1.0)+p[34]*(expn-1.0); + Ibe_expi=p[31]; + Ibe_expn=p[34]; + *Ibe_Vbei=Ibe_expi*expi_Vbei; + *Ibe_Vbei=(*Ibe_Vbei)+Ibe_expn*expn_Vbei; + } + (*Ibex)=0.0; + *Ibex_Vbex=0.0; + }else if(p[32]==0.0){ + (*Ibe)=0.0; + *Ibe_Vbei=0.0; + argi=(*Vbex)/(p[33]*Vtv); + argi_Vbex=1.0/(p[33]*Vtv); + expi=exp(argi); + expi_argi=expi; + expi_Vbex=expi_argi*argi_Vbex; + argn=(*Vbex)/(p[35]*Vtv); + argn_Vbex=1.0/(p[35]*Vtv); + expn=exp(argn); + expn_argn=expn; + expn_Vbex=expn_argn*argn_Vbex; + if(p[98]>0.0){ + argx=(-p[98]-(*Vbex))/(p[99]*Vtv); + argx_Vbex=-1.0/(p[99]*Vtv); + expx=exp(argx); + expx_argx=expx; + expx_Vbex=expx_argx*argx_Vbex; + (*Ibex)=p[31]*(expi-1.0)+p[34]*(expn-1.0)-p[100]*(expx-p[104]); + Ibex_expi=p[31]; + Ibex_expn=p[34]; + Ibex_expx=-p[100]; + *Ibex_Vbex=Ibex_expi*expi_Vbex; + *Ibex_Vbex=(*Ibex_Vbex)+Ibex_expn*expn_Vbex; + *Ibex_Vbex=(*Ibex_Vbex)+Ibex_expx*expx_Vbex; + }else{ + (*Ibex)=p[31]*(expi-1.0)+p[34]*(expn-1.0); + Ibex_expi=p[31]; + Ibex_expn=p[34]; + *Ibex_Vbex=Ibex_expi*expi_Vbex; + *Ibex_Vbex=(*Ibex_Vbex)+Ibex_expn*expn_Vbex; + } + }else{ + argi=(*Vbei)/(p[33]*Vtv); + argi_Vbei=1.0/(p[33]*Vtv); + expi=exp(argi); + expi_argi=expi; + expi_Vbei=expi_argi*argi_Vbei; + argn=(*Vbei)/(p[35]*Vtv); + argn_Vbei=1.0/(p[35]*Vtv); + expn=exp(argn); + expn_argn=expn; + expn_Vbei=expn_argn*argn_Vbei; + if(p[98]>0.0){ + argx=(-p[98]-(*Vbei))/(p[99]*Vtv); + argx_Vbei=-1.0/(p[99]*Vtv); + expx=exp(argx); + expx_argx=expx; + expx_Vbei=expx_argx*argx_Vbei; + (*Ibe)=p[32]*(p[31]*(expi-1.0)+p[34]*(expn-1.0)-p[100]*(expx-p[104])); + Ibe_expi=p[31]*p[32]; + Ibe_expn=p[34]*p[32]; + Ibe_expx=-p[100]*p[32]; + *Ibe_Vbei=Ibe_expi*expi_Vbei; + *Ibe_Vbei=(*Ibe_Vbei)+Ibe_expn*expn_Vbei; + *Ibe_Vbei=(*Ibe_Vbei)+Ibe_expx*expx_Vbei; + }else{ + (*Ibe)=p[32]*(p[31]*(expi-1.0)+p[34]*(expn-1.0)); + Ibe_expi=p[31]*p[32]; + Ibe_expn=p[34]*p[32]; + *Ibe_Vbei=Ibe_expi*expi_Vbei; + *Ibe_Vbei=(*Ibe_Vbei)+Ibe_expn*expn_Vbei; + } + argi=(*Vbex)/(p[33]*Vtv); + argi_Vbex=1.0/(p[33]*Vtv); + expi=exp(argi); + expi_argi=expi; + expi_Vbex=expi_argi*argi_Vbex; + argn=(*Vbex)/(p[35]*Vtv); + argn_Vbex=1.0/(p[35]*Vtv); + expn=exp(argn); + expn_argn=expn; + expn_Vbex=expn_argn*argn_Vbex; + if(p[98]>0.0){ + argx=(-p[98]-(*Vbex))/(p[99]*Vtv); + argx_Vbex=-1.0/(p[99]*Vtv); + expx=exp(argx); + expx_argx=expx; + expx_Vbex=expx_argx*argx_Vbex; + (*Ibex)=(1.0-p[32])*(p[31]*(expi-1.0)+p[34]*(expn-1.0)-p[100]*(expx-p[104])); + Ibex_expi=p[31]*(1.0-p[32]); + Ibex_expn=p[34]*(1.0-p[32]); + Ibex_expx=-p[100]*(1.0-p[32]); + *Ibex_Vbex=Ibex_expi*expi_Vbex; + *Ibex_Vbex=(*Ibex_Vbex)+Ibex_expn*expn_Vbex; + *Ibex_Vbex=(*Ibex_Vbex)+Ibex_expx*expx_Vbex; + }else{ + (*Ibex)=(1.0-p[32])*(p[31]*(expi-1.0)+p[34]*(expn-1.0)); + Ibex_expi=p[31]*(1.0-p[32]); + Ibex_expn=p[34]*(1.0-p[32]); + *Ibex_Vbex=Ibex_expi*expi_Vbex; + *Ibex_Vbex=(*Ibex_Vbex)+Ibex_expn*expn_Vbex; + } + } + argi=(*Vbci)/(p[37]*Vtv); + argi_Vbci=1.0/(p[37]*Vtv); + expi=exp(argi); + expi_argi=expi; + expi_Vbci=expi_argi*argi_Vbci; + argn=(*Vbci)/(p[39]*Vtv); + argn_Vbci=1.0/(p[39]*Vtv); + expn=exp(argn); + expn_argn=expn; + expn_Vbci=expn_argn*argn_Vbci; + Ibcj=p[36]*(expi-1.0)+p[38]*(expn-1.0); + Ibcj_expi=p[36]; + Ibcj_expn=p[38]; + Ibcj_Vbci=Ibcj_expi*expi_Vbci; + Ibcj_Vbci=Ibcj_Vbci+Ibcj_expn*expn_Vbci; + if((p[45]>0.0)||(p[46]>0.0)){ + argi=(*Vbep)/(p[37]*Vtv); + argi_Vbep=1.0/(p[37]*Vtv); + expi=exp(argi); + expi_argi=expi; + expi_Vbep=expi_argi*argi_Vbep; + argn=(*Vbep)/(p[39]*Vtv); + argn_Vbep=1.0/(p[39]*Vtv); + expn=exp(argn); + expn_argn=expn; + expn_Vbep=expn_argn*argn_Vbep; + (*Ibep)=p[45]*(expi-1.0)+p[46]*(expn-1.0); + Ibep_expi=p[45]; + Ibep_expn=p[46]; + *Ibep_Vbep=Ibep_expi*expi_Vbep; + *Ibep_Vbep=(*Ibep_Vbep)+Ibep_expn*expn_Vbep; + }else{ + (*Ibep)=0.0; + *Ibep_Vbep=0.0; + } + if(p[40]>0.0){ + vl=0.5*(sqrt((p[24]-(*Vbci))*(p[24]-(*Vbci))+0.01)+(p[24]-(*Vbci))); + vl_Vbci=0.5*(-(p[24]-(*Vbci))/sqrt(((p[24]-(*Vbci))*(p[24]-(*Vbci)))+0.01)-1.0); + xvar2=(p[25]-1.0); + xvar3=pow(vl,xvar2); + xvar3_vl=xvar3*xvar2/vl; + xvar3_Vbci=xvar3_vl*vl_Vbci; + xvar1=-p[41]*xvar3; + xvar1_xvar3=-p[41]; + xvar1_Vbci=xvar1_xvar3*xvar3_Vbci; + xvar4=exp(xvar1); + xvar4_xvar1=xvar4; + xvar4_Vbci=xvar4_xvar1*xvar1_Vbci; + avalf=p[40]*vl*xvar4; + avalf_vl=p[40]*xvar4; + avalf_xvar4=p[40]*vl; + avalf_Vbci=avalf_vl*vl_Vbci; + avalf_Vbci=avalf_Vbci+avalf_xvar4*xvar4_Vbci; + Igc=((*Itzf)-(*Itzr)-Ibcj)*avalf; + Igc_Itzf=avalf; + Igc_Itzr=-avalf; + Igc_Ibcj=-avalf; + Igc_avalf=-(*Itzr)+(*Itzf)-Ibcj; + Igc_Vbei=Igc_Itzf*(*Itzf_Vbei); + Igc_Vbci=Igc_Itzf*(*Itzf_Vbci); + Igc_Vbci=Igc_Vbci+Igc_Itzr*(*Itzr_Vbci); + Igc_Vbei=Igc_Vbei+Igc_Itzr*(*Itzr_Vbei); + Igc_Vbci=Igc_Vbci+Igc_Ibcj*Ibcj_Vbci; + Igc_Vbci=Igc_Vbci+Igc_avalf*avalf_Vbci; + }else{ + Igc=0.0; + Igc_Vbei=0.0; + Igc_Vbci=0.0; + } + (*Ibc)=Ibcj-Igc; + Ibc_Ibcj=1.0; + Ibc_Igc=-1.0; + *Ibc_Vbci=Ibc_Ibcj*Ibcj_Vbci; + *Ibc_Vbei=Ibc_Igc*Igc_Vbei; + *Ibc_Vbci=(*Ibc_Vbci)+Ibc_Igc*Igc_Vbci; + if(p[1]>0.0){ + (*Ircx)=(*Vrcx)/p[1]; + *Ircx_Vrcx=1.0/p[1]; + }else{ + (*Ircx)=0.0; + *Ircx_Vrcx=0.0; + } + argi=(*Vbci)/Vtv; + argi_Vbci=1.0/Vtv; + expi=exp(argi); + expi_argi=expi; + expi_Vbci=expi_argi*argi_Vbci; + argx=(*Vbcx)/Vtv; + argx_Vbcx=1.0/Vtv; + expx=exp(argx); + expx_argx=expx; + expx_Vbcx=expx_argx*argx_Vbcx; + Kbci=sqrt(1.0+p[4]*expi); + Kbci_expi=p[4]/(2.0*sqrt(expi*p[4]+1.0)); + Kbci_Vbci=Kbci_expi*expi_Vbci; + Kbcx=sqrt(1.0+p[4]*expx); + Kbcx_expx=p[4]/(2.0*sqrt(expx*p[4]+1.0)); + Kbcx_Vbcx=Kbcx_expx*expx_Vbcx; + if(p[2]>0.0){ + rKp1=(Kbci+1.0)/(Kbcx+1.0); + rKp1_Kbci=1.0/(Kbcx+1.0); + rKp1_Kbcx=-(Kbci+1.0)/((Kbcx+1.0)*(Kbcx+1.0)); + rKp1_Vbci=rKp1_Kbci*Kbci_Vbci; + rKp1_Vbcx=rKp1_Kbcx*Kbcx_Vbcx; + xvar1=log(rKp1); + xvar1_rKp1=1.0/rKp1; + xvar1_Vbci=xvar1_rKp1*rKp1_Vbci; + xvar1_Vbcx=xvar1_rKp1*rKp1_Vbcx; + Iohm=((*Vrci)+Vtv*(Kbci-Kbcx-xvar1))/p[2]; + Iohm_Vrci=1.0/p[2]; + Iohm_Kbci=Vtv/p[2]; + Iohm_Kbcx=-Vtv/p[2]; + Iohm_xvar1=-Vtv/p[2]; + Iohm_Vbci=Iohm_Kbci*Kbci_Vbci; + Iohm_Vbcx=Iohm_Kbcx*Kbcx_Vbcx; + Iohm_Vbci=Iohm_Vbci+Iohm_xvar1*xvar1_Vbci; + Iohm_Vbcx=Iohm_Vbcx+Iohm_xvar1*xvar1_Vbcx; + derf=IVO*p[2]*Iohm/(1.0+0.5*IVO*IHRCF*sqrt((*Vrci)*(*Vrci)+0.01)); + derf_Iohm=IVO*p[2]/(0.5*IHRCF*IVO*sqrt(((*Vrci)*(*Vrci))+0.01)+1.0); + derf_Vrci=-0.5*IHRCF*Iohm*(IVO*IVO)*p[2]*(*Vrci)/(sqrt(((*Vrci)*(*Vrci))+0.01)*((0.5*IHRCF*IVO*sqrt(((*Vrci)*(*Vrci))+0.01)+1.0)*(0.5*IHRCF*IVO*sqrt(((*Vrci)*(*Vrci))+0.01)+1.0))); + derf_Vrci=derf_Vrci+derf_Iohm*Iohm_Vrci; + derf_Vbci=derf_Iohm*Iohm_Vbci; + derf_Vbcx=derf_Iohm*Iohm_Vbcx; + (*Irci)=Iohm/sqrt(1.0+derf*derf); + Irci_Iohm=1.0/sqrt((derf*derf)+1.0); + Irci_derf=-derf*Iohm/pow(((derf*derf)+1.0),(3.0/2.0)); + *Irci_Vrci=Irci_Iohm*Iohm_Vrci; + *Irci_Vbci=Irci_Iohm*Iohm_Vbci; + *Irci_Vbcx=Irci_Iohm*Iohm_Vbcx; + *Irci_Vrci=(*Irci_Vrci)+Irci_derf*derf_Vrci; + *Irci_Vbci=(*Irci_Vbci)+Irci_derf*derf_Vbci; + *Irci_Vbcx=(*Irci_Vbcx)+Irci_derf*derf_Vbcx; + }else{ + (*Irci)=0.0; + *Irci_Vrci=0.0; + *Irci_Vbci=0.0; + *Irci_Vbcx=0.0; + } + if(p[6]>0.0){ + (*Irbx)=(*Vrbx)/p[6]; + *Irbx_Vrbx=1.0/p[6]; + }else{ + (*Irbx)=0.0; + *Irbx_Vrbx=0.0; + } + if(p[7]>0.0){ + (*Irbi)=(*Vrbi)*qb/p[7]; + *Irbi_Vrbi=qb/p[7]; + Irbi_qb=(*Vrbi)/p[7]; + *Irbi_Vbei=Irbi_qb*qb_Vbei; + *Irbi_Vbci=Irbi_qb*qb_Vbci; + }else{ + (*Irbi)=0.0; + *Irbi_Vrbi=0.0; + *Irbi_Vbei=0.0; + *Irbi_Vbci=0.0; + } + if(p[8]>0.0){ + (*Ire)=(*Vre)/p[8]; + *Ire_Vre=1.0/p[8]; + }else{ + (*Ire)=0.0; + *Ire_Vre=0.0; + } + if(p[10]>0.0){ + (*Irbp)=(*Vrbp)*qbp/p[10]; + *Irbp_Vrbp=qbp/p[10]; + Irbp_qbp=(*Vrbp)/p[10]; + *Irbp_Vbep=Irbp_qbp*qbp_Vbep; + *Irbp_Vbci=Irbp_qbp*qbp_Vbci; + }else{ + (*Irbp)=0.0; + *Irbp_Vrbp=0.0; + *Irbp_Vbep=0.0; + *Irbp_Vbci=0.0; + } + if((p[47]>0.0)||(p[49]>0.0)){ + argi=(*Vbcp)/(p[48]*Vtv); + argi_Vbcp=1.0/(p[48]*Vtv); + expi=exp(argi); + expi_argi=expi; + expi_Vbcp=expi_argi*argi_Vbcp; + argn=(*Vbcp)/(p[50]*Vtv); + argn_Vbcp=1.0/(p[50]*Vtv); + expn=exp(argn); + expn_argn=expn; + expn_Vbcp=expn_argn*argn_Vbcp; + (*Ibcp)=p[47]*(expi-1.0)+p[49]*(expn-1.0); + Ibcp_expi=p[47]; + Ibcp_expn=p[49]; + *Ibcp_Vbcp=Ibcp_expi*expi_Vbcp; + *Ibcp_Vbcp=(*Ibcp_Vbcp)+Ibcp_expn*expn_Vbcp; + }else{ + (*Ibcp)=0.0; + *Ibcp_Vbcp=0.0; + } + if(p[9]>0.0){ + (*Irs)=(*Vrs)/p[9]; + *Irs_Vrs=1.0/p[9]; + }else{ + (*Irs)=0.0; + *Irs_Vrs=0.0; + } + if(Ifi>0.0){ + sgIf=1.0; + }else{ + sgIf=0.0; + } + rIf=Ifi*sgIf*IITF; + rIf_Ifi=IITF*sgIf; + rIf_Vbei=rIf_Ifi*Ifi_Vbei; + mIf=rIf/(rIf+1.0); + mIf_rIf=1.0/(rIf+1.0)-rIf/((rIf+1.0)*(rIf+1.0)); + mIf_Vbei=mIf_rIf*rIf_Vbei; + xvar1=(*Vbci)*IVTF/1.44; + xvar1_Vbci=0.6944444*IVTF; + xvar2=exp(xvar1); + xvar2_xvar1=xvar2; + xvar2_Vbci=xvar2_xvar1*xvar1_Vbci; + tff=p[56]*(1.0+p[57]*q1)*(1.0+p[58]*xvar2*(slTF+mIf*mIf)*sgIf); + tff_q1=p[57]*p[56]*(sgIf*(slTF+(mIf*mIf))*p[58]*xvar2+1.0); + tff_xvar2=(q1*p[57]+1.0)*sgIf*(slTF+(mIf*mIf))*p[56]*p[58]; + tff_mIf=2.0*mIf*(q1*p[57]+1.0)*sgIf*p[56]*p[58]*xvar2; + tff_Vbei=tff_q1*q1_Vbei; + tff_Vbci=tff_q1*q1_Vbci; + tff_Vbci=tff_Vbci+tff_xvar2*xvar2_Vbci; + tff_Vbei=tff_Vbei+tff_mIf*mIf_Vbei; + (*Qbe)=p[16]*qdbe*p[32]+tff*Ifi/qb; + Qbe_qdbe=p[16]*p[32]; + Qbe_tff=Ifi/qb; + Qbe_Ifi=tff/qb; + Qbe_qb=-Ifi*tff/(qb*qb); + *Qbe_Vbei=Qbe_qdbe*qdbe_Vbei; + *Qbe_Vbei=(*Qbe_Vbei)+Qbe_tff*tff_Vbei; + *Qbe_Vbci=Qbe_tff*tff_Vbci; + *Qbe_Vbei=(*Qbe_Vbei)+Qbe_Ifi*Ifi_Vbei; + *Qbe_Vbei=(*Qbe_Vbei)+Qbe_qb*qb_Vbei; + *Qbe_Vbci=(*Qbe_Vbci)+Qbe_qb*qb_Vbci; + (*Qbex)=p[16]*qdbex*(1.0-p[32]); + Qbex_qdbex=p[16]*(1.0-p[32]); + *Qbex_Vbex=Qbex_qdbex*qdbex_Vbex; + (*Qbc)=p[21]*qdbc+p[61]*Iri+p[22]*Kbci; + Qbc_qdbc=p[21]; + Qbc_Iri=p[61]; + Qbc_Kbci=p[22]; + *Qbc_Vbci=Qbc_qdbc*qdbc_Vbci; + *Qbc_Vbci=(*Qbc_Vbci)+Qbc_Iri*Iri_Vbci; + *Qbc_Vbci=(*Qbc_Vbci)+Qbc_Kbci*Kbci_Vbci; + (*Qbcx)=p[22]*Kbcx; + Qbcx_Kbcx=p[22]; + *Qbcx_Vbcx=Qbcx_Kbcx*Kbcx_Vbcx; + (*Qbep)=p[23]*qdbep+p[61]*Ifp; + Qbep_qdbep=p[23]; + Qbep_Ifp=p[61]; + *Qbep_Vbep=Qbep_qdbep*qdbep_Vbep; + *Qbep_Vbep=(*Qbep_Vbep)+Qbep_Ifp*Ifp_Vbep; + *Qbep_Vbci=Qbep_Ifp*Ifp_Vbci; + (*Qbcp)=p[27]*qdbcp+p[87]*(*Vbcp); + Qbcp_qdbcp=p[27]; + *Qbcp_Vbcp=p[87]; + *Qbcp_Vbcp=(*Qbcp_Vbcp)+Qbcp_qdbcp*qdbcp_Vbcp; + (*Qbeo)=(*Vbe)*p[15]; + *Qbeo_Vbe=p[15]; + (*Qbco)=(*Vbc)*p[20]; + *Qbco_Vbc=p[20]; + +/* Scale outputs */ + + if((*SCALE)!=1.0){ + *Ibe=(*SCALE)*(*Ibe); + *Ibe_Vbei=(*SCALE)*(*Ibe_Vbei); + *Ibex=(*SCALE)*(*Ibex); + *Ibex_Vbex=(*SCALE)*(*Ibex_Vbex); + *Itzf=(*SCALE)*(*Itzf); + *Itzf_Vbei=(*SCALE)*(*Itzf_Vbei); + *Itzf_Vbci=(*SCALE)*(*Itzf_Vbci); + *Itzr=(*SCALE)*(*Itzr); + *Itzr_Vbci=(*SCALE)*(*Itzr_Vbci); + *Itzr_Vbei=(*SCALE)*(*Itzr_Vbei); + *Ibc=(*SCALE)*(*Ibc); + *Ibc_Vbci=(*SCALE)*(*Ibc_Vbci); + *Ibc_Vbei=(*SCALE)*(*Ibc_Vbei); + *Ibep=(*SCALE)*(*Ibep); + *Ibep_Vbep=(*SCALE)*(*Ibep_Vbep); + *Ircx=(*SCALE)*(*Ircx); + *Ircx_Vrcx=(*SCALE)*(*Ircx_Vrcx); + *Irci=(*SCALE)*(*Irci); + *Irci_Vrci=(*SCALE)*(*Irci_Vrci); + *Irci_Vbci=(*SCALE)*(*Irci_Vbci); + *Irci_Vbcx=(*SCALE)*(*Irci_Vbcx); + *Irbx=(*SCALE)*(*Irbx); + *Irbx_Vrbx=(*SCALE)*(*Irbx_Vrbx); + *Irbi=(*SCALE)*(*Irbi); + *Irbi_Vrbi=(*SCALE)*(*Irbi_Vrbi); + *Irbi_Vbei=(*SCALE)*(*Irbi_Vbei); + *Irbi_Vbci=(*SCALE)*(*Irbi_Vbci); + *Ire=(*SCALE)*(*Ire); + *Ire_Vre=(*SCALE)*(*Ire_Vre); + *Irbp=(*SCALE)*(*Irbp); + *Irbp_Vrbp=(*SCALE)*(*Irbp_Vrbp); + *Irbp_Vbep=(*SCALE)*(*Irbp_Vbep); + *Irbp_Vbci=(*SCALE)*(*Irbp_Vbci); + *Qbe=(*SCALE)*(*Qbe); + *Qbe_Vbei=(*SCALE)*(*Qbe_Vbei); + *Qbe_Vbci=(*SCALE)*(*Qbe_Vbci); + *Qbex=(*SCALE)*(*Qbex); + *Qbex_Vbex=(*SCALE)*(*Qbex_Vbex); + *Qbc=(*SCALE)*(*Qbc); + *Qbc_Vbci=(*SCALE)*(*Qbc_Vbci); + *Qbcx=(*SCALE)*(*Qbcx); + *Qbcx_Vbcx=(*SCALE)*(*Qbcx_Vbcx); + *Qbep=(*SCALE)*(*Qbep); + *Qbep_Vbep=(*SCALE)*(*Qbep_Vbep); + *Qbep_Vbci=(*SCALE)*(*Qbep_Vbci); + *Qbeo=(*SCALE)*(*Qbeo); + *Qbeo_Vbe=(*SCALE)*(*Qbeo_Vbe); + *Qbco=(*SCALE)*(*Qbco); + *Qbco_Vbc=(*SCALE)*(*Qbco_Vbc); + *Ibcp=(*SCALE)*(*Ibcp); + *Ibcp_Vbcp=(*SCALE)*(*Ibcp_Vbcp); + *Iccp=(*SCALE)*(*Iccp); + *Iccp_Vbep=(*SCALE)*(*Iccp_Vbep); + *Iccp_Vbci=(*SCALE)*(*Iccp_Vbci); + *Iccp_Vbcp=(*SCALE)*(*Iccp_Vbcp); + *Irs=(*SCALE)*(*Irs); + *Irs_Vrs=(*SCALE)*(*Irs_Vrs); + *Qbcp=(*SCALE)*(*Qbcp); + *Qbcp_Vbcp=(*SCALE)*(*Qbcp_Vbcp); + } + return(0); +} int vbic_4T_et_cf_fj(double *p ,double *Vrth, double *Vbei, double *Vbex, double *Vbci, double *Vbep, double *Vbcp ,double *Vrcx, double *Vbcx, double *Vrci, double *Vrbx, double *Vrbi, double *Vre, double *Vrbp @@ -3937,67 +5414,709 @@ double Ith_Iccp,Ith_Ircx,Ith_Irci,Ith_Irbx,Ith_Irbi,Ith_Ire,Ith_Irbp; } return(0); } -int vbic_4T_it_cf_fj(double *p - ,double *Vbei, double *Vbex, double *Vbci, double *Vbep, double *Vbcp, double *Vrcx - ,double *Vbcx, double *Vrci, double *Vrbx, double *Vrbi, double *Vre, double *Vrbp, double *Vrs - ,double *Vbe, double *Vbc, double *Ibe, double *Ibe_Vbei, double *Ibex, double *Ibex_Vbex, double *Itzf - ,double *Itzf_Vbei, double *Itzf_Vbci, double *Itzr, double *Itzr_Vbci, double *Itzr_Vbei, double *Ibc, double *Ibc_Vbci - ,double *Ibc_Vbei, double *Ibep, double *Ibep_Vbep, double *Ircx, double *Ircx_Vrcx, double *Irci, double *Irci_Vrci - ,double *Irci_Vbci, double *Irci_Vbcx, double *Irbx, double *Irbx_Vrbx, double *Irbi, double *Irbi_Vrbi, double *Irbi_Vbei - ,double *Irbi_Vbci, double *Ire, double *Ire_Vre, double *Irbp, double *Irbp_Vrbp, double *Irbp_Vbep, double *Irbp_Vbci - ,double *Qbe, double *Qbe_Vbei, double *Qbe_Vbci, double *Qbex, double *Qbex_Vbex, double *Qbc, double *Qbc_Vbci - ,double *Qbcx, double *Qbcx_Vbcx, double *Qbep, double *Qbep_Vbep, double *Qbep_Vbci, double *Qbeo, double *Qbeo_Vbe - ,double *Qbco, double *Qbco_Vbc, double *Ibcp, double *Ibcp_Vbcp, double *Iccp, double *Iccp_Vbep, double *Iccp_Vbci - ,double *Iccp_Vbcp, double *Irs, double *Irs_Vrs, double *Qbcp, double *Qbcp_Vbcp, double *SCALE) +int vbic_4T_et_xf_fj(double *p + ,double *Vrth,double *Vbei,double *Vbex,double *Vbci,double *Vbep,double *Vbcp + ,double *Vrxf,double *Vrcx,double *Vbcx,double *Vrci,double *Vrbx,double *Vrbi,double *Vre + ,double *Vrbp,double *Vrs,double *Vbe,double *Vbc,double *Vcei,double *Vcep,double *Vcxf + ,double *Ibe,double *Ibe_Vrth,double *Ibe_Vbei,double *Ibex,double *Ibex_Vrth,double *Ibex_Vbex,double *Itxf + ,double *Itxf_Vrxf,double *Itzr,double *Itzr_Vrth,double *Itzr_Vbci,double *Itzr_Vbei,double *Ibc,double *Ibc_Vrth + ,double *Ibc_Vbci,double *Ibc_Vrxf,double *Ibc_Vbei,double *Ibep,double *Ibep_Vrth,double *Ibep_Vbep,double *Ircx + ,double *Ircx_Vrcx,double *Ircx_Vrth,double *Irci,double *Irci_Vrci,double *Irci_Vrth,double *Irci_Vbci,double *Irci_Vbcx + ,double *Irbx,double *Irbx_Vrbx,double *Irbx_Vrth,double *Irbi,double *Irbi_Vrbi,double *Irbi_Vrth,double *Irbi_Vbei + ,double *Irbi_Vbci,double *Ire,double *Ire_Vre,double *Ire_Vrth,double *Irbp,double *Irbp_Vrbp,double *Irbp_Vrth + ,double *Irbp_Vbep,double *Irbp_Vbci,double *Qbe,double *Qbe_Vrth,double *Qbe_Vbei,double *Qbe_Vbci,double *Qbex + ,double *Qbex_Vrth,double *Qbex_Vbex,double *Qbc,double *Qbc_Vrth,double *Qbc_Vbci,double *Qbcx,double *Qbcx_Vrth + ,double *Qbcx_Vbcx,double *Qbep,double *Qbep_Vrth,double *Qbep_Vbep,double *Qbep_Vbci,double *Qbeo,double *Qbeo_Vbe + ,double *Qbco,double *Qbco_Vbc,double *Ibcp,double *Ibcp_Vrth,double *Ibcp_Vbcp,double *Iccp,double *Iccp_Vrth + ,double *Iccp_Vbep,double *Iccp_Vbci,double *Iccp_Vbcp,double *Irs,double *Irs_Vrs,double *Irs_Vrth,double *Qbcp + ,double *Qbcp_Vrth,double *Qbcp_Vbcp,double *Irth,double *Irth_Vrth,double *Ith,double *Ith_Vrth,double *Ith_Vbei + ,double *Ith_Vbci,double *Ith_Vrxf,double *Ith_Vcei,double *Ith_Vbex,double *Ith_Vbep,double *Ith_Vrs,double *Ith_Vbcp + ,double *Ith_Vcep,double *Ith_Vrcx,double *Ith_Vrci,double *Ith_Vbcx,double *Ith_Vrbx,double *Ith_Vrbi,double *Ith_Vre + ,double *Ith_Vrbp,double *Qcth,double *Qcth_Vrth,double *Ixzf,double *Ixzf_Vrth,double *Ixzf_Vbei,double *Ixzf_Vbci + ,double *Ixxf,double *Ixxf_Vrxf,double *Qcxf,double *Qcxf_Vcxf,double *Flxf,double *Flxf_Vrxf,double *SCALE) { -double Vtv,IVEF,IVER,IIKF,IIKR,IIKP,IVO; -double IHRCF,IVTF,IITF,slTF,dv0,dvh,dvh_Vbei; -double xvar1,xvar2,pwq,qlo,qlo_Vbei,qhi,qhi_dvh; -double qhi_Vbei,xvar1_Vbei,xvar3,xvar3_xvar1,xvar3_Vbei,qlo_xvar3,qdbe; -double qdbe_qlo,qdbe_Vbei,qdbe_qhi,mv0,vl0,q0,dv; -double dv_Vbei,mv,mv_dv,mv_Vbei,vl,vl_dv,vl_Vbei; -double vl_mv,xvar1_vl,qdbe_vl,dvh_Vbex,qlo_Vbex,qhi_Vbex,xvar1_Vbex; -double xvar3_Vbex,qdbex,qdbex_qlo,qdbex_Vbex,qdbex_qhi,dv_Vbex,mv_Vbex; -double vl_Vbex,qdbex_vl,dvh_Vbci,qlo_Vbci,qhi_Vbci,xvar1_Vbci,xvar3_Vbci; -double qdbc,qdbc_qlo,qdbc_Vbci,qdbc_qhi,vn0,vnl0,qlo0; -double vn,vn_Vbci,vnl,vnl_vn,vnl_Vbci,vl_vnl,vl_Vbci; -double sel,sel_vnl,sel_Vbci,crt,cmx,cl,cl_sel; -double cl_Vbci,ql,ql_Vbci,ql_vl,ql_cl,qdbc_ql,dv_Vbci; -double mv_Vbci,qdbc_vl,dvh_Vbep,qlo_Vbep,qhi_Vbep,xvar1_Vbep,xvar3_Vbep; -double qdbep,qdbep_qlo,qdbep_Vbep,qdbep_qhi,vn_Vbep,vnl_Vbep,vl_Vbep; -double sel_Vbep,cl_Vbep,ql_Vbep,qdbep_ql,dv_Vbep,mv_Vbep,qdbep_vl; -double dvh_Vbcp,qlo_Vbcp,qhi_Vbcp,xvar1_Vbcp,xvar3_Vbcp,qdbcp,qdbcp_qlo; -double qdbcp_Vbcp,qdbcp_Vbep,qdbcp_qhi,dv_Vbcp,mv_Vbcp,vl_Vbcp,qdbcp_vl; -double argi,argi_Vbei,expi,expi_argi,expi_Vbei,Ifi,Ifi_expi; -double Ifi_Vbei,argi_Vbci,expi_Vbci,Iri,Iri_expi,Iri_Vbci,q1z; -double q1z_qdbe,q1z_Vbei,q1z_qdbc,q1z_Vbci,q1,q1_q1z,q1_Vbei; -double q1_Vbci,q2,q2_Ifi,q2_Vbei,q2_Iri,q2_Vbci,xvar3_q1; -double xvar1_xvar3,xvar1_q2,xvar4,xvar4_xvar1,xvar4_Vbei,xvar4_Vbci,qb; -double qb_q1,qb_Vbei,qb_Vbci,qb_xvar4,xvar2_xvar1,xvar2_Vbei,xvar2_Vbci; -double qb_xvar2,Itzr_Iri,Itzr_qb,Itzf_Ifi,Itzf_qb,argi_Vbep,expi_Vbep; -double argx,argx_Vbci,expx,expx_argx,expx_Vbci,Ifp,Ifp_expi; -double Ifp_Vbep,Ifp_expx,Ifp_Vbci,q2p,q2p_Ifp,q2p_Vbep,q2p_Vbci; -double qbp,qbp_q2p,qbp_Vbep,qbp_Vbci,argi_Vbcp,expi_Vbcp,Irp; -double Irp_expi,Irp_Vbcp,Iccp_Ifp,Iccp_Irp,Iccp_qbp,argn,argn_Vbei; -double expn,expn_argn,expn_Vbei,argx_Vbei,expx_Vbei,Ibe_expi,Ibe_expn; -double Ibe_expx,argi_Vbex,expi_Vbex,argn_Vbex,expn_Vbex,argx_Vbex,expx_Vbex; -double Ibex_expi,Ibex_expn,Ibex_expx,argn_Vbci,expn_Vbci,Ibcj,Ibcj_expi; -double Ibcj_Vbci,Ibcj_expn,argn_Vbep,expn_Vbep,Ibep_expi,Ibep_expn,xvar3_vl; -double avalf,avalf_vl,avalf_Vbci,avalf_xvar4,Igc,Igc_Itzf,Igc_Vbei; -double Igc_Vbci,Igc_Itzr,Igc_Ibcj,Igc_avalf,Ibc_Ibcj,Ibc_Igc,argx_Vbcx; -double expx_Vbcx,Kbci,Kbci_expi,Kbci_Vbci,Kbcx,Kbcx_expx,Kbcx_Vbcx; -double rKp1,rKp1_Kbci,rKp1_Vbci,rKp1_Kbcx,rKp1_Vbcx,xvar1_rKp1,xvar1_Vbcx; -double Iohm,Iohm_Vrci,Iohm_Kbci,Iohm_Vbci,Iohm_Kbcx,Iohm_Vbcx,Iohm_xvar1; -double derf,derf_Iohm,derf_Vrci,derf_Vbci,derf_Vbcx,Irci_Iohm,Irci_derf; -double Irbi_qb,Irbp_qbp,argn_Vbcp,expn_Vbcp,Ibcp_expi,Ibcp_expn,sgIf; -double rIf,rIf_Ifi,rIf_Vbei,mIf,mIf_rIf,mIf_Vbei,tff; -double tff_q1,tff_Vbei,tff_Vbci,tff_xvar2,tff_mIf,Qbe_qdbe,Qbe_tff; -double Qbe_Ifi,Qbe_qb,Qbex_qdbex,Qbc_qdbc,Qbc_Iri,Qbc_Kbci,Qbcx_Kbcx; -double Qbep_qdbep,Qbep_Ifp,Qbcp_qdbcp; +double Tini,Tdev,Tdev_Vrth,Vtv,Vtv_Tdev,Vtv_Vrth,rT; +double rT_Tdev,rT_Vrth,dT,dT_Tdev,dT_Vrth,xvar1,xvar1_rT; +double xvar1_Vrth,IKFatT,IKFatT_xvar1,IKFatT_Vrth,RCXatT,RCXatT_xvar1,RCXatT_Vrth; +double RCIatT,RCIatT_xvar1,RCIatT_Vrth,RBXatT,RBXatT_xvar1,RBXatT_Vrth,RBIatT; +double RBIatT_xvar1,RBIatT_Vrth,REatT,REatT_xvar1,REatT_Vrth,RSatT,RSatT_xvar1; +double RSatT_Vrth,RBPatT,RBPatT_xvar1,RBPatT_Vrth,xvar2,xvar2_rT,xvar2_Vrth; +double xvar3,xvar3_rT,xvar3_Vrth,xvar3_Vtv,xvar4,xvar4_xvar3,xvar4_Vrth; +double xvar1_xvar2,xvar1_xvar4,xvar5,xvar6,xvar6_xvar1,xvar6_Vrth,ISatT; +double ISatT_xvar6,ISatT_Vrth,ISRRatT,ISRRatT_xvar6,ISRRatT_Vrth,ISPatT,ISPatT_xvar6; +double ISPatT_Vrth,IBEIatT,IBEIatT_xvar6,IBEIatT_Vrth,IBENatT,IBENatT_xvar6,IBENatT_Vrth; +double IBCIatT,IBCIatT_xvar6,IBCIatT_Vrth,IBCNatT,IBCNatT_xvar6,IBCNatT_Vrth,IBEIPatT; +double IBEIPatT_xvar6,IBEIPatT_Vrth,IBENPatT,IBENPatT_xvar6,IBENPatT_Vrth,IBCIPatT,IBCIPatT_xvar6; +double IBCIPatT_Vrth,IBCNPatT,IBCNPatT_xvar6,IBCNPatT_Vrth,NFatT,NFatT_dT,NFatT_Vrth; +double NRatT,NRatT_dT,NRatT_Vrth,AVC2atT,AVC2atT_dT,AVC2atT_Vrth,VBBEatT; +double VBBEatT_dT,VBBEatT_Vrth,NBBEatT,NBBEatT_dT,NBBEatT_Vrth,xvar2_Vtv,xvar3_xvar2; +double xvar4_rT,xvar4_Vtv,xvar5_xvar4,xvar5_Vrth,xvar1_xvar3,xvar1_xvar5,psiio; +double psiio_Vtv,psiio_Vrth,psiio_rT,psiio_xvar6,psiin,psiin_psiio,psiin_Vrth; +double psiin_rT,psiin_Vtv,psiin_xvar1,xvar2_psiin,xvar4_xvar1,PEatT,PEatT_psiin; +double PEatT_Vrth,PEatT_Vtv,PEatT_xvar4,PCatT,PCatT_psiin,PCatT_Vrth,PCatT_Vtv; +double PCatT_xvar4,PSatT,PSatT_psiin,PSatT_Vrth,PSatT_Vtv,PSatT_xvar4,xvar1_PEatT; +double xvar2_xvar1,CJEatT,CJEatT_xvar2,CJEatT_Vrth,xvar1_PCatT,CJCatT,CJCatT_xvar2; +double CJCatT_Vrth,CJEPatT,CJEPatT_xvar2,CJEPatT_Vrth,xvar1_PSatT,CJCPatT,CJCPatT_xvar2; +double CJCPatT_Vrth,GAMMatT,GAMMatT_xvar1,GAMMatT_Vrth,GAMMatT_xvar3,VOatT,VOatT_xvar1; +double VOatT_Vrth,xvar1_VBBEatT,xvar1_NBBEatT,xvar1_Vtv,EBBEatT,EBBEatT_xvar1,EBBEatT_Vrth; +double IVEF,IVER,IIKF,IIKF_IKFatT,IIKF_Vrth,IIKR,IIKP; +double IVO,IVO_VOatT,IVO_Vrth,IHRCF,IVTF,IITF,slTF; +double LEP,CEP,dv0,dv0_PEatT,dv0_Vrth,dvh,dvh_Vbei; +double dvh_dv0,dvh_Vrth,pwq,qlo,qlo_PEatT,qlo_Vrth,qlo_Vbei; +double qhi,qhi_dvh,qhi_Vbei,qhi_Vrth,qhi_PEatT,xvar1_Vbei,xvar3_xvar1; +double xvar3_Vbei,qlo_xvar3,qdbe,qdbe_qlo,qdbe_Vrth,qdbe_Vbei,qdbe_qhi; +double mv0,mv0_dv0,mv0_Vrth,vl0,vl0_dv0,vl0_Vrth,vl0_mv0; +double xvar1_vl0,q0,q0_PEatT,q0_Vrth,q0_xvar3,dv,dv_Vbei; +double dv_dv0,dv_Vrth,mv,mv_dv,mv_Vbei,mv_Vrth,vl; +double vl_dv,vl_Vbei,vl_Vrth,vl_mv,vl_dv0,xvar1_vl,qdbe_vl; +double qdbe_vl0,qdbe_q0,dvh_Vbex,qlo_Vbex,qhi_Vbex,xvar1_Vbex,xvar3_Vbex; +double qdbex,qdbex_qlo,qdbex_Vrth,qdbex_Vbex,qdbex_qhi,dv_Vbex,mv_Vbex; +double vl_Vbex,qdbex_vl,qdbex_vl0,qdbex_q0,dv0_PCatT,dvh_Vbci,qlo_PCatT; +double qlo_Vbci,qhi_Vbci,qhi_PCatT,xvar1_Vbci,xvar3_Vbci,qdbc,qdbc_qlo; +double qdbc_Vrth,qdbc_Vbci,qdbc_qhi,vn0,vn0_dv0,vn0_Vrth,vnl0; +double vnl0_vn0,vnl0_Vrth,vl0_vnl0,qlo0,qlo0_PCatT,qlo0_Vrth,qlo0_xvar3; +double vn,vn_Vbci,vn_dv0,vn_Vrth,vnl,vnl_vn,vnl_Vbci; +double vnl_Vrth,vl_vnl,vl_Vbci,sel,sel_vnl,sel_Vbci,sel_Vrth; +double crt,crt_xvar1,crt_Vrth,xvar1_dv0,cmx,cmx_xvar1,cmx_Vrth; +double cl,cl_sel,cl_Vbci,cl_Vrth,cl_crt,cl_cmx,ql; +double ql_Vbci,ql_vl,ql_Vrth,ql_vl0,ql_cl,qdbc_ql,qdbc_qlo0; +double q0_PCatT,dv_Vbci,mv_Vbci,qdbc_vl,qdbc_vl0,qdbc_q0,dvh_Vbep; +double qlo_Vbep,qhi_Vbep,xvar1_Vbep,xvar3_Vbep,qdbep,qdbep_qlo,qdbep_Vrth; +double qdbep_Vbep,qdbep_qhi,vn_Vbep,vnl_Vbep,vl_Vbep,sel_Vbep,cl_Vbep; +double ql_Vbep,qdbep_ql,qdbep_qlo0,dv_Vbep,mv_Vbep,qdbep_vl,qdbep_vl0; +double qdbep_q0,dv0_PSatT,dvh_Vbcp,qlo_PSatT,qlo_Vbcp,qhi_Vbcp,qhi_PSatT; +double xvar1_Vbcp,xvar3_Vbcp,qdbcp,qdbcp_qlo,qdbcp_Vrth,qdbcp_Vbcp,qdbcp_Vbep; +double qdbcp_qhi,q0_PSatT,dv_Vbcp,mv_Vbcp,vl_Vbcp,qdbcp_vl,qdbcp_vl0; +double qdbcp_q0,argi,argi_Vbei,argi_NFatT,argi_Vrth,argi_Vtv,expi; +double expi_argi,expi_Vbei,expi_Vrth,Ifi,Ifi_ISatT,Ifi_Vrth,Ifi_expi; +double Ifi_Vbei,argi_Vbci,argi_NRatT,expi_Vbci,Iri,Iri_ISatT,Iri_Vrth; +double Iri_ISRRatT,Iri_expi,Iri_Vbci,q1z,q1z_qdbe,q1z_Vrth,q1z_Vbei; +double q1z_qdbc,q1z_Vbci,q1,q1_q1z,q1_Vrth,q1_Vbei,q1_Vbci; +double q2,q2_Ifi,q2_Vrth,q2_Vbei,q2_IIKF,q2_Iri,q2_Vbci; +double xvar3_q1,xvar1_q2,xvar4_Vbei,xvar4_Vbci,qb,qb_q1,qb_Vrth; +double qb_Vbei,qb_Vbci,qb_xvar4,xvar2_Vbei,xvar2_Vbci,qb_xvar2,Itzr_Iri; +double Itzr_qb,Itzf,Itzf_Ifi,Itzf_Vrth,Itzf_Vbei,Itzf_qb,Itzf_Vbci; +double Ixzf_Itzf,argi_Vbep,expi_Vbep,argx,argx_Vbci,argx_Vtv,argx_Vrth; +double expx,expx_argx,expx_Vbci,expx_Vrth,Ifp,Ifp_ISPatT,Ifp_Vrth; +double Ifp_expi,Ifp_Vbep,Ifp_expx,Ifp_Vbci,q2p,q2p_Ifp,q2p_Vrth; +double q2p_Vbep,q2p_Vbci,qbp,qbp_q2p,qbp_Vrth,qbp_Vbep,qbp_Vbci; +double argi_Vbcp,expi_Vbcp,Irp,Irp_ISPatT,Irp_Vrth,Irp_expi,Irp_Vbcp; +double Iccp_Ifp,Iccp_Irp,Iccp_qbp,argn,argn_Vbei,argn_Vtv,argn_Vrth; +double expn,expn_argn,expn_Vbei,expn_Vrth,argx_VBBEatT,argx_Vbei,argx_NBBEatT; +double expx_Vbei,Ibe_IBEIatT,Ibe_expi,Ibe_IBENatT,Ibe_expn,Ibe_expx,Ibe_EBBEatT; +double argi_Vbex,expi_Vbex,argn_Vbex,expn_Vbex,argx_Vbex,expx_Vbex,Ibex_IBEIatT; +double Ibex_expi,Ibex_IBENatT,Ibex_expn,Ibex_expx,Ibex_EBBEatT,argn_Vbci,expn_Vbci; +double Ibcj,Ibcj_IBCIatT,Ibcj_Vrth,Ibcj_expi,Ibcj_Vbci,Ibcj_IBCNatT,Ibcj_expn; +double argn_Vbep,expn_Vbep,Ibep_IBEIPatT,Ibep_expi,Ibep_IBENPatT,Ibep_expn,vl_PCatT; +double xvar3_vl,xvar1_AVC2atT,avalf,avalf_vl,avalf_Vrth,avalf_Vbci,avalf_xvar4; +double Igc,Igc_Itxf,Igc_Vrxf,Igc_Itzr,Igc_Vrth,Igc_Vbci,Igc_Vbei; +double Igc_Ibcj,Igc_avalf,Ibc_Ibcj,Ibc_Igc,Ircx_RCXatT,argx_Vbcx,expx_Vbcx; +double Kbci,Kbci_GAMMatT,Kbci_Vrth,Kbci_expi,Kbci_Vbci,Kbcx,Kbcx_GAMMatT; +double Kbcx_Vrth,Kbcx_expx,Kbcx_Vbcx,rKp1,rKp1_Kbci,rKp1_Vrth,rKp1_Vbci; +double rKp1_Kbcx,rKp1_Vbcx,xvar1_rKp1,xvar1_Vbcx,Iohm,Iohm_Vrci,Iohm_Vtv; +double Iohm_Vrth,Iohm_Kbci,Iohm_Vbci,Iohm_Kbcx,Iohm_Vbcx,Iohm_xvar1,Iohm_RCIatT; +double derf,derf_IVO,derf_Vrth,derf_RCIatT,derf_Iohm,derf_Vrci,derf_Vbci; +double derf_Vbcx,Irci_Iohm,Irci_derf,Irbx_RBXatT,Irbi_qb,Irbi_RBIatT,Ire_REatT; +double Irbp_qbp,Irbp_RBPatT,argn_Vbcp,expn_Vbcp,Ibcp_IBCIPatT,Ibcp_expi,Ibcp_IBCNPatT; +double Ibcp_expn,Irs_RSatT,sgIf,rIf,rIf_Ifi,rIf_Vrth,rIf_Vbei; +double mIf,mIf_rIf,mIf_Vrth,mIf_Vbei,tff,tff_q1,tff_Vrth; +double tff_Vbei,tff_Vbci,tff_xvar2,tff_mIf,Qbe_CJEatT,Qbe_qdbe,Qbe_tff; +double Qbe_Ifi,Qbe_qb,Qbex_CJEatT,Qbex_qdbex,Qbc_CJCatT,Qbc_qdbc,Qbc_Iri; +double Qbc_Kbci,Qbcx_Kbcx,Qbep_CJEPatT,Qbep_qdbep,Qbep_Ifp,Qbcp_CJCPatT,Qbcp_qdbcp; +double Ith_Ibe,Ith_Ibc,Ith_Itxf,Ith_Itzr,Ith_Ibex,Ith_Ibep,Ith_Irs; +double Ith_Ibcp,Ith_Iccp,Ith_Ircx,Ith_Irci,Ith_Irbx,Ith_Irbi,Ith_Ire; +double Ith_Irbp,Flxf_Ixxf; /* Function and derivative code */ - Vtv=1.380662e-23*(2.731500e+02+p[0])/1.602189e-19; + Tini=2.731500e+02+p[0]; + Tdev=(2.731500e+02+p[0])+(*Vrth); + Tdev_Vrth=1.0; + Vtv=1.380662e-23*Tdev/1.602189e-19; + Vtv_Tdev=8.617347e-5; + Vtv_Vrth=Vtv_Tdev*Tdev_Vrth; + rT=Tdev/Tini; + rT_Tdev=1.0/Tini; + rT_Vrth=rT_Tdev*Tdev_Vrth; + dT=Tdev-Tini; + dT_Tdev=1.0; + dT_Vrth=dT_Tdev*Tdev_Vrth; + xvar1=pow(rT,p[90]); + xvar1_rT=xvar1*p[90]/rT; + xvar1_Vrth=xvar1_rT*rT_Vrth; + IKFatT=p[53]*xvar1; + IKFatT_xvar1=p[53]; + IKFatT_Vrth=IKFatT_xvar1*xvar1_Vrth; + xvar1=pow(rT,p[91]); + xvar1_rT=xvar1*p[91]/rT; + xvar1_Vrth=xvar1_rT*rT_Vrth; + RCXatT=p[1]*xvar1; + RCXatT_xvar1=p[1]; + RCXatT_Vrth=RCXatT_xvar1*xvar1_Vrth; + xvar1=pow(rT,p[68]); + xvar1_rT=xvar1*p[68]/rT; + xvar1_Vrth=xvar1_rT*rT_Vrth; + RCIatT=p[2]*xvar1; + RCIatT_xvar1=p[2]; + RCIatT_Vrth=RCIatT_xvar1*xvar1_Vrth; + xvar1=pow(rT,p[92]); + xvar1_rT=xvar1*p[92]/rT; + xvar1_Vrth=xvar1_rT*rT_Vrth; + RBXatT=p[6]*xvar1; + RBXatT_xvar1=p[6]; + RBXatT_Vrth=RBXatT_xvar1*xvar1_Vrth; + xvar1=pow(rT,p[67]); + xvar1_rT=xvar1*p[67]/rT; + xvar1_Vrth=xvar1_rT*rT_Vrth; + RBIatT=p[7]*xvar1; + RBIatT_xvar1=p[7]; + RBIatT_Vrth=RBIatT_xvar1*xvar1_Vrth; + xvar1=pow(rT,p[66]); + xvar1_rT=xvar1*p[66]/rT; + xvar1_Vrth=xvar1_rT*rT_Vrth; + REatT=p[8]*xvar1; + REatT_xvar1=p[8]; + REatT_Vrth=REatT_xvar1*xvar1_Vrth; + xvar1=pow(rT,p[69]); + xvar1_rT=xvar1*p[69]/rT; + xvar1_Vrth=xvar1_rT*rT_Vrth; + RSatT=p[9]*xvar1; + RSatT_xvar1=p[9]; + RSatT_Vrth=RSatT_xvar1*xvar1_Vrth; + xvar1=pow(rT,p[93]); + xvar1_rT=xvar1*p[93]/rT; + xvar1_Vrth=xvar1_rT*rT_Vrth; + RBPatT=p[10]*xvar1; + RBPatT_xvar1=p[10]; + RBPatT_Vrth=RBPatT_xvar1*xvar1_Vrth; + xvar2=pow(rT,p[78]); + xvar2_rT=xvar2*p[78]/rT; + xvar2_Vrth=xvar2_rT*rT_Vrth; + xvar3=-p[71]*(1.0-rT)/Vtv; + xvar3_rT=p[71]/Vtv; + xvar3_Vtv=p[71]*(1.0-rT)/(Vtv*Vtv); + xvar3_Vrth=xvar3_rT*rT_Vrth; + xvar3_Vrth=xvar3_Vrth+xvar3_Vtv*Vtv_Vrth; + xvar4=exp(xvar3); + xvar4_xvar3=xvar4; + xvar4_Vrth=xvar4_xvar3*xvar3_Vrth; + xvar1=(xvar2*xvar4); + xvar1_xvar2=xvar4; + xvar1_xvar4=xvar2; + xvar1_Vrth=xvar1_xvar2*xvar2_Vrth; + xvar1_Vrth=xvar1_Vrth+xvar1_xvar4*xvar4_Vrth; + xvar5=(1.0/p[12]); + xvar6=pow(xvar1,xvar5); + xvar6_xvar1=xvar6*xvar5/xvar1; + xvar6_Vrth=xvar6_xvar1*xvar1_Vrth; + ISatT=p[11]*xvar6; + ISatT_xvar6=p[11]; + ISatT_Vrth=ISatT_xvar6*xvar6_Vrth; + xvar2=pow(rT,p[95]); + xvar2_rT=xvar2*p[95]/rT; + xvar2_Vrth=xvar2_rT*rT_Vrth; + xvar3=-p[96]*(1.0-rT)/Vtv; + xvar3_rT=p[96]/Vtv; + xvar3_Vtv=p[96]*(1.0-rT)/(Vtv*Vtv); + xvar3_Vrth=xvar3_rT*rT_Vrth; + xvar3_Vrth=xvar3_Vrth+xvar3_Vtv*Vtv_Vrth; + xvar4=exp(xvar3); + xvar4_xvar3=xvar4; + xvar4_Vrth=xvar4_xvar3*xvar3_Vrth; + xvar1=(xvar2*xvar4); + xvar1_xvar2=xvar4; + xvar1_xvar4=xvar2; + xvar1_Vrth=xvar1_xvar2*xvar2_Vrth; + xvar1_Vrth=xvar1_Vrth+xvar1_xvar4*xvar4_Vrth; + xvar5=(1.0/p[13]); + xvar6=pow(xvar1,xvar5); + xvar6_xvar1=xvar6*xvar5/xvar1; + xvar6_Vrth=xvar6_xvar1*xvar1_Vrth; + ISRRatT=p[94]*xvar6; + ISRRatT_xvar6=p[94]; + ISRRatT_Vrth=ISRRatT_xvar6*xvar6_Vrth; + xvar2=pow(rT,p[78]); + xvar2_rT=xvar2*p[78]/rT; + xvar2_Vrth=xvar2_rT*rT_Vrth; + xvar3=-p[97]*(1.0-rT)/Vtv; + xvar3_rT=p[97]/Vtv; + xvar3_Vtv=p[97]*(1.0-rT)/(Vtv*Vtv); + xvar3_Vrth=xvar3_rT*rT_Vrth; + xvar3_Vrth=xvar3_Vrth+xvar3_Vtv*Vtv_Vrth; + xvar4=exp(xvar3); + xvar4_xvar3=xvar4; + xvar4_Vrth=xvar4_xvar3*xvar3_Vrth; + xvar1=(xvar2*xvar4); + xvar1_xvar2=xvar4; + xvar1_xvar4=xvar2; + xvar1_Vrth=xvar1_xvar2*xvar2_Vrth; + xvar1_Vrth=xvar1_Vrth+xvar1_xvar4*xvar4_Vrth; + xvar5=(1.0/p[44]); + xvar6=pow(xvar1,xvar5); + xvar6_xvar1=xvar6*xvar5/xvar1; + xvar6_Vrth=xvar6_xvar1*xvar1_Vrth; + ISPatT=p[42]*xvar6; + ISPatT_xvar6=p[42]; + ISPatT_Vrth=ISPatT_xvar6*xvar6_Vrth; + xvar2=pow(rT,p[79]); + xvar2_rT=xvar2*p[79]/rT; + xvar2_Vrth=xvar2_rT*rT_Vrth; + xvar3=-p[72]*(1.0-rT)/Vtv; + xvar3_rT=p[72]/Vtv; + xvar3_Vtv=p[72]*(1.0-rT)/(Vtv*Vtv); + xvar3_Vrth=xvar3_rT*rT_Vrth; + xvar3_Vrth=xvar3_Vrth+xvar3_Vtv*Vtv_Vrth; + xvar4=exp(xvar3); + xvar4_xvar3=xvar4; + xvar4_Vrth=xvar4_xvar3*xvar3_Vrth; + xvar1=(xvar2*xvar4); + xvar1_xvar2=xvar4; + xvar1_xvar4=xvar2; + xvar1_Vrth=xvar1_xvar2*xvar2_Vrth; + xvar1_Vrth=xvar1_Vrth+xvar1_xvar4*xvar4_Vrth; + xvar5=(1.0/p[33]); + xvar6=pow(xvar1,xvar5); + xvar6_xvar1=xvar6*xvar5/xvar1; + xvar6_Vrth=xvar6_xvar1*xvar1_Vrth; + IBEIatT=p[31]*xvar6; + IBEIatT_xvar6=p[31]; + IBEIatT_Vrth=IBEIatT_xvar6*xvar6_Vrth; + xvar2=pow(rT,p[80]); + xvar2_rT=xvar2*p[80]/rT; + xvar2_Vrth=xvar2_rT*rT_Vrth; + xvar3=-p[75]*(1.0-rT)/Vtv; + xvar3_rT=p[75]/Vtv; + xvar3_Vtv=p[75]*(1.0-rT)/(Vtv*Vtv); + xvar3_Vrth=xvar3_rT*rT_Vrth; + xvar3_Vrth=xvar3_Vrth+xvar3_Vtv*Vtv_Vrth; + xvar4=exp(xvar3); + xvar4_xvar3=xvar4; + xvar4_Vrth=xvar4_xvar3*xvar3_Vrth; + xvar1=(xvar2*xvar4); + xvar1_xvar2=xvar4; + xvar1_xvar4=xvar2; + xvar1_Vrth=xvar1_xvar2*xvar2_Vrth; + xvar1_Vrth=xvar1_Vrth+xvar1_xvar4*xvar4_Vrth; + xvar5=(1.0/p[35]); + xvar6=pow(xvar1,xvar5); + xvar6_xvar1=xvar6*xvar5/xvar1; + xvar6_Vrth=xvar6_xvar1*xvar1_Vrth; + IBENatT=p[34]*xvar6; + IBENatT_xvar6=p[34]; + IBENatT_Vrth=IBENatT_xvar6*xvar6_Vrth; + xvar2=pow(rT,p[79]); + xvar2_rT=xvar2*p[79]/rT; + xvar2_Vrth=xvar2_rT*rT_Vrth; + xvar3=-p[73]*(1.0-rT)/Vtv; + xvar3_rT=p[73]/Vtv; + xvar3_Vtv=p[73]*(1.0-rT)/(Vtv*Vtv); + xvar3_Vrth=xvar3_rT*rT_Vrth; + xvar3_Vrth=xvar3_Vrth+xvar3_Vtv*Vtv_Vrth; + xvar4=exp(xvar3); + xvar4_xvar3=xvar4; + xvar4_Vrth=xvar4_xvar3*xvar3_Vrth; + xvar1=(xvar2*xvar4); + xvar1_xvar2=xvar4; + xvar1_xvar4=xvar2; + xvar1_Vrth=xvar1_xvar2*xvar2_Vrth; + xvar1_Vrth=xvar1_Vrth+xvar1_xvar4*xvar4_Vrth; + xvar5=(1.0/p[37]); + xvar6=pow(xvar1,xvar5); + xvar6_xvar1=xvar6*xvar5/xvar1; + xvar6_Vrth=xvar6_xvar1*xvar1_Vrth; + IBCIatT=p[36]*xvar6; + IBCIatT_xvar6=p[36]; + IBCIatT_Vrth=IBCIatT_xvar6*xvar6_Vrth; + xvar2=pow(rT,p[80]); + xvar2_rT=xvar2*p[80]/rT; + xvar2_Vrth=xvar2_rT*rT_Vrth; + xvar3=-p[76]*(1.0-rT)/Vtv; + xvar3_rT=p[76]/Vtv; + xvar3_Vtv=p[76]*(1.0-rT)/(Vtv*Vtv); + xvar3_Vrth=xvar3_rT*rT_Vrth; + xvar3_Vrth=xvar3_Vrth+xvar3_Vtv*Vtv_Vrth; + xvar4=exp(xvar3); + xvar4_xvar3=xvar4; + xvar4_Vrth=xvar4_xvar3*xvar3_Vrth; + xvar1=(xvar2*xvar4); + xvar1_xvar2=xvar4; + xvar1_xvar4=xvar2; + xvar1_Vrth=xvar1_xvar2*xvar2_Vrth; + xvar1_Vrth=xvar1_Vrth+xvar1_xvar4*xvar4_Vrth; + xvar5=(1.0/p[39]); + xvar6=pow(xvar1,xvar5); + xvar6_xvar1=xvar6*xvar5/xvar1; + xvar6_Vrth=xvar6_xvar1*xvar1_Vrth; + IBCNatT=p[38]*xvar6; + IBCNatT_xvar6=p[38]; + IBCNatT_Vrth=IBCNatT_xvar6*xvar6_Vrth; + xvar2=pow(rT,p[79]); + xvar2_rT=xvar2*p[79]/rT; + xvar2_Vrth=xvar2_rT*rT_Vrth; + xvar3=-p[73]*(1.0-rT)/Vtv; + xvar3_rT=p[73]/Vtv; + xvar3_Vtv=p[73]*(1.0-rT)/(Vtv*Vtv); + xvar3_Vrth=xvar3_rT*rT_Vrth; + xvar3_Vrth=xvar3_Vrth+xvar3_Vtv*Vtv_Vrth; + xvar4=exp(xvar3); + xvar4_xvar3=xvar4; + xvar4_Vrth=xvar4_xvar3*xvar3_Vrth; + xvar1=(xvar2*xvar4); + xvar1_xvar2=xvar4; + xvar1_xvar4=xvar2; + xvar1_Vrth=xvar1_xvar2*xvar2_Vrth; + xvar1_Vrth=xvar1_Vrth+xvar1_xvar4*xvar4_Vrth; + xvar5=(1.0/p[37]); + xvar6=pow(xvar1,xvar5); + xvar6_xvar1=xvar6*xvar5/xvar1; + xvar6_Vrth=xvar6_xvar1*xvar1_Vrth; + IBEIPatT=p[45]*xvar6; + IBEIPatT_xvar6=p[45]; + IBEIPatT_Vrth=IBEIPatT_xvar6*xvar6_Vrth; + xvar2=pow(rT,p[80]); + xvar2_rT=xvar2*p[80]/rT; + xvar2_Vrth=xvar2_rT*rT_Vrth; + xvar3=-p[76]*(1.0-rT)/Vtv; + xvar3_rT=p[76]/Vtv; + xvar3_Vtv=p[76]*(1.0-rT)/(Vtv*Vtv); + xvar3_Vrth=xvar3_rT*rT_Vrth; + xvar3_Vrth=xvar3_Vrth+xvar3_Vtv*Vtv_Vrth; + xvar4=exp(xvar3); + xvar4_xvar3=xvar4; + xvar4_Vrth=xvar4_xvar3*xvar3_Vrth; + xvar1=(xvar2*xvar4); + xvar1_xvar2=xvar4; + xvar1_xvar4=xvar2; + xvar1_Vrth=xvar1_xvar2*xvar2_Vrth; + xvar1_Vrth=xvar1_Vrth+xvar1_xvar4*xvar4_Vrth; + xvar5=(1.0/p[39]); + xvar6=pow(xvar1,xvar5); + xvar6_xvar1=xvar6*xvar5/xvar1; + xvar6_Vrth=xvar6_xvar1*xvar1_Vrth; + IBENPatT=p[46]*xvar6; + IBENPatT_xvar6=p[46]; + IBENPatT_Vrth=IBENPatT_xvar6*xvar6_Vrth; + xvar2=pow(rT,p[79]); + xvar2_rT=xvar2*p[79]/rT; + xvar2_Vrth=xvar2_rT*rT_Vrth; + xvar3=-p[74]*(1.0-rT)/Vtv; + xvar3_rT=p[74]/Vtv; + xvar3_Vtv=p[74]*(1.0-rT)/(Vtv*Vtv); + xvar3_Vrth=xvar3_rT*rT_Vrth; + xvar3_Vrth=xvar3_Vrth+xvar3_Vtv*Vtv_Vrth; + xvar4=exp(xvar3); + xvar4_xvar3=xvar4; + xvar4_Vrth=xvar4_xvar3*xvar3_Vrth; + xvar1=(xvar2*xvar4); + xvar1_xvar2=xvar4; + xvar1_xvar4=xvar2; + xvar1_Vrth=xvar1_xvar2*xvar2_Vrth; + xvar1_Vrth=xvar1_Vrth+xvar1_xvar4*xvar4_Vrth; + xvar5=(1.0/p[48]); + xvar6=pow(xvar1,xvar5); + xvar6_xvar1=xvar6*xvar5/xvar1; + xvar6_Vrth=xvar6_xvar1*xvar1_Vrth; + IBCIPatT=p[47]*xvar6; + IBCIPatT_xvar6=p[47]; + IBCIPatT_Vrth=IBCIPatT_xvar6*xvar6_Vrth; + xvar2=pow(rT,p[80]); + xvar2_rT=xvar2*p[80]/rT; + xvar2_Vrth=xvar2_rT*rT_Vrth; + xvar3=-p[77]*(1.0-rT)/Vtv; + xvar3_rT=p[77]/Vtv; + xvar3_Vtv=p[77]*(1.0-rT)/(Vtv*Vtv); + xvar3_Vrth=xvar3_rT*rT_Vrth; + xvar3_Vrth=xvar3_Vrth+xvar3_Vtv*Vtv_Vrth; + xvar4=exp(xvar3); + xvar4_xvar3=xvar4; + xvar4_Vrth=xvar4_xvar3*xvar3_Vrth; + xvar1=(xvar2*xvar4); + xvar1_xvar2=xvar4; + xvar1_xvar4=xvar2; + xvar1_Vrth=xvar1_xvar2*xvar2_Vrth; + xvar1_Vrth=xvar1_Vrth+xvar1_xvar4*xvar4_Vrth; + xvar5=(1.0/p[50]); + xvar6=pow(xvar1,xvar5); + xvar6_xvar1=xvar6*xvar5/xvar1; + xvar6_Vrth=xvar6_xvar1*xvar1_Vrth; + IBCNPatT=p[49]*xvar6; + IBCNPatT_xvar6=p[49]; + IBCNPatT_Vrth=IBCNPatT_xvar6*xvar6_Vrth; + NFatT=p[12]*(1.0+dT*p[81]); + NFatT_dT=p[12]*p[81]; + NFatT_Vrth=NFatT_dT*dT_Vrth; + NRatT=p[13]*(1.0+dT*p[81]); + NRatT_dT=p[13]*p[81]; + NRatT_Vrth=NRatT_dT*dT_Vrth; + AVC2atT=p[41]*(1.0+dT*p[82]); + AVC2atT_dT=p[41]*p[82]; + AVC2atT_Vrth=AVC2atT_dT*dT_Vrth; + VBBEatT=p[98]*(1.0+dT*(p[101]+dT*p[102])); + VBBEatT_dT=(2.0*dT*p[102]+p[101])*p[98]; + VBBEatT_Vrth=VBBEatT_dT*dT_Vrth; + NBBEatT=p[99]*(1.0+dT*p[103]); + NBBEatT_dT=p[99]*p[103]; + NBBEatT_Vrth=NBBEatT_dT*dT_Vrth; + xvar2=0.5*p[17]*rT/Vtv; + xvar2_rT=0.5*p[17]/Vtv; + xvar2_Vtv=-0.5*p[17]*rT/(Vtv*Vtv); + xvar2_Vrth=xvar2_rT*rT_Vrth; + xvar2_Vrth=xvar2_Vrth+xvar2_Vtv*Vtv_Vrth; + xvar3=exp(xvar2); + xvar3_xvar2=xvar3; + xvar3_Vrth=xvar3_xvar2*xvar2_Vrth; + xvar4=-0.5*p[17]*rT/Vtv; + xvar4_rT=-0.5*p[17]/Vtv; + xvar4_Vtv=0.5*p[17]*rT/(Vtv*Vtv); + xvar4_Vrth=xvar4_rT*rT_Vrth; + xvar4_Vrth=xvar4_Vrth+xvar4_Vtv*Vtv_Vrth; + xvar5=exp(xvar4); + xvar5_xvar4=xvar5; + xvar5_Vrth=xvar5_xvar4*xvar4_Vrth; + xvar1=xvar3-xvar5; + xvar1_xvar3=1.0; + xvar1_xvar5=-1.0; + xvar1_Vrth=xvar1_xvar3*xvar3_Vrth; + xvar1_Vrth=xvar1_Vrth+xvar1_xvar5*xvar5_Vrth; + xvar6=log(xvar1); + xvar6_xvar1=1.0/xvar1; + xvar6_Vrth=xvar6_xvar1*xvar1_Vrth; + psiio=2.0*(Vtv/rT)*xvar6; + psiio_Vtv=2.0*xvar6/rT; + psiio_rT=-2.0*Vtv*xvar6/(rT*rT); + psiio_xvar6=2.0*Vtv/rT; + psiio_Vrth=psiio_Vtv*Vtv_Vrth; + psiio_Vrth=psiio_Vrth+psiio_rT*rT_Vrth; + psiio_Vrth=psiio_Vrth+psiio_xvar6*xvar6_Vrth; + xvar1=log(rT); + xvar1_rT=1.0/rT; + xvar1_Vrth=xvar1_rT*rT_Vrth; + psiin=psiio*rT-3.0*Vtv*xvar1-p[72]*(rT-1.0); + psiin_psiio=rT; + psiin_rT=psiio-p[72]; + psiin_Vtv=-3.0*xvar1; + psiin_xvar1=-3.0*Vtv; + psiin_Vrth=psiin_psiio*psiio_Vrth; + psiin_Vrth=psiin_Vrth+psiin_rT*rT_Vrth; + psiin_Vrth=psiin_Vrth+psiin_Vtv*Vtv_Vrth; + psiin_Vrth=psiin_Vrth+psiin_xvar1*xvar1_Vrth; + xvar2=-psiin/Vtv; + xvar2_psiin=-1.0/Vtv; + xvar2_Vtv=psiin/(Vtv*Vtv); + xvar2_Vrth=xvar2_psiin*psiin_Vrth; + xvar2_Vrth=xvar2_Vrth+xvar2_Vtv*Vtv_Vrth; + xvar3=exp(xvar2); + xvar3_xvar2=xvar3; + xvar3_Vrth=xvar3_xvar2*xvar2_Vrth; + xvar1=0.5*(1.0+sqrt(1.0+4.0*xvar3)); + xvar1_xvar3=1.0/sqrt(4.0*xvar3+1.0); + xvar1_Vrth=xvar1_xvar3*xvar3_Vrth; + xvar4=log(xvar1); + xvar4_xvar1=1.0/xvar1; + xvar4_Vrth=xvar4_xvar1*xvar1_Vrth; + PEatT=psiin+2.0*Vtv*xvar4; + PEatT_psiin=1.0; + PEatT_Vtv=2.0*xvar4; + PEatT_xvar4=2.0*Vtv; + PEatT_Vrth=PEatT_psiin*psiin_Vrth; + PEatT_Vrth=PEatT_Vrth+PEatT_Vtv*Vtv_Vrth; + PEatT_Vrth=PEatT_Vrth+PEatT_xvar4*xvar4_Vrth; + xvar2=0.5*p[24]*rT/Vtv; + xvar2_rT=0.5*p[24]/Vtv; + xvar2_Vtv=-0.5*p[24]*rT/(Vtv*Vtv); + xvar2_Vrth=xvar2_rT*rT_Vrth; + xvar2_Vrth=xvar2_Vrth+xvar2_Vtv*Vtv_Vrth; + xvar3=exp(xvar2); + xvar3_xvar2=xvar3; + xvar3_Vrth=xvar3_xvar2*xvar2_Vrth; + xvar4=-0.5*p[24]*rT/Vtv; + xvar4_rT=-0.5*p[24]/Vtv; + xvar4_Vtv=0.5*p[24]*rT/(Vtv*Vtv); + xvar4_Vrth=xvar4_rT*rT_Vrth; + xvar4_Vrth=xvar4_Vrth+xvar4_Vtv*Vtv_Vrth; + xvar5=exp(xvar4); + xvar5_xvar4=xvar5; + xvar5_Vrth=xvar5_xvar4*xvar4_Vrth; + xvar1=xvar3-xvar5; + xvar1_xvar3=1.0; + xvar1_xvar5=-1.0; + xvar1_Vrth=xvar1_xvar3*xvar3_Vrth; + xvar1_Vrth=xvar1_Vrth+xvar1_xvar5*xvar5_Vrth; + xvar6=log(xvar1); + xvar6_xvar1=1.0/xvar1; + xvar6_Vrth=xvar6_xvar1*xvar1_Vrth; + psiio=2.0*(Vtv/rT)*xvar6; + psiio_Vtv=2.0*xvar6/rT; + psiio_rT=-2.0*Vtv*xvar6/(rT*rT); + psiio_xvar6=2.0*Vtv/rT; + psiio_Vrth=psiio_Vtv*Vtv_Vrth; + psiio_Vrth=psiio_Vrth+psiio_rT*rT_Vrth; + psiio_Vrth=psiio_Vrth+psiio_xvar6*xvar6_Vrth; + xvar1=log(rT); + xvar1_rT=1.0/rT; + xvar1_Vrth=xvar1_rT*rT_Vrth; + psiin=psiio*rT-3.0*Vtv*xvar1-p[73]*(rT-1.0); + psiin_psiio=rT; + psiin_rT=psiio-p[73]; + psiin_Vtv=-3.0*xvar1; + psiin_xvar1=-3.0*Vtv; + psiin_Vrth=psiin_psiio*psiio_Vrth; + psiin_Vrth=psiin_Vrth+psiin_rT*rT_Vrth; + psiin_Vrth=psiin_Vrth+psiin_Vtv*Vtv_Vrth; + psiin_Vrth=psiin_Vrth+psiin_xvar1*xvar1_Vrth; + xvar2=-psiin/Vtv; + xvar2_psiin=-1.0/Vtv; + xvar2_Vtv=psiin/(Vtv*Vtv); + xvar2_Vrth=xvar2_psiin*psiin_Vrth; + xvar2_Vrth=xvar2_Vrth+xvar2_Vtv*Vtv_Vrth; + xvar3=exp(xvar2); + xvar3_xvar2=xvar3; + xvar3_Vrth=xvar3_xvar2*xvar2_Vrth; + xvar1=0.5*(1.0+sqrt(1.0+4.0*xvar3)); + xvar1_xvar3=1.0/sqrt(4.0*xvar3+1.0); + xvar1_Vrth=xvar1_xvar3*xvar3_Vrth; + xvar4=log(xvar1); + xvar4_xvar1=1.0/xvar1; + xvar4_Vrth=xvar4_xvar1*xvar1_Vrth; + PCatT=psiin+2.0*Vtv*xvar4; + PCatT_psiin=1.0; + PCatT_Vtv=2.0*xvar4; + PCatT_xvar4=2.0*Vtv; + PCatT_Vrth=PCatT_psiin*psiin_Vrth; + PCatT_Vrth=PCatT_Vrth+PCatT_Vtv*Vtv_Vrth; + PCatT_Vrth=PCatT_Vrth+PCatT_xvar4*xvar4_Vrth; + xvar2=0.5*p[28]*rT/Vtv; + xvar2_rT=0.5*p[28]/Vtv; + xvar2_Vtv=-0.5*p[28]*rT/(Vtv*Vtv); + xvar2_Vrth=xvar2_rT*rT_Vrth; + xvar2_Vrth=xvar2_Vrth+xvar2_Vtv*Vtv_Vrth; + xvar3=exp(xvar2); + xvar3_xvar2=xvar3; + xvar3_Vrth=xvar3_xvar2*xvar2_Vrth; + xvar4=-0.5*p[28]*rT/Vtv; + xvar4_rT=-0.5*p[28]/Vtv; + xvar4_Vtv=0.5*p[28]*rT/(Vtv*Vtv); + xvar4_Vrth=xvar4_rT*rT_Vrth; + xvar4_Vrth=xvar4_Vrth+xvar4_Vtv*Vtv_Vrth; + xvar5=exp(xvar4); + xvar5_xvar4=xvar5; + xvar5_Vrth=xvar5_xvar4*xvar4_Vrth; + xvar1=xvar3-xvar5; + xvar1_xvar3=1.0; + xvar1_xvar5=-1.0; + xvar1_Vrth=xvar1_xvar3*xvar3_Vrth; + xvar1_Vrth=xvar1_Vrth+xvar1_xvar5*xvar5_Vrth; + xvar6=log(xvar1); + xvar6_xvar1=1.0/xvar1; + xvar6_Vrth=xvar6_xvar1*xvar1_Vrth; + psiio=2.0*(Vtv/rT)*xvar6; + psiio_Vtv=2.0*xvar6/rT; + psiio_rT=-2.0*Vtv*xvar6/(rT*rT); + psiio_xvar6=2.0*Vtv/rT; + psiio_Vrth=psiio_Vtv*Vtv_Vrth; + psiio_Vrth=psiio_Vrth+psiio_rT*rT_Vrth; + psiio_Vrth=psiio_Vrth+psiio_xvar6*xvar6_Vrth; + xvar1=log(rT); + xvar1_rT=1.0/rT; + xvar1_Vrth=xvar1_rT*rT_Vrth; + psiin=psiio*rT-3.0*Vtv*xvar1-p[74]*(rT-1.0); + psiin_psiio=rT; + psiin_rT=psiio-p[74]; + psiin_Vtv=-3.0*xvar1; + psiin_xvar1=-3.0*Vtv; + psiin_Vrth=psiin_psiio*psiio_Vrth; + psiin_Vrth=psiin_Vrth+psiin_rT*rT_Vrth; + psiin_Vrth=psiin_Vrth+psiin_Vtv*Vtv_Vrth; + psiin_Vrth=psiin_Vrth+psiin_xvar1*xvar1_Vrth; + xvar2=-psiin/Vtv; + xvar2_psiin=-1.0/Vtv; + xvar2_Vtv=psiin/(Vtv*Vtv); + xvar2_Vrth=xvar2_psiin*psiin_Vrth; + xvar2_Vrth=xvar2_Vrth+xvar2_Vtv*Vtv_Vrth; + xvar3=exp(xvar2); + xvar3_xvar2=xvar3; + xvar3_Vrth=xvar3_xvar2*xvar2_Vrth; + xvar1=0.5*(1.0+sqrt(1.0+4.0*xvar3)); + xvar1_xvar3=1.0/sqrt(4.0*xvar3+1.0); + xvar1_Vrth=xvar1_xvar3*xvar3_Vrth; + xvar4=log(xvar1); + xvar4_xvar1=1.0/xvar1; + xvar4_Vrth=xvar4_xvar1*xvar1_Vrth; + PSatT=psiin+2.0*Vtv*xvar4; + PSatT_psiin=1.0; + PSatT_Vtv=2.0*xvar4; + PSatT_xvar4=2.0*Vtv; + PSatT_Vrth=PSatT_psiin*psiin_Vrth; + PSatT_Vrth=PSatT_Vrth+PSatT_Vtv*Vtv_Vrth; + PSatT_Vrth=PSatT_Vrth+PSatT_xvar4*xvar4_Vrth; + xvar1=p[17]/PEatT; + xvar1_PEatT=-p[17]/(PEatT*PEatT); + xvar1_Vrth=xvar1_PEatT*PEatT_Vrth; + xvar2=pow(xvar1,p[18]); + xvar2_xvar1=xvar2*p[18]/xvar1; + xvar2_Vrth=xvar2_xvar1*xvar1_Vrth; + CJEatT=p[16]*xvar2; + CJEatT_xvar2=p[16]; + CJEatT_Vrth=CJEatT_xvar2*xvar2_Vrth; + xvar1=p[24]/PCatT; + xvar1_PCatT=-p[24]/(PCatT*PCatT); + xvar1_Vrth=xvar1_PCatT*PCatT_Vrth; + xvar2=pow(xvar1,p[25]); + xvar2_xvar1=xvar2*p[25]/xvar1; + xvar2_Vrth=xvar2_xvar1*xvar1_Vrth; + CJCatT=p[21]*xvar2; + CJCatT_xvar2=p[21]; + CJCatT_Vrth=CJCatT_xvar2*xvar2_Vrth; + xvar1=p[24]/PCatT; + xvar1_PCatT=-p[24]/(PCatT*PCatT); + xvar1_Vrth=xvar1_PCatT*PCatT_Vrth; + xvar2=pow(xvar1,p[25]); + xvar2_xvar1=xvar2*p[25]/xvar1; + xvar2_Vrth=xvar2_xvar1*xvar1_Vrth; + CJEPatT=p[23]*xvar2; + CJEPatT_xvar2=p[23]; + CJEPatT_Vrth=CJEPatT_xvar2*xvar2_Vrth; + xvar1=p[28]/PSatT; + xvar1_PSatT=-p[28]/(PSatT*PSatT); + xvar1_Vrth=xvar1_PSatT*PSatT_Vrth; + xvar2=pow(xvar1,p[29]); + xvar2_xvar1=xvar2*p[29]/xvar1; + xvar2_Vrth=xvar2_xvar1*xvar1_Vrth; + CJCPatT=p[27]*xvar2; + CJCPatT_xvar2=p[27]; + CJCPatT_Vrth=CJCPatT_xvar2*xvar2_Vrth; + xvar1=pow(rT,p[78]); + xvar1_rT=xvar1*p[78]/rT; + xvar1_Vrth=xvar1_rT*rT_Vrth; + xvar2=-p[71]*(1.0-rT)/Vtv; + xvar2_rT=p[71]/Vtv; + xvar2_Vtv=p[71]*(1.0-rT)/(Vtv*Vtv); + xvar2_Vrth=xvar2_rT*rT_Vrth; + xvar2_Vrth=xvar2_Vrth+xvar2_Vtv*Vtv_Vrth; + xvar3=exp(xvar2); + xvar3_xvar2=xvar3; + xvar3_Vrth=xvar3_xvar2*xvar2_Vrth; + GAMMatT=p[4]*xvar1*xvar3; + GAMMatT_xvar1=p[4]*xvar3; + GAMMatT_xvar3=p[4]*xvar1; + GAMMatT_Vrth=GAMMatT_xvar1*xvar1_Vrth; + GAMMatT_Vrth=GAMMatT_Vrth+GAMMatT_xvar3*xvar3_Vrth; + xvar1=pow(rT,p[70]); + xvar1_rT=xvar1*p[70]/rT; + xvar1_Vrth=xvar1_rT*rT_Vrth; + VOatT=p[3]*xvar1; + VOatT_xvar1=p[3]; + VOatT_Vrth=VOatT_xvar1*xvar1_Vrth; + xvar1=-VBBEatT/(NBBEatT*Vtv); + xvar1_VBBEatT=-1.0/(NBBEatT*Vtv); + xvar1_NBBEatT=VBBEatT/((NBBEatT*NBBEatT)*Vtv); + xvar1_Vtv=VBBEatT/(NBBEatT*(Vtv*Vtv)); + xvar1_Vrth=xvar1_VBBEatT*VBBEatT_Vrth; + xvar1_Vrth=xvar1_Vrth+xvar1_NBBEatT*NBBEatT_Vrth; + xvar1_Vrth=xvar1_Vrth+xvar1_Vtv*Vtv_Vrth; + EBBEatT=exp(xvar1); + EBBEatT_xvar1=EBBEatT; + EBBEatT_Vrth=EBBEatT_xvar1*xvar1_Vrth; if(p[51]>0.0){ IVEF=1.0/p[51]; }else{ @@ -4009,9 +6128,12 @@ double Qbep_qdbep,Qbep_Ifp,Qbcp_qdbcp; IVER=0.0; } if(p[53]>0.0){ - IIKF=1.0/p[53]; + IIKF=1.0/IKFatT; + IIKF_IKFatT=-1.0/(IKFatT*IKFatT); + IIKF_Vrth=IIKF_IKFatT*IKFatT_Vrth; }else{ IIKF=0.0; + IIKF_Vrth=0.0; } if(p[54]>0.0){ IIKR=1.0/p[54]; @@ -4024,9 +6146,12 @@ double Qbep_qdbep,Qbep_Ifp,Qbcp_qdbcp; IIKP=0.0; } if(p[3]>0.0){ - IVO=1.0/p[3]; + IVO=1.0/VOatT; + IVO_VOatT=-1.0/(VOatT*VOatT); + IVO_Vrth=IVO_VOatT*VOatT_Vrth; }else{ IVO=0.0; + IVO_Vrth=0.0; } if(p[5]>0.0){ IHRCF=1.0/p[5]; @@ -4048,64 +6173,122 @@ double Qbep_qdbep,Qbep_Ifp,Qbcp_qdbcp; }else{ slTF=1.0; } - dv0=-p[17]*p[14]; + if(p[62]>0.0){ + LEP=p[62]/3.0; + }else{ + LEP=0.0; + } + if(p[62]>0.0){ + CEP=p[62]; + }else{ + CEP=0.0; + } + dv0=-PEatT*p[14]; + dv0_PEatT=-p[14]; + dv0_Vrth=dv0_PEatT*PEatT_Vrth; if(p[19]<=0.0){ dvh=(*Vbei)+dv0; dvh_Vbei=1.0; + dvh_dv0=1.0; + dvh_Vrth=dvh_dv0*dv0_Vrth; if(dvh>0.0){ xvar1=(1.0-p[14]); xvar2=(-1.0-p[18]); pwq=pow(xvar1,xvar2); - qlo=p[17]*(1.0-pwq*(1.0-p[14])*(1.0-p[14]))/(1.0-p[18]); + qlo=PEatT*(1.0-pwq*(1.0-p[14])*(1.0-p[14]))/(1.0-p[18]); + qlo_PEatT=(1.0-((1.0-p[14])*(1.0-p[14]))*pwq)/(1.0-p[18]); qlo_Vbei=0.0; - qhi=dvh*(1.0-p[14]+0.5*p[18]*dvh/p[17])*pwq; - qhi_dvh=(0.5*dvh*p[18]/p[17]-p[14]+1.0)*pwq+0.5*dvh*p[18]*pwq/p[17]; + qlo_Vrth=qlo_PEatT*PEatT_Vrth; + qhi=dvh*(1.0-p[14]+0.5*p[18]*dvh/PEatT)*pwq; + qhi_dvh=(0.5*dvh*p[18]/PEatT-p[14]+1.0)*pwq+0.5*dvh*p[18]*pwq/PEatT; + qhi_PEatT=-0.5*(dvh*dvh)*p[18]*pwq/(PEatT*PEatT); qhi_Vbei=qhi_dvh*dvh_Vbei; + qhi_Vrth=qhi_dvh*dvh_Vrth; + qhi_Vrth=qhi_Vrth+qhi_PEatT*PEatT_Vrth; }else{ - xvar1=(1.0-(*Vbei)/p[17]); - xvar1_Vbei=-1.0/p[17]; + xvar1=(1.0-(*Vbei)/PEatT); + xvar1_Vbei=-1.0/PEatT; + xvar1_PEatT=(*Vbei)/(PEatT*PEatT); + xvar1_Vrth=xvar1_PEatT*PEatT_Vrth; xvar2=(1.0-p[18]); xvar3=pow(xvar1,xvar2); xvar3_xvar1=xvar3*xvar2/xvar1; xvar3_Vbei=xvar3_xvar1*xvar1_Vbei; - qlo=p[17]*(1.0-xvar3)/(1.0-p[18]); - qlo_xvar3=-p[17]/(1.0-p[18]); + xvar3_Vrth=xvar3_xvar1*xvar1_Vrth; + qlo=PEatT*(1.0-xvar3)/(1.0-p[18]); + qlo_PEatT=(1.0-xvar3)/(1.0-p[18]); + qlo_xvar3=-PEatT/(1.0-p[18]); + qlo_Vrth=qlo_PEatT*PEatT_Vrth; qlo_Vbei=qlo_xvar3*xvar3_Vbei; + qlo_Vrth=qlo_Vrth+qlo_xvar3*xvar3_Vrth; qhi=0.0; qhi_Vbei=0.0; + qhi_Vrth=0.0; } qdbe=qlo+qhi; qdbe_qlo=1.0; qdbe_qhi=1.0; + qdbe_Vrth=qdbe_qlo*qlo_Vrth; qdbe_Vbei=qdbe_qlo*qlo_Vbei; qdbe_Vbei=qdbe_Vbei+qdbe_qhi*qhi_Vbei; + qdbe_Vrth=qdbe_Vrth+qdbe_qhi*qhi_Vrth; }else{ mv0=sqrt(dv0*dv0+4.0*p[19]*p[19]); + mv0_dv0=dv0/sqrt((dv0*dv0)+4.0*(p[19]*p[19])); + mv0_Vrth=mv0_dv0*dv0_Vrth; vl0=-0.5*(dv0+mv0); - xvar1=(1.0-vl0/p[17]); + vl0_dv0=-0.5; + vl0_mv0=-0.5; + vl0_Vrth=vl0_dv0*dv0_Vrth; + vl0_Vrth=vl0_Vrth+vl0_mv0*mv0_Vrth; + xvar1=(1.0-vl0/PEatT); + xvar1_vl0=-1.0/PEatT; + xvar1_PEatT=vl0/(PEatT*PEatT); + xvar1_Vrth=xvar1_vl0*vl0_Vrth; + xvar1_Vrth=xvar1_Vrth+xvar1_PEatT*PEatT_Vrth; xvar2=(1.0-p[18]); xvar3=pow(xvar1,xvar2); - q0=-p[17]*xvar3/(1.0-p[18]); + xvar3_xvar1=xvar3*xvar2/xvar1; + xvar3_Vrth=xvar3_xvar1*xvar1_Vrth; + q0=-PEatT*xvar3/(1.0-p[18]); + q0_PEatT=-xvar3/(1.0-p[18]); + q0_xvar3=-PEatT/(1.0-p[18]); + q0_Vrth=q0_PEatT*PEatT_Vrth; + q0_Vrth=q0_Vrth+q0_xvar3*xvar3_Vrth; dv=(*Vbei)+dv0; dv_Vbei=1.0; + dv_dv0=1.0; + dv_Vrth=dv_dv0*dv0_Vrth; mv=sqrt(dv*dv+4.0*p[19]*p[19]); mv_dv=dv/sqrt((dv*dv)+4.0*(p[19]*p[19])); mv_Vbei=mv_dv*dv_Vbei; + mv_Vrth=mv_dv*dv_Vrth; vl=0.5*(dv-mv)-dv0; vl_dv=0.5; vl_mv=-0.5; + vl_dv0=-1.0; vl_Vbei=vl_dv*dv_Vbei; + vl_Vrth=vl_dv*dv_Vrth; vl_Vbei=vl_Vbei+vl_mv*mv_Vbei; - xvar1=(1.0-vl/p[17]); - xvar1_vl=-1.0/p[17]; + vl_Vrth=vl_Vrth+vl_mv*mv_Vrth; + vl_Vrth=vl_Vrth+vl_dv0*dv0_Vrth; + xvar1=(1.0-vl/PEatT); + xvar1_vl=-1.0/PEatT; + xvar1_PEatT=vl/(PEatT*PEatT); xvar1_Vbei=xvar1_vl*vl_Vbei; + xvar1_Vrth=xvar1_vl*vl_Vrth; + xvar1_Vrth=xvar1_Vrth+xvar1_PEatT*PEatT_Vrth; xvar2=(1.0-p[18]); xvar3=pow(xvar1,xvar2); xvar3_xvar1=xvar3*xvar2/xvar1; xvar3_Vbei=xvar3_xvar1*xvar1_Vbei; - qlo=-p[17]*xvar3/(1.0-p[18]); - qlo_xvar3=-p[17]/(1.0-p[18]); + xvar3_Vrth=xvar3_xvar1*xvar1_Vrth; + qlo=-PEatT*xvar3/(1.0-p[18]); + qlo_PEatT=-xvar3/(1.0-p[18]); + qlo_xvar3=-PEatT/(1.0-p[18]); + qlo_Vrth=qlo_PEatT*PEatT_Vrth; qlo_Vbei=qlo_xvar3*xvar3_Vbei; + qlo_Vrth=qlo_Vrth+qlo_xvar3*xvar3_Vrth; xvar1=(1.0-p[14]); xvar2=(-p[18]); xvar3=pow(xvar1,xvar2); @@ -4113,67 +6296,121 @@ double Qbep_qdbep,Qbep_Ifp,Qbcp_qdbcp; qdbe_qlo=1.0; qdbe_Vbei=xvar3; qdbe_vl=-xvar3; + qdbe_vl0=xvar3; + qdbe_q0=-1.0; + qdbe_Vrth=qdbe_qlo*qlo_Vrth; qdbe_Vbei=qdbe_Vbei+qdbe_qlo*qlo_Vbei; qdbe_Vbei=qdbe_Vbei+qdbe_vl*vl_Vbei; + qdbe_Vrth=qdbe_Vrth+qdbe_vl*vl_Vrth; + qdbe_Vrth=qdbe_Vrth+qdbe_vl0*vl0_Vrth; + qdbe_Vrth=qdbe_Vrth+qdbe_q0*q0_Vrth; } - dv0=-p[17]*p[14]; + dv0=-PEatT*p[14]; + dv0_PEatT=-p[14]; + dv0_Vrth=dv0_PEatT*PEatT_Vrth; if(p[19]<=0.0){ dvh=(*Vbex)+dv0; dvh_Vbex=1.0; + dvh_dv0=1.0; + dvh_Vrth=dvh_dv0*dv0_Vrth; if(dvh>0.0){ xvar1=(1.0-p[14]); xvar2=(-1.0-p[18]); pwq=pow(xvar1,xvar2); - qlo=p[17]*(1.0-pwq*(1.0-p[14])*(1.0-p[14]))/(1.0-p[18]); + qlo=PEatT*(1.0-pwq*(1.0-p[14])*(1.0-p[14]))/(1.0-p[18]); + qlo_PEatT=(1.0-((1.0-p[14])*(1.0-p[14]))*pwq)/(1.0-p[18]); qlo_Vbex=0.0; - qhi=dvh*(1.0-p[14]+0.5*p[18]*dvh/p[17])*pwq; - qhi_dvh=(0.5*dvh*p[18]/p[17]-p[14]+1.0)*pwq+0.5*dvh*p[18]*pwq/p[17]; + qlo_Vrth=qlo_PEatT*PEatT_Vrth; + qhi=dvh*(1.0-p[14]+0.5*p[18]*dvh/PEatT)*pwq; + qhi_dvh=(0.5*dvh*p[18]/PEatT-p[14]+1.0)*pwq+0.5*dvh*p[18]*pwq/PEatT; + qhi_PEatT=-0.5*(dvh*dvh)*p[18]*pwq/(PEatT*PEatT); qhi_Vbex=qhi_dvh*dvh_Vbex; + qhi_Vrth=qhi_dvh*dvh_Vrth; + qhi_Vrth=qhi_Vrth+qhi_PEatT*PEatT_Vrth; }else{ - xvar1=(1.0-(*Vbex)/p[17]); - xvar1_Vbex=-1.0/p[17]; + xvar1=(1.0-(*Vbex)/PEatT); + xvar1_Vbex=-1.0/PEatT; + xvar1_PEatT=(*Vbex)/(PEatT*PEatT); + xvar1_Vrth=xvar1_PEatT*PEatT_Vrth; xvar2=(1.0-p[18]); xvar3=pow(xvar1,xvar2); xvar3_xvar1=xvar3*xvar2/xvar1; xvar3_Vbex=xvar3_xvar1*xvar1_Vbex; - qlo=p[17]*(1.0-xvar3)/(1.0-p[18]); - qlo_xvar3=-p[17]/(1.0-p[18]); + xvar3_Vrth=xvar3_xvar1*xvar1_Vrth; + qlo=PEatT*(1.0-xvar3)/(1.0-p[18]); + qlo_PEatT=(1.0-xvar3)/(1.0-p[18]); + qlo_xvar3=-PEatT/(1.0-p[18]); + qlo_Vrth=qlo_PEatT*PEatT_Vrth; qlo_Vbex=qlo_xvar3*xvar3_Vbex; + qlo_Vrth=qlo_Vrth+qlo_xvar3*xvar3_Vrth; qhi=0.0; qhi_Vbex=0.0; + qhi_Vrth=0.0; } qdbex=qlo+qhi; qdbex_qlo=1.0; qdbex_qhi=1.0; + qdbex_Vrth=qdbex_qlo*qlo_Vrth; qdbex_Vbex=qdbex_qlo*qlo_Vbex; qdbex_Vbex=qdbex_Vbex+qdbex_qhi*qhi_Vbex; + qdbex_Vrth=qdbex_Vrth+qdbex_qhi*qhi_Vrth; }else{ mv0=sqrt(dv0*dv0+4.0*p[19]*p[19]); + mv0_dv0=dv0/sqrt((dv0*dv0)+4.0*(p[19]*p[19])); + mv0_Vrth=mv0_dv0*dv0_Vrth; vl0=-0.5*(dv0+mv0); - xvar1=(1.0-vl0/p[17]); + vl0_dv0=-0.5; + vl0_mv0=-0.5; + vl0_Vrth=vl0_dv0*dv0_Vrth; + vl0_Vrth=vl0_Vrth+vl0_mv0*mv0_Vrth; + xvar1=(1.0-vl0/PEatT); + xvar1_vl0=-1.0/PEatT; + xvar1_PEatT=vl0/(PEatT*PEatT); + xvar1_Vrth=xvar1_vl0*vl0_Vrth; + xvar1_Vrth=xvar1_Vrth+xvar1_PEatT*PEatT_Vrth; xvar2=(1.0-p[18]); xvar3=pow(xvar1,xvar2); - q0=-p[17]*xvar3/(1.0-p[18]); + xvar3_xvar1=xvar3*xvar2/xvar1; + xvar3_Vrth=xvar3_xvar1*xvar1_Vrth; + q0=-PEatT*xvar3/(1.0-p[18]); + q0_PEatT=-xvar3/(1.0-p[18]); + q0_xvar3=-PEatT/(1.0-p[18]); + q0_Vrth=q0_PEatT*PEatT_Vrth; + q0_Vrth=q0_Vrth+q0_xvar3*xvar3_Vrth; dv=(*Vbex)+dv0; dv_Vbex=1.0; + dv_dv0=1.0; + dv_Vrth=dv_dv0*dv0_Vrth; mv=sqrt(dv*dv+4.0*p[19]*p[19]); mv_dv=dv/sqrt((dv*dv)+4.0*(p[19]*p[19])); mv_Vbex=mv_dv*dv_Vbex; + mv_Vrth=mv_dv*dv_Vrth; vl=0.5*(dv-mv)-dv0; vl_dv=0.5; vl_mv=-0.5; + vl_dv0=-1.0; vl_Vbex=vl_dv*dv_Vbex; + vl_Vrth=vl_dv*dv_Vrth; vl_Vbex=vl_Vbex+vl_mv*mv_Vbex; - xvar1=(1.0-vl/p[17]); - xvar1_vl=-1.0/p[17]; + vl_Vrth=vl_Vrth+vl_mv*mv_Vrth; + vl_Vrth=vl_Vrth+vl_dv0*dv0_Vrth; + xvar1=(1.0-vl/PEatT); + xvar1_vl=-1.0/PEatT; + xvar1_PEatT=vl/(PEatT*PEatT); xvar1_Vbex=xvar1_vl*vl_Vbex; + xvar1_Vrth=xvar1_vl*vl_Vrth; + xvar1_Vrth=xvar1_Vrth+xvar1_PEatT*PEatT_Vrth; xvar2=(1.0-p[18]); xvar3=pow(xvar1,xvar2); xvar3_xvar1=xvar3*xvar2/xvar1; xvar3_Vbex=xvar3_xvar1*xvar1_Vbex; - qlo=-p[17]*xvar3/(1.0-p[18]); - qlo_xvar3=-p[17]/(1.0-p[18]); + xvar3_Vrth=xvar3_xvar1*xvar1_Vrth; + qlo=-PEatT*xvar3/(1.0-p[18]); + qlo_PEatT=-xvar3/(1.0-p[18]); + qlo_xvar3=-PEatT/(1.0-p[18]); + qlo_Vrth=qlo_PEatT*PEatT_Vrth; qlo_Vbex=qlo_xvar3*xvar3_Vbex; + qlo_Vrth=qlo_Vrth+qlo_xvar3*xvar3_Vrth; xvar1=(1.0-p[14]); xvar2=(-p[18]); xvar3=pow(xvar1,xvar2); @@ -4181,125 +6418,242 @@ double Qbep_qdbep,Qbep_Ifp,Qbcp_qdbcp; qdbex_qlo=1.0; qdbex_Vbex=xvar3; qdbex_vl=-xvar3; + qdbex_vl0=xvar3; + qdbex_q0=-1.0; + qdbex_Vrth=qdbex_qlo*qlo_Vrth; qdbex_Vbex=qdbex_Vbex+qdbex_qlo*qlo_Vbex; qdbex_Vbex=qdbex_Vbex+qdbex_vl*vl_Vbex; + qdbex_Vrth=qdbex_Vrth+qdbex_vl*vl_Vrth; + qdbex_Vrth=qdbex_Vrth+qdbex_vl0*vl0_Vrth; + qdbex_Vrth=qdbex_Vrth+qdbex_q0*q0_Vrth; } - dv0=-p[24]*p[14]; + dv0=-PCatT*p[14]; + dv0_PCatT=-p[14]; + dv0_Vrth=dv0_PCatT*PCatT_Vrth; if(p[26]<=0.0){ dvh=(*Vbci)+dv0; dvh_Vbci=1.0; + dvh_dv0=1.0; + dvh_Vrth=dvh_dv0*dv0_Vrth; if(dvh>0.0){ xvar1=(1.0-p[14]); xvar2=(-1.0-p[25]); pwq=pow(xvar1,xvar2); - qlo=p[24]*(1.0-pwq*(1.0-p[14])*(1.0-p[14]))/(1.0-p[25]); + qlo=PCatT*(1.0-pwq*(1.0-p[14])*(1.0-p[14]))/(1.0-p[25]); + qlo_PCatT=(1.0-((1.0-p[14])*(1.0-p[14]))*pwq)/(1.0-p[25]); qlo_Vbci=0.0; - qhi=dvh*(1.0-p[14]+0.5*p[25]*dvh/p[24])*pwq; - qhi_dvh=(0.5*dvh*p[25]/p[24]-p[14]+1.0)*pwq+0.5*dvh*p[25]*pwq/p[24]; + qlo_Vrth=qlo_PCatT*PCatT_Vrth; + qhi=dvh*(1.0-p[14]+0.5*p[25]*dvh/PCatT)*pwq; + qhi_dvh=(0.5*dvh*p[25]/PCatT-p[14]+1.0)*pwq+0.5*dvh*p[25]*pwq/PCatT; + qhi_PCatT=-0.5*(dvh*dvh)*p[25]*pwq/(PCatT*PCatT); qhi_Vbci=qhi_dvh*dvh_Vbci; + qhi_Vrth=qhi_dvh*dvh_Vrth; + qhi_Vrth=qhi_Vrth+qhi_PCatT*PCatT_Vrth; }else{ if((p[85]>0.0)&&((*Vbci)<-p[85])){ - xvar1=(1.0+p[85]/p[24]); + xvar1=(1.0+p[85]/PCatT); + xvar1_PCatT=-p[85]/(PCatT*PCatT); + xvar1_Vrth=xvar1_PCatT*PCatT_Vrth; xvar2=(1.0-p[25]); xvar3=pow(xvar1,xvar2); - qlo=p[24]*(1.0-xvar3*(1.0-((1.0-p[25])*((*Vbci)+p[85]))/(p[24]+p[85])))/(1.0-p[25]); - qlo_Vbci=p[24]*xvar3/(p[85]+p[24]); + xvar3_xvar1=xvar3*xvar2/xvar1; + xvar3_Vrth=xvar3_xvar1*xvar1_Vrth; + qlo=PCatT*(1.0-xvar3*(1.0-((1.0-p[25])*((*Vbci)+p[85]))/(PCatT+p[85])))/(1.0-p[25]); + qlo_PCatT=(1.0-(1.0-(1.0-p[25])*(p[85]+(*Vbci))/(p[85]+PCatT))*xvar3)/(1.0-p[25])-PCatT*(p[85]+(*Vbci))*xvar3/((p[85]+PCatT)*(p[85]+PCatT)); + qlo_xvar3=PCatT*((1.0-p[25])*(p[85]+(*Vbci))/(p[85]+PCatT)-1.0)/(1.0-p[25]); + qlo_Vbci=PCatT*xvar3/(p[85]+PCatT); + qlo_Vrth=qlo_PCatT*PCatT_Vrth; + qlo_Vrth=qlo_Vrth+qlo_xvar3*xvar3_Vrth; }else{ - xvar1=(1.0-(*Vbci)/p[24]); - xvar1_Vbci=-1.0/p[24]; + xvar1=(1.0-(*Vbci)/PCatT); + xvar1_Vbci=-1.0/PCatT; + xvar1_PCatT=(*Vbci)/(PCatT*PCatT); + xvar1_Vrth=xvar1_PCatT*PCatT_Vrth; xvar2=(1.0-p[25]); xvar3=pow(xvar1,xvar2); xvar3_xvar1=xvar3*xvar2/xvar1; xvar3_Vbci=xvar3_xvar1*xvar1_Vbci; - qlo=p[24]*(1.0-xvar3)/(1.0-p[25]); - qlo_xvar3=-p[24]/(1.0-p[25]); + xvar3_Vrth=xvar3_xvar1*xvar1_Vrth; + qlo=PCatT*(1.0-xvar3)/(1.0-p[25]); + qlo_PCatT=(1.0-xvar3)/(1.0-p[25]); + qlo_xvar3=-PCatT/(1.0-p[25]); + qlo_Vrth=qlo_PCatT*PCatT_Vrth; qlo_Vbci=qlo_xvar3*xvar3_Vbci; + qlo_Vrth=qlo_Vrth+qlo_xvar3*xvar3_Vrth; } qhi=0.0; qhi_Vbci=0.0; + qhi_Vrth=0.0; } qdbc=qlo+qhi; qdbc_qlo=1.0; qdbc_qhi=1.0; + qdbc_Vrth=qdbc_qlo*qlo_Vrth; qdbc_Vbci=qdbc_qlo*qlo_Vbci; qdbc_Vbci=qdbc_Vbci+qdbc_qhi*qhi_Vbci; + qdbc_Vrth=qdbc_Vrth+qdbc_qhi*qhi_Vrth; }else{ if((p[85]>0.0)&&(p[86]>0.0)){ vn0=(p[85]+dv0)/(p[85]-dv0); + vn0_dv0=(p[85]+dv0)/((p[85]-dv0)*(p[85]-dv0))+1.0/(p[85]-dv0); + vn0_Vrth=vn0_dv0*dv0_Vrth; vnl0=2.0*vn0/(sqrt((vn0-1.0)*(vn0-1.0)+4.0*p[26]*p[26])+sqrt((vn0+1.0)*(vn0+1.0)+4.0*p[86]*p[86])); + vnl0_vn0=2.0/(sqrt(((vn0+1.0)*(vn0+1.0))+4.0*(p[86]*p[86]))+sqrt(((vn0-1.0)*(vn0-1.0))+4.0*(p[26]*p[26])))-2.0*vn0*((vn0+1.0)/sqrt(((vn0+1.0)*(vn0+1.0))+4.0*(p[86]*p[86]))+(vn0-1.0)/sqrt(((vn0-1.0)*(vn0-1.0))+4.0*(p[26]*p[26])))/((sqrt(((vn0+1.0)*(vn0+1.0))+4.0*(p[86]*p[86]))+sqrt(((vn0-1.0)*(vn0-1.0))+4.0*(p[26]*p[26])))*(sqrt(((vn0+1.0)*(vn0+1.0))+4.0*(p[86]*p[86]))+sqrt(((vn0-1.0)*(vn0-1.0))+4.0*(p[26]*p[26])))); + vnl0_Vrth=vnl0_vn0*vn0_Vrth; vl0=0.5*(vnl0*(p[85]-dv0)-p[85]-dv0); - xvar1=(1.0-vl0/p[24]); + vl0_vnl0=0.5*(p[85]-dv0); + vl0_dv0=0.5*(-vnl0-1.0); + vl0_Vrth=vl0_vnl0*vnl0_Vrth; + vl0_Vrth=vl0_Vrth+vl0_dv0*dv0_Vrth; + xvar1=(1.0-vl0/PCatT); + xvar1_vl0=-1.0/PCatT; + xvar1_PCatT=vl0/(PCatT*PCatT); + xvar1_Vrth=xvar1_vl0*vl0_Vrth; + xvar1_Vrth=xvar1_Vrth+xvar1_PCatT*PCatT_Vrth; xvar2=(1.0-p[25]); xvar3=pow(xvar1,xvar2); - qlo0=p[24]*(1.0-xvar3)/(1.0-p[25]); + xvar3_xvar1=xvar3*xvar2/xvar1; + xvar3_Vrth=xvar3_xvar1*xvar1_Vrth; + qlo0=PCatT*(1.0-xvar3)/(1.0-p[25]); + qlo0_PCatT=(1.0-xvar3)/(1.0-p[25]); + qlo0_xvar3=-PCatT/(1.0-p[25]); + qlo0_Vrth=qlo0_PCatT*PCatT_Vrth; + qlo0_Vrth=qlo0_Vrth+qlo0_xvar3*xvar3_Vrth; vn=(2.0*(*Vbci)+p[85]+dv0)/(p[85]-dv0); vn_Vbci=2.0/(p[85]-dv0); + vn_dv0=(p[85]+2.0*(*Vbci)+dv0)/((p[85]-dv0)*(p[85]-dv0))+1.0/(p[85]-dv0); + vn_Vrth=vn_dv0*dv0_Vrth; vnl=2.0*vn/(sqrt((vn-1.0)*(vn-1.0)+4.0*p[26]*p[26])+sqrt((vn+1.0)*(vn+1.0)+4.0*p[86]*p[86])); vnl_vn=2.0/(sqrt(((vn+1.0)*(vn+1.0))+4.0*(p[86]*p[86]))+sqrt(((vn-1.0)*(vn-1.0))+4.0*(p[26]*p[26])))-2.0*vn*((vn+1.0)/sqrt(((vn+1.0)*(vn+1.0))+4.0*(p[86]*p[86]))+(vn-1.0)/sqrt(((vn-1.0)*(vn-1.0))+4.0*(p[26]*p[26])))/((sqrt(((vn+1.0)*(vn+1.0))+4.0*(p[86]*p[86]))+sqrt(((vn-1.0)*(vn-1.0))+4.0*(p[26]*p[26])))*(sqrt(((vn+1.0)*(vn+1.0))+4.0*(p[86]*p[86]))+sqrt(((vn-1.0)*(vn-1.0))+4.0*(p[26]*p[26])))); vnl_Vbci=vnl_vn*vn_Vbci; + vnl_Vrth=vnl_vn*vn_Vrth; vl=0.5*(vnl*(p[85]-dv0)-p[85]-dv0); vl_vnl=0.5*(p[85]-dv0); + vl_dv0=0.5*(-vnl-1.0); vl_Vbci=vl_vnl*vnl_Vbci; - xvar1=(1.0-vl/p[24]); - xvar1_vl=-1.0/p[24]; + vl_Vrth=vl_vnl*vnl_Vrth; + vl_Vrth=vl_Vrth+vl_dv0*dv0_Vrth; + xvar1=(1.0-vl/PCatT); + xvar1_vl=-1.0/PCatT; + xvar1_PCatT=vl/(PCatT*PCatT); xvar1_Vbci=xvar1_vl*vl_Vbci; + xvar1_Vrth=xvar1_vl*vl_Vrth; + xvar1_Vrth=xvar1_Vrth+xvar1_PCatT*PCatT_Vrth; xvar2=(1.0-p[25]); xvar3=pow(xvar1,xvar2); xvar3_xvar1=xvar3*xvar2/xvar1; xvar3_Vbci=xvar3_xvar1*xvar1_Vbci; - qlo=p[24]*(1.0-xvar3)/(1.0-p[25]); - qlo_xvar3=-p[24]/(1.0-p[25]); + xvar3_Vrth=xvar3_xvar1*xvar1_Vrth; + qlo=PCatT*(1.0-xvar3)/(1.0-p[25]); + qlo_PCatT=(1.0-xvar3)/(1.0-p[25]); + qlo_xvar3=-PCatT/(1.0-p[25]); + qlo_Vrth=qlo_PCatT*PCatT_Vrth; qlo_Vbci=qlo_xvar3*xvar3_Vbci; + qlo_Vrth=qlo_Vrth+qlo_xvar3*xvar3_Vrth; sel=0.5*(vnl+1.0); sel_vnl=0.5; sel_Vbci=sel_vnl*vnl_Vbci; - xvar1=(1.0+p[85]/p[24]); + sel_Vrth=sel_vnl*vnl_Vrth; + xvar1=(1.0+p[85]/PCatT); + xvar1_PCatT=-p[85]/(PCatT*PCatT); + xvar1_Vrth=xvar1_PCatT*PCatT_Vrth; xvar2=(-p[25]); crt=pow(xvar1,xvar2); - xvar1=(1.0+dv0/p[24]); + crt_xvar1=crt*xvar2/xvar1; + crt_Vrth=crt_xvar1*xvar1_Vrth; + xvar1=(1.0+dv0/PCatT); + xvar1_dv0=1.0/PCatT; + xvar1_PCatT=-dv0/(PCatT*PCatT); + xvar1_Vrth=xvar1_dv0*dv0_Vrth; + xvar1_Vrth=xvar1_Vrth+xvar1_PCatT*PCatT_Vrth; xvar2=(-p[25]); cmx=pow(xvar1,xvar2); + cmx_xvar1=cmx*xvar2/xvar1; + cmx_Vrth=cmx_xvar1*xvar1_Vrth; cl=(1.0-sel)*crt+sel*cmx; cl_sel=cmx-crt; + cl_crt=1.0-sel; + cl_cmx=sel; cl_Vbci=cl_sel*sel_Vbci; + cl_Vrth=cl_sel*sel_Vrth; + cl_Vrth=cl_Vrth+cl_crt*crt_Vrth; + cl_Vrth=cl_Vrth+cl_cmx*cmx_Vrth; ql=((*Vbci)-vl+vl0)*cl; ql_Vbci=cl; ql_vl=-cl; + ql_vl0=cl; ql_cl=vl0-vl+(*Vbci); ql_Vbci=ql_Vbci+ql_vl*vl_Vbci; + ql_Vrth=ql_vl*vl_Vrth; + ql_Vrth=ql_Vrth+ql_vl0*vl0_Vrth; ql_Vbci=ql_Vbci+ql_cl*cl_Vbci; + ql_Vrth=ql_Vrth+ql_cl*cl_Vrth; qdbc=ql+qlo-qlo0; qdbc_ql=1.0; qdbc_qlo=1.0; + qdbc_qlo0=-1.0; qdbc_Vbci=qdbc_ql*ql_Vbci; + qdbc_Vrth=qdbc_ql*ql_Vrth; + qdbc_Vrth=qdbc_Vrth+qdbc_qlo*qlo_Vrth; qdbc_Vbci=qdbc_Vbci+qdbc_qlo*qlo_Vbci; + qdbc_Vrth=qdbc_Vrth+qdbc_qlo0*qlo0_Vrth; }else{ mv0=sqrt(dv0*dv0+4.0*p[26]*p[26]); + mv0_dv0=dv0/sqrt((dv0*dv0)+4.0*(p[26]*p[26])); + mv0_Vrth=mv0_dv0*dv0_Vrth; vl0=-0.5*(dv0+mv0); - xvar1=(1.0-vl0/p[24]); + vl0_dv0=-0.5; + vl0_mv0=-0.5; + vl0_Vrth=vl0_dv0*dv0_Vrth; + vl0_Vrth=vl0_Vrth+vl0_mv0*mv0_Vrth; + xvar1=(1.0-vl0/PCatT); + xvar1_vl0=-1.0/PCatT; + xvar1_PCatT=vl0/(PCatT*PCatT); + xvar1_Vrth=xvar1_vl0*vl0_Vrth; + xvar1_Vrth=xvar1_Vrth+xvar1_PCatT*PCatT_Vrth; xvar2=(1.0-p[25]); xvar3=pow(xvar1,xvar2); - q0=-p[24]*xvar3/(1.0-p[25]); + xvar3_xvar1=xvar3*xvar2/xvar1; + xvar3_Vrth=xvar3_xvar1*xvar1_Vrth; + q0=-PCatT*xvar3/(1.0-p[25]); + q0_PCatT=-xvar3/(1.0-p[25]); + q0_xvar3=-PCatT/(1.0-p[25]); + q0_Vrth=q0_PCatT*PCatT_Vrth; + q0_Vrth=q0_Vrth+q0_xvar3*xvar3_Vrth; dv=(*Vbci)+dv0; dv_Vbci=1.0; + dv_dv0=1.0; + dv_Vrth=dv_dv0*dv0_Vrth; mv=sqrt(dv*dv+4.0*p[26]*p[26]); mv_dv=dv/sqrt((dv*dv)+4.0*(p[26]*p[26])); mv_Vbci=mv_dv*dv_Vbci; + mv_Vrth=mv_dv*dv_Vrth; vl=0.5*(dv-mv)-dv0; vl_dv=0.5; vl_mv=-0.5; + vl_dv0=-1.0; vl_Vbci=vl_dv*dv_Vbci; + vl_Vrth=vl_dv*dv_Vrth; vl_Vbci=vl_Vbci+vl_mv*mv_Vbci; - xvar1=(1.0-vl/p[24]); - xvar1_vl=-1.0/p[24]; + vl_Vrth=vl_Vrth+vl_mv*mv_Vrth; + vl_Vrth=vl_Vrth+vl_dv0*dv0_Vrth; + xvar1=(1.0-vl/PCatT); + xvar1_vl=-1.0/PCatT; + xvar1_PCatT=vl/(PCatT*PCatT); xvar1_Vbci=xvar1_vl*vl_Vbci; + xvar1_Vrth=xvar1_vl*vl_Vrth; + xvar1_Vrth=xvar1_Vrth+xvar1_PCatT*PCatT_Vrth; xvar2=(1.0-p[25]); xvar3=pow(xvar1,xvar2); xvar3_xvar1=xvar3*xvar2/xvar1; xvar3_Vbci=xvar3_xvar1*xvar1_Vbci; - qlo=-p[24]*xvar3/(1.0-p[25]); - qlo_xvar3=-p[24]/(1.0-p[25]); + xvar3_Vrth=xvar3_xvar1*xvar1_Vrth; + qlo=-PCatT*xvar3/(1.0-p[25]); + qlo_PCatT=-xvar3/(1.0-p[25]); + qlo_xvar3=-PCatT/(1.0-p[25]); + qlo_Vrth=qlo_PCatT*PCatT_Vrth; qlo_Vbci=qlo_xvar3*xvar3_Vbci; + qlo_Vrth=qlo_Vrth+qlo_xvar3*xvar3_Vrth; xvar1=(1.0-p[14]); xvar2=(-p[25]); xvar3=pow(xvar1,xvar2); @@ -4307,126 +6661,243 @@ double Qbep_qdbep,Qbep_Ifp,Qbcp_qdbcp; qdbc_qlo=1.0; qdbc_Vbci=xvar3; qdbc_vl=-xvar3; + qdbc_vl0=xvar3; + qdbc_q0=-1.0; + qdbc_Vrth=qdbc_qlo*qlo_Vrth; qdbc_Vbci=qdbc_Vbci+qdbc_qlo*qlo_Vbci; qdbc_Vbci=qdbc_Vbci+qdbc_vl*vl_Vbci; + qdbc_Vrth=qdbc_Vrth+qdbc_vl*vl_Vrth; + qdbc_Vrth=qdbc_Vrth+qdbc_vl0*vl0_Vrth; + qdbc_Vrth=qdbc_Vrth+qdbc_q0*q0_Vrth; } } - dv0=-p[24]*p[14]; + dv0=-PCatT*p[14]; + dv0_PCatT=-p[14]; + dv0_Vrth=dv0_PCatT*PCatT_Vrth; if(p[26]<=0.0){ dvh=(*Vbep)+dv0; dvh_Vbep=1.0; + dvh_dv0=1.0; + dvh_Vrth=dvh_dv0*dv0_Vrth; if(dvh>0.0){ xvar1=(1.0-p[14]); xvar2=(-1.0-p[25]); pwq=pow(xvar1,xvar2); - qlo=p[24]*(1.0-pwq*(1.0-p[14])*(1.0-p[14]))/(1.0-p[25]); + qlo=PCatT*(1.0-pwq*(1.0-p[14])*(1.0-p[14]))/(1.0-p[25]); + qlo_PCatT=(1.0-((1.0-p[14])*(1.0-p[14]))*pwq)/(1.0-p[25]); qlo_Vbep=0.0; - qhi=dvh*(1.0-p[14]+0.5*p[25]*dvh/p[24])*pwq; - qhi_dvh=(0.5*dvh*p[25]/p[24]-p[14]+1.0)*pwq+0.5*dvh*p[25]*pwq/p[24]; + qlo_Vrth=qlo_PCatT*PCatT_Vrth; + qhi=dvh*(1.0-p[14]+0.5*p[25]*dvh/PCatT)*pwq; + qhi_dvh=(0.5*dvh*p[25]/PCatT-p[14]+1.0)*pwq+0.5*dvh*p[25]*pwq/PCatT; + qhi_PCatT=-0.5*(dvh*dvh)*p[25]*pwq/(PCatT*PCatT); qhi_Vbep=qhi_dvh*dvh_Vbep; + qhi_Vrth=qhi_dvh*dvh_Vrth; + qhi_Vrth=qhi_Vrth+qhi_PCatT*PCatT_Vrth; }else{ if((p[85]>0.0)&&((*Vbep)<-p[85])){ - xvar1=(1.0+p[85]/p[24]); + xvar1=(1.0+p[85]/PCatT); + xvar1_PCatT=-p[85]/(PCatT*PCatT); + xvar1_Vrth=xvar1_PCatT*PCatT_Vrth; xvar2=(1.0-p[25]); xvar3=pow(xvar1,xvar2); - qlo=p[24]*(1.0-xvar3*(1.0-((1.0-p[25])*((*Vbep)+p[85]))/(p[24]+p[85])))/(1.0-p[25]); - qlo_Vbep=p[24]*xvar3/(p[85]+p[24]); + xvar3_xvar1=xvar3*xvar2/xvar1; + xvar3_Vrth=xvar3_xvar1*xvar1_Vrth; + qlo=PCatT*(1.0-xvar3*(1.0-((1.0-p[25])*((*Vbep)+p[85]))/(PCatT+p[85])))/(1.0-p[25]); + qlo_PCatT=(1.0-(1.0-(1.0-p[25])*(p[85]+(*Vbep))/(p[85]+PCatT))*xvar3)/(1.0-p[25])-PCatT*(p[85]+(*Vbep))*xvar3/((p[85]+PCatT)*(p[85]+PCatT)); + qlo_xvar3=PCatT*((1.0-p[25])*(p[85]+(*Vbep))/(p[85]+PCatT)-1.0)/(1.0-p[25]); + qlo_Vbep=PCatT*xvar3/(p[85]+PCatT); + qlo_Vrth=qlo_PCatT*PCatT_Vrth; + qlo_Vrth=qlo_Vrth+qlo_xvar3*xvar3_Vrth; }else{ - xvar1=(1.0-(*Vbep)/p[24]); - xvar1_Vbep=-1.0/p[24]; + xvar1=(1.0-(*Vbep)/PCatT); + xvar1_Vbep=-1.0/PCatT; + xvar1_PCatT=(*Vbep)/(PCatT*PCatT); + xvar1_Vrth=xvar1_PCatT*PCatT_Vrth; xvar2=(1.0-p[25]); xvar3=pow(xvar1,xvar2); xvar3_xvar1=xvar3*xvar2/xvar1; xvar3_Vbep=xvar3_xvar1*xvar1_Vbep; - qlo=p[24]*(1.0-xvar3)/(1.0-p[25]); - qlo_xvar3=-p[24]/(1.0-p[25]); + xvar3_Vrth=xvar3_xvar1*xvar1_Vrth; + qlo=PCatT*(1.0-xvar3)/(1.0-p[25]); + qlo_PCatT=(1.0-xvar3)/(1.0-p[25]); + qlo_xvar3=-PCatT/(1.0-p[25]); + qlo_Vrth=qlo_PCatT*PCatT_Vrth; qlo_Vbep=qlo_xvar3*xvar3_Vbep; + qlo_Vrth=qlo_Vrth+qlo_xvar3*xvar3_Vrth; } qhi=0.0; qhi_Vbep=0.0; + qhi_Vrth=0.0; } qdbep=qlo+qhi; qdbep_qlo=1.0; qdbep_qhi=1.0; + qdbep_Vrth=qdbep_qlo*qlo_Vrth; qdbep_Vbep=qdbep_qlo*qlo_Vbep; qdbep_Vbep=qdbep_Vbep+qdbep_qhi*qhi_Vbep; + qdbep_Vrth=qdbep_Vrth+qdbep_qhi*qhi_Vrth; }else{ if((p[85]>0.0)&&(p[86]>0.0)){ vn0=(p[85]+dv0)/(p[85]-dv0); + vn0_dv0=(p[85]+dv0)/((p[85]-dv0)*(p[85]-dv0))+1.0/(p[85]-dv0); + vn0_Vrth=vn0_dv0*dv0_Vrth; vnl0=2.0*vn0/(sqrt((vn0-1.0)*(vn0-1.0)+4.0*p[26]*p[26])+sqrt((vn0+1.0)*(vn0+1.0)+4.0*p[86]*p[86])); + vnl0_vn0=2.0/(sqrt(((vn0+1.0)*(vn0+1.0))+4.0*(p[86]*p[86]))+sqrt(((vn0-1.0)*(vn0-1.0))+4.0*(p[26]*p[26])))-2.0*vn0*((vn0+1.0)/sqrt(((vn0+1.0)*(vn0+1.0))+4.0*(p[86]*p[86]))+(vn0-1.0)/sqrt(((vn0-1.0)*(vn0-1.0))+4.0*(p[26]*p[26])))/((sqrt(((vn0+1.0)*(vn0+1.0))+4.0*(p[86]*p[86]))+sqrt(((vn0-1.0)*(vn0-1.0))+4.0*(p[26]*p[26])))*(sqrt(((vn0+1.0)*(vn0+1.0))+4.0*(p[86]*p[86]))+sqrt(((vn0-1.0)*(vn0-1.0))+4.0*(p[26]*p[26])))); + vnl0_Vrth=vnl0_vn0*vn0_Vrth; vl0=0.5*(vnl0*(p[85]-dv0)-p[85]-dv0); - xvar1=(1.0-vl0/p[24]); + vl0_vnl0=0.5*(p[85]-dv0); + vl0_dv0=0.5*(-vnl0-1.0); + vl0_Vrth=vl0_vnl0*vnl0_Vrth; + vl0_Vrth=vl0_Vrth+vl0_dv0*dv0_Vrth; + xvar1=(1.0-vl0/PCatT); + xvar1_vl0=-1.0/PCatT; + xvar1_PCatT=vl0/(PCatT*PCatT); + xvar1_Vrth=xvar1_vl0*vl0_Vrth; + xvar1_Vrth=xvar1_Vrth+xvar1_PCatT*PCatT_Vrth; xvar2=(1.0-p[25]); xvar3=pow(xvar1,xvar2); - qlo0=p[24]*(1.0-xvar3)/(1.0-p[25]); + xvar3_xvar1=xvar3*xvar2/xvar1; + xvar3_Vrth=xvar3_xvar1*xvar1_Vrth; + qlo0=PCatT*(1.0-xvar3)/(1.0-p[25]); + qlo0_PCatT=(1.0-xvar3)/(1.0-p[25]); + qlo0_xvar3=-PCatT/(1.0-p[25]); + qlo0_Vrth=qlo0_PCatT*PCatT_Vrth; + qlo0_Vrth=qlo0_Vrth+qlo0_xvar3*xvar3_Vrth; vn=(2.0*(*Vbep)+p[85]+dv0)/(p[85]-dv0); vn_Vbep=2.0/(p[85]-dv0); + vn_dv0=(p[85]+2.0*(*Vbep)+dv0)/((p[85]-dv0)*(p[85]-dv0))+1.0/(p[85]-dv0); + vn_Vrth=vn_dv0*dv0_Vrth; vnl=2.0*vn/(sqrt((vn-1.0)*(vn-1.0)+4.0*p[26]*p[26])+sqrt((vn+1.0)*(vn+1.0)+4.0*p[86]*p[86])); vnl_vn=2.0/(sqrt(((vn+1.0)*(vn+1.0))+4.0*(p[86]*p[86]))+sqrt(((vn-1.0)*(vn-1.0))+4.0*(p[26]*p[26])))-2.0*vn*((vn+1.0)/sqrt(((vn+1.0)*(vn+1.0))+4.0*(p[86]*p[86]))+(vn-1.0)/sqrt(((vn-1.0)*(vn-1.0))+4.0*(p[26]*p[26])))/((sqrt(((vn+1.0)*(vn+1.0))+4.0*(p[86]*p[86]))+sqrt(((vn-1.0)*(vn-1.0))+4.0*(p[26]*p[26])))*(sqrt(((vn+1.0)*(vn+1.0))+4.0*(p[86]*p[86]))+sqrt(((vn-1.0)*(vn-1.0))+4.0*(p[26]*p[26])))); vnl_Vbep=vnl_vn*vn_Vbep; + vnl_Vrth=vnl_vn*vn_Vrth; vl=0.5*(vnl*(p[85]-dv0)-p[85]-dv0); vl_vnl=0.5*(p[85]-dv0); + vl_dv0=0.5*(-vnl-1.0); vl_Vbep=vl_vnl*vnl_Vbep; - xvar1=(1.0-vl/p[24]); - xvar1_vl=-1.0/p[24]; + vl_Vrth=vl_vnl*vnl_Vrth; + vl_Vrth=vl_Vrth+vl_dv0*dv0_Vrth; + xvar1=(1.0-vl/PCatT); + xvar1_vl=-1.0/PCatT; + xvar1_PCatT=vl/(PCatT*PCatT); xvar1_Vbep=xvar1_vl*vl_Vbep; + xvar1_Vrth=xvar1_vl*vl_Vrth; + xvar1_Vrth=xvar1_Vrth+xvar1_PCatT*PCatT_Vrth; xvar2=(1.0-p[25]); xvar3=pow(xvar1,xvar2); xvar3_xvar1=xvar3*xvar2/xvar1; xvar3_Vbep=xvar3_xvar1*xvar1_Vbep; - qlo=p[24]*(1.0-xvar3)/(1.0-p[25]); - qlo_xvar3=-p[24]/(1.0-p[25]); + xvar3_Vrth=xvar3_xvar1*xvar1_Vrth; + qlo=PCatT*(1.0-xvar3)/(1.0-p[25]); + qlo_PCatT=(1.0-xvar3)/(1.0-p[25]); + qlo_xvar3=-PCatT/(1.0-p[25]); + qlo_Vrth=qlo_PCatT*PCatT_Vrth; qlo_Vbep=qlo_xvar3*xvar3_Vbep; + qlo_Vrth=qlo_Vrth+qlo_xvar3*xvar3_Vrth; sel=0.5*(vnl+1.0); sel_vnl=0.5; sel_Vbep=sel_vnl*vnl_Vbep; - xvar1=(1.0+p[85]/p[24]); + sel_Vrth=sel_vnl*vnl_Vrth; + xvar1=(1.0+p[85]/PCatT); + xvar1_PCatT=-p[85]/(PCatT*PCatT); + xvar1_Vrth=xvar1_PCatT*PCatT_Vrth; xvar2=(-p[25]); crt=pow(xvar1,xvar2); - xvar1=(1.0+dv0/p[24]); + crt_xvar1=crt*xvar2/xvar1; + crt_Vrth=crt_xvar1*xvar1_Vrth; + xvar1=(1.0+dv0/PCatT); + xvar1_dv0=1.0/PCatT; + xvar1_PCatT=-dv0/(PCatT*PCatT); + xvar1_Vrth=xvar1_dv0*dv0_Vrth; + xvar1_Vrth=xvar1_Vrth+xvar1_PCatT*PCatT_Vrth; xvar2=(-p[25]); cmx=pow(xvar1,xvar2); + cmx_xvar1=cmx*xvar2/xvar1; + cmx_Vrth=cmx_xvar1*xvar1_Vrth; cl=(1.0-sel)*crt+sel*cmx; cl_sel=cmx-crt; + cl_crt=1.0-sel; + cl_cmx=sel; cl_Vbep=cl_sel*sel_Vbep; + cl_Vrth=cl_sel*sel_Vrth; + cl_Vrth=cl_Vrth+cl_crt*crt_Vrth; + cl_Vrth=cl_Vrth+cl_cmx*cmx_Vrth; ql=((*Vbep)-vl+vl0)*cl; ql_Vbep=cl; ql_vl=-cl; + ql_vl0=cl; ql_cl=vl0-vl+(*Vbep); ql_Vbep=ql_Vbep+ql_vl*vl_Vbep; + ql_Vrth=ql_vl*vl_Vrth; + ql_Vrth=ql_Vrth+ql_vl0*vl0_Vrth; ql_Vbep=ql_Vbep+ql_cl*cl_Vbep; + ql_Vrth=ql_Vrth+ql_cl*cl_Vrth; qdbep=ql+qlo-qlo0; qdbep_ql=1.0; qdbep_qlo=1.0; + qdbep_qlo0=-1.0; qdbep_Vbep=qdbep_ql*ql_Vbep; + qdbep_Vrth=qdbep_ql*ql_Vrth; + qdbep_Vrth=qdbep_Vrth+qdbep_qlo*qlo_Vrth; qdbep_Vbep=qdbep_Vbep+qdbep_qlo*qlo_Vbep; + qdbep_Vrth=qdbep_Vrth+qdbep_qlo0*qlo0_Vrth; }else{ mv0=sqrt(dv0*dv0+4.0*p[26]*p[26]); + mv0_dv0=dv0/sqrt((dv0*dv0)+4.0*(p[26]*p[26])); + mv0_Vrth=mv0_dv0*dv0_Vrth; vl0=-0.5*(dv0+mv0); - xvar1=(1.0-vl0/p[24]); + vl0_dv0=-0.5; + vl0_mv0=-0.5; + vl0_Vrth=vl0_dv0*dv0_Vrth; + vl0_Vrth=vl0_Vrth+vl0_mv0*mv0_Vrth; + xvar1=(1.0-vl0/PCatT); + xvar1_vl0=-1.0/PCatT; + xvar1_PCatT=vl0/(PCatT*PCatT); + xvar1_Vrth=xvar1_vl0*vl0_Vrth; + xvar1_Vrth=xvar1_Vrth+xvar1_PCatT*PCatT_Vrth; xvar2=(1.0-p[25]); xvar3=pow(xvar1,xvar2); - q0=-p[24]*xvar3/(1.0-p[25]); + xvar3_xvar1=xvar3*xvar2/xvar1; + xvar3_Vrth=xvar3_xvar1*xvar1_Vrth; + q0=-PCatT*xvar3/(1.0-p[25]); + q0_PCatT=-xvar3/(1.0-p[25]); + q0_xvar3=-PCatT/(1.0-p[25]); + q0_Vrth=q0_PCatT*PCatT_Vrth; + q0_Vrth=q0_Vrth+q0_xvar3*xvar3_Vrth; dv=(*Vbep)+dv0; dv_Vbep=1.0; + dv_dv0=1.0; + dv_Vrth=dv_dv0*dv0_Vrth; mv=sqrt(dv*dv+4.0*p[26]*p[26]); mv_dv=dv/sqrt((dv*dv)+4.0*(p[26]*p[26])); mv_Vbep=mv_dv*dv_Vbep; + mv_Vrth=mv_dv*dv_Vrth; vl=0.5*(dv-mv)-dv0; vl_dv=0.5; vl_mv=-0.5; + vl_dv0=-1.0; vl_Vbep=vl_dv*dv_Vbep; + vl_Vrth=vl_dv*dv_Vrth; vl_Vbep=vl_Vbep+vl_mv*mv_Vbep; - xvar1=(1.0-vl/p[24]); - xvar1_vl=-1.0/p[24]; + vl_Vrth=vl_Vrth+vl_mv*mv_Vrth; + vl_Vrth=vl_Vrth+vl_dv0*dv0_Vrth; + xvar1=(1.0-vl/PCatT); + xvar1_vl=-1.0/PCatT; + xvar1_PCatT=vl/(PCatT*PCatT); xvar1_Vbep=xvar1_vl*vl_Vbep; + xvar1_Vrth=xvar1_vl*vl_Vrth; + xvar1_Vrth=xvar1_Vrth+xvar1_PCatT*PCatT_Vrth; xvar2=(1.0-p[25]); xvar3=pow(xvar1,xvar2); xvar3_xvar1=xvar3*xvar2/xvar1; xvar3_Vbep=xvar3_xvar1*xvar1_Vbep; - qlo=-p[24]*xvar3/(1.0-p[25]); - qlo_xvar3=-p[24]/(1.0-p[25]); + xvar3_Vrth=xvar3_xvar1*xvar1_Vrth; + qlo=-PCatT*xvar3/(1.0-p[25]); + qlo_PCatT=-xvar3/(1.0-p[25]); + qlo_xvar3=-PCatT/(1.0-p[25]); + qlo_Vrth=qlo_PCatT*PCatT_Vrth; qlo_Vbep=qlo_xvar3*xvar3_Vbep; + qlo_Vrth=qlo_Vrth+qlo_xvar3*xvar3_Vrth; xvar1=(1.0-p[14]); xvar2=(-p[25]); xvar3=pow(xvar1,xvar2); @@ -4434,76 +6905,130 @@ double Qbep_qdbep,Qbep_Ifp,Qbcp_qdbcp; qdbep_qlo=1.0; qdbep_Vbep=xvar3; qdbep_vl=-xvar3; + qdbep_vl0=xvar3; + qdbep_q0=-1.0; + qdbep_Vrth=qdbep_qlo*qlo_Vrth; qdbep_Vbep=qdbep_Vbep+qdbep_qlo*qlo_Vbep; qdbep_Vbep=qdbep_Vbep+qdbep_vl*vl_Vbep; + qdbep_Vrth=qdbep_Vrth+qdbep_vl*vl_Vrth; + qdbep_Vrth=qdbep_Vrth+qdbep_vl0*vl0_Vrth; + qdbep_Vrth=qdbep_Vrth+qdbep_q0*q0_Vrth; } } if(p[27]>0.0){ - dv0=-p[28]*p[14]; + dv0=-PSatT*p[14]; + dv0_PSatT=-p[14]; + dv0_Vrth=dv0_PSatT*PSatT_Vrth; if(p[30]<=0.0){ dvh=(*Vbcp)+dv0; dvh_Vbcp=1.0; + dvh_dv0=1.0; + dvh_Vrth=dvh_dv0*dv0_Vrth; if(dvh>0.0){ xvar1=(1.0-p[14]); xvar2=(-1.0-p[29]); pwq=pow(xvar1,xvar2); - qlo=p[28]*(1.0-pwq*(1.0-p[14])*(1.0-p[14]))/(1.0-p[29]); + qlo=PSatT*(1.0-pwq*(1.0-p[14])*(1.0-p[14]))/(1.0-p[29]); + qlo_PSatT=(1.0-((1.0-p[14])*(1.0-p[14]))*pwq)/(1.0-p[29]); qlo_Vbep=0.0; qlo_Vbcp=0.0; - qhi=dvh*(1.0-p[14]+0.5*p[29]*dvh/p[28])*pwq; - qhi_dvh=(0.5*dvh*p[29]/p[28]-p[14]+1.0)*pwq+0.5*dvh*p[29]*pwq/p[28]; + qlo_Vrth=qlo_PSatT*PSatT_Vrth; + qhi=dvh*(1.0-p[14]+0.5*p[29]*dvh/PSatT)*pwq; + qhi_dvh=(0.5*dvh*p[29]/PSatT-p[14]+1.0)*pwq+0.5*dvh*p[29]*pwq/PSatT; + qhi_PSatT=-0.5*(dvh*dvh)*p[29]*pwq/(PSatT*PSatT); qhi_Vbep=0.0; qhi_Vbcp=qhi_dvh*dvh_Vbcp; + qhi_Vrth=qhi_dvh*dvh_Vrth; + qhi_Vrth=qhi_Vrth+qhi_PSatT*PSatT_Vrth; }else{ - xvar1=(1.0-(*Vbcp)/p[28]); - xvar1_Vbcp=-1.0/p[28]; + xvar1=(1.0-(*Vbcp)/PSatT); + xvar1_Vbcp=-1.0/PSatT; + xvar1_PSatT=(*Vbcp)/(PSatT*PSatT); + xvar1_Vrth=xvar1_PSatT*PSatT_Vrth; xvar2=(1.0-p[29]); xvar3=pow(xvar1,xvar2); xvar3_xvar1=xvar3*xvar2/xvar1; xvar3_Vbcp=xvar3_xvar1*xvar1_Vbcp; - qlo=p[28]*(1.0-xvar3)/(1.0-p[29]); - qlo_xvar3=-p[28]/(1.0-p[29]); + xvar3_Vrth=xvar3_xvar1*xvar1_Vrth; + qlo=PSatT*(1.0-xvar3)/(1.0-p[29]); + qlo_PSatT=(1.0-xvar3)/(1.0-p[29]); + qlo_xvar3=-PSatT/(1.0-p[29]); qlo_Vbep=0.0; + qlo_Vrth=qlo_PSatT*PSatT_Vrth; qlo_Vbcp=qlo_xvar3*xvar3_Vbcp; + qlo_Vrth=qlo_Vrth+qlo_xvar3*xvar3_Vrth; qhi=0.0; qhi_Vbep=0.0; + qhi_Vrth=0.0; qhi_Vbcp=0.0; } qdbcp=qlo+qhi; qdbcp_qlo=1.0; qdbcp_qhi=1.0; + qdbcp_Vrth=qdbcp_qlo*qlo_Vrth; qdbcp_Vbcp=qdbcp_qlo*qlo_Vbcp; qdbcp_Vbep=qdbcp_qlo*qlo_Vbep; qdbcp_Vbep=qdbcp_Vbep+qdbcp_qhi*qhi_Vbep; + qdbcp_Vrth=qdbcp_Vrth+qdbcp_qhi*qhi_Vrth; qdbcp_Vbcp=qdbcp_Vbcp+qdbcp_qhi*qhi_Vbcp; }else{ mv0=sqrt(dv0*dv0+4.0*p[30]*p[30]); + mv0_dv0=dv0/sqrt((dv0*dv0)+4.0*(p[30]*p[30])); + mv0_Vrth=mv0_dv0*dv0_Vrth; vl0=-0.5*(dv0+mv0); - xvar1=(1.0-vl0/p[28]); + vl0_dv0=-0.5; + vl0_mv0=-0.5; + vl0_Vrth=vl0_dv0*dv0_Vrth; + vl0_Vrth=vl0_Vrth+vl0_mv0*mv0_Vrth; + xvar1=(1.0-vl0/PSatT); + xvar1_vl0=-1.0/PSatT; + xvar1_PSatT=vl0/(PSatT*PSatT); + xvar1_Vrth=xvar1_vl0*vl0_Vrth; + xvar1_Vrth=xvar1_Vrth+xvar1_PSatT*PSatT_Vrth; xvar2=(1.0-p[29]); xvar3=pow(xvar1,xvar2); - q0=-p[28]*xvar3/(1.0-p[29]); + xvar3_xvar1=xvar3*xvar2/xvar1; + xvar3_Vrth=xvar3_xvar1*xvar1_Vrth; + q0=-PSatT*xvar3/(1.0-p[29]); + q0_PSatT=-xvar3/(1.0-p[29]); + q0_xvar3=-PSatT/(1.0-p[29]); + q0_Vrth=q0_PSatT*PSatT_Vrth; + q0_Vrth=q0_Vrth+q0_xvar3*xvar3_Vrth; dv=(*Vbcp)+dv0; dv_Vbcp=1.0; + dv_dv0=1.0; + dv_Vrth=dv_dv0*dv0_Vrth; mv=sqrt(dv*dv+4.0*p[30]*p[30]); mv_dv=dv/sqrt((dv*dv)+4.0*(p[30]*p[30])); mv_Vbcp=mv_dv*dv_Vbcp; + mv_Vrth=mv_dv*dv_Vrth; vl=0.5*(dv-mv)-dv0; vl_dv=0.5; vl_mv=-0.5; + vl_dv0=-1.0; vl_Vbcp=vl_dv*dv_Vbcp; + vl_Vrth=vl_dv*dv_Vrth; vl_Vbcp=vl_Vbcp+vl_mv*mv_Vbcp; - xvar1=(1.0-vl/p[28]); - xvar1_vl=-1.0/p[28]; + vl_Vrth=vl_Vrth+vl_mv*mv_Vrth; + vl_Vrth=vl_Vrth+vl_dv0*dv0_Vrth; + xvar1=(1.0-vl/PSatT); + xvar1_vl=-1.0/PSatT; + xvar1_PSatT=vl/(PSatT*PSatT); xvar1_Vbcp=xvar1_vl*vl_Vbcp; + xvar1_Vrth=xvar1_vl*vl_Vrth; + xvar1_Vrth=xvar1_Vrth+xvar1_PSatT*PSatT_Vrth; xvar2=(1.0-p[29]); xvar3=pow(xvar1,xvar2); xvar3_xvar1=xvar3*xvar2/xvar1; xvar3_Vbcp=xvar3_xvar1*xvar1_Vbcp; - qlo=-p[28]*xvar3/(1.0-p[29]); - qlo_xvar3=-p[28]/(1.0-p[29]); + xvar3_Vrth=xvar3_xvar1*xvar1_Vrth; + qlo=-PSatT*xvar3/(1.0-p[29]); + qlo_PSatT=-xvar3/(1.0-p[29]); + qlo_xvar3=-PSatT/(1.0-p[29]); qlo_Vbep=0.0; + qlo_Vrth=qlo_PSatT*PSatT_Vrth; qlo_Vbcp=qlo_xvar3*xvar3_Vbcp; + qlo_Vrth=qlo_Vrth+qlo_xvar3*xvar3_Vrth; xvar1=(1.0-p[14]); xvar2=(-p[29]); xvar3=pow(xvar1,xvar2); @@ -4511,146 +7036,225 @@ double Qbep_qdbep,Qbep_Ifp,Qbcp_qdbcp; qdbcp_qlo=1.0; qdbcp_Vbcp=xvar3; qdbcp_vl=-xvar3; + qdbcp_vl0=xvar3; + qdbcp_q0=-1.0; + qdbcp_Vrth=qdbcp_qlo*qlo_Vrth; qdbcp_Vbcp=qdbcp_Vbcp+qdbcp_qlo*qlo_Vbcp; qdbcp_Vbep=qdbcp_qlo*qlo_Vbep; qdbcp_Vbcp=qdbcp_Vbcp+qdbcp_vl*vl_Vbcp; + qdbcp_Vrth=qdbcp_Vrth+qdbcp_vl*vl_Vrth; + qdbcp_Vrth=qdbcp_Vrth+qdbcp_vl0*vl0_Vrth; + qdbcp_Vrth=qdbcp_Vrth+qdbcp_q0*q0_Vrth; } }else{ qdbcp=0.0; + qdbcp_Vrth=0.0; qdbcp_Vbcp=0.0; } - argi=(*Vbei)/(p[12]*Vtv); - argi_Vbei=1.0/(p[12]*Vtv); + argi=(*Vbei)/(NFatT*Vtv); + argi_Vbei=1.0/(NFatT*Vtv); + argi_NFatT=-(*Vbei)/((NFatT*NFatT)*Vtv); + argi_Vtv=-(*Vbei)/(NFatT*(Vtv*Vtv)); + argi_Vrth=argi_NFatT*NFatT_Vrth; + argi_Vrth=argi_Vrth+argi_Vtv*Vtv_Vrth; expi=exp(argi); expi_argi=expi; expi_Vbei=expi_argi*argi_Vbei; - Ifi=p[11]*(expi-1.0); - Ifi_expi=p[11]; + expi_Vrth=expi_argi*argi_Vrth; + Ifi=ISatT*(expi-1.0); + Ifi_ISatT=expi-1.0; + Ifi_expi=ISatT; + Ifi_Vrth=Ifi_ISatT*ISatT_Vrth; Ifi_Vbei=Ifi_expi*expi_Vbei; - argi=(*Vbci)/(p[13]*Vtv); - argi_Vbci=1.0/(p[13]*Vtv); + Ifi_Vrth=Ifi_Vrth+Ifi_expi*expi_Vrth; + argi=(*Vbci)/(NRatT*Vtv); + argi_Vbci=1.0/(NRatT*Vtv); + argi_NRatT=-(*Vbci)/((NRatT*NRatT)*Vtv); + argi_Vtv=-(*Vbci)/(NRatT*(Vtv*Vtv)); + argi_Vrth=argi_NRatT*NRatT_Vrth; + argi_Vrth=argi_Vrth+argi_Vtv*Vtv_Vrth; expi=exp(argi); expi_argi=expi; expi_Vbci=expi_argi*argi_Vbci; - Iri=p[11]*p[94]*(expi-1.0); - Iri_expi=p[11]*p[94]; + expi_Vrth=expi_argi*argi_Vrth; + Iri=ISatT*ISRRatT*(expi-1.0); + Iri_ISatT=(expi-1.0)*ISRRatT; + Iri_ISRRatT=(expi-1.0)*ISatT; + Iri_expi=ISatT*ISRRatT; + Iri_Vrth=Iri_ISatT*ISatT_Vrth; + Iri_Vrth=Iri_Vrth+Iri_ISRRatT*ISRRatT_Vrth; Iri_Vbci=Iri_expi*expi_Vbci; + Iri_Vrth=Iri_Vrth+Iri_expi*expi_Vrth; q1z=1.0+qdbe*IVER+qdbc*IVEF; q1z_qdbe=IVER; q1z_qdbc=IVEF; + q1z_Vrth=q1z_qdbe*qdbe_Vrth; q1z_Vbei=q1z_qdbe*qdbe_Vbei; + q1z_Vrth=q1z_Vrth+q1z_qdbc*qdbc_Vrth; q1z_Vbci=q1z_qdbc*qdbc_Vbci; q1=0.5*(sqrt((q1z-1.0e-4)*(q1z-1.0e-4)+1.0e-8)+q1z-1.0e-4)+1.0e-4; q1_q1z=0.5*((q1z-1.0e-4)/sqrt(((q1z-1.0e-4)*(q1z-1.0e-4))+1.0e-8)+1.0); + q1_Vrth=q1_q1z*q1z_Vrth; q1_Vbei=q1_q1z*q1z_Vbei; q1_Vbci=q1_q1z*q1z_Vbci; q2=Ifi*IIKF+Iri*IIKR; q2_Ifi=IIKF; + q2_IIKF=Ifi; q2_Iri=IIKR; + q2_Vrth=q2_Ifi*Ifi_Vrth; q2_Vbei=q2_Ifi*Ifi_Vbei; + q2_Vrth=q2_Vrth+q2_IIKF*IIKF_Vrth; + q2_Vrth=q2_Vrth+q2_Iri*Iri_Vrth; q2_Vbci=q2_Iri*Iri_Vbci; if(p[88]<0.5){ xvar2=1.0/p[89]; xvar3=pow(q1,xvar2); xvar3_q1=xvar3*xvar2/q1; + xvar3_Vrth=xvar3_q1*q1_Vrth; xvar3_Vbei=xvar3_q1*q1_Vbei; xvar3_Vbci=xvar3_q1*q1_Vbci; xvar1=(xvar3+4.0*q2); xvar1_xvar3=1.0; xvar1_q2=4.0; + xvar1_Vrth=xvar1_xvar3*xvar3_Vrth; xvar1_Vbei=xvar1_xvar3*xvar3_Vbei; xvar1_Vbci=xvar1_xvar3*xvar3_Vbci; + xvar1_Vrth=xvar1_Vrth+xvar1_q2*q2_Vrth; xvar1_Vbei=xvar1_Vbei+xvar1_q2*q2_Vbei; xvar1_Vbci=xvar1_Vbci+xvar1_q2*q2_Vbci; xvar4=pow(xvar1,p[89]); xvar4_xvar1=xvar4*p[89]/xvar1; + xvar4_Vrth=xvar4_xvar1*xvar1_Vrth; xvar4_Vbei=xvar4_xvar1*xvar1_Vbei; xvar4_Vbci=xvar4_xvar1*xvar1_Vbci; qb=0.5*(q1+xvar4); qb_q1=0.5; qb_xvar4=0.5; + qb_Vrth=qb_q1*q1_Vrth; qb_Vbei=qb_q1*q1_Vbei; qb_Vbci=qb_q1*q1_Vbci; + qb_Vrth=qb_Vrth+qb_xvar4*xvar4_Vrth; qb_Vbei=qb_Vbei+qb_xvar4*xvar4_Vbei; qb_Vbci=qb_Vbci+qb_xvar4*xvar4_Vbci; }else{ xvar1=(1.0+4.0*q2); xvar1_q2=4.0; + xvar1_Vrth=xvar1_q2*q2_Vrth; xvar1_Vbei=xvar1_q2*q2_Vbei; xvar1_Vbci=xvar1_q2*q2_Vbci; xvar2=pow(xvar1,p[89]); xvar2_xvar1=xvar2*p[89]/xvar1; + xvar2_Vrth=xvar2_xvar1*xvar1_Vrth; xvar2_Vbei=xvar2_xvar1*xvar1_Vbei; xvar2_Vbci=xvar2_xvar1*xvar1_Vbci; qb=0.5*q1*(1.0+xvar2); qb_q1=0.5*(xvar2+1.0); qb_xvar2=0.5*q1; + qb_Vrth=qb_q1*q1_Vrth; qb_Vbei=qb_q1*q1_Vbei; qb_Vbci=qb_q1*q1_Vbci; + qb_Vrth=qb_Vrth+qb_xvar2*xvar2_Vrth; qb_Vbei=qb_Vbei+qb_xvar2*xvar2_Vbei; qb_Vbci=qb_Vbci+qb_xvar2*xvar2_Vbci; } (*Itzr)=Iri/qb; Itzr_Iri=1.0/qb; Itzr_qb=-Iri/(qb*qb); + *Itzr_Vrth=Itzr_Iri*Iri_Vrth; *Itzr_Vbci=Itzr_Iri*Iri_Vbci; + *Itzr_Vrth=(*Itzr_Vrth)+Itzr_qb*qb_Vrth; *Itzr_Vbei=Itzr_qb*qb_Vbei; *Itzr_Vbci=(*Itzr_Vbci)+Itzr_qb*qb_Vbci; - (*Itzf)=Ifi/qb; + Itzf=Ifi/qb; Itzf_Ifi=1.0/qb; Itzf_qb=-Ifi/(qb*qb); - *Itzf_Vbei=Itzf_Ifi*Ifi_Vbei; - *Itzf_Vbei=(*Itzf_Vbei)+Itzf_qb*qb_Vbei; - *Itzf_Vbci=Itzf_qb*qb_Vbci; + Itzf_Vrth=Itzf_Ifi*Ifi_Vrth; + Itzf_Vbei=Itzf_Ifi*Ifi_Vbei; + Itzf_Vrth=Itzf_Vrth+Itzf_qb*qb_Vrth; + Itzf_Vbei=Itzf_Vbei+Itzf_qb*qb_Vbei; + Itzf_Vbci=Itzf_qb*qb_Vbci; + (*Ixzf)=-Itzf; + Ixzf_Itzf=-1.0; + *Ixzf_Vrth=Ixzf_Itzf*Itzf_Vrth; + *Ixzf_Vbei=Ixzf_Itzf*Itzf_Vbei; + *Ixzf_Vbci=Ixzf_Itzf*Itzf_Vbci; + (*Itxf)=(*Vrxf); + *Itxf_Vrxf=1.0; + (*Ixxf)=(*Vrxf); + *Ixxf_Vrxf=1.0; if(p[42]>0.0){ argi=(*Vbep)/(p[44]*Vtv); argi_Vbep=1.0/(p[44]*Vtv); + argi_Vtv=-(*Vbep)/(p[44]*(Vtv*Vtv)); + argi_Vrth=argi_Vtv*Vtv_Vrth; expi=exp(argi); expi_argi=expi; expi_Vbep=expi_argi*argi_Vbep; + expi_Vrth=expi_argi*argi_Vrth; argx=(*Vbci)/(p[44]*Vtv); argx_Vbci=1.0/(p[44]*Vtv); + argx_Vtv=-(*Vbci)/(p[44]*(Vtv*Vtv)); + argx_Vrth=argx_Vtv*Vtv_Vrth; expx=exp(argx); expx_argx=expx; expx_Vbci=expx_argx*argx_Vbci; - Ifp=p[42]*(p[43]*expi+(1.0-p[43])*expx-1.0); - Ifp_expi=p[42]*p[43]; - Ifp_expx=p[42]*(1.0-p[43]); + expx_Vrth=expx_argx*argx_Vrth; + Ifp=ISPatT*(p[43]*expi+(1.0-p[43])*expx-1.0); + Ifp_ISPatT=expi*p[43]+expx*(1.0-p[43])-1.0; + Ifp_expi=ISPatT*p[43]; + Ifp_expx=ISPatT*(1.0-p[43]); + Ifp_Vrth=Ifp_ISPatT*ISPatT_Vrth; Ifp_Vbep=Ifp_expi*expi_Vbep; + Ifp_Vrth=Ifp_Vrth+Ifp_expi*expi_Vrth; Ifp_Vbci=Ifp_expx*expx_Vbci; + Ifp_Vrth=Ifp_Vrth+Ifp_expx*expx_Vrth; q2p=Ifp*IIKP; q2p_Ifp=IIKP; + q2p_Vrth=q2p_Ifp*Ifp_Vrth; q2p_Vbep=q2p_Ifp*Ifp_Vbep; q2p_Vbci=q2p_Ifp*Ifp_Vbci; qbp=0.5*(1.0+sqrt(1.0+4.0*q2p)); qbp_q2p=1.0/sqrt(4.0*q2p+1.0); + qbp_Vrth=qbp_q2p*q2p_Vrth; qbp_Vbep=qbp_q2p*q2p_Vbep; qbp_Vbci=qbp_q2p*q2p_Vbci; argi=(*Vbcp)/(p[44]*Vtv); argi_Vbcp=1.0/(p[44]*Vtv); + argi_Vtv=-(*Vbcp)/(p[44]*(Vtv*Vtv)); + argi_Vrth=argi_Vtv*Vtv_Vrth; expi=exp(argi); expi_argi=expi; expi_Vbcp=expi_argi*argi_Vbcp; - Irp=p[42]*(expi-1.0); - Irp_expi=p[42]; + expi_Vrth=expi_argi*argi_Vrth; + Irp=ISPatT*(expi-1.0); + Irp_ISPatT=expi-1.0; + Irp_expi=ISPatT; + Irp_Vrth=Irp_ISPatT*ISPatT_Vrth; Irp_Vbcp=Irp_expi*expi_Vbcp; + Irp_Vrth=Irp_Vrth+Irp_expi*expi_Vrth; (*Iccp)=(Ifp-Irp)/qbp; Iccp_Ifp=1.0/qbp; Iccp_Irp=-1.0/qbp; Iccp_qbp=-(Ifp-Irp)/(qbp*qbp); + *Iccp_Vrth=Iccp_Ifp*Ifp_Vrth; *Iccp_Vbep=Iccp_Ifp*Ifp_Vbep; *Iccp_Vbci=Iccp_Ifp*Ifp_Vbci; + *Iccp_Vrth=(*Iccp_Vrth)+Iccp_Irp*Irp_Vrth; *Iccp_Vbcp=Iccp_Irp*Irp_Vbcp; + *Iccp_Vrth=(*Iccp_Vrth)+Iccp_qbp*qbp_Vrth; *Iccp_Vbep=(*Iccp_Vbep)+Iccp_qbp*qbp_Vbep; *Iccp_Vbci=(*Iccp_Vbci)+Iccp_qbp*qbp_Vbci; }else{ Ifp=0.0; + Ifp_Vrth=0.0; Ifp_Vbep=0.0; Ifp_Vbci=0.0; qbp=1.0; + qbp_Vrth=0.0; qbp_Vbep=0.0; qbp_Vbci=0.0; (*Iccp)=0.0; + *Iccp_Vrth=0.0; *Iccp_Vbep=0.0; *Iccp_Vbci=0.0; *Iccp_Vbcp=0.0; @@ -4658,333 +7262,551 @@ double Qbep_qdbep,Qbep_Ifp,Qbcp_qdbcp; if(p[32]==1.0){ argi=(*Vbei)/(p[33]*Vtv); argi_Vbei=1.0/(p[33]*Vtv); + argi_Vtv=-(*Vbei)/(p[33]*(Vtv*Vtv)); + argi_Vrth=argi_Vtv*Vtv_Vrth; expi=exp(argi); expi_argi=expi; expi_Vbei=expi_argi*argi_Vbei; + expi_Vrth=expi_argi*argi_Vrth; argn=(*Vbei)/(p[35]*Vtv); argn_Vbei=1.0/(p[35]*Vtv); + argn_Vtv=-(*Vbei)/(p[35]*(Vtv*Vtv)); + argn_Vrth=argn_Vtv*Vtv_Vrth; expn=exp(argn); expn_argn=expn; expn_Vbei=expn_argn*argn_Vbei; + expn_Vrth=expn_argn*argn_Vrth; if(p[98]>0.0){ - argx=(-p[98]-(*Vbei))/(p[99]*Vtv); - argx_Vbei=-1.0/(p[99]*Vtv); + argx=(-VBBEatT-(*Vbei))/(NBBEatT*Vtv); + argx_VBBEatT=-1.0/(NBBEatT*Vtv); + argx_Vbei=-1.0/(NBBEatT*Vtv); + argx_NBBEatT=-(-(*Vbei)-VBBEatT)/((NBBEatT*NBBEatT)*Vtv); + argx_Vtv=-(-(*Vbei)-VBBEatT)/(NBBEatT*(Vtv*Vtv)); + argx_Vrth=argx_VBBEatT*VBBEatT_Vrth; + argx_Vrth=argx_Vrth+argx_NBBEatT*NBBEatT_Vrth; + argx_Vrth=argx_Vrth+argx_Vtv*Vtv_Vrth; expx=exp(argx); expx_argx=expx; + expx_Vrth=expx_argx*argx_Vrth; expx_Vbei=expx_argx*argx_Vbei; - (*Ibe)=p[31]*(expi-1.0)+p[34]*(expn-1.0)-p[100]*(expx-p[104]); - Ibe_expi=p[31]; - Ibe_expn=p[34]; + (*Ibe)=IBEIatT*(expi-1.0)+IBENatT*(expn-1.0)-p[100]*(expx-EBBEatT); + Ibe_IBEIatT=expi-1.0; + Ibe_expi=IBEIatT; + Ibe_IBENatT=expn-1.0; + Ibe_expn=IBENatT; Ibe_expx=-p[100]; + Ibe_EBBEatT=p[100]; + *Ibe_Vrth=Ibe_IBEIatT*IBEIatT_Vrth; *Ibe_Vbei=Ibe_expi*expi_Vbei; + *Ibe_Vrth=(*Ibe_Vrth)+Ibe_expi*expi_Vrth; + *Ibe_Vrth=(*Ibe_Vrth)+Ibe_IBENatT*IBENatT_Vrth; *Ibe_Vbei=(*Ibe_Vbei)+Ibe_expn*expn_Vbei; + *Ibe_Vrth=(*Ibe_Vrth)+Ibe_expn*expn_Vrth; + *Ibe_Vrth=(*Ibe_Vrth)+Ibe_expx*expx_Vrth; *Ibe_Vbei=(*Ibe_Vbei)+Ibe_expx*expx_Vbei; + *Ibe_Vrth=(*Ibe_Vrth)+Ibe_EBBEatT*EBBEatT_Vrth; }else{ - (*Ibe)=p[31]*(expi-1.0)+p[34]*(expn-1.0); - Ibe_expi=p[31]; - Ibe_expn=p[34]; + (*Ibe)=IBEIatT*(expi-1.0)+IBENatT*(expn-1.0); + Ibe_IBEIatT=expi-1.0; + Ibe_expi=IBEIatT; + Ibe_IBENatT=expn-1.0; + Ibe_expn=IBENatT; + *Ibe_Vrth=Ibe_IBEIatT*IBEIatT_Vrth; *Ibe_Vbei=Ibe_expi*expi_Vbei; + *Ibe_Vrth=(*Ibe_Vrth)+Ibe_expi*expi_Vrth; + *Ibe_Vrth=(*Ibe_Vrth)+Ibe_IBENatT*IBENatT_Vrth; *Ibe_Vbei=(*Ibe_Vbei)+Ibe_expn*expn_Vbei; + *Ibe_Vrth=(*Ibe_Vrth)+Ibe_expn*expn_Vrth; } (*Ibex)=0.0; + *Ibex_Vrth=0.0; *Ibex_Vbex=0.0; }else if(p[32]==0.0){ (*Ibe)=0.0; + *Ibe_Vrth=0.0; *Ibe_Vbei=0.0; argi=(*Vbex)/(p[33]*Vtv); argi_Vbex=1.0/(p[33]*Vtv); + argi_Vtv=-(*Vbex)/(p[33]*(Vtv*Vtv)); + argi_Vrth=argi_Vtv*Vtv_Vrth; expi=exp(argi); expi_argi=expi; expi_Vbex=expi_argi*argi_Vbex; + expi_Vrth=expi_argi*argi_Vrth; argn=(*Vbex)/(p[35]*Vtv); argn_Vbex=1.0/(p[35]*Vtv); + argn_Vtv=-(*Vbex)/(p[35]*(Vtv*Vtv)); + argn_Vrth=argn_Vtv*Vtv_Vrth; expn=exp(argn); expn_argn=expn; expn_Vbex=expn_argn*argn_Vbex; + expn_Vrth=expn_argn*argn_Vrth; if(p[98]>0.0){ - argx=(-p[98]-(*Vbex))/(p[99]*Vtv); - argx_Vbex=-1.0/(p[99]*Vtv); + argx=(-VBBEatT-(*Vbex))/(NBBEatT*Vtv); + argx_VBBEatT=-1.0/(NBBEatT*Vtv); + argx_Vbex=-1.0/(NBBEatT*Vtv); + argx_NBBEatT=-(-(*Vbex)-VBBEatT)/((NBBEatT*NBBEatT)*Vtv); + argx_Vtv=-(-(*Vbex)-VBBEatT)/(NBBEatT*(Vtv*Vtv)); + argx_Vrth=argx_VBBEatT*VBBEatT_Vrth; + argx_Vrth=argx_Vrth+argx_NBBEatT*NBBEatT_Vrth; + argx_Vrth=argx_Vrth+argx_Vtv*Vtv_Vrth; expx=exp(argx); expx_argx=expx; + expx_Vrth=expx_argx*argx_Vrth; expx_Vbex=expx_argx*argx_Vbex; - (*Ibex)=p[31]*(expi-1.0)+p[34]*(expn-1.0)-p[100]*(expx-p[104]); - Ibex_expi=p[31]; - Ibex_expn=p[34]; + (*Ibex)=IBEIatT*(expi-1.0)+IBENatT*(expn-1.0)-p[100]*(expx-EBBEatT); + Ibex_IBEIatT=expi-1.0; + Ibex_expi=IBEIatT; + Ibex_IBENatT=expn-1.0; + Ibex_expn=IBENatT; Ibex_expx=-p[100]; + Ibex_EBBEatT=p[100]; + *Ibex_Vrth=Ibex_IBEIatT*IBEIatT_Vrth; *Ibex_Vbex=Ibex_expi*expi_Vbex; + *Ibex_Vrth=(*Ibex_Vrth)+Ibex_expi*expi_Vrth; + *Ibex_Vrth=(*Ibex_Vrth)+Ibex_IBENatT*IBENatT_Vrth; *Ibex_Vbex=(*Ibex_Vbex)+Ibex_expn*expn_Vbex; + *Ibex_Vrth=(*Ibex_Vrth)+Ibex_expn*expn_Vrth; + *Ibex_Vrth=(*Ibex_Vrth)+Ibex_expx*expx_Vrth; *Ibex_Vbex=(*Ibex_Vbex)+Ibex_expx*expx_Vbex; + *Ibex_Vrth=(*Ibex_Vrth)+Ibex_EBBEatT*EBBEatT_Vrth; }else{ - (*Ibex)=p[31]*(expi-1.0)+p[34]*(expn-1.0); - Ibex_expi=p[31]; - Ibex_expn=p[34]; + (*Ibex)=IBEIatT*(expi-1.0)+IBENatT*(expn-1.0); + Ibex_IBEIatT=expi-1.0; + Ibex_expi=IBEIatT; + Ibex_IBENatT=expn-1.0; + Ibex_expn=IBENatT; + *Ibex_Vrth=Ibex_IBEIatT*IBEIatT_Vrth; *Ibex_Vbex=Ibex_expi*expi_Vbex; + *Ibex_Vrth=(*Ibex_Vrth)+Ibex_expi*expi_Vrth; + *Ibex_Vrth=(*Ibex_Vrth)+Ibex_IBENatT*IBENatT_Vrth; *Ibex_Vbex=(*Ibex_Vbex)+Ibex_expn*expn_Vbex; + *Ibex_Vrth=(*Ibex_Vrth)+Ibex_expn*expn_Vrth; } }else{ argi=(*Vbei)/(p[33]*Vtv); argi_Vbei=1.0/(p[33]*Vtv); + argi_Vtv=-(*Vbei)/(p[33]*(Vtv*Vtv)); + argi_Vrth=argi_Vtv*Vtv_Vrth; expi=exp(argi); expi_argi=expi; expi_Vbei=expi_argi*argi_Vbei; + expi_Vrth=expi_argi*argi_Vrth; argn=(*Vbei)/(p[35]*Vtv); argn_Vbei=1.0/(p[35]*Vtv); + argn_Vtv=-(*Vbei)/(p[35]*(Vtv*Vtv)); + argn_Vrth=argn_Vtv*Vtv_Vrth; expn=exp(argn); expn_argn=expn; expn_Vbei=expn_argn*argn_Vbei; + expn_Vrth=expn_argn*argn_Vrth; if(p[98]>0.0){ - argx=(-p[98]-(*Vbei))/(p[99]*Vtv); - argx_Vbei=-1.0/(p[99]*Vtv); + argx=(-VBBEatT-(*Vbei))/(NBBEatT*Vtv); + argx_VBBEatT=-1.0/(NBBEatT*Vtv); + argx_Vbei=-1.0/(NBBEatT*Vtv); + argx_NBBEatT=-(-(*Vbei)-VBBEatT)/((NBBEatT*NBBEatT)*Vtv); + argx_Vtv=-(-(*Vbei)-VBBEatT)/(NBBEatT*(Vtv*Vtv)); + argx_Vrth=argx_VBBEatT*VBBEatT_Vrth; + argx_Vrth=argx_Vrth+argx_NBBEatT*NBBEatT_Vrth; + argx_Vrth=argx_Vrth+argx_Vtv*Vtv_Vrth; expx=exp(argx); expx_argx=expx; + expx_Vrth=expx_argx*argx_Vrth; expx_Vbei=expx_argx*argx_Vbei; - (*Ibe)=p[32]*(p[31]*(expi-1.0)+p[34]*(expn-1.0)-p[100]*(expx-p[104])); - Ibe_expi=p[31]*p[32]; - Ibe_expn=p[34]*p[32]; + (*Ibe)=p[32]*(IBEIatT*(expi-1.0)+IBENatT*(expn-1.0)-p[100]*(expx-EBBEatT)); + Ibe_IBEIatT=(expi-1.0)*p[32]; + Ibe_expi=IBEIatT*p[32]; + Ibe_IBENatT=(expn-1.0)*p[32]; + Ibe_expn=IBENatT*p[32]; Ibe_expx=-p[100]*p[32]; + Ibe_EBBEatT=p[100]*p[32]; + *Ibe_Vrth=Ibe_IBEIatT*IBEIatT_Vrth; *Ibe_Vbei=Ibe_expi*expi_Vbei; + *Ibe_Vrth=(*Ibe_Vrth)+Ibe_expi*expi_Vrth; + *Ibe_Vrth=(*Ibe_Vrth)+Ibe_IBENatT*IBENatT_Vrth; *Ibe_Vbei=(*Ibe_Vbei)+Ibe_expn*expn_Vbei; + *Ibe_Vrth=(*Ibe_Vrth)+Ibe_expn*expn_Vrth; + *Ibe_Vrth=(*Ibe_Vrth)+Ibe_expx*expx_Vrth; *Ibe_Vbei=(*Ibe_Vbei)+Ibe_expx*expx_Vbei; + *Ibe_Vrth=(*Ibe_Vrth)+Ibe_EBBEatT*EBBEatT_Vrth; }else{ - (*Ibe)=p[32]*(p[31]*(expi-1.0)+p[34]*(expn-1.0)); - Ibe_expi=p[31]*p[32]; - Ibe_expn=p[34]*p[32]; + (*Ibe)=p[32]*(IBEIatT*(expi-1.0)+IBENatT*(expn-1.0)); + Ibe_IBEIatT=(expi-1.0)*p[32]; + Ibe_expi=IBEIatT*p[32]; + Ibe_IBENatT=(expn-1.0)*p[32]; + Ibe_expn=IBENatT*p[32]; + *Ibe_Vrth=Ibe_IBEIatT*IBEIatT_Vrth; *Ibe_Vbei=Ibe_expi*expi_Vbei; + *Ibe_Vrth=(*Ibe_Vrth)+Ibe_expi*expi_Vrth; + *Ibe_Vrth=(*Ibe_Vrth)+Ibe_IBENatT*IBENatT_Vrth; *Ibe_Vbei=(*Ibe_Vbei)+Ibe_expn*expn_Vbei; + *Ibe_Vrth=(*Ibe_Vrth)+Ibe_expn*expn_Vrth; } argi=(*Vbex)/(p[33]*Vtv); argi_Vbex=1.0/(p[33]*Vtv); + argi_Vtv=-(*Vbex)/(p[33]*(Vtv*Vtv)); + argi_Vrth=argi_Vtv*Vtv_Vrth; expi=exp(argi); expi_argi=expi; expi_Vbex=expi_argi*argi_Vbex; + expi_Vrth=expi_argi*argi_Vrth; argn=(*Vbex)/(p[35]*Vtv); argn_Vbex=1.0/(p[35]*Vtv); + argn_Vtv=-(*Vbex)/(p[35]*(Vtv*Vtv)); + argn_Vrth=argn_Vtv*Vtv_Vrth; expn=exp(argn); expn_argn=expn; expn_Vbex=expn_argn*argn_Vbex; + expn_Vrth=expn_argn*argn_Vrth; if(p[98]>0.0){ - argx=(-p[98]-(*Vbex))/(p[99]*Vtv); - argx_Vbex=-1.0/(p[99]*Vtv); + argx=(-VBBEatT-(*Vbex))/(NBBEatT*Vtv); + argx_VBBEatT=-1.0/(NBBEatT*Vtv); + argx_Vbex=-1.0/(NBBEatT*Vtv); + argx_NBBEatT=-(-(*Vbex)-VBBEatT)/((NBBEatT*NBBEatT)*Vtv); + argx_Vtv=-(-(*Vbex)-VBBEatT)/(NBBEatT*(Vtv*Vtv)); + argx_Vrth=argx_VBBEatT*VBBEatT_Vrth; + argx_Vrth=argx_Vrth+argx_NBBEatT*NBBEatT_Vrth; + argx_Vrth=argx_Vrth+argx_Vtv*Vtv_Vrth; expx=exp(argx); expx_argx=expx; + expx_Vrth=expx_argx*argx_Vrth; expx_Vbex=expx_argx*argx_Vbex; - (*Ibex)=(1.0-p[32])*(p[31]*(expi-1.0)+p[34]*(expn-1.0)-p[100]*(expx-p[104])); - Ibex_expi=p[31]*(1.0-p[32]); - Ibex_expn=p[34]*(1.0-p[32]); + (*Ibex)=(1.0-p[32])*(IBEIatT*(expi-1.0)+IBENatT*(expn-1.0)-p[100]*(expx-EBBEatT)); + Ibex_IBEIatT=(expi-1.0)*(1.0-p[32]); + Ibex_expi=IBEIatT*(1.0-p[32]); + Ibex_IBENatT=(expn-1.0)*(1.0-p[32]); + Ibex_expn=IBENatT*(1.0-p[32]); Ibex_expx=-p[100]*(1.0-p[32]); + Ibex_EBBEatT=p[100]*(1.0-p[32]); + *Ibex_Vrth=Ibex_IBEIatT*IBEIatT_Vrth; *Ibex_Vbex=Ibex_expi*expi_Vbex; + *Ibex_Vrth=(*Ibex_Vrth)+Ibex_expi*expi_Vrth; + *Ibex_Vrth=(*Ibex_Vrth)+Ibex_IBENatT*IBENatT_Vrth; *Ibex_Vbex=(*Ibex_Vbex)+Ibex_expn*expn_Vbex; + *Ibex_Vrth=(*Ibex_Vrth)+Ibex_expn*expn_Vrth; + *Ibex_Vrth=(*Ibex_Vrth)+Ibex_expx*expx_Vrth; *Ibex_Vbex=(*Ibex_Vbex)+Ibex_expx*expx_Vbex; + *Ibex_Vrth=(*Ibex_Vrth)+Ibex_EBBEatT*EBBEatT_Vrth; }else{ - (*Ibex)=(1.0-p[32])*(p[31]*(expi-1.0)+p[34]*(expn-1.0)); - Ibex_expi=p[31]*(1.0-p[32]); - Ibex_expn=p[34]*(1.0-p[32]); + (*Ibex)=(1.0-p[32])*(IBEIatT*(expi-1.0)+IBENatT*(expn-1.0)); + Ibex_IBEIatT=(expi-1.0)*(1.0-p[32]); + Ibex_expi=IBEIatT*(1.0-p[32]); + Ibex_IBENatT=(expn-1.0)*(1.0-p[32]); + Ibex_expn=IBENatT*(1.0-p[32]); + *Ibex_Vrth=Ibex_IBEIatT*IBEIatT_Vrth; *Ibex_Vbex=Ibex_expi*expi_Vbex; + *Ibex_Vrth=(*Ibex_Vrth)+Ibex_expi*expi_Vrth; + *Ibex_Vrth=(*Ibex_Vrth)+Ibex_IBENatT*IBENatT_Vrth; *Ibex_Vbex=(*Ibex_Vbex)+Ibex_expn*expn_Vbex; + *Ibex_Vrth=(*Ibex_Vrth)+Ibex_expn*expn_Vrth; } } argi=(*Vbci)/(p[37]*Vtv); argi_Vbci=1.0/(p[37]*Vtv); + argi_Vtv=-(*Vbci)/(p[37]*(Vtv*Vtv)); + argi_Vrth=argi_Vtv*Vtv_Vrth; expi=exp(argi); expi_argi=expi; expi_Vbci=expi_argi*argi_Vbci; + expi_Vrth=expi_argi*argi_Vrth; argn=(*Vbci)/(p[39]*Vtv); argn_Vbci=1.0/(p[39]*Vtv); + argn_Vtv=-(*Vbci)/(p[39]*(Vtv*Vtv)); + argn_Vrth=argn_Vtv*Vtv_Vrth; expn=exp(argn); expn_argn=expn; expn_Vbci=expn_argn*argn_Vbci; - Ibcj=p[36]*(expi-1.0)+p[38]*(expn-1.0); - Ibcj_expi=p[36]; - Ibcj_expn=p[38]; + expn_Vrth=expn_argn*argn_Vrth; + Ibcj=IBCIatT*(expi-1.0)+IBCNatT*(expn-1.0); + Ibcj_IBCIatT=expi-1.0; + Ibcj_expi=IBCIatT; + Ibcj_IBCNatT=expn-1.0; + Ibcj_expn=IBCNatT; + Ibcj_Vrth=Ibcj_IBCIatT*IBCIatT_Vrth; Ibcj_Vbci=Ibcj_expi*expi_Vbci; + Ibcj_Vrth=Ibcj_Vrth+Ibcj_expi*expi_Vrth; + Ibcj_Vrth=Ibcj_Vrth+Ibcj_IBCNatT*IBCNatT_Vrth; Ibcj_Vbci=Ibcj_Vbci+Ibcj_expn*expn_Vbci; + Ibcj_Vrth=Ibcj_Vrth+Ibcj_expn*expn_Vrth; if((p[45]>0.0)||(p[46]>0.0)){ argi=(*Vbep)/(p[37]*Vtv); argi_Vbep=1.0/(p[37]*Vtv); + argi_Vtv=-(*Vbep)/(p[37]*(Vtv*Vtv)); + argi_Vrth=argi_Vtv*Vtv_Vrth; expi=exp(argi); expi_argi=expi; expi_Vbep=expi_argi*argi_Vbep; + expi_Vrth=expi_argi*argi_Vrth; argn=(*Vbep)/(p[39]*Vtv); argn_Vbep=1.0/(p[39]*Vtv); + argn_Vtv=-(*Vbep)/(p[39]*(Vtv*Vtv)); + argn_Vrth=argn_Vtv*Vtv_Vrth; expn=exp(argn); expn_argn=expn; expn_Vbep=expn_argn*argn_Vbep; - (*Ibep)=p[45]*(expi-1.0)+p[46]*(expn-1.0); - Ibep_expi=p[45]; - Ibep_expn=p[46]; + expn_Vrth=expn_argn*argn_Vrth; + (*Ibep)=IBEIPatT*(expi-1.0)+IBENPatT*(expn-1.0); + Ibep_IBEIPatT=expi-1.0; + Ibep_expi=IBEIPatT; + Ibep_IBENPatT=expn-1.0; + Ibep_expn=IBENPatT; + *Ibep_Vrth=Ibep_IBEIPatT*IBEIPatT_Vrth; *Ibep_Vbep=Ibep_expi*expi_Vbep; + *Ibep_Vrth=(*Ibep_Vrth)+Ibep_expi*expi_Vrth; + *Ibep_Vrth=(*Ibep_Vrth)+Ibep_IBENPatT*IBENPatT_Vrth; *Ibep_Vbep=(*Ibep_Vbep)+Ibep_expn*expn_Vbep; + *Ibep_Vrth=(*Ibep_Vrth)+Ibep_expn*expn_Vrth; }else{ (*Ibep)=0.0; + *Ibep_Vrth=0.0; *Ibep_Vbep=0.0; } if(p[40]>0.0){ - vl=0.5*(sqrt((p[24]-(*Vbci))*(p[24]-(*Vbci))+0.01)+(p[24]-(*Vbci))); - vl_Vbci=0.5*(-(p[24]-(*Vbci))/sqrt(((p[24]-(*Vbci))*(p[24]-(*Vbci)))+0.01)-1.0); + vl=0.5*(sqrt((PCatT-(*Vbci))*(PCatT-(*Vbci))+0.01)+(PCatT-(*Vbci))); + vl_PCatT=0.5*((PCatT-(*Vbci))/sqrt(((PCatT-(*Vbci))*(PCatT-(*Vbci)))+0.01)+1.0); + vl_Vbci=0.5*(-(PCatT-(*Vbci))/sqrt(((PCatT-(*Vbci))*(PCatT-(*Vbci)))+0.01)-1.0); + vl_Vrth=vl_PCatT*PCatT_Vrth; xvar2=(p[25]-1.0); xvar3=pow(vl,xvar2); xvar3_vl=xvar3*xvar2/vl; + xvar3_Vrth=xvar3_vl*vl_Vrth; xvar3_Vbci=xvar3_vl*vl_Vbci; - xvar1=-p[41]*xvar3; - xvar1_xvar3=-p[41]; + xvar1=-AVC2atT*xvar3; + xvar1_AVC2atT=-xvar3; + xvar1_xvar3=-AVC2atT; + xvar1_Vrth=xvar1_AVC2atT*AVC2atT_Vrth; + xvar1_Vrth=xvar1_Vrth+xvar1_xvar3*xvar3_Vrth; xvar1_Vbci=xvar1_xvar3*xvar3_Vbci; xvar4=exp(xvar1); xvar4_xvar1=xvar4; + xvar4_Vrth=xvar4_xvar1*xvar1_Vrth; xvar4_Vbci=xvar4_xvar1*xvar1_Vbci; avalf=p[40]*vl*xvar4; avalf_vl=p[40]*xvar4; avalf_xvar4=p[40]*vl; + avalf_Vrth=avalf_vl*vl_Vrth; avalf_Vbci=avalf_vl*vl_Vbci; + avalf_Vrth=avalf_Vrth+avalf_xvar4*xvar4_Vrth; avalf_Vbci=avalf_Vbci+avalf_xvar4*xvar4_Vbci; - Igc=((*Itzf)-(*Itzr)-Ibcj)*avalf; - Igc_Itzf=avalf; + Igc=((*Itxf)-(*Itzr)-Ibcj)*avalf; + Igc_Itxf=avalf; Igc_Itzr=-avalf; Igc_Ibcj=-avalf; - Igc_avalf=-(*Itzr)+(*Itzf)-Ibcj; - Igc_Vbei=Igc_Itzf*(*Itzf_Vbei); - Igc_Vbci=Igc_Itzf*(*Itzf_Vbci); - Igc_Vbci=Igc_Vbci+Igc_Itzr*(*Itzr_Vbci); - Igc_Vbei=Igc_Vbei+Igc_Itzr*(*Itzr_Vbei); + Igc_avalf=-(*Itzr)+(*Itxf)-Ibcj; + Igc_Vrxf=Igc_Itxf*(*Itxf_Vrxf); + Igc_Vrth=Igc_Itzr*(*Itzr_Vrth); + Igc_Vbci=Igc_Itzr*(*Itzr_Vbci); + Igc_Vbei=Igc_Itzr*(*Itzr_Vbei); + Igc_Vrth=Igc_Vrth+Igc_Ibcj*Ibcj_Vrth; Igc_Vbci=Igc_Vbci+Igc_Ibcj*Ibcj_Vbci; + Igc_Vrth=Igc_Vrth+Igc_avalf*avalf_Vrth; Igc_Vbci=Igc_Vbci+Igc_avalf*avalf_Vbci; }else{ Igc=0.0; - Igc_Vbei=0.0; + Igc_Vrxf=0.0; + Igc_Vrth=0.0; Igc_Vbci=0.0; + Igc_Vbei=0.0; } (*Ibc)=Ibcj-Igc; Ibc_Ibcj=1.0; Ibc_Igc=-1.0; + *Ibc_Vrth=Ibc_Ibcj*Ibcj_Vrth; *Ibc_Vbci=Ibc_Ibcj*Ibcj_Vbci; - *Ibc_Vbei=Ibc_Igc*Igc_Vbei; + *Ibc_Vrxf=Ibc_Igc*Igc_Vrxf; + *Ibc_Vrth=(*Ibc_Vrth)+Ibc_Igc*Igc_Vrth; *Ibc_Vbci=(*Ibc_Vbci)+Ibc_Igc*Igc_Vbci; + *Ibc_Vbei=Ibc_Igc*Igc_Vbei; if(p[1]>0.0){ - (*Ircx)=(*Vrcx)/p[1]; - *Ircx_Vrcx=1.0/p[1]; + (*Ircx)=(*Vrcx)/RCXatT; + *Ircx_Vrcx=1.0/RCXatT; + Ircx_RCXatT=-(*Vrcx)/(RCXatT*RCXatT); + *Ircx_Vrth=Ircx_RCXatT*RCXatT_Vrth; }else{ (*Ircx)=0.0; *Ircx_Vrcx=0.0; + *Ircx_Vrth=0.0; } argi=(*Vbci)/Vtv; argi_Vbci=1.0/Vtv; + argi_Vtv=-(*Vbci)/(Vtv*Vtv); + argi_Vrth=argi_Vtv*Vtv_Vrth; expi=exp(argi); expi_argi=expi; expi_Vbci=expi_argi*argi_Vbci; + expi_Vrth=expi_argi*argi_Vrth; argx=(*Vbcx)/Vtv; argx_Vbcx=1.0/Vtv; + argx_Vtv=-(*Vbcx)/(Vtv*Vtv); + argx_Vrth=argx_Vtv*Vtv_Vrth; expx=exp(argx); expx_argx=expx; expx_Vbcx=expx_argx*argx_Vbcx; - Kbci=sqrt(1.0+p[4]*expi); - Kbci_expi=p[4]/(2.0*sqrt(expi*p[4]+1.0)); + expx_Vrth=expx_argx*argx_Vrth; + Kbci=sqrt(1.0+GAMMatT*expi); + Kbci_GAMMatT=expi/(2.0*sqrt(expi*GAMMatT+1.0)); + Kbci_expi=GAMMatT/(2.0*sqrt(expi*GAMMatT+1.0)); + Kbci_Vrth=Kbci_GAMMatT*GAMMatT_Vrth; Kbci_Vbci=Kbci_expi*expi_Vbci; - Kbcx=sqrt(1.0+p[4]*expx); - Kbcx_expx=p[4]/(2.0*sqrt(expx*p[4]+1.0)); + Kbci_Vrth=Kbci_Vrth+Kbci_expi*expi_Vrth; + Kbcx=sqrt(1.0+GAMMatT*expx); + Kbcx_GAMMatT=expx/(2.0*sqrt(expx*GAMMatT+1.0)); + Kbcx_expx=GAMMatT/(2.0*sqrt(expx*GAMMatT+1.0)); + Kbcx_Vrth=Kbcx_GAMMatT*GAMMatT_Vrth; Kbcx_Vbcx=Kbcx_expx*expx_Vbcx; + Kbcx_Vrth=Kbcx_Vrth+Kbcx_expx*expx_Vrth; if(p[2]>0.0){ rKp1=(Kbci+1.0)/(Kbcx+1.0); rKp1_Kbci=1.0/(Kbcx+1.0); rKp1_Kbcx=-(Kbci+1.0)/((Kbcx+1.0)*(Kbcx+1.0)); + rKp1_Vrth=rKp1_Kbci*Kbci_Vrth; rKp1_Vbci=rKp1_Kbci*Kbci_Vbci; + rKp1_Vrth=rKp1_Vrth+rKp1_Kbcx*Kbcx_Vrth; rKp1_Vbcx=rKp1_Kbcx*Kbcx_Vbcx; xvar1=log(rKp1); xvar1_rKp1=1.0/rKp1; + xvar1_Vrth=xvar1_rKp1*rKp1_Vrth; xvar1_Vbci=xvar1_rKp1*rKp1_Vbci; xvar1_Vbcx=xvar1_rKp1*rKp1_Vbcx; - Iohm=((*Vrci)+Vtv*(Kbci-Kbcx-xvar1))/p[2]; - Iohm_Vrci=1.0/p[2]; - Iohm_Kbci=Vtv/p[2]; - Iohm_Kbcx=-Vtv/p[2]; - Iohm_xvar1=-Vtv/p[2]; + Iohm=((*Vrci)+Vtv*(Kbci-Kbcx-xvar1))/RCIatT; + Iohm_Vrci=1.0/RCIatT; + Iohm_Vtv=(-xvar1-Kbcx+Kbci)/RCIatT; + Iohm_Kbci=Vtv/RCIatT; + Iohm_Kbcx=-Vtv/RCIatT; + Iohm_xvar1=-Vtv/RCIatT; + Iohm_RCIatT=-(Vtv*(-xvar1-Kbcx+Kbci)+(*Vrci))/(RCIatT*RCIatT); + Iohm_Vrth=Iohm_Vtv*Vtv_Vrth; + Iohm_Vrth=Iohm_Vrth+Iohm_Kbci*Kbci_Vrth; Iohm_Vbci=Iohm_Kbci*Kbci_Vbci; + Iohm_Vrth=Iohm_Vrth+Iohm_Kbcx*Kbcx_Vrth; Iohm_Vbcx=Iohm_Kbcx*Kbcx_Vbcx; + Iohm_Vrth=Iohm_Vrth+Iohm_xvar1*xvar1_Vrth; Iohm_Vbci=Iohm_Vbci+Iohm_xvar1*xvar1_Vbci; Iohm_Vbcx=Iohm_Vbcx+Iohm_xvar1*xvar1_Vbcx; - derf=IVO*p[2]*Iohm/(1.0+0.5*IVO*IHRCF*sqrt((*Vrci)*(*Vrci)+0.01)); - derf_Iohm=IVO*p[2]/(0.5*IHRCF*IVO*sqrt(((*Vrci)*(*Vrci))+0.01)+1.0); - derf_Vrci=-0.5*IHRCF*Iohm*(IVO*IVO)*p[2]*(*Vrci)/(sqrt(((*Vrci)*(*Vrci))+0.01)*((0.5*IHRCF*IVO*sqrt(((*Vrci)*(*Vrci))+0.01)+1.0)*(0.5*IHRCF*IVO*sqrt(((*Vrci)*(*Vrci))+0.01)+1.0))); + Iohm_Vrth=Iohm_Vrth+Iohm_RCIatT*RCIatT_Vrth; + derf=IVO*RCIatT*Iohm/(1.0+0.5*IVO*IHRCF*sqrt((*Vrci)*(*Vrci)+0.01)); + derf_IVO=Iohm*RCIatT/(0.5*IHRCF*IVO*sqrt(((*Vrci)*(*Vrci))+0.01)+1.0)-0.5*IHRCF*Iohm*IVO*RCIatT*sqrt(((*Vrci)*(*Vrci))+0.01)/((0.5*IHRCF*IVO*sqrt(((*Vrci)*(*Vrci))+0.01)+1.0)*(0.5*IHRCF*IVO*sqrt(((*Vrci)*(*Vrci))+0.01)+1.0)); + derf_RCIatT=Iohm*IVO/(0.5*IHRCF*IVO*sqrt(((*Vrci)*(*Vrci))+0.01)+1.0); + derf_Iohm=IVO*RCIatT/(0.5*IHRCF*IVO*sqrt(((*Vrci)*(*Vrci))+0.01)+1.0); + derf_Vrci=-0.5*IHRCF*Iohm*(IVO*IVO)*RCIatT*(*Vrci)/(sqrt(((*Vrci)*(*Vrci))+0.01)*((0.5*IHRCF*IVO*sqrt(((*Vrci)*(*Vrci))+0.01)+1.0)*(0.5*IHRCF*IVO*sqrt(((*Vrci)*(*Vrci))+0.01)+1.0))); + derf_Vrth=derf_IVO*IVO_Vrth; + derf_Vrth=derf_Vrth+derf_RCIatT*RCIatT_Vrth; derf_Vrci=derf_Vrci+derf_Iohm*Iohm_Vrci; + derf_Vrth=derf_Vrth+derf_Iohm*Iohm_Vrth; derf_Vbci=derf_Iohm*Iohm_Vbci; derf_Vbcx=derf_Iohm*Iohm_Vbcx; (*Irci)=Iohm/sqrt(1.0+derf*derf); Irci_Iohm=1.0/sqrt((derf*derf)+1.0); Irci_derf=-derf*Iohm/pow(((derf*derf)+1.0),(3.0/2.0)); *Irci_Vrci=Irci_Iohm*Iohm_Vrci; + *Irci_Vrth=Irci_Iohm*Iohm_Vrth; *Irci_Vbci=Irci_Iohm*Iohm_Vbci; *Irci_Vbcx=Irci_Iohm*Iohm_Vbcx; + *Irci_Vrth=(*Irci_Vrth)+Irci_derf*derf_Vrth; *Irci_Vrci=(*Irci_Vrci)+Irci_derf*derf_Vrci; *Irci_Vbci=(*Irci_Vbci)+Irci_derf*derf_Vbci; *Irci_Vbcx=(*Irci_Vbcx)+Irci_derf*derf_Vbcx; }else{ (*Irci)=0.0; *Irci_Vrci=0.0; + *Irci_Vrth=0.0; *Irci_Vbci=0.0; *Irci_Vbcx=0.0; } if(p[6]>0.0){ - (*Irbx)=(*Vrbx)/p[6]; - *Irbx_Vrbx=1.0/p[6]; + (*Irbx)=(*Vrbx)/RBXatT; + *Irbx_Vrbx=1.0/RBXatT; + Irbx_RBXatT=-(*Vrbx)/(RBXatT*RBXatT); + *Irbx_Vrth=Irbx_RBXatT*RBXatT_Vrth; }else{ (*Irbx)=0.0; *Irbx_Vrbx=0.0; + *Irbx_Vrth=0.0; } if(p[7]>0.0){ - (*Irbi)=(*Vrbi)*qb/p[7]; - *Irbi_Vrbi=qb/p[7]; - Irbi_qb=(*Vrbi)/p[7]; + (*Irbi)=(*Vrbi)*qb/RBIatT; + *Irbi_Vrbi=qb/RBIatT; + Irbi_qb=(*Vrbi)/RBIatT; + Irbi_RBIatT=-qb*(*Vrbi)/(RBIatT*RBIatT); + *Irbi_Vrth=Irbi_qb*qb_Vrth; *Irbi_Vbei=Irbi_qb*qb_Vbei; *Irbi_Vbci=Irbi_qb*qb_Vbci; + *Irbi_Vrth=(*Irbi_Vrth)+Irbi_RBIatT*RBIatT_Vrth; }else{ (*Irbi)=0.0; *Irbi_Vrbi=0.0; + *Irbi_Vrth=0.0; *Irbi_Vbei=0.0; *Irbi_Vbci=0.0; } if(p[8]>0.0){ - (*Ire)=(*Vre)/p[8]; - *Ire_Vre=1.0/p[8]; + (*Ire)=(*Vre)/REatT; + *Ire_Vre=1.0/REatT; + Ire_REatT=-(*Vre)/(REatT*REatT); + *Ire_Vrth=Ire_REatT*REatT_Vrth; }else{ (*Ire)=0.0; *Ire_Vre=0.0; + *Ire_Vrth=0.0; } if(p[10]>0.0){ - (*Irbp)=(*Vrbp)*qbp/p[10]; - *Irbp_Vrbp=qbp/p[10]; - Irbp_qbp=(*Vrbp)/p[10]; + (*Irbp)=(*Vrbp)*qbp/RBPatT; + *Irbp_Vrbp=qbp/RBPatT; + Irbp_qbp=(*Vrbp)/RBPatT; + Irbp_RBPatT=-qbp*(*Vrbp)/(RBPatT*RBPatT); + *Irbp_Vrth=Irbp_qbp*qbp_Vrth; *Irbp_Vbep=Irbp_qbp*qbp_Vbep; *Irbp_Vbci=Irbp_qbp*qbp_Vbci; + *Irbp_Vrth=(*Irbp_Vrth)+Irbp_RBPatT*RBPatT_Vrth; }else{ (*Irbp)=0.0; *Irbp_Vrbp=0.0; + *Irbp_Vrth=0.0; *Irbp_Vbep=0.0; *Irbp_Vbci=0.0; } if((p[47]>0.0)||(p[49]>0.0)){ argi=(*Vbcp)/(p[48]*Vtv); argi_Vbcp=1.0/(p[48]*Vtv); + argi_Vtv=-(*Vbcp)/(p[48]*(Vtv*Vtv)); + argi_Vrth=argi_Vtv*Vtv_Vrth; expi=exp(argi); expi_argi=expi; expi_Vbcp=expi_argi*argi_Vbcp; + expi_Vrth=expi_argi*argi_Vrth; argn=(*Vbcp)/(p[50]*Vtv); argn_Vbcp=1.0/(p[50]*Vtv); + argn_Vtv=-(*Vbcp)/(p[50]*(Vtv*Vtv)); + argn_Vrth=argn_Vtv*Vtv_Vrth; expn=exp(argn); expn_argn=expn; expn_Vbcp=expn_argn*argn_Vbcp; - (*Ibcp)=p[47]*(expi-1.0)+p[49]*(expn-1.0); - Ibcp_expi=p[47]; - Ibcp_expn=p[49]; + expn_Vrth=expn_argn*argn_Vrth; + (*Ibcp)=IBCIPatT*(expi-1.0)+IBCNPatT*(expn-1.0); + Ibcp_IBCIPatT=expi-1.0; + Ibcp_expi=IBCIPatT; + Ibcp_IBCNPatT=expn-1.0; + Ibcp_expn=IBCNPatT; + *Ibcp_Vrth=Ibcp_IBCIPatT*IBCIPatT_Vrth; *Ibcp_Vbcp=Ibcp_expi*expi_Vbcp; + *Ibcp_Vrth=(*Ibcp_Vrth)+Ibcp_expi*expi_Vrth; + *Ibcp_Vrth=(*Ibcp_Vrth)+Ibcp_IBCNPatT*IBCNPatT_Vrth; *Ibcp_Vbcp=(*Ibcp_Vbcp)+Ibcp_expn*expn_Vbcp; + *Ibcp_Vrth=(*Ibcp_Vrth)+Ibcp_expn*expn_Vrth; }else{ (*Ibcp)=0.0; + *Ibcp_Vrth=0.0; *Ibcp_Vbcp=0.0; } if(p[9]>0.0){ - (*Irs)=(*Vrs)/p[9]; - *Irs_Vrs=1.0/p[9]; + (*Irs)=(*Vrs)/RSatT; + *Irs_Vrs=1.0/RSatT; + Irs_RSatT=-(*Vrs)/(RSatT*RSatT); + *Irs_Vrth=Irs_RSatT*RSatT_Vrth; }else{ (*Irs)=0.0; *Irs_Vrs=0.0; + *Irs_Vrth=0.0; } if(Ifi>0.0){ sgIf=1.0; @@ -4993,9 +7815,11 @@ double Qbep_qdbep,Qbep_Ifp,Qbcp_qdbcp; } rIf=Ifi*sgIf*IITF; rIf_Ifi=IITF*sgIf; + rIf_Vrth=rIf_Ifi*Ifi_Vrth; rIf_Vbei=rIf_Ifi*Ifi_Vbei; mIf=rIf/(rIf+1.0); mIf_rIf=1.0/(rIf+1.0)-rIf/((rIf+1.0)*(rIf+1.0)); + mIf_Vrth=mIf_rIf*rIf_Vrth; mIf_Vbei=mIf_rIf*rIf_Vbei; xvar1=(*Vbci)*IVTF/1.44; xvar1_Vbci=0.6944444*IVTF; @@ -5006,95 +7830,219 @@ double Qbep_qdbep,Qbep_Ifp,Qbcp_qdbcp; tff_q1=p[57]*p[56]*(sgIf*(slTF+(mIf*mIf))*p[58]*xvar2+1.0); tff_xvar2=(q1*p[57]+1.0)*sgIf*(slTF+(mIf*mIf))*p[56]*p[58]; tff_mIf=2.0*mIf*(q1*p[57]+1.0)*sgIf*p[56]*p[58]*xvar2; + tff_Vrth=tff_q1*q1_Vrth; tff_Vbei=tff_q1*q1_Vbei; tff_Vbci=tff_q1*q1_Vbci; tff_Vbci=tff_Vbci+tff_xvar2*xvar2_Vbci; + tff_Vrth=tff_Vrth+tff_mIf*mIf_Vrth; tff_Vbei=tff_Vbei+tff_mIf*mIf_Vbei; - (*Qbe)=p[16]*qdbe*p[32]+tff*Ifi/qb; - Qbe_qdbe=p[16]*p[32]; + (*Qbe)=CJEatT*qdbe*p[32]+tff*Ifi/qb; + Qbe_CJEatT=qdbe*p[32]; + Qbe_qdbe=CJEatT*p[32]; Qbe_tff=Ifi/qb; Qbe_Ifi=tff/qb; Qbe_qb=-Ifi*tff/(qb*qb); + *Qbe_Vrth=Qbe_CJEatT*CJEatT_Vrth; + *Qbe_Vrth=(*Qbe_Vrth)+Qbe_qdbe*qdbe_Vrth; *Qbe_Vbei=Qbe_qdbe*qdbe_Vbei; + *Qbe_Vrth=(*Qbe_Vrth)+Qbe_tff*tff_Vrth; *Qbe_Vbei=(*Qbe_Vbei)+Qbe_tff*tff_Vbei; *Qbe_Vbci=Qbe_tff*tff_Vbci; + *Qbe_Vrth=(*Qbe_Vrth)+Qbe_Ifi*Ifi_Vrth; *Qbe_Vbei=(*Qbe_Vbei)+Qbe_Ifi*Ifi_Vbei; + *Qbe_Vrth=(*Qbe_Vrth)+Qbe_qb*qb_Vrth; *Qbe_Vbei=(*Qbe_Vbei)+Qbe_qb*qb_Vbei; *Qbe_Vbci=(*Qbe_Vbci)+Qbe_qb*qb_Vbci; - (*Qbex)=p[16]*qdbex*(1.0-p[32]); - Qbex_qdbex=p[16]*(1.0-p[32]); + (*Qbex)=CJEatT*qdbex*(1.0-p[32]); + Qbex_CJEatT=qdbex*(1.0-p[32]); + Qbex_qdbex=CJEatT*(1.0-p[32]); + *Qbex_Vrth=Qbex_CJEatT*CJEatT_Vrth; + *Qbex_Vrth=(*Qbex_Vrth)+Qbex_qdbex*qdbex_Vrth; *Qbex_Vbex=Qbex_qdbex*qdbex_Vbex; - (*Qbc)=p[21]*qdbc+p[61]*Iri+p[22]*Kbci; - Qbc_qdbc=p[21]; + (*Qbc)=CJCatT*qdbc+p[61]*Iri+p[22]*Kbci; + Qbc_CJCatT=qdbc; + Qbc_qdbc=CJCatT; Qbc_Iri=p[61]; Qbc_Kbci=p[22]; + *Qbc_Vrth=Qbc_CJCatT*CJCatT_Vrth; + *Qbc_Vrth=(*Qbc_Vrth)+Qbc_qdbc*qdbc_Vrth; *Qbc_Vbci=Qbc_qdbc*qdbc_Vbci; + *Qbc_Vrth=(*Qbc_Vrth)+Qbc_Iri*Iri_Vrth; *Qbc_Vbci=(*Qbc_Vbci)+Qbc_Iri*Iri_Vbci; + *Qbc_Vrth=(*Qbc_Vrth)+Qbc_Kbci*Kbci_Vrth; *Qbc_Vbci=(*Qbc_Vbci)+Qbc_Kbci*Kbci_Vbci; (*Qbcx)=p[22]*Kbcx; Qbcx_Kbcx=p[22]; + *Qbcx_Vrth=Qbcx_Kbcx*Kbcx_Vrth; *Qbcx_Vbcx=Qbcx_Kbcx*Kbcx_Vbcx; - (*Qbep)=p[23]*qdbep+p[61]*Ifp; - Qbep_qdbep=p[23]; + (*Qbep)=CJEPatT*qdbep+p[61]*Ifp; + Qbep_CJEPatT=qdbep; + Qbep_qdbep=CJEPatT; Qbep_Ifp=p[61]; + *Qbep_Vrth=Qbep_CJEPatT*CJEPatT_Vrth; + *Qbep_Vrth=(*Qbep_Vrth)+Qbep_qdbep*qdbep_Vrth; *Qbep_Vbep=Qbep_qdbep*qdbep_Vbep; + *Qbep_Vrth=(*Qbep_Vrth)+Qbep_Ifp*Ifp_Vrth; *Qbep_Vbep=(*Qbep_Vbep)+Qbep_Ifp*Ifp_Vbep; *Qbep_Vbci=Qbep_Ifp*Ifp_Vbci; - (*Qbcp)=p[27]*qdbcp+p[87]*(*Vbcp); - Qbcp_qdbcp=p[27]; + (*Qbcp)=CJCPatT*qdbcp+p[87]*(*Vbcp); + Qbcp_CJCPatT=qdbcp; + Qbcp_qdbcp=CJCPatT; *Qbcp_Vbcp=p[87]; + *Qbcp_Vrth=Qbcp_CJCPatT*CJCPatT_Vrth; + *Qbcp_Vrth=(*Qbcp_Vrth)+Qbcp_qdbcp*qdbcp_Vrth; *Qbcp_Vbcp=(*Qbcp_Vbcp)+Qbcp_qdbcp*qdbcp_Vbcp; (*Qbeo)=(*Vbe)*p[15]; *Qbeo_Vbe=p[15]; (*Qbco)=(*Vbc)*p[20]; *Qbco_Vbc=p[20]; + (*Ith)=-((*Ibe)*(*Vbei)+(*Ibc)*(*Vbci)+((*Itxf)-(*Itzr))*(*Vcei)+(*Ibex)*(*Vbex)+(*Ibep)*(*Vbep)+(*Irs)*(*Vrs)+(*Ibcp)*(*Vbcp)+(*Iccp)*(*Vcep)+(*Ircx)*(*Vrcx)+(*Irci)*(*Vrci)+(*Irbx)*(*Vrbx)+(*Irbi)*(*Vrbi)+(*Ire)*(*Vre)+(*Irbp)*(*Vrbp)); + Ith_Ibe=-(*Vbei); + *Ith_Vbei=-(*Ibe); + Ith_Ibc=-(*Vbci); + *Ith_Vbci=-(*Ibc); + Ith_Itxf=-(*Vcei); + Ith_Itzr=(*Vcei); + *Ith_Vcei=(*Itzr)-(*Itxf); + Ith_Ibex=-(*Vbex); + *Ith_Vbex=-(*Ibex); + Ith_Ibep=-(*Vbep); + *Ith_Vbep=-(*Ibep); + Ith_Irs=-(*Vrs); + *Ith_Vrs=-(*Irs); + Ith_Ibcp=-(*Vbcp); + *Ith_Vbcp=-(*Ibcp); + Ith_Iccp=-(*Vcep); + *Ith_Vcep=-(*Iccp); + Ith_Ircx=-(*Vrcx); + *Ith_Vrcx=-(*Ircx); + Ith_Irci=-(*Vrci); + *Ith_Vrci=-(*Irci); + Ith_Irbx=-(*Vrbx); + *Ith_Vrbx=-(*Irbx); + Ith_Irbi=-(*Vrbi); + *Ith_Vrbi=-(*Irbi); + Ith_Ire=-(*Vre); + *Ith_Vre=-(*Ire); + Ith_Irbp=-(*Vrbp); + *Ith_Vrbp=-(*Irbp); + *Ith_Vrth=Ith_Ibe*(*Ibe_Vrth); + *Ith_Vbei=(*Ith_Vbei)+Ith_Ibe*(*Ibe_Vbei); + *Ith_Vrth=(*Ith_Vrth)+Ith_Ibc*(*Ibc_Vrth); + *Ith_Vbci=(*Ith_Vbci)+Ith_Ibc*(*Ibc_Vbci); + *Ith_Vrxf=Ith_Ibc*(*Ibc_Vrxf); + *Ith_Vbei=(*Ith_Vbei)+Ith_Ibc*(*Ibc_Vbei); + *Ith_Vrxf=(*Ith_Vrxf)+Ith_Itxf*(*Itxf_Vrxf); + *Ith_Vrth=(*Ith_Vrth)+Ith_Itzr*(*Itzr_Vrth); + *Ith_Vbci=(*Ith_Vbci)+Ith_Itzr*(*Itzr_Vbci); + *Ith_Vbei=(*Ith_Vbei)+Ith_Itzr*(*Itzr_Vbei); + *Ith_Vrth=(*Ith_Vrth)+Ith_Ibex*(*Ibex_Vrth); + *Ith_Vbex=(*Ith_Vbex)+Ith_Ibex*(*Ibex_Vbex); + *Ith_Vrth=(*Ith_Vrth)+Ith_Ibep*(*Ibep_Vrth); + *Ith_Vbep=(*Ith_Vbep)+Ith_Ibep*(*Ibep_Vbep); + *Ith_Vrs=(*Ith_Vrs)+Ith_Irs*(*Irs_Vrs); + *Ith_Vrth=(*Ith_Vrth)+Ith_Irs*(*Irs_Vrth); + *Ith_Vrth=(*Ith_Vrth)+Ith_Ibcp*(*Ibcp_Vrth); + *Ith_Vbcp=(*Ith_Vbcp)+Ith_Ibcp*(*Ibcp_Vbcp); + *Ith_Vrth=(*Ith_Vrth)+Ith_Iccp*(*Iccp_Vrth); + *Ith_Vbep=(*Ith_Vbep)+Ith_Iccp*(*Iccp_Vbep); + *Ith_Vbci=(*Ith_Vbci)+Ith_Iccp*(*Iccp_Vbci); + *Ith_Vbcp=(*Ith_Vbcp)+Ith_Iccp*(*Iccp_Vbcp); + *Ith_Vrcx=(*Ith_Vrcx)+Ith_Ircx*(*Ircx_Vrcx); + *Ith_Vrth=(*Ith_Vrth)+Ith_Ircx*(*Ircx_Vrth); + *Ith_Vrci=(*Ith_Vrci)+Ith_Irci*(*Irci_Vrci); + *Ith_Vrth=(*Ith_Vrth)+Ith_Irci*(*Irci_Vrth); + *Ith_Vbci=(*Ith_Vbci)+Ith_Irci*(*Irci_Vbci); + *Ith_Vbcx=Ith_Irci*(*Irci_Vbcx); + *Ith_Vrbx=(*Ith_Vrbx)+Ith_Irbx*(*Irbx_Vrbx); + *Ith_Vrth=(*Ith_Vrth)+Ith_Irbx*(*Irbx_Vrth); + *Ith_Vrbi=(*Ith_Vrbi)+Ith_Irbi*(*Irbi_Vrbi); + *Ith_Vrth=(*Ith_Vrth)+Ith_Irbi*(*Irbi_Vrth); + *Ith_Vbei=(*Ith_Vbei)+Ith_Irbi*(*Irbi_Vbei); + *Ith_Vbci=(*Ith_Vbci)+Ith_Irbi*(*Irbi_Vbci); + *Ith_Vre=(*Ith_Vre)+Ith_Ire*(*Ire_Vre); + *Ith_Vrth=(*Ith_Vrth)+Ith_Ire*(*Ire_Vrth); + *Ith_Vrbp=(*Ith_Vrbp)+Ith_Irbp*(*Irbp_Vrbp); + *Ith_Vrth=(*Ith_Vrth)+Ith_Irbp*(*Irbp_Vrth); + *Ith_Vbep=(*Ith_Vbep)+Ith_Irbp*(*Irbp_Vbep); + *Ith_Vbci=(*Ith_Vbci)+Ith_Irbp*(*Irbp_Vbci); + if(p[83]>0.0){ + (*Irth)=(*Vrth)/p[83]; + *Irth_Vrth=1.0/p[83]; + }else{ + (*Irth)=0.0; + *Irth_Vrth=0.0; + } + (*Qcth)=(*Vrth)*p[84]; + *Qcth_Vrth=p[84]; + (*Flxf)=LEP*(*Ixxf); + Flxf_Ixxf=LEP; + *Flxf_Vrxf=Flxf_Ixxf*(*Ixxf_Vrxf); + (*Qcxf)=CEP*(*Vcxf); + *Qcxf_Vcxf=CEP; /* Scale outputs */ if((*SCALE)!=1.0){ *Ibe=(*SCALE)*(*Ibe); + *Ibe_Vrth=(*SCALE)*(*Ibe_Vrth); *Ibe_Vbei=(*SCALE)*(*Ibe_Vbei); *Ibex=(*SCALE)*(*Ibex); + *Ibex_Vrth=(*SCALE)*(*Ibex_Vrth); *Ibex_Vbex=(*SCALE)*(*Ibex_Vbex); - *Itzf=(*SCALE)*(*Itzf); - *Itzf_Vbei=(*SCALE)*(*Itzf_Vbei); - *Itzf_Vbci=(*SCALE)*(*Itzf_Vbci); + *Itxf=(*SCALE)*(*Itxf); + *Itxf_Vrxf=(*SCALE)*(*Itxf_Vrxf); *Itzr=(*SCALE)*(*Itzr); + *Itzr_Vrth=(*SCALE)*(*Itzr_Vrth); *Itzr_Vbci=(*SCALE)*(*Itzr_Vbci); *Itzr_Vbei=(*SCALE)*(*Itzr_Vbei); *Ibc=(*SCALE)*(*Ibc); + *Ibc_Vrth=(*SCALE)*(*Ibc_Vrth); *Ibc_Vbci=(*SCALE)*(*Ibc_Vbci); + *Ibc_Vrxf=(*SCALE)*(*Ibc_Vrxf); *Ibc_Vbei=(*SCALE)*(*Ibc_Vbei); *Ibep=(*SCALE)*(*Ibep); + *Ibep_Vrth=(*SCALE)*(*Ibep_Vrth); *Ibep_Vbep=(*SCALE)*(*Ibep_Vbep); *Ircx=(*SCALE)*(*Ircx); *Ircx_Vrcx=(*SCALE)*(*Ircx_Vrcx); + *Ircx_Vrth=(*SCALE)*(*Ircx_Vrth); *Irci=(*SCALE)*(*Irci); *Irci_Vrci=(*SCALE)*(*Irci_Vrci); + *Irci_Vrth=(*SCALE)*(*Irci_Vrth); *Irci_Vbci=(*SCALE)*(*Irci_Vbci); *Irci_Vbcx=(*SCALE)*(*Irci_Vbcx); *Irbx=(*SCALE)*(*Irbx); *Irbx_Vrbx=(*SCALE)*(*Irbx_Vrbx); + *Irbx_Vrth=(*SCALE)*(*Irbx_Vrth); *Irbi=(*SCALE)*(*Irbi); *Irbi_Vrbi=(*SCALE)*(*Irbi_Vrbi); + *Irbi_Vrth=(*SCALE)*(*Irbi_Vrth); *Irbi_Vbei=(*SCALE)*(*Irbi_Vbei); *Irbi_Vbci=(*SCALE)*(*Irbi_Vbci); *Ire=(*SCALE)*(*Ire); *Ire_Vre=(*SCALE)*(*Ire_Vre); + *Ire_Vrth=(*SCALE)*(*Ire_Vrth); *Irbp=(*SCALE)*(*Irbp); *Irbp_Vrbp=(*SCALE)*(*Irbp_Vrbp); + *Irbp_Vrth=(*SCALE)*(*Irbp_Vrth); *Irbp_Vbep=(*SCALE)*(*Irbp_Vbep); *Irbp_Vbci=(*SCALE)*(*Irbp_Vbci); *Qbe=(*SCALE)*(*Qbe); + *Qbe_Vrth=(*SCALE)*(*Qbe_Vrth); *Qbe_Vbei=(*SCALE)*(*Qbe_Vbei); *Qbe_Vbci=(*SCALE)*(*Qbe_Vbci); *Qbex=(*SCALE)*(*Qbex); + *Qbex_Vrth=(*SCALE)*(*Qbex_Vrth); *Qbex_Vbex=(*SCALE)*(*Qbex_Vbex); *Qbc=(*SCALE)*(*Qbc); + *Qbc_Vrth=(*SCALE)*(*Qbc_Vrth); *Qbc_Vbci=(*SCALE)*(*Qbc_Vbci); *Qbcx=(*SCALE)*(*Qbcx); + *Qbcx_Vrth=(*SCALE)*(*Qbcx_Vrth); *Qbcx_Vbcx=(*SCALE)*(*Qbcx_Vbcx); *Qbep=(*SCALE)*(*Qbep); + *Qbep_Vrth=(*SCALE)*(*Qbep_Vrth); *Qbep_Vbep=(*SCALE)*(*Qbep_Vbep); *Qbep_Vbci=(*SCALE)*(*Qbep_Vbci); *Qbeo=(*SCALE)*(*Qbeo); @@ -5102,15 +8050,51 @@ double Qbep_qdbep,Qbep_Ifp,Qbcp_qdbcp; *Qbco=(*SCALE)*(*Qbco); *Qbco_Vbc=(*SCALE)*(*Qbco_Vbc); *Ibcp=(*SCALE)*(*Ibcp); + *Ibcp_Vrth=(*SCALE)*(*Ibcp_Vrth); *Ibcp_Vbcp=(*SCALE)*(*Ibcp_Vbcp); *Iccp=(*SCALE)*(*Iccp); + *Iccp_Vrth=(*SCALE)*(*Iccp_Vrth); *Iccp_Vbep=(*SCALE)*(*Iccp_Vbep); *Iccp_Vbci=(*SCALE)*(*Iccp_Vbci); *Iccp_Vbcp=(*SCALE)*(*Iccp_Vbcp); *Irs=(*SCALE)*(*Irs); *Irs_Vrs=(*SCALE)*(*Irs_Vrs); + *Irs_Vrth=(*SCALE)*(*Irs_Vrth); *Qbcp=(*SCALE)*(*Qbcp); + *Qbcp_Vrth=(*SCALE)*(*Qbcp_Vrth); *Qbcp_Vbcp=(*SCALE)*(*Qbcp_Vbcp); + *Irth=(*SCALE)*(*Irth); + *Irth_Vrth=(*SCALE)*(*Irth_Vrth); + *Ith=(*SCALE)*(*Ith); + *Ith_Vrth=(*SCALE)*(*Ith_Vrth); + *Ith_Vbei=(*SCALE)*(*Ith_Vbei); + *Ith_Vbci=(*SCALE)*(*Ith_Vbci); + *Ith_Vrxf=(*SCALE)*(*Ith_Vrxf); + *Ith_Vcei=(*SCALE)*(*Ith_Vcei); + *Ith_Vbex=(*SCALE)*(*Ith_Vbex); + *Ith_Vbep=(*SCALE)*(*Ith_Vbep); + *Ith_Vrs=(*SCALE)*(*Ith_Vrs); + *Ith_Vbcp=(*SCALE)*(*Ith_Vbcp); + *Ith_Vcep=(*SCALE)*(*Ith_Vcep); + *Ith_Vrcx=(*SCALE)*(*Ith_Vrcx); + *Ith_Vrci=(*SCALE)*(*Ith_Vrci); + *Ith_Vbcx=(*SCALE)*(*Ith_Vbcx); + *Ith_Vrbx=(*SCALE)*(*Ith_Vrbx); + *Ith_Vrbi=(*SCALE)*(*Ith_Vrbi); + *Ith_Vre=(*SCALE)*(*Ith_Vre); + *Ith_Vrbp=(*SCALE)*(*Ith_Vrbp); + *Qcth=(*SCALE)*(*Qcth); + *Qcth_Vrth=(*SCALE)*(*Qcth_Vrth); + *Ixzf=(*SCALE)*(*Ixzf); + *Ixzf_Vrth=(*SCALE)*(*Ixzf_Vrth); + *Ixzf_Vbei=(*SCALE)*(*Ixzf_Vbei); + *Ixzf_Vbci=(*SCALE)*(*Ixzf_Vbci); + *Ixxf=(*SCALE)*(*Ixxf); + *Ixxf_Vrxf=(*SCALE)*(*Ixxf_Vrxf); + *Qcxf=(*SCALE)*(*Qcxf); + *Qcxf_Vcxf=(*SCALE)*(*Qcxf_Vcxf); + *Flxf=(*SCALE)*(*Flxf); + *Flxf_Vrxf=(*SCALE)*(*Flxf_Vrxf); } return(0); } diff --git a/src/spicelib/devices/vbic/vbicnoise.c b/src/spicelib/devices/vbic/vbicnoise.c index 09dea77a6..f1995a24d 100644 --- a/src/spicelib/devices/vbic/vbicnoise.c +++ b/src/spicelib/devices/vbic/vbicnoise.c @@ -127,11 +127,16 @@ VBICnoise (int mode, int operation, GENmodel *genmodel, CKTcircuit *ckt, Ndata * ckt,THERMNOISE,inst->VBICsubsSINode,inst->VBICsubsNode, *(ckt->CKTstate0 + inst->VBICirs_Vrs), dtemp); - - NevalSrc(&noizDens[VBICICNOIZ],&lnNdens[VBICICNOIZ], - ckt,SHOTNOISE,inst->VBICcollCINode, inst->VBICemitEINode, - *(ckt->CKTstate0 + inst->VBICitzf)); - + if (!inst->VBIC_excessPhase) { + NevalSrc(&noizDens[VBICICNOIZ],&lnNdens[VBICICNOIZ], + ckt,SHOTNOISE,inst->VBICcollCINode, inst->VBICemitEINode, + *(ckt->CKTstate0 + inst->VBICitzf)); + } + if (inst->VBIC_excessPhase) { + NevalSrc(&noizDens[VBICICNOIZ],&lnNdens[VBICICNOIZ], + ckt,SHOTNOISE,inst->VBICcollCINode, inst->VBICemitEINode, + *(ckt->CKTstate0 + inst->VBICitxf)); + } NevalSrc(&noizDens[VBICIBNOIZ],&lnNdens[VBICIBNOIZ], ckt,SHOTNOISE,inst->VBICbaseBINode, inst->VBICemitEINode, *(ckt->CKTstate0 + inst->VBICibe)); diff --git a/src/spicelib/devices/vbic/vbicpzld.c b/src/spicelib/devices/vbic/vbicpzld.c index 18c59410a..6fe9cc06a 100644 --- a/src/spicelib/devices/vbic/vbicpzld.c +++ b/src/spicelib/devices/vbic/vbicpzld.c @@ -30,7 +30,18 @@ VBICpzLoad(GENmodel *inModel, CKTcircuit *ckt, SPcomplex *s) ,Ibcp_Vbcp,Iccp_Vbep,Irs_Vrs,Iccp_Vbci,Iccp_Vbcp; double XQbe_Vbei, XQbe_Vbci, XQbex_Vbex, XQbc_Vbci, XQbcx_Vbcx, XQbep_Vbep, XQbep_Vbci, - XQbcp_Vbcp; + XQbcp_Vbcp, XQbeo_Vbe, XQbco_Vbc; + + double Ibe_Vrth, Ibex_Vrth, Itzf_Vrth=0.0, Itzr_Vrth, Ibc_Vrth, Ibep_Vrth, + Ircx_Vrth, Irci_Vrth, Irbx_Vrth, Irbi_Vrth, Ire_Vrth, Irbp_Vrth, + Ibcp_Vrth, Iccp_Vrth, Irs_Vrth, Irth_Vrth, Ith_Vrth, + Ith_Vbei, Ith_Vbci, Ith_Vcei, Ith_Vbex, Ith_Vbep, Ith_Vbcp, Ith_Vcep, + Ith_Vrci, Ith_Vbcx, Ith_Vrbi, Ith_Vrbp, Ith_Vrcx, Ith_Vrbx, Ith_Vre, Ith_Vrs; + double XQcth_Vrth, XQbe_Vrth, XQbex_Vrth, XQbc_Vrth, XQbcx_Vrth, XQbep_Vrth, XQbcp_Vrth; + + //NQS + double Itxf_Vrxf, Ibc_Vrxf, Ith_Vrxf, Ixzf_Vrth, Ixxf_Vrxf, XQcxf_Vcxf; + double Ixzf_Vbei, Ixzf_Vbci, Xl; /* loop through all the models */ for( ; model != NULL; model = VBICnextModel(model)) { @@ -83,17 +94,20 @@ c Stamp element: Ibex *(here->VBICbaseBXEmitEIPtr) += -Ibex_Vbex; *(here->VBICemitEIBaseBXPtr) += -Ibex_Vbex; *(here->VBICemitEIEmitEIPtr) += Ibex_Vbex; + + if (!here->VBIC_excessPhase) { /* c Stamp element: Itzf */ - *(here->VBICcollCIBaseBIPtr) += Itzf_Vbei; - *(here->VBICcollCIEmitEIPtr) += -Itzf_Vbei; - *(here->VBICcollCIBaseBIPtr) += Itzf_Vbci; - *(here->VBICcollCICollCIPtr) += -Itzf_Vbci; - *(here->VBICemitEIBaseBIPtr) += -Itzf_Vbei; - *(here->VBICemitEIEmitEIPtr) += Itzf_Vbei; - *(here->VBICemitEIBaseBIPtr) += -Itzf_Vbci; - *(here->VBICemitEICollCIPtr) += Itzf_Vbci; + *(here->VBICcollCIBaseBIPtr) += Itzf_Vbei; + *(here->VBICcollCIEmitEIPtr) += -Itzf_Vbei; + *(here->VBICcollCIBaseBIPtr) += Itzf_Vbci; + *(here->VBICcollCICollCIPtr) += -Itzf_Vbci; + *(here->VBICemitEIBaseBIPtr) += -Itzf_Vbei; + *(here->VBICemitEIEmitEIPtr) += Itzf_Vbei; + *(here->VBICemitEIBaseBIPtr) += -Itzf_Vbci; + *(here->VBICemitEICollCIPtr) += Itzf_Vbci; + } /* c Stamp element: Itzr */ @@ -126,10 +140,10 @@ c Stamp element: Ibep /* c Stamp element: Ircx */ - *(here->VBICcollCollPtr) += Ircx_Vrcx; + *(here->VBICcollCollPtr) += Ircx_Vrcx; *(here->VBICcollCXCollCXPtr) += Ircx_Vrcx; - *(here->VBICcollCXCollPtr) += -Ircx_Vrcx; - *(here->VBICcollCollCXPtr) += -Ircx_Vrcx; + *(here->VBICcollCXCollPtr) += -Ircx_Vrcx; + *(here->VBICcollCollCXPtr) += -Ircx_Vrcx; /* c Stamp element: Irci */ @@ -148,10 +162,10 @@ c Stamp element: Irci /* c Stamp element: Irbx */ - *(here->VBICbaseBasePtr) += Irbx_Vrbx; + *(here->VBICbaseBasePtr) += Irbx_Vrbx; *(here->VBICbaseBXBaseBXPtr) += Irbx_Vrbx; - *(here->VBICbaseBXBasePtr) += -Irbx_Vrbx; - *(here->VBICbaseBaseBXPtr) += -Irbx_Vrbx; + *(here->VBICbaseBXBasePtr) += -Irbx_Vrbx; + *(here->VBICbaseBaseBXPtr) += -Irbx_Vrbx; /* c Stamp element: Irbi */ @@ -170,10 +184,10 @@ c Stamp element: Irbi /* c Stamp element: Ire */ - *(here->VBICemitEmitPtr) += Ire_Vre; + *(here->VBICemitEmitPtr) += Ire_Vre; *(here->VBICemitEIEmitEIPtr) += Ire_Vre; - *(here->VBICemitEIEmitPtr) += -Ire_Vre; - *(here->VBICemitEmitEIPtr) += -Ire_Vre; + *(here->VBICemitEIEmitPtr) += -Ire_Vre; + *(here->VBICemitEmitEIPtr) += -Ire_Vre; /* c Stamp element: Irbp */ @@ -214,10 +228,204 @@ c Stamp element: Iccp /* c Stamp element: Irs */ - *(here->VBICsubsSubsPtr) += Irs_Vrs; + *(here->VBICsubsSubsPtr) += Irs_Vrs; *(here->VBICsubsSISubsSIPtr) += Irs_Vrs; - *(here->VBICsubsSISubsPtr) += -Irs_Vrs; - *(here->VBICsubsSubsSIPtr) += -Irs_Vrs; + *(here->VBICsubsSISubsPtr) += -Irs_Vrs; + *(here->VBICsubsSubsSIPtr) += -Irs_Vrs; + + if (here->VBIC_selfheat) { + + Ibe_Vrth = here->VBICibe_Vrth; + Ibex_Vrth = here->VBICibex_Vrth; + if (!here->VBIC_excessPhase) + Itzf_Vrth = here->VBICitzf_vrth; + Itzr_Vrth = here->VBICitzr_Vrth; + Ibc_Vrth = here->VBICibc_Vrth; + Ibep_Vrth = here->VBICibep_Vrth; + Ircx_Vrth = here->VBICircx_Vrth; + Irci_Vrth = here->VBICirci_Vrth; + Irbx_Vrth = here->VBICirbx_Vrth; + Irbi_Vrth = here->VBICirbi_Vrth; + Ire_Vrth = here->VBICire_Vrth; + Irbp_Vrth = here->VBICirbp_Vrth; + Ibcp_Vrth = here->VBICibcp_Vrth; + Iccp_Vrth = here->VBICiccp_Vrth; + Irs_Vrth = here->VBICirs_Vrth; + Irth_Vrth = here->VBICirth_Vrth; + Ith_Vrth = here->VBICith_Vrth; + Ith_Vbei = here->VBICith_Vbei; + Ith_Vbci = here->VBICith_Vbci; + Ith_Vcei = here->VBICith_Vcei; + Ith_Vbex = here->VBICith_Vbex; + Ith_Vbep = here->VBICith_Vbep; + Ith_Vbcp = here->VBICith_Vbcp; + Ith_Vcep = here->VBICith_Vcep; + Ith_Vrci = here->VBICith_Vrci; + Ith_Vbcx = here->VBICith_Vbcx; + Ith_Vrbi = here->VBICith_Vrbi; + Ith_Vrbp = here->VBICith_Vrbp; + Ith_Vrcx = here->VBICith_Vrcx; + Ith_Vrbx = here->VBICith_Vrbx; + Ith_Vre = here->VBICith_Vre; + Ith_Vrs = here->VBICith_Vrs; + +/* +c Stamp element: Ibe +*/ + *(here->VBICbaseBItempPtr) += Ibe_Vrth; + *(here->VBICemitEItempPtr) += -Ibe_Vrth; +/* +c Stamp element: Ibex +*/ + *(here->VBICbaseBXtempPtr) += Ibex_Vrth; + *(here->VBICemitEItempPtr) += -Ibex_Vrth; + + if (!here->VBIC_excessPhase) { +/* +c Stamp element: Itzf +*/ + *(here->VBICcollCItempPtr) += Itzf_Vrth; + *(here->VBICemitEItempPtr) += -Itzf_Vrth; + } +/* +c Stamp element: Itzr +*/ + *(here->VBICemitEItempPtr) += Itzr_Vrth; + *(here->VBICcollCItempPtr) += -Itzr_Vrth; +/* +c Stamp element: Ibc +*/ + *(here->VBICbaseBItempPtr) += Ibc_Vrth; + *(here->VBICcollCItempPtr) += -Ibc_Vrth; +/* +c Stamp element: Ibep +*/ + *(here->VBICbaseBXtempPtr) += Ibep_Vrth; + *(here->VBICbaseBPtempPtr) += -Ibep_Vrth; +/* +c Stamp element: Rcx +*/ + *(here->VBICcollTempPtr) += Ircx_Vrth; + *(here->VBICcollCXtempPtr) += -Ircx_Vrth; +/* +c Stamp element: Irci +*/ + *(here->VBICcollCXtempPtr) += Irci_Vrth; + *(here->VBICcollCItempPtr) += -Irci_Vrth; +/* +c Stamp element: Rbx +*/ + *(here->VBICbaseTempPtr) += Irbx_Vrth; + *(here->VBICbaseBXtempPtr) += -Irbx_Vrth; +/* +c Stamp element: Irbi +*/ + *(here->VBICbaseBXtempPtr) += Irbi_Vrth; + *(here->VBICbaseBItempPtr) += -Irbi_Vrth; +/* +c Stamp element: Re +*/ + *(here->VBICemitTempPtr) += Ire_Vrth; + *(here->VBICemitEItempPtr) += -Ire_Vrth; +/* +c Stamp element: Irbp +*/ + *(here->VBICbaseBPtempPtr) += Irbp_Vrth; + *(here->VBICcollCXtempPtr) += -Irbp_Vrth; +/* +c Stamp element: Ibcp +*/ + *(here->VBICsubsSItempPtr) += Ibcp_Vrth; + *(here->VBICbaseBPtempPtr) += -Ibcp_Vrth; +/* +c Stamp element: Iccp +*/ + *(here->VBICbaseBXtempPtr) += Iccp_Vrth; + *(here->VBICsubsSItempPtr) += -Iccp_Vrth; +/* +c Stamp element: Rs +*/ + *(here->VBICsubsTempPtr) += Irs_Vrth; + *(here->VBICsubsSItempPtr) += -Irs_Vrth; +/* +c Stamp element: Rth +*/ + *(here->VBICtempTempPtr) += Irth_Vrth; +/* +c Stamp element: Ith +*/ + *(here->VBICtempTempPtr) += -Ith_Vrth; + + *(here->VBICtempBaseBIPtr) += -Ith_Vbei; + *(here->VBICtempEmitEIPtr) += +Ith_Vbei; + *(here->VBICtempBaseBIPtr) += -Ith_Vbci; + *(here->VBICtempCollCIPtr) += +Ith_Vbci; + *(here->VBICtempCollCIPtr) += -Ith_Vcei; + *(here->VBICtempEmitEIPtr) += +Ith_Vcei; + *(here->VBICtempBaseBXPtr) += -Ith_Vbex; + *(here->VBICtempEmitEIPtr) += +Ith_Vbex; + *(here->VBICtempBaseBXPtr) += -Ith_Vbep; + *(here->VBICtempBaseBPPtr) += +Ith_Vbep; + *(here->VBICtempSubsPtr) += -Ith_Vbcp; + *(here->VBICtempBaseBPPtr) += +Ith_Vbcp; + *(here->VBICtempBaseBXPtr) += -Ith_Vcep; + *(here->VBICtempSubsPtr) += +Ith_Vcep; + *(here->VBICtempCollCXPtr) += -Ith_Vrci; + *(here->VBICtempCollCIPtr) += +Ith_Vrci; + *(here->VBICtempBaseBIPtr) += -Ith_Vbcx; + *(here->VBICtempCollCXPtr) += +Ith_Vbcx; + *(here->VBICtempBaseBXPtr) += -Ith_Vrbi; + *(here->VBICtempBaseBIPtr) += +Ith_Vrbi; + *(here->VBICtempBaseBPPtr) += -Ith_Vrbp; + *(here->VBICtempCollCXPtr) += +Ith_Vrbp; + *(here->VBICtempCollPtr) += -Ith_Vrcx; + *(here->VBICtempCollCXPtr) += +Ith_Vrcx; + *(here->VBICtempBasePtr) += -Ith_Vrbx; + *(here->VBICtempBaseBXPtr) += +Ith_Vrbx; + *(here->VBICtempEmitPtr) += -Ith_Vre; + *(here->VBICtempEmitEIPtr) += +Ith_Vre; + *(here->VBICtempSubsPtr) += -Ith_Vrs; + *(here->VBICtempSubsSIPtr) += +Ith_Vrs; + if (here->VBIC_excessPhase) { + Ith_Vrxf = *(ckt->CKTstate0 + here->VBICith_Vrxf); + *(here->VBICtempXf2Ptr) += +Ith_Vrxf; + } + } + + if (here->VBIC_excessPhase) { + Itxf_Vrxf = *(ckt->CKTstate0 + here->VBICitxf_Vrxf); + Ibc_Vrxf = *(ckt->CKTstate0 + here->VBICibc_Vrxf); + Ixzf_Vbei = *(ckt->CKTstate0 + here->VBICixzf_Vbei); + Ixzf_Vbci = *(ckt->CKTstate0 + here->VBICixzf_Vbci); + Ixxf_Vrxf = *(ckt->CKTstate0 + here->VBICixxf_Vrxf); +/* +c Stamp element: Itxf +*/ + *(here->VBICcollCIXf2Ptr) += Itxf_Vrxf; + *(here->VBICemitEIXf2Ptr) += -Itxf_Vrxf; +/* +c Stamp element: Ibc +*/ + *(here->VBICbaseBIXf2Ptr) += Ibc_Vrxf; + *(here->VBICcollCIXf2Ptr) += -Ibc_Vrxf; +/* +c Stamp element: Ixzf, Branch: xf1-ground +*/ + *(here->VBICxf1BaseBIPtr) += +Ixzf_Vbei; + *(here->VBICxf1EmitEIPtr) += -Ixzf_Vbei; + *(here->VBICxf1BaseBIPtr) += +Ixzf_Vbci; + *(here->VBICxf1CollCIPtr) += -Ixzf_Vbci; + if (here->VBIC_selfheat) { + Ixzf_Vrth = *(ckt->CKTstate0 + here->VBICixzf_Vrth); + *(here->VBICxf1TempPtr) += Ixzf_Vrth; + } +/* +c Stamp element: Ixxf, Branch: xf2-ground +*/ + *(here->VBICxf2Xf2Ptr) += +Ixxf_Vrxf; + + } + /* c The complex part */ @@ -229,6 +437,8 @@ c The complex part XQbep_Vbep = *(ckt->CKTstate0 + here->VBICcqbep); XQbep_Vbci = *(ckt->CKTstate0 + here->VBICcqbepci); XQbcp_Vbcp = *(ckt->CKTstate0 + here->VBICcqbcp); + XQbeo_Vbe = *(ckt->CKTstate0 + here->VBICcqbeo); + XQbco_Vbc = *(ckt->CKTstate0 + here->VBICcqbco); /* c Stamp element: Qbe */ @@ -312,6 +522,87 @@ c Stamp element: Qbcp *(here->VBICbaseBPBaseBPPtr) += XQbcp_Vbcp * (s->real); *(here->VBICbaseBPBaseBPPtr + 1) += XQbcp_Vbcp * (s->imag); +/* +c Stamp element: Qbeo +*/ + *(here->VBICbaseBasePtr ) += XQbeo_Vbe * (s->real); + *(here->VBICbaseBasePtr + 1) += XQbeo_Vbe * (s->imag); + *(here->VBICemitEmitPtr ) += XQbeo_Vbe * (s->real); + *(here->VBICemitEmitPtr + 1) += XQbeo_Vbe * (s->imag); + *(here->VBICbaseEmitPtr ) += -XQbeo_Vbe * (s->real); + *(here->VBICbaseEmitPtr + 1) += -XQbeo_Vbe * (s->imag); + *(here->VBICemitBasePtr ) += -XQbeo_Vbe * (s->real); + *(here->VBICemitBasePtr + 1) += -XQbeo_Vbe * (s->imag); +/* +c Stamp element: Qbco +*/ + *(here->VBICbaseBasePtr ) += XQbco_Vbc * (s->real); + *(here->VBICbaseBasePtr + 1) += XQbco_Vbc * (s->imag); + *(here->VBICcollCollPtr ) += XQbco_Vbc * (s->real); + *(here->VBICcollCollPtr + 1) += XQbco_Vbc * (s->imag); + *(here->VBICbaseCollPtr ) += -XQbco_Vbc * (s->real); + *(here->VBICbaseCollPtr + 1) += -XQbco_Vbc * (s->imag); + *(here->VBICcollBasePtr ) += -XQbco_Vbc * (s->real); + *(here->VBICcollBasePtr + 1) += -XQbco_Vbc * (s->imag); + + if (here->VBIC_selfheat) { + XQcth_Vrth = here->VBICcapcth; + XQbe_Vrth = here->VBICcapqbeth; + XQbex_Vrth = here->VBICcapqbexth; + XQbc_Vrth = here->VBICcapqbcth; + XQbcx_Vrth = here->VBICcapqbcxth; + XQbep_Vrth = here->VBICcapqbepth; + XQbcp_Vrth = here->VBICcapqbcpth; + + *(here->VBICtempTempPtr ) += XQcth_Vrth * (s->real); + *(here->VBICtempTempPtr + 1) += XQcth_Vrth * (s->imag); + + *(here->VBICbaseBItempPtr ) += XQbe_Vrth * (s->real); + *(here->VBICbaseBItempPtr + 1) += XQbe_Vrth * (s->imag); + *(here->VBICemitEItempPtr ) += -XQbe_Vrth * (s->real); + *(here->VBICemitEItempPtr + 1) += -XQbe_Vrth * (s->imag); + *(here->VBICbaseBXtempPtr ) += XQbex_Vrth * (s->real); + *(here->VBICbaseBXtempPtr + 1) += XQbex_Vrth * (s->imag); + *(here->VBICemitEItempPtr ) += -XQbex_Vrth * (s->real); + *(here->VBICemitEItempPtr + 1) += -XQbex_Vrth * (s->imag); + *(here->VBICbaseBItempPtr ) += XQbc_Vrth * (s->real); + *(here->VBICbaseBItempPtr + 1) += XQbc_Vrth * (s->imag); + *(here->VBICcollCItempPtr ) += -XQbc_Vrth * (s->real); + *(here->VBICcollCItempPtr + 1) += -XQbc_Vrth * (s->imag); + *(here->VBICbaseBItempPtr ) += XQbcx_Vrth * (s->real); + *(here->VBICbaseBItempPtr + 1) += XQbcx_Vrth * (s->imag); + *(here->VBICcollCXtempPtr ) += -XQbcx_Vrth * (s->real); + *(here->VBICcollCXtempPtr + 1) += -XQbcx_Vrth * (s->imag); + *(here->VBICbaseBXtempPtr ) += XQbep_Vrth * (s->real); + *(here->VBICbaseBXtempPtr + 1) += XQbep_Vrth * (s->imag); + *(here->VBICbaseBPtempPtr ) += -XQbep_Vrth * (s->real); + *(here->VBICbaseBPtempPtr + 1) += -XQbep_Vrth * (s->imag); + *(here->VBICsubsSItempPtr ) += XQbcp_Vrth * (s->real); + *(here->VBICsubsSItempPtr + 1) += XQbcp_Vrth * (s->imag); + *(here->VBICbaseBPtempPtr ) += -XQbcp_Vrth * (s->real); + *(here->VBICbaseBPtempPtr + 1) += -XQbcp_Vrth * (s->imag); + + } + if (here->VBIC_excessPhase) { +/* +c Stamp element: Qcxf +*/ + XQcxf_Vcxf = here->VBICcapQcxf; + *(here->VBICxf1Xf1Ptr ) += XQcxf_Vcxf * s->real; + *(here->VBICxf1Xf1Ptr + 1) += XQcxf_Vcxf * s->imag; +/* +c Stamp element: L = TD/3 +*/ + Xl = here->VBICindInduct; + + *(here->VBICxf1IbrPtr) += 1; + *(here->VBICxf2IbrPtr) -= 1; + *(here->VBICibrXf1Ptr) += 1; + *(here->VBICibrXf2Ptr) -= 1; + *(here->VBICibrIbrPtr ) -= Xl * s->real; + *(here->VBICibrIbrPtr + 1) -= Xl * s->imag; + + } } } return(OK); diff --git a/src/spicelib/devices/vbic/vbicsetup.c b/src/spicelib/devices/vbic/vbicsetup.c index f40a59988..5c65aefc9 100644 --- a/src/spicelib/devices/vbic/vbicsetup.c +++ b/src/spicelib/devices/vbic/vbicsetup.c @@ -482,6 +482,12 @@ VBICsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states) if((model->VBICthermalResistGiven) && (model->VBICthermalCapacitance < 1e-12)) model->VBICthermalCapacitance = 1e-12; + if((model->VBICdelayTimeFGiven) && (model->VBICdelayTimeF > 0.0)) { + here->VBICindInduct = model->VBICdelayTimeF / 3.0 / here->VBICm; + here->VBIC_excessPhase = 1; + } else { + here->VBIC_excessPhase = 0; + } if(here->VBICcollCINode == 0) { error = CKTmkVolt(ckt, &tmp, here->VBICname, "collCI"); @@ -501,6 +507,27 @@ VBICsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states) here->VBICbaseBINode = tmp->number; } + if (here->VBIC_excessPhase) { + if(here->VBICxf1Node == 0) { + error = CKTmkVolt(ckt, &tmp, here->VBICname, "xf1"); + if(error) return(error); + here->VBICxf1Node = tmp->number; + } + if(here->VBICxf2Node == 0) { + error = CKTmkVolt(ckt, &tmp, here->VBICname, "xf2"); + if(error) return(error); + here->VBICxf2Node = tmp->number; + } + if(here->VBICbrEq == 0) { + error = CKTmkCur(ckt,&tmp,here->VBICname,"branch"); + if(error) return(error); + here->VBICbrEq = tmp->number; + } + } else { + here->VBICxf1Node = 0; + here->VBICxf2Node = 0; + } + /* macro to make elements with built in test for out of memory */ #define TSTALLOC(ptr,first,second) \ do { if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\ @@ -584,6 +611,28 @@ do { if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\ TSTALLOC(VBICtempSubsPtr,VBICtempNode,VBICsubsNode); TSTALLOC(VBICtempSubsSIPtr,VBICtempNode,VBICsubsSINode); TSTALLOC(VBICtempTempPtr,VBICtempNode,VBICtempNode); + if (here->VBIC_excessPhase) { + TSTALLOC(VBICtempXf2Ptr, VBICtempNode, VBICxf2Node); + TSTALLOC(VBICxf1TempPtr, VBICxf1Node ,VBICtempNode); + } + } + + if (here->VBIC_excessPhase) { + TSTALLOC(VBICxf1Xf1Ptr , VBICxf1Node , VBICxf1Node); + TSTALLOC(VBICxf1Xf2Ptr , VBICxf1Node , VBICxf2Node); + TSTALLOC(VBICxf1CollCIPtr, VBICxf1Node , VBICcollCINode); + TSTALLOC(VBICxf1BaseBIPtr, VBICxf1Node , VBICbaseBINode); + TSTALLOC(VBICxf1EmitEIPtr, VBICxf1Node , VBICemitEINode); + TSTALLOC(VBICxf2Xf2Ptr , VBICxf2Node , VBICxf2Node); + TSTALLOC(VBICxf2Xf1Ptr , VBICxf2Node , VBICxf1Node); + TSTALLOC(VBICcollCIXf2Ptr, VBICcollCINode, VBICxf2Node); + TSTALLOC(VBICbaseBIXf2Ptr, VBICbaseBINode, VBICxf2Node); + TSTALLOC(VBICemitEIXf2Ptr, VBICemitEINode, VBICxf2Node); + TSTALLOC(VBICxf1IbrPtr, VBICxf1Node, VBICbrEq); + TSTALLOC(VBICxf2IbrPtr, VBICxf2Node, VBICbrEq); + TSTALLOC(VBICibrXf2Ptr, VBICbrEq, VBICxf2Node); + TSTALLOC(VBICibrXf1Ptr, VBICbrEq, VBICxf1Node); + TSTALLOC(VBICibrIbrPtr, VBICbrEq, VBICbrEq); } } @@ -636,6 +685,20 @@ VBICunsetup( && here->VBICcollCXNode != here->VBICcollNode) CKTdltNNum(ckt, here->VBICcollCXNode); here->VBICcollCXNode = 0; + + if (here->VBIC_excessPhase) { + if(here->VBICxf1Node > 0) + CKTdltNNum(ckt, here->VBICxf1Node); + here->VBICxf1Node = 0; + + if(here->VBICxf2Node > 0) + CKTdltNNum(ckt, here->VBICxf2Node); + here->VBICxf2Node = 0; + + if (here->VBICbrEq > 0) + CKTdltNNum(ckt, here->VBICbrEq); + here->VBICbrEq = 0; + } } } return OK; diff --git a/src/spicelib/parser/inp2n.c b/src/spicelib/parser/inp2n.c index e76e41c8d..f02c33bf9 100644 --- a/src/spicelib/parser/inp2n.c +++ b/src/spicelib/parser/inp2n.c @@ -46,7 +46,8 @@ void INP2N(CKTcircuit *ckt, INPtables *tab, struct card *current) { char *token; INPgetNetTok(&line, &token, 1); - if (i >= 2) { + /* We have single terminal Verilog-A modules */ + if (i >= 1) { txfree(INPgetMod(ckt, token, &thismodel, tab)); /* /1* check if using model binning -- pass in line since need 'l' and 'w' *1/ */ diff --git a/src/spicelib/parser/inpptree.c b/src/spicelib/parser/inpptree.c index 2301dd979..66c88768b 100644 --- a/src/spicelib/parser/inpptree.c +++ b/src/spicelib/parser/inpptree.c @@ -753,7 +753,7 @@ static INPparseNode *PTdifferentiate(INPparseNode * p, int varnum) break; default: - fprintf(stderr, "Internal error: bad node type %d\n", p->type); + fprintf(stderr, "Error: bad node type %d\n", p->type); newp = NULL; break; } @@ -778,6 +778,10 @@ static INPparseNode *mkb(int type, INPparseNode * left, INPparseNode *p; int i; + if (!right || !left) { + return (NULL); + } + if ((right->type == PT_CONSTANT) && (left->type == PT_CONSTANT)) { double value; switch (type) { @@ -890,6 +894,9 @@ static INPparseNode *mkf(int type, INPparseNode * arg) INPparseNode *p; int i; + if (!arg) + return NULL; + for (i = 0; i < NUM_FUNCS; i++) if (funcs[i].number == type) break; diff --git a/src/xspice/Makefile.am b/src/xspice/Makefile.am index 9ff281f97..53669c8b3 100644 --- a/src/xspice/Makefile.am +++ b/src/xspice/Makefile.am @@ -8,17 +8,8 @@ EXTRA_DIST = README examples icm xspice.c .gitignore \ ## libs. It is currently compiled manually, last. ##SUBDIRS = mif cm enh evt ipc idn icm -SUBDIRS = mif cm enh evt ipc idn cmpp icm +SUBDIRS = mif cm enh evt ipc idn cmpp icm verilog -initdatadir = $(pkgdatadir)/scripts -initdata_DATA = verilog/vlnggen - -initdata1dir = $(pkgdatadir)/scripts/src -initdata1_DATA = verilog/verilator_shim.cpp verilog/verilator_main.cpp - -initdata2dir = $(pkgdatadir)/scripts/src/ngspice -initdata2_DATA = ../include/ngspice/cosim.h ../include/ngspice/miftypes.h \ - ../include/ngspice/cmtypes.h dist-hook: rm -f "$(distdir)/icm/makedefs" rm -f "$(distdir)/icm/GNUmakefile" diff --git a/src/xspice/icm/digital/d_cosim/cfunc.mod b/src/xspice/icm/digital/d_cosim/cfunc.mod index 1f5e58b44..a3755731d 100644 --- a/src/xspice/icm/digital/d_cosim/cfunc.mod +++ b/src/xspice/icm/digital/d_cosim/cfunc.mod @@ -39,13 +39,15 @@ char *dlerror(void) // Lifted from dev.c. if (rc == 0) { /* FormatMessage failed */ (void) sprintf(errstr, errstr_fmt, (unsigned long) GetLastError()); } else { - snprintf(errstr, sizeof errstr, errstr_fmt, lpMsgBuf); + snprintf(errstr, sizeof errstr, "%s", (char *)lpMsgBuf); LocalFree(lpMsgBuf); } return errstr; } /* end of function dlerror */ #else #include +#include +#include #endif #include "ngspice/cosim.h" @@ -77,6 +79,7 @@ struct instance { unsigned int inout_ports; // Number of XSPICE inout ports. unsigned int op_pending; // Output is pending. Digital_t *out_vals; // The new output values. + double last_step; // Time of previous accepted step. double extra; // Margin to extend timestep. void *so_handle; // dlopen() handle to the simulation binary. }; @@ -93,6 +96,10 @@ static void callback(ARGS, Mif_Callback_Reason_t reason) return; if (ip->info.cleanup) (*ip->info.cleanup)(&ip->info); + if (ip->info.lib_argv) + free((void *)ip->info.lib_argv); + if (ip->info.sim_argv) + free((void *)ip->info.sim_argv); if (ip->so_handle) dlclose(ip->so_handle); if (ip->q) @@ -104,11 +111,71 @@ static void callback(ARGS, Mif_Callback_Reason_t reason) } } +/* A utility function used to open static libraries, trying an installation + * directory and different file extenstions. + */ + +#if defined (__MINGW32__) || defined (__CYGWIN__) || defined (_MSC_VER) +#include + +static const char *exts[] = { "", ".so", ".DLL", NULL}; +#if defined (__CYGWIN__) +#define CMPFN strcasecmp // Ignores case. +#define TESTFN(f) (access(f, 4) == 0) // Checks for read access. +#else +#define CMPFN _stricmp // Ignores case. +#define TESTFN(f) (_access(f, 4) == 0) // Checks for read access. +#endif +#define SLIBFILE "DLL" +#ifndef NGSPICELIBDIR +#define NGSPICELIBDIR "C:\\Spice64\\lib\\ngspice" // Defined by configure? +#endif + +#else + +static const char *exts[] = { "", ".so", NULL}; +#define CMPFN strcmp +#define TESTFN(f) (access(f, R_OK) == 0) +#define SLIBFILE "shared library" +#endif +#define FLAGS (RTLD_GLOBAL | RTLD_NOW) + +static void *cosim_dlopen(const char *fn) +{ + const char **xp; + size_t l1, l2; + void *handle; + char path[2048]; + + l1 = strlen(fn); + for (xp = exts; *xp; xp++) { + l2 = strlen(*xp); + if (l2 && l1 > l2 && !CMPFN(*xp, fn + l1 - l2)) + continue; // Extension already present + snprintf(path, sizeof path, "%s%s", fn, *xp); + handle = dlopen(path, FLAGS); + if (handle) + return handle; + if (TESTFN(path)) // File exists. + break; + snprintf(path, sizeof path, NGSPICELIBDIR "/%s%s", fn, *xp); + handle = dlopen(path, FLAGS); + if (handle) + return handle; + if (TESTFN(path)) + break; + } + + fprintf(stderr, "Cannot open " SLIBFILE " %s: %s\n", path, dlerror()); + return NULL; +} + /* Function called when a co-simulator output changes. * Out-of-range values for bit_num must be ignored. */ -void accept_output(struct co_info *pinfo, unsigned int bit_num, Digital_t *val) +static void accept_output(struct co_info *pinfo, + unsigned int bit_num, Digital_t *val) { struct instance *ip = (struct instance *)pinfo; // First member. Digital_t *out_vals; // XSPICE rotating memory. @@ -147,7 +214,7 @@ static void output(struct instance *ip, ARGS) delay = PARAM(delay) - (TIME - ip->info.vtime); if (delay <= 0) { cm_message_printf("WARNING: output scheduled with impossible " - "delay (%g) at %g.", delay, TIME); + "delay (%g) at %g/%g.", delay, TIME, ip->info.vtime); delay = 1e-12; } out_vals = (Digital_t *)cm_event_get_ptr(1, 0); @@ -213,6 +280,7 @@ static int advance(struct instance *ip, ARGS) cm_event_queue((TIME + ip->info.vtime + PARAM(delay)) / 2.0); #endif } else { + double when, delta; /* Something changed that may alter the future of the * SPICE simulation. Truncate the current timestep so that @@ -220,8 +288,32 @@ static int advance(struct instance *ip, ARGS) * in the past. */ - DBG("Truncating timestep to %.16g", ip->info.vtime + ip->extra); - cm_analog_set_temp_bkpt(ip->info.vtime + ip->extra); + when = ip->info.vtime + ip->extra; + DBG("Truncating timestep from %.16g to %.16g", TIME, when); + if (cm_analog_set_temp_bkpt(when)) { + /* Failed to set breakpoint, as it was probably too early. + * This could happen if a "Normal" simulation behaves like + * an "After_input" simulation is expected to do, and produces + * output immediately on input, and uses its own time. + * Try and recover: this may lead to a warning on output. + */ + + DBG("Attempting recovery from failed timestep truncation: %s " + "%.16g->%.16g", + cm_message_get_errmsg(), TIME, when); + delta = (TIME - ip->info.vtime) / 1000; + when = ip->info.vtime; + if (when < ip->last_step) { + cm_message_printf("WARNING: client simulator requested " + "output in the past: %.16g < %.16g", + when, ip->last_step); + when = ip->last_step - delta; + } + + do { + when += delta; + } while (cm_analog_set_temp_bkpt(when)); + } /* Any remaining input events are in an alternate future. */ @@ -243,10 +335,11 @@ static void run(struct instance *ip, ARGS) if (ip->q_index < 0) { /* No queued input, advance to current TIME. */ - DBG("Advancing vtime without input %.16g -> %.16g", - ip->info.vtime , TIME); + DBG("Advancing vtime by %g without input %.16g -> %.16g", + TIME - ip->info.vtime, ip->info.vtime, TIME); ip->info.vtime = TIME; - advance(ip, XSPICE_ARG); + if (!advance(ip, XSPICE_ARG)) + ip->last_step = ip->info.vtime; return; } @@ -272,7 +365,8 @@ static void run(struct instance *ip, ARGS) /* Step the simulation forward to the input event time. */ ip->info.vtime = rp->when; - if (ip->info.method == Normal && advance(ip, XSPICE_ARG)) { + if ((ip->info.method == Normal || ip->info.method == Both) && + advance(ip, XSPICE_ARG)) { ip->q_index = -1; return; } @@ -290,7 +384,8 @@ static void run(struct instance *ip, ARGS) /* Simulator requested to run after input change. */ - if (ip->info.method == After_input && advance(ip, XSPICE_ARG)) { + if ((ip->info.method == After_input || ip->info.method == Both) && + advance(ip, XSPICE_ARG)) { ip->q_index = -1; return; } @@ -301,8 +396,10 @@ static void run(struct instance *ip, ARGS) ip->q_index = -1; if (ip->info.method == Normal && TIME > ip->info.vtime) { ip->info.vtime = TIME; - advance(ip, XSPICE_ARG); + if (advance(ip, XSPICE_ARG)) + return; } + ip->last_step = ip->info.vtime; } /* Check whether an input value has changed. @@ -357,14 +454,14 @@ void ucm_d_cosim(ARGS) /* Initialise outputs. Done early in case of failure. */ - outs = PORT_NULL(d_out) ? 0 : PORT_SIZE(d_out); + outs = PORT_NULL(d_out) ? 0 : (unsigned int)PORT_SIZE(d_out); for (i = 0; i < outs; ++i) { OUTPUT_STATE(d_out[i]) = ZERO; OUTPUT_STRENGTH(d_out[i]) = STRONG; OUTPUT_DELAY(d_out[i]) = PARAM(delay); } - inouts = PORT_NULL(d_inout) ? 0 : PORT_SIZE(d_inout); + inouts = PORT_NULL(d_inout) ? 0 : (unsigned int)PORT_SIZE(d_inout); for (i = 0; i < inouts; ++i) { OUTPUT_STATE(d_inout[i]) = ZERO; OUTPUT_STRENGTH(d_inout[i]) = STRONG; @@ -374,11 +471,9 @@ void ucm_d_cosim(ARGS) /* Load the shared library containing the co-simulator. */ fn = PARAM(simulation); - handle = dlopen(fn, RTLD_LAZY | RTLD_LOCAL); + handle = cosim_dlopen(fn); if (!handle) { - cm_message_send("Failed to load simulation binary. " - "Try setting LD_LIBRARY_PATH."); - cm_message_send(dlerror()); + cm_message_send("d_cosim failed to load simulation binary."); return; } ifp = (void (*)(struct co_info *))dlsym(handle, "Cosim_setup"); @@ -397,15 +492,48 @@ void ucm_d_cosim(ARGS) ip->so_handle = handle; ip->info.vtime = 0.0; ip->info.out_fn = accept_output; + ip->info.dlopen_fn = cosim_dlopen; CALLBACK = callback; - /* Store the simulation interface information. */ + if (PARAM_NULL(lib_args)) { + ip->info.lib_argc = 0; + *(void **)&ip->info.lib_argv = NULL; + } else { + char **args; + + ip->info.lib_argc = (unsigned int)PARAM_SIZE(lib_args); + args = malloc((ip->info.lib_argc + 1) * sizeof (char *)); + if (args) { + for (i = 0; i < ip->info.lib_argc; ++i) + args[i] = PARAM(lib_args[i]); + args[i] = NULL; + } + *(char ***)&ip->info.lib_argv = args; + } + + if (PARAM_NULL(sim_args)) { + ip->info.sim_argc = 0; + *(void **)&ip->info.sim_argv = NULL; + } else { + char **args; + + ip->info.sim_argc = (unsigned int)PARAM_SIZE(sim_args); + args = malloc((ip->info.sim_argc + 1) * sizeof (char *)); + if (args) { + for (i = 0; i < ip->info.sim_argc; ++i) + args[i] = PARAM(sim_args[i]); + args[i] = NULL; + } + *(char ***)&ip->info.sim_argv = args; + } + + /* Get the simulation interface information. */ (*ifp)(&ip->info); /* Check lengths. */ - ins = PORT_NULL(d_in) ? 0 : PORT_SIZE(d_in); + ins = PORT_NULL(d_in) ? 0 : (unsigned int)PORT_SIZE(d_in); if (ins != ip->info.in_count) { cm_message_printf("Warning: mismatched XSPICE/co-simulator " "input counts: %d/%d.", @@ -426,7 +554,7 @@ void ucm_d_cosim(ARGS) /* Create input queue and output buffer. */ ip->q_index = -1; - ip->q_length = PARAM(queue_size); + ip->q_length = (unsigned int)PARAM(queue_size); ip->in_ports = ins; ip->out_ports = outs; ip->inout_ports = inouts; @@ -448,13 +576,13 @@ void ucm_d_cosim(ARGS) /* Allocate XSPICE rotating storage to track changes. */ - cm_event_alloc(0, (ins + inouts) * sizeof (Digital_t)); - cm_event_alloc(1, (outs + inouts) * sizeof (Digital_t)); + cm_event_alloc(0, (int)((ins + inouts) * sizeof (Digital_t))); + cm_event_alloc(1, (int)((outs + inouts) * sizeof (Digital_t))); /* Declare irreversible. */ if (PARAM(irreversible) > 0) - cm_irreversible(PARAM(irreversible)); + cm_irreversible((unsigned int)PARAM(irreversible)); return; /* Handle malloc failures. */ @@ -473,10 +601,10 @@ void ucm_d_cosim(ARGS) /* Error state. Do nothing at all. */ - ports = PORT_NULL(d_out) ? 0 : PORT_SIZE(d_out); + ports = PORT_NULL(d_out) ? 0 : (unsigned int)PORT_SIZE(d_out); for (i = 0; i < ports; ++i) OUTPUT_CHANGED(d_out[i]) = FALSE; - ports = PORT_NULL(d_inout) ? 0 : PORT_SIZE(d_inout); + ports = PORT_NULL(d_inout) ? 0 : (unsigned int)PORT_SIZE(d_inout); for (i = 0; i < ports; ++i) OUTPUT_CHANGED(d_inout[i]) = FALSE; return; @@ -569,11 +697,21 @@ void ucm_d_cosim(ARGS) * forward, replaying any saved input events. */ - if (TIME <= ip->info.vtime) + if (ip->last_step == 0.0) { + /* First step. "Step" the co-simulation to time zero, + * as that may trigger initialisations. + */ + + if (advance(ip, XSPICE_ARG)) + return; + } + + if (TIME <= ip->info.vtime) { cm_message_printf("XSPICE time is behind vtime:\n" "XSPICE %.16g\n" "Cosim %.16g", TIME, ip->info.vtime); + } run(ip, XSPICE_ARG); } } diff --git a/src/xspice/icm/digital/d_cosim/ifspec.ifs b/src/xspice/icm/digital/d_cosim/ifspec.ifs index 8138b53f2..cb77502c3 100644 --- a/src/xspice/icm/digital/d_cosim/ifspec.ifs +++ b/src/xspice/icm/digital/d_cosim/ifspec.ifs @@ -67,6 +67,28 @@ Vector: no Vector_Bounds: - Null_Allowed: no +PARAMETER_TABLE: + +Parameter_Name: lib_args +Description: "Argument strings made available to the shared library" +Data_Type: string +Default_Value: - +Limits: - +Vector: yes +Vector_Bounds: - +Null_Allowed: yes + +PARAMETER_TABLE: + +Parameter_Name: sim_args +Description: "Argument strings made available to the simulation" +Data_Type: string +Default_Value: - +Limits: - +Vector: yes +Vector_Bounds: - +Null_Allowed: yes + /* Instances maintain an internal input event queue that should be at least * as large as the number of inputs. Performance with clocked logic may * be improved by making it larger than (2 * F) / MTS, where F is diff --git a/src/xspice/icm/digital/d_state/cfunc.mod b/src/xspice/icm/digital/d_state/cfunc.mod index 4666e8b8d..da8413223 100644 --- a/src/xspice/icm/digital/d_state/cfunc.mod +++ b/src/xspice/icm/digital/d_state/cfunc.mod @@ -1690,19 +1690,24 @@ void cm_d_state(ARGS) *s; /* Main string variable. */ static char *open_error = - "\nERROR\n D_STATE: failed to open state file.\n"; + "\nError:\n D_STATE: failed to open state file.\n"; static char *loading_error = - "\nERROR\n D_STATE: state file was not read successfully.\n " + "\nError:\n D_STATE: state file was not read successfully.\n " "The most common cause of this problem is a\n " "trailing blank line in the state.in file.\n"; - /* Allocate storage for the state transition table. */ - table = calloc(1, sizeof (State_Table_t)); - STATIC_VAR(table) = table; /*** open file and count the number of vectors in it ***/ state_file = fopen_with_path( PARAM(state_file), "r"); + if(!state_file) { + cm_message_send(open_error); + cm_cexit(1); + } + + /* Allocate storage for the state transition table. */ + table = calloc(1, sizeof (State_Table_t)); + STATIC_VAR(table) = table; /* increment counter if not a comment until EOF reached... */ i = 0; diff --git a/src/xspice/mif/mif_inp2.c b/src/xspice/mif/mif_inp2.c index 1368b9ba2..a45c0059d 100644 --- a/src/xspice/mif/mif_inp2.c +++ b/src/xspice/mif/mif_inp2.c @@ -165,34 +165,31 @@ MIF_INP2A ( /* Must be called "current" for compatibility */ /* with macros */ { - /* parse a code model instance card */ /* Aname */ - char *line; /* the text line for this card */ - char *name; /* the name of the instance */ - char *model=NULL; /* the name of the model */ + char *line; /* the text line for this card */ + char *name; /* the name of the instance */ + char *model=NULL; /* the name of the model */ - char *def_port_type_str = NULL; /* The default port type in string form */ - char *next_token; /* a token string */ - char *tmp_token; /* a token string */ + char *def_port_type_str = NULL; // Default port type as string + char *next_token; /* a token string */ + char *tmp_token; /* a token string */ + char *model_loc; /* Pointer to the model in the input. */ + int i, j; /* Loop counters */ + int type; /* Type of the model for this instance */ + int error; /* for the IFC macro */ - int i; /* a loop counter */ - int j; /* a loop counter */ - int type; /* the type of the model for this instance */ - /* int num_conn; number of connections for this model */ - int error; /* for the IFC macro */ + MIFmodel *mdfast; /* pointer to model struct */ + MIFinstance *fast; /* pointer to instance struct */ - MIFmodel *mdfast; /* pointer to model struct */ - MIFinstance *fast[1]; /* pointer to instance struct */ + INPmodel *thismodel; /* pointer to model struct */ - INPmodel *thismodel; /* pointer to model struct */ - - Mif_Conn_Info_t *conn_info; /* for faster access to conn info struct */ - Mif_Param_Info_t *param_info; /* for faster access to param info struct */ - Mif_Port_Type_t def_port_type = MIF_VOLTAGE; /* the default port type */ - Mif_Status_t status; /* return status */ - Mif_Token_Type_t next_token_type; /* the type of the next token */ + Mif_Conn_Info_t *conn_info; /* For faster access to conn info struct */ + Mif_Param_Info_t *param_info; /* Faster access to param info struct */ + Mif_Port_Type_t def_port_type = MIF_VOLTAGE; /* The default port type */ + Mif_Status_t status; /* return status */ + Mif_Token_Type_t next_token_type; /* the type of the next token */ #ifdef TRACE /* SDB debug statement */ @@ -209,8 +206,10 @@ MIF_INP2A ( name = copy(MIFgettok(&line)); INPinsert(&name, tab); - /* locate the last token on the line (i.e. model name) and put it into "model" */ - while(*line != '\0') { + /* Locate the last token on the line, the model name. */ + + while (*line != '\0') { + model_loc = line; model = MIFgettok(&line); } @@ -241,11 +240,11 @@ MIF_INP2A ( /* create a new structure for this instance in ckt */ mdfast = (MIFmodel*) thismodel->INPmodfast; - IFC(newInstance, (ckt, (GENmodel*)mdfast, (GENinstance **)fast, name)); + IFC(newInstance, (ckt, (GENmodel*)mdfast, (GENinstance **)&fast, name)); /* initialize the code model specific elements of the inst struct */ - MIFinit_inst(mdfast, fast[0]); + MIFinit_inst(mdfast, fast); /* *********************** */ @@ -276,10 +275,21 @@ MIF_INP2A ( for(i = 0; i < DEVices[type]->DEVpublic.num_conn; i++) { /* Check that the line is not finished yet. */ - if(*line == '\0') { - LITERR("Encountered end of line before all connections were found in model."); - gc_end(); - return; + + if (*line == '\0') { + conn_info = &(DEVices[type]->DEVpublic.conn[i]); + if (i == 0 || !conn_info->null_allowed) { + LITERR("Encountered end of line before all required " + "connections were found."); + gc_end(); + return; + } + + /* Allow trailing nulls to be missed. Set the null flag. */ + + fast->conn[i]->is_null = MIF_TRUE; + fast->conn[i]->size = 0; + continue; } /* At this point, we have one of three possibilities: @@ -323,10 +333,10 @@ MIF_INP2A ( /* set analog and event_driven flags on instance and model */ if((def_port_type == MIF_DIGITAL) || (def_port_type == MIF_USER_DEFINED)) { - fast[0]->event_driven = MIF_TRUE; + fast->event_driven = MIF_TRUE; mdfast->event_driven = MIF_TRUE; } else { - fast[0]->analog = MIF_TRUE; + fast->analog = MIF_TRUE; mdfast->analog = MIF_TRUE; } @@ -334,6 +344,7 @@ MIF_INP2A ( /* check for a null connection and continue to next connection if found */ if(next_token_type == MIF_NULL_TOK) { /* make sure null is allowed */ + if(! conn_info->null_allowed) { LITERR("NULL connection found where not allowed"); gc_end(); @@ -341,15 +352,15 @@ MIF_INP2A ( } /* set the null flag to true */ - fast[0]->conn[i]->is_null = MIF_TRUE; - fast[0]->conn[i]->size = 0; + fast->conn[i]->is_null = MIF_TRUE; + fast->conn[i]->size = 0; /* eat the null token and continue to next connection */ next_token = MIFget_token(&line,&next_token_type); continue; /* iterate */ } else { /* set the null flag to false */ - fast[0]->conn[i]->is_null = MIF_FALSE; + fast->conn[i]->is_null = MIF_FALSE; } @@ -376,7 +387,7 @@ MIF_INP2A ( MIFget_port(ckt, tab, current, - fast[0], + fast, &line, &next_token, &next_token_type, @@ -392,7 +403,7 @@ MIF_INP2A ( return; } - fast[0]->conn[i]->size = 1; + fast->conn[i]->size = 1; /* when we leave here, next_token should hold the next, unprocessed netname */ @@ -461,7 +472,7 @@ MIF_INP2A ( MIFget_port(ckt, tab, current, - fast[0], + fast, &line, &next_token, &next_token_type, @@ -496,7 +507,7 @@ MIF_INP2A ( gc_end(); return; } - fast[0]->conn[i]->size = j; + fast->conn[i]->size = j; /* At this point, the next time we get_token, we should get a % or a net name. We'll do that now, since when we enter the loop, we expect next_token @@ -535,7 +546,7 @@ MIF_INP2A ( conn_info = &(DEVices[type]->DEVpublic.conn[i]); - if( (fast[0]->conn[i]->is_null) && + if( (fast->conn[i]->is_null) && (! conn_info->null_allowed) ) { LITERR("Null found for connection where not allowed"); gc_end(); @@ -543,7 +554,7 @@ MIF_INP2A ( } if(conn_info->has_lower_bound) { - if(fast[0]->conn[i]->size < conn_info->lower_bound) { + if(fast->conn[i]->size < conn_info->lower_bound) { LITERR("Too few ports in connection"); gc_end(); return; @@ -551,7 +562,7 @@ MIF_INP2A ( } if(conn_info->has_upper_bound) { - if(fast[0]->conn[i]->size > conn_info->upper_bound) { + if(fast->conn[i]->size > conn_info->upper_bound) { LITERR("Too many ports in connection"); gc_end(); return; @@ -588,8 +599,8 @@ MIF_INP2A ( return; } } else if (param_info->is_array && param_info->has_conn_ref && - fast[0]->conn[param_info->conn_ref]->size != - fast[0]->param[i]->size) { + fast->conn[param_info->conn_ref]->size != + fast->param[i]->size) { LITERR("Array parameter size on model does not match " "connection size"); gc_end(); diff --git a/src/xspice/verilog/MSVC.CMD b/src/xspice/verilog/MSVC.CMD index bd9ab9696..97a3c127f 100644 --- a/src/xspice/verilog/MSVC.CMD +++ b/src/xspice/verilog/MSVC.CMD @@ -1 +1 @@ -CL /O2 /LD /EHsc /Fe..\adc.DLL /I. /IC:\mingw64\share\verilator\include\vltstd /IC:\mingw64\share\verilator\include Vlng__ALL.cpp verilator_shim.cpp C:\mingw64\share\verilator\include\verilated.cpp C:\mingw64\share\verilator\include\verilated_threads.cpp /link /DLL /EXPORT:Cosim_setup +CL /O2 /LD /EHsc /Fe..\Verilated.DLL /I. /IC:\mingw64\share\verilator\include\vltstd /IC:\mingw64\share\verilator\include Vlng__ALL.cpp verilator_shim.cpp C:\mingw64\share\verilator\include\verilated.cpp C:\mingw64\share\verilator\include\verilated_threads.cpp /link /DLL /EXPORT:Cosim_setup diff --git a/src/xspice/verilog/Makefile.am b/src/xspice/verilog/Makefile.am new file mode 100644 index 000000000..50ecc0131 --- /dev/null +++ b/src/xspice/verilog/Makefile.am @@ -0,0 +1,51 @@ + ## Process this file with automake to produce Makefile.in + +MAINTAINERCLEANFILES = Makefile.in + +# Verilator support: files installed to script directory and below. + +initdatadir = $(pkgdatadir)/scripts +initdata_DATA = vlnggen + +initdata1dir = $(pkgdatadir)/scripts/src +initdata1_DATA = verilator_shim.cpp verilator_main.cpp + +initdata2dir = $(pkgdatadir)/scripts/src/ngspice +initdata2_DATA = ../../include/ngspice/cosim.h \ + ../../include/ngspice/miftypes.h \ + ../../include/ngspice/cmtypes.h + +# Icarus Verilog support: build two shared libraries. + +pkglib_LTLIBRARIES = ivlng.la ivlngvpi.la +ivlng_la_SOURCES = icarus_shim.c icarus_shim.h +ivlng_la_CFLAGS = -I../../../../src/include +ivlng_la_LDFLAGS = -module -shared -avoid-version + +ivlngvpi_la_SOURCES = vpi.c icarus_shim.h vpi_user_dummy.h +ivlngvpi_la_CFLAGS = -I../../../../src/include +ivlngvpi_la_LDFLAGS = -module -shared -avoid-version + +# On Windows, symbols in DLLs must be fully resolved. +# Create a dummy libvvp.DLL so that Icarus Verilog need not be installed +# for building. + +if DLIBS_FULLY_RESOLVED +pkglib_LTLIBRARIES += libvvp.la +libvvp_la_SOURCES = vpi_dummy.c vpi_user_dummy.h +libvvp_la_LDFLAGS = -no-undefined -module -shared -avoid-version +ivlng_la_LDFLAGS += -no-undefined +ivlngvpi_la_LIBADD = libvvp.la ivlng.la +ivlngvpi_la_LDFLAGS += -no-undefined +endif + +# Libtool installs unwanted libraries, remove them after installation. +# On Windows, the dummy libvvp.* files are removed also. + +install-exec-hook: + cd $(DESTDIR)$(pkglibdir); \ + rm -f ivlng*a libvvp* ; \ + mv ivlngvpi.* ivlng.vpi + +uninstall-hook: + rm -f $(DESTDIR)$(pkglibdir)/ivlng.vpi $(DESTDIR)$(pkglibdir)/ivlng.so diff --git a/src/xspice/verilog/README.txt b/src/xspice/verilog/README.txt index 6eea6d832..cb789f2af 100644 --- a/src/xspice/verilog/README.txt +++ b/src/xspice/verilog/README.txt @@ -1,3 +1,19 @@ This directory contains Ngspice scripts and other files used to prepare -Verilog (and possibly VHDL) code to be included in an Ngspice simulation. -An example circuit can be found in examples/xspice/verilator. +Verilog code to be included in an Ngspice simulation, using Verilator +or Icarus Verilog. + + +For Verilator the relevant files are vlnggen (an Ngspice script), +verilator_main.cpp and verilator_shim.cpp. The two C++ files are +compiled together with C++ source code generated from the Verilog input. +The compilation is handled by Verilator unless the Microsoft Visual C++ +compiler is used. MSVC.CMD contains an example command for that. + +Example circuits can be found in examples/xspice/verilator. + + +The following files are for Icarus Verilog support and are built into +shared libraries while compiling Ngspice: icarus_shim.h, icarus_shim.c, +vpi.c, vpi_dummy.c, user_vpi_dummy.h, coroutine*.h and libvvp.def. + +Example circuits can be found in examples/xspice/icarus_verilog. diff --git a/src/xspice/verilog/coroutine.h b/src/xspice/verilog/coroutine.h new file mode 100644 index 000000000..09e1c9247 --- /dev/null +++ b/src/xspice/verilog/coroutine.h @@ -0,0 +1,29 @@ +#ifndef _COSIM_COROUTINE_H_ +#define _COSIM_COROUTINE_H_ + +#if defined(__MINGW32__) || defined(_MSC_VER) +#include // Windows has a simple co-routine library - "Fibers" + +/* Coroutine context information. */ + +struct cr_ctx { + LPVOID spice_fiber; // OS-provided coroutine context. + LPVOID cosim_fiber; // OS-provided context and stack. +}; +#else +/* On a Unix-like OS pthreads are used to give a co-simulation its own stack, + * but setcontext() and friends would avoid the overhead of a OS thread. + */ + +#include + +struct cr_ctx { + pthread_t thread; // Thread for VVP execution. + pthread_mutex_t mutex; + pthread_cond_t spice_cond; // Condition variables for each thread. + pthread_cond_t cosim_cond; +}; + +#endif /* pthread code. */ +#endif // _COSIM_COROUTINE_H_ + diff --git a/src/xspice/verilog/coroutine_cosim.h b/src/xspice/verilog/coroutine_cosim.h new file mode 100644 index 000000000..81513e0f0 --- /dev/null +++ b/src/xspice/verilog/coroutine_cosim.h @@ -0,0 +1,28 @@ +#ifndef _COSIM_COROUTINE_SIM_H_ +#define _COSIM_COROUTINE_SIM_H_ + +/* Code that supplies a set of simple, portable functions for running + * a co-simulation as a co-routine inside Ngspice: co-simulator side. + */ + +#include "coroutine.h" + +#if defined(__MINGW32__) || defined(_MSC_VER) +static void cr_yield_to_spice(struct cr_ctx *ctx) { + SwitchToFiber(ctx->spice_fiber); +} + +#define cr_init(X) /* All initialisation was done in the primary fiber. */ +#else +/* On a Unix-like OS pthreads are used to give libvvp its own stack. */ + +static void cr_yield_to_spice(struct cr_ctx *ctx) { + pthread_cond_signal(&ctx->spice_cond); + pthread_cond_wait(&ctx->cosim_cond, &ctx->mutex); +} + +static void cr_init(struct cr_ctx *ctx) { + pthread_mutex_lock(&ctx->mutex); +} +#endif +#endif // _COSIM_COROUTINE_SIM_H_ diff --git a/src/xspice/verilog/coroutine_shim.h b/src/xspice/verilog/coroutine_shim.h new file mode 100644 index 000000000..63a3fa692 --- /dev/null +++ b/src/xspice/verilog/coroutine_shim.h @@ -0,0 +1,147 @@ +#ifndef _COSIM_COROUTINE_SHIM_H_ +#define _COSIM_COROUTINE_SHIM_H_ + +/* Code that supplies a set of simple, portable functions for running + * a co-simulation as a co-routine inside Ngspice: d_cosim shim side. + * For Windows it also emulates the Unix dlopen() family of functions + * for dynamic loading. + */ + +#include "coroutine.h" + +static void fail(const char *what, int why); + +#if defined(__MINGW32__) || defined(_MSC_VER) +#define dlopen(name, type) LoadLibrary(name) +#define dlsym(handle, name) (void *)GetProcAddress(handle, name) +#define dlclose(handle) FreeLibrary(handle) +#define cr_safety() while (0) // Not needed with Fibers. + +static char *dlerror(void) // Lifted from dev.c. +{ + static const char errstr_fmt[] = + "Unable to find message in dlerr(). System code = %lu"; + static char errstr[256]; + LPVOID lpMsgBuf; + + DWORD rc = FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR) &lpMsgBuf, + 0, + NULL + ); + + if (rc == 0) { /* FormatMessage failed */ + (void) sprintf(errstr, errstr_fmt, (unsigned long) GetLastError()); + } else { + snprintf(errstr, sizeof errstr, "%s", (char *)lpMsgBuf); + LocalFree(lpMsgBuf); + } + return errstr; +} /* end of function dlerror */ + +static void cr_yield_to_sim(struct cr_ctx *ctx) { + SwitchToFiber(ctx->cosim_fiber); +} + +static void cr_init(struct cr_ctx *ctx, void *(*fn)(void *), void *data) { + ctx->spice_fiber = ConvertThreadToFiber(NULL); + + /* Start the cosimulator fiber and wait for it to be ready. */ + + ctx->cosim_fiber = CreateFiber(1024*1024, (void (*)(void *))fn, data); + cr_yield_to_sim(ctx); +} + +static void cr_cleanup(struct cr_ctx *ctx) { + DeleteFiber(ctx->cosim_fiber); +} + +static void cr_yield_to_spice(struct cr_ctx *ctx) { + SwitchToFiber(ctx->spice_fiber); +} + +#else // Pthreads + +#include +#include + +static void cr_yield_to_sim(struct cr_ctx *ctx) { + int err; + + err = pthread_cond_signal(&ctx->cosim_cond); + if (err) + fail("pthread_cond_signal (sim)", err); + err = pthread_cond_wait(&ctx->spice_cond, &ctx->mutex); + if (err) + fail("pthread_cond_wait (spice)", err); +} + +static void cr_init(struct cr_ctx *ctx, void *(*fn)(void *), void *data) { + int err; + + /* Create pthread apparatus. */ + + err = pthread_mutex_init(&ctx->mutex, NULL); + if (err) + fail("pthread_mutex_init", err); + err = pthread_cond_init(&ctx->spice_cond, NULL); + if (!err) + err = pthread_cond_init(&ctx->cosim_cond, NULL); + if (err) + fail("pthread_cond_init", err); + + /* Start the cosimulator thread and wait for it to be ready. */ + + pthread_mutex_lock(&ctx->mutex); + err = pthread_create(&ctx->thread, NULL, fn, data); + if (err) + fail("pthread_create", err); + err = pthread_cond_wait(&ctx->spice_cond, &ctx->mutex); + if (err) + fail("pthread_cond_wait", err); +} + +static void cr_safety(void) { + sigset_t set; + + /* Signals that are handled with longjump() in signal_handler.c + * must be blocked to prevent threads sharing a stack. + */ + + sigemptyset(&set); + sigaddset(&set, SIGINT); + sigaddset(&set, SIGFPE); + sigaddset(&set, SIGTTIN); + sigaddset(&set, SIGTTOU); + sigaddset(&set, SIGTSTP); + sigaddset(&set, SIGCONT); + pthread_sigmask(SIG_BLOCK, &set, NULL); +} + +static void cr_cleanup(struct cr_ctx *ctx) { + /* For now, just cancel the cosimulator thread. + * It should be in pthread_cond_wait() and will go quickly. + */ + + pthread_cancel(ctx->thread); + pthread_mutex_unlock(&ctx->mutex); + pthread_cond_signal(&ctx->cosim_cond); // Make it run + pthread_join(ctx->thread, NULL); // Wait for it. + pthread_cond_destroy(&ctx->spice_cond); + pthread_cond_destroy(&ctx->cosim_cond); + pthread_mutex_destroy(&ctx->mutex); +} + +static void cr_yield_to_spice(struct cr_ctx *ctx) { + pthread_cond_signal(&ctx->spice_cond); + pthread_cond_wait(&ctx->cosim_cond, &ctx->mutex); +} +#endif /* pthread code. */ +#endif // _COSIM_COROUTINE_SHIM_H_ + diff --git a/src/xspice/verilog/icarus_shim.c b/src/xspice/verilog/icarus_shim.c new file mode 100644 index 000000000..ff1c6fb3f --- /dev/null +++ b/src/xspice/verilog/icarus_shim.c @@ -0,0 +1,312 @@ +/* + * Main file for the shared library ivlng.so that is used + * by ngspice's d_cosim code model to connect an instance of + * an Icarus Verilog simulation (libvvp.so). + * Licensed on the same terms as Ngspice. + * + * Copyright (c) 2024 Giles Atkinson + */ + +#include +#include +#include +#include +#include +#include + +/* The VVP code runs on its own stack, handled by cr_xxx() functions. */ + +#include "coroutine_shim.h" + +#include "ngspice/cmtypes.h" // For Digital_t +#include "ngspice/cosim.h" + + +#ifndef NGSPICELIBDIR +#if defined(__MINGW32__) || defined(_MSC_VER) +#define NGSPICELIBDIR "C:\\Spice64\\lib\\ngspice" +#else +#define NGSPICELIBDIR "/usr/local/lib/ngspice" +#endif +#endif + +/* This header file defines the external interface. It also contains an initial + * comment that describes how this shared library is used. + */ + +#include "icarus_shim.h" + +/* Report fatal errors. */ + +static void fail(const char *what, int why) +{ + fprintf(stderr, "Icarus shim failed in function %s: %s.\n", + what, strerror(why)); + abort(); +} + +static void input(struct co_info *pinfo, unsigned int bit, Digital_t *val) +{ + struct ng_vvp *ctx = (struct ng_vvp *)pinfo->handle; + struct ngvp_port *pp; + unsigned int count; + int a, b, dirty; + + /* Convert the value. */ + + if (val->strength <= HI_IMPEDANCE && val->state != UNKNOWN) { + a = val->state; // Normal - '0'/'1'. + b = 0; + } else if (val->strength == HI_IMPEDANCE) { + a = 0; // High impedance - 'z'. + b = 1; + } else { + a = 1; // Undefined - 'x'. + b = 1; + } + + /* Find the port. */ + + if (bit >= pinfo->in_count) { + bit -= pinfo->in_count; + if (bit >= pinfo->inout_count) + return; + pp = ctx->ports + ctx->ins + ctx->outs; // Point at inouts. + count = ctx->inouts; + } else { + pp = ctx->ports; + count = ctx->ins; + } + + while (count--) { + if (pp[count].position <= bit) + break; + } + pp = pp + count; + bit -= pp->position; + + /* Check and update. */ + + dirty = 0; + bit = pp->bits - bit - 1; // Bit position for big-endian. + a <<= bit; + if (a ^ pp->previous.aval) { + if (a) + pp->previous.aval |= a; + else + pp->previous.aval &= ~(1 << bit); + dirty = 1; + } + b <<= bit; + if (b ^ pp->previous.bval) { + if (b) + pp->previous.bval |= b; + else + pp->previous.bval &= ~(1 << bit); + dirty = 1; + } + + if (dirty && !(pp->flags & IN_PENDING)) { + pp->flags |= IN_PENDING; + ++ctx->in_pending; + } +} + +/* Move the VVP simulation forward. */ + +static void step(struct co_info *pinfo) +{ + struct ng_vvp *ctx = (struct ng_vvp *)pinfo->handle; + + /* Let VVP run. It will stop when it has caught up with SPICE time + * (pinfo->vtime) or produced output. + */ + + cr_yield_to_sim(&ctx->cr_ctx); + + /* Check for output. */ + + if (ctx->out_pending) { + struct ngvp_port *pp; + uint32_t changed, mask, limit, i, bit; + + limit = ctx->outs + ctx->inouts; + for (i = 0, pp = ctx->ports + ctx->ins; i < limit; ++i, ++pp) { + if (!(pp->flags & OUT_PENDING)) + continue; + + pp->flags &= (uint16_t)~OUT_PENDING; + changed = (uint32_t)((pp->new.aval ^ pp->previous.aval) | + (pp->new.bval ^ pp->previous.bval)); + if (changed) { + bit = pp->position; + mask = 1 << (pp->bits - 1); + while (changed) { + if (mask & changed) { + const Digital_t lv_vals[] = + { {ZERO, STRONG}, {ONE, STRONG}, + {ZERO, HI_IMPEDANCE}, {UNKNOWN, STRONG} }; + uint32_t a, b; + + a = ((uint32_t)pp->new.aval & mask) != 0; + b = ((uint32_t)pp->new.bval & mask) != 0; + a += (b << 1); + pinfo->out_fn(pinfo, bit, (Digital_t *)lv_vals + a); + changed &= ~mask; + } + mask >>= 1; + ++bit; + } + pp->previous.aval = pp->new.aval; + pp->previous.bval = pp->new.bval; + } + if (--ctx->out_pending == 0) + break; + } + if (ctx->out_pending) + abort(); + } +} + +static void cleanup(struct co_info *pinfo) +{ + struct ng_vvp *ctx = (struct ng_vvp *)pinfo->handle; + + if (!ctx) + return; + + /* Tell VVP to exit. */ + + ctx->stop = 1; + cr_yield_to_sim(&ctx->cr_ctx); + cr_cleanup(&ctx->cr_ctx); + free(ctx->ports); + dlclose(ctx->vvp_handle); + free(ctx); + pinfo->handle = NULL; +} + +/* Static variable and function for passing context from this library + * to an instance of ivlng.vpi running in the VVP thread. + * Get_ng_vvp() is called in the VVP thread and must synchronise. + * XSPICE initialisation is single-threaded, so a static is OK. + */ + +static struct ng_vvp *context; + +struct ng_vvp *Get_ng_vvp(void) +{ + return context; +} + +/* Thread start function runs the Verilog simulation. */ + +static void *run_vvp(void *arg) +{ + static const char * const fn_names[] = { VVP_FN_0, VVP_FN_1, VVP_FN_2, + VVP_FN_3, VVP_FN_4, 0 }; + struct co_info *pinfo = (struct co_info *)arg; + struct vvp_ptrs fns; + void **fpptr; + const char *file; + struct ng_vvp *ctx; + int i; + + cr_safety(); // Make safe with signals. + + /* Find the functions to be called in libvvp. */ + + fpptr = (void **)&fns; + for (i = 0; ; ++i, ++fpptr) { + if (!fn_names[i]) + break; + *fpptr = dlsym(context->vvp_handle, fn_names[i]); + if (!*fpptr) { + fprintf(stderr, "Icarus shim failed to find VVP function: %s.\n", + dlerror()); + abort(); + } + } + + /* Start the simulation. */ + + fns.add_module_path("."); + file = (pinfo->lib_argc >= 3) ? pinfo->lib_argv[2] : NULL; // VVP log file. + fns.init(file, (int)pinfo->sim_argc, (char **)pinfo->sim_argv); + fns.no_signals(); + + /* The VPI file will usually be /usr/local/lib/ngspice/ivlng.vpi + * or C:\Spice64\lib\ngspice\ivlng.vpi. + */ + + if (pinfo->lib_argc >= 2 && pinfo->lib_argv[1][0]) // Explicit VPI file. + file = pinfo->lib_argv[1]; + else +#ifdef STAND_ALONE + file = "./ivlng"; +#else + file = NGSPICELIBDIR "/ivlng"; +#endif + fns.load_module(file); + fns.run(pinfo->sim_argv[0]); + + /* The simulation has finished. Do nothing until destroyed. */ + + ctx = (struct ng_vvp *)pinfo->handle; + ctx->stop = 1; + for (;;) + cr_yield_to_spice(&ctx->cr_ctx); + + return NULL; +} + +/* Entry point to this shared library. Called by d_cosim. */ + +void Cosim_setup(struct co_info *pinfo) +{ + char *file; + struct ngvp_port *last_port; + + /* It is assumed that there is no parallel access to this function + * as ngspice initialisation is single-threaded. + */ + + context = calloc(1, sizeof (struct ng_vvp)); + if (!context) + fail("malloc", errno); + context->cosim_context = pinfo; + pinfo->handle = context; + + /* Load libvvp. It is not statically linked as that would create + * an unwanted build dependency on Icarus Verilog. + */ + + if (pinfo->lib_argc > 0 && pinfo->lib_argv[0][0]) // Explicit path to VVP? + file = (char *)pinfo->lib_argv[0]; + else //libvvp is assumed to be in the OS search path. + file = "libvvp"; + context->vvp_handle = pinfo->dlopen_fn(file); + if (!context->vvp_handle) { + fprintf(stderr, "Icarus shim failed to load VVP library\n"); + abort(); + } + + /* Set-up the execution stack for libvvp and start it. */ + + cr_init(&context->cr_ctx, run_vvp, pinfo); + + /* Return required values in *pinfo. */ + + last_port = context->ports + context->ins - 1; + pinfo->in_count = context->ins ? last_port->position + last_port->bits : 0; + last_port += context->outs; + pinfo->out_count = + context->outs ? last_port->position + last_port->bits : 0; + last_port += context->inouts; + pinfo->inout_count = + context->inouts ? last_port->position + last_port->bits : 0; + pinfo->cleanup = cleanup; + pinfo->step = step; + pinfo->in_fn = input; + pinfo->method = Normal; +} diff --git a/src/xspice/verilog/icarus_shim.h b/src/xspice/verilog/icarus_shim.h new file mode 100644 index 000000000..0a9559635 --- /dev/null +++ b/src/xspice/verilog/icarus_shim.h @@ -0,0 +1,81 @@ +#ifndef _ICARUS_SHIM_H_ +#define _ICARUS_SHIM_H_ + +/* This is the interface definition file for the shim library (ivlng.so) + * and associated Verilog VPI module (icarus_shim.vpi). + * + * Together, the two libraries allow execution of Verilog code using the + * shared library version of Icarus Verilog's VVP program inside a SPICE + * simulation performed by ngspice. + * + * Use of these components starts with a SPICE netlist containing an A-device + * (XSPICE device) whose model card specifies the d_cosim code model and + * parameter 'simulation="some_path/ivlng.so"'. During initialisation, + * the shim library finds the VVP file to be run as a model card parameter, + * loads libvvp.so, and creates a thread to run it, passing the path + * to the VVP file and options to load the VPI module. + * + * The VPI module is called on loading: its first task is to obtain the + * list of ports for the top-level Verilog module. After that the VPI code + * controls the execution of the Verilog code by blocking execution until + * commanded to proceed by the d_cosim instance, always regaining control via + * a VPI callback before the Verilog code moves ahead of the SPICE simulation. + */ + +/* Structure holding pointers to functions in libvvp.so, the Icarus runtime. */ + +struct vvp_ptrs { + void (*add_module_path)(const char *path); +#define VVP_FN_0 "vpip_add_module_path" + void (*init)(const char *logfile_name, int argc, char*argv[]); +#define VVP_FN_1 "vvp_init" + void (*no_signals)(void); +#define VVP_FN_2 "vvp_no_signals" + void (*load_module)(const char *name); +#define VVP_FN_3 "vpip_load_module" + int (*run)(const char *design_path); +#define VVP_FN_4 "vvp_run" +}; + +/* Data stored for each port. */ + +struct ngvp_port { + uint16_t bits; // How many bits? + uint16_t flags; // I/O pending. + uint32_t position; // Number of bits before this port. + struct { // Like struct t_vpi_vecval. + int32_t aval; + int32_t bval; + } previous, new; // Previous and new values. + struct __vpiHandle *handle; // Handle to the port's variable. + struct ng_vvp *ctx; // Pointer back to parent. +}; + +#define IN_PENDING 1 +#define OUT_PENDING 2 + +/* Data strucure used to share context between the ngspice and VVP threads. */ + +struct ng_vvp { + struct cr_ctx cr_ctx; // Coroutine context. + int stop; // Indicates simulation is over. + struct co_info *cosim_context; + uint32_t ins; // Port counts by type. + uint32_t outs; + uint32_t inouts; + double base_time; // SPICE time on entry. + double tick_length; // VVP's time unit. + struct __vpiHandle *stop_cb; // Handle to end-of-tick callback. + volatile uint32_t in_pending; // Counts of changed ports. + volatile uint32_t out_pending; + struct ngvp_port *ports; // Port information array. + void *vvp_handle; // dlopen() handle for libvvp. +}; + +/* Function to find the current d_cosim instance data. Called by VPI code + * and valid only during initialisation: while ngspice thread is waiting. + */ + +struct ng_vvp *Get_ng_vvp(void); + +#endif // _ICARUS_SHIM_H_ diff --git a/src/xspice/verilog/libvvp.def b/src/xspice/verilog/libvvp.def new file mode 100644 index 000000000..0ae7d5a00 --- /dev/null +++ b/src/xspice/verilog/libvvp.def @@ -0,0 +1,57 @@ +; +; Definition file of libvvp.DLL +; Automatic generated by gendef +; written by Kai Tietz 2008 +; +LIBRARY "libvvp.DLL" +EXPORTS +vpi_chk_error +vpi_compare_objects +vpi_control +vpi_flush +vpi_fopen +vpi_free_object +vpi_get +vpi_get_delays +vpi_get_file +vpi_get_str +vpi_get_systf_info +vpi_get_time +vpi_get_userdata +vpi_get_value +vpi_get_vlog_info +vpi_handle +vpi_handle_by_index +vpi_handle_by_name +vpi_handle_multi +vpi_iterate +vpi_mcd_close +vpi_mcd_flush +vpi_mcd_name +vpi_mcd_open +vpi_mcd_printf +vpi_mcd_vprintf +vpi_mode_flag DATA +vpi_printf +vpi_put_delays +vpi_put_userdata +vpi_put_value +vpi_register_cb +vpi_register_systf +vpi_release_handle +vpi_remove_cb +vpi_routines DATA +vpi_scan +vpi_sim_control +vpi_sim_vcontrol +vpi_trace DATA +vpi_vprintf +vpip_add_module_path +vpip_clear_module_paths +vpip_load_module +vvp_init +vvp_no_signals +vvp_run +vvp_set_stop_is_finish +vvp_set_stop_is_finish_exit_code +vvp_set_verbose_flag diff --git a/src/xspice/verilog/verilator_main.cpp b/src/xspice/verilog/verilator_main.cpp index c6b6eef15..e8812f0d8 100644 --- a/src/xspice/verilog/verilator_main.cpp +++ b/src/xspice/verilog/verilator_main.cpp @@ -4,7 +4,7 @@ #include "ngspice/cosim.h" // For struct co_info and prototypes int main(int argc, char** argv, char**) { - struct co_info info; + struct co_info info = {}; Cosim_setup(&info); for (;;) diff --git a/src/xspice/verilog/verilator_shim.cpp b/src/xspice/verilog/verilator_shim.cpp index 186d4a61c..df508658d 100644 --- a/src/xspice/verilog/verilator_shim.cpp +++ b/src/xspice/verilog/verilator_shim.cpp @@ -93,6 +93,11 @@ static void accept_input(struct co_info *pinfo, /* The step function that calls the Verilator code. */ +#ifndef WITH_TIMING +/* The simple case is when the Verilog source contained no time delays, + * or was compiled with compiled with --no-timing. + */ + #define VL_DATA(size, name, msb, lsb) \ for (i = msb; i >= lsb; --i) { \ if (topp->name & (1 << i)) \ @@ -106,7 +111,7 @@ static void accept_input(struct co_info *pinfo, } \ ++index; \ } - + static void step(struct co_info *pinfo) { static Digital_t oval = {ZERO, STRONG}; @@ -123,6 +128,71 @@ static void step(struct co_info *pinfo) #include "outputs.h" #include "inouts.h" } + +#else /* WITH_TIMING */ + +#define VL_DATA(size, name, msb, lsb) \ + for (i = msb; i >= lsb; --i) { \ + if (topp->name & (1 << i)) \ + bit = 1; \ + else \ + bit = 0; \ + if (bit ^ previous_output[index]) { \ + stop = 1; \ + previous_output[index] = bit; \ + oval.state = (Digital_State_t)bit; \ + (*pinfo->out_fn)(pinfo, index, &oval); \ + } \ + ++index; \ + } + +static void step(struct co_info *pinfo) +{ + static Digital_t oval = {ZERO, STRONG}; + VerilatedContext *contextp; + Vlng *topp; + double tick; + uint64_t target, next; + int index, i, stop = 0; + unsigned char bit; + + /* When Verilog source was compiled with --timing, run queued evants + * until the Verilog simulation catches up with SPICE. + */ + + topp = (Vlng *)pinfo->handle; + contextp = topp->contextp(); + tick = pow(10, contextp->timeprecision()); + target = pinfo->vtime / tick; + + /* Step the Verilog simulation towards the target time. */ + + do { + if (topp->eventsPending()) + next = topp->nextTimeSlot(); + else + next = target; + if (next >= target) { + stop = 1; + next = target; + } + contextp->time(next); + topp->eval(); + + /* Scan for output and stop early if found. */ + + index = 0; +#include "outputs.h" +#include "inouts.h" + } while (!stop); + + /* Update the shared simulation time on early exit. */ + + if (next < target) + pinfo->vtime = next * tick; +} + +#endif /* WITH_TIMING */ #undef VL_DATA extern "C" void Cosim_setup(struct co_info *pinfo) @@ -152,6 +222,10 @@ extern "C" void Cosim_setup(struct co_info *pinfo) pinfo->out_count = outs; pinfo->inout_count = inouts; pinfo->in_fn = accept_input; +#ifdef WITH_TIMING + pinfo->method = Both; // There may be immediate results from input. +#else pinfo->method = After_input; // Verilator requires input to advance. +#endif } #undef VL_DATA diff --git a/src/xspice/verilog/vlnggen b/src/xspice/verilog/vlnggen index 956d345c5..0486259ae 100644 --- a/src/xspice/verilog/vlnggen +++ b/src/xspice/verilog/vlnggen @@ -1,5 +1,5 @@ *ng_script_with_params -// This Ngspice interpreter script accepts arbitrary argiments to +// This Ngspice interpreter script accepts arbitrary arguments to // the Verilator compiler (Verilog to C++) and builds a shared library // or DLL that can be loaded by the d_cosim XSPICE code model. // Instances of the model are then digital circuit elements whose @@ -30,7 +30,7 @@ set noglob // Compilation option for C/C++: -fpic is required by GCC for a shared library -if $oscompiled = 8 // VisualC++ - Verilator is a Perl script +if $oscompiled = 8 // VisualC++ setcs cflags="--CFLAGS -fpic --compiler msvc" else setcs cflags="--CFLAGS -fpic" // For g++ @@ -41,7 +41,7 @@ if $oscompiled = 2 | $oscompiled = 3 | $oscompiled = 8 // Windows set dirsep1="\\" set dirsep2="/" set vloc="C:/mingw64/bin/verilator" // Expected location on Windows - set run_verilator="perl $vloc" + set run_verilator="perl $vloc" // Verilator is a Perl script else set windows=0 set dirsep1="/" @@ -55,14 +55,32 @@ else set macos=0 end +// Check for an input.h file in the current directory. If present it may +// override the generated one with incorrect results. A previous failure +// may create such files. + +set silent_fileio +fopen fh inputs.h +if $fh >= 0 + echo File inputs.h (and any other header files) in current directory + echo may interfere with compilation. + quit +end +unset silent_fileio + // Loop through the arguments to find Verilog source: some_path/xxxx.v // The output file will have the same base name. let index=1 set off=1 // Avoid error in dowhile +set timing=1 repeat $argc set base="$argv[$&index]" let index = index + 1 + if $timing <> 0 + // Additional check for --timing option, preceeding any *.v files. + strcmp timing "$base" "--timing" + end strstr l "$base" "" if $l > 2 // Look for xxxx.v strslice tail "$base" -2 2 @@ -122,6 +140,9 @@ setcs prefix="Vlng" // Run Verilator on the given input files. shell $run_verilator --Mdir $objdir --prefix $prefix $cflags --cc $argv +if $shellstatus > 0 + quit +end // Parse the primary interface Class definition for members representing // the ports of the top-level Verilog module. @@ -214,6 +235,8 @@ set shimfile=verilator_shim.cpp set shimobj=verilator_shim.o set mainfile=verilator_main.cpp set srcdir=src +set hfile="cmtypes.h" +set hpath="ngspice$dirsep1$hfile" set silent_fileio // Silences fopen complaints let i=1 @@ -221,15 +244,22 @@ repeat $#sourcepath set stem="$sourcepath[$&i]" let i = i + 1 set fn="$stem$dirsep1$shimfile" - fopen fh $fn - if $fh > 0 - break + fopen fh "$fn" + if $fh < 0 + // Look in any "src" subdirectory (probably in installed tree). + set stem="$stem$dirsep1$srcdir" + set fn="$stem$dirsep1$shimfile" + fopen fh $fn end - set stem="$stem$dirsep1$srcdir" - set fn="$stem$dirsep1$shimfile" - fopen fh $fn if $fh > 0 - break + // Found verilator_shim.cpp, but it needs header files on relative path. + fclose $fh + set hn="$stem$dirsep1$hpath" + fopen fh "$hn" + if $fh > 0 + break + end + echo Ignoring source file "$fn" as "$hn" was not found. end end @@ -263,6 +293,11 @@ else end end +// verilator_shim.cpp has conditionally-compiled sections for --timing. + +if $timing = 0 + setcs cflags="--CFLAGS -DWITH_TIMING ""$cflags" +end // Compile the code. Verilator only does that when building an executable, // so include verilator_main.cpp. @@ -277,6 +312,9 @@ if $bad = 0 // g++ must be available: make a shared library/DLL. set v_objs="$objdir$dirsep1$shimobj $objdir/verilated.o $objdir/verilated_threads.o" + if $timing = 0 + set v_objs="$v_objs $objdir/verilated_timing.o" + end setcs tail="__ALL.a" setcs v_lib="$objdir/$prefix$tail" // Like Vlng__ALL.a diff --git a/src/xspice/verilog/vpi.c b/src/xspice/verilog/vpi.c new file mode 100644 index 000000000..60800f6e0 --- /dev/null +++ b/src/xspice/verilog/vpi.c @@ -0,0 +1,385 @@ +/* + * Copyright (c) 2002 Stephen Williams (steve@icarus.com) + * Copyright (c) 2023 Giles Atkinson + * + * This source code is free software; you can redistribute it + * and/or modify it in source code form under the terms of the GNU + * General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include +#include +#include +#include +//#include +#include "vpi_user_dummy.h" + +#include "ngspice/cmtypes.h" // For Digital_t +#include "ngspice/cosim.h" + +/* The VVP code runs on its own stack, handled by cr_xxx() functions. */ + +#include "coroutine_cosim.h" + +/* This header file defines external interfaces. It also contains an initial + * comment that describes how this VPI module is used. + */ + +#include "icarus_shim.h" + +/* Functions that VPI calls have a returned parameter argument that + * is not used here. + */ + +#define UNUSED __attribute__((unused)) + +/* Debugging printfs(). */ + +//#define DEBUG +#ifdef DEBUG +#define DBG(...) vpi_printf(__VA_ARGS__) +#else +#define DBG(...) +#endif + +static PLI_INT32 next_advance_cb(struct t_cb_data *cb); + +/* Get current simulation time: no module-specific values. */ + +static double get_time(struct ng_vvp *ctx) +{ + static struct t_vpi_time now = { .type = vpiSimTime }; + uint64_t ticks; + + vpi_get_time(NULL, &now); + ticks = ((uint64_t)now.high << 32) + now.low; + return (double)ticks * ctx->tick_length; +} + +/* Arrange for end_advance_cb() to be called in the future. */ + +static vpiHandle set_stop(uint64_t length, struct ng_vvp *ctx) +{ + static struct t_vpi_time now = { .type = vpiSimTime }; + static struct t_cb_data cbd = { .cb_rtn = next_advance_cb, .time = &now }; + + now.low = (unsigned int)length; + now.high = (unsigned int)(length >> 32); + if (length == 0) + cbd.reason = cbReadWriteSynch; + else + cbd.reason = cbAfterDelay; + + /* Callback after delay. */ + + cbd.user_data = (PLI_BYTE8 *)ctx; + return vpi_register_cb(&cbd); +} + +/* Timed callback at end of simulation advance: wait for a command + * from the main thread, and schedule the next callback. + * On return, VVP runs some more. + */ + +static PLI_INT32 next_advance_cb(struct t_cb_data *cb) +{ + struct ng_vvp *ctx = (struct ng_vvp *)cb->user_data; + struct t_vpi_value val; + double vl_time; + uint64_t ticks; + unsigned int i; + + for (;;) { + /* Still wanted? */ + + if (ctx->stop) { + vpi_control(vpiFinish, 0); // Returns after scheduling $finish. + return 0; + } + + /* Save base time for next slice. */ + + ctx->base_time = ctx->cosim_context->vtime; + + /* Repeatedly wait for instructions from the main thread + * until VVP can advance at least one time unit. + */ + + cr_yield_to_spice(&ctx->cr_ctx); + + /* Check for input. */ + + val.format = vpiVectorVal; + i = ctx->ins ? 0 : ctx->outs; + while (ctx->in_pending) { + if (ctx->ports[i].flags & IN_PENDING) { + ctx->ports[i].flags ^= IN_PENDING; + val.value.vector = + (struct t_vpi_vecval *)&ctx->ports[i].previous; + vpi_put_value(ctx->ports[i].handle, &val, NULL, vpiNoDelay); + ctx->in_pending--; + DBG("VPI input %d/%d on %s\n", + val.value.vector->aval, val.value.vector->bval, + vpi_get_str(vpiName, ctx->ports[i].handle)); + } else if (++i == ctx->ins) { + i = ctx->ins + ctx->outs; // Now scan inouts + } + } + + /* How many VVP ticks to advance? */ + + vl_time = get_time(ctx); + if (ctx->cosim_context->vtime < vl_time) { + /* This can occur legitimately as the two times need not + * align exactly. But it should be less than one SPICE timestep. + */ + + DBG("VVP time %.16g ahead of SPICE target %.16g\n", + vl_time, ctx->cosim_context->vtime); + if (ctx->cosim_context->vtime + ctx->tick_length < vl_time) { + fprintf(stderr, + "Error: time reversal (%.10g->%.10g) in " + "Icarus Shim VPI!\n", + vl_time, ctx->cosim_context->vtime); + } + continue; + } + + ticks = (uint64_t) + ((ctx->cosim_context->vtime - vl_time) / ctx->tick_length); + if (ticks > 0) { + DBG("Advancing from %g to %g: %lu ticks\n", + vl_time, ctx->cosim_context->vtime, ticks); + ctx->stop_cb = set_stop(ticks, ctx); + return 0; + } + } +} + +/* Callback function - new output value. */ + +static PLI_INT32 output_cb(struct t_cb_data *cb) +{ + struct ngvp_port *pp = (struct ngvp_port *)cb->user_data; + struct ng_vvp *ctx = pp->ctx; + + DBG("Output: %s is %d now %g (VL) %g (SPICE)\n", + vpi_get_str(vpiName, cb->obj), + cb->value->value.vector->aval, + get_time(ctx), ctx->cosim_context->vtime); + + if (ctx->stop_cb) { + /* First call in the current VVP cycle: cancel the current + * stop CB and request a new one before the next VVP time point. + * That allows all output events in the current timestep + * to be gathered before stopping. + */ + + vpi_remove_cb(ctx->stop_cb); + ctx->stop_cb = NULL; + set_stop(0, ctx); + + /* Set the output time in SPICE format. + * It must not be earlier than entry time. + */ + + ctx->cosim_context->vtime = get_time(ctx); + if (ctx->cosim_context->vtime < ctx->base_time) + ctx->cosim_context->vtime = ctx->base_time; + } + + /* Record the value. */ + + pp->new.aval = cb->value->value.vector->aval; + pp->new.bval = cb->value->value.vector->bval; + if (!(pp->flags & OUT_PENDING)) { + pp->flags |= OUT_PENDING; + ++ctx->out_pending; + } + return 0; +} + +/* Utilty functions for start_cb() - initialise or set watch on a variable.*/ + +static void init(vpiHandle handle) +{ + static struct t_vpi_value val = { .format = vpiIntVal }; + + DBG("Initialising %s to 0\n", vpi_get_str(vpiName, handle)); + + vpi_put_value(handle, &val, NULL, vpiNoDelay); +} + +static void watch(vpiHandle handle, void *pp) +{ + static struct t_vpi_time time = { .type = vpiSuppressTime }; + static struct t_vpi_value val = { .format = vpiVectorVal }; + static struct t_cb_data cb = { + .reason = cbValueChange, .cb_rtn = output_cb, + .time = &time, .value = &val + }; + + cb.obj = handle; + cb.user_data = pp; + vpi_register_cb(&cb); +} + +/* Callback function - simulation is starting. */ + +static PLI_INT32 start_cb(struct t_cb_data *cb) +{ + struct ng_vvp *ctx = (struct ng_vvp *)cb->user_data; + vpiHandle iter, top, item; + PLI_INT32 direction; + char *name; + int ii, oi, ioi; + + DBG("Unit %d precision %d\n", + vpi_get(vpiTimeUnit, NULL), vpi_get(vpiTimePrecision, NULL)); + ctx->tick_length = pow(10.0, vpi_get(vpiTimeUnit, NULL)); + + /* Find the (unique?) top-level module and the one inside it. */ + + iter = vpi_iterate(vpiModule, NULL); + top = vpi_scan(iter); + vpi_free_object(iter); + DBG("Top %s\n", vpi_get_str(vpiName, top)); + + /* Count the ports. */ + + iter = vpi_iterate(vpiPort, top); + if (!iter) + vpi_printf("Top module has no ports!\n"); // vpi_scan() aborts. + ctx->ins = ctx->outs = ctx->inouts = 0; + while ((item = vpi_scan(iter))) { + direction = vpi_get(vpiDirection, item); + switch (direction) { + case vpiInput: + ++ctx->ins; + break; + case vpiOutput: + ++ctx->outs; + break; + case vpiInout: + ++ctx->inouts; + break; + default: + break; + } + } + ctx->ports = (struct ngvp_port *)malloc( + (ctx->ins + ctx->outs + ctx->inouts) * + sizeof (struct ngvp_port)); + if (!ctx->ports) { + vpi_printf("No memory for ports at " __FILE__ ":%d\n", __LINE__); + abort(); + } + + /* Get the ports. */ + + iter = vpi_iterate(vpiPort, top); + ii = oi = ioi = 0; + while ((item = vpi_scan(iter))) { + vpiHandle namesake; + struct ngvp_port *pp; + int first; + + direction = vpi_get(vpiDirection, item); + name = vpi_get_str(vpiName, item); + + /* Assume that there is an object with the same name as the port + * whose value may be read or set as needed. This is an assumption + * about how code for VVP is generated. + */ + + namesake = vpi_handle_by_name(name, top); + DBG("Port %s direction %d size %d, namesake type %d\n", + name, direction, vpi_get(vpiSize, item), + vpi_get(vpiType, namesake)); + + switch (direction) { + case vpiInput: + first = !ii; + pp = ctx->ports + ii++; + init(namesake); + break; + case vpiOutput: + first = !oi; + pp = ctx->ports + ctx->ins + oi++; + watch(namesake, pp); + break; + case vpiInout: + first = !ioi; + init(namesake); + pp = ctx->ports + ctx->ins + ctx->outs + ioi++; + watch(namesake, pp); + break; + default: + continue; + } + pp->bits = (uint16_t)vpi_get(vpiSize, item); + pp->flags = 0; + pp->position = first ? 0 : pp[-1].position + pp[-1].bits; + pp->previous.aval = pp->previous.bval = 0; + pp->handle = namesake; + pp->ctx = ctx; + } + + /* Make a direct call to the "end-of-advance" callback to start running. */ + + cr_init(&ctx->cr_ctx); + cb->user_data = (PLI_BYTE8 *)ctx; + next_advance_cb(cb); + return 0; +} + +/* VPI initialisation. */ + +static void start(void) +{ + static struct t_vpi_time now = { .type = vpiSimTime }; + static struct t_cb_data cbd = { .reason = cbStartOfSimulation, + .time = &now, .cb_rtn = start_cb }; +#ifdef DEBUG + struct t_vpi_vlog_info info; + + /* Get the program name. */ + + if (vpi_get_vlog_info(&info)) { + vpi_printf("Starting ivlng.vpi in %s\n", info.argv[0]); + for (int i = 0; i < info.argc; ++i) + vpi_printf("%d: %s\n", i, info.argv[i]); + vpi_printf("P: %s V: %s\n", info.product, info.version); + } else { + vpi_printf("Failed to get invocation information.\n"); + } +#endif + + /* The first step is to find the top-level module and query its ports. + * At this point they do not exist, so request a callback once they do. + */ + + cbd.user_data = (PLI_BYTE8 *)Get_ng_vvp(); + vpi_register_cb(&cbd); +} + +/* This is a table of registration functions. It is the external symbol + * that the VVP simulator looks for when loading this .vpi module. + */ + +void (*vlog_startup_routines[])(void) = { + start, + 0 +}; diff --git a/src/xspice/verilog/vpi_dummy.c b/src/xspice/verilog/vpi_dummy.c new file mode 100644 index 000000000..2283b4e63 --- /dev/null +++ b/src/xspice/verilog/vpi_dummy.c @@ -0,0 +1,24 @@ +/* Dummy implementations of the functions defined in vpi_user_dummy.h, + * used to make a DLL to replace libvvp.DLL when linking, so that + * Icarus Verilog need not be installed when linking components for it. + */ + +#include +#include "vpi_user_dummy.h" + +PLI_INT32 vpi_printf(const char *, ...) {return 0;} +PLI_INT32 vpi_get_vlog_info(struct t_vpi_vlog_info *p) {return 0;} +void vpi_get_time(vpiHandle h, struct t_vpi_time *p) {} +vpiHandle vpi_register_cb(struct t_cb_data *p) {return (void *)0;} +PLI_INT32 vpi_remove_cb(vpiHandle h) {return 0;} +PLI_INT32 vpi_free_object(vpiHandle h) {return 0;} + +vpiHandle vpi_put_value(vpiHandle h, struct t_vpi_value *p1, + struct t_vpi_time *p2, PLI_INT32 i) {return (void *)0;} +char *vpi_get_str(PLI_INT32 i, vpiHandle h) {return (char *)0;} +PLI_INT32 vpi_get(int, vpiHandle) {return 0;} + +vpiHandle vpi_iterate(PLI_INT32, vpiHandle) {return (void *)0;} +vpiHandle vpi_scan(vpiHandle) {return (void *)0;} +vpiHandle vpi_handle_by_name(const char *, vpiHandle) {return (void *)0;} +void vpi_control(PLI_INT32 operation, ...) {} diff --git a/src/xspice/verilog/vpi_user_dummy.h b/src/xspice/verilog/vpi_user_dummy.h new file mode 100644 index 000000000..ce109548b --- /dev/null +++ b/src/xspice/verilog/vpi_user_dummy.h @@ -0,0 +1,102 @@ +/* A minimal extract from the Verilog Standard's vpi_user.h, so that + * Icarus Verilog support for ngspice can be compiled + * without an installed copy. + */ + +typedef char PLI_BYTE8; +typedef uint32_t PLI_UINT32; +typedef int32_t PLI_INT32; + +struct t_vpi_time { + PLI_INT32 type; + PLI_UINT32 high; + PLI_UINT32 low; + double real; +}; + +#define vpiScaledRealTime 1 +#define vpiSimTime 2 +#define vpiSuppressTime 3 + +struct t_vpi_vecval { + PLI_INT32 aval, bval; +}; + +struct t_vpi_value { + PLI_INT32 format; + union { + char *str; + PLI_INT32 scalar; + PLI_INT32 integer; + double real; + struct t_vpi_time *time; + struct t_vpi_vecval *vector; + struct t_vpi_strengthval *strength; + char *misc; + } value; +}; + +#define vpiIntVal 6 +#define vpiVectorVal 9 + +typedef struct __vpiHandle *vpiHandle; + +struct t_cb_data { + PLI_INT32 reason; + PLI_INT32 (*cb_rtn)(struct t_cb_data *); + vpiHandle obj; + struct t_vpi_time *time; + struct t_vpi_value *value; + PLI_INT32 index; + const PLI_BYTE8 *user_data; +}; + +#define cbValueChange 1 +#define cbReadWriteSynch 6 +#define cbReadOnlySynch 7 +#define cbNextSimTime 8 +#define cbAfterDelay 9 +#define cbStartOfSimulation 11 + +struct t_vpi_vlog_info +{ + PLI_INT32 argc; + char **argv; + char *product; + char *version; +}; + +extern PLI_INT32 vpi_printf(const char *, ...); +extern PLI_INT32 vpi_get_vlog_info(struct t_vpi_vlog_info *); +extern void vpi_get_time(vpiHandle, struct t_vpi_time *); +extern vpiHandle vpi_register_cb(struct t_cb_data *); +extern PLI_INT32 vpi_remove_cb(vpiHandle); +extern PLI_INT32 vpi_free_object(vpiHandle); + +#define vpiNoDelay 1 +extern vpiHandle vpi_put_value(vpiHandle, struct t_vpi_value *, + struct t_vpi_time *, PLI_INT32); + +#define vpiType 1 +#define vpiName 2 +#define vpiSize 4 +#define vpiTimeUnit 11 +#define vpiTimePrecision 12 +#define vpiDirection 20 + +#define vpiInput 1 +#define vpiOutput 2 +#define vpiInout 3 + +#define vpiModule 32 +#define vpiPort 44 + +extern char *vpi_get_str(PLI_INT32, vpiHandle); +extern PLI_INT32 vpi_get(int, vpiHandle); +extern vpiHandle vpi_iterate(PLI_INT32, vpiHandle); +extern vpiHandle vpi_scan(vpiHandle); +extern vpiHandle vpi_handle_by_name(const char *, vpiHandle); + +#define vpiFinish 67 + +extern void vpi_control(PLI_INT32 operation, ...); diff --git a/visualc/make-install-vngspice.bat b/visualc/make-install-vngspice.bat index 871abf6d9..3891a718e 100644 --- a/visualc/make-install-vngspice.bat +++ b/visualc/make-install-vngspice.bat @@ -20,6 +20,8 @@ copy %cmsrc%\table.cm %dst%\lib\ngspice\table.cm copy %cmsrc%\xtraevt.cm %dst%\lib\ngspice\xtraevt.cm copy %cmsrc%\xtradev.cm %dst%\lib\ngspice\xtradev.cm copy %cmsrc%\spice2poly.cm %dst%\lib\ngspice\spice2poly.cm +copy xspice\verilog\ivlng.dll %dst%\lib\ngspice\ivlng.dll +copy xspice\verilog\shim.vpi %dst%\lib\ngspice\ivlng.vpi if "%2" == "fftw" goto copy2 if "%3" == "fftw" goto copy2 @@ -47,6 +49,8 @@ copy %cmsrc%\table64.cm %dst%\lib\ngspice\table.cm copy %cmsrc%\xtraevt64.cm %dst%\lib\ngspice\xtraevt.cm copy %cmsrc%\xtradev64.cm %dst%\lib\ngspice\xtradev.cm copy %cmsrc%\spice2poly64.cm %dst%\lib\ngspice\spice2poly.cm +copy xspice\verilog\ivlng.dll %dst%\lib\ngspice\ivlng.dll +copy xspice\verilog\shim.vpi %dst%\lib\ngspice\ivlng.vpi if "%2" == "fftw" goto copy2-64 if "%3" == "fftw" goto copy2-64 diff --git a/visualc/make-install-vngspiced.bat b/visualc/make-install-vngspiced.bat index a75f8c705..3de5fc68a 100644 --- a/visualc/make-install-vngspiced.bat +++ b/visualc/make-install-vngspiced.bat @@ -20,6 +20,8 @@ copy %cmsrc%\table.cm %dst%\lib\ngspice\table.cm copy %cmsrc%\xtraevt.cm %dst%\lib\ngspice\xtraevt.cm copy %cmsrc%\xtradev.cm %dst%\lib\ngspice\xtradev.cm copy %cmsrc%\spice2poly.cm %dst%\lib\ngspice\spice2poly.cm +copy xspice\verilog\ivlng.dll %dst%\lib\ngspice\ivlng.dll +copy xspice\verilog\shim.vpi %dst%\lib\ngspice\ivlng.vpi if "%2" == "fftw" goto copy2 if "%3" == "fftw" goto copy2 @@ -47,6 +49,8 @@ copy %cmsrc%\table64.cm %dst%\lib\ngspice\table.cm copy %cmsrc%\xtraevt64.cm %dst%\lib\ngspice\xtraevt.cm copy %cmsrc%\xtradev64.cm %dst%\lib\ngspice\xtradev.cm copy %cmsrc%\spice2poly64.cm %dst%\lib\ngspice\spice2poly.cm +copy xspice\verilog\ivlng.dll %dst%\lib\ngspice\ivlng.dll +copy xspice\verilog\shim.vpi %dst%\lib\ngspice\ivlng.vpi if "%2" == "fftw" goto copy2-64 if "%3" == "fftw" goto copy2-64 diff --git a/visualc/src/include/ngspice/config.h b/visualc/src/include/ngspice/config.h index 98da3ab21..81707d84d 100644 --- a/visualc/src/include/ngspice/config.h +++ b/visualc/src/include/ngspice/config.h @@ -15,7 +15,7 @@ #define PACKAGE "ngspice" /* Version number of package */ -#define VERSION "42+" +#define VERSION "43+" /* Define the directory for executables */ #define NGSPICEBINDIR "../bin" diff --git a/visualc/vngspice.sln b/visualc/vngspice.sln index 48ddbc4df..e2a21cf7c 100644 --- a/visualc/vngspice.sln +++ b/visualc/vngspice.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.29806.167 +# Visual Studio Version 17 +VisualStudioVersion = 17.9.34902.65 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vngspice", "vngspice.vcxproj", "{83E315C7-EDD3-4F6B-AF28-87A92A4FA49A}" ProjectSection(ProjectDependencies) = postProject @@ -257,10 +257,10 @@ Global {13500662-AF0B-4AB6-9AF9-BC3E07B5C1C6}.ReleaseOMP|x64.Build.0 = Release|x64 {13500662-AF0B-4AB6-9AF9-BC3E07B5C1C6}.ReleaseOMP|x86.ActiveCfg = Release|Win32 {13500662-AF0B-4AB6-9AF9-BC3E07B5C1C6}.ReleaseOMP|x86.Build.0 = Release|Win32 - {B8DD41C5-70C6-4183-9018-C4B518E8D36A}.console_debug|x64.ActiveCfg = Release|x64 - {B8DD41C5-70C6-4183-9018-C4B518E8D36A}.console_debug|x64.Build.0 = Release|x64 - {B8DD41C5-70C6-4183-9018-C4B518E8D36A}.console_debug|x86.ActiveCfg = Release|Win32 - {B8DD41C5-70C6-4183-9018-C4B518E8D36A}.console_debug|x86.Build.0 = Release|Win32 + {B8DD41C5-70C6-4183-9018-C4B518E8D36A}.console_debug|x64.ActiveCfg = Debug|x64 + {B8DD41C5-70C6-4183-9018-C4B518E8D36A}.console_debug|x64.Build.0 = Debug|x64 + {B8DD41C5-70C6-4183-9018-C4B518E8D36A}.console_debug|x86.ActiveCfg = Debug|Win32 + {B8DD41C5-70C6-4183-9018-C4B518E8D36A}.console_debug|x86.Build.0 = Debug|Win32 {B8DD41C5-70C6-4183-9018-C4B518E8D36A}.console_release_omp|x64.ActiveCfg = Release|x64 {B8DD41C5-70C6-4183-9018-C4B518E8D36A}.console_release_omp|x64.Build.0 = Release|x64 {B8DD41C5-70C6-4183-9018-C4B518E8D36A}.console_release_omp|x86.ActiveCfg = Release|Win32 diff --git a/visualc/xspice/aux-digital.bat b/visualc/xspice/aux-digital.bat new file mode 100644 index 000000000..26920bb3b --- /dev/null +++ b/visualc/xspice/aux-digital.bat @@ -0,0 +1,18 @@ +rem Pre-build commands for digital.cm. +rem Make support components for Icarus Verilog co-simulation: +rem ivlng.dll and ivlng.vpi. Then run aux-cfunc.bat. + +md verilog +pushd verilog +set src=..\..\..\src\xspice\verilog +set inc=..\..\..\src\include +CL.EXE /O2 /LD /EHsc /Feivlng.DLL /I%src% /I%inc% %src%\icarus_shim.c ^ +/link /EXPORT:Cosim_setup /EXPORT:Get_ng_vvp + +rem Make a dummy libvvp.obj, needed for shim.vpi (to be renamed ivlng.vpi). + +lib.exe /def:%src%\libvvp.def /machine:X64 +CL.EXE /O2 /LD /EHsc /Feshim.vpi /I. /I%inc% %src%\vpi.c libvvp.lib ivlng.lib /link /DLL /EXPORT:vlog_startup_routines +dir +popd +.\aux-cfunc.bat digital diff --git a/visualc/xspice/digital.vcxproj b/visualc/xspice/digital.vcxproj index 53616fa1d..1585a1551 100644 --- a/visualc/xspice/digital.vcxproj +++ b/visualc/xspice/digital.vcxproj @@ -87,8 +87,8 @@ - generate cfunc.c and ifspec.c files - call .\aux-cfunc.bat $(ProjectName) + Generate Iverilog support, cfunc.c and ifspec.c files + call .\aux-digital.bat $(ProjectName) @@ -400,4 +400,4 @@ - \ No newline at end of file +