[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