Load Scilab libs adapted to Scilab 5 modules organization.
[scilab.git] / scilab / modules / scicos / macros / scicos_auto / scicos_simulate.sci
1 //  Scicos
2 //
3 //  Copyright (C) INRIA - METALAU Project <scicos@inria.fr>
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2 of the License, or
8 // (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 //
19 // See the file ./license.txt
20 //
21
22 function Info=scicos_simulate(scs_m,Info,%scicos_context,flag,Ignb)
23 // Function for running scicos simulation in batch mode
24 // Info=scicos_simulate(scs_m[,Info][,%scicos_context][,flag]...
25 //                      [,Ignb])
26 //
27 // scs_m: scicos diagram (obtained by "load file.cos"). Note that
28 // the version of file.cos must be the current version. If not, load
29 // into scicos and save.
30 //
31 // %scicos_context: a scilab struct containing values of
32 // symbolic variables used in the context and Scicos blocks. This
33 // is often used to change a parameter in the diagram context. In that
34 // case, make sure that in the diagram context the variable is defined such
35 // that it can be modified. Say a variable "a" is to be defined in the
36 // context having value 1, and later in batch mode, we want to change
37 // the value of "a". In that case, in the context of the diagram place:
38 //  if ~exists('a') then a=1,end
39 // If you want then to run the simulation in batch mode using the value
40 // a=2, set:
41 // %scicos_context.a=2
42 //
43 // Info: a list. It must be list() at the first call, then use output
44 // Info as input Info for the next calls. Info contains compilation and
45 // simulation information and is used to avoid recompilation when not
46 // needed.
47 //
48 // flag: string. If it equals 'nw' (no window), then blocks using
49 // graphical windows are not executed. Note that the list of such
50 // blocks must be updated as new blocks are added.
51 //
52 // Ignb : matrix of string : The name of blocks to ignore.
53 // If flag is set and equal to 'nw' then Ignb contains
54 // name of blocks that are added to the list
55 // of blocks to ignore.
56 //
57
58   noguimode=find(sciargs()=="-nogui");
59   if (noguimode <>[]) then
60      clear noguimode
61      flag='nw'
62   //    warning(" Scilab in no gui mode : Scicos unavailable");
63   //    abort;
64   end;
65   clear noguimode
66
67   //** define Scicos data tables
68   if (~isdef("scicos_pal") | ~isdef("%scicos_menu") | ..
69       ~isdef("%scicos_short") | ~isdef("%scicos_help") | ..
70       ~isdef("%scicos_display_mode") | ~isdef("modelica_libs") | ..
71       ~isdef("scicos_pal_libs") | ~isdef("%scicos_gif") | ..
72       ~isdef("%scicos_contrib") ) then
73          [scicos_pal,%scicos_menu,...
74           %scicos_short,%scicos_help,..
75           %scicos_display_mode,modelica_libs,..
76           scicos_pal_libs,%scicos_gif,..
77           %scicos_contrib]=initial_scicos_tables()
78          clear initial_scicos_tables
79   end
80
81   //** initialize a "scicos_debug_gr" variable
82   %scicos_debug_gr = %f;
83
84   //** list of scopes to ignore
85   Ignoreb=['bouncexy',...
86            'cscope',...
87            'cmscope',...
88            'canimxy',...
89            'canimxy3d',...
90            'cevscpe',...
91            'cfscope',...
92            'cscopexy',...
93            'cscopexy3d',...
94            'cmatview',...
95            'cmat3d',...
96            'affich',...
97            'affich2']
98
99   //** load macros libraries and palettes
100   // Scilab 5 new modules split
101   load('SCI/modules/scicos/macros/scicos_auto/lib')
102   load('SCI/modules/scicos/macros/scicos_utils/lib')
103   load('SCI/modules/scicos/macros/scicos_scicos/lib')
104
105   exec(loadpallibs,-1)
106
107   //** redefine some gui functions
108   prot=funcprot();funcprot(0);
109   deff('disablemenus()',' ')
110   deff('enablemenus()',' ')
111   do_terminate=do_terminate1
112   funcprot(prot)
113
114   //** check/set rhs parameters
115   if argn(2)==1 then
116     Info=list()
117     %scicos_context=struct()
118     flag=[]
119     Ignb=[]
120   elseif argn(2)==2 then
121     if type(Info)==10&(stripblanks(Info)=='nw') then
122       Info=list()
123       flag='nw'
124     elseif type(Info)<>15 then
125       Info=list()
126       flag=[]
127     else
128       flag=[]
129     end
130     %scicos_context=struct()
131     Ignb=[]
132   elseif argn(2)==3 then
133     if type(Info)<>15 then
134       Info=list()
135     end
136     if type(%scicos_context)==10&(stripblanks(%scicos_context)=='nw') then
137       %scicos_context=struct()
138       flag='nw'
139     elseif type(%scicos_context)<>17 then
140       %scicos_context=struct()
141       flag=[]
142     else
143       flag=[]
144     end
145     Ignb=[]
146   elseif argn(2)==4 then
147     if type(Info)<>15 then
148       Info=list()
149     end
150     if type(%scicos_context)<>17 then
151       %scicos_context=struct()
152     end
153     if type(flag)<>10 then
154      flag=[]
155     elseif (stripblanks(flag)<>'nw') then
156        flag=[]
157     end
158     Ignb=[]
159   elseif argn(2)==5 then
160     if type(Info)<>15 then
161       Info=list()
162     end
163     if type(%scicos_context)<>17 then
164       %scicos_context=struct()
165     end
166     if type(flag)<>10 then
167       flag=[]
168     elseif (stripblanks(flag)<>'nw') then
169       flag=[]
170     end
171     if type(Ignb)<>10 then
172       Ignb=[]
173     else
174       Ignb=(Ignb(:))'
175     end
176   else
177      error('scicos_simulate : wrong number of parameters.')
178   end
179
180   //check version
181   current_version = get_scicos_version()
182   scicos_ver = find_scicos_version(scs_m)
183
184   //do version
185   if scicos_ver<>current_version then
186     ierr=execstr('scs_m=do_version(scs_m,scicos_ver)','errcatch')
187     if ierr<>0 then
188       message("Can''t convert old diagram (problem in version)")
189       return
190     end
191   end
192
193   //prepare from and to workspace stuff
194   curdir=getcwd()
195   chdir(TMPDIR)
196   mkdir('Workspace')
197   chdir('Workspace')
198   %a=who('get');
199   %a=%a(1:$-predef()+1);  // exclude protected variables
200   for %ij=1:size(%a,1)
201     var=%a(%ij)
202     if var<>'ans' & typeof(evstr(var))=='st' then
203       ierr=execstr('x='+var+'.values','errcatch')
204       if ierr==0 then
205         ierr=execstr('t='+var+'.time','errcatch')
206       end
207       if ierr==0 then
208         execstr('save('"'+var+''",x,t)')
209       end
210     end
211   end
212   chdir(curdir)
213   // end of /prepare from and to workspace stuff
214
215   Ignore=[]
216
217   if flag=='nw' then
218     Ignore=Ignoreb
219   end
220
221   if Ignb<>[] then
222     Ignore=[Ignore,Ignb]
223   end
224
225   //** retrieve Info list
226   if Info<>list() then
227     [%tcur,%cpr,alreadyran,needstart,needcompile,%state0]=Info(:)
228   else
229     %tcur=0;%cpr=list();alreadyran=%f;needstart=%t;needcompile=4;%state0=list();
230   end
231
232   //** set solver
233   tolerances=scs_m.props.tol
234   solver=tolerances(6)
235   %scicos_solver=solver
236
237   //** set variables of context
238   [%scicos_context,ierr]=script2var(scs_m.props.context, ...
239                                     %scicos_context);
240
241   if ierr==0 then
242     [scs_m,%cpr,needcompile,ok]=do_eval(scs_m,%cpr)
243     if needcompile<>4&size(%cpr)>0 then %state0=%cpr.state,end
244     alreadyran=%f
245   else
246       error(['Incorrect context definition, '+lasterror()] )
247   end
248
249   if %cpr==list() then need_suppress=%t, else need_suppress=%f,end
250
251   [%cpr,%state0_n,needcompile,alreadyran,ok]=..
252       do_update(%cpr,%state0,needcompile)
253   if ~ok then error('Error updating parameters.'),end
254
255   if or(%state0_n<>%state0) then //initial state has been changed
256     %state0=%state0_n
257     [alreadyran,%cpr]=do_terminate1(scs_m,%cpr)
258     choix=[]
259   end
260   if %cpr.sim.xptr($)-1<size(%cpr.state.x,'*') & solver<100 then
261     warning(['Diagram has been compiled for implicit solver'
262              'switching to implicit Solver'])
263     solver=100
264     tolerances(6)=solver
265   elseif (%cpr.sim.xptr($)-1==size(%cpr.state.x,'*')) & ..
266         ( solver==100 & size(%cpr.state.x,'*')<>0) then
267     warning(['Diagram has been compiled for explicit solver'
268              'switching to explicit Solver'])
269     solver=0
270     tolerances(6)=solver
271   end
272
273   if need_suppress then //this is done only once
274     for i=1:length(%cpr.sim.funs)
275       if type(%cpr.sim.funs(i))<>13 then
276         if find(%cpr.sim.funs(i)(1)==Ignore)<>[] then
277           %cpr.sim.funs(i)(1)='trash';
278         end
279       end
280     end
281   end
282
283   if needstart then //scicos initialisation
284     if alreadyran then
285       [alreadyran,%cpr]=do_terminate1(scs_m,%cpr)
286       alreadyran=%f
287     end
288     %tcur=0
289     %cpr.state=%state0
290     tf=scs_m.props.tf;
291     if tf*tolerances==[] then
292       error(['Simulation parameters not set']);
293     end
294
295     ierr=execstr('[state,t]=scicosim(%cpr.state,%tcur,tf,%cpr.sim,'+..
296                  '''start'',tolerances)','errcatch')
297     if ierr<>0 then
298       error(['Initialisation problem:'])
299     end
300     %cpr.state=state
301   end
302
303   ierr=execstr('[state,t]=scicosim(%cpr.state,%tcur,tf,%cpr.sim,'+..
304                '''run'',tolerances)','errcatch')
305
306   if ierr==0 then
307     %cpr.state=state
308     alreadyran=%t
309     if tf-t<tolerances(3) then
310       needstart=%t
311       [alreadyran,%cpr]=do_terminate1(scs_m,%cpr)
312     else
313       %tcur=t
314     end
315   else
316     error(['Simulation problem:';lasterror()])
317   end
318
319   Info=list(%tcur,%cpr,alreadyran,needstart,needcompile,%state0)
320
321   [txt,files]=returntoscilab()
322   n=size(files,1)
323   for i=1:n
324     load(TMPDIR+'/Workspace/'+files(i))
325     execstr(files(i)+'=struct('"values'",x,'"time'",t)')
326   end
327   execstr(txt)
328 endfunction
329
330 function [alreadyran,%cpr]=do_terminate1(scs_m,%cpr)
331 // Copyright INRIA
332
333   if prod(size(%cpr))<2 then   alreadyran=%f,return,end
334   par=scs_m.props;
335
336   if alreadyran then
337     alreadyran=%f
338     //terminate current simulation
339     ierr=execstr('[state,t]=scicosim(%cpr.state,par.tf,par.tf,'+..
340                  '%cpr.sim,''finish'',par.tol)','errcatch')
341
342     %cpr.state=state
343     if ierr<>0 then
344       error(['End problem:';lasterror()])
345     end
346   end
347 endfunction