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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

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