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

Annotation of /trunk/pygtk/interface/simulation.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 225 - (hide annotations) (download) (as text)
Fri Jan 27 14:55:43 2006 UTC (15 years ago) by johnpye
File MIME type: text/x-c++src
File size: 14233 byte(s)
Added const-ness to 2nd parameter of slv_set_char_parameter.
Implemented setting of int, real and string parameters via PyGTK interface.
1 johnpye 132 #include <iostream>
2     #include <iomanip>
3     #include <stdexcept>
4     #include <sstream>
5     using namespace std;
6    
7     extern "C"{
8     #include <utilities/ascConfig.h>
9     #include <utilities/ascSignal.h>
10     #include <utilities/ascMalloc.h>
11     #include <general/dstring.h>
12 johnpye 196 #include <general/tm_time.h>
13 johnpye 132 #include <compiler/instance_enum.h>
14     #include <compiler/fractions.h>
15     #include <compiler/compiler.h>
16     #include <compiler/dimen.h>
17     #include <compiler/symtab.h>
18     #include <compiler/instance_io.h>
19     #include <compiler/instantiate.h>
20     #include <compiler/bintoken.h>
21     #include <compiler/instance_enum.h>
22     #include <compiler/instquery.h>
23     #include <compiler/check.h>
24     #include <compiler/name.h>
25     #include <compiler/pending.h>
26    
27     #include <utilities/readln.h>
28     #include <solver/mtx.h>
29     #include <solver/slv_types.h>
30     #include <solver/var.h>
31     #include <solver/rel.h>
32     #include <solver/discrete.h>
33     #include <solver/conditional.h>
34     #include <solver/logrel.h>
35     #include <solver/bnd.h>
36     #include <solver/calc.h>
37     #include <solver/relman.h>
38     #include <solver/slv_common.h>
39     #include <solver/linsol.h>
40     #include <solver/linsolqr.h>
41     #include <solver/slv_client.h>
42     #include <solver/system.h>
43     #include <solver/slv_interface.h>
44     #include <solver/slvDOF.h>
45     #include <solver/slv3.h>
46     #include <solver/slv_stdcalls.h>
47     }
48    
49     #include "simulation.h"
50     #include "solver.h"
51 johnpye 208 #include "solverparameters.h"
52 johnpye 132 #include "name.h"
53    
54     /**
55     Create an instance of a type (call compiler etc)
56    
57     @TODO fix mutex on compile command filenames
58     */
59     Simulation::Simulation(Instance *i, const SymChar &name) : Instanc(i, name), simroot(GetSimulationRoot(i),SymChar("simroot")){
60 johnpye 153 is_built = false;
61 johnpye 132 // Create an Instance object for the 'simulation root' (we'll call
62 johnpye 190 // it the 'simulation model') and it can be fetched using 'getModel()'
63 johnpye 132 // any time later.
64     //simroot = Instanc(GetSimulationRoot(i),name);
65     }
66    
67 johnpye 164 Simulation::Simulation(const Simulation &old) : Instanc(old), simroot(old.simroot){
68     is_built = old.is_built;
69     sys = old.sys;
70     bin_srcname = old.bin_srcname;
71     bin_objname = old.bin_objname;
72     bin_libname = old.bin_libname;
73     bin_cmd = old.bin_cmd;
74 johnpye 190 bin_rm = old.bin_rm;
75 johnpye 164 }
76    
77     Simulation::~Simulation(){
78     //CONSOLE_DEBUG("Deleting simulation %s", getName().toString());
79     }
80    
81 johnpye 132 Instanc &
82     Simulation::getModel(){
83     if(!simroot.getInternalType()){
84     throw runtime_error("Simulation::getModel: simroot.getInternalType()is NULL");
85     }
86     return simroot;
87     }
88    
89     void
90     Simulation::checkDoF() const{
91     cerr << "CHECKING DOF..." << endl;
92     int dof, status;
93 johnpye 164 if(!sys){
94 johnpye 132 throw runtime_error("System not yet built");
95     }
96     slvDOF_status(sys, &status, &dof);
97     switch(status){
98 johnpye 190 case 1: ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"Underspecified; %d degrees of freedom",dof); break;
99     case 2: ERROR_REPORTER_NOLINE(ASC_USER_NOTE,"Square"); break;
100     case 3: ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"Structurally singular"); break;
101     case 4: ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"Overspecified"); break;
102 johnpye 132 case 5:
103     throw runtime_error("Unable to resolve degrees of freedom"); break;
104     default:
105     throw runtime_error("Invalid return status from slvDOF_status");
106     }
107     }
108    
109     void
110     Simulation::run(const Method &method){
111     cerr << "RUNNING PROCEDURE " << method.getName() << endl;
112     Nam name = Nam(method.getSym());
113 johnpye 154 //cerr << "CREATED NAME '" << name.getName() << "'" << endl;
114 johnpye 132 Proc_enum pe;
115     pe = Initialize(
116 johnpye 164 &*(getModel().getInternalType()) ,name.getInternalType(), "__not_named__"
117 johnpye 132 ,ASCERR
118     ,0, NULL, NULL
119     );
120    
121     if(pe == Proc_all_ok){
122 johnpye 190 ERROR_REPORTER_NOLINE(ASC_PROG_NOTE,"Method '%s' was run (check above for errors)\n",method.getName());
123 johnpye 132 //cerr << "METHOD " << method.getName() << " COMPLETED OK" << endl;
124     }else{
125     stringstream ss;
126     ss << "Simulation::run: Method '" << method.getName() << "' returned error: ";
127     switch(pe){
128     case Proc_CallOK: ss << "Call OK"; break;
129     case Proc_CallError: ss << "Error occurred in call"; break;
130     case Proc_CallReturn: ss << "Request that caller return (OK)"; break;
131     case Proc_CallBreak: ss << "Break out of enclosing loop"; break;
132     case Proc_CallContinue: ss << "Skip to next iteration"; break;
133    
134     case Proc_break: ss << "Break"; break;
135     case Proc_continue: ss << "Continue"; break;
136     case Proc_fallthru: ss << "Fall-through"; break;
137     case Proc_return: ss << "Return"; break;
138     case Proc_stop: ss << "Stop"; break;
139     case Proc_stack_exceeded: ss << "Stack exceeded"; break;
140     case Proc_stack_exceeded_this_frame: ss << "Stack exceeded this frame"; break;
141     case Proc_case_matched: ss << "Case matched"; break;
142     case Proc_case_unmatched: ss << "Case unmatched"; break;
143    
144     case Proc_case_undefined_value: ss << "Undefined value in case"; break;
145     case Proc_case_boolean_mismatch: ss << "Boolean mismatch in case"; break;
146     case Proc_case_integer_mismatch: ss << "Integer mismatch in case"; break;
147     case Proc_case_symbol_mismatch: ss << "Symbol mismatch in case"; break;
148     case Proc_case_wrong_index: ss << "Wrong index in case"; break;
149     case Proc_case_wrong_value: ss << "Wrong value in case"; break;
150     case Proc_case_extra_values: ss << "Extra values in case"; break;
151     case Proc_bad_statement: ss << "Bad statement"; break;
152     case Proc_bad_name: ss << "Bad name"; break;
153     case Proc_for_duplicate_index: ss << "Duplicate index"; break;
154     case Proc_for_set_err: ss << "For set error"; break;
155     case Proc_for_not_set: ss << "For not set"; break;
156     case Proc_illegal_name_use: ss << "Illegal name use"; break;
157     case Proc_name_not_found: ss << "Name not found"; break;
158     case Proc_instance_not_found: ss << "Instance not found"; break;
159     case Proc_type_not_found: ss << "Type not found"; break;
160     case Proc_illegal_type_use: ss << "Illegal use"; break;
161     case Proc_proc_not_found: ss << "Method not found"; break;
162     case Proc_if_expr_error_typeconflict: ss << "Type conflict in 'if' expression"; break;
163     case Proc_if_expr_error_nameunfound: ss << "Name not found in 'if' expression"; break;
164     case Proc_if_expr_error_incorrectname: ss << "Incorrect name in 'if' expression"; break;
165     case Proc_if_expr_error_undefinedvalue: ss << "Undefined value in 'if' expression"; break;
166     case Proc_if_expr_error_dimensionconflict: ss << "Dimension conflict in 'if' expression"; break;
167     case Proc_if_expr_error_emptychoice: ss << "Empty choice in 'if' expression"; break;
168     case Proc_if_expr_error_emptyintersection: ss << "Empty intersection in 'if' expression"; break;
169     case Proc_if_expr_error_confused: ss << "Confused in 'if' expression"; break;
170     case Proc_if_real_expr: ss << "Real-valued result in 'if' expression"; break;
171     case Proc_if_integer_expr: ss << "Integeter-valued result in 'if' expression"; break;
172     case Proc_if_symbol_expr: ss << "Symbol-valued result in 'if' expression"; break;
173     case Proc_if_set_expr: ss << "Set-valued result in 'if' expression"; break;
174     case Proc_if_not_logical: ss << "If expression is not logical"; break;
175     case Proc_user_interrupt: ss << "User interrupt"; break;
176     case Proc_infinite_loop: ss << "Infinite loop"; break;
177     case Proc_declarative_constant_assignment: ss << "Declarative constant assignment"; break;
178     case Proc_nonsense_assignment: ss << "Nonsense assginment (bogus)"; break;
179     case Proc_nonconsistent_assignment: ss << "Inconsistent assignment"; break;
180     case Proc_nonatom_assignment: ss << "Non-atom assignment"; break;
181     case Proc_nonboolean_assignment: ss << "Non-boolean assignment"; break;
182     case Proc_noninteger_assignment: ss << "Non-integer assignment"; break;
183     case Proc_nonreal_assignment: ss << "Non-real assignment"; break;
184     case Proc_nonsymbol_assignment: ss << "Non-symbol assignment"; break;
185     case Proc_lhs_error: ss << "Left-hand-side error"; break;
186     case Proc_rhs_error: ss << "Right-hand-side error"; break;
187     case Proc_unknown_error: ss << "Unknown error"; break;
188     default:
189     ss << "Invalid error code";
190     }
191    
192    
193     ss << " (" << int(pe) << ")";
194     throw runtime_error(ss.str());
195     }
196     }
197    
198     const bool
199     Simulation::check(){
200     cerr << "CHECKING SIMULATION" << endl;
201     Instance *i1 = getModel().getInternalType();
202 johnpye 164 CheckInstance(stderr, &*i1);
203 johnpye 132 cerr << "...DONE CHECKING" << endl;
204 johnpye 190 }
205 johnpye 132
206     void
207     Simulation::build(){
208     cerr << "BUILDING SIMULATION..." << endl;
209 johnpye 164 Instance *i1 = getModel().getInternalType();
210     sys = system_build(&*i1);
211     if(!sys){
212 johnpye 132 throw runtime_error("Unable to build system");
213     }
214 johnpye 153 is_built = true;
215 johnpye 132 cerr << "...DONE BUILDING" << endl;
216     }
217    
218     vector<Variable>
219     Simulation::getFixableVariables(){
220     cerr << "GETTING FIXABLE VARIABLES..." << endl;
221     vector<Variable> vars;
222     vars.reserve(100);
223    
224 johnpye 164 if(!sys){
225 johnpye 132 throw runtime_error("Simulation system not yet built");
226     }
227    
228     int32 **vip; /** TODO ensure 32 bit integers are used */
229    
230     // Get IDs of elegible variables in array at vip...
231     if(!slvDOF_eligible(sys,vip)){
232 johnpye 190 ERROR_REPORTER_NOLINE(ASC_USER_NOTE,"No fixable variables found.");
233 johnpye 132 }else{
234     //cerr << "FIXABLE VARS FOUND" << endl;
235     struct var_variable **vp = slv_get_solvers_var_list(sys);
236    
237     /*struct var_variable *first_var = vp[0];
238     char *first_var_name = var_make_name(sys,first_var);
239     cerr << "FIRST SYS VAR IS NAMED " << var_make_name(s,first_var) << endl;
240     ascfree(first_var_name);*/
241    
242     if(vp==NULL){
243     throw runtime_error("Simulation variable list is null");
244     }
245 johnpye 190
246 johnpye 132 // iterate through this list until we find a -1:
247     int i=0;
248     int var_index = (*vip)[i];
249     while(var_index >= 0){
250     //cerr << "FOUND VARIABLE var_index = " << var_index << endl;
251     struct var_variable *var = vp[var_index];
252     //cerr << "VARIABLE " << var_index << " IS ELIGIBLE" << endl;
253     char *var_name = var_make_name(sys,var);
254     //cerr << "ELIGIBLE VAR: " << var_name << endl;
255     ascfree(var_name);
256     vars.push_back(Variable( sys,var ));
257     ++i;
258     var_index = (*vip)[i];
259     }
260 johnpye 190 ERROR_REPORTER_NOLINE(ASC_USER_NOTE,"Found %d fixable variables.",i);
261 johnpye 132 //cerr << "END ELEGIBLE VARS LIST" << endl;
262     ascfree(*vip);
263     //cerr << "FREED VIP LIST" << endl;
264     }
265    
266     //cerr << "FINISHED WITH FINDING ELEGIBLE VARIABLES" << endl;
267     return vars;
268     }
269    
270 johnpye 196
271 johnpye 132 void
272     Simulation::solve(Solver solver){
273 johnpye 153 if(!is_built){
274     throw runtime_error("Simulation::solver: simulation is not yet built, can't start solving.");
275     }
276    
277 johnpye 132 cerr << "SIMULATION::SOLVE STARTING..." << endl;
278     enum inst_t k = getModel().getKind();
279     if(k!=MODEL_INST)throw runtime_error("Can't solve: not an instance of type MODEL_INST");
280 johnpye 190
281 johnpye 164 Instance *i1 = getInternalType();
282     int npend = NumberPendingInstances(&*i1);
283 johnpye 190 if(npend)throw runtime_error("Can't solve: There are still %d pending instances");
284 johnpye 132
285     if(!sys)throw runtime_error("Can't solve: Simulation system has not been built yet.");
286 johnpye 190
287 johnpye 132 cerr << "SIMULATION::SOLVE: SET SOLVER..." << endl;
288     setSolver(solver);
289 johnpye 190
290    
291 johnpye 207 cerr << "PRESOLVING SYSTEM...";
292 johnpye 132 slv_presolve(sys);
293 johnpye 207 cerr << "DONE" << endl;
294 johnpye 190
295 johnpye 132 cerr << "SOLVING SYSTEM..." << endl;
296 johnpye 196 // Add some stuff here for cleverer iteration....
297 johnpye 207 unsigned niter = 1000;
298 johnpye 196 double updateinterval = 0.02;
299 johnpye 132
300 johnpye 196 double starttime = tm_cpu_time();
301     double lastupdate = starttime;
302     slv_status_t status;
303     int solved_vars=0;
304     bool stop=false;
305    
306 johnpye 207 for(int iter = 1; iter <= niter && !stop; ++iter){
307 johnpye 196 slv_get_status(sys,&status);
308     if(status.ready_to_solve){
309     slv_iterate(sys);
310     }
311     if(tm_cpu_time() - lastupdate > updateinterval && iter > 0){
312     if(solved_vars < status.block.previous_total_size){
313     solved_vars = status.block.previous_total_size;
314     CONSOLE_DEBUG("Solved %5d vars. Now block %3d/%-3d...", solved_vars, status.block.current_block, status.block.number_of);
315     }else{
316     CONSOLE_DEBUG("Total %5d iterations (%5d in current block of %d vars)", iter, status.block.iteration, status.block.current_size);
317     }
318     lastupdate = tm_cpu_time();
319     }
320     }
321    
322     if(status.ok){
323 johnpye 132 cerr << "... DONE SOLVING SYSTEM" << endl;
324     }else{
325 johnpye 190 ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"Solver failed");
326 johnpye 132 }
327    
328 johnpye 196 cerr << "SOLVER PERFORMED " << status.iteration << " ITERATIONS IN " << (tm_cpu_time() - starttime) << "s" << endl;
329 johnpye 132
330 johnpye 196 if(status.iteration_limit_exceeded){
331 johnpye 190 ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"Exceeded interation limit");
332 johnpye 132 }
333    
334 johnpye 196 if(status.converged){
335 johnpye 190 ERROR_REPORTER_NOLINE(ASC_USER_SUCCESS,"Solver converged: %d iterations, %3.2e s"
336 johnpye 196 ,status.iteration,status.cpu_elapsed);
337 johnpye 132 }else{
338 johnpye 196 ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"Solver not converged after %d iterations.",status.iteration);
339 johnpye 132 }
340    
341     }
342    
343     void
344     Simulation::write(){
345     simroot.write();
346     }
347    
348     //------------------------------------------
349     // ASSIGNING SOLVER TO SIMULATION
350 johnpye 190
351 johnpye 132 void
352     Simulation::setSolver(Solver &solver){
353 johnpye 151 cerr << "SETTING SOLVER ON SIMULATION TO " << solver.getName() << endl;
354    
355 johnpye 132 if(!sys)throw runtime_error("Can't solve: Simulation system has not been built yet.");
356     // Update the solver object because sometimes an alternative solver can be returned, apparently.
357    
358     int selected = slv_select_solver(sys, solver.getIndex());
359 johnpye 154 //cerr << "Simulation::setSolver: slv_select_solver returned " << selected << endl;
360 johnpye 132
361     if(selected<0){
362 johnpye 190 ERROR_REPORTER_NOLINE(ASC_PROG_ERROR,"Failed to select solver");
363 johnpye 132 throw runtime_error("Failed to select solver");
364     }
365    
366     if(selected!=solver.getIndex()){
367 johnpye 150 solver = Solver(slv_solver_name(selected));
368 johnpye 190 ERROR_REPORTER_NOLINE(ASC_PROG_NOTE,"Substitute solver '%s' (index %d) selected.\n", solver.getName().c_str(), selected);
369 johnpye 132 }
370 johnpye 190
371 johnpye 132 if( slv_eligible_solver(sys) <= 0){
372 johnpye 190 ERROR_REPORTER_NOLINE(ASC_PROG_ERROR,"Inelegible solver '%s'", solver.getName().c_str() );
373 johnpye 132 throw runtime_error("Inelegible solver");
374     }
375     }
376    
377     const Solver
378     Simulation::getSolver() const{
379     int index = slv_get_selected_solver(sys);
380 johnpye 154 //cerr << "Simulation::getSolver: index = " << index << endl;
381 johnpye 132 if(index<0)throw runtime_error("No solver selected");
382    
383 johnpye 150 return Solver(slv_solver_name(index));
384 johnpye 132 }
385    
386    
387 johnpye 208 /**
388     Get solver parameters struct wrapped up as a SolverParameters class.
389     */
390     SolverParameters
391     Simulation::getSolverParameters() const{
392 johnpye 225 if(!sys)throw runtime_error("Can't getSolverParameters: Simulation system has not been built yet.");
393 johnpye 132
394 johnpye 208 slv_parameters_t p;
395     slv_get_parameters(sys,&p);
396     return SolverParameters(p);
397     }
398    
399 johnpye 225 /**
400     Update the solver parameters by passing a new set back
401     */
402     void
403     Simulation::setSolverParameters(SolverParameters &P){
404     if(!sys)throw runtime_error("Can't set solver parameters: simulation has not been built yet.");
405     slv_set_parameters(sys, &(P.getInternalType()));
406     }
407    

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