Scicos: option 'nw' for block BPlatform
[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                     %cpr.sim.funs(i)(1) = "trash";
287                 end
288             end
289         end
290     end
291
292     if needstart then //scicos initialization
293         if alreadyran then
294             [alreadyran, %cpr] = do_terminate1(scs_m, %cpr)
295             alreadyran = %f
296         end
297         %tcur = 0
298         %cpr.state = %state0
299         tf = scs_m.props.tf;
300         if tf*tolerances == [] then
301             error(_("Simulation parameters not set:"));
302         end
303         ierr = execstr("[state, t] = scicosim(%cpr.state, %tcur, tf, %cpr.sim," + ..
304         "''start'', tolerances)","errcatch")
305         if ierr <> 0 then
306             error(_("Initialisation problem:"))
307         end
308         %cpr.state = state
309     end
310
311     ierr = execstr("[state, t] = scicosim(%cpr.state, %tcur, tf, %cpr.sim," + ..
312     "''run'', tolerances)","errcatch")
313     if ierr == 0 then
314         %cpr.state = state
315         alreadyran = %t
316         if (tf - t) < tolerances(3) then
317             needstart = %t
318             [alreadyran, %cpr] = do_terminate1(scs_m, %cpr)
319         else
320             %tcur = t
321         end
322     else
323         error([_("Simulation problem: ");lasterror()])
324     end
325
326     Info = list(%tcur, %cpr, alreadyran, needstart, needcompile, %state0)
327
328     [txt, files] = returntoscilab()
329     n = size(files,1)
330     for i = 1:n
331         load(TMPDIR + "/Workspace/" + files(i))
332         execstr(files(i) + " = struct('"values'", x, '"time'", t)")
333     end
334     execstr(txt)
335 endfunction
336
337 function [alreadyran, %cpr] = do_terminate1(scs_m, %cpr)
338     // Copyright INRIA
339
340     if prod(size(%cpr)) < 2 then
341         alreadyran = %f
342         return
343     end
344
345     par = scs_m.props;
346
347     if alreadyran then
348         alreadyran = %f
349         // terminate current simulation
350         ierr = execstr("[state, t] = scicosim(%cpr.state, par.tf, par.tf, %cpr.sim, ''finish'', par.tol)", "errcatch")
351
352         %cpr.state = state
353         if ierr <> 0 then
354             error([_("End problem: ");lasterror()])
355         end
356     end
357 endfunction