[Pkg-electronics-commits] [gnucap] 13/49: transient "very backward time step" fix dc continue fix
felix salfelder
felix-guest at moszumanska.debian.org
Tue Feb 2 21:39:55 UTC 2016
This is an automated email from the git hooks/post-receive script.
felix-guest pushed a commit to branch wip
in repository gnucap.
commit 8c4fae6d2d322caef34bd823ec19b2e5572e26e6
Author: al davis <al at floyd.freeelectron.net>
Date: Fri Jul 4 16:51:19 2014 -0400
transient "very backward time step" fix
dc continue fix
---
apps/s_dc.cc | 14 ++++++------
apps/s_fo.cc | 4 ++--
apps/s_tr_set.cc | 6 ++---
apps/s_tr_swp.cc | 64 ++++++++++++++++++++++++++++++++++--------------------
include/patchlev.h | 2 +-
include/s_tr.h | 4 ++--
6 files changed, 55 insertions(+), 39 deletions(-)
diff --git a/apps/s_dc.cc b/apps/s_dc.cc
index a2606ef..67719b6 100644
--- a/apps/s_dc.cc
+++ b/apps/s_dc.cc
@@ -1,4 +1,4 @@
-/*$Id: s_dc.cc,v 26.137 2010/04/10 02:37:05 al Exp $ -*- C++ -*-
+/*$Id: s_dc.cc 2014/07/04 al $ -*- C++ -*-
* Copyright (C) 2001 Albert Davis
* Author: Albert Davis <aldavis at gnu.org>
*
@@ -144,7 +144,7 @@ DCOP::DCOP()
void DCOP::finish(void)
{
for (int ii = 0; ii < _n_sweeps; ++ii) {
- if (exists(_zap[ii])) { // component
+ if (_zap[ii]) { // component
_stash[ii].restore();
_zap[ii]->dec_probes();
_zap[ii]->precalc_first();
@@ -242,7 +242,7 @@ void DC::setup(CS& Cmd)
_start[ii].e_val(0., _scope);
fix_args(ii);
- if (exists(_zap[ii])) { // component
+ if (_zap[ii]) { // component
_stash[ii] = _zap[ii]; // stash the std value
_zap[ii]->inc_probes(); // we need to keep track of it
_zap[ii]->set_value(_zap[ii]->value(),0); // zap out extensions
@@ -347,13 +347,13 @@ void DCOP::sweep()
head(_start[0], _stop[0], " ");
_sim->_bypass_ok = false;
_sim->set_inc_mode_bad();
- if (_cont) {untested();
+ if (_cont) {
_sim->restore_voltages();
+ CARD_LIST::card_list.tr_restore();
}else{
+ _sim->clear_limit();
+ CARD_LIST::card_list.tr_begin();
}
-
- _sim->clear_limit();
- CARD_LIST::card_list.tr_begin();
sweep_recursive(_n_sweeps);
}
/*--------------------------------------------------------------------------*/
diff --git a/apps/s_fo.cc b/apps/s_fo.cc
index a021f77..b85b1ee 100644
--- a/apps/s_fo.cc
+++ b/apps/s_fo.cc
@@ -1,4 +1,4 @@
-/*$Id: s_fo.cc,v 26.137 2010/04/10 02:37:05 al Exp $ -*- C++ -*-
+/*$Id: s_fo.cc 2014/07/04 al $ -*- C++ -*-
* Copyright (C) 2001 Albert Davis
* Author: Albert Davis <aldavis at gnu.org>
*
@@ -298,7 +298,7 @@ void FOURIER::setup(CS& Cmd)
}
_tstop = _tstart + 1. / _fstep;
_tstep = 1. / _fstep / (_timesteps-1);
- time1 = _sim->_time0 = _tstart;
+ _time1 = _sim->_time0 = _tstart;
_sim->_freq = _fstep;
diff --git a/apps/s_tr_set.cc b/apps/s_tr_set.cc
index e5c4ccd..b8585a9 100644
--- a/apps/s_tr_set.cc
+++ b/apps/s_tr_set.cc
@@ -1,4 +1,4 @@
-/*$Id: s_tr_set.cc,v 26.133 2009/11/26 04:58:04 al Exp $ -*- C++ -*-
+/*$Id: s_tr_set.cc 2014/07/04 al $ -*- C++ -*-
* Copyright (C) 2001 Albert Davis
* Author: Albert Davis <aldavis at gnu.org>
*
@@ -128,10 +128,10 @@ void TRANSIENT::setup(CS& Cmd)
if (_cold || _tstart < _sim->_last_time || _sim->_last_time <= 0.) {
_cont = false;
- time1 = _sim->_time0 = 0.;
+ _time1 = _sim->_time0 = 0.;
}else{
_cont = true;
- time1 = _sim->_time0 = _sim->_last_time;
+ _time1 = _sim->_time0 = _sim->_last_time;
}
_sim->_freq = ((_tstop > _tstart) ? (1 / (_tstop - _tstart)) : (0.));
diff --git a/apps/s_tr_swp.cc b/apps/s_tr_swp.cc
index 6b318a1..40a39bc 100644
--- a/apps/s_tr_swp.cc
+++ b/apps/s_tr_swp.cc
@@ -1,4 +1,4 @@
-/*$Id: s_tr_swp.cc,v 26.137 2010/04/10 02:37:05 al Exp $ -*- C++ -*-
+/*$Id: s_tr_swp.cc 2014/07/04 al $ -*- C++ -*-
* Copyright (C) 2001 Albert Davis
* Author: Albert Davis <aldavis at gnu.org>
*
@@ -122,7 +122,7 @@ void TRANSIENT::sweep()
assert(_sim->_time0 < _time_by_user_request);
}else{
reject();
- assert(time1 < _time_by_user_request);
+ assert(_time1 < _time_by_user_request);
}
{
bool printnow =
@@ -175,7 +175,7 @@ int TRANSIENT::step_cause()const
void TRANSIENT::first()
{
/* usually, _sim->_time0, time1 == 0, from setup */
- assert(_sim->_time0 == time1);
+ assert(_sim->_time0 == _time1);
assert(_sim->_time0 <= _tstart);
::status.review.start();
_time_by_user_request = _sim->_time0 + _tstep; /* set next user step */
@@ -196,7 +196,7 @@ void TRANSIENT::first()
/*assert(newtime == fixed_time || newtime <= fixed_time -_sim->_dtmin);*/ \
assert(newtime <= almost_fixed_time); \
/*assert(newtime == almost_fixed_time || newtime <= almost_fixed_time - _sim->_dtmin);*/ \
- assert(newtime > time1); \
+ assert(newtime > _time1); \
assert(newtime > reftime); \
assert(new_dt > 0.); \
assert(new_dt >= _sim->_dtmin); \
@@ -205,7 +205,7 @@ void TRANSIENT::first()
/* || newtime < _time_by_user_request - _sim->_dtmin); */ \
}
#define check_consistency2() { \
- assert(newtime > time1); \
+ assert(newtime > _time1); \
assert(new_dt > 0.); \
assert(new_dt >= _sim->_dtmin); \
assert(newtime <= _time_by_user_request); \
@@ -221,14 +221,14 @@ bool TRANSIENT::next()
{
::status.review.start();
- double old_dt = _sim->_time0 - time1;
+ double old_dt = _sim->_time0 - _time1;
assert(old_dt >= 0);
double newtime = NEVER;
double new_dt = NEVER;
STEP_CAUSE new_control = scNO_ADVANCE;
- if (_sim->_time0 == time1) {
+ if (_sim->_time0 == _time1) {
// initial step -- could be either t==0 or continue
// for the first time, just guess
// make it 100x smaller than expected
@@ -237,7 +237,7 @@ bool TRANSIENT::next()
new_control = scINITIAL;
}else if (!_converged) {
new_dt = old_dt / OPT::trstepshrink;
- newtime = _time_by_iteration_count = time1 + new_dt;
+ newtime = _time_by_iteration_count = _time1 + new_dt;
new_control = scITER_R;
}else{
double reftime;
@@ -245,7 +245,7 @@ bool TRANSIENT::next()
reftime = _sim->_time0;
trace0("accepted");
}else{
- reftime = time1;
+ reftime = _time1;
trace0("rejected");
}
trace2("", step_cause(), old_dt);
@@ -280,8 +280,8 @@ bool TRANSIENT::next()
// not sure of exact time. will be rescheduled if wrong.
// ok to move by _sim->_dtmin. time is not that accurate anyway.
if (_time_by_ambiguous_event < newtime - _sim->_dtmin) {
- if (_time_by_ambiguous_event < time1 + 2*_sim->_dtmin) {untested();
- double mintime = time1 + 2*_sim->_dtmin;
+ if (_time_by_ambiguous_event < _time1 + 2*_sim->_dtmin) {untested();
+ double mintime = _time1 + 2*_sim->_dtmin;
if (newtime - _sim->_dtmin < mintime) {untested();
newtime = mintime;
new_control = scAMBEVENT;
@@ -341,11 +341,25 @@ bool TRANSIENT::next()
// quantize
if (newtime < almost_fixed_time) {
assert(new_dt >= 0);
- if (newtime > reftime + old_dt*.8
+ if (newtime < _sim->_time0) {untested();
+ assert(reftime == _time1);
+ assert(reftime < _sim->_time0); // not moving forward
+ // try to pick a step that will end up repeating the rejected step
+ // with an integer number of same size steps
+ double target_dt = _sim->_time0 - reftime;
+ assert(target_dt > new_dt);
+ double steps = 1 + floor((target_dt - _sim->_dtmin) / new_dt);
+ assert(steps > 0);
+ new_dt = target_dt / steps;
+ newtime = reftime + new_dt;
+ check_consistency();
+ }else if (newtime > reftime + old_dt*.8
&& newtime < reftime + old_dt*1.5
&& reftime + old_dt <= almost_fixed_time) {
// new_dt is close enough to old_dt.
// use old_dt, to avoid a step change.
+ assert(reftime == _sim->_time0); // moving forward
+ assert(reftime > _time1);
new_dt = old_dt;
newtime = reftime + new_dt;
if (newtime > almost_fixed_time) {untested();
@@ -359,6 +373,8 @@ bool TRANSIENT::next()
// There will be a step change.
// Try to choose one that we will keep for a while.
// Choose new_dt to be in integer fraction of target_dt.
+ assert(reftime == _sim->_time0); // moving forward
+ assert(reftime > _time1);
double target_dt = fixed_time - reftime;
assert(target_dt >= new_dt);
double steps = 1 + floor((target_dt - _sim->_dtmin) / new_dt);
@@ -398,7 +414,7 @@ bool TRANSIENT::next()
/* got it, I think */
/* check to be sure */
- if (newtime < time1 + _sim->_dtmin) {itested();
+ if (newtime < _time1 + _sim->_dtmin) {itested();
/* It's really bad. */
/* Reject the most recent step, back up as much as possible, */
/* and creep along */
@@ -407,8 +423,8 @@ bool TRANSIENT::next()
assert(step_cause() >= 0);
error(bDANGER,"non-recoverable " + TR::step_cause[step_cause()] + "\n");
error(bDANGER, "newtime=%e rejectedtime=%e oldtime=%e using=%e\n",
- newtime, _sim->_time0, time1, time1 + _sim->_dtmin);
- newtime = time1 + _sim->_dtmin;
+ newtime, _sim->_time0, _time1, _time1 + _sim->_dtmin);
+ newtime = _time1 + _sim->_dtmin;
set_step_cause(scSMALL);
//check_consistency2();
throw Exception("tried everything, still doesn't work, giving up");
@@ -417,9 +433,9 @@ bool TRANSIENT::next()
/* Reject the most recent step. */
/* We have faith that it will work with a smaller time step. */
assert(!_accepted);
- assert(newtime >= time1 + _sim->_dtmin);
+ assert(newtime >= _time1 + _sim->_dtmin);
error(bLOG, "backwards time step\n");
- error(bLOG, "newtime=%e rejectedtime=%e oldtime=%e\n", newtime, _sim->_time0, time1);
+ error(bLOG, "newtime=%e rejectedtime=%e oldtime=%e\n", newtime, _sim->_time0, _time1);
set_step_cause(scREJECT);
_sim->mark_inc_mode_bad();
check_consistency2();
@@ -428,9 +444,9 @@ bool TRANSIENT::next()
/* Keep the most recent step, but creep along. */
assert(newtime > _sim->_time0 - _sim->_dtmin);
error(bDANGER, "zero time step\n");
- error(bDANGER, "newtime=%e rejectedtime=%e oldtime=%e\n", newtime, _sim->_time0, time1);
+ error(bDANGER, "newtime=%e rejectedtime=%e oldtime=%e\n", newtime, _sim->_time0, _time1);
if (_accepted) {untested();
- time1 = _sim->_time0;
+ _time1 = _sim->_time0;
}else{untested();
assert(_converged);
}
@@ -448,7 +464,7 @@ bool TRANSIENT::next()
assert(newtime >= _sim->_time0 + _sim->_dtmin);
/* All is OK. Moving on. */
/* Keep value of newtime */
- time1 = _sim->_time0;
+ _time1 = _sim->_time0;
check_consistency2();
}
_sim->_time0 = newtime;
@@ -483,8 +499,8 @@ bool TRANSIENT::review()
// limit minimum time step
// 2*_sim->_dtmin because _time[1] + _sim->_dtmin might be == _time[0].
- if (time_by._event < time1 + 2*_sim->_dtmin) {
- _time_by_ambiguous_event = time1 + 2*_sim->_dtmin;
+ if (time_by._event < _time1 + 2*_sim->_dtmin) {
+ _time_by_ambiguous_event = _time1 + 2*_sim->_dtmin;
}else{
_time_by_ambiguous_event = time_by._event;
}
@@ -494,8 +510,8 @@ bool TRANSIENT::review()
}else{
}
- if (time_by._error_estimate < time1 + 2*_sim->_dtmin) {
- _time_by_error_estimate = time1 + 2*_sim->_dtmin;
+ if (time_by._error_estimate < _time1 + 2*_sim->_dtmin) {
+ _time_by_error_estimate = _time1 + 2*_sim->_dtmin;
}else{
_time_by_error_estimate = time_by._error_estimate;
}
diff --git a/include/patchlev.h b/include/patchlev.h
index 8b4fec4..36b0384 100644
--- a/include/patchlev.h
+++ b/include/patchlev.h
@@ -1 +1 @@
-#define PATCHLEVEL "2014-07-03 bugfix-WIP"
+#define PATCHLEVEL "2014-07-04 bugfix-WIP"
diff --git a/include/s_tr.h b/include/s_tr.h
index be90bf6..b1d16dc 100644
--- a/include/s_tr.h
+++ b/include/s_tr.h
@@ -1,4 +1,4 @@
-/*$Id: s_tr.h,v 26.131 2009/11/20 08:22:10 al Exp $ -*- C++ -*-
+/*$Id: s_tr.h 2014/07/04 al $ -*- C++ -*-
* Copyright (C) 2001 Albert Davis
* Author: Albert Davis <aldavis at gnu.org>
*
@@ -98,7 +98,7 @@ protected:
PARAMETER<double> _dtmin_in; // min internal step size
PARAMETER<double> _dtmax_in; // max internal step size (user)
PARAMETER<int> _skip_in; // fixed step size: internal steps per external
- double time1; /* time at previous time step */
+ double _time1; /* time at previous time step */
double _dtmax; // max internal step size (step / _skip)
bool _cold; // flag: start time=0, all voltages=0
bool _cont; // flag: continue from previous run
--
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