Indenting scicos_simulate and xcos_simulate
[scilab.git] / scilab / modules / xcos / macros / xcos_simulate.sci
1 //
2 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 // Copyright (C) 2009-2009 - DIGITEO - Bruno JOFRET
4 //
5 // This file must be used under the terms of the CeCILL.
6 // This source file is licensed as described in the file COPYING, which
7 // you should have received as part of this distribution.  The terms
8 // are also available at
9 // http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
10 //
11 //
12
13 function %cpr = xcos_simulate(scs_m, needcompile)
14
15     // Load the block libs if not defined
16     prot = funcprot();
17     funcprot(0);
18     if ~exists("scicos_diagram") then
19         loadXcosLibs();
20     end
21     funcprot(prot);
22     [modelica_libs, scicos_pal_libs, %scicos_with_grid, %scs_wgrid] = initial_scicos_tables();
23
24     // Hook according to SEP066
25     function [ok]=invoke_pre_simulate(fun, scs_m, needcompile)
26         ok=%f;
27         ierr=execstr("[continueSimulation]="+fun+"(scs_m, needcompile);", "errcatch");
28         if ierr<>0 then
29             disp(_("Error occurred in pre_xcos_simulate: Cancelling simulation."));
30             [str,n,line,func]=lasterror();
31             mprintf(" at line %d of function %s\n", line, func);
32             return
33         end
34         if ~continueSimulation then
35             return
36         end
37         ok=%t;
38
39         // force update on the parent in case of scoped modification
40         scs_m=resume(scs_m);
41     endfunction
42
43     if isdef("pre_xcos_simulate") then
44         if type(pre_xcos_simulate) == 15 then
45             // if has a multiple implementation (on a list)
46             for f=pre_xcos_simulate;
47                 ok=invoke_pre_simulate(f, scs_m, needcompile);
48                 if ~ok then
49                     %cpr=[];
50                     return;
51                 end
52             end
53         else
54             // if has a unique implementation
55             ok=invoke_pre_simulate("pre_xcos_simulate", scs_m, needcompile);
56             if ~ok then
57                 %cpr=[];
58                 return;
59             end
60         end
61     end
62
63     //**---- prepare from and to workspace stuff ( "From workspace" block )
64     scicos_workspace_init()
65
66
67     //** extract tolerances from scs_m.props.tol
68     tolerances = scs_m.props.tol ;
69     //** extract solver type from tolerances
70     solver = tolerances(6) ;
71     //** initialize a "scicos_debug_gr" variable
72     %scicos_debug_gr = %f;
73
74     ////////////////////////////////////////////////////////////////
75     // Add global environment variable so that scicos is not lost //
76     ////////////////////////////////////////////////////////////////
77     if needcompile == 4 then
78         %state0     = list();
79         needcompile = 4;
80         curwin      = 1000;
81         %cpr        = struct();
82         %tcur       = 0;
83         %cpr.state  = %state0;
84         alreadyran = %f;
85     else
86         %state0 = %cpr.state;
87         alreadyran = %f;
88     end
89
90     tf          = scs_m.props.tf;
91     %zoom       = 1.4;
92     Select      = [];
93
94     //** extract tolerances from scs_m.props.tol
95     tolerances = scs_m.props.tol ;
96     //** extract solver type from tolerances
97     solver = tolerances(6) ;
98
99     // Propagate context through all blocks
100     %scicos_context = struct();
101     context = scs_m.props.context;
102     //** context eval here
103     [%scicos_context, ierr] = script2var(context, %scicos_context);
104
105     //for backward compatibility for scifunc
106     if ierr==0 then
107         %mm = getfield(1,%scicos_context)
108         for %mi=%mm(3:$)
109             ierr = execstr(%mi+"=%scicos_context(%mi)","errcatch")
110             if ierr<>0 then
111                 break; //** in case of error exit
112             end
113         end
114     end
115     //end of for backward compatibility for scifuncpagate context values
116
117     [scs_m,%cpr,needcompile,ok] = do_eval(scs_m, %cpr, %scicos_context);
118     if ~ok then
119         msg = msprintf(gettext("%s: Error during block parameters evaluation.\n"), "Xcos");
120         messagebox(msg, "Xcos", "error");
121         error(msprintf(gettext("%s: Error during block parameters evaluation.\n"), "xcos_simulate"));
122     end
123
124     //** update parameters or compilation results
125     [%cpr,%state0_n,needcompile,alreadyran,ok] = do_update(%cpr,%state0,needcompile)
126     if ~ok then
127         error(msprintf(gettext("%s: Error during block parameters update.\n"), "xcos_simulate"));
128     end
129
130     //** if alreadyran then set the var choice
131     if alreadyran then
132         choix = ["Continue";"Restart";"End"]
133     else
134         choix = [] ;
135     end
136
137     issequal = %t;
138     //** initial state has been changed
139     if ~isequal(%state0_n,%state0) then
140         issequal = %f
141     else
142         //** test typeof outtb element
143         for i=1:lstsize(%state0_n.outtb)
144             if typeof(%state0_n.outtb(i))<>typeof(%state0.outtb(i))
145                 issequal = %f
146                 break
147             end
148         end
149         //** test typeof oz element
150         for i=1:lstsize(%state0_n.oz)
151             if typeof(%state0_n.oz(i))<>typeof(%state0.oz(i))
152                 issequal = %f
153                 break
154             end
155         end
156     end
157
158     //** if state have changed
159     //** finish the simulation via do_terminate()
160     if ~issequal then
161         %state0 = %state0_n
162         [alreadyran,%cpr] = do_terminate()
163         choix = []
164     end
165
166     //** switch appropriate solver
167     if %cpr.sim.xptr($)-1<size(%cpr.state.x,"*") & solver<100 then
168         warning(["Diagram has been compiled for implicit solver"
169         "switching to implicit Solver"])
170         solver = 100 ; //** Magic number
171         tolerances(6) = solver ; //** save Magic number solver type
172     elseif (%cpr.sim.xptr($)-1==size(%cpr.state.x,"*")) & (solver==100 & size(%cpr.state.x,"*")<>0) then
173         message(["Diagram has been compiled for explicit solver"
174         "switching to explicit Solver"])
175         solver = 0 ; //** Magic number
176         tolerances(6) = solver ; //** save Magic number solver type
177     end
178
179     //** ask user what to do
180     if choix<>[] then
181         //** open dialog box
182         to_do = choose(choix,"What do you want to do")
183
184         //** if cancel then exit
185         if to_do==0 then
186             ok = %f
187             return
188         end
189
190         select choix(to_do)
191
192         case "Continue" then
193             needstart = %f ;
194             state     = %cpr.state ;
195
196         case "Restart" then
197             needstart = %t ;
198             state     = %state0 ;
199
200         case "End" then
201             state     = %cpr.state ;
202             needstart = %t ;
203             tf        = scs_m.props.tf;
204
205             //Alan: Cannot call do_terminate() here ?
206             //Answer: No, because do_terminate() doesn't
207             //          return control to the user
208
209             //** run scicosim via 'finish' flag
210             ierr = execstr("[state,t]=scicosim(%cpr.state,%tcur,tf,%cpr.sim,"+..
211             "''finish'',tolerances)","errcatch")
212
213             %cpr.state = state
214             alreadyran = %f
215
216             //** error case
217             if ierr<>0 then
218                 str_err = split_lasterror(lasterror());
219                 kfun    = curblock()
220                 corinv  = %cpr.corinv
221
222                 if kfun<>0 then //** block error
223                     path = corinv(kfun)
224                     //** get error cmd for the block
225                     get_errorcmd(path,"End problem.",str_err);
226
227                 else //** simulator error
228                     message(["End problem:";str_err])
229                     //scf(curwin);
230                 end
231                 ok = %f
232             end
233
234             return
235         end
236
237     else //** Normal first start simulation
238
239         needstart = %t
240         state     = %state0
241
242     end
243
244     //gh_win = gcf();
245
246     //** scicos initialization
247     if needstart then
248         //** if the simulation has already run
249         //** and is not finished then call do_terminate
250         if alreadyran then
251             [alreadyran,%cpr] = do_terminate()
252             alreadyran = %f ;
253         end
254         //** set initial values for a new simulation
255         %tcur      = 0
256         %cpr.state = %state0
257         tf         = scs_m.props.tf;
258         if tf*tolerances==[] then
259             message(["Simulation parameters not set";"use setup button"]);
260             return;
261         end
262
263         //** Run the normal first start simulation here
264
265         //** run scicosim via 'start' flag
266         ierr = execstr("[state,t]=scicosim(%cpr.state,%tcur,tf,%cpr.sim,"+..
267         "''start'',tolerances)","errcatch")
268
269         %cpr.state = state ; //** save the state
270         //** error case
271         if ierr<>0 then
272             str_err=split_lasterror(lasterror());
273
274             kfun=curblock()
275             corinv=%cpr.corinv
276             if kfun<>0 then  //** block error
277                 path=corinv(kfun)
278                 //** get error cmd for the block
279                 disp(str_err);
280                 get_errorcmd(path,gettext("Initialisation problem"),str_err);
281
282
283             else //** simulator error
284                 message(["Initialisation problem:";str_err])
285                 //scf(curwin);
286             end
287
288             ok = %f;
289             //xset('window',curwin)
290             return
291         end
292         //scf(gh_win);
293         //xset('window',win);
294     end
295
296     //** scicos simulation
297     tf = scs_m.props.tf
298
299     // inform Xcos the simulator is going to run
300     xcosSimulationStarted();
301
302     //** run scicosim via 'start' flag
303     ierr = execstr("[state,t]=scicosim(%cpr.state,%tcur,tf,%cpr.sim,"+..
304     "''run'',tolerances)","errcatch")
305
306     %cpr.state = state
307
308     //** no error
309     if ierr==0 then
310         alreadyran = %t;
311         //** we are at the end of the simulation
312         //** finish the simulation via do_terminate()
313         if tf-t<tolerances(3) then
314             //disp('fin');
315             //Alan : removing do_terminate() here because it
316             //       doesn't return control
317             //[alreadyran,%cpr]=do_terminate()
318             needstart  = %t;
319             alreadyran = %f;
320             //** run scicosim via 'finish' flag
321             ierr = execstr("[state,t]=scicosim(%cpr.state,tf,tf,%cpr.sim,"+..
322             "''finish'',tolerances)","errcatch")
323
324             %cpr.state = state;
325
326             //** error case
327             if ierr<>0 then
328                 str_err = split_lasterror(lasterror());
329
330                 kfun   = curblock()
331                 corinv = %cpr.corinv
332
333                 if kfun<>0 then //** block error
334                     path = corinv(kfun)
335                     //** get error cmd for the block
336                     get_errorcmd(path,gettext("End problem"),str_err);
337                 else //** simulator error
338                     message(["End problem:";str_err])
339                     //scf(curwin);
340                 end
341             end
342         else
343             %tcur = t;
344         end
345         //** error case
346     else
347         str_err = split_lasterror(lasterror());
348
349         alreadyran = %f;
350         kfun       = curblock();
351         corinv     = %cpr.corinv;
352
353         if kfun<>0 then //** block error
354             path = corinv(kfun);
355             //** get error cmd for the block
356             get_errorcmd(path,gettext("Simulation problem"),str_err);
357         else //** simulator error
358             message(["Simulation problem:";str_err])
359             //scf(curwin);
360         end
361         ok = %f;
362     end
363
364     //restore saved variables in Scilab environment ( "To workspace" block )
365     [txt,files]=returntoscilab()
366     n=size(files,1)
367     for i=1:n
368         load(TMPDIR+"/Workspace/"+files(i))
369         ierr = execstr(files(i)+"=struct('"values'",x,'"time'",t)", "errcatch")
370         if ierr <> 0
371             str_err = split_lasterror(lasterror());
372             message(["Simulation problem:";str_err]);
373         end
374
375     end
376
377     // Hook according to SEP066
378     function ok=invoke_post_simulate(fun, %cpr, scs_m, needcompile)
379         ok=%f;
380         ierr=execstr(fun+"(%cpr, scs_m, needcompile);", "errcatch");
381         if ierr<>0 then
382             disp(_("Error in post_xcos_simulate: ending simulation."))
383             return
384         end
385         ok=%t
386         // force update on the parent in case of scoped modification
387         scs_m=resume(scs_m);
388     endfunction
389
390     if isdef("post_xcos_simulate") then
391         if type(post_xcos_simulate) == 15 then
392             // if has a multiple implementation (on a list)
393             for f=post_xcos_simulate;
394                 ok=invoke_post_simulate(f, scs_m, needcompile);
395                 if ~ok then
396                     %cpr=[];
397                     return;
398                 end
399             end
400         else
401             // if has a unique implementation
402             ok=invoke_post_simulate("post_xcos_simulate", %cpr, scs_m, needcompile);
403             if ~ok then
404                 %cpr=[];
405                 return;
406             end
407         end
408     end
409
410     // finally restore the exported variables on the parent context
411     if ~isempty(txt) then
412         ierr = execstr(txt, "errcatch")
413         if ierr <> 0 then
414             str_err = split_lasterror(lasterror());
415             message(["Simulation problem while executing <"+txt+">:";str_err]);
416         end
417     end
418 endfunction
419