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)
152 struct sockaddr_in sin
;
154 double *matrixg
, *matrixc
,*vectorq
;
156 static const int printlevel
=0;
159 /*--------------------------------------------------------------------------*/
160 unsigned SOCK::tr_steps_rejected_
= 0;
161 double SOCK::temp_c_in
= 0.;
162 /*--------------------------------------------------------------------------*/
163 void SOCK::do_it(CS
& Cmd
, CARD_LIST
* Scope
)
165 trace0("SOCK::do_it");
166 IO::error
.detach(stdout
);
167 IO::error
.attach(stderr
);
170 //_sim->set_command_ddc();
171 _sim
->set_command_dc();
172 _sim
->_phase
= p_INIT_DC
;
174 ::status
.ddc
.reset().start();
175 _sim
->_temp_c
= temp_c_in
;
180 _client_mode
= false;
188 /*--------------------------------------------------------------------------*/
189 SOCK::SOCK() :DDC_BASE(),
195 for (int ii
= 0; ii
< DCNEST
; ++ii
) {
197 _reverse_in
[ii
] = false;
198 _reverse
[ii
] = false;
202 _stepmode
[ii
] = ONE_PT
;
204 temp_c_in
=OPT::temp_c
;
207 /*--------------------------------------------------------------------------*/
208 void SOCK::setup(CS
& Cmd
)
211 trace0("SOCK::setup");
215 _out
.reset(); //BUG// don't know why this is needed */
216 bool ploton
= IO::plotset
&& plotlist().size() > 0;
223 Cmd
.check(bWARNING
, "what's this?");
226 CKT_BASE::_sim
->init();
228 IO::plotout
= (ploton
) ? IO::mstdout
: OMSTREAM();
231 _error
= 0; /* verainit(v_flag, n_inputs, &n_vars, charbuf, &length); */
232 n_vars
= static_cast<uint16_t>( _sim
->_total_nodes
) ; // _sim->total_nodes doesnt include gnd
233 // do this also in sweep to initialize the socket streaM
234 var_namen_arr
.resize( n_vars
, string("unset"));
235 // var_namen_arr[0]="0";
236 fillnames( &CARD_LIST::card_list
);
237 n_vars_square
= n_vars
* n_vars
;
239 findcaps(&CARD_LIST::card_list
);
241 // BUG! this kills cap bm's
242 cap_prepare(); // attach value common if !has_common. stash old common
245 for (unsigned i
=0; i
< n_vars
; i
++)
246 trace0("name: " + var_namen_arr
[i
]);
249 assert(_n_sweeps
> 0);
252 // not implemented. need to queue sources properly (CARDLIST::q_hack..?)
253 if(OPT::prequeue
) { // incomplete();
254 error(bDANGER
, "prequeueing is experimental, this might not work\n");
259 /*--------------------------------------------------------------------------*/
260 void SOCK::options(CS
& Cmd
, int Nest
)
262 trace0("SOCK::options... ");
264 _sim
->_uic
= _loop
[Nest
] = _reverse_in
[Nest
] = false;
269 unsigned here
= Cmd
.cursor();
272 || (Cmd
.match1("'\"({") && ((Cmd
>> _step_in
[Nest
]), (_stepmode
[Nest
] = LIN_STEP
)))
273 || (Cmd
.is_float() && ((Cmd
>> _step_in
[Nest
]), (_stepmode
[Nest
] = LIN_STEP
)))
274 || (Get(Cmd
, "*", &_step_in
[Nest
]) && (_stepmode
[Nest
] = TIMES
))
275 || (Get(Cmd
, "+", &_step_in
[Nest
]) && (_stepmode
[Nest
] = LIN_STEP
))
276 || Get(Cmd
, "b{ufsize}", &_bufsize
)
277 || Get(Cmd
, "c{ontinue}", &_cont
)
278 || Get(Cmd
, "port" , &_port
)
279 || Get(Cmd
, "listen{port}", &_port
)
280 || Get(Cmd
, "bigarg", &_bigarg
)
281 || Get(Cmd
, "binout", &_binout
)
282 || Get(Cmd
, "host" , &_host
)
283 || Get(Cmd
, "tr{s}", &_do_tran_step
)
284 || Get(Cmd
, "dm", &_dump_matrix
)
285 || Get(Cmd
, "client", &_client_mode
)
286 || Get(Cmd
, "server", &_server_mode
)
287 || Get(Cmd
, "dt{emp}", &temp_c_in
, mOFFSET
, OPT::temp_c
)
288 || Get(Cmd
, "lo{op}", &_loop
[Nest
])
289 || Get(Cmd
, "re{verse}", &_reverse_in
[Nest
])
290 || Get(Cmd
, "te{mperature}",&temp_c_in
)
291 || (Cmd
.umatch("tr{ace} {=}") &&
293 || Set(Cmd
, "n{one}", &_trace
, tNONE
)
294 || Set(Cmd
, "o{ff}", &_trace
, tNONE
)
295 || Set(Cmd
, "w{arnings}", &_trace
, tUNDER
)
296 || Set(Cmd
, "i{terations}",&_trace
, tITERATION
)
297 || Set(Cmd
, "v{erbose}", &_trace
, tVERBOSE
)
298 || Cmd
.warn(bWARNING
,
299 "need none, off, warnings, iterations, verbose")
303 }while (Cmd
.more() && !Cmd
.stuck(&here
));
305 /*--------------------------------------------------------------------------*/
306 static void register_status();
307 /*--------------------------------------------------------------------------*/
315 trace1("SOCK::do_it", _port
);
317 // Calculate buffersize
318 n_vars
= _sim
->_total_nodes
;
319 // _sim->total_nodes doesnt include gnd
320 n_vars_square
= n_vars
* n_vars
;
321 _bufsize
= n_vars_square
* 3 * (unsigned)sizeof(double) + 32;
322 // 3 quadratic matrices * doubles + some safety margin (BUG)
325 trace1("bufsize Client ", _bufsize
);
326 socket
= new ClientSocket(Socket::TCP
, _port
, _host
, _bufsize
);
327 trace1("connected to "+ _host
, _port
);
329 } else if (_server_mode
) {
330 stringstream
p(_port
);
333 trace1("bufsize Server ", _bufsize
);
334 socket
= new ServerSocket(Socket::TCP
, _port_
, 1u, _bufsize
);
335 ServerSocket
* sock
=prechecked_cast
<ServerSocket
*>(socket
);
337 trace0("SOCK::do_it waiting");
338 stream
= sock
->listen();
342 trace0("SOCK::sweep simple i/o");
344 trace1("bufsize Stdin ", _bufsize
);
346 int devnull
=open("/dev/null",O_WRONLY
);
347 trace2("Socket stream for dev null" ,devnull
, STDIN_FILENO
);
348 stream
= SocketStream( devnull
, STDIN_FILENO
, _bufsize
);
350 stream
= SocketStream( STDOUT_FILENO
, STDIN_FILENO
, _bufsize
);
352 stream
<< "gnucap sock ready";
359 /*--------------------------------------------------------------------------*/
360 string
SOCK::status()const
363 return "sock: tr rejected=" + ::to_string(tr_steps_rejected_
) + "\n";
365 /*--------------------------------------------------------------------------*/
366 // void SOCK::sweep_recursive(int )
370 /*--------------------------------------------------------------------------*/
371 // fetch names from circuit recursively. fill into local vector.
372 void SOCK::fillnames( const CARD_LIST
* scope
){
373 trace0("SOCK::fillnames");
375 const NODE_MAP
* nm
= scope
->nodes();
376 for (NODE_MAP::const_iterator i
= nm
->begin(); i
!= nm
->end(); ++i
) {
377 if (i
->first
!= "0") {
378 if (const NODE
* a
= dynamic_cast<const NODE
*>(i
->second
)){
380 string
myname(a
->long_label());
381 var_namen_arr
[a
->matrix_number()-1] = myname
;
382 var_namen_total_size
= static_cast<uint16_t>( var_namen_total_size
+ static_cast<uint16_t>(myname
.length()) + 1 );
388 for (CARD_LIST::const_iterator i
= scope
->begin(); i
!= scope
->end(); ++i
) {
389 if(const COMPONENT
* s
= dynamic_cast<const COMPONENT
*>(*i
)){
390 if (!s
->is_device()){
391 }else if ( s
->subckt() ) {
392 fillnames( s
->subckt() );
398 /*--------------------------------------------------------------------------*/
399 void SOCK::findcaps( CARD_LIST
* scope
){
400 for (CARD_LIST::iterator i
= scope
->begin(); i
!= scope
->end(); ++i
) {
401 if ( COMPONENT
* c
= dynamic_cast< COMPONENT
*>(*i
) ) {
402 if (c
->is_device() && c
->has_memory()){
403 trace1("found cap", c
->long_label());
404 _caplist
.push_back( c
);
407 if (!(*i
)->is_device()){
408 } else if ( BASE_SUBCKT
* s
= dynamic_cast< BASE_SUBCKT
*>(*i
) ) {
409 trace1("going down", s
->long_label());
410 findcaps( s
->subckt() );
414 /*--------------------------------------------------------------------------*/
416 static DISPATCHER
<CMD
>::INSTALL
d2(&command_dispatcher
, "sock", &p2
);
417 /*--------------------------------------------------------------------------*/
418 static void register_status()
423 new DISPATCHER
<CKT_BASE
>::INSTALL(&status_dispatcher
, "sock", &p2
);
428 /*--------------------------------------------------------------------------*/
430 /*--------------------------------------------------------------------------*/
431 static unsigned argc(unsigned opcode
)
447 /*--------------------------------------------------------------------------*/
448 void SOCK::main_loop()
450 trace0("SOCK::main_loop");
456 bool init_done
=false;
459 trace0("SOCK::main_loop waiting for opcode");
462 stream
>> tmp
>> 7; // sic!
464 for(unsigned i
=0; i
<argc(opcode
); ++i
){
465 stream
>> arg
[i
] >> 6;
474 _sim
->_mode
= s_SOCK
; // nonsense.
475 // use respective built-in mode!
478 ::error(bDEBUG
, "sock opcode %d\n", opcode
);
480 ::error(bDEBUG
, "sock opcode %d %d %d %d\n", opcode
, arg
[0], arg
[1], arg
[2]);
490 if(init_done
) throw Exception("init twice??");
491 verainit(arg
[0], arg
[1], arg
[2]);
503 case 101: untested();
508 status
= transtep(arg
[0], dt
);
509 transtep_reply(status
);
516 status
= transtep(arg
[0], dt
);
517 transtep_gc_reply(status
);
520 ::error(bDANGER
, "unknown opcode %i\n", opcode
);
521 throw Exception("unknown opcode");
524 _sim
->reset_iteration_counter(iPRINTSTEP
); // used by solve_with_homotopy
525 // reset in outdata (not called)
528 /*--------------------------------------------------------------------------*/
529 // very clever way to transfer strings.
530 static void putstring8(SocketStream
* s
, const string x
)
532 const char* A
= x
.c_str();
535 *s
<<*A
<<*A
<<*A
<<*A
<<*A
<<*A
<<*A
<<*A
;
539 /*--------------------------------------------------------------------------*/
540 void SOCK::verainit(unsigned verbose
, unsigned n_in
, unsigned length
)
543 char input_namen
[length
+1];
547 _input_names
.resize(n_in
);
548 _input_devs
.resize(n_in
);
549 trace3("verainit: ", verbose
,n_inputs(),length
);
550 assert(n_inputs()==n_in
);
552 for (unsigned i
=0; i
< length
; i
++) {
553 stream
>> input_namen
[i
] >> 7;
554 if(input_namen
[i
] == '\t'){
556 trace1("input_namen", string(input_namen
+here
));
557 trace5("input_namen",input_namen
[i
-2],input_namen
[i
-1], input_namen
[i
-0],here
,i
);
558 _input_names
[n
] = string(input_namen
+here
);
561 trace1("looking out for", _input_names
[n
]);
562 CARD_LIST::fat_iterator ci
= findbranch(_input_names
[n
], &CARD_LIST::card_list
);
564 throw Exception("cannot find voltage source \"" + _input_names
[n
] +"\", giving up");
566 trace0("found input device");
567 ELEMENT
* d
= prechecked_cast
<ELEMENT
*>(*ci
);
569 throw Exception("not something we can use as source, \"" + _input_names
[n
] +"\", giving up");
572 assert(_input_devs
[n
]);
575 // see s_cd. FIXME: revert.
576 _stash
[ii
] = _input_devs
[ii
];
577 _input_devs
[ii
]->inc_probes();
578 _input_devs
[ii
]->set_value(_input_devs
[ii
]->value(),0);
579 _input_devs
[ii
]->set_constant(false); // <= insufficient for PREQEUE
585 //trace0("input_namen " + string(input_namen) );
586 total
= (unsigned) (length
+4);
587 assert(stream
.bufsize() >= total
);
589 assert(!var_names_buf
);
590 var_names_buf
= (char*) malloc( n_vars
* 128 * sizeof(char));
591 strcpy(var_names_buf
,"");
592 for (unsigned i
=0; i
< n_vars
; i
++)
594 trace1("SOCK::verainit ", var_namen_arr
[i
]);
595 strcat(var_names_buf
, var_namen_arr
[i
].c_str());
596 strcat(var_names_buf
, "\t");
598 //length = static_cast<uint16_t>( strlen(var_names_buf) );
599 // userinfo(1,"vera_titan_ak","Variablennamen %s\n",var_names_buf);
601 /*--------------------------------------------------------------------------*/
604 trace1("SOCK::veraop",n_vars
);
606 _sim
->set_command_dc();
607 assert(stream
.bufsize() >= total
);
609 dc_werteA
= (double*) malloc(sizeof(double)*n_vars
);
610 trace1("fetching ",n_vars
);
611 assert(_sim
->vdc()[0] == 0 );
612 for (unsigned i
=0; i
< n_inputs(); i
++) {
615 trace3("SOCK::veraop setting input", _input_devs
[i
]->long_label(), i
, d
);
616 _input_devs
[i
]->set_value(d
);
619 _error
= 0; /* veraop(sweep_val, x_new, G, C); */
621 // ================do_dc========
623 _sim
->_bypass_ok
= false;
624 _sim
->set_inc_mode_bad();
625 OPT::ITL itl
= OPT::DCBIAS
;
626 _sim
->_phase
= p_INIT_DC
;
628 trace2("SOCK::veraop homotopy", _sim
->_phase
, _sim
->_mode
);
632 CARD_LIST::card_list
.tr_begin(); // hier muesste eigentlich eine dc hin.
633 if(printlist().size()) {
636 bool converged
= false;
638 converged
= solve_with_homotopy(itl
,_trace
);
639 }catch( Exception e
) {
640 ::error(bDANGER
, "hot failed\n");
644 if(!converged
){ itested();
648 ::status
.accept
.start();
650 trace0("SOCK::veraop, accepting");
651 CARD_LIST::card_list
.tr_accept();
652 ::status
.accept
.stop();
654 _sim
->keep_voltages();
656 //========================
658 // Die Variablenwerte stehen schon durch solve_system in var_werte
659 // in dc_sysA und muessen noch nach A kopiert werden:
661 //A->var_werte = x_neu;
664 // A->var_werte = dc_loesungA;
665 // diff_werte, par_werte muessen auch gesetzt sein!
666 // in diesem Falle sind sie per default = 0
670 // A->eval_lin_gl(dc_werteA,&matrixg,&matrixc,&vectorq);
674 /*--------------------------------------------------------------------------*/
675 void SOCK::verakons()
677 // n_eingaenge == #caps?
678 _sim
->set_command_dc();
679 trace1("SOCK::kons", _caplist
.size());
680 _sim
->_time0
= 0; // just assert?
681 _sim
->_dt0
= 0; // just assert?
683 _sim
->_phase
= p_INIT_DC
;
684 total
= n_eingaenge
+ n_vars
+ 1;
686 for (unsigned i
=0; i
< n_inputs(); i
++) {
689 trace3("SOCK::verakons setting input", _input_devs
[i
]->long_label(), i
, d
);
690 _input_devs
[i
]->set_value(d
);
694 for (unsigned i
=1; i
<= n_vars
; i
++) {
695 stream
>> _sim
->_v0
[i
];
696 // trace2("SOCK::kons start ", i, _sim->_v0[i] );
698 if (printlist().size()) {
701 _sim
->keep_voltages(); // v0->vdc
703 _error
= 0; /* verakons(Dwork, x_new, q_dot, G, C); */
704 // n_vars = A->n_var;
706 for( unsigned i
= 0; i
< _caplist
.size(); i
++) {
707 trace1("SOCK::kons",_caplist
[i
]->long_label());
708 _caplist
[i
]->keep_ic(); // latch voltage applied to _v0
709 _caplist
[i
]->set_constant(true); // maybe not a good idea at all.
710 _caplist
[i
]->q_eval(); // so it will be updated
713 //================do_dc========
715 _sim
->_bypass_ok
= false;
716 _sim
->set_inc_mode_bad();
718 OPT::ITL itl
= OPT::DCBIAS
;
720 if(printlist().size()) {
723 CARD_LIST::card_list
.tr_begin();
724 bool converged
= false;
726 for( unsigned i
= 0; i
< _caplist
.size(); i
++) {
727 trace1("SOCK::kons",_caplist
[i
]->long_label());
728 // assert(!_caplist[i]->is_constant()); // NO caps are const, when they are in VS mode.
729 _caplist
[i
]->do_tr(); // so it will be updated. is this sufficient?
730 // is it sufficient to only queue caps?
732 converged
= solve(itl
,_trace
);
733 // solve(OPT::TRHIGH,_trace);
734 // solve_with_homotopy(itl,_trace);
735 // homotopy is to much effort calling
736 // procedures must catch problems with convergence.
737 }catch( Exception e
) {
738 ::error(bDANGER
, "hot failed\n");
742 ::error(bWARNING
, "s_sock::verakons: solve did not converge\n");
743 converged
= solve_with_homotopy(itl
,_trace
);
745 ::error(bWARNING
, "s_sock::verakons: solve did not converge even with homotopy\n");
749 ::status
.accept
.start();
751 CARD_LIST::card_list
.tr_accept();
752 ::status
.accept
.stop();
754 // assert(_sim->_mode==s_SOCK);
755 if (printlist().size()) {
756 outdata(_sim
->_time0
);
758 _sim
->_mode
= s_SOCK
; // for now.
760 _sim
->keep_voltages();
761 _sim
->zero_currents();
762 _sim
->set_inc_mode_no();
764 // vera wants just cap stamps
765 for (unsigned i
= 0; i
< _caplist
.size(); i
++) { itested();
766 CARD
* c
= prechecked_cast
<CARD
*>(_caplist
[i
]);
768 trace1("verakons, loading cap", c
->long_label());
769 _sim
->_damp
= 1.; // need raw stamps
773 for( unsigned i
= 0; i
< _caplist
.size(); i
++) {
774 /// oops. maybe the next command is tran?!
775 // (this is a hack!!)
776 _caplist
[i
]->set_constant(false);
779 /*--------------------------------------------------------------------------*/
784 trace1("SOCK::ev_iter", n_vars
);
787 if(!aug
){ untested(); // quick hack!
788 assert(_sim
->_aa
.size()==n_vars
);
789 aug
= new double[n_vars
*2+1];
792 for (unsigned i
=0; i
< 1+2*n_vars
; i
++){ aug
[i
]=i
; }
794 _sim
->_aa
= -(_sim
->_acx
.real());
795 assert(_sim
->_aa
.size()==n_vars
);
796 double tmp
[n_vars
+1];
797 double xiin
[n_vars
+1];
799 for (unsigned i
=0; i
< n_vars
; i
++) {
801 trace1("SOCK::ev_iter got", tmp
[i
]);
807 for (unsigned i
=0; i
< n_vars
; i
++) {
811 aug
[n_vars
*2-i
] = tmp
[i
];
817 aug
[n_vars
] = norm
-1;
819 trace1("SOCK filled xi aa", _sim
->_aa
);
821 const BSMATRIX
<double> C
= _sim
->_acx
.imag();
822 C
.rmul(aug
-1,xiin
-1);
826 for (unsigned i
=0; i
< n_vars
; i
++) {aug
[i
]*=lambda
;}
829 _sim
->_aa
+= lambda
* _sim
->_acx
.imag();
831 trace0("SOCK::ev_iter rmul");
832 _sim
->_aa
.rmul(tmp
-1,xiin
-1);
835 for (unsigned i
=0; i
<= n_vars
; i
++){ untested();
836 trace2("rhs",i
,tmp
[i
]);
839 _sim
->_aa
.augment(aug
);
840 assert(_sim
->_aa
.size()==n_vars
+1);
841 trace1("SOCK augmented aa", _sim
->_aa
);
842 _sim
->_aa
.lu_decomp();
843 trace1("SOCK decomposed aa", _sim
->_aa
);
846 _sim
->_aa
.fbsub(tmp
-1);
847 for (unsigned i
=0; i
<= n_vars
; i
++){
848 trace2("res",i
,tmp
[i
]);
851 trace0("SOCK::ev_iter done");
852 _sim
->_aa
.deaugment();
853 assert(_sim
->_aa
.size()==n_vars
);
854 stream
<< ((uint16_t)_error
); stream
.pad(6);
855 double resnormsq
= 0;
856 for (unsigned i
=0; i
< n_vars
; i
++) { untested();
857 resnormsq
+=tmp
[i
]*tmp
[i
];
858 stream
<< xiin
[i
]-tmp
[i
];
861 resnormsq
+=lambda
*tmp
[n_vars
]*lambda
*tmp
[n_vars
];
862 stream
<< lambda
*(1-tmp
[n_vars
]);
864 resnormsq
+=tmp
[n_vars
]*tmp
[n_vars
];
865 stream
<< lambda
-tmp
[n_vars
];
868 stream
<< SocketStream::eol
;
869 trace0("SOCK::ev_iter sent");
871 /*--------------------------------------------------------------------------*/
872 void SOCK::set_param()
877 PARAM_LIST
* pl
= CARD_LIST::card_list
.params();
878 string paramcommand
= tmp
[0]+"={"+tmp
[1]+"}";
879 trace3("set_param", tmp
[0], tmp
[1], paramcommand
);
880 CS
cmd(CS::_STRING
, paramcommand
);
882 CARD_LIST::card_list
.precalc_first(); // BUG? params don't propagate into sckts otherwise
883 CARD_LIST::card_list
.precalc_last();
885 /*--------------------------------------------------------------------------*/
887 sOK
=0, // ok, returned time step indicates next prefered
888 sNOCONV
=1, // no convergence for second or 3. newton iteration: hope
889 // for success with shorter time step
890 sTRUNC
=2, // Truncation error (time step not accepted (to long!))
891 // restart with shorter returned time step
892 sFIRSTNOCONV
=3, // no convergence for first newton iteration after cons
893 // time step has no meaning, but reduction of time step should
895 sTROUBLE
=99 // exception in solve.
897 /*--------------------------------------------------------------------------*/
898 // init=0 continue with ruse of all old data (do 1 step)
899 // 1 restore op and do ~5 steps (could be used directly after a not accepted
901 // 2 do cons_op followed by do ~5 step (depending on Euler,Gear,
902 // Trapezoid, options)
906 // dt. positive timestep, use instead in next call.
909 unsigned SOCK::transtep(unsigned init
, double dt
)
913 trace3("SOCK::transtep", n_vars
, init
, dt
);
914 _sim
->set_command_tran();
915 _sim
->restore_voltages(); // _vt1[ii] = _v0[ii] = vdc[ii];
917 _sim
->_phase
= p_RESTORE
;
920 double reftime
= _sim
->_time0
;
929 if (init
==0) { itested(); // continue
931 ::error(bDEBUG
, "transient step, at %f, dt %f\n", _sim
->_time0
, dt
);
933 assert(_sim
->_time0
);
934 _sim
->_time0
+= _sim
->_dt0
;
935 // CARD_LIST::card_list.tr_restore();
936 } else if (init
==1) { itested(); // restore
937 assert(_sim
->_time0
> 0);
938 // CARD_LIST::card_list.tr_restore();
940 _sim
->_dt0
= dt
/stepno
;
941 ::error(bDEBUG
, "restore step, dt %e\n", dt
);
942 _sim
->_time0
+= _sim
->_dt0
;
943 } else if (init
==2) {
944 _sim
->_time0
= reftime
= 0;
945 verakons(); // do we need it ?
947 _sim
->_dt0
= dt
/stepno
;
948 ::error(bDEBUG
, "initial step, dt %e\n", dt
);
949 _sim
->_time0
+= _sim
->_dt0
;
950 } else { unreachable();
954 trace2("SOCK::transtep ", _sim
->_phase
, _sim
->_mode
);
956 advance_time(); // sink _time0 into devices
957 _sim
->set_command_tran();
959 if (printlist().size()) {
963 _sim
->_phase
= p_TRAN
;
965 //_sim->_bypass_ok = false;
966 assert(_sim
->_dt0
== dt
/stepno
);
967 //_sim->_genout = gen();
969 assert(_sim
->analysis_is_tran());
971 // this is too expensive here.
972 // CARD_LIST::card_list.do_tr();
975 for (unsigned i
= stepno
; i
>0; --i
) {
976 tr_converged
= false;
978 for( unsigned i
= 0; i
< _caplist
.size(); i
++) { itested();
979 trace1("SOCK::kons",_caplist
[i
]->long_label());
980 assert(!_caplist
[i
]->is_constant());
981 _caplist
[i
]->q_eval(); // so it will be updated. is this sufficient?
982 // is it sufficient to only queue caps?
984 tr_converged
= solve(OPT::TRHIGH
, _trace
);
985 }catch (Exception e
) { incomplete();
988 if (!tr_converged
) { itested();
989 ::error(bDEBUG
, "s_sock::transtep did not converge\n");
990 if (i
==stepno
) { untested();
1002 assert(ret
!=sFIRSTNOCONV
);
1003 ::status
.accept
.start(); // accounting
1005 CARD_LIST::card_list
.tr_accept(); // accept solution in all components
1006 ::status
.accept
.stop();
1008 if (printlist().size()) {
1009 outdata(_sim
->_time0
);
1012 _sim
->_time0
+= _sim
->_dt0
;
1016 TIME_PAIR time_by
= CARD_LIST::card_list
.tr_review();
1017 double time_by_error_estimate
= time_by
._error_estimate
;
1018 assert(time_by_error_estimate
>=0);
1020 // if(!tr_converged?) { ... } else
1021 if (time_by_error_estimate
> _sim
->_time0
) {
1022 dt
= time_by_error_estimate
- _sim
->_time0
;
1023 ::status
.accept
.start();
1025 CARD_LIST::card_list
.tr_accept();
1026 ::status
.accept
.stop();
1027 _sim
->keep_voltages(); // vdc = v0
1030 double t1
= _sim
->_time0
- _sim
->_dt0
;
1031 dt
= time_by_error_estimate
- t1
;
1033 ::error(bTRACE
,"sock step not accepted at %f, need %f\n", reftime
, dt
);
1035 assert (dt
>0); // hopefully.
1036 assert (dt
< _sim
->_dt0
); // hopefully.
1037 dt
*= stepno
; // stepno is valid for next step.
1038 _sim
->_time0
= reftime
;
1043 for (unsigned i
=1; i
<= n_vars
; i
++) {
1044 if(isnan(_sim
->_i
[i
])||isnan(_sim
->_vdcstack
.top()[i
]) ) {
1046 assert(!tr_converged
);
1052 return ret
; // FIXME: proper status.
1054 /*--------------------------------------------------------------------------*/
1055 void SOCK::tr_reject()
1057 ::status
.accept
.start();
1058 _sim
->_acceptq
.clear();
1059 ++tr_steps_rejected_
;
1060 ::status
.accept
.stop();
1062 /*--------------------------------------------------------------------------*/
1063 void SOCK::verakons_reply()
1065 stream
<< ((uint16_t)_error
); stream
.pad(6);
1066 for (unsigned i
=1; i
<= n_vars
; i
++) {
1067 trace1("SOCK::kons_reply", _sim
->vdc()[i
]);
1068 stream
<< _sim
->vdc()[i
];
1072 // now i contains the negative sum of the cap value.
1073 // does this break anything?
1075 for (unsigned i
=1; i
<= n_vars
; i
++) /* Q-Punkt == I == RS */
1077 trace1("SOCK::verakons_reply dqdt", _sim
->_i
[i
]);
1078 stream
<< _sim
->_i
[i
];
1082 _out
<< "u,dq=i: \n";
1083 for (unsigned i
=0; i
<= n_vars
; i
++) /* Variablen-Werte */
1085 _out
<< _sim
->vdc()[i
] << "," << _sim
->_i
[i
] << "\n" ;
1089 trace0("SOCK::verakons_reply ac_snap");
1090 ac_snapshot(); // FIXME: to verakons()
1094 assert(stream
.bufsize() >= total
);
1095 stream
<< SocketStream::eol
;
1097 // for( unsigned i = 0; i < _caplist.size(); i++)
1099 // trace1("unlatching", i);
1101 // dashier umgekehrt.
1102 // commonstash[i] = _caplist[i]->common();
1103 // detach(_caplist[i]);
1105 // COMMON_COMPONENT* c = bm_dispatcher.clone("eval_bm_value");
1106 // COMMON_COMPONENT* dc = c->deflate();
1108 // _caplist[i]->attach_common(dc);
1110 // _caplist[i]->keep_ic(); // latch voltage applied to _v0
1117 void SOCK::transtep_reply(unsigned ret
, bool eol
)
1120 stream
<< _error
; stream
.pad(6);
1121 stream
<< (uint64_t)ret
;
1124 for (unsigned i
=1; i
<= n_vars
; i
++) {
1125 trace2("SOCK::transtep_reply v ", _sim
->_vdcstack
.top()[i
],i
);
1126 stream
<< _sim
->_vdcstack
.top()[i
];
1129 // OUCH, move to main loop.
1131 stream
<< SocketStream::eol
;
1135 void SOCK::transtep_gc_reply(unsigned ret
)
1137 transtep_reply(ret
, false);
1139 for (unsigned i
=1; i
<= n_vars
; i
++)
1141 trace1("SOCK::transtep_gc_reply dqdt", _sim
->_i
[i
]);
1142 stream
<< _sim
->_i
[i
];
1145 trace0("SOCK::transtep_gc_reply ac_snap");
1146 ac_snapshot(); // BUG: calls tr_begin
1148 assert(stream
.bufsize() >= total
);
1149 stream
<< SocketStream::eol
;
1151 /*--------------------------------------------------------------------------*/
1152 void SOCK::verainit_reply()
1154 trace4("SOCK::verainit_reply ", _error
, n_vars
, length
, var_namen_total_size
);
1155 stream
<< _error
; stream
.pad(6);
1156 stream
<< int32_t (n_vars
); stream
.pad(4);
1157 stream
<< int32_t (var_namen_total_size
); stream
.pad(4);
1159 assert(stream
.tcur() == 24);
1161 for (unsigned i
= 0; i
< n_vars
; i
++) {
1162 trace2("SOCK::verainit_reply", i
, var_namen_arr
[i
]);
1163 putstring8( &stream
, var_namen_arr
[i
]);
1164 stream
<< '\t'; stream
.pad(7);
1167 //good idea?? not yet. vera insists on branch node
1169 // for (unsigned i=0; i < n_inputs; i++)
1171 // trace1("putting name " + input_names[i], i);
1172 // putstring8( &stream, input_names[i]);
1173 // stream << '\t'; stream.pad(7);
1177 trace0("done verainit_reply");
1179 /*--------------------------------------------------------------------------*/
1180 void SOCK::veraop_reply()
1182 assert(n_vars
==_sim
->_total_nodes
);
1183 trace1("SOCK::veraop_reply ", n_vars
);
1184 stream
<< _error
; stream
.pad(6);
1185 for (unsigned i
=1; i
<= n_vars
; i
++) /* Variablen-Werte */
1187 stream
<< _sim
->vdc()[i
];
1191 for (unsigned i
=0; i
<= n_vars
; i
++) /* Variablen-Werte */
1193 _out
<< _sim
->_i
[i
] << "," << _sim
->vdc()[i
] << "\n" ;
1197 trace0("SOCK::veraop_reply taking ac snapshot (matrix only?).");
1200 stream
<< SocketStream::eol
;
1202 trace0("SOCK::veraop_reply sent");
1204 total
= 2*n_vars_square
+n_vars
+1;
1205 assert(stream
.bufsize() >= total
);
1206 if (printlevel
>= 1)
1208 userinfo(1,"vera_titan_ak","Sende: Error %i Framenumber %i, Laenge %i\n",
1209 _error
,frame_number
,total
);
1212 /*--------------------------------------------------------------------------*/
1213 /*--------------------------------------------------------------------------*/
1214 void SOCK::send_matrix()
1216 const BSMATRIX
<double> G
= _sim
->_acx
.real();
1217 const BSMATRIX
<double> C
= _sim
->_acx
.imag();
1219 _out
<< "G\n" << G
<< "\n";
1220 _out
<< "C\n" << C
<< "\n";
1222 trace0("SOCK::send_matrix G");
1223 for (unsigned i
=1; i
<= n_vars
; i
++){
1224 for (unsigned j
=1; j
<= n_vars
; j
++) {
1228 trace0("SOCK::send_matrix C");
1229 for (unsigned i
=1; i
<= n_vars
; i
++){
1230 for (unsigned j
=1; j
<= n_vars
; j
++) {
1235 /*--------------------------------------------------------------------------*/
1236 void SOCK::cap_prepare(void)
1238 trace1("SOCK::cap_prepare", _caplist
.size() );
1240 _capstash
= new CARDSTASH
[_caplist
.size()];
1242 for (unsigned ii
= 0; ii
< _caplist
.size(); ++ii
) {
1243 _caplist
[ii
]->inc_probes(); // we need to keep track of it
1244 _capstash
[ii
] = _caplist
[ii
]; // stash the std value
1246 if(_caplist
[ii
]->has_common()){
1247 trace1("SOCK::cap_prepare. have common", _caplist
[ii
]->value());
1248 // _caplist[ii]->set_value(_caplist[ii]->value(), 0); // zap out extensions
1249 // _caplist[ii]->set_constant(false); // update HACK?
1251 // all devices need individual commons.
1252 _caplist
[ii
]->attach_common(_caplist
[ii
]->common()->clone());
1253 assert(_caplist
[ii
]->has_common());
1255 // _sweepval[ii] = _zap[ii]->set__value(); // point to value to patch
1256 COMMON_COMPONENT
* c
= bm_dispatcher
.clone("eval_bm_value");
1257 double capval
= _caplist
[ii
]->value();
1258 trace2("SOCK::cap_prepare, attaching common", _caplist
[ii
]->long_label(), capval
);
1259 c
->set_value(capval
);
1260 COMMON_COMPONENT
* dc
= c
->deflate();
1263 _caplist
[ii
]->set_value(_caplist
[ii
]->value(), dc
); // zap out extensions
1264 _caplist
[ii
]->set_constant(false); // so it will be updated
1265 trace1("SOCK::cap_prepare calling precalc_first", _caplist
[ii
]->long_label());
1266 _caplist
[ii
]->precalc_first();
1267 trace0("SOCK::cap_prepare calling precalc_last");
1268 _caplist
[ii
]->precalc_last();
1269 trace0("SOCK::cap_prepare calling trbegin");
1270 _caplist
[ii
]->tr_begin();
1274 /*--------------------------------------------------------------------------*/
1275 void SOCK::cap_reset(void)
1277 trace0("SOCK::cap_reset");
1278 for (unsigned ii
= 0; ii
< _caplist
.size(); ++ii
) {
1279 _capstash
[ii
].restore();
1280 _caplist
[ii
]->dec_probes();
1281 // _caplist[ii]->precalc_first();
1282 // _caplist[ii]->precalc_last();
1286 trace0("SOCK::cap_reset done");
1288 /*--------------------------------------------------------------------------*/
1291 trace0("SOCK::~SOCK()");
1293 /*--------------------------------------------------------------------------*/
1294 // vim:ts=8:sw=2:noet: