[Pkg-electronics-commits] [gnucap] 34/47: transient: tstep becomes tstrobe, allow not specifying tstrobe
felix salfelder
felix-guest at moszumanska.debian.org
Mon Sep 26 10:37:34 UTC 2016
This is an automated email from the git hooks/post-receive script.
felix-guest pushed a commit to branch master
in repository gnucap.
commit 42e2d5b853d68d542367b97d455dd16ef000f4bc
Author: al davis <ad211 at freeelectron.net>
Date: Tue Aug 2 23:36:25 2016 -0400
transient: tstep becomes tstrobe, allow not specifying tstrobe
---
apps/s_fo.cc | 4 +--
apps/s_tr_set.cc | 78 ++++++++++++++++++++++++-------------------
apps/s_tr_swp.cc | 27 ++++++++++-----
include/patchlev.h | 2 +-
include/s_tr.h | 2 +-
tests/d_mos1.nand3.ckt | 36 ++++++++++++++++++++
tests/d_switch.nro.2.auto.ckt | 12 +++++++
tests/d_tcap.5.ckt | 14 ++++++++
8 files changed, 129 insertions(+), 46 deletions(-)
diff --git a/apps/s_fo.cc b/apps/s_fo.cc
index 7d6785e..c253bb1 100644
--- a/apps/s_fo.cc
+++ b/apps/s_fo.cc
@@ -298,12 +298,12 @@ void FOURIER::setup(CS& Cmd)
_tstart = _sim->_last_time;
}
_tstop = _tstart + 1. / _fstep;
- _tstep = 1. / _fstep / (_timesteps-1);
+ _tstrobe = 1. / _fstep / (_timesteps-1);
_time1 = _sim->_time0 = _tstart;
_sim->_freq = _fstep;
- _dtmax = std::min(double(_dtmax_in), _tstep / double(_skip_in));
+ _dtmax = std::min(double(_dtmax_in), _tstrobe / double(_skip_in));
if (_dtmin_in.has_hard_value()) {untested();
_sim->_dtmin = _dtmin_in;
}else if (_dtratio_in.has_hard_value()) {untested();
diff --git a/apps/s_tr_set.cc b/apps/s_tr_set.cc
index 64099c5..b43cef3 100644
--- a/apps/s_tr_set.cc
+++ b/apps/s_tr_set.cc
@@ -21,7 +21,7 @@
*------------------------------------------------------------------
* set up transient and fourier analysis
*/
-//testing=script 2016.03.25
+//testing=script 2016.08.01
#include "u_sim_data.h"
#include "u_prblst.h"
#include "ap.h"
@@ -37,17 +37,17 @@ void TRANSIENT::setup(CS& Cmd)
{
_tstart.e_val(NOT_INPUT, _scope);
_tstop.e_val(NOT_INPUT, _scope);
- _tstep.e_val(NOT_INPUT, _scope);
+ _tstrobe.e_val(NOT_INPUT, _scope);
_cont = true;
if (Cmd.match1("'\"({") || Cmd.is_pfloat()) {
PARAMETER<double> arg1, arg2, arg3;
Cmd >> arg1;
- if (Cmd.match1("'\"({") || Cmd.is_float()) {
+ if (Cmd.match1("'\"({") || Cmd.is_pfloat()) {
Cmd >> arg2;
}else{
}
- if (Cmd.match1("'\"({") || Cmd.is_float()) {
+ if (Cmd.match1("'\"({") || Cmd.is_pfloat()) {
Cmd >> arg3;
}else{
}
@@ -58,38 +58,39 @@ void TRANSIENT::setup(CS& Cmd)
arg1.e_val(0.,_scope);
arg3.e_val(0.,_scope);
if (arg3 == 0.) { /* spice (illogical) order */
- _tstart = arg3; /* _tstep _tstop _tstart */
+ _tstart = arg3; /* _tstrobe _tstop _tstart */
_tstop = arg2;
- _tstep = arg1;
+ _tstrobe = arg1;
}else if (arg1 == 0.) { /* eca (logical) order: */
- _tstart = arg1; /* _tstart _tstop _tstep */
+ _tstart = arg1; /* _tstart _tstop _tstrobe */
_tstop = arg2;
- _tstep = arg3;
+ _tstrobe = arg3;
}else if (arg1 > arg3) {untested(); /* eca (logical) order: */
- _tstart = arg1; /* _tstart _tstop _tstep */
+ _tstart = arg1; /* _tstart _tstop _tstrobe */
_tstop = arg2;
- _tstep = arg3;
+ _tstrobe = arg3;
}else{ /* spice (illogical) order */
- _tstart = arg3; /* _tstep _tstop _tstart */
+ _tstart = arg3; /* _tstrobe _tstop _tstart */
_tstop = arg2;
- _tstep = arg1;
+ _tstrobe = arg1;
}
}else if (arg2.has_hard_value()) { /* 2 args */
assert(arg1.has_hard_value());
arg1.e_val(0.,_scope);
arg2.e_val(0.,_scope);
- if (arg1 == 0.) {untested(); /* 2 args: _tstart, _tstop */
+ if (arg1 == 0.) { /* 2 args: _tstart, _tstop */
_tstart = arg1;
_tstop = arg2;
- /* _tstep unchanged */
- }else if (arg1 >= arg2) { /* 2 args: _tstop, _tstep */
+ /* _tstrobe unchanged */
+ }else if (arg1 >= arg2) { /* 2 args: _tstop, _tstrobe */
_tstart = _sim->_last_time;
_tstop = arg1;
- _tstep = arg2;
- }else{ /* arg1 < arg2 */ /* 2 args: _tstep, _tstop */
- _tstart = "NA"; /* 0 */ /* spice order */
+ _tstrobe = arg2;
+ }else{ /* 2 args: _tstrobe, _tstop */
+ assert(arg1 < arg2); /* spice order */
+ _tstart = "NA"; /* 0 */
_tstop = arg2;
- _tstep = arg1;
+ _tstrobe = arg1;
}
}else{ /* 1 arg */
assert(arg1.has_hard_value());
@@ -97,34 +98,47 @@ void TRANSIENT::setup(CS& Cmd)
if (arg1 > _sim->_last_time) { /* 1 arg: _tstop */
_tstart = _sim->_last_time;
_tstop = arg1;
- /* _tstep unchanged */
+ /* _tstrobe unchanged */
}else if (arg1 == 0.) {untested(); /* 1 arg: _tstart */
double oldrange = _tstop - _tstart;
_tstart = 0.;
_tstop = oldrange;
- /* _tstep unchanged */
- }else{untested(); /* arg1 < _sim->_last_time, but not 0 */ /* 1 arg: _tstep */
+ /* _tstrobe unchanged */
+ }else{untested(); /* 1 arg: _tstrobe */
+ assert(arg1 <= _sim->_last_time);
+ assert(arg1 > 0.);
double oldrange = _tstop - _tstart;
_tstart = _sim->_last_time;
_tstop = _sim->_last_time + oldrange;
- _tstep = arg1;
+ _tstrobe = arg1;
}
}
}else{ /* no args */
double oldrange = _tstop - _tstart;
_tstart = _sim->_last_time;
_tstop = _sim->_last_time + oldrange;
- /* _tstep unchanged */
+ /* _tstrobe unchanged */
}
if (Cmd.match1("'\"({") || Cmd.is_pfloat()) {
Cmd >> _dtmax_in;
}else{
}
+
options(Cmd);
_tstart.e_val(0., _scope);
_tstop.e_val(NOT_INPUT, _scope);
- _tstep.e_val(NOT_INPUT, _scope);
+ if (_tstart < 0 || _tstop <= _tstart) {untested();
+ throw Exception("transient: bad time args");
+ }else{
+ }
+
+ _tstrobe.e_val(NOT_INPUT, _scope);
+ if (_tstrobe <= 0.) {
+ _tstrobe.set_default(NOT_INPUT);
+ }else{
+ }
+ _tstrobe.e_val(_tstop-_tstart, _scope);
if (_cold || _tstart < _sim->_last_time || _sim->_last_time <= 0.) {
_cont = false;
@@ -135,19 +149,12 @@ void TRANSIENT::setup(CS& Cmd)
}
_sim->_freq = ((_tstop > _tstart) ? (1 / (_tstop - _tstart)) : (0.));
- if (!_tstep.has_good_value()) {untested();
- throw Exception("transient: time step is required");
- }else if (_tstep==0.) {untested();
- throw Exception("time step = 0");
- }else{
- }
-
if (_dtmax_in.has_hard_value()) {
_dtmax = _dtmax_in;
}else if (_skip_in.has_hard_value()) {
- _dtmax = _tstep / double(_skip_in);
+ _dtmax = _tstrobe / double(_skip_in);
}else{
- _dtmax = std::min(_dtmax_in, _tstep);
+ _dtmax = std::min(_dtmax_in, _tstrobe);
}
if (_dtmin_in.has_hard_value()) {untested();
@@ -180,6 +187,9 @@ void TRANSIENT::options(CS& Cmd)
|| Get(Cmd, "dtr{atio}", &_dtratio_in)
|| Get(Cmd, "pl{ot}", &ploton)
|| Get(Cmd, "sk{ip}", &_skip_in)
+ || Get(Cmd, "sta{rt}", &_tstart)
+ || Get(Cmd, "sto{p}", &_tstop)
+ || Get(Cmd, "str{obeperiod}",&_tstrobe)
|| Get(Cmd, "te{mperature}", &_sim->_temp_c)
|| Get(Cmd, "uic", &_sim->_uic)
|| (Cmd.umatch("tr{ace} {=}") &&
diff --git a/apps/s_tr_swp.cc b/apps/s_tr_swp.cc
index 8e8af0f..371fff4 100644
--- a/apps/s_tr_swp.cc
+++ b/apps/s_tr_swp.cc
@@ -22,7 +22,7 @@
* sweep time and simulate. output results.
* manage event queue
*/
-//testing=script 2014.07.04
+//testing=script 2016.08.01
#include "u_time_pair.h"
#include "u_sim_data.h"
#include "u_status.h"
@@ -116,7 +116,7 @@ void TRANSIENT::sweep()
if (step_cause() == scUSER) {
assert(up_order(_sim->_time0-_sim->_dtmin, _time_by_user_request, _sim->_time0+_sim->_dtmin));
++_stepno;
- _time_by_user_request += _tstep; /* advance user time */
+ _time_by_user_request += _tstrobe; /* advance user time */
}else{
}
assert(_sim->_time0 < _time_by_user_request);
@@ -127,8 +127,9 @@ void TRANSIENT::sweep()
{
bool printnow =
(_trace >= tREJECTED)
- || (_accepted && ((_trace >= tALLTIME)
- || (step_cause() == scUSER && _sim->_time0+_sim->_dtmin > _tstart)));
+ || (_accepted && (_trace >= tALLTIME
+ || step_cause() == scUSER
+ || (!_tstrobe.has_hard_value() && _sim->_time0+_sim->_dtmin > _tstart)));
if (printnow) {
_sim->keep_voltages();
outdata(_sim->_time0);
@@ -178,13 +179,24 @@ void TRANSIENT::first()
assert(_sim->_time0 == _time1);
assert(_sim->_time0 <= _tstart);
::status.review.start();
- _time_by_user_request = _sim->_time0 + _tstep; /* set next user step */
- //_eq.Clear(); /* empty the queue */
+
+ //_eq.Clear(); /* empty the queue */
while (!_sim->_eq.empty()) {untested();
_sim->_eq.pop();
}
_stepno = 0;
- set_step_cause(scUSER);
+
+ //_time_by_user_request = _sim->_time0 + _tstrobe; /* set next user step */
+ //set_step_cause(scUSER);
+
+ if (_sim->_time0 < _tstart) { // skip until _tstart
+ set_step_cause(scINITIAL); // suppressed
+ _time_by_user_request = _tstart; // set first strobe
+ }else{ // no skip
+ set_step_cause(scUSER); // strobe here
+ _time_by_user_request = _sim->_time0 + _tstrobe; // set next strobe
+ }
+
++::status.hidden_steps;
::status.review.stop();
}
@@ -428,7 +440,6 @@ bool TRANSIENT::next()
set_step_cause(scSMALL);
//check_consistency2();
throw Exception("tried everything, still doesn't work, giving up");
- //}else if (newtime <= _sim->_time0 - _sim->_dtmin) {untested();
}else if (newtime < _sim->_time0) {
/* Reject the most recent step. */
/* We have faith that it will work with a smaller time step. */
diff --git a/include/patchlev.h b/include/patchlev.h
index 025b292..1f51b57 100644
--- a/include/patchlev.h
+++ b/include/patchlev.h
@@ -1 +1 @@
-#define PATCHLEVEL "unstable 2016.09.19"
+#define PATCHLEVEL "(no 2016.09.19"
diff --git a/include/s_tr.h b/include/s_tr.h
index 9384715..f591ee6 100644
--- a/include/s_tr.h
+++ b/include/s_tr.h
@@ -93,7 +93,7 @@ private:
protected:
PARAMETER<double> _tstart; // sweep start time
PARAMETER<double> _tstop; // sweep stop time
- PARAMETER<double> _tstep; // printed step size
+ PARAMETER<double> _tstrobe; // printed step size
PARAMETER<double> _dtratio_in;// ratio of max/min dt
PARAMETER<double> _dtmin_in; // min internal step size
PARAMETER<double> _dtmax_in; // max internal step size (user)
diff --git a/tests/d_mos1.nand3.ckt b/tests/d_mos1.nand3.ckt
new file mode 100644
index 0000000..ba8355c
--- /dev/null
+++ b/tests/d_mos1.nand3.ckt
@@ -0,0 +1,36 @@
+.title na2
+
+.model nmos nmos level=1 vto=0.7
+.model pmos pmos level=1 vto=-0.7
+
+.SUBCKT nand2 2 3 1 4 11
+Mp1 4 2 1 1 PMOS W=8e-6 L=600e-9
+Mp2 4 3 1 1 PMOS W=8e-6 L=600e-9
+Mn1 4 2 11 0 NMOS W=8e-6 L=600e-9
+Mn2 11 3 0 0 NMOS W=8e-6 L=600e-9
+.ENDS
+
+XI10 2 2 1 4 5 nand2
+C1 4 0 1p
+
+vdd 1 0 5
+vin 2 0 PWL (0 0, 1n 0, 3n 5, 10n 5, 12n 0, 20n 0)
+
+.print op v(nodes) z(5) iter(0)
+.op trace iter
+
+.print op Cgs(Mp1.XI10) Cgd(Mp1.XI10) Cgb(Mp1.XI10)
+.op
+.print op Cgs(Mp2.XI10) Cgd(Mp2.XI10) Cgb(Mp2.XI10)
+.op
+.print op Cgs(Mn1.XI10) Cgd(Mn1.XI10) Cgb(Mn1.XI10)
+.op
+.print op Cgs(Mn2.XI10) Cgd(Mn2.XI10) Cgb(Mn2.XI10)
+.op
+
+.option chgtol=1f trtol=1
+.print tran v(2) v(4) v(5) iter(0)
+.tran 0 10n
+
+.stat notime
+.end
diff --git a/tests/d_switch.nro.2.auto.ckt b/tests/d_switch.nro.2.auto.ckt
new file mode 100644
index 0000000..077693d
--- /dev/null
+++ b/tests/d_switch.nro.2.auto.ckt
@@ -0,0 +1,12 @@
+* switch as negative resistance oscillator
+* Spice netlister for gnetlist
+SW1 1 0 1 0 SWITCH1
+C1 1 0 1n
+I1 0 1 100u
+.MODEL SWITCH1 SW VT=2.5 VH=2.475 RON=1 ROFF=10MEG
+.print tran V(1)
+*>.print tran + r(SW1) iter(0) input(sw1) timef(sw1) control(0)
+.option method=trap noincmode nolubypass nobypass
+.tran 200e-6 uic
+*>.status notime
+.END
diff --git a/tests/d_tcap.5.ckt b/tests/d_tcap.5.ckt
new file mode 100644
index 0000000..0963d1f
--- /dev/null
+++ b/tests/d_tcap.5.ckt
@@ -0,0 +1,14 @@
+'
+V1 1 0 SIN offset= 0. amplitude= 1. frequency= 1. delay= 0.
++ damping= 0.
+C1 1 0 1.
+F1 2 0 C1 1.
+R1 2 0 1.
+R2 3 0 1.
+.tcap C2 3 0 1 0 1.
+.print tran v nodes
+.tran 0 1
+.option trtol=1 reltol=.00001
+.tran 0 1
+.status notime
+.end
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-electronics/gnucap.git
More information about the Pkg-electronics-commits
mailing list