/[ascend]/trunk/pygtk/simulation.cpp
ViewVC logotype

Contents of /trunk/pygtk/simulation.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 910 - (show annotations) (download) (as text)
Thu Oct 26 13:35:25 2006 UTC (13 years, 8 months ago) by johnpye
File MIME type: text/x-c++src
File size: 21924 byte(s)
In instantiate.c, made new blackbox code tolerant of blackboxes that don't need initialisation.
Removed some debug output.
Expanded 'extfntest.py' a little bit, for ease of testing.
Converted 'blackbox is experimental' warnings to one-time-only.
Minor change to way that webbrowser is invoked under linux.
1 /* ASCEND modelling environment
2 Copyright (C) 2006 Carnegie Mellon University
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA.
18 */
19 #include <iostream>
20 #include <iomanip>
21 #include <stdexcept>
22 #include <sstream>
23 using namespace std;
24
25 #include "config.h"
26
27 extern "C"{
28 #include <utilities/ascConfig.h>
29 #include <utilities/error.h>
30 #include <utilities/ascSignal.h>
31 #include <utilities/ascMalloc.h>
32 #include <general/dstring.h>
33 #include <general/tm_time.h>
34 #include <compiler/instance_enum.h>
35 #include <compiler/fractions.h>
36 #include <compiler/compiler.h>
37 #include <compiler/dimen.h>
38 #include <compiler/symtab.h>
39 #include <compiler/instance_io.h>
40 #include <compiler/instantiate.h>
41 #include <compiler/bintoken.h>
42 #include <compiler/instance_enum.h>
43 #include <compiler/instquery.h>
44 #include <compiler/check.h>
45 #include <compiler/name.h>
46 #include <compiler/pending.h>
47 #include <compiler/importhandler.h>
48
49 #include <utilities/readln.h>
50 #include <solver/mtx.h>
51 #include <solver/slv_types.h>
52 #include <solver/var.h>
53 #include <solver/rel.h>
54 #include <solver/discrete.h>
55 #include <solver/conditional.h>
56 #include <solver/logrel.h>
57 #include <solver/bnd.h>
58 #include <solver/calc.h>
59 #include <solver/relman.h>
60 #include <solver/slv_common.h>
61 #include <solver/linsol.h>
62 #include <solver/linsolqr.h>
63 #include <solver/slv_client.h>
64 #include <solver/system.h>
65 #include <solver/slv_interface.h>
66 #include <solver/slvDOF.h>
67 #include <solver/slv3.h>
68 #include <solver/slv_stdcalls.h>
69 #include <solver/slv_server.h>
70 }
71
72 #include "simulation.h"
73 #include "solver.h"
74 #include "solverparameters.h"
75 #include "name.h"
76 #include "incidencematrix.h"
77 #include "variable.h"
78 #include "solverstatus.h"
79 #include "solverreporter.h"
80
81 /**
82 Create an instance of a type (call compiler etc)
83
84 @TODO fix mutex on compile command filenames
85 */
86 Simulation::Simulation(Instance *i, const SymChar &name) : Instanc(i, name), simroot(GetSimulationRoot(i),SymChar("simroot")){
87 is_built = false;
88 // Create an Instance object for the 'simulation root' (we'll call
89 // it the 'simulation model') and it can be fetched using 'getModel()'
90 // any time later.
91 //simroot = Instanc(GetSimulationRoot(i),name);
92 }
93
94 Simulation::Simulation(const Simulation &old) : Instanc(old), simroot(old.simroot){
95 is_built = old.is_built;
96 sys = old.sys;
97 bin_srcname = old.bin_srcname;
98 bin_objname = old.bin_objname;
99 bin_libname = old.bin_libname;
100 bin_cmd = old.bin_cmd;
101 bin_rm = old.bin_rm;
102 sing = NULL;
103 }
104
105 Simulation::~Simulation(){
106 //CONSOLE_DEBUG("Deleting simulation %s", getName().toString());
107 }
108
109 Instanc &
110 Simulation::getModel(){
111 if(!simroot.getInternalType()){
112 throw runtime_error("Simulation::getModel: simroot.getInternalType()is NULL");
113 }
114 return simroot;
115 }
116
117
118 slv_system_structure *
119 Simulation::getSystem(){
120 if(!sys)throw runtime_error("Can't getSystem: simulation not yet built");
121 return sys;
122 }
123
124
125 const string
126 Simulation::getInstanceName(const Instanc &i) const{
127 char *n;
128 n = WriteInstanceNameString(i.getInternalType(),simroot.getInternalType());
129 string s(n);
130 ascfree(n);
131 return s;
132 }
133
134 const int
135 Simulation::getNumVars(){
136 return slv_get_num_solvers_vars(getSystem());
137 }
138
139
140 void
141 Simulation::write(){
142 simroot.write();
143 }
144
145 //------------------------------------------------------------------------------
146 // RUNNING MODEL 'METHODS'
147
148 void
149 Simulation::run(const Method &method){
150 Instanc &model = getModel();
151 this->run(method,model);
152 }
153
154 void
155 Simulation::runDefaultMethod(){
156 Method m = getType().getMethod(SymChar("on_load"));
157 run(m);
158 }
159
160 void
161 Simulation::run(const Method &method, Instanc &model){
162
163 // set the 'sim' pointer to our local variable...
164 CONSOLE_DEBUG("Setting shared pointer 'sim'");
165 importhandler_setsharedpointer("sim",this);
166
167 cerr << "RUNNING PROCEDURE " << method.getName() << endl;
168 Nam name = Nam(method.getSym());
169 //cerr << "CREATED NAME '" << name.getName() << "'" << endl;
170
171
172 Proc_enum pe;
173 pe = Initialize(
174 &*(model.getInternalType()) ,name.getInternalType(), "__not_named__"
175 ,ASCERR
176 ,0, NULL, NULL
177 );
178
179 // clear out the 'sim' pointer (soon it will be invalid)
180 importhandler_setsharedpointer("sim",NULL);
181 CONSOLE_DEBUG("Cleared shared pointer 'sim'");
182
183 if(pe == Proc_all_ok){
184 ERROR_REPORTER_NOLINE(ASC_PROG_NOTE,"Method '%s' was run (check above for errors)\n",method.getName());
185 //cerr << "METHOD " << method.getName() << " COMPLETED OK" << endl;
186 }else{
187 stringstream ss;
188 ss << "Simulation::run: Method '" << method.getName() << "' returned error: ";
189 switch(pe){
190 case Proc_CallOK: ss << "Call OK"; break;
191 case Proc_CallError: ss << "Error occurred in call"; break;
192 case Proc_CallReturn: ss << "Request that caller return (OK)"; break;
193 case Proc_CallBreak: ss << "Break out of enclosing loop"; break;
194 case Proc_CallContinue: ss << "Skip to next iteration"; break;
195
196 case Proc_break: ss << "Break"; break;
197 case Proc_continue: ss << "Continue"; break;
198 case Proc_fallthru: ss << "Fall-through"; break;
199 case Proc_return: ss << "Return"; break;
200 case Proc_stop: ss << "Stop"; break;
201 case Proc_stack_exceeded: ss << "Stack exceeded"; break;
202 case Proc_stack_exceeded_this_frame: ss << "Stack exceeded this frame"; break;
203 case Proc_case_matched: ss << "Case matched"; break;
204 case Proc_case_unmatched: ss << "Case unmatched"; break;
205
206 case Proc_case_undefined_value: ss << "Undefined value in case"; break;
207 case Proc_case_boolean_mismatch: ss << "Boolean mismatch in case"; break;
208 case Proc_case_integer_mismatch: ss << "Integer mismatch in case"; break;
209 case Proc_case_symbol_mismatch: ss << "Symbol mismatch in case"; break;
210 case Proc_case_wrong_index: ss << "Wrong index in case"; break;
211 case Proc_case_wrong_value: ss << "Wrong value in case"; break;
212 case Proc_case_extra_values: ss << "Extra values in case"; break;
213 case Proc_bad_statement: ss << "Bad statement"; break;
214 case Proc_bad_name: ss << "Bad name"; break;
215 case Proc_for_duplicate_index: ss << "Duplicate index"; break;
216 case Proc_for_set_err: ss << "For set error"; break;
217 case Proc_for_not_set: ss << "For not set"; break;
218 case Proc_illegal_name_use: ss << "Illegal name use"; break;
219 case Proc_name_not_found: ss << "Name not found"; break;
220 case Proc_instance_not_found: ss << "Instance not found"; break;
221 case Proc_type_not_found: ss << "Type not found"; break;
222 case Proc_illegal_type_use: ss << "Illegal use"; break;
223 case Proc_proc_not_found: ss << "Method not found"; break;
224 case Proc_if_expr_error_typeconflict: ss << "Type conflict in 'if' expression"; break;
225 case Proc_if_expr_error_nameunfound: ss << "Name not found in 'if' expression"; break;
226 case Proc_if_expr_error_incorrectname: ss << "Incorrect name in 'if' expression"; break;
227 case Proc_if_expr_error_undefinedvalue: ss << "Undefined value in 'if' expression"; break;
228 case Proc_if_expr_error_dimensionconflict: ss << "Dimension conflict in 'if' expression"; break;
229 case Proc_if_expr_error_emptychoice: ss << "Empty choice in 'if' expression"; break;
230 case Proc_if_expr_error_emptyintersection: ss << "Empty intersection in 'if' expression"; break;
231 case Proc_if_expr_error_confused: ss << "Confused in 'if' expression"; break;
232 case Proc_if_real_expr: ss << "Real-valued result in 'if' expression"; break;
233 case Proc_if_integer_expr: ss << "Integeter-valued result in 'if' expression"; break;
234 case Proc_if_symbol_expr: ss << "Symbol-valued result in 'if' expression"; break;
235 case Proc_if_set_expr: ss << "Set-valued result in 'if' expression"; break;
236 case Proc_if_not_logical: ss << "If expression is not logical"; break;
237 case Proc_user_interrupt: ss << "User interrupt"; break;
238 case Proc_infinite_loop: ss << "Infinite loop"; break;
239 case Proc_declarative_constant_assignment: ss << "Declarative constant assignment"; break;
240 case Proc_nonsense_assignment: ss << "Nonsense assginment (bogus)"; break;
241 case Proc_nonconsistent_assignment: ss << "Inconsistent assignment"; break;
242 case Proc_nonatom_assignment: ss << "Non-atom assignment"; break;
243 case Proc_nonboolean_assignment: ss << "Non-boolean assignment"; break;
244 case Proc_noninteger_assignment: ss << "Non-integer assignment"; break;
245 case Proc_nonreal_assignment: ss << "Non-real assignment"; break;
246 case Proc_nonsymbol_assignment: ss << "Non-symbol assignment"; break;
247 case Proc_lhs_error: ss << "Left-hand-side error"; break;
248 case Proc_rhs_error: ss << "Right-hand-side error"; break;
249 case Proc_unknown_error: ss << "Unknown error"; break;
250 default:
251 ss << "Invalid error code";
252 }
253
254 ss << " (" << int(pe) << ")";
255 throw runtime_error(ss.str());
256 }
257 }
258
259 //-----------------------------------------------------------------------------
260 // CHECKING METHODS
261
262 /**
263 Check that all the analysis went OK: solver lists are all there, etc...?
264
265 Can't return anything here because of limitations in the C API
266 */
267 void
268 Simulation::checkInstance(){
269 //cerr << "CHECKING SIMULATION INSTANCE" << endl;
270 Instance *i1 = getModel().getInternalType();
271 CheckInstance(stderr, &*i1);
272 //cerr << "DONE CHECKING INSTANCE" << endl;
273 }
274
275 /**
276 @return 1 = underspecified, 2 = square, 3 = structurally singular, 4 = overspecified
277 */
278 enum StructuralStatus
279 Simulation::checkDoF() const{
280 cerr << "CHECKING DOF..." << endl;
281 int dof, status;
282 if(!sys){
283 throw runtime_error("System not yet built");
284 }
285 slvDOF_status(sys, &status, &dof);
286 switch(status){
287 case ASCXX_DOF_UNDERSPECIFIED:
288 case ASCXX_DOF_SQUARE:
289 case ASCXX_DOF_OVERSPECIFIED:
290 case ASCXX_DOF_STRUCT_SINGULAR:
291 return (enum StructuralStatus)status;
292 case 5:
293 throw runtime_error("Unable to resolve degrees of freedom"); break;
294 default:
295 throw runtime_error("Invalid return status from slvDOF_status");
296 }
297 }
298
299 /**
300 Check consistency
301
302 @TODO what is the difference between this and checkStructuralSingularity?
303
304 @return list of freeable variables. List will be empty if sys is consistent.
305 */
306 vector<Variable>
307 Simulation::getFreeableVariables(){
308 vector<Variable> v;
309
310 //cerr << "CHECKING CONSISTENCY..." << endl;
311 int *fixedarrayptr=NULL;
312
313 if(!sys){
314 throw runtime_error("System not yet built");
315 }
316
317 int res = consistency_analysis(sys, &fixedarrayptr);
318
319 if(res==1){
320 cerr << "STRUCTURALLY CONSISTENT" << endl;
321 }else{
322 if(fixedarrayptr ==NULL){
323 ERROR_REPORTER_HERE(ASC_USER_ERROR,"STRUCTURALLY INCONSISTENT");
324 throw runtime_error("Invalid constistency analysis result returned!");
325 }
326
327 struct var_variable **vp = slv_get_master_var_list(sys);
328 for(int i=0; fixedarrayptr[i]!=-1; ++i){
329 v.push_back( Variable(this, vp[fixedarrayptr[i]]) );
330 }
331 }
332 return v;
333 }
334
335 /** Returns TRUE if all is OK (not singular) */
336 bool
337 Simulation::checkStructuralSingularity(){
338 int *vil;
339 int *ril;
340 int *fil;
341
342 cerr << "RETREIVING slfDOF_structsing INFO" << endl;
343
344 int res = slvDOF_structsing(sys, mtx_FIRST, &vil, &ril, &fil);
345 struct var_variable **varlist = slv_get_solvers_var_list(sys);
346 struct rel_relation **rellist = slv_get_solvers_rel_list(sys);
347
348 if(this->sing){
349 cerr << "DELETING OLD SINGULATING INFO" << endl;
350 delete this->sing;
351 this->sing = NULL;
352 }
353
354 if(res==1){
355 CONSOLE_DEBUG("processing singularity data...");
356 sing = new SingularityInfo();
357
358 // pull in the lists of vars and rels, and the freeable vars:
359 for(int i=0; ril[i]!=-1; ++i){
360 sing->rels.push_back( Relation(this, rellist[ril[i]]) );
361 }
362
363 for(int i=0; vil[i]!=-1; ++i){
364 sing->vars.push_back( Variable(this, varlist[vil[i]]) );
365 }
366
367 for(int i=0; fil[i]!=-1; ++i){
368 sing->freeablevars.push_back( Variable(this, varlist[fil[i]]) );
369 }
370
371 // we're done with those lists now
372 ASC_FREE(vil);
373 ASC_FREE(ril);
374 ASC_FREE(fil);
375
376 if(sing->isSingular()){
377 CONSOLE_DEBUG("singularity found");
378 this->sing = sing;
379 return FALSE;
380 }
381 CONSOLE_DEBUG("no singularity");
382 delete sing;
383 return TRUE;
384 }else{
385 if(res==0){
386 throw runtime_error("Unable to determine singularity lists");
387 }else{
388 throw runtime_error("Invalid return from slvDOF_structsing.");
389 }
390 }
391 }
392
393 /**
394 If the checkStructuralSingularity analysis has been done,
395 this funciton will let you access the SingularityInfo data that was
396 stored.
397 */
398 const SingularityInfo &
399 Simulation::getSingularityInfo() const{
400 if(sing==NULL){
401 throw runtime_error("No singularity info present");
402 }
403 return *sing;
404 }
405
406 //------------------------------------------
407 // ASSIGNING SOLVER TO SIMULATION
408
409 void
410 Simulation::setSolver(Solver &solver){
411 /* CONSOLE_DEBUG("Setting solver on sim %p, root inst %p",this,this->simroot.getInternalType()); */
412 if(!is_built)throw runtime_error("Can't setSolver: simulation has not been built yet");
413 if(!sys)throw runtime_error("Can't setSolver: 'sys' is not assigned.");
414
415 // Update the solver object because sometimes an alternative solver can be returned, apparently.
416
417 int selected = slv_select_solver(sys, solver.getIndex());
418 //cerr << "Simulation::setSolver: slv_select_solver returned " << selected << endl;
419
420 if(selected<0){
421 ERROR_REPORTER_NOLINE(ASC_PROG_ERROR,"Failed to select solver");
422 throw runtime_error("Failed to select solver");
423 }
424
425 if(selected!=solver.getIndex()){
426 solver = Solver(slv_solver_name(selected));
427 ERROR_REPORTER_NOLINE(ASC_PROG_NOTE,"Substitute solver '%s' (index %d) selected.\n", solver.getName().c_str(), selected);
428 }
429
430 if( slv_eligible_solver(sys) <= 0){
431 ERROR_REPORTER_NOLINE(ASC_PROG_ERROR,"Inelegible solver '%s'", solver.getName().c_str() );
432 throw runtime_error("Inelegible solver");
433 }
434 }
435
436 const Solver
437 Simulation::getSolver() const{
438 int index = slv_get_selected_solver(sys);
439 //cerr << "Simulation::getSolver: index = " << index << endl;
440 if(index<0)throw runtime_error("No solver selected");
441
442 return Solver(slv_solver_name(index));
443 }
444
445 //------------------------------------------------------------------------------
446 // BUILD THE SYSTEM (SEND IT TO THE SOLVER)
447
448 /**
449 Build the system (send it to the solver)
450 */
451 void
452 Simulation::build(){
453 //cerr << "BUILDING SIMULATION..." << endl;
454 if(is_built){
455 throw runtime_error("Simulation is already built");
456 }
457
458 Instance *i1 = getModel().getInternalType();
459 sys = system_build(&*i1);
460 if(!sys){
461 throw runtime_error("Unable to build system");
462 }
463 is_built = true;
464 //cerr << "...DONE BUILDING" << endl;
465 }
466
467
468 //------------------------------------------------------------------------------
469 // SOLVER CONFIGURATION PARAMETERS
470
471 /**
472 Get solver parameters struct wrapped up as a SolverParameters class.
473 */
474 SolverParameters
475 Simulation::getSolverParameters() const{
476 if(!is_built)throw runtime_error("Can't getSolverParameters: Simulation system has not been built yet.");
477 if(!sys)throw runtime_error("Can't getSolverParameters: Simulation system has no 'sys' assigned.");
478
479 slv_parameters_t p;
480 slv_get_parameters(sys,&p);
481 return SolverParameters(p);
482 }
483
484 /**
485 Update the solver parameters by passing a new set back
486 */
487 void
488 Simulation::setSolverParameters(SolverParameters &P){
489 if(!sys)throw runtime_error("Can't set solver parameters: simulation has not been built yet.");
490 slv_set_parameters(sys, &(P.getInternalType()));
491 }
492
493 //------------------------------------------------------------------------------
494 // PRE-SOLVE DIAGNOSTICS
495
496 /**
497 Get a list of variables to fix to make an underspecified system
498 become square. Also seems to return stuff when you have a structurally
499 singuler system.
500 */
501 vector<Variable>
502 Simulation::getFixableVariables(){
503 //cerr << "GETTING FIXABLE VARIABLES..." << endl;
504 vector<Variable> vars;
505
506 if(!sys){
507 throw runtime_error("Simulation system not yet built");
508 }
509
510 int32 *vip; /** TODO ensure 32 bit integers are used */
511
512 // Get IDs of elegible variables in array at vip...
513 if(!slvDOF_eligible(sys,&vip)){
514 ERROR_REPORTER_NOLINE(ASC_USER_NOTE,"No fixable variables found.");
515 }else{
516 struct var_variable **vp = slv_get_solvers_var_list(sys);
517
518 if(vp==NULL){
519 throw runtime_error("Simulation variable list is null");
520 }
521
522 // iterate through this list until we find a -1:
523 int i=0;
524 int var_index = vip[i];
525 while(var_index >= 0){
526 struct var_variable *var = vp[var_index];
527 vars.push_back( Variable(this, var) );
528 ++i;
529 var_index = vip[i];
530 }
531 ERROR_REPORTER_NOLINE(ASC_USER_NOTE,"Found %d fixable variables.",i);
532 ascfree(vip);
533 }
534
535 return vars;
536 }
537
538 /**
539 Get the list of variables near their bounds. Helps to indentify why
540 you might be having non-convergence problems.
541 */
542 vector<Variable>
543 Simulation::getVariablesNearBounds(const double &epsilon){
544 //cerr << "GETTING VARIABLES NEAR BOUNDS..." << endl;
545 vector<Variable> vars;
546
547 if(!sys){
548 throw runtime_error("Simulation system not yet built");
549 }
550
551 int *vip;
552 if(slv_near_bounds(sys,epsilon,&vip)){
553 struct var_variable **vp = slv_get_solvers_var_list(sys);
554 struct var_variable *var;
555 cerr << "VARS FOUND NEAR BOUNDS" << endl;
556 int nlow = vip[0];
557 int nhigh = vip[1];
558 int lim1 = 2 + nlow;
559 for(int i=2; i<lim1; ++i){
560 var = vp[vip[i]];
561 char *var_name = var_make_name(sys,var);
562 cerr << "AT LOWER BOUND: " << var_name << endl;
563 ascfree(var_name);
564 vars.push_back(Variable(this,var));
565 };
566 int lim2 = lim1 + nhigh;
567 for(int i=lim1; i<lim2; ++i){
568 var = vp[vip[i]];
569 char *var_name = var_make_name(sys,var);
570 cerr << "AT UPPER BOUND: " << var_name << endl;
571 ascfree(var_name);
572 vars.push_back(Variable(this,var));
573 }
574 }
575 ascfree(vip);
576 return vars;
577 }
578
579
580 bool
581 SingularityInfo::isSingular() const{
582 if(vars.size()||rels.size()){
583 return true;
584 }
585 return false;
586 }
587
588 //------------------------------------------------------------------------------
589 // SOLVING
590
591 /**
592 Solve the system through to convergence. This function is hardwired with
593 a maximum of 1000 iterations, but will interrupt itself when the 'stop'
594 condition comes back from the SolverReporter.
595 */
596 void
597 Simulation::solve(Solver solver, SolverReporter &reporter){
598 if(!is_built){
599 throw runtime_error("Simulation::solver: simulation is not yet built, can't start solving.");
600 }
601
602 //cerr << "SIMULATION::SOLVE STARTING..." << endl;
603 enum inst_t k = getModel().getKind();
604 if(k!=MODEL_INST)throw runtime_error("Can't solve: not an instance of type MODEL_INST");
605
606 Instance *i1 = getInternalType();
607 int npend = NumberPendingInstances(&*i1);
608 if(npend)throw runtime_error("Can't solve: There are still %d pending instances");
609
610 if(!sys)throw runtime_error("Can't solve: Simulation system has not been built yet.");
611
612 //cerr << "SIMULATION::SOLVE: SET SOLVER..." << endl;
613 setSolver(solver);
614
615
616 //cerr << "PRESOLVING SYSTEM...";
617 slv_presolve(sys);
618 //cerr << "DONE" << endl;
619
620 //cerr << "SOLVING SYSTEM..." << endl;
621 // Add some stuff here for cleverer iteration....
622 unsigned niter = 1000;
623 //double updateinterval = 0.02;
624
625 double starttime = tm_cpu_time();
626 //double lastupdate = starttime;
627 SolverStatus status;
628 //int solved_vars=0;
629 bool stop=false;
630
631 status.getSimulationStatus(*this);
632 reporter.report(&status);
633
634 for(unsigned iter = 1; iter <= niter && !stop; ++iter){
635
636 if(status.isReadyToSolve()){
637 slv_iterate(sys);
638 }
639
640 status.getSimulationStatus(*this);
641
642 if(reporter.report(&status)){
643 stop = true;
644 }
645 }
646
647 double elapsed = tm_cpu_time() - starttime;
648
649
650 activeblock = status.getCurrentBlockNum();
651
652 reporter.finalise(&status);
653
654 // Just a little bit of console output:
655
656 if(status.isOK()){
657 //cerr << "... SOLVED, STATUS OK" << endl;
658 }else{
659 cerr << "... SOLVER FAILED" << endl;
660 }
661
662 //cerr << "SOLVER PERFORMED " << status.getIterationNum() << " ITERATIONS IN " << elapsed << "s" << endl;
663 }
664
665 //------------------------------------------------------------------------------
666 // POST-SOLVE DIAGNOSTICS
667
668 const int
669 Simulation::getActiveBlock() const{
670 return activeblock;
671 }
672
673 /**
674 Return an IncidenceMatrix built from the current state of the solver system.
675
676 This will actually return something meaningful even before solve.
677 */
678 IncidenceMatrix
679 Simulation::getIncidenceMatrix(){
680 return IncidenceMatrix(*this);
681 }
682
683 /**
684 This function looks at all the variables in the solve's list and updates
685 the variable status for the corresponding instances.
686
687 It does this by using the 'interface pointer' in the Instance, see
688 the C-API function GetInterfacePtr.
689
690 This is used to display visually which variables have been solved, which
691 ones have not yet been attempted, and which ones were active when the solver
692 failed (ASCXX_VAR_ACTIVE).
693 */
694 void
695 Simulation::processVarStatus(){
696
697 // this is a cheap function call:
698 const mtx_block_t *bb = slv_get_solvers_blocks(getSystem());
699
700 var_variable **vlist = slv_get_solvers_var_list(getSystem());
701 int nvars = slv_get_num_solvers_vars(getSystem());
702
703 slv_status_t status;
704 slv_get_status(getSystem(), &status);
705
706 if(status.block.number_of == 0){
707 cerr << "Variable statuses can't be set: block structure not yet determined." << endl;
708 return;
709 }
710
711 int activeblock = status.block.current_block;
712 int low = bb->block[activeblock].col.low;
713 int high = bb->block[activeblock].col.high;
714 bool allsolved = status.converged;
715 for(int c=0; c < nvars; ++c){
716 var_variable *v = vlist[c];
717 Instanc i((Instance *)var_instance(v));
718 VarStatus s = ASCXX_VAR_STATUS_UNKNOWN;
719 if(i.isFixed()){
720 s = ASCXX_VAR_FIXED;
721 }else if(var_incident(v) && var_active(v)){
722 if(allsolved || c < low){
723 s = ASCXX_VAR_SOLVED;
724 }else if(c <= high){
725 s = ASCXX_VAR_ACTIVE;
726 }else{
727 s = ASCXX_VAR_UNSOLVED;
728 }
729 }
730 i.setVarStatus(s);
731 }
732 }
733

john.pye@anu.edu.au
ViewVC Help
Powered by ViewVC 1.1.22