f6c4c91e08098d3a78cf15610c3215a1360785fc
[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,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             then
164             eqns=[eqns
165             "  "+n1+"."+p1+" = "+n2+"."+p2+";"]
166         else
167             eqns=[eqns
168             "  connect ("+n1+"."+p1+","+n2+"."+p2+");"]
169         end
170     end
171
172     txt=[txt;
173     "model "+name
174     Params
175     models
176     "equation"
177     eqns
178     "end "+name+";"]
179 endfunction
180
181 function r=validvar_modelica(s)
182     r=validvar(s);
183
184     if r then
185         bad_char=["%" "#" "$"]
186         for j=1:size(bad_char,2)
187             if strindex(s,bad_char(j)) then
188                 r=%f
189                 return
190             end
191         end
192     end
193 endfunction
194
195
196
197 function r=write_nD_format(x)
198     sx=size(x)
199
200     if size(sx,"*")==2 then // Matrix/Vector
201         [nD1,nD2]=size(x)
202         if nD1==1 then // rows vector
203             r="{"+strcat(string(x),",")+"}"
204             r=strsubst(r,"D","e");
205             return r;
206         elseif nD2==1   then // column vector
207             N=nD1;
208             cmd=")"
209         else  //matrix
210             N=sx(1);
211             cmd=",:)"
212         end
213     else // hypermatrix
214         // typeof(x)==hypermat
215         //  xd=x.entries
216         //  sdims=x.dims(2:$)
217         //  N=x.dims(1)
218         //  cmd=':)'
219         //  n=size(sx,'c')
220         //  for i=1:n-2;cmd=':,'+cmd;end;
221         //  cmd=','+cmd;
222     end
223     r=[];
224     for i=1:N
225         cmdx="write_nD_format(x("+string(i)+cmd+")";
226         execstr("r(i)="+cmdx,"errcatch")
227     end
228     r="{"+strcat(r,",")+"}";
229 endfunction
230
231 // a 2x3 matrix {{xx,xx,xx},{xx,xx,xx}}
232 // A[2] {xx,xx}
233 // A[1,2] {{xx,xx}}
234 // A[2,1] {{xx},{xx}}
235 // A[1,1,2] {{{xx,xx}}}
236 // a=rand(2,3)
237 // a=[3,4];
238 // a=[4;2];
239 // a=rand(2,3);
240 // a=rand(1,2,3,4,5);
241 // a=[1 2 3 4 1 4];a(:,:,2)=[5 6 7 8 1 5] ;
242 //if typeof(a)== 'hypermat' then
243 // disp('not supported')
244 //end
245 //sa=write_nD_format(a)
246
247
248 function     Pari=construct_Pars(Pari,opari,Parembed)
249
250     if Pari==[] then
251         return " "
252     end
253     // Pars='  parameter Real '+Pars+'(fixed=false);'
254     [atemp]=format();
255     format(20);// writing in long format
256
257     //erpar=string(rpar); will put 1e-16 to zero in a vector containing
258     //big numbers
259
260     C=opari;
261     [a1,b1]=size(C);
262     npi=a1*b1;
263     if typeof(C)== "hypermat" then
264         messagebox(_("Hyper Matrix is not supported"),"error","modal")
265         return
266     end
267
268     if (type(C)==1) then
269         if isreal(C) then
270             par_type="Real"
271         else
272             par_type="Complex"
273         end
274         FIXED="false"
275     elseif (typeof(C)=="int32") | (typeof(C)=="int16") |...
276         (typeof(C)=="int8") |(typeof(C)=="uint32") |...
277         (typeof(C)=="uint16") | (typeof(C)=="uint8") then
278         par_type="Integer"
279         FIXED="true"
280     else
281         par_type="UnKnown_Type"
282         FIXED="???"
283         messagebox(_("Type not recognized"),"error","modal");ok=%f;
284     end
285
286     if ~Parembed then
287         FIXED="true"
288     end
289
290     if (npi==1) then,
291         eopari=strsubst(string(C),"D","e");
292         fixings="(fixed="+FIXED+") "
293     else
294         eopari=write_nD_format(C)
295         fixings="(each fixed="+FIXED+") ";
296         [d1,d2]=size(C);
297         if (d1==1) then
298             Pari=Pari+"["+string(d2)+"]"; //[d2]
299         else
300             Pari=Pari+"["+string(d1)+","+string(d2)+"]"; //[d1,d2]
301         end
302     end
303     Pari="  parameter "+par_type+" "+Pari+ fixings+"="+eopari+ "  """+Pari+""""+";"
304     format(atemp(2))// restituing the format
305
306 endfunction
307
308 function eopari = construct_redeclar(opari)
309
310     [atemp]=format();
311     format(20);// writing in long format
312     C=opari;
313     npi=size(C,"*");
314
315     if typeof(C)== "hypermat" then
316         messagebox(_("Hyper Matrix is not supported"),"error","modal")
317         return
318     end
319     if  ~isreal(C) then
320         messagebox(_("Complex Matrix is not supported"),"error","modal")
321         return
322     end
323
324     if (npi==1) then,
325         eopari=strsubst(string(C),"D","e");
326     else
327         eopari=write_nD_format(C)
328     end
329
330     format(atemp(2))// restituing the format
331
332 endfunction