2 * Copyright (C) 2010-2012
3 * Author: Felix Salfelder
5 * This file is part of "Gnucap", the Gnu Circuit Analysis Package
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3, or (at your option)
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 53 Franklin Street, Fifth Floor, Boston, MA
21 *------------------------------------------------------------------
22 * performs tt analysis
28 * - tt_begin/tt_continue
29 * - tt_advance / regress
31 * - TR::sweep (calls tr_accept)
34 * - tt_accept (if queued?)
37 #include "declare.h" /* plclose, plclear, fft */
40 #include "u_nodemap.h"
42 #include "u_sim_data.h"
45 #include "u_function.h" // after?
52 // #include "globals.h" ??
54 #include "e_adplist.h"
56 /*--------------------------------------------------------------------------*/
57 #define sanitycheck() assert ( is_almost( _sim->_Time0 , _Time1 + _sim->_dT0 ));\
58 assert ( _sim->_Time0 > _Time1 || _sim->tt_iteration_number()==0 );\
59 assert ( _sim->_dT0 == 0 || _sim->tt_iteration_number()!=0 );
60 /*--------------------------------------------------------------------------*/
62 /*--------------------------------------------------------------------------*/
63 OMSTREAM
TTT::mstdout(stdout
);
64 /*--------------------------------------------------------------------------*/
65 /*--------------------------------------------------------------------------*/
66 #define check_consistency_tt() { \
67 trace4("", __LINE__, newTime, almost_fixed_Time, fixed_Time); \
68 assert(almost_fixed_Time <= fixed_Time); \
69 assert(newTime <= fixed_Time); \
70 /*assert(newTime == fixed_Time || newTime <= fixed_Time -_dTmin);*/ \
71 assert(newTime <= almost_fixed_Time); \
72 /*assert(newTime == almost_fixed_Time || newTime <= almost_fixed_Time - _dTmin);*/ \
73 assert(newTime > _Time1); \
74 assert(newTime > refTime); \
75 assert(new_dT > 0.); \
76 assert(new_dT >= _dTmin); \
77 assert(newTime <= _Time_by_user_request); \
78 /*assert(newTime == _Time_by_user_request*/ \
79 /* || newTime < _Time_by_user_request - _dTmin); */ \
81 /*--------------------------------------------------------------------------*/
82 int TTT::step_cause()const
84 return ::status
.control
/100;
86 /*--------------------------------------------------------------------------*/
87 double behaviour_time()
91 /*--------------------------------------------------------------------------*/
92 void TTT::set_step_cause(STEP_CAUSE C
)
95 case scITER_A
:untested();
96 case scADT
:untested();
106 ::status
.control
= 100*C
;
108 case scNO_ADVANCE
: untested();
109 case scZERO
: untested();
112 ::status
.control
+= 100*C
;
116 /*--------------------------------------------------------------------------*/
117 double TTT::get_new_dT()
119 double factor
= (double) steps_total();
120 double buf
= 100 / CKT_BASE::tt_behaviour_rel
* factor
;
123 /*--------------------------------------------------------------------------*/
124 void TTT::rescale_behaviour()
128 /*--------------------------------------------------------------------------*/
131 trace2("TTT::first()", _Time1
, _Tstart
);
132 _sim
->force_tt_order(0);
133 // _sim->zero_voltages();
135 // ADP_NODE_LIST::adp_node_list.do_forall( &ADP_NODE::tt_clear );
137 // _Time1 = 0; BUG! a first after powerdown doesnt start at 0
143 if (_sim
->_loadq
.size()) {
144 trace0("TTT::first loadq nonempty -- clearing");
145 _sim
->_loadq
.clear() ; // why?
149 // tell gnuplot that we start from the beginning.
150 // TRANSIENT::_out << "* newline hack\n\n";
152 assert(_sim
->get_tt_order() == 0 );
154 _Time_by_user_request
= _sim
->_Time0
= _Tstart
;
156 if (_Tstop
>0) assert(_Tstep
>0);
158 _sim
->_tt_accepted
= 0;
159 _sim
->_tt_rejects
= 0;
160 _sim
->_tt_rejects_total
= 0;
163 assert(_sim
->_Time0
>= 0 );
167 _sim
->set_command_tt();
169 trace1("TTT::first", _sim
->_Time0
);
171 if (TRANSIENT::_trace
>= tDEBUG
) { untested();
172 TRANSIENT::outdata(_sim
->_Time0
);
174 // outdata(_sim->_Time0);
176 ::status
.tran
.reset().start();
178 //CARD_LIST::card_list.tr_begin(); ///????
179 trace0("TTT::first sweep");
180 CARD_LIST::card_list
.do_tt(); // before sweep_tr
181 // BUG: outdata here maybe
183 print_head_tr(); // always (no review)
186 trace1("TTT::first sweep done", _sim
->_Time0
);
187 // assert (_sim->_loadq.empty());
189 ::status
.hidden_steps
=1;
191 ::status
.review
.stop();
193 _sim
->set_command_tt();
194 set_step_cause(scUSER
);
196 assert(_sim
->_Time0
>= 0 );
197 assert( _sim
->_mode
== s_TTT
);
200 // CARD_LIST::card_list.tt_review();
202 assert(_time_by_ambiguous_event
> _sim
->_Time0
);
204 outdata_tt(_sim
->_Time0
); // first.
206 _Time_by_user_request
= _sim
->_last_Time
= _sim
->_Time0
+ _sim
->last_time();
207 _sim
->_dT0
= _sim
->last_time();
210 /*--------------------------------------------------------------------------*/
216 _sim
->tr_reset(); // assert _sim->_last_time == 0;?
217 trace0("TTT::tt_begin");
219 _sim
->_tt_uic
= false;
220 CARD_LIST::card_list
.do_forall( &CARD::tt_begin
);
221 // advance_time() // must be done, as tt1 is used in do_tt...
222 CARD_LIST::card_list
.do_tt();
224 /*--------------------------------------------------------------*/
227 // continue from externally set adp_node values...
234 _sim
->_tt_uic
= true;
235 CARD_LIST::card_list
.do_forall( &CARD::tt_begin
);
236 CARD_LIST::card_list
.do_tt();
238 /*--------------------------------------------------------------*/
239 void TTT::do_initial_dc()
241 trace3("TTT::do_initial_dc", _sim
->_Time0
, _cont
, _cont_dc
);
242 // set adp_nodes to initial values
243 _sim
->set_inc_mode_bad();
244 CARD_LIST::card_list
.do_forall( &CARD::tr_begin
);
245 _sim
->_phase
= p_INIT_DC
;
246 bool _converged
= solve_with_homotopy(OPT::DCBIAS
,TRANSIENT::_trace
);
247 assert(_converged
); USE(_converged
); // incomplete(); (why?)
253 trace0("TTT::do_initial_dc done");
254 _sim
->keep_voltages();
255 assert(_sim
->last_time() == 0.);
256 _sim
->set_inc_mode_yes();
259 /*--------------------------------------------------------------*/
260 void TTT::power_down(double until
)
263 // do stress apply now, then tt advance and stress_last.
265 _sim
->force_tt_order(0);
266 double time
= until
-_sim
->_last_Time
;
267 trace2("TTT::power_down... ", _sim
->_last_Time
, until
);
271 for(unsigned i
=0; i
<_sim
->_adp_nodes
;i
++ ){
272 trace2("TTT::power_down... ",i
, _sim
->_tt
[i
]);
274 for(unsigned i
=0; i
<_sim
->_adp_nodes
;i
++ ) {
275 trace2("TTT::power_down... ",i
, _sim
->_tr
[i
]);
278 _Time1
= _sim
->_last_Time
;
279 _sim
->_Time0
= _sim
->_last_Time
;
280 assert(tt_iteration_number() == 0);
281 assert(tt_iteration_number() == 0);
287 _sim
->force_tt_order(0); assert(_sim
->get_tt_order() == 0 );
290 advance_Time(); // fix last_iter time (dT0==0);
294 if(_trace
>tDEBUG
) { untested();
295 outdata_b4(_sim
->_Time0
);
298 // start at age stored in tt.
299 notstd::copy_n(_sim
->_tt
, _sim
->_adp_nodes
, _sim
->_tt1
);
301 CARD_LIST::card_list
.tt_advance();
302 // CARD_LIST::card_list.do_tt(); // why?!
304 for (uint_t ii
= 1; ii
<= _sim
->_total_nodes
; ++ii
) {
305 _sim
->_nstat
[_sim
->_nm
[ii
]].set_last_change_time(0);
306 _sim
->_nstat
[_sim
->_nm
[ii
]].store_old_last_change_time();
307 _sim
->_nstat
[_sim
->_nm
[ii
]].set_final_time(0);
309 for (unsigned i
=0; i
<_sim
->_adp_nodes
; i
++) {
310 trace2("TTT::power_down... ",i
, _sim
->_tr
[i
]);
313 // NOW do the powerdown.
315 _sim
->zero_some_voltages();
317 assert( _sim
->_mode
== s_TTT
);
318 print_results_tt( _sim
->_Time0
);
320 trace0("TTT::power_down accept...");
321 CARD_LIST::card_list
.tr_accept();
322 CARD_LIST::card_list
.tr_stress_last(); // FIXME: merge into tt_review
324 for (unsigned i
=0; i
<_sim
->_adp_nodes
; i
++) {
325 trace2("TTT::power_down... ",i
, _sim
->_tr
[i
]);
330 _sim
->_Time0
= until
;
332 advance_Time(); // check: move tr->tr1 correctly...
333 _sim
->force_tt_order(0);
335 for(unsigned i
=0; i
<_sim
->_adp_nodes
;i
++ ) {
336 trace3("TTT::power_down advanced ",i
, _sim
->_tt
[i
], hp(_sim
->_tt
));
338 for(unsigned i
=0; i
<_sim
->_adp_nodes
;i
++ ) {
339 trace3("TTT::power_down advanced ",i
, _sim
->_tt1
[i
], hp(_sim
->_tt1
));
342 CARD_LIST::card_list
.do_tt();
344 trace0("TTT::power_down done");
346 // go on with old voltages (good idea?)
348 _sim
->restore_voltages();
350 /*--------------------------------------------------------------------------*/
352 // do a 2nd tt to check aging impact.
353 // ie. take some norm of node-voltage difference over time.
355 // printing (preliminary)
356 // tALL, /* all accepted time steps */
357 // tGUESS , /* show guess, (accepted only) */
358 // tREJECTED , /* show rejected time steps (+ guesses)
359 // tITERATION , /* also show corrector iterations (not yet) */
360 // tVERBOSE , /* show more stuff? */
361 /*--------------------------------------------------------------------------*/
362 static void register_status();
363 /*--------------------------------------------------------------------------*/
367 assert( _sim
->_mode
== s_TTT
);
368 assert( _sim
->_Time0
>= 0 );
369 _sim
->_phase
= p_NONE
;
371 ::error(bLOG
, "TTT sweep cont %d cont_tt %d new %d cont_dc %d\n", _cont
, _cont_tt
, _new
, _cont_dc
);
372 ::error(bLOG
, "TTT sweep Tstart %f Tstop %f Tstep %f stepmode %d\n",
373 (double)_Tstart
, (double)_Tstop
, (double)_Tstep
, (int)_stepmode
);
374 assert(_sim
->tt_iteration_number() == 0);
380 head_tt(_tstart
, _tstop
, "TTime");
382 // assert(!_new || !_cont_tt); ??
384 if(_sim
->_last_Time
== 0. && !_new
&& !_cont_tt
) {
386 } else if (_sim
->last_time() != 0. && !_cont_tt
) {
391 if(_no_act
) { untested();
392 _out
<< "ttt " << string(_Tstart
) << " " << string(_Tstop
) << " " << string(_Tstep
)
393 << " tran " << string(_tstop
) << " " << string(_tstrobe
) << "\n";
394 _out
<< "stepmode " << _stepmode
<< "\n";
399 _sim
->force_tt_order(0); //hack
402 trace2("TTT::sweep tt_begin", _Tstart
, _sim
->_phase
);
403 _sim
->_last_Time
= _Tstart
;
405 // CARD_LIST::card_list.do_tt(); BUG: not idempotent (?!)
406 set_step_cause(scUSER
);
407 assert(_sim
->_mode
== s_TTT
);
412 // bug: _new not correctly processed (?)
415 if (_new
) {untested();
416 print_results_tt(_sim
->_Time0
);
418 trace1("TTT::sweep pd until", _Tstop
);
420 print_results_tt(_Tstop
);
421 store_results(_Tstop
);
422 _sim
->_last_Time
= _Tstop
;
423 trace0("TTT::sweep pd done");
425 }else if( _Tstop
== _Tstart
|| double(_Tstop
) == 0) {
427 print_results_tt(_sim
->_Time0
);
429 trace0("TTT::sweep just apply");
432 CARD_LIST::card_list
.do_tt();
433 _sim
->_acceptq
.clear();
436 }else if (_Tstop
== _Tstart
) { untested();
437 if (_new
) {untested();
438 print_results_tt(_sim
->_Time0
);
440 trace0("TTT::sweep just printing");
441 outdata_b4(_sim
->_Time0
); // first output tt data
443 }else if (!_cont_dc
) {
445 print_results_tt(_sim
->_Time0
);
447 // _cont_dc == skip initial dc
448 trace0("TTT::sweep from 0");
449 // print_head_tr(); // BUG
452 // outdata_tt( _sim->_Time0); no.
453 assert( _sim
->_mode
== s_TTT
);
454 trace0("initial done");
457 assert(_sim
->_Time0
<= _Tstart
);
459 trace2("",_Time1
,_Tstart
);
460 trace3("TTT::sweep first done", _sim
->_Time0
, _Time1
, _Tstart
);
461 assert (_Time1
== _Tstart
);
462 }else if(_tstop
==0. && _tstrobe
==0. && (!_cont_tt
)) { untested();
463 if (_new
) {untested();
464 print_results_tt(_sim
->_Time0
);
470 }else if (_cont_tt
) { untested();
471 if (_new
) {untested();
472 print_results_tt(_sim
->_Time0
);
474 trace3("cont tt", _sim
->last_Time(), _Tstart
, _sim
->_Time0
);
475 _sim
->_Time0
= _sim
->last_Time();
476 _Tstart
= _sim
->last_Time();
478 assert(_sim
->_Time0
<= _Tstart
);
480 }else if (_cont_dc
) {
481 _sim
->restore_voltages();
483 print_results_tt(_sim
->_Time0
);
485 trace3("tt after tr?", _sim
->last_Time(), _sim
->last_time(), _sim
->last_Time());
486 _sim
->_Time0
= _Tstart
;
487 _sim
->_dT0
= _sim
->last_time();
490 assert(_sim
->_Time0
<= _Tstart
);
493 error(bDANGER
, "tt, unhandled. cont_tt %d cont_dc %d new %d %f %f\n",
494 _cont_tt
, _cont_dc
, _new
, _sim
->last_time(), _sim
->last_Time());
498 // assert (_sim->_loadq.empty());
499 assert(_sim
->_Time0
== _Tstart
);
501 //_time_by_adp=NEVER;
503 trace2("",_Time1
,_Tstart
);
504 assert (_Time1
== _Tstart
);
505 assert( _sim
->_mode
== s_TTT
);
508 assert(step_cause());
509 assert( _sim
->_mode
== s_TTT
);
510 trace8( "TTT::sweep loop start ", _sim
->_Time0
, _Time1
, _sim
->_dT0
,
511 _accepted
, _accepted_tt
, tt_iteration_number(), _sim
->_last_Time
, _sim
->last_time() );
512 assert(_sim
->_dT0
>= _sim
->last_time());
515 // _sim->_last_time = _tstop; // UARGH hack, should be implicit...
516 trace2("TTT::sweep CARD::do_tt", _sim
->_dT0
, _sim
->last_time());
517 assert( _sim
->_dT0
- _sim
->last_time() >= 0);
520 CARD_LIST::card_list
.do_tt(); // before sweep_tr
522 assert( _sim
->_mode
== s_TTT
);
523 if(_trace
>= tITERATION
) {
524 outdata_b4(_sim
->_Time0
);
526 store_results_tt(_sim
->_Time0
); // first output tt data
527 assert( _sim
->_mode
== s_TTT
);
528 // _sim->_time0 = _sim->last_time(); // time0 does not necessarily correspond to a
530 // assert( _sim->_time0 <= _sim->_dT0);
532 assert(step_cause());
534 assert(step_cause());
536 if (!_accepted
) { incomplete();
537 assert(_sim
->_mode
==s_TTT
);
538 _accepted_tt
= false;
540 _accepted_tt
= review();
543 trace4("", _sim
->_Time0
, _Time_by_user_request
, _tstop
, step_cause());
544 // assert (_sim->_Time0 <= _Time_by_user_request + _tstop * 1.0001 );
547 error(bDEBUG
, "rejected step at %f, want %f, delta %E\n",
548 _sim
->_Time0
, _Time_by_error_estimate
,
549 _sim
->_Time0
- _Time_by_error_estimate
);
551 _sim
->_tt_rejects_total
++;
552 if (_trace
>= tDEBUG
) { untested();
553 print_stored_results_tt(-_sim
->_Time0
);
556 if (_trace
>= tREJECTED
) {
557 TRANSIENT::_out
<< "#r\n";
558 assert(step_cause());
559 outdata_tt(_sim
->_Time0
);
560 assert( _sim
->_mode
== s_TTT
);
565 _sim
->_time0
= _sim
->last_time(); // time0 does not necessarily correspond to a
567 _sim
->keep_voltages(); // assume that v0 is still what we want to keep...
568 assert(0.99999* _sim
->last_time() <= _tstop
);
569 if (_trace
== tGUESS
) {
570 // in verbose mode, stored data have been printed already...
571 print_stored_results_tt(_sim
->_Time0
);
574 assert( _sim
->_mode
== s_TTT
);
578 // } else if (_sim->_last_Time + 0.00001 > _Tstop) {
579 // // good idea? better leave it to next() ...
580 // _Time_by_user_request = _Tstop;
581 } else if (_sim
->_Time0
>= _Time_by_user_request
// incomplete
582 || step_cause() == scUSER
|| step_cause() == scLAST
) {
583 trace3("TTT::sweep user step", _sim
->_Time0
, _sim
->last_time(), _Time_by_user_request
);
584 assert(step_cause() == scUSER
|| step_cause() == scINITIAL
|| step_cause() == scLAST
);
585 outdata_tt(_sim
->_Time0
);
587 switch (_stepmode
) { //
589 _Time_by_user_request
= _sim
->_Time0
+ _Tstep
;
590 // _out << "LIN" << _Time_by_user_request << " " << _Tstep << "\n";
593 _Time_by_user_request
= _sim
->_Time0
+ _sim
->last_time() * pow((double)_Tstep
, _printed_steps
);
598 assert(_Time_by_user_request
>=_sim
->_last_Time
);
599 // if(_Time_by_user_request > _Tstop - 2.*_tstop){ untested();
600 // _Time_by_user_request = _Tstop - _tstop;
601 // }else if(_Time_by_user_request > _Tstop - _tstop){ untested();
602 // _Time_by_user_request = _Tstop - _tstop;
605 } else if(_trace
>= tALLTIME
) {
606 assert(step_cause());
607 outdata_tt(_sim
->_Time0
);
609 trace1("TTT::sweep not printing", _sim
->_Time0
);
610 TTT::store_results( _sim
->_Time0
+ _tstop
);
615 _Time_by_user_request
= min(_Time_by_user_request
, _Tstop
-_sim
->last_time());
617 _sim
->_last_Time
= _sim
->_Time0
+ _sim
->last_time();
618 trace5("TTT::sweep bottom loop", _sim
->_last_Time
, _sim
->_Time0
, _Time_by_user_request
, _stepmode
, _Tstep
);
619 assert( _sim
->_mode
== s_TTT
);
622 assert( _sim
->_mode
== s_TTT
);
624 // _out << "* TTT::sweep =================== endof loop "<<_sim->_last_Time<<"\n";
625 _sim
->_Time0
= _sim
->_last_Time
;
631 /// invalidate history
632 std::fill_n(_sim
->_tr1
, _sim
->_adp_nodes
, NAN
);
633 std::fill_n(_sim
->_tt1
, _sim
->_adp_nodes
, NAN
);
635 _sim
->set_command_tt();
637 /*--------------------------------------------------------------------------*/
638 void TTT::sweep_tr() // tr sweep wrapper.
640 _sim
->_time0
= 0.;// for now?
641 _sim
->keep_voltages(true); // also sets _last_time=_time0
642 unsigned hidden
= ::status
.hidden_steps
;
643 int ttcontrol
= ::status
.control
;
644 _sim
->_mode
= s_TRAN
;
645 //print_head_tr(); wrong. not b4 accept
646 trace4("TTT::sweep_tr", storelist().size() , _sim
->tt_iteration_number(), ttcontrol
, _tstop
);
647 typedef std::map
<std::string
, WAVE
> wavemap_t
;
648 for ( wavemap_t::iterator i
= _sim
->_waves
["tran"].begin(); i
!= _sim
->_waves
["tran"].end(); ++i
) {
649 i
->second
.initialize();
653 trace1("TTT::sweep_tr() ", _inside_tt
);
658 trace4("TTT::sweep calling sweep", _sim
->_time0
, _sim
->last_time(), _tstrobe
, _sim
->_phase
);
660 assert(_sim
->_mode
== s_TTT
);
663 assert( _sim
->last_time() <= _tstop
+ _sim
->_dtmin
);
665 }catch (Exception
& e
) { untested();
666 assert(_sim
->_mode
== s_TTT
);
667 error(bDANGER
, "Sweep exception \"%s\" at %E, dT0 %E, step %i\n",
668 e
.message().c_str(), _sim
->_Time0
, _sim
->_dT0
, tt_iteration_number());
669 assert(_sim
->_dT0
> _sim
->last_time()); // = means zero step
670 // if this fails, something is wrong.
671 _accepted
=_accepted_tt
=false;
672 ::status
.review
.stop();
673 // _sim->invalidate_tt();
674 // throw(e); go on with smalller step?
675 if (!tt_iteration_number()) { untested();
676 _out
<< "* first one must not fail\n";
681 if(_sim
->_tt_accepted
&& _agemode
== amONCE
){
682 error(bNOERROR
, "skipping tr_stress_last\n");
684 CARD_LIST::card_list
.tr_stress_last(); // FIXME: merge into tt_review
691 ::status
.control
= ttcontrol
;
692 ::status
.hidden_steps
= hidden
;
694 _sim
->pop_voltages();
695 _sim
->_time0
= _sim
->last_time();
696 _sim
->keep_voltages();
697 trace4( "TTT::sweep_tr done", _sim
->_Time0
, _sim
->_time0
, _sim
->last_time(), _tstop
);
698 assert(_sim
->_last_time
*0.9999 <= _tstop
);
700 /*--------------------------------------------------------------------------*/
704 ADP_NODE_LIST::adp_node_list
.do_forall( &ADP_NODE::tt_accept
);
706 // FIXME: _tt_acceptq -> corrector?
707 if(_sim
->_tt_accepted
&& _agemode
== amONCE
){
708 error(bNOERROR
, "skipping tt_accept\n");
710 while (!_sim
->_tt_acceptq
.empty()) {
711 _sim
->_tt_acceptq
.back()->tt_accept();
712 _sim
->_tt_acceptq
.pop_back();
715 _sim
->_tt_accepted
++;
716 // _sim->_last_Time = _sim->_Time0+_tstop;
718 /*--------------------------------------------------------------------------*/
719 double TTT::time_by_voltages()
721 // we started at vdc (unchanged), before keep, compare v0<->vdc
725 for (unsigned i
=1; i
<=_sim
->_total_nodes
; ++i
) { untested();
726 double delta
= fabs(_sim
->_v0
[i
]-_sim
->vdc()[i
]);
727 double sum
= fabs(_sim
->_v0
[i
])+fabs(_sim
->vdc()[i
]);
738 /*-----------------------------------------------------------*/
739 // need to check that boundaries are consistent.
740 bool TTT::conchk() const
742 double a
= OPT::abstol
;
743 double r
= OPT::reltol
;
745 for (unsigned i
=1; i
<=_sim
->_total_nodes
; ++i
) { untested();
746 double n
= fabs(_sim
->_v0
[i
]);
747 double o
= fabs(_sim
->vdc()[i
]);
749 if (std::abs(n
-o
) > (r
* std::abs(n
) + a
))
754 /*--------------------------------------------------------------------------*/
759 assert(_sim
->_Time0
>= _sim
->_dT0
);
760 assert(_sim
->_Time0
- _sim
->_dT0
>=0 );
762 TIME_PAIR Time_by
= CARD_LIST::card_list
.tt_review();
763 _Time_by_error_estimate
= Time_by
._error_estimate
;
765 if(Time_by
._event
< _Time1
+ _sim
->last_time()){
766 _time_by_ambiguous_event
= _Time1
+ _sim
->last_time();
768 _time_by_ambiguous_event
= Time_by
._event
;
771 trace6("TTT::review", _sim
->_Time0
, _sim
->_dT0
, _Time_by_error_estimate
, _time_by_ambiguous_event
, _sim
->last_time(), _Time1
);
773 _dT_by_adp
= (ADP_NODE_LIST::adp_node_list
.tt_review())._event
;
775 // double _dT_by_nodes = time_by_voltages();// 1.0 / (1e-20+voltage_distance());//
777 // BUG. don't use _Time1 here.
778 _time_by_adp
= _Time1
+ _dT_by_adp
;
780 if ((_dT_by_adp
< _tstop
) && (_tstop
== _sim
->_dT0
)) { untested();
784 if( _time_by_adp
< _sim
->_Time0
){ untested();
785 // _out << "* tt reject (adp) timestep " << _sim->_dT0 << " want dT " << _dT_by_adp << " \n";
786 trace3( "TTT::review_tt: reject adptime", _sim
->_Time0
, _dT_by_adp
, _sim
->_dT0
);
789 bool acc
= _Time_by_error_estimate
+ .01*_sim
->_dtmin
>= _sim
->_Time0
790 && _time_by_ambiguous_event
>= _sim
->_Time0
;
792 if(step_cause() == scLAST
&& !acc
) {
794 trace3( "TTT::review_tt: endless loop", _sim
->_Time0
, _sim
->_dT0
, _Tstop
);
800 /*--------------------------------------------------------------------------*/
801 void TTT::do_it(CS
& Cmd
, CARD_LIST
* Scope
)
804 _sim
->set_command_tt();
805 _sim
->set_label("tt");
806 // _sim->_age = false; // a tr option
807 ::status
.ttt
.reset().start();
808 ::status
.tt_tries
= 0;
809 command_base(Cmd
); // s__init.cc
810 assert(_sim
->_mode
==s_TTT
);
813 ::status
.four
.stop(); // ?
814 ::status
.total
.stop(); // ?
816 /*--------------------------------------------------------------------------*/
817 void TTT::probeexpand()
819 trace0("TTT::probeexpand");
820 _sim
->_mode
= s_TRAN
; // BUG: use phase.
821 PROBELIST
* transtore
= &_probe_lists
->store
[s_TRAN
];
823 // append prior prints to store (aligned)
824 for (PROBELIST::const_iterator p
=printlist().begin();
825 p
!=printlist().end(); ++p
) {
826 PROBE
* x
=((*p
)->clone());
827 transtore
->push_probe(x
);
830 // additionally store during TR as user wishes. (if necessary)
831 for (PROBELIST::const_iterator p
=oldstore
.begin();
832 p
!=oldstore
.end(); ++p
) {
833 PROBE
* x
=((*p
)->clone());
834 transtore
->merge_probe(x
);
837 _sim
->set_command_tt();
840 for (PROBELIST::const_iterator
841 p
=printlist().begin(); p
!=printlist().end(); ++p
) {
842 MEAS_PROBE
* w
= dynamic_cast<MEAS_PROBE
*>(*p
);
845 string probe_name
= w
->probe_name
;
846 trace1("TTT::probeexpand", probe_name
);
847 CS
* c
= new CS(CS::_STRING
,probe_name
);
848 measstore
.add_list(*c
);
854 // merge some more measure nodes.
855 for (PROBELIST::const_iterator p
=measstore
.begin();
856 p
!=measstore
.end(); ++p
) {
857 PROBE
* x
=((*p
)->clone());
858 transtore
->merge_probe(x
);
861 /*--------------------------------------------------------------------------*/
862 /* allocate: allocate space for tt
866 int probes
= printlist().size();
868 trace1("TTT::allocate allocating probes ", probes
);
869 _tt_store
= new double[probes
]; // shadows the .print tt probes
871 PROBELIST
* transtore
= &_probe_lists
->store
[s_TRAN
];
873 for (PROBELIST::const_iterator p
=transtore
->begin();
874 p
!=transtore
->end(); ++p
) {
875 oldstore
.push_probe((*p
)->clone());
881 assert(_sim
->_mode
==s_TTT
);
883 _sim
->set_command_tran();
885 _sim
->_waves
["tran"].clear();
891 _wavep
= new WAVE
*[_probe_lists
->store
[s_TRAN
].size()];
894 for (PROBELIST::const_iterator
895 p
=storelist().begin(); p
!=storelist().end(); ++p
) {
896 string l
= (*p
)->label();
897 if (OPT::case_insensitive
) {
898 notstd::to_upper(&l
);
900 _wavep
[ii
++] = &(_sim
->_waves
["tran"][l
]);
902 _sim
->set_command_tt();
904 trace1("TTT::allocate allocated transtore waves", _probe_lists
->store
[s_TRAN
].size());
906 /*--------------------------------------------------------------------------*/
907 /* unallocate: unallocate space for tt
908 * (merge further up?)
912 // int probes = printlist().size();
914 trace2("TTT::unallocate freeing _tt_store", printlist().size(), storelist().size());
915 // incomplete(); //unallocate at deconstruction...
916 // make consecutive sims faster.
920 _probe_lists
->store
[s_TRAN
].clear();
921 //FIXME: delete waves;
923 // if (_fdata_tt) { untested();
924 // for (int ii = 0; ii < printlist().size(); ++ii) { untested();
925 // delete [] _fdata_tt[ii];
927 // delete [] _fdata_tt;
931 // TRANSIENT::finish?
932 _sim
->unalloc_vectors();
933 _sim
->_lu
.unallocate();
934 _sim
->_aa
.unallocate();
936 PROBELIST
* transtore
= &_probe_lists
->store
[s_TRAN
];
939 // insert previous store probes
940 for (PROBELIST::const_iterator p
=oldstore
.begin();
941 p
!=oldstore
.end(); ++p
) {
942 transtore
->push_probe((*p
)->clone());
945 // move waves back (hack, workaround)
946 // trace1("TTT::unallocate deleting", _sim->_waves);
948 /*--------------------------------------------------------------------------*/
950 DISPATCHER
<CMD
>::INSTALL
d10(&command_dispatcher
, "twotimetran|ttr", &p10
);
951 /*--------------------------------------------------------------------------*/
952 static void register_status()
957 new DISPATCHER
<CKT_BASE
>::INSTALL(&status_dispatcher
, "tt", &p10
);
961 /*--------------------------------------------------------------------------*/
962 /*--------------------------------------------------------------------------*/
963 double behaviour_timestep()
967 /*--------------------------------------------------------------------------*/
970 if(_Time_by_user_request
> _Tstop
){ untested();
974 assert( _sim
->_mode
== s_TTT
);
977 double refTime
= _Time1
;
980 trace7( "TTT::next()", tt_iteration_number(), _sim
->_Time0
, _Time1
,
981 _sim
->_last_Time
, _accepted_tt
, _Time_by_user_request
, _Time_by_error_estimate
);
983 assert(_sim
->_Time0
>=0 || tt_iteration_number() == 0);
984 STEP_CAUSE new_control
= scNO_ADVANCE
;
986 if (_sim
->_dT0
== 0.) { unreachable();
987 // first transient. is this reachable?
989 }else if (_Time1
== _sim
->_Time0
) {
991 new_dT
= _sim
->last_time();
992 new_control
= scINITIAL
;
993 } else if (!_accepted_tt
) {
994 error(bTRACE
, "rejected step %f... at %f\n", _sim
->_dT0
, _sim
->_Time0
);
996 new_dT
= 0.9 * ( _sim
->_dT0
- _sim
->last_time() ) + _sim
->last_time(); // back at least this much.
997 if ( _time_by_adp
< _sim
->_Time0
){ untested();
998 assert(_time_by_adp
>= 0);
999 new_dT
= fmin(new_dT
, _dT_by_adp
);
1002 if ( _Time_by_error_estimate
< _sim
->_Time0
){
1003 assert(_Time_by_error_estimate
>= 0);
1004 new_dT
= fmin(new_dT
, _Time_by_error_estimate
- _Time1
);
1009 new_dT
= fmin(new_dT
,.5*_sim
->_dT0
);
1013 assert( is_number(new_dT
));
1014 new_control
= scREJECT
;
1016 // accepted step. calculating new_dT
1017 refTime
= _sim
->_Time0
;
1019 new_dT
= _Time_by_user_request
- refTime
;
1020 new_control
= scUSER
;
1022 if (new_dT
> _dT_by_adp
) { untested();
1024 if (new_dT
> _Time_by_error_estimate
- refTime
) {
1026 new_dT
= _Time_by_error_estimate
- refTime
;
1029 if(OPT::ttstepgrow
== 0) {
1030 // fixme: allow "inf" in u_opt
1031 }else if(new_dT
> _sim
->_dT0
* OPT::ttstepgrow
) {
1032 new_control
= scGROW
;
1033 new_dT
= _sim
->_dT0
* OPT::ttstepgrow
;
1037 // new_dT = max( new_dT, (double) _tstop );
1038 new_dT
= max( new_dT
, (double) _sim
->last_time() );
1039 assert(new_dT
>= 0.);
1041 if (new_dT
< _dTmin
) {
1042 error(bTRACE
, "step too small %e %e adp %e\n", new_dT
, _dTmin
, _dT_by_adp
);
1046 // last step handler, snap to edge
1048 assert( !OPT::ttstepgrow
|| new_dT
< (OPT::ttstepgrow
+1) * _sim
->_dT0
|| _sim
->_dT1
<=0 );
1050 ++::status
.hidden_steps_tt
;
1053 double newTime
= refTime
+ new_dT
;
1054 trace8("TTT::next", _time_by_ambiguous_event
, _Time1
, _sim
->_last_Time
, _tstop
, _Tstart
, newTime
, _Time_by_user_request
, _sim
->last_time());
1055 assert(_time_by_ambiguous_event
> _Time1
);
1057 if (!_evt
) { untested();
1058 new_dT
= newTime
- refTime
; // bug?
1059 assert(new_dT
>= 0.9999 * _sim
->last_time());
1060 }else if (_time_by_ambiguous_event
< newTime
- _sim
->_dTmin
) {
1061 if (_time_by_ambiguous_event
< _Time1
+ 2*_sim
->last_time()) {
1062 double minTime
= _Time1
+ 2*_sim
->last_time();
1063 if (newTime
- _sim
->last_time() < minTime
) {
1065 new_control
= scAMBEVENT
;
1069 newTime
= _time_by_ambiguous_event
;
1070 new_control
= scAMBEVENT
;
1072 trace5("ambevent", _time_by_ambiguous_event
, _sim
->_Time0
, newTime
, refTime
, _accepted_tt
);
1073 new_dT
= newTime
- refTime
;
1074 assert(new_dT
>= 0.);
1078 assert(step_cause());
1080 new_Time0
= _sim
->_last_Time
+ new_dT
- _sim
->last_time();
1081 trace6("TTT::next ", new_dT
, _tstop
, new_dT
, _Time_by_user_request
, new_Time0
, refTime
);
1082 assert(new_Time0
> _Time1
);
1084 assert(new_Time0
> _Time1
);
1086 // hmm rethink. maybe don't shift forwards if not necessary....
1087 if ( (double)_Tstop
- _sim
->last_time() <= _sim
->_last_Time
) {
1088 // new_control = scLAST;
1089 }else if ( ( (double)_Tstop
- _sim
->_last_Time
< 2.00001 * _tstop
1090 || new_dT
+ _sim
->_last_Time
> _Tstop
) ) {
1092 new_dT
= _Tstop
- _sim
->_Time0
- _sim
->last_time();
1093 assert(new_dT
> 0.999*_sim
->last_time()); //noise?
1094 new_Time0
= _sim
->_last_Time
+ new_dT
- _sim
->last_time();
1095 new_control
= scLAST
;
1096 }else if(new_Time0
+ _sim
->last_time() >= _Time_by_user_request
){
1097 new_control
= scUSER
;
1100 set_step_cause(new_control
);
1102 if (_sim
->_dT1
&& new_dT
< _sim
->last_time() ) {
1103 new_dT
= _sim
->last_time();
1104 assert(new_dT
> 0.999*_sim
->last_time()); //noise?
1105 set_step_cause(scSMALL
);
1109 bool another_step
= true;
1111 if (! ( _Tstop
- _sim
->_last_Time
>= _sim
->last_time() )){
1112 another_step
= false;
1113 }else if (! ( new_Time0
<= _Tstop
- _sim
->last_time() )) {untested();
1114 another_step
= false;
1115 }else if (! ( new_dT
!= 0 || !_sim
->_dT0
)){ untested();
1116 another_step
= false;
1119 trace7("TTT::next", another_step
, _sim
->last_time(), new_Time0
, new_dT
, _sim
->last_Time(), _Time1
, step_cause());
1121 assert(new_Time0
>= new_dT
);
1122 assert(new_Time0
> _Time1
);
1124 if(_accepted_tt
){ // fixme: obenhin, oder?
1125 _sim
->_dT3
= _sim
->_dT2
;
1126 _sim
->_dT2
= _sim
->_dT1
;
1127 _sim
->_dT1
= _sim
->_dT0
;
1130 if (!another_step
) {
1131 trace6( "TTT::next no next @ Time0: " , _sim
->_Time0
, _sim
->_dT0
, new_dT
, _dTmin
, _tstop
, new_Time0
);
1132 trace5( "TTT::next no next @ Time0: " ,\
1133 _Time1
, _Tstop
, new_dT
>= _dTmin
, _Tstop
- _Time1
>= _dTmin
, new_Time0
+ _tstop
<= _Tstop
);
1134 // _sim->_last_Time = _Time1 + _tstop; // FIXME
1136 return (false); // bug
1138 trace8("TTT::next another step ", _sim
->_Time0
, new_dT
, _Time1
, _Tstop
,
1139 _sim
->_dT0
, new_Time0
, _Time_by_user_request
, _dTmin
);
1142 assert(new_dT
> 0.999*_sim
->last_time()); //noise?
1143 if (new_dT
< _sim
->last_time()) {
1145 new_dT
= _sim
->last_time();
1148 _sim
->_dT0
= new_dT
;
1149 _sim
->_Time0
= new_Time0
;
1151 assert( _sim
->_Time0
>= _sim
->_dT0
*0.9999 );
1152 if (_sim
->_Time0
< _sim
->_dT0
) {
1154 _sim
->_Time0
= _sim
->_dT0
;
1158 // assert(_sim->_dT0 >= _dTmin);
1159 assert(_sim
->_dT0
+ 0.001*_dTmin
>= _sim
->last_time());
1160 assert(_sim
->_dT0
>= _sim
->last_time());
1164 assert( _sim
->_Time0
< 1+ _Time1
+ _sim
->_dT0
);
1165 assert( _sim
->_Time0
>= _sim
->_dT0
);
1166 assert( _sim
->_Time0
> 0 || tt_iteration_number() == 0);
1168 _sim
->restore_voltages();
1170 trace0("praparing nodes nodes");
1172 for (uint_t ii
= 1; ii
<= _sim
->_total_nodes
; ++ii
) {
1173 _sim
->_nstat
[_sim
->_nm
[ii
]].set_last_change_time(0);
1174 _sim
->_nstat
[_sim
->_nm
[ii
]].store_old_last_change_time();
1175 _sim
->_nstat
[_sim
->_nm
[ii
]].set_final_time(0);
1180 ++::status
.hidden_steps
;
1182 trace8( "TTT::next: exiting next: " , _sim
->tt_iteration_number(),
1183 _sim
->_Time0
, _Time1
, _sim
->_dT0
, _sim
->_dT1
, _sim
->_dT2
, _sim
->_last_Time
, step_cause() );
1184 assert(_sim
->_Time0
> _Time1
);
1185 // assert(_sim->_dT0 >= _dTmin);
1186 assert(step_cause());
1187 return another_step
;
1189 /*--------------------------------------------------------------------------*/
1190 /* SIM::head: print column headings and draw plot borders
1193 void TTT::head_tt(double start
, double stop
, const std::string
& col1
)
1195 trace2("TTT::head_tt", start
, stop
);
1196 assert(_sim
->_mode
==s_TTT
);
1197 //PROBELIST* transtore = &_probe_lists->store[s_TRAN];
1199 print_tr_probe_number
= printlist().size();
1201 trace1("TTT::head tr ttt WAVE", storelist().size() );
1207 _wavep_tt
= new WAVE
*[storelist().size()];
1209 for (PROBELIST::const_iterator
1210 p
=storelist().begin(); p
!=storelist().end(); ++p
) {
1211 string l
= (*p
)->label();
1212 if (OPT::case_insensitive
) {
1213 notstd::to_upper(&l
);
1215 _wavep_tt
[ii
] = &(_sim
->_waves
[_sim
->_label
][l
]);
1216 _wavep_tt
[ii
++]->initialize();
1220 if (!plopen(start
, stop
, plotlist())) {
1221 // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1222 int width
= std::min(OPT::numdgt
+5, BIGBUFLEN
-10);
1224 //sprintf(format, "%%c%%-%u.%us", width, width);
1225 sprintf(format
, "%%c%%-%us", width
);
1226 _out
.form(format
, '#', col1
.c_str());
1228 for (PROBELIST::const_iterator
1229 p
=printlist().begin(); p
!=printlist().end(); ++p
) {
1230 _out
.form(format
, ' ', (*p
)->label().c_str());
1231 //trace1("TTT::head_tt", (*p)->label() );
1232 if ( !(--print_tr_probe_number
) ) break;
1240 trace3("TTT::tt_head probe TRAN", printlist().size(), storelist().size(), oldstore
.size());
1242 // _sim->_waves = new WAVE[storelist().size()];
1245 for (PROBELIST::const_iterator
1246 p
=printlist().begin(); p
!=printlist().end(); ++p
) {
1248 (*p
)->precalc_last();
1252 /*--------------------------------------------------------------------------*/
1253 /* SIM::head: initialize waves, override TRANSIENT::head()
1255 void TTT::head(double /* start */ , double /* stop */, const std::string
& )
1257 trace0("TTT::head");
1258 assert(_sim
->_mode
==s_TTT
);
1260 if (_sim
->tt_iteration_number() == 0) {
1261 TRANSIENT::_out
.setfloatwidth(OPT::numdgt
, OPT::numdgt
+6);
1264 trace3("TTT::head probe TTT", printlist().size(), storelist().size(), _sim
->_phase
);
1267 for (PROBELIST::const_iterator
1268 p
=storelist().begin(); p
!=storelist().end(); ++p
) {
1269 string l
= (*p
)->label();
1270 if (OPT::case_insensitive
) {
1271 notstd::to_upper(&l
);
1273 _wavep
[ii
] = &(_sim
->_waves
["tran"][l
]);
1274 _wavep
[ii
++]->initialize();
1277 _sim
->_mode
= s_TTT
;
1279 /*--------------------------------------------------------------------------*/
1280 /* SIM::print_head: print column headers TR
1282 void TTT::print_head_tr()
1284 trace0("TTT::print_head_tr");
1286 //assert( _sim->_mode==s_TRAN );
1287 _sim
->_mode
= s_TRAN
;
1288 SIM_MODE oldmode
= _sim
->_mode
;
1290 if (!printlist().size()) {
1291 // incomplete(); // bug: what to do with empty printlists?
1292 // for now: suppress output...
1293 _sim
->_mode
= oldmode
;
1296 TRANSIENT::_out
<< "#TTime ";
1298 // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1299 int width
= std::min(OPT::numdgt
+5, BIGBUFLEN
-10);
1301 sprintf(format
, "%%c%%-%us", width
);
1302 for (int i
=0; i
< OPT::numdgt
; i
++) {
1303 TRANSIENT::_out
<< " ";
1305 TRANSIENT::_out
<< "time";
1306 for (int i
=0; i
< OPT::numdgt
+1; i
++) {
1307 TRANSIENT::_out
<< " ";
1309 for (PROBELIST::const_iterator
1310 p
=printlist().begin(); p
!=printlist().end(); ++p
) {
1311 TRANSIENT::_out
.form(format
, ' ', (*p
)->label().c_str());
1313 TRANSIENT::_out
<< '\n';
1315 _sim
->_mode
= oldmode
;
1316 TRANSIENT::_out
.setfloatwidth(OPT::numdgt
, OPT::numdgt
+6);
1318 /*--------------------------------------------------------------------------*/
1319 void TTT::print_foot_tr()
1321 // make plotter happy. (only if _out!=TRANSIENT::_out?)
1322 _sim
->set_command_tran();
1323 if (printlist().size()) {
1324 TRANSIENT::_out
<< '\n';
1327 /*--------------------------------------------------------------------------*/
1328 // override TRANSIENT::outdata
1329 // save things during TR.
1330 void TTT::outdata(double time0
)
1332 assert(TRANSIENT::step_cause());
1333 assert(is_number(time0
));
1334 _sim
->_mode
= s_TTT
;
1335 ::status
.output
.start();
1336 assert( _sim
->_mode
== s_TTT
);
1340 if ( _trace
>=tDEBUG
) { untested();
1341 TRANSIENT::print_results(time0
);
1344 _sim
->set_command_tran();
1345 if (_sim
->tt_iteration_number()==0 && printlist().size() != 0) {
1346 // will always accept 1st
1347 TRANSIENT::_out
<< (double)_sim
->_Time0
;
1348 TRANSIENT::print_results(time0
);
1350 // store_results(time0);
1351 if (TRANSIENT::_trace
>= tDEBUG
){ untested();
1352 TRANSIENT::_out
<< "*" << (double)_sim
->_Time0
;
1353 TRANSIENT::print_results(time0
);
1356 _sim
->set_command_tt();
1359 // FIXME (only > 0)?
1360 TRANSIENT::store_results(time0
);
1362 _sim
->_mode
= s_TTT
;
1363 _sim
->reset_iteration_counter(iPRINTSTEP
);
1364 ::status
.hidden_steps
= 0;
1365 ::status
.output
.stop();
1366 assert( _sim
->_mode
== s_TTT
);
1368 /*--------------------------------------------------------------------------*/
1369 void TTT::outdata_b4(double time
)
1371 assert( _sim
->_mode
== s_TTT
);
1372 ::status
.output
.start();
1373 print_results_tt(time
);
1374 ::status
.output
.stop();
1376 /*--------------------------------------------------------------------------*/
1377 // print at end of timeframe. "now" is begin of timeframe...
1378 void TTT::outdata_tt(double now
)
1380 assert(step_cause());
1381 assert(_sim
->_mode
==s_TTT
);
1382 if ( 0 && _accepted_tt
&& _sim
->_dT0
&& !is_almost (_sim
->_dT0
+ _sim
->_last_Time
, now
+ _sim
->last_time() )) { untested();
1383 error(bWARNING
, "EOF: %.9f, last_Time: %.9f, dT0: %f, now: %f\n", _sim
->_Time0
+_sim
->last_time(), _sim
->_last_Time
, _sim
->_dT0
,now
);
1385 ::status
.output
.start();
1386 assert( _sim
->_mode
== s_TTT
);
1387 print_results_tr(now
); //transient print?
1388 assert( _sim
->_mode
== s_TTT
);
1389 print_results_tt(now
+ _sim
->last_time());
1390 tt_alarm(_alarm
, &_out
);
1391 assert(_sim
->_mode
==s_TTT
);
1392 if (!tt_iteration_number()) {
1393 TTT::store_results( now
); // store extra results.
1395 TTT::store_results( now
+ _sim
->last_time() ); // results are stored after TRAN
1396 assert(_sim
->_mode
==s_TTT
);
1397 _sim
->reset_iteration_counter(iPRINTSTEP
);
1398 ::status
.hidden_steps
= 0;
1399 ::status
.output
.stop();
1401 /*--------------------------------------------------------------------------*/
1402 // fixme: merge back to s__out.cc
1403 void TTT::tt_alarm(ALARM a
, OMSTREAM
* out
)
1408 if (!out
) { untested();
1412 _out
.setfloatwidth(OPT::numdgt
, OPT::numdgt
+6);
1413 for (PROBELIST::const_iterator
1414 p
=alarmlist().begin(); p
!=alarmlist().end(); ++p
) {
1415 if (!(*p
)->in_range()) {
1417 s
<< (*p
)->label() << '=' << (*p
)->value() << '\n';
1425 *out
<< string(s
.str());
1429 if (abort
&& _accepted_tt
) {
1430 throw Exception_Alarm("values out of range\n");
1433 /*--------------------------------------------------------------------------*/
1434 // print during tr. i.e. print from storelist
1435 void TTT::print_results(double time
)
1440 print_results_tr(time
);
1442 /*--------------------------------------------------------------------------*/
1443 void TTT::print_results_tr(double Time
) // Time is begin of frame
1445 SIM_MODE oldmode
= _sim
->_mode
;
1446 trace4("TTT::print_results_tr()", tt_iteration_number(), Time
, _sim
->_mode
, oldmode
);
1448 _sim
->set_command_tran();
1449 const WAVE
* w
= NULL
;
1451 if ( printlist().size() == 0 ) {
1452 _sim
->_mode
= oldmode
;
1455 assert(_sim
->_mode
=s_TRAN
);
1457 if (!IO::plotout
.any() && _sim
->tt_iteration_number() > 0 ) {
1458 // 1st step has already been printed (no need for review)
1459 TRANSIENT::_out
.setfloatwidth(OPT::numdgt
, OPT::numdgt
+6);
1460 std::map
<std::string
, WAVE
>::const_iterator wi
= _sim
->_waves
["tran"].begin();
1461 assert(wi
!=_sim
->_waves
["tran"].end());
1468 WAVE::const_iterator
* myiterators
= new WAVE::const_iterator
[printlist().size()];
1470 for (PROBELIST::const_iterator p
= printlist().begin();
1471 p
!=printlist().end(); ++p
) {
1472 myiterators
[ii
] = _wavep
[ii
]->begin();
1475 for (WAVE::const_iterator i
= w
->begin(); i
!= w
->end(); i
++) {
1476 TRANSIENT::_out
<< _sim
->_Time0
;
1477 if( i
->first
> _sim
->last_time()) { untested();
1481 TRANSIENT::_out
<< i
->first
;
1484 for (PROBELIST::const_iterator
1485 p
=printlist().begin(); p
!=printlist().end(); ++p
) {
1487 TRANSIENT::_out
<< myiterators
[ii
]->second
;
1492 TRANSIENT::_out
<< '\n';
1494 delete[] myiterators
;
1498 _sim
->set_command_tt(); // FIXME
1499 _sim
->_mode
= oldmode
;
1500 trace3("TTT::print_results_tr done", tt_iteration_number(), Time
, _sim
->_mode
);
1502 /*--------------------------------------------------------------------------*/
1503 void TTT::print_stored_results_tt(double x
)
1506 if ( printlist().size() ==0) { untested();
1507 trace0("no ttprint");
1511 assert( _sim
->_mode
== s_TTT
);
1512 if (!IO::plotout
.any()) {
1513 assert(x
!= NOT_VALID
);
1516 for (i
=0; i
< printlist().size(); i
++ ) {
1517 _out
<< _tt_store
[i
];
1520 } else { untested();
1523 /*--------------------------------------------------------------------------*/
1524 // store things at begin of timeframe, so it may be printed
1525 // after/if the step is accepted.
1526 void TTT::store_results_tt(double x
)
1528 trace0("TTT::store_results_tt()");
1529 if ( printlist().size() ==0) {
1534 assert( _sim
->_mode
== s_TTT
);
1535 if (!IO::plotout
.any()) {
1536 assert(x
!= NOT_VALID
); USE(x
);
1537 for (PROBELIST::const_iterator
1538 p
=printlist().begin(); p
!=printlist().end(); ++p
) {
1539 _tt_store
[i
++] = (*p
)->value();
1541 } else { untested();
1545 /*--------------------------------------------------------------------------*/
1546 void TTT::print_results_tt(double x
)
1548 if( printlist().size() == 0 && _quiet
){ untested();
1552 assert( _sim
->_mode
== s_TTT
);
1553 if (!IO::plotout
.any()) {
1554 _out
.setfloatwidth(OPT::numdgt
, OPT::numdgt
+6);
1555 assert(x
!= NOT_VALID
);
1557 for (PROBELIST::const_iterator
1558 p
=printlist().begin(); p
!=printlist().end(); ++p
) {
1560 if (!(*p
)) { unreachable(); // ??
1565 _out
<< (*p
)->value();
1566 } catch( Exception_No_Match
) { untested();
1574 /*--------------------------------------------------------------------------*/
1575 string
TTT::status()const
1577 return "twotime timesteps: accepted=" + ::to_string(steps_accepted())
1578 + ", rejected=" + ::to_string(steps_rejected())
1579 + ", total=" + ::to_string(steps_total()) + "\n";
1581 /*--------------------------------------------------------------------------*/
1582 /* SIM::store: store data in preparation for post processing
1583 * use storelist as index for waves
1585 void TTT::store_results(double time
)
1587 trace3("TTT::store_results()", tt_iteration_number(), iteration_number(), time
);
1588 assert(_sim
->_mode
==s_TTT
);
1590 for (PROBELIST::const_iterator
1591 p
=storelist().begin(); p
!=storelist().end(); ++p
) {
1592 trace3("TTT::store_results", time
, (*p
)->label(), (*p
)->value());
1593 _wavep_tt
[ii
++]->push(time
, (*p
)->value());
1596 /*--------------------------------------------------------------------------*/
1597 void TTT::advance_Time(void)
1599 trace6("TTT::advance_Time", _sim
->_tr
[0], _sim
->_tt
[0], _sim
->_Time0
, _sim
->_adp_nodes
, _tstop
, _sim
->_time0
);
1600 ::status
.tt_advance
.start();
1602 static double last_iter_time
;
1603 // _sim->_time0 = 0.;
1604 assert(_sim
->last_time() == _sim
->_time0
);
1605 _sim
->keep_voltages();
1606 assert(_sim
->last_time()*0.9999 <= _tstop
);
1607 if (_sim
->_Time0
> 0) {
1608 if (_sim
->_dT0
== 0) {
1609 } else if (_sim
->_Time0
> last_iter_time
&& _accepted_tt
) {
1610 /* moving forward */
1612 // _sim->_tt_rejects = 0;
1613 _sim
->update_tt_order();
1615 // trace2("TTT::advance_Time", _sim->_tr1[0], _sim->_tt1[0]);
1617 notstd::copy_n(_sim
->_tr2
, _sim
->_adp_nodes
, _sim
->_tr3
);
1618 notstd::copy_n(_sim
->_tr1
, _sim
->_adp_nodes
, _sim
->_tr2
);
1620 assert(is_number(_sim
->_tt
[0]) || !_sim
->_adp_nodes
);
1622 notstd::copy_n(_sim
->_tr
, _sim
->_adp_nodes
, _sim
->_tr1
);
1623 notstd::copy_n(_sim
->_tt
, _sim
->_adp_nodes
, _sim
->_tt1
);
1626 // std::fill_n(_sim->_tr, _sim->_adp_nodes, NAN); // no. needed if ttsteporder==0
1627 // std::fill_n(_sim->_tt, _sim->_adp_nodes, NAN); // no. needed if ttsteporder==0
1629 trace3("TTT::advance_Time done", _sim
->_tr
[0], _sim
->_tt
[0], _sim
->_Time0
);
1630 trace2("TTT::advance_Time done", _sim
->_tr1
[0], _sim
->_tt1
[0]);
1632 // assert(is_number(_sim->_tr1[0]) || !_sim->_adp_nodes); // BUG?
1633 assert(is_number(_sim
->_tt1
[0]) || !_sim
->_adp_nodes
);
1635 ADP_NODE_LIST::adp_node_list
.do_forall( &ADP_NODE::tt_advance
);
1636 /// AFTER tr and tt have been shifted.
1637 CARD_LIST::card_list
.tt_advance();
1641 std::fill_n(_sim
->_tr
, _sim
->_adp_nodes
, NAN
); // invalidate.
1642 std::fill_n(_sim
->_tt
, _sim
->_adp_nodes
, NAN
); // invalidate.
1644 _sim
->restore_voltages();
1646 CARD_LIST::card_list
.tt_regress();
1647 /* moving backward */
1650 trace0("TTT::advance_Time obsolete call?");
1651 ADP_NODE_LIST::adp_node_list
.do_forall( &ADP_NODE::tt_advance
);
1652 /// AFTER tr and tt have been shifted.
1653 CARD_LIST::card_list
.tt_advance();
1655 last_iter_time
= _sim
->_Time0
;
1656 trace0("TTT::advance_Time() done");
1657 ::status
.tt_advance
.stop();
1659 /*--------------------------------------------------------------------------*/
1660 /*--------------------------------------------------------------------------*/