[Pkg-electronics-commits] [gnucap] 39/47: transient-3: more changes to initial time step control also more digits in to_string() tests (==out) not updated, so many "fail"
felix salfelder
felix-guest at moszumanska.debian.org
Mon Sep 26 10:37:50 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 bf2d2991f57a14dede3e302e1e9ddc7a85bfd78d
Author: al davis <ad211 at freeelectron.net>
Date: Wed Sep 21 21:12:30 2016 -0400
transient-3: more changes to initial time step control
also more digits in to_string()
tests (==out) not updated, so many "fail"
---
apps/s_tr_swp.cc | 6 ++--
include/patchlev.h | 2 +-
lib/e_elemnt.cc | 94 +++++++++++++++++++++++++++++-------------------------
lib/l_ftos.cc | 4 +--
4 files changed, 57 insertions(+), 49 deletions(-)
diff --git a/apps/s_tr_swp.cc b/apps/s_tr_swp.cc
index f9b785e..3715910 100644
--- a/apps/s_tr_swp.cc
+++ b/apps/s_tr_swp.cc
@@ -1,4 +1,4 @@
-/*$Id: s_tr_swp.cc 2016/09/20 al $ -*- C++ -*-
+/*$Id: s_tr_swp.cc 2016/09/21 al $ -*- C++ -*-
* Copyright (C) 2001 Albert Davis
* Author: Albert Davis <aldavis at gnu.org>
*
@@ -394,7 +394,7 @@ bool TRANSIENT::next()
// 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);
+ //assert(reftime > _time1); // _time1==_time0 on restart, ok
double target_dt = fixed_time - reftime;
assert(target_dt >= new_dt);
double steps = 1 + floor((target_dt - _sim->_dtmin) / new_dt);
@@ -528,7 +528,7 @@ bool TRANSIENT::review()
}else{
}
- if (time_by._error_estimate < _time1 + 2*_sim->_dtmin) {untested();
+ if (time_by._error_estimate < _time1 + 2*_sim->_dtmin) {itested();
_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 e5a85ec..48c1d39 100644
--- a/include/patchlev.h
+++ b/include/patchlev.h
@@ -1 +1 @@
-#define PATCHLEVEL "transient-3 2016.09.20"
+#define PATCHLEVEL "transient-3 2016.09.21"
diff --git a/lib/e_elemnt.cc b/lib/e_elemnt.cc
index 6534784..31ed39a 100644
--- a/lib/e_elemnt.cc
+++ b/lib/e_elemnt.cc
@@ -1,4 +1,4 @@
-/*$Id: e_elemnt.cc 2016/09/20 al $ -*- C++ -*-
+/*$Id: e_elemnt.cc 2016/09/21 al $ -*- C++ -*-
* Copyright (C) 2001 Albert Davis
* Author: Albert Davis <aldavis at gnu.org>
*
@@ -395,58 +395,66 @@ XPROBE ELEMENT::ac_probe_ext(const std::string& x)const
/*--------------------------------------------------------------------------*/
double ELEMENT::tr_review_trunc_error(const FPOLY1* q)
{
- int error_deriv;
- if (order() >= OPT::_keep_time_steps - 2) {
- error_deriv = OPT::_keep_time_steps - 1;
- }else if (order() < 0) {untested();
- error_deriv = 1;
- }else{
- error_deriv = order()+1;
- }
double timestep;
if (_time[0] <= 0.) {
// DC, I know nothing
timestep = NEVER;
- }else if (_time[error_deriv] <= 0.) {
- // first few steps, I still know nothing
- // repeat whatever step was used the first time
- timestep = _dt;
}else{
- for (int i=error_deriv; i>0; --i) {
- assert(_time[i] < _time[i-1]); // || _time[i] == 0.);
+ int error_deriv; // which derivative to use for error estimate
+ if (order() >= OPT::_keep_time_steps - 2) {
+ error_deriv = OPT::_keep_time_steps - 1;
+ }else if (order() < 0) {untested();
+ error_deriv = 1;
+ }else{
+ error_deriv = order()+1;
}
-
- double c[OPT::_keep_time_steps];
- for (int i=0; i<OPT::_keep_time_steps; ++i) {
- c[i] = q[i].f0;
+ while (_time[error_deriv-1] <= 0.) {
+ // not enough info to use that derivative, use a lower order derivative
+ --error_deriv;
}
+ assert(error_deriv >= 0);
assert(error_deriv < OPT::_keep_time_steps);
- derivatives(c, OPT::_keep_time_steps, _time);
- // now c[i] is i'th derivative
-
- assert(OPT::_keep_time_steps >= 5);
- trace0(("ts" + long_label()).c_str());
- trace5("time", _time[0], _time[1], _time[2], _time[3], _time[4]);
- trace5("charge", q[0].f0, q[1].f0, q[2].f0, q[3].f0, q[4].f0);
- trace5("deriv", c[0], c[1], c[2], c[3], c[4]);
+ for (int i=error_deriv; i>0; --i) {
+ assert(_time[i] < _time[i-1]); // || _time[i] == 0.);
+ }
- if (c[error_deriv] == 0) {
- timestep = NEVER;
+ if (error_deriv == 0) {untested();
+ // this is the second step, and we have no more info
+ // repeat whatever step was used the first time
+ timestep = _dt;
}else{
- double chargetol = std::max(OPT::chgtol,
- OPT::reltol * std::max(std::abs(q[0].f0), std::abs(q[1].f0)));
- double tol = OPT::trtol * chargetol;
- double denom = error_factor() * std::abs(c[error_deriv]);
- assert(tol > 0.);
- assert(denom > 0.);
- switch (error_deriv) { // pow is slow.
- case 1: timestep = tol / denom; break;
- case 2: timestep = sqrt(tol / denom); break;
- case 3: timestep = cbrt(tol / denom); break;
- default: timestep = pow((tol / denom), 1./(error_deriv)); break;
+ double c[OPT::_keep_time_steps];
+ for (int i=0; i<OPT::_keep_time_steps; ++i) {
+ c[i] = q[i].f0;
+ }
+ derivatives(c, OPT::_keep_time_steps, _time);
+ // now c[i] is i'th derivative
+
+ assert(OPT::_keep_time_steps >= 5);
+ trace0(("ts" + long_label()).c_str());
+ trace5("time", _time[0], _time[1], _time[2], _time[3], _time[4]);
+ trace5("charge", q[0].f0, q[1].f0, q[2].f0, q[3].f0, q[4].f0);
+ trace5("deriv", c[0], c[1], c[2], c[3], c[4]);
+
+ if (c[error_deriv] == 0) {
+ // avoid divide by zero
+ timestep = NEVER;
+ }else{
+ double chargetol = std::max(OPT::chgtol,
+ OPT::reltol * std::max(std::abs(q[0].f0), std::abs(q[1].f0)));
+ double tol = OPT::trtol * chargetol;
+ double denom = error_factor() * std::abs(c[error_deriv]);
+ assert(tol > 0.);
+ assert(denom > 0.);
+ switch (error_deriv) { // pow is slow.
+ case 1: timestep = tol / denom; break;
+ case 2: timestep = sqrt(tol / denom); break;
+ case 3: timestep = cbrt(tol / denom); break;
+ default: timestep = pow((tol / denom), 1./(error_deriv)); break;
+ }
+ trace4("", chargetol, tol, denom, timestep);
}
- trace4("", chargetol, tol, denom, timestep);
}
}
assert(timestep > 0.);
@@ -466,8 +474,8 @@ double ELEMENT::tr_review_check_and_convert(double timestep)
if (timestep < _dt * OPT::trreject) {
if (_time[order()] == 0) {
- error(bWARNING, "initial step rejected:" + long_label() + '\n');
- error(bWARNING, "new=%g old=%g required=%g\n",
+ error(bTRACE, "initial step rejected:" + long_label() + '\n');
+ error(bTRACE, "new=%g old=%g required=%g\n",
timestep, _dt, _dt * OPT::trreject);
}else{
error(bTRACE, "step rejected:" + long_label() + '\n');
diff --git a/lib/l_ftos.cc b/lib/l_ftos.cc
index a4883c2..4434507 100644
--- a/lib/l_ftos.cc
+++ b/lib/l_ftos.cc
@@ -1,4 +1,4 @@
-/*$Id: l_ftos.cc,v 26.96 2008/10/09 05:36:27 al Exp $ -*- C++ -*-
+/*$Id: l_ftos.cc 2016/09/21 $ -*- C++ -*-
* Copyright (C) 2001 Albert Davis
* Author: Albert Davis <aldavis at gnu.org>
*
@@ -62,7 +62,7 @@ std::string to_string(int n)
/*--------------------------------------------------------------------------*/
std::string to_string(double n)
{
- return ftos(n, 0, 7, 0);
+ return ftos(n, 0, 15, 0);
}
/*--------------------------------------------------------------------------*/
char* ftos(double num, int fieldwidth, int len, int fmt)
--
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