* Bug #10510 fixed - Unused variables was generated by xcos on startup.
[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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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
160   if exists('scicos_scicoslib')==0 then
161     load("SCI/modules/scicos/macros/scicos_scicos/lib") ;
162   end
163
164   if exists('scicos_autolib')==0 then
165     load("SCI/modules/scicos/macros/scicos_auto/lib") ;
166   end
167
168   if exists('scicos_utilslib')==0 then
169     load("SCI/modules/scicos/macros/scicos_utils/lib") ;
170   end
171
172 // Define Scicos data tables ===========================================
173   [modelica_libs, scicos_pal_libs, %scicos_with_grid, %scs_wgrid] = initial_scicos_tables();
174   // =====================================================================
175
176   //** initialize a "scicos_debug_gr" variable
177   %scicos_debug_gr = %f;
178
179
180   //** redefine some  functions
181   prot = funcprot();funcprot(0);
182   do_terminate = do_terminate1
183   funcprot(prot)
184
185
186   //check version
187   current_version = get_scicos_version()
188   scicos_ver = find_scicos_version(scs_m)
189
190   //do version
191   if scicos_ver <> current_version then
192     ierr = execstr('scs_m = do_version(scs_m, scicos_ver)','errcatch')
193     if ierr <> 0 then
194       messagebox(_("Can''t convert old diagram (problem in version)"),"modal")
195       return
196     end
197   end
198
199   //** prepare from and to workspace stuff
200   //-------------------------------------
201   scicos_workspace_init()
202
203   if flag == 'nw' then
204     Ignore = [Ignore,Ignoreb]
205   end
206   //add user ignored blocks if any
207   Ignore = [Ignore, Ignb]
208
209   //** retrieve Info list
210   if Info <> list() then
211     [%tcur, %cpr, alreadyran, needstart, needcompile, %state0] = Info(:)
212   else
213     %tcur = 0;
214     %cpr = list();
215     alreadyran = %f;
216     needstart = %t;
217     needcompile = 4;
218     %state0 = list();
219   end
220
221   //** set solver
222   tolerances     = scs_m.props.tol
223   solver         = tolerances(6)
224   %scicos_solver = solver
225   //** set variables of context
226   [%scicos_context, ierr] = script2var(scs_m.props.context,struct())
227   //overload %scicos_context variables with those defined by updated_vars
228   contextvars=fieldnames(%scicos_context)
229   updatedvars=fieldnames(updated_vars)
230   for k=1:size(updatedvars,'*')
231     u=updatedvars(k)
232     if or(u==contextvars) then
233       %scicos_context(u)=updated_vars(u)
234     else
235       mprintf(_("Warning the variable %s do not match any context variable name\nignored"),u)
236     end
237   end
238   if ierr == 0 then //++ no error
239     [scs_m, %cpr, needcompile, ok] = do_eval(scs_m, %cpr,%scicos_context)
240     if ~ok then
241       error(msprintf(gettext("%s: Error during block parameters evaluation.\n"), "scicos_simulate"));
242     end
243     if needcompile <> 4 & size(%cpr) > 0 then
244       %state0 = %cpr.state
245     end
246     alreadyran = %f
247   else
248     error(['Incorrect context definition, ' + lasterror()])
249   end
250
251   if %cpr == list() then
252     need_suppress  =%t
253   else
254     need_suppress = %f
255   end
256
257   [%cpr, %state0_n, needcompile, alreadyran, ok] = do_update(%cpr, ...
258                                                   %state0, needcompile)
259
260   if ~ok then
261     error(msprintf(gettext("%s: Error during block parameters update.\n"), "scicos_simulate"));
262   end
263
264   if or(%state0_n <> %state0) then //initial state has been changed
265     %state0 = %state0_n
266     [alreadyran, %cpr] = do_terminate1(scs_m, %cpr)
267     choix = []
268   end
269   if (%cpr.sim.xptr($) - 1) < size(%cpr.state.x,'*') & solver < 100 then
270     warning(msprintf(_("Diagram has been compiled for implicit solver\nswitching to implicit solver.\n")))
271     solver = 100
272     tolerances(6) = solver
273   elseif (%cpr.sim.xptr($) - 1) == size(%cpr.state.x,'*') & ...
274         solver == 100 & size(%cpr.state.x,'*') <> 0 then
275     warning(msprintf(_("Diagram has been compiled for explicit solver\nswitching to explicit solver.\n")))
276     solver = 0
277     tolerances(6) = solver
278   end
279
280   if need_suppress then //this is done only once
281     for i = 1:length(%cpr.sim.funs)
282       if type(%cpr.sim.funs(i)) <> 13 then
283         if find(%cpr.sim.funs(i)(1) == Ignore) <> [] then
284           %cpr.sim.funs(i)(1) = 'trash';
285         end
286       end
287     end
288   end
289
290   if needstart then //scicos initialisation
291     if alreadyran then
292       [alreadyran, %cpr] = do_terminate1(scs_m, %cpr)
293       alreadyran = %f
294     end
295     %tcur = 0
296     %cpr.state = %state0
297     tf = scs_m.props.tf;
298     if tf*tolerances == [] then
299       error(_("Simulation parameters not set:"));
300     end
301     ierr = execstr('[state, t] = scicosim(%cpr.state, %tcur, tf, %cpr.sim,' + ..
302                    '''start'', tolerances)','errcatch')
303     if ierr <> 0 then
304       error(_("Initialisation problem:"))
305     end
306     %cpr.state = state
307   end
308
309   ierr = execstr('[state, t] = scicosim(%cpr.state, %tcur, tf, %cpr.sim,' + ..
310                  '''run'', tolerances)','errcatch')
311   if ierr == 0 then
312     %cpr.state = state
313     alreadyran = %t
314     if (tf - t) < tolerances(3) then
315       needstart = %t
316       [alreadyran, %cpr] = do_terminate1(scs_m, %cpr)
317     else
318       %tcur = t
319     end
320   else
321     error([_("Simulation problem: ");lasterror()])
322   end
323
324   Info = list(%tcur, %cpr, alreadyran, needstart, needcompile, %state0)
325
326   [txt, files] = returntoscilab()
327   n = size(files,1)
328   for i = 1:n
329     load(TMPDIR + '/Workspace/' + files(i))
330     execstr(files(i) + ' = struct('"values'", x, '"time'", t)')
331   end
332   execstr(txt)
333 endfunction
334
335 function [alreadyran, %cpr] = do_terminate1(scs_m, %cpr)
336 // Copyright INRIA
337
338   if prod(size(%cpr)) < 2 then
339     alreadyran = %f
340     return
341   end
342
343   par = scs_m.props;
344
345   if alreadyran then
346     alreadyran = %f
347     // terminate current simulation
348     ierr = execstr('[state, t] = scicosim(%cpr.state, par.tf, par.tf, %cpr.sim, ''finish'', par.tol)', 'errcatch')
349
350     %cpr.state = state
351     if ierr <> 0 then
352       error([_("End problem: ");lasterror()])
353     end
354   end
355 endfunction