* Bug #12384 fixed - Using a modelica part linked with explicit link to
[scilab.git] / scilab / modules / scicos / macros / scicos_scicos / create_modelica.sci
1 //  Scicos
2 //
3 //  Copyright (C) INRIA - METALAU Project <scicos@inria.fr>
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2 of the License, or
8 // (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 //
19 // See the file ../license.txt
20 //
21
22 function [txt,rpar,ipar] = create_modelica(blklst,corinvm,cmat,NvM,name,scs_m)
23
24     if exists("%Modelica_Init")==0 then
25         // Modelica_Init becomes true only in "Modelicainitialize_.sci"
26         %Modelica_Init=%f;
27     end
28     if exists("%Modelica_ParEmb")==0 then
29         %Modelica_ParEmb=%t;
30     end
31
32     Parembed=%Modelica_ParEmb & ~%Modelica_Init;
33
34     txt=[];tab=ascii(9)
35     rpar=[];//will contain all parameters associated with the all modelica blocs
36     ipar=[];//will contain the "adress" of each block in rpar
37     models=[]//will contain the model declaration part
38     eqns=[]//will contain the modelica equations part
39     Pin=[]
40     Bnumbers=[]
41     Bnam=[]
42     Bnames=[]
43     nb=size(blklst)
44     Params=[];
45     for k=1:nb
46         ipar(k)=0
47         o=blklst(k);
48         //#########
49         //## Params
50         //#########
51         mo=o.equations;
52         np=size(mo.parameters(1),"*");
53         P=[];
54         //** mo.parameters have size=2
55         //** it only contains parameters
56         if np<>0 then
57             if lstsize(mo.parameters)==2 then
58                 mo.parameters(3)=zeros(1,np)
59             end
60         end
61
62         for j=1:np
63             //## loop on number of param value
64             //## can be both scalar or array
65             Parj=mo.parameters(1)(j)
66             Parjv=mo.parameters(2)(j)
67             Parj_in=Parj+"_"+string(k)+string(j)
68
69             if type(Parjv)==1 then // if Real/Complex   Integers are used with "fixed=true"
70                 rpar=[rpar;matrix(Parjv,-1,1)]
71                 ipar(k)=ipar(k)+size(Parjv,"*")
72             end
73             //======================================================
74             Params=[Params;construct_Pars(Parj_in,Parjv,Parembed)]
75             if mo.parameters(3)(j)==0 then
76                 P=[P;Parj+"="+Parj_in]
77             elseif mo.parameters(3)(j)==1 then
78                 //eParjv=construct_redeclar(Parjv)
79                 P=[P;Parj+"(start="+Parj_in+")"];
80             elseif mo.parameters(3)(j)==2 then
81                 //eParjv=construct_redeclar(Parjv)
82                 P=[P;Parj+"(start="+Parj_in+",fixed=true)"];
83             end
84             //======================================================
85         end
86
87         //#########
88         //## models
89         //#########
90         Bnumbers=[Bnumbers k];
91
92         //## update list of names of modelica blocks
93         // Modelica compiler complains about ID containing dots
94         // So remove them Modelica.package.subpackage => Modelica_DOT_package_DOT_subpackage
95         Bnam = [Bnam, get_model_name(strsubst(mo.model, ".", "_DOT_"),Bnam)];
96         Bnames = [Bnames, Bnam($)]
97
98         if P==[] then
99             models=[models;
100             "  "+mo.model+" "+tab+Bnames($)];
101         else
102             models=[models;
103             "  "+mo.model+" "+tab+Bnames($)+"("+strcat(P,", ")+")"];
104         end
105
106         //## Add gr_i identification in comments of models
107         if mo.model<>"OutPutPort" & mo.model<>"InPutPort" then
108             //## retrieve the object in the scs_m structure
109             o_scsm = scs_m(scs_full_path(corinvm(k)));
110             //## get the structure graphics
111             o_gr  = o_scsm.graphics;
112             //## get the identification field
113             id = stripblanks(o_gr.id)
114
115             if id<>"" then
116                 models($)=models($)+" """+id+""";"
117             else
118                 models($)=models($)+";"
119             end
120         else
121             models($)=models($)+";"
122         end
123
124         //rajouter les ports
125     end
126     ipar=cumsum([1;ipar(:)])
127
128     //links
129     for k=1:size(cmat,1)
130         from=cmat(k,1:3)
131         to=cmat(k,4:6)
132         if from(1)==0 then //input port
133             nb=nb+1
134             Bnumbers=[Bnumbers nb];
135             Bnames=[Bnames,"B"+string(nb)];
136             models=[models;"  InPutPort"+" "+tab+"B"+string(nb)+";"];
137             n1="B"+string(nb)
138         elseif from(3)==1 then
139             p1=blklst(from(1)).equations.inputs(from(2))
140             n1=Bnames(find(Bnumbers==from(1)))
141         else
142             p1=blklst(from(1)).equations.outputs(from(2))
143             n1=Bnames(find(Bnumbers==from(1)))
144         end
145
146         if to(1)==0 then //output port
147             nb=nb+1
148             Bnumbers=[Bnumbers nb];
149             Bnames=[Bnames,"B"+string(nb)];
150             models=[models;"  OutPutPort"+" "+tab+"B"+string(nb)+";"];
151             n1="B"+string(nb)
152         elseif to(3)==1 then
153             p2=blklst(to(1)).equations.inputs(to(2))
154             n2=Bnames(find(Bnumbers==to(1)))
155         else
156             if size(blklst(to(1)).equations.outputs,"*")<to(2) then pause,end
157             p2=blklst(to(1)).equations.outputs(to(2))
158             n2=Bnames(find(Bnumbers==to(1)))
159         end
160
161         if or(blklst(from(1)).equations.model==["InPutPort","OutPutPort"]) ...
162             | or(blklst(to(1)).equations.model==["InPutPort","OutPutPort"]) ...
163             | (k > (size(cmat,1) - NvM)) ...
164             then
165             eqns=[eqns
166             "  "+n1+"."+p1+" = "+n2+"."+p2+";"]
167         else
168             eqns=[eqns
169             "  connect ("+n1+"."+p1+","+n2+"."+p2+");"]
170         end
171     end
172
173     txt=[txt;
174     "model "+name
175     Params
176     models
177     "equation"
178     eqns
179     "end "+name+";"]
180 endfunction
181
182 function r=validvar_modelica(s)
183     r=validvar(s);
184
185     if r then
186         bad_char=["%" "#" "$"]
187         for j=1:size(bad_char,2)
188             if strindex(s,bad_char(j)) then
189                 r=%f
190                 return
191             end
192         end
193     end
194 endfunction
195
196
197
198 function r=write_nD_format(x)
199     sx=size(x)
200
201     if size(sx,"*")==2 then // Matrix/Vector
202         [nD1,nD2]=size(x)
203         if nD1==1 then // rows vector
204             r="{"+strcat(string(x),",")+"}"
205             r=strsubst(r,"D","e");
206             return r;
207         elseif nD2==1   then // column vector
208             N=nD1;
209             cmd=")"
210         else  //matrix
211             N=sx(1);
212             cmd=",:)"
213         end
214     else // hypermatrix
215         // typeof(x)==hypermat
216         //  xd=x.entries
217         //  sdims=x.dims(2:$)
218         //  N=x.dims(1)
219         //  cmd=':)'
220         //  n=size(sx,'c')
221         //  for i=1:n-2;cmd=':,'+cmd;end;
222         //  cmd=','+cmd;
223     end
224     r=[];
225     for i=1:N
226         cmdx="write_nD_format(x("+string(i)+cmd+")";
227         execstr("r(i)="+cmdx,"errcatch")
228     end
229     r="{"+strcat(r,",")+"}";
230 endfunction
231
232 // a 2x3 matrix {{xx,xx,xx},{xx,xx,xx}}
233 // A[2] {xx,xx}
234 // A[1,2] {{xx,xx}}
235 // A[2,1] {{xx},{xx}}
236 // A[1,1,2] {{{xx,xx}}}
237 // a=rand(2,3)
238 // a=[3,4];
239 // a=[4;2];
240 // a=rand(2,3);
241 // a=rand(1,2,3,4,5);
242 // a=[1 2 3 4 1 4];a(:,:,2)=[5 6 7 8 1 5] ;
243 //if typeof(a)== 'hypermat' then
244 // disp('not supported')
245 //end
246 //sa=write_nD_format(a)
247
248
249 function     Pari=construct_Pars(Pari,opari,Parembed)
250
251     if Pari==[] then
252         return " "
253     end
254     // Pars='  parameter Real '+Pars+'(fixed=false);'
255     [atemp]=format();
256     format(20);// writing in long format
257
258     //erpar=string(rpar); will put 1e-16 to zero in a vector containing
259     //big numbers
260
261     C=opari;
262     [a1,b1]=size(C);
263     npi=a1*b1;
264     if typeof(C)== "hypermat" then
265         messagebox(_("Hyper Matrix is not supported"),"error","modal")
266         return
267     end
268
269     if (type(C)==1) then
270         if isreal(C) then
271             par_type="Real"
272         else
273             par_type="Complex"
274         end
275         FIXED="false"
276     elseif (typeof(C)=="int32") | (typeof(C)=="int16") |...
277         (typeof(C)=="int8") |(typeof(C)=="uint32") |...
278         (typeof(C)=="uint16") | (typeof(C)=="uint8") then
279         par_type="Integer"
280         FIXED="true"
281     else
282         par_type="UnKnown_Type"
283         FIXED="???"
284         messagebox(_("Type not recognized"),"error","modal");ok=%f;
285     end
286
287     if ~Parembed then
288         FIXED="true"
289     end
290
291     if (npi==1) then,
292         eopari=strsubst(string(C),"D","e");
293         fixings="(fixed="+FIXED+") "
294     else
295         eopari=write_nD_format(C)
296         fixings="(each fixed="+FIXED+") ";
297         [d1,d2]=size(C);
298         if (d1==1) then
299             Pari=Pari+"["+string(d2)+"]"; //[d2]
300         else
301             Pari=Pari+"["+string(d1)+","+string(d2)+"]"; //[d1,d2]
302         end
303     end
304     Pari="  parameter "+par_type+" "+Pari+ fixings+"="+eopari+ "  """+Pari+""""+";"
305     format(atemp(2))// restituing the format
306
307 endfunction
308
309 function eopari = construct_redeclar(opari)
310
311     [atemp]=format();
312     format(20);// writing in long format
313     C=opari;
314     npi=size(C,"*");
315
316     if typeof(C)== "hypermat" then
317         messagebox(_("Hyper Matrix is not supported"),"error","modal")
318         return
319     end
320     if  ~isreal(C) then
321         messagebox(_("Complex Matrix is not supported"),"error","modal")
322         return
323     end
324
325     if (npi==1) then,
326         eopari=strsubst(string(C),"D","e");
327     else
328         eopari=write_nD_format(C)
329     end
330
331     format(atemp(2))// restituing the format
332
333 endfunction