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

Contents of /trunk/pygtk/simulation.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 208 - (show annotations) (download) (as text)
Tue Jan 24 03:19:37 2006 UTC (14 years, 8 months ago) by johnpye
Original Path: trunk/pygtk/interface/simulation.cpp
File MIME type: text/x-c++src
File size: 13947 byte(s)
Added menu bar at top of PyGTK interface.
'Preferences' menu currently just outputs the number of
solver parameters in use. Plan is to allow the parameters
to be viewed and edited via the GUI.
1 #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 #include <general/tm_time.h>
13 #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 #include "solverparameters.h"
52 #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 is_built = false;
61 // Create an Instance object for the 'simulation root' (we'll call
62 // it the 'simulation model') and it can be fetched using 'getModel()'
63 // any time later.
64 //simroot = Instanc(GetSimulationRoot(i),name);
65 }
66
67 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 bin_rm = old.bin_rm;
75 }
76
77 Simulation::~Simulation(){
78 //CONSOLE_DEBUG("Deleting simulation %s", getName().toString());
79 }
80
81 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 if(!sys){
94 throw runtime_error("System not yet built");
95 }
96 slvDOF_status(sys, &status, &dof);
97 switch(status){
98 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 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 //cerr << "CREATED NAME '" << name.getName() << "'" << endl;
114 Proc_enum pe;
115 pe = Initialize(
116 &*(getModel().getInternalType()) ,name.getInternalType(), "__not_named__"
117 ,ASCERR
118 ,0, NULL, NULL
119 );
120
121 if(pe == Proc_all_ok){
122 ERROR_REPORTER_NOLINE(ASC_PROG_NOTE,"Method '%s' was run (check above for errors)\n",method.getName());
123 //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 CheckInstance(stderr, &*i1);
203 cerr << "...DONE CHECKING" << endl;
204 }
205
206 void
207 Simulation::build(){
208 cerr << "BUILDING SIMULATION..." << endl;
209 Instance *i1 = getModel().getInternalType();
210 sys = system_build(&*i1);
211 if(!sys){
212 throw runtime_error("Unable to build system");
213 }
214 is_built = true;
215 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 if(!sys){
225 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 ERROR_REPORTER_NOLINE(ASC_USER_NOTE,"No fixable variables found.");
233 }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
246 // 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 ERROR_REPORTER_NOLINE(ASC_USER_NOTE,"Found %d fixable variables.",i);
261 //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
271 void
272 Simulation::solve(Solver solver){
273 if(!is_built){
274 throw runtime_error("Simulation::solver: simulation is not yet built, can't start solving.");
275 }
276
277 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
281 Instance *i1 = getInternalType();
282 int npend = NumberPendingInstances(&*i1);
283 if(npend)throw runtime_error("Can't solve: There are still %d pending instances");
284
285 if(!sys)throw runtime_error("Can't solve: Simulation system has not been built yet.");
286
287 cerr << "SIMULATION::SOLVE: SET SOLVER..." << endl;
288 setSolver(solver);
289
290
291 cerr << "PRESOLVING SYSTEM...";
292 slv_presolve(sys);
293 cerr << "DONE" << endl;
294
295 cerr << "SOLVING SYSTEM..." << endl;
296 // Add some stuff here for cleverer iteration....
297 unsigned niter = 1000;
298 double updateinterval = 0.02;
299
300 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 for(int iter = 1; iter <= niter && !stop; ++iter){
307 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 cerr << "... DONE SOLVING SYSTEM" << endl;
324 }else{
325 ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"Solver failed");
326 }
327
328 cerr << "SOLVER PERFORMED " << status.iteration << " ITERATIONS IN " << (tm_cpu_time() - starttime) << "s" << endl;
329
330 if(status.iteration_limit_exceeded){
331 ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"Exceeded interation limit");
332 }
333
334 if(status.converged){
335 ERROR_REPORTER_NOLINE(ASC_USER_SUCCESS,"Solver converged: %d iterations, %3.2e s"
336 ,status.iteration,status.cpu_elapsed);
337 }else{
338 ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"Solver not converged after %d iterations.",status.iteration);
339 }
340
341 }
342
343 void
344 Simulation::write(){
345 simroot.write();
346 }
347
348 //------------------------------------------
349 // ASSIGNING SOLVER TO SIMULATION
350
351 void
352 Simulation::setSolver(Solver &solver){
353 cerr << "SETTING SOLVER ON SIMULATION TO " << solver.getName() << endl;
354
355 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 //cerr << "Simulation::setSolver: slv_select_solver returned " << selected << endl;
360
361 if(selected<0){
362 ERROR_REPORTER_NOLINE(ASC_PROG_ERROR,"Failed to select solver");
363 throw runtime_error("Failed to select solver");
364 }
365
366 if(selected!=solver.getIndex()){
367 solver = Solver(slv_solver_name(selected));
368 ERROR_REPORTER_NOLINE(ASC_PROG_NOTE,"Substitute solver '%s' (index %d) selected.\n", solver.getName().c_str(), selected);
369 }
370
371 if( slv_eligible_solver(sys) <= 0){
372 ERROR_REPORTER_NOLINE(ASC_PROG_ERROR,"Inelegible solver '%s'", solver.getName().c_str() );
373 throw runtime_error("Inelegible solver");
374 }
375 }
376
377 const Solver
378 Simulation::getSolver() const{
379 int index = slv_get_selected_solver(sys);
380 //cerr << "Simulation::getSolver: index = " << index << endl;
381 if(index<0)throw runtime_error("No solver selected");
382
383 return Solver(slv_solver_name(index));
384 }
385
386
387 /**
388 Get solver parameters struct wrapped up as a SolverParameters class.
389 */
390 SolverParameters
391 Simulation::getSolverParameters() const{
392 if(!sys)throw runtime_error("Can't solve: Simulation system has not been built yet.");
393
394 slv_parameters_t p;
395 slv_get_parameters(sys,&p);
396 return SolverParameters(p);
397 }
398

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