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