copy SCI/macros/auto to SCI/modules/scicos/macros/scicos_auto
[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   load SCI/macros/scicos/lib
101   exec(loadpallibs,-1)
102
103   //** redefine some gui functions
104   prot=funcprot();funcprot(0);
105   deff('disablemenus()',' ')
106   deff('enablemenus()',' ')
107   do_terminate=do_terminate1
108   funcprot(prot)
109
110   //** check/set rhs parameters
111   if argn(2)==1 then
112     Info=list()
113     %scicos_context=struct()
114     flag=[]
115     Ignb=[]
116   elseif argn(2)==2 then
117     if type(Info)==10&(stripblanks(Info)=='nw') then
118       Info=list()
119       flag='nw'
120     elseif type(Info)<>15 then
121       Info=list()
122       flag=[]
123     else
124       flag=[]
125     end
126     %scicos_context=struct()
127     Ignb=[]
128   elseif argn(2)==3 then
129     if type(Info)<>15 then
130       Info=list()
131     end
132     if type(%scicos_context)==10&(stripblanks(%scicos_context)=='nw') then
133       %scicos_context=struct()
134       flag='nw'
135     elseif type(%scicos_context)<>17 then
136       %scicos_context=struct()
137       flag=[]
138     else
139       flag=[]
140     end
141     Ignb=[]
142   elseif argn(2)==4 then
143     if type(Info)<>15 then
144       Info=list()
145     end
146     if type(%scicos_context)<>17 then
147       %scicos_context=struct()
148     end
149     if type(flag)<>10 then
150      flag=[]
151     elseif (stripblanks(flag)<>'nw') then
152        flag=[]
153     end
154     Ignb=[]
155   elseif argn(2)==5 then
156     if type(Info)<>15 then
157       Info=list()
158     end
159     if type(%scicos_context)<>17 then
160       %scicos_context=struct()
161     end
162     if type(flag)<>10 then
163       flag=[]
164     elseif (stripblanks(flag)<>'nw') then
165       flag=[]
166     end
167     if type(Ignb)<>10 then
168       Ignb=[]
169     else
170       Ignb=(Ignb(:))'
171     end
172   else
173      error('scicos_simulate : wrong number of parameters.')
174   end
175
176   //check version
177   current_version = get_scicos_version()
178   scicos_ver = find_scicos_version(scs_m)
179
180   //do version
181   if scicos_ver<>current_version then
182     ierr=execstr('scs_m=do_version(scs_m,scicos_ver)','errcatch')
183     if ierr<>0 then
184       message("Can''t convert old diagram (problem in version)")
185       return
186     end
187   end
188
189   //prepare from and to workspace stuff
190   curdir=getcwd()
191   chdir(TMPDIR)
192   mkdir('Workspace')
193   chdir('Workspace')
194   %a=who('get');
195   %a=%a(1:$-predef()+1);  // exclude protected variables
196   for %ij=1:size(%a,1) 
197     var=%a(%ij)
198     if var<>'ans' & typeof(evstr(var))=='st' then
199       ierr=execstr('x='+var+'.values','errcatch')
200       if ierr==0 then
201         ierr=execstr('t='+var+'.time','errcatch')
202       end
203       if ierr==0 then
204         execstr('save('"'+var+''",x,t)')
205       end
206     end
207   end
208   chdir(curdir)
209   // end of /prepare from and to workspace stuff
210
211   Ignore=[]
212
213   if flag=='nw' then
214     Ignore=Ignoreb
215   end
216
217   if Ignb<>[] then
218     Ignore=[Ignore,Ignb]
219   end
220
221   //** retrieve Info list
222   if Info<>list() then
223     [%tcur,%cpr,alreadyran,needstart,needcompile,%state0]=Info(:)
224   else
225     %tcur=0;%cpr=list();alreadyran=%f;needstart=%t;needcompile=4;%state0=list();
226   end
227
228   //** set solver
229   tolerances=scs_m.props.tol
230   solver=tolerances(6)
231   %scicos_solver=solver
232
233   //** set variables of context
234   [%scicos_context,ierr]=script2var(scs_m.props.context, ...
235                                     %scicos_context);
236
237   if ierr==0 then 
238     [scs_m,%cpr,needcompile,ok]=do_eval(scs_m,%cpr)
239     if needcompile<>4&size(%cpr)>0 then %state0=%cpr.state,end
240     alreadyran=%f
241   else
242       error(['Incorrect context definition, '+lasterror()] )
243   end
244
245   if %cpr==list() then need_suppress=%t, else need_suppress=%f,end
246
247   [%cpr,%state0_n,needcompile,alreadyran,ok]=..
248       do_update(%cpr,%state0,needcompile)
249   if ~ok then error('Error updating parameters.'),end
250
251   if or(%state0_n<>%state0) then //initial state has been changed
252     %state0=%state0_n
253     [alreadyran,%cpr]=do_terminate1(scs_m,%cpr)
254     choix=[]
255   end
256   if %cpr.sim.xptr($)-1<size(%cpr.state.x,'*') & solver<100 then
257     warning(['Diagram has been compiled for implicit solver'
258              'switching to implicit Solver'])
259     solver=100
260     tolerances(6)=solver
261   elseif (%cpr.sim.xptr($)-1==size(%cpr.state.x,'*')) & ..
262         ( solver==100 & size(%cpr.state.x,'*')<>0) then
263     warning(['Diagram has been compiled for explicit solver'
264              'switching to explicit Solver'])
265     solver=0
266     tolerances(6)=solver
267   end
268
269   if need_suppress then //this is done only once
270     for i=1:length(%cpr.sim.funs)
271       if type(%cpr.sim.funs(i))<>13 then
272         if find(%cpr.sim.funs(i)(1)==Ignore)<>[] then
273           %cpr.sim.funs(i)(1)='trash';
274         end
275       end
276     end
277   end
278
279   if needstart then //scicos initialisation
280     if alreadyran then
281       [alreadyran,%cpr]=do_terminate1(scs_m,%cpr)
282       alreadyran=%f
283     end
284     %tcur=0
285     %cpr.state=%state0
286     tf=scs_m.props.tf;
287     if tf*tolerances==[] then 
288       error(['Simulation parameters not set']);
289     end
290
291     ierr=execstr('[state,t]=scicosim(%cpr.state,%tcur,tf,%cpr.sim,'+..
292                  '''start'',tolerances)','errcatch')
293     if ierr<>0 then
294       error(['Initialisation problem:'])
295     end
296     %cpr.state=state
297   end
298
299   ierr=execstr('[state,t]=scicosim(%cpr.state,%tcur,tf,%cpr.sim,'+..
300                '''run'',tolerances)','errcatch')
301
302   if ierr==0 then
303     %cpr.state=state
304     alreadyran=%t
305     if tf-t<tolerances(3) then
306       needstart=%t
307       [alreadyran,%cpr]=do_terminate1(scs_m,%cpr)
308     else
309       %tcur=t
310     end
311   else
312     error(['Simulation problem:';lasterror()])
313   end
314
315   Info=list(%tcur,%cpr,alreadyran,needstart,needcompile,%state0)
316
317   [txt,files]=returntoscilab()
318   n=size(files,1)
319   for i=1:n
320     load(TMPDIR+'/Workspace/'+files(i))
321     execstr(files(i)+'=struct('"values'",x,'"time'",t)')
322   end
323   execstr(txt)
324 endfunction
325
326 function [alreadyran,%cpr]=do_terminate1(scs_m,%cpr)
327 // Copyright INRIA
328
329   if prod(size(%cpr))<2 then   alreadyran=%f,return,end
330   par=scs_m.props;
331
332   if alreadyran then
333     alreadyran=%f
334     //terminate current simulation
335     ierr=execstr('[state,t]=scicosim(%cpr.state,par.tf,par.tf,'+..
336                  '%cpr.sim,''finish'',par.tol)','errcatch')
337
338     %cpr.state=state
339     if ierr<>0 then
340       error(['End problem:';lasterror()])
341     end
342   end
343 endfunction