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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 230 - (show annotations) (download) (as text)
Sun Jan 29 07:16:06 2006 UTC (14 years, 5 months ago) by johnpye
File MIME type: text/x-c++src
File size: 14264 byte(s)
Solverparameters GUI code split into separate file.
Help launcher started, will need more work.
Corrected wrong cpu_elapsed values in GUI by direct use of tm_cpu_time()
Added 'about' box.
Fixed 'auto' menu option.
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 double elapsed = tm_cpu_time() - starttime;
322
323 if(status.ok){
324 cerr << "... DONE SOLVING SYSTEM" << endl;
325 }else{
326 ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"Solver failed");
327 }
328
329 cerr << "SOLVER PERFORMED " << status.iteration << " ITERATIONS IN " << elapsed << "s" << endl;
330
331 if(status.iteration_limit_exceeded){
332 ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"Exceeded interation limit");
333 }
334
335 if(status.converged){
336 ERROR_REPORTER_NOLINE(ASC_USER_SUCCESS,"Solver converged: %d iterations (%.2f s)"
337 ,status.iteration,elapsed);
338 }else{
339 ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"Solver not converged after %d iterations (%.2f s).",status.iteration,elapsed);
340 }
341
342 }
343
344 void
345 Simulation::write(){
346 simroot.write();
347 }
348
349 //------------------------------------------
350 // ASSIGNING SOLVER TO SIMULATION
351
352 void
353 Simulation::setSolver(Solver &solver){
354 cerr << "SETTING SOLVER ON SIMULATION TO " << solver.getName() << endl;
355
356 if(!sys)throw runtime_error("Can't solve: Simulation system has not been built yet.");
357 // Update the solver object because sometimes an alternative solver can be returned, apparently.
358
359 int selected = slv_select_solver(sys, solver.getIndex());
360 //cerr << "Simulation::setSolver: slv_select_solver returned " << selected << endl;
361
362 if(selected<0){
363 ERROR_REPORTER_NOLINE(ASC_PROG_ERROR,"Failed to select solver");
364 throw runtime_error("Failed to select solver");
365 }
366
367 if(selected!=solver.getIndex()){
368 solver = Solver(slv_solver_name(selected));
369 ERROR_REPORTER_NOLINE(ASC_PROG_NOTE,"Substitute solver '%s' (index %d) selected.\n", solver.getName().c_str(), selected);
370 }
371
372 if( slv_eligible_solver(sys) <= 0){
373 ERROR_REPORTER_NOLINE(ASC_PROG_ERROR,"Inelegible solver '%s'", solver.getName().c_str() );
374 throw runtime_error("Inelegible solver");
375 }
376 }
377
378 const Solver
379 Simulation::getSolver() const{
380 int index = slv_get_selected_solver(sys);
381 //cerr << "Simulation::getSolver: index = " << index << endl;
382 if(index<0)throw runtime_error("No solver selected");
383
384 return Solver(slv_solver_name(index));
385 }
386
387
388 /**
389 Get solver parameters struct wrapped up as a SolverParameters class.
390 */
391 SolverParameters
392 Simulation::getSolverParameters() const{
393 if(!sys)throw runtime_error("Can't getSolverParameters: Simulation system has not been built yet.");
394
395 slv_parameters_t p;
396 slv_get_parameters(sys,&p);
397 return SolverParameters(p);
398 }
399
400 /**
401 Update the solver parameters by passing a new set back
402 */
403 void
404 Simulation::setSolverParameters(SolverParameters &P){
405 if(!sys)throw runtime_error("Can't set solver parameters: simulation has not been built yet.");
406 slv_set_parameters(sys, &(P.getInternalType()));
407 }
408

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