1 /* Copyright (C) 2011-2013 Felix Salfelder, Lars Hedrich
2 * Author: Felix Salfelder
4 * This file is part of "Gnucap", the Gnu Circuit Analysis Package
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3, or (at your option)
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 *------------------------------------------------------------------
21 * a remote control socket. used by verification tools
28 #include "u_nodemap.h"
38 #include "io_matrix.h"
39 #include "m_matrix_extra.h"
43 /*--------------------------------------------------------------------------*/
44 #define userinfo( a,b,c,d,e,f )
45 /*--------------------------------------------------------------------------*/
47 using namespace SOME_CAP_HACK
; // FIXME. (maybe use STORAGE device interface?)
48 /*--------------------------------------------------------------------------*/
50 /*--------------------------------------------------------------------------*/
56 /*--------------------------------------------------------------------------*/
57 class SOCK
: public DDC_BASE
{
63 void options(CS
&, int x
=0);
66 void sweep_recursive(int);
70 void undo_time_step();
72 static unsigned tr_steps_rejected_
;
76 // typedef void (*p)(double);
77 //ELEMENT* (_pushel[DCNEST]); /* pointer to thing to sweep, dc command */
78 CARDSTASH _stash
[DCNEST
]; /* store std values of elements being swept */
79 bool _loop
[DCNEST
]; /* flag: do it again backwards */
80 bool _reverse_in
[DCNEST
]; /* flag: sweep backwards, input */
81 bool _reverse
[DCNEST
]; /* flag: sweep backwards, working */
82 bool _cont
; /* flag: continue from previous run */
83 TRACE _trace
; /* enum: show extended diagnostics */
84 enum {ONE_PT
, LIN_STEP
, LIN_PTS
, TIMES
, OCTAVE
, DECADE
} _stepmode
[DCNEST
];
85 static double temp_c_in
; /* ambient temperature, input and sweep variable */
92 void do_it(CS
&, CARD_LIST
*);
95 void fillnames( const CARD_LIST
* scope
);
96 void findcaps( CARD_LIST
* scope
);
99 vector
<string
> var_namen_arr
;
100 vector
<COMPONENT
*> _caplist
; // FIXME: use cardlist
101 CARDSTASH
* _capstash
;
102 uint16_t var_namen_total_size
;
104 private: //vera stuff.
106 void verainit(unsigned, unsigned, unsigned);
109 void verainit_reply();
110 void verakons_reply();
114 unsigned transtep(unsigned init
, double dt
);
115 void transtep_reply(unsigned, bool eol
=true);
116 void transtep_gc_reply(unsigned);
122 size_t n_inputs() const{return _input_names
.size();}
123 vector
<string
> _input_names
;
124 vector
<ELEMENT
*> _input_devs
;
126 unsigned n_vars_square
;
127 uint16_t n_eingaenge
;
134 uint16_t _error
; // transport between method and method_reply
135 double _dthack
; // same
137 double *dc_werteA
,*dc_loesungA
,*kons_loesungA
,*kons_residuumA
;
142 short unsigned _port_range
;
143 string _port
; // kommt ueber die Uebergabeparamter port
144 // globale Variable daher (default: port=1400)
151 struct sockaddr_in sin
;
153 double *matrixg
, *matrixc
,*vectorq
;
155 static const int printlevel
=0;
158 /*--------------------------------------------------------------------------*/
159 unsigned SOCK::tr_steps_rejected_
= 0;
160 double SOCK::temp_c_in
= 0.;
161 /*--------------------------------------------------------------------------*/
162 void SOCK::do_it(CS
& Cmd
, CARD_LIST
* Scope
)
164 trace0("SOCK::do_it");
165 IO::error
.detach(stdout
);
166 IO::error
.attach(stderr
);
169 //_sim->set_command_ddc();
170 _sim
->set_command_dc();
171 _sim
->_phase
= p_INIT_DC
;
173 ::status
.ddc
.reset().start();
174 _sim
->_temp_c
= temp_c_in
;
179 _client_mode
= false;
187 /*--------------------------------------------------------------------------*/
188 SOCK::SOCK() :DDC_BASE(),
194 for (int ii
= 0; ii
< DCNEST
; ++ii
) {
196 _reverse_in
[ii
] = false;
197 _reverse
[ii
] = false;
201 _stepmode
[ii
] = ONE_PT
;
203 temp_c_in
=OPT::temp_c
;
206 /*--------------------------------------------------------------------------*/
207 void SOCK::setup(CS
& Cmd
)
210 trace0("SOCK::setup");
214 _out
.reset(); //BUG// don't know why this is needed */
215 bool ploton
= IO::plotset
&& plotlist().size() > 0;
222 Cmd
.check(bWARNING
, "what's this?");
225 CKT_BASE::_sim
->init();
227 IO::plotout
= (ploton
) ? IO::mstdout
: OMSTREAM();
230 _error
= 0; /* verainit(v_flag, n_inputs, &n_vars, charbuf, &length); */
231 n_vars
= static_cast<uint16_t>( _sim
->_total_nodes
) ; // _sim->total_nodes doesnt include gnd
232 // do this also in sweep to initialize the socket streaM
233 var_namen_arr
.resize( n_vars
, string("unset"));
234 // var_namen_arr[0]="0";
235 fillnames( &CARD_LIST::card_list
);
236 n_vars_square
= n_vars
* n_vars
;
238 findcaps(&CARD_LIST::card_list
);
240 // BUG! this kills cap bm's
241 cap_prepare(); // attach value common if !has_common. stash old common
244 for (unsigned i
=0; i
< n_vars
; i
++)
245 trace0("name: " + var_namen_arr
[i
]);
248 assert(_n_sweeps
> 0);
251 /*--------------------------------------------------------------------------*/
252 void SOCK::options(CS
& Cmd
, int Nest
)
254 trace0("SOCK::options... ");
256 _sim
->_uic
= _loop
[Nest
] = _reverse_in
[Nest
] = false;
260 unsigned here
= Cmd
.cursor();
263 || (Cmd
.match1("'\"({") && ((Cmd
>> _step_in
[Nest
]), (_stepmode
[Nest
] = LIN_STEP
)))
264 || (Cmd
.is_float() && ((Cmd
>> _step_in
[Nest
]), (_stepmode
[Nest
] = LIN_STEP
)))
265 || (Get(Cmd
, "*", &_step_in
[Nest
]) && (_stepmode
[Nest
] = TIMES
))
266 || (Get(Cmd
, "+", &_step_in
[Nest
]) && (_stepmode
[Nest
] = LIN_STEP
))
267 || Get(Cmd
, "b{ufsize}", &_bufsize
)
268 || Get(Cmd
, "c{ontinue}", &_cont
)
269 || Get(Cmd
, "port" , &_port
)
270 || Get(Cmd
, "listen{port}", &_port
)
271 || Get(Cmd
, "bigarg", &_bigarg
)
272 || Get(Cmd
, "host" , &_host
)
273 || Get(Cmd
, "tr{s}", &_do_tran_step
)
274 || Get(Cmd
, "dm", &_dump_matrix
)
275 || Get(Cmd
, "client", &_client_mode
)
276 || Get(Cmd
, "server", &_server_mode
)
277 || Get(Cmd
, "dt{emp}", &temp_c_in
, mOFFSET
, OPT::temp_c
)
278 || Get(Cmd
, "lo{op}", &_loop
[Nest
])
279 || Get(Cmd
, "re{verse}", &_reverse_in
[Nest
])
280 || Get(Cmd
, "te{mperature}",&temp_c_in
)
281 || (Cmd
.umatch("tr{ace} {=}") &&
283 || Set(Cmd
, "n{one}", &_trace
, tNONE
)
284 || Set(Cmd
, "o{ff}", &_trace
, tNONE
)
285 || Set(Cmd
, "w{arnings}", &_trace
, tUNDER
)
286 || Set(Cmd
, "i{terations}",&_trace
, tITERATION
)
287 || Set(Cmd
, "v{erbose}", &_trace
, tVERBOSE
)
288 || Cmd
.warn(bWARNING
,
289 "need none, off, warnings, iterations, verbose")
293 }while (Cmd
.more() && !Cmd
.stuck(&here
));
295 /*--------------------------------------------------------------------------*/
296 static void register_status();
297 /*--------------------------------------------------------------------------*/
305 trace1("SOCK::do_it", _port
);
307 // Calculate buffersize
308 n_vars
= _sim
->_total_nodes
;
309 // _sim->total_nodes doesnt include gnd
310 n_vars_square
= n_vars
* n_vars
;
311 _bufsize
= n_vars_square
* 3 * (unsigned)sizeof(double) + 32;
312 // 3 quadratic matrices * doubles + some safety margin (BUG)
315 trace1("bufsize Client ", _bufsize
);
316 socket
= new ClientSocket(Socket::TCP
, _port
, _host
, _bufsize
);
317 trace1("connected to "+ _host
, _port
);
319 } else if (_server_mode
) {
320 stringstream
p(_port
);
323 trace1("bufsize Server ", _bufsize
);
324 socket
= new ServerSocket(Socket::TCP
, _port_
, 1u, _bufsize
);
325 ServerSocket
* sock
=prechecked_cast
<ServerSocket
*>(socket
);
327 trace0("SOCK::do_it waiting");
328 stream
= sock
->listen();
332 trace0("SOCK::sweep simple i/o");
334 trace1("bufsize Stdin ", _bufsize
);
335 stream
= SocketStream( STDOUT_FILENO
, STDIN_FILENO
, _bufsize
);
336 stream
<< "gnucap sock ready";
343 /*--------------------------------------------------------------------------*/
344 string
SOCK::status()const
347 return "sock: tr rejected=" + to_string(tr_steps_rejected_
) + "\n";
349 /*--------------------------------------------------------------------------*/
350 void SOCK::sweep_recursive(int )
354 /*--------------------------------------------------------------------------*/
355 // fetch names from circuit recursively. fill into local vector.
356 void SOCK::fillnames( const CARD_LIST
* scope
){
357 trace0("SOCK::fillnames");
359 const NODE_MAP
* nm
= scope
->nodes();
360 for (NODE_MAP::const_iterator i
= nm
->begin(); i
!= nm
->end(); ++i
) {
361 if (i
->first
!= "0") {
362 if (const NODE
* a
= dynamic_cast<const NODE
*>(i
->second
)){
364 string
myname(a
->long_label());
365 var_namen_arr
[a
->matrix_number()-1] = myname
;
366 var_namen_total_size
= static_cast<uint16_t>( var_namen_total_size
+ static_cast<uint16_t>(myname
.length()) + 1 );
372 for (CARD_LIST::const_iterator i
= scope
->begin(); i
!= scope
->end(); ++i
) {
373 if(const COMPONENT
* s
= dynamic_cast<const COMPONENT
*>(*i
)){
374 if (!s
->is_device()){ untested();
375 }else if ( s
->subckt() ) {
376 fillnames( s
->subckt() );
382 /*--------------------------------------------------------------------------*/
383 void SOCK::findcaps( CARD_LIST
* scope
){
384 for (CARD_LIST::iterator i
= scope
->begin(); i
!= scope
->end(); ++i
) {
385 if ( COMPONENT
* c
= dynamic_cast< COMPONENT
*>(*i
) ) {
386 if (c
->is_device() && c
->has_memory()){
387 trace1("found cap", c
->long_label());
388 _caplist
.push_back( c
);
391 if (!(*i
)->is_device()){ untested();
392 } else if ( BASE_SUBCKT
* s
= dynamic_cast< BASE_SUBCKT
*>(*i
) ) { untested();
393 trace1("going down", s
->long_label());
394 findcaps( s
->subckt() );
398 /*--------------------------------------------------------------------------*/
400 static DISPATCHER
<CMD
>::INSTALL
d2(&command_dispatcher
, "sock", &p2
);
401 /*--------------------------------------------------------------------------*/
402 static void register_status()
407 new DISPATCHER
<CKT_BASE
>::INSTALL(&status_dispatcher
, "sock", &p2
);
412 /*--------------------------------------------------------------------------*/
414 /*--------------------------------------------------------------------------*/
415 static unsigned argc(unsigned opcode
)
424 case 104: untested();
431 /*--------------------------------------------------------------------------*/
432 void SOCK::main_loop()
434 trace0("SOCK::main_loop");
440 bool init_done
=false;
443 trace0("SOCK::main_loop waiting for opcode");
446 stream
>> tmp
>> 7; // sic!
448 for(unsigned i
=0; i
<argc(opcode
); ++i
){
449 stream
>> arg
[i
] >> 6;
458 _sim
->_mode
= s_SOCK
; // nonsense.
459 // use respective built-in mode!
462 ::error(bDEBUG
, "sock opcode %d\n", opcode
);
464 ::error(bDEBUG
, "sock opcode %d %d %d %d\n", opcode
, arg
[0], arg
[1], arg
[2]);
474 if(init_done
) throw Exception("init twice??");
475 verainit(arg
[0], arg
[1], arg
[2]);
487 case 101: untested();
492 status
= transtep(arg
[0], dt
);
493 transtep_reply(status
);
495 case 103: untested();
500 status
= transtep(arg
[0], dt
);
501 transtep_gc_reply(status
);
504 ::error(bDANGER
, "unknown opcode %i\n", opcode
);
505 throw Exception("unknown opcode");
508 _sim
->reset_iteration_counter(iPRINTSTEP
); // used by solve_with_homotopy
509 // reset in outdata (not called)
512 /*--------------------------------------------------------------------------*/
513 // very clever way to transfer strings.
514 static void putstring8(SocketStream
* s
, const string x
)
516 const char* A
= x
.c_str();
519 *s
<<*A
<<*A
<<*A
<<*A
<<*A
<<*A
<<*A
<<*A
;
523 /*--------------------------------------------------------------------------*/
524 void SOCK::verainit(unsigned verbose
, unsigned n_in
, unsigned length
)
527 char input_namen
[length
+1];
530 _input_names
.resize(n_in
);
531 _input_devs
.resize(n_in
);
532 trace3("verainit: ", verbose
,n_inputs(),length
);
533 assert(n_inputs()==n_in
);
535 for (unsigned i
=0; i
< length
; i
++) {
536 stream
>> input_namen
[i
] >> 7;
537 if(input_namen
[i
] == '\t'){
539 trace1("input_namen", string(input_namen
+here
));
540 trace5("input_namen",input_namen
[i
-2],input_namen
[i
-1], input_namen
[i
-0],here
,i
);
541 _input_names
[n
] = string(input_namen
+here
);
544 trace1("looking out for", _input_names
[n
]);
545 CARD_LIST::fat_iterator ci
= findbranch(_input_names
[n
], &CARD_LIST::card_list
);
547 throw Exception("cannot find voltage source \"" + _input_names
[n
] +"\", giving up");
549 trace0("found input device");
550 ELEMENT
* d
= prechecked_cast
<ELEMENT
*>(*ci
);
552 throw Exception("not something we can use as source, \"" + _input_names
[n
] +"\", giving up");
555 assert(_input_devs
[n
]);
558 // see s_cd. FIXME: revert.
559 _stash
[ii
] = _input_devs
[ii
];
560 _input_devs
[ii
]->inc_probes();
561 _input_devs
[ii
]->set_value(_input_devs
[ii
]->value(),0);
562 _input_devs
[ii
]->set_constant(false);
568 //trace0("input_namen " + string(input_namen) );
569 total
= (unsigned) (length
+4);
570 assert(stream
.bufsize() >= total
);
572 if (!stream
.at_end())
574 printf("Error in Verainit! no of bytes received %i <> expected %i\n",
575 n_bytes
, (int)(total
*sizeof(di_union_t
)));
576 throw Exception("bloed\n");
579 assert(!var_names_buf
);
580 var_names_buf
= (char*) malloc( n_vars
* 128 * sizeof(char));
581 strcpy(var_names_buf
,"");
582 for (unsigned i
=0; i
< n_vars
; i
++)
584 trace1("SOCK::verainit ", var_namen_arr
[i
]);
585 strcat(var_names_buf
, var_namen_arr
[i
].c_str());
586 strcat(var_names_buf
, "\t");
588 //length = static_cast<uint16_t>( strlen(var_names_buf) );
589 // userinfo(1,"vera_titan_ak","Variablennamen %s\n",var_names_buf);
591 /*--------------------------------------------------------------------------*/
594 trace1("SOCK::veraop",n_vars
);
596 _sim
->set_command_dc();
597 assert(stream
.bufsize() >= total
);
599 dc_werteA
= (double*) malloc(sizeof(double)*n_vars
);
600 trace1("fetching ",n_vars
);
601 assert(_sim
->vdc()[0] == 0 );
602 for (unsigned i
=0; i
< n_inputs(); i
++) {
605 trace3("SOCK::veraop setting input", _input_devs
[i
]->long_label(), i
, d
);
606 _input_devs
[i
]->set_value(d
);
609 _error
= 0; /* veraop(sweep_val, x_new, G, C); */
611 // ================do_dc========
613 _sim
->_bypass_ok
= false;
614 _sim
->set_inc_mode_bad();
615 OPT::ITL itl
= OPT::DCBIAS
;
616 _sim
->_phase
= p_INIT_DC
;
618 trace2("SOCK::veraop homotopy", _sim
->_phase
, _sim
->_mode
);
622 CARD_LIST::card_list
.tr_begin(); // hier muesste eigentlich eine dc hin.
623 if(printlist().size()) {
626 bool converged
= false;
628 converged
= solve_with_homotopy(itl
,_trace
);
629 }catch( Exception e
) {
630 ::error(bDANGER
, "hot failed\n");
634 if(!converged
){ itested();
638 ::status
.accept
.start();
640 trace0("SOCK::veraop, accepting");
641 CARD_LIST::card_list
.tr_accept();
642 ::status
.accept
.stop();
644 _sim
->keep_voltages();
646 //========================
648 // Die Variablenwerte stehen schon durch solve_system in var_werte
649 // in dc_sysA und muessen noch nach A kopiert werden:
651 //A->var_werte = x_neu;
654 // A->var_werte = dc_loesungA;
655 // diff_werte, par_werte muessen auch gesetzt sein!
656 // in diesem Falle sind sie per default = 0
660 // A->eval_lin_gl(dc_werteA,&matrixg,&matrixc,&vectorq);
664 /*--------------------------------------------------------------------------*/
665 void SOCK::verakons()
667 // n_eingaenge == #caps?
668 _sim
->set_command_dc();
669 trace1("SOCK::kons", _caplist
.size());
670 _sim
->_time0
= 0; // just assert?
671 _sim
->_dt0
= 0; // just assert?
673 _sim
->_phase
= p_INIT_DC
;
674 total
= n_eingaenge
+ n_vars
+ 1;
676 for (unsigned i
=0; i
< n_inputs(); i
++) {
679 trace3("SOCK::verakons setting input", _input_devs
[i
]->long_label(), i
, d
);
680 _input_devs
[i
]->set_value(d
);
684 for (unsigned i
=1; i
<= n_vars
; i
++) {
685 stream
>> _sim
->_v0
[i
];
686 // trace2("SOCK::kons start ", i, _sim->_v0[i] );
688 if (printlist().size()) { untested();
691 _sim
->keep_voltages(); // v0->vdc
693 _error
= 0; /* verakons(Dwork, x_new, q_dot, G, C); */
694 // n_vars = A->n_var;
696 for( unsigned i
= 0; i
< _caplist
.size(); i
++) {
697 trace1("SOCK::kons",_caplist
[i
]->long_label());
698 _caplist
[i
]->keep_ic(); // latch voltage applied to _v0
699 _caplist
[i
]->set_constant(true);
700 _caplist
[i
]->q_eval(); // so it will be updated
703 //================do_dc========
705 _sim
->_bypass_ok
= false;
706 _sim
->set_inc_mode_bad();
708 OPT::ITL itl
= OPT::DCBIAS
;
710 if(printlist().size()) { untested();
713 CARD_LIST::card_list
.tr_begin();
714 bool converged
= false;
716 converged
= solve(itl
,_trace
);
717 // solve(OPT::TRHIGH,_trace);
718 // solve_with_homotopy(itl,_trace);
719 // homotopy is to much effort calling
720 // procedures must catch problems with convergence.
721 }catch( Exception e
) {
722 ::error(bDANGER
, "hot failed\n");
726 ::error(bWARNING
, "s_sock::verakons: solve did not converge\n");
727 converged
= solve_with_homotopy(itl
,_trace
);
729 ::error(bWARNING
, "s_sock::verakons: solve did not converge even with homotopy\n");
733 ::status
.accept
.start();
735 CARD_LIST::card_list
.tr_accept();
736 ::status
.accept
.stop();
738 // assert(_sim->_mode==s_SOCK);
739 if (printlist().size()) { untested();
740 outdata(_sim
->_time0
);
742 _sim
->_mode
= s_SOCK
; // for now.
744 _sim
->keep_voltages();
745 _sim
->zero_currents();
746 _sim
->set_inc_mode_no();
748 // vera wants just cap stamps
749 for (unsigned i
= 0; i
< _caplist
.size(); i
++) { itested();
750 CARD
* c
= prechecked_cast
<CARD
*>(_caplist
[i
]);
752 trace1("verakons, loading cap", c
->long_label());
753 _sim
->_damp
= 1.; // need raw stamps
757 /*--------------------------------------------------------------------------*/
762 trace1("SOCK::ev_iter", n_vars
);
765 if(!aug
){ untested(); // quick hack!
766 assert(_sim
->_aa
.size()==n_vars
);
767 aug
= new double[n_vars
*2+1];
770 for (unsigned i
=0; i
< 1+2*n_vars
; i
++){ aug
[i
]=i
; }
772 _sim
->_aa
= -(_sim
->_acx
.real());
773 assert(_sim
->_aa
.size()==n_vars
);
774 double tmp
[n_vars
+1];
775 double xiin
[n_vars
+1];
777 for (unsigned i
=0; i
< n_vars
; i
++) {
779 trace1("SOCK::ev_iter got", tmp
[i
]);
785 for (unsigned i
=0; i
< n_vars
; i
++) {
789 aug
[n_vars
*2-i
] = tmp
[i
];
795 aug
[n_vars
] = norm
-1;
797 trace1("SOCK filled xi aa", _sim
->_aa
);
799 const BSMATRIX
<double> C
= _sim
->_acx
.imag();
800 C
.rmul(aug
-1,xiin
-1);
804 for (unsigned i
=0; i
< n_vars
; i
++) {aug
[i
]*=lambda
;}
807 _sim
->_aa
+= lambda
* _sim
->_acx
.imag();
809 trace0("SOCK::ev_iter rmul");
810 _sim
->_aa
.rmul(tmp
-1,xiin
-1);
813 for (unsigned i
=0; i
<= n_vars
; i
++){ untested();
814 trace2("rhs",i
,tmp
[i
]);
817 _sim
->_aa
.augment(aug
);
818 assert(_sim
->_aa
.size()==n_vars
+1);
819 trace1("SOCK augmented aa", _sim
->_aa
);
820 _sim
->_aa
.lu_decomp();
821 trace1("SOCK decomposed aa", _sim
->_aa
);
824 _sim
->_aa
.fbsub(tmp
-1);
825 for (unsigned i
=0; i
<= n_vars
; i
++){
826 trace2("res",i
,tmp
[i
]);
829 trace0("SOCK::ev_iter done");
830 _sim
->_aa
.deaugment();
831 assert(_sim
->_aa
.size()==n_vars
);
832 stream
<< ((uint16_t)_error
); stream
.pad(6);
833 double resnormsq
= 0;
834 for (unsigned i
=0; i
< n_vars
; i
++) { untested();
835 resnormsq
+=tmp
[i
]*tmp
[i
];
836 stream
<< xiin
[i
]-tmp
[i
];
839 resnormsq
+=lambda
*tmp
[n_vars
]*lambda
*tmp
[n_vars
];
840 stream
<< lambda
*(1-tmp
[n_vars
]);
842 resnormsq
+=tmp
[n_vars
]*tmp
[n_vars
];
843 stream
<< lambda
-tmp
[n_vars
];
846 stream
<< SocketStream::eol
;
847 trace0("SOCK::ev_iter sent");
849 /*--------------------------------------------------------------------------*/
850 void SOCK::set_param()
855 PARAM_LIST
* pl
= CARD_LIST::card_list
.params();
856 string paramcommand
= tmp
[0]+"={"+tmp
[1]+"}";
857 trace3("set_param", tmp
[0], tmp
[1], paramcommand
);
858 CS
cmd(CS::_STRING
, paramcommand
);
860 CARD_LIST::card_list
.precalc_first(); // BUG? params don't propagate into sckts otherwise
861 CARD_LIST::card_list
.precalc_last();
863 /*--------------------------------------------------------------------------*/
865 sOK
=0, // ok, returned time step indicates next prefered
866 sNOCONV
=1, // no convergence for second or 3. newton iteration: hope
867 // for success with shorter time step
868 sTRUNC
=2, // Truncation error (time step not accepted (to long!))
869 // restart with shorter returned time step
870 sFIRSTNOCONV
=3, // no convergence for first newton iteration after cons
871 // time step has no meaning, but reduction of time step should
873 sTROUBLE
=99 // exception in solve.
875 /*--------------------------------------------------------------------------*/
876 // init=0 continue with ruse of all old data (do 1 step)
877 // 1 restore op and do ~5 steps (could be used directly after a not accepted
879 // 2 do cons_op followed by do ~5 step (depending on Euler,Gear,
880 // Trapezoid, options)
884 // dt. positive timestep, use instead in next call.
887 unsigned SOCK::transtep(unsigned init
, double dt
)
891 trace3("SOCK::transtep", n_vars
, init
, dt
);
892 _sim
->set_command_tran();
893 _sim
->restore_voltages(); // _vt1[ii] = _v0[ii] = vdc[ii];
895 _sim
->_phase
= p_RESTORE
;
898 double reftime
= _sim
->_time0
;
907 if (init
==0) { itested(); // continue
909 ::error(bDEBUG
, "transient step, at %f, dt %f\n", _sim
->_time0
, dt
);
911 assert(_sim
->_time0
);
912 _sim
->_time0
+= _sim
->_dt0
;
913 // CARD_LIST::card_list.tr_restore();
914 } else if (init
==1) { itested(); // restore
915 assert(_sim
->_time0
> 0);
916 // CARD_LIST::card_list.tr_restore();
918 _sim
->_dt0
= dt
/stepno
;
919 ::error(bDEBUG
, "restore step, dt %e\n", dt
);
920 _sim
->_time0
+= _sim
->_dt0
;
921 } else if (init
==2) {
922 _sim
->_time0
= reftime
= 0;
923 verakons(); // do we need it ?
925 _sim
->_dt0
= dt
/stepno
;
926 ::error(bDEBUG
, "initial step, dt %e\n", dt
);
927 _sim
->_time0
+= _sim
->_dt0
;
928 } else { unreachable();
932 trace2("SOCK::transtep ", _sim
->_phase
, _sim
->_mode
);
934 advance_time(); // sink _time0 into devices
935 _sim
->set_command_tran();
937 if (printlist().size()) {
941 _sim
->_phase
= p_TRAN
;
943 //_sim->_bypass_ok = false;
944 assert(_sim
->_dt0
== dt
/stepno
);
945 //_sim->_genout = gen();
947 assert(_sim
->analysis_is_tran());
951 for (unsigned i
= stepno
; i
>0; --i
) {
952 tr_converged
= false;
954 tr_converged
= solve(OPT::TRHIGH
, _trace
);
955 }catch (Exception e
) { incomplete();
958 if (!tr_converged
) { itested();
959 ::error(bDEBUG
, "s_sock::transtep did not converge\n");
960 if (i
==stepno
) { untested();
972 assert(ret
!=sFIRSTNOCONV
);
973 ::status
.accept
.start(); // accounting
975 CARD_LIST::card_list
.tr_accept(); // accept solution in all components
976 ::status
.accept
.stop();
978 if (printlist().size()) {
979 outdata(_sim
->_time0
);
982 _sim
->_time0
+= _sim
->_dt0
;
986 TIME_PAIR time_by
= CARD_LIST::card_list
.tr_review();
987 double time_by_error_estimate
= time_by
._error_estimate
;
988 assert(time_by_error_estimate
>=0);
990 // if(!tr_converged?) { ... } else
991 if (time_by_error_estimate
> _sim
->_time0
) {
992 dt
= time_by_error_estimate
- _sim
->_time0
;
993 ::status
.accept
.start();
995 CARD_LIST::card_list
.tr_accept();
996 ::status
.accept
.stop();
997 _sim
->keep_voltages(); // vdc = v0
1000 double t1
= _sim
->_time0
- _sim
->_dt0
;
1001 dt
= time_by_error_estimate
- t1
;
1003 ::error(bTRACE
,"sock step not accepted at %f, need %f\n", reftime
, dt
);
1005 assert (dt
>0); // hopefully.
1006 assert (dt
< _sim
->_dt0
); // hopefully.
1007 dt
*= stepno
; // stepno is valid for next step.
1008 _sim
->_time0
= reftime
;
1013 for (unsigned i
=1; i
<= n_vars
; i
++) {
1014 if(isnan(_sim
->_i
[i
])||isnan(_sim
->_vdcstack
.top()[i
]) ) {
1016 assert(!tr_converged
);
1022 return ret
; // FIXME: proper status.
1024 /*--------------------------------------------------------------------------*/
1025 void SOCK::tr_reject()
1027 ::status
.accept
.start();
1028 _sim
->_acceptq
.clear();
1029 ++tr_steps_rejected_
;
1030 ::status
.accept
.stop();
1032 /*--------------------------------------------------------------------------*/
1033 void SOCK::verakons_reply()
1035 stream
<< ((uint16_t)_error
); stream
.pad(6);
1036 for (unsigned i
=1; i
<= n_vars
; i
++) {
1037 trace1("SOCK::kons_reply", _sim
->vdc()[i
]);
1038 stream
<< _sim
->vdc()[i
];
1042 // now i contains the negative sum of the cap value.
1043 // does this break anything?
1045 for (unsigned i
=1; i
<= n_vars
; i
++) /* Q-Punkt == I == RS */
1047 trace1("SOCK::verakons_reply dqdt", _sim
->_i
[i
]);
1048 stream
<< _sim
->_i
[i
];
1052 _out
<< "u,dq=i: \n";
1053 for (unsigned i
=0; i
<= n_vars
; i
++) /* Variablen-Werte */
1055 _out
<< _sim
->vdc()[i
] << "," << _sim
->_i
[i
] << "\n" ;
1059 trace0("SOCK::verakons_reply ac_snap");
1060 ac_snapshot(); // FIXME: to verakons()
1064 assert(stream
.bufsize() >= total
);
1065 stream
<< SocketStream::eol
;
1067 // for( unsigned i = 0; i < _caplist.size(); i++)
1069 // trace1("unlatching", i);
1071 // dashier umgekehrt.
1072 // commonstash[i] = _caplist[i]->common();
1073 // detach(_caplist[i]);
1075 // COMMON_COMPONENT* c = bm_dispatcher.clone("eval_bm_value");
1076 // COMMON_COMPONENT* dc = c->deflate();
1078 // _caplist[i]->attach_common(dc);
1080 // _caplist[i]->keep_ic(); // latch voltage applied to _v0
1087 void SOCK::transtep_reply(unsigned ret
, bool eol
)
1090 stream
<< _error
; stream
.pad(6);
1091 stream
<< (uint64_t)ret
;
1094 for (unsigned i
=1; i
<= n_vars
; i
++) {
1095 stream
<< _sim
->_vdcstack
.top()[i
];
1098 // OUCH, move to main loop.
1100 stream
<< SocketStream::eol
;
1104 void SOCK::transtep_gc_reply(unsigned ret
)
1106 transtep_reply(ret
, false);
1108 for (unsigned i
=1; i
<= n_vars
; i
++)
1110 trace1("SOCK::transtep_gc_reply dqdt", _sim
->_i
[i
]);
1111 stream
<< _sim
->_i
[i
];
1114 trace0("SOCK::transtep_gc_reply ac_snap");
1115 ac_snapshot(); // BUG: calls tr_begin
1117 assert(stream
.bufsize() >= total
);
1118 stream
<< SocketStream::eol
;
1120 /*--------------------------------------------------------------------------*/
1121 void SOCK::verainit_reply()
1123 trace4("SOCK::verainit_reply ", _error
, n_vars
, length
, var_namen_total_size
);
1124 stream
<< _error
; stream
.pad(6);
1125 stream
<< int32_t (n_vars
); stream
.pad(4);
1126 stream
<< int32_t (var_namen_total_size
); stream
.pad(4);
1128 assert(stream
.tcur() == 24);
1130 for (unsigned i
= 0; i
< n_vars
; i
++) {
1131 trace2("SOCK::verainit_reply", i
, var_namen_arr
[i
]);
1132 putstring8( &stream
, var_namen_arr
[i
]);
1133 stream
<< '\t'; stream
.pad(7);
1136 //good idea?? not yet. vera insists on branch node
1138 // for (unsigned i=0; i < n_inputs; i++)
1140 // trace1("putting name " + input_names[i], i);
1141 // putstring8( &stream, input_names[i]);
1142 // stream << '\t'; stream.pad(7);
1146 trace0("done verainit_reply");
1148 /*--------------------------------------------------------------------------*/
1149 void SOCK::veraop_reply()
1151 assert(n_vars
==_sim
->_total_nodes
);
1152 trace1("SOCK::veraop_reply ", n_vars
);
1153 stream
<< _error
; stream
.pad(6);
1154 for (unsigned i
=1; i
<= n_vars
; i
++) /* Variablen-Werte */
1156 stream
<< _sim
->vdc()[i
];
1160 for (unsigned i
=0; i
<= n_vars
; i
++) /* Variablen-Werte */
1162 _out
<< _sim
->_i
[i
] << "," << _sim
->vdc()[i
] << "\n" ;
1166 trace0("SOCK::veraop_reply taking ac snapshot (matrix only?).");
1169 stream
<< SocketStream::eol
;
1171 trace0("SOCK::veraop_reply sent");
1173 total
= 2*n_vars_square
+n_vars
+1;
1174 assert(stream
.bufsize() >= total
);
1175 if (printlevel
>= 1)
1177 userinfo(1,"vera_titan_ak","Sende: Error %i Framenumber %i, Laenge %i\n",
1178 _error
,frame_number
,total
);
1181 /*--------------------------------------------------------------------------*/
1182 /*--------------------------------------------------------------------------*/
1183 void SOCK::send_matrix()
1185 const BSMATRIX
<double> G
= _sim
->_acx
.real();
1186 const BSMATRIX
<double> C
= _sim
->_acx
.imag();
1188 _out
<< "G\n" << G
<< "\n";
1189 _out
<< "C\n" << C
<< "\n";
1191 trace0("SOCK::send_matrix G");
1192 for (unsigned i
=1; i
<= n_vars
; i
++){
1193 for (unsigned j
=1; j
<= n_vars
; j
++) {
1197 trace0("SOCK::send_matrix C");
1198 for (unsigned i
=1; i
<= n_vars
; i
++){
1199 for (unsigned j
=1; j
<= n_vars
; j
++) {
1204 /*--------------------------------------------------------------------------*/
1205 void SOCK::cap_prepare(void)
1207 trace1("SOCK::cap_prepare", _caplist
.size() );
1209 _capstash
= new CARDSTASH
[_caplist
.size()];
1211 for (unsigned ii
= 0; ii
< _caplist
.size(); ++ii
) { untested();
1212 _caplist
[ii
]->inc_probes(); // we need to keep track of it
1213 _capstash
[ii
] = _caplist
[ii
]; // stash the std value
1215 if(_caplist
[ii
]->has_common()){ untested();
1216 trace1("SOCK::cap_prepare. have common", _caplist
[ii
]->value());
1217 // _caplist[ii]->set_value(_caplist[ii]->value(), 0); // zap out extensions
1218 // _caplist[ii]->set_constant(false); // update HACK?
1220 // all devices need individual commons.
1221 _caplist
[ii
]->attach_common(_caplist
[ii
]->common()->clone());
1222 assert(_caplist
[ii
]->has_common());
1224 // _sweepval[ii] = _zap[ii]->set__value(); // point to value to patch
1225 COMMON_COMPONENT
* c
= bm_dispatcher
.clone("eval_bm_value");
1226 double capval
= _caplist
[ii
]->value();
1227 trace2("SOCK::cap_prepare, attaching common", _caplist
[ii
]->long_label(), capval
);
1228 c
->set_value(capval
);
1229 COMMON_COMPONENT
* dc
= c
->deflate();
1232 _caplist
[ii
]->set_value(_caplist
[ii
]->value(), dc
); // zap out extensions
1233 _caplist
[ii
]->set_constant(false); // so it will be updated
1234 trace1("SOCK::cap_prepare calling precalc_first", _caplist
[ii
]->long_label());
1235 _caplist
[ii
]->precalc_first();
1236 trace0("SOCK::cap_prepare calling precalc_last");
1237 _caplist
[ii
]->precalc_last();
1238 trace0("SOCK::cap_prepare calling trbegin");
1239 _caplist
[ii
]->tr_begin();
1243 /*--------------------------------------------------------------------------*/
1244 void SOCK::cap_reset(void)
1246 trace0("SOCK::cap_reset");
1247 for (unsigned ii
= 0; ii
< _caplist
.size(); ++ii
) {
1248 _capstash
[ii
].restore();
1249 _caplist
[ii
]->dec_probes();
1250 // _caplist[ii]->precalc_first();
1251 // _caplist[ii]->precalc_last();
1255 trace0("SOCK::cap_reset done");
1257 /*--------------------------------------------------------------------------*/
1260 trace0("SOCK::~SOCK()");
1262 /*--------------------------------------------------------------------------*/
1263 // vim:ts=8:sw=2:noet: