Indenting scicos_simulate and xcos_simulate
[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
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 does 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 initialization
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