[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