Hello I want to be able to make the following modification:
Zone.ZONE[nZones] MultiZone(
nMONOL={{nMONOL[i] for i in (1:nSURFS[j])} for j in 1:nZones});
with nZones = 2
with nSURFS = {2,4}
with nMONOL = {5,4,6,7,8,9}
.
The result should be:
MultiZone[1].nMONOL[2] = {5,4}
MultiZone[2].nMONOL[3] = {6,7,8,9}
But the modification above does not work. Is there a way to make it work? Kind Regards K
Here are two possible solutions that may be sufficient for your purposes. As described by the syntax of your question there is a package Zone
which contains a model ZONE
. The example
model is then what was presented in your question.
A couple notes
fixed=false
allows the definition of nMONOL in an initial algorithm/equation section
sum(nSURFS[1:i-1])
is generic to the number of nSURFS
specified.
Instead of specifing nZones you could have that be dependent on nSURFS
. Depends on what is actually occuring with your code though if that makes sense.
i.e., parameter Integer nZones = size(nSURFS,1)
The code is as follows:
package Zone
model ZONE
parameter Integer nSURFS = 2;
parameter Integer nMONOL[nSURFS](fixed=false); // Notice the modification
end ZONE;
model example
parameter Integer nZones=2;
parameter Integer nSURFS[nZones]={2,4};
parameter Integer nMONOL[sum(nSURFS)]={5,4,6,7,8,9};
Zone.ZONE[nZones] MultiZone(nSURFS=nSURFS);
initial algorithm // or initial equation
for i in 1:nZones loop
for j in 1:nSURFS[i] loop
MultiZone[i].nMONOL[j] := nMONOL[j + sum(nSURFS[1:i-1])];
end for;
end for;
end example;
end Zone;
Producing the desired result:
MultiZone[1].nMONOL[2] = {5,4}
MultiZone[2].nMONOL[4] = {6,7,8,9}
Talked with a friend to get inspired for an alternative approach.
This second approach is an attempt get around the language restriction that type arrays have the same length (at least when you are trying to define them inline). To do so, rely on a matrix where 0
or some other value that makes sense pads the matrix. Internal to the model you can then have a internal (_int
) parameter to help clarify what you are using. But that is not necessary so long as you ensure any loops, etc. are keyed to go from 1:nSURFS (i.e., the 0 values will never be used.
Also the note about nZones in Approach #1 still applies if desired.
package Zone
model ZONE
parameter Integer nSURFS = integer(if Modelica.Math.Vectors.find(0,nMONOL) == 0 then size(nMONOL,1) else Modelica.Math.Vectors.find(0,nMONOL)-1);
parameter Integer nMONOL[:];
final parameter Integer nMONOL_int[nSURFS] = {nMONOL[i] for i in 1:nSURFS};
end ZONE;
model example
parameter Integer nZones=2;
parameter Integer nMONOL[nZones,:]={{5,4,0,0},{6,7,8,9}};
Zone.ZONE[nZones] MultiZone(nMONOL = nMONOL);
end example;
end Zone;
Producing the desired result:
MultiZone[1].nMONOL[4] = {5,4,0,0}
MultiZone[1].nMONOL_int[2] = {5,4}
MultiZone[2].nMONOL[4] = {6,7,8,9}
MultiZone[2].nMONOL_int[4] = {6,7,8,9}
A slightly simpler version of Approach #2. Note, be sure that when using nMONOL in a ZONE
type that you loop over nSURFS, or create an internal variable so as to not use the 0
values.
package Zone
model ZONE
parameter Integer nSURFS;
parameter Integer nMONOL[:];
end ZONE;
model example
parameter Integer nZones=2;
parameter Integer nSURFS[:] = {2, 4};
parameter Integer nMONOL[nZones,max(nSURFS)]={{5,4,0,0},{6,7,8,9}};
Zone.ZONE[nZones] MultiZone(nSURFS = nSURFS, nMONOL = nMONOL);
end example;
end Zone;