6472e45685ae50a39ab1141f3377b86793cb88cc
[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