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