05a5c4e8c60d723b15ebb2b0eaeb280a06d9c31e
[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
23   //**---- prepare from and to workspace stuff ( "From workspace" block )
24   xcos_workspace_init()
25
26  
27 //** extract tolerances from scs_m.props.tol
28   tolerances = scs_m.props.tol ;
29   //** extract solver type from tolerances
30   solver = tolerances(6) ; 
31   //** initialize a "scicos_debug_gr" variable
32   %scicos_debug_gr = %f;
33
34   ////////////////////////////////////////////////////////////////
35   // Add global environment variable so that scicos is not lost //
36   ////////////////////////////////////////////////////////////////
37   if needcompile == 4 then
38     %state0     = list();
39     needcompile = 4;
40     curwin      = 1000;
41     %cpr        = struct();
42     %tcur       = 0;
43     %cpr.state  = %state0;
44   else
45     %state0 = %cpr.state;
46     alreadyran = %f;
47   end
48   
49   tf          = scs_m.props.tf;
50   %zoom       = 1.4;
51   Select      = [];
52   
53   //** extract tolerances from scs_m.props.tol
54   tolerances = scs_m.props.tol ;
55   //** extract solver type from tolerances
56   solver = tolerances(6) ; 
57
58   // Propagate context through all blocks
59   %scicos_context = struct();
60   context = scs_m.props.context;
61   //** context eval here
62   [%scicos_context, ierr] = script2var(context, %scicos_context);
63   
64   //for backward compatibility for scifunc
65   if ierr==0 then
66     %mm = getfield(1,%scicos_context)
67     for %mi=%mm(3:$)
68       ierr = execstr(%mi+'=%scicos_context(%mi)','errcatch')
69       if ierr<>0 then
70         break; //** in case of error exit 
71       end
72     end
73   end
74   //end of for backward compatibility for scifuncpagate context values
75   
76   [scs_m,%cpr,needcompile,ok] = do_eval(scs_m, %cpr, %scicos_context);
77   if ~ok then
78     error(msprintf(gettext("%s: Error during block parameters evaluation.\n"), "xcos_simulate"));
79   end
80   
81   //** update parameters or compilation results
82   [%cpr,%state0_n,needcompile,alreadyran,ok] = do_update(%cpr,%state0,needcompile)
83   if ~ok then
84     error(msprintf(gettext("%s: Error during block parameters update.\n"), "xcos_simulate"));
85   end
86
87   //** if alreadyran then set the var choice
88   if alreadyran then
89     choix = ['Continue';'Restart';'End']
90   else
91     choix = [] ;
92   end
93
94   issequal = %t;
95   //** initial state has been changed
96   if ~isequal(%state0_n,%state0) then
97     issequal = %f
98   else
99     //** test typeof outtb element
100     for i=1:lstsize(%state0_n.outtb)
101       if typeof(%state0_n.outtb(i))<>typeof(%state0.outtb(i))
102         issequal = %f
103         break
104       end
105     end
106     //** test typeof oz element
107     for i=1:lstsize(%state0_n.oz)
108       if typeof(%state0_n.oz(i))<>typeof(%state0.oz(i))
109         issequal = %f
110         break
111       end
112     end
113   end
114
115   //** if state have changed
116   //** finish the simulation via do_terminate()
117   if ~issequal then
118      %state0 = %state0_n
119     [alreadyran,%cpr] = do_terminate()
120     choix = []
121   end
122
123   //** switch appropriate solver
124   if %cpr.sim.xptr($)-1<size(%cpr.state.x,'*') & solver<100 then
125     message(["Diagram has been compiled for implicit solver"
126              "switching to implicit Solver"])
127     solver = 100 ; //** Magic number 
128     tolerances(6) = solver ; //** save Magic number solver type
129   elseif (%cpr.sim.xptr($)-1==size(%cpr.state.x,'*')) & (solver==100 & size(%cpr.state.x,'*')<>0) then
130     message(["Diagram has been compiled for explicit solver"
131              "switching to explicit Solver"])
132     solver = 0 ; //** Magic number 
133     tolerances(6) = solver ; //** save Magic number solver type
134   end
135
136   //** ask user what to do
137   if choix<>[] then
138     //** open dialog box
139     to_do = choose(choix,"What do you want to do")
140
141     //** if cancel then exit
142     if to_do==0 then
143       ok = %f
144       return
145     end
146
147     select choix(to_do)
148
149       case "Continue" then 
150         needstart = %f ;
151         state     = %cpr.state ;
152
153       case "Restart" then 
154         needstart = %t ;
155         state     = %state0 ;
156
157       case "End" then 
158         state     = %cpr.state ;
159         needstart = %t ;
160         tf        = scs_m.props.tf;
161
162         //Alan: ONPEUTPASAPPELLERDOTERMINATEICI?
163         //reponse : non, car do_terminate() ne rend
164         //          pas forc�ment la main � l'utilisateur
165
166         //** run scicosim via 'finish' flag
167         ierr = execstr('[state,t]=scicosim(%cpr.state,%tcur,tf,%cpr.sim,'+..
168                        '''finish'',tolerances)','errcatch')
169
170         %cpr.state = state
171         alreadyran = %f
172
173         //** error case
174         if ierr<>0 then
175           str_err = split_lasterror(lasterror());
176           kfun    = curblock()
177           corinv  = %cpr.corinv
178
179           if kfun<>0 then //** block error
180             path = corinv(kfun)
181             //** get error cmd for the block
182             get_errorcmd(path,'End problem.',str_err);
183
184           else //** simulator error
185             message(["End problem:";str_err])
186             //scf(curwin);
187           end
188           ok = %f
189         end
190        
191         return
192     end
193   
194   else //** Normal first start simulation 
195
196     needstart = %t
197     state     = %state0
198
199   end
200
201   //gh_win = gcf();
202
203   //** scicos initialisation
204   if needstart then
205     //** if the simulation have already ran
206     //** and is not finished then call do_terminate
207     if alreadyran then
208       [alreadyran,%cpr] = do_terminate()
209       alreadyran = %f ;
210     end
211     //** set initial values for a new simulation
212     %tcur      = 0
213     %cpr.state = %state0
214     tf         = scs_m.props.tf;
215     if tf*tolerances==[] then 
216       message(["Simulation parameters not set";"use setup button"]);
217       return;
218     end
219
220     //** Run the normal first start simulation here 
221
222     //** run scicosim via 'start' flag
223     ierr = execstr('[state,t]=scicosim(%cpr.state,%tcur,tf,%cpr.sim,'+..
224                    '''start'',tolerances)','errcatch')
225
226     %cpr.state = state ; //** save the state 
227     //** error case
228     if ierr<>0 then
229       str_err=split_lasterror(lasterror());
230
231       kfun=curblock()
232       corinv=%cpr.corinv
233       if kfun<>0 then  //** block error
234         path=corinv(kfun)
235         //** get error cmd for the block
236         disp(str_err);
237         get_errorcmd(path,gettext('Initialisation problem'),str_err);
238         
239
240       else //** simulator error
241         message(['Initialisation problem:';str_err])
242         //scf(curwin);
243       end
244
245       ok = %f;
246       //xset('window',curwin)
247       return
248     end
249     //scf(gh_win);
250     //xset('window',win);
251   end
252
253   //** scicos simulation
254   //needreplay=%t
255   tf = scs_m.props.tf;
256   //setmenu(curwin,'Stop')
257   //timer()
258   needreplay = %t
259
260   //** run scicosim via 'start' flag
261   ierr = execstr('[state,t]=scicosim(%cpr.state,%tcur,tf,%cpr.sim,'+..
262                      '''run'',tolerances)','errcatch')
263
264   %cpr.state = state
265   
266   //** no error
267   if ierr==0 then
268     alreadyran = %t;
269     //** we are at the end of the simulation
270     //** finish the simulation via do_terminate()
271     if tf-t<tolerances(3) then
272       //disp('fin');
273       //Alan : j'enl�ve do_terminate ici car do_terminate
274       //       ne rend pas la main
275       //[alreadyran,%cpr]=do_terminate()
276       needstart  = %t;
277       alreadyran = %f;
278       //** run scicosim via 'finish' flag
279       ierr = execstr('[state,t]=scicosim(%cpr.state,tf,tf,%cpr.sim,'+..
280                      '''finish'',tolerances)','errcatch')
281
282       %cpr.state = state;
283
284       //** error case
285       if ierr<>0 then
286         str_err = split_lasterror(lasterror());
287
288         kfun   = curblock()
289         corinv = %cpr.corinv
290
291         if kfun<>0 then //** block error
292           path = corinv(kfun)
293           //** get error cmd for the block
294           get_errorcmd(path,gettext('End problem'),str_err);
295         else //** simulator error
296           message(['End problem:';str_err])
297           //scf(curwin);
298         end
299       end
300     else
301       %tcur = t;
302     end
303   //** error case
304   else
305     str_err = split_lasterror(lasterror());
306
307     alreadyran = %f;
308     kfun       = curblock();
309     corinv     = %cpr.corinv;
310
311     if kfun<>0 then //** block error
312       path = corinv(kfun);
313       //** get error cmd for the block
314       get_errorcmd(path,gettext("Simulation problem"),str_err);
315     else //** simulateur error
316       message(['Simulation problem:';str_err])
317       //scf(curwin);
318     end
319     ok = %f;
320   end
321   
322   //restore saved variables in Scilab environment ( "To workspace" block )
323   [txt,files]=returntoscilab()
324   n=size(files,1)
325   for i=1:n
326     load(TMPDIR+'/Workspace/'+files(i))
327     execstr(files(i)+'=struct('"values'",x,'"time'",t)')
328   end
329   execstr(txt)
330
331   needreplay = resume(needreplay);
332 endfunction
333