modelica: изменение параметра массива в массиве компонентов
Здравствуйте, я хочу иметь возможность внести следующие изменения:
Zone.ZONE[nZones] MultiZone(
nMONOL={{nMONOL[i] for i in (1:nSURFS[j])} for j in 1:nZones});
с nZones = 2
с nSURFS = {2,4}
с nMONOL = {5,4,6,7,8,9}
,
Результат должен быть:
MultiZone [1].nMONOL [2] = {5,4}
MultiZone [2].nMONOL [3] = {6,7,8,9}
Но модификация выше не работает. Есть ли способ заставить его работать? С наилучшими пожеланиями K
1 ответ
Вот два возможных решения, которые могут быть достаточными для ваших целей. Как описано в синтаксисе вашего вопроса есть пакет Zone
который содержит модель ZONE
, example
Модель - это то, что было представлено в вашем вопросе.
Подход № 1
Пара заметок
fixed=false
позволяет определить nMONOL в начальном разделе алгоритма / уравненияsum(nSURFS[1:i-1])
является общим для числаnSURFS
указано.Вместо того, чтобы указывать nZones, вы можете зависеть от
nSURFS
, Зависит от того, что на самом деле происходит с вашим кодом, хотя, если это имеет смысл.т.е.
parameter Integer nZones = size(nSURFS,1)
Код выглядит следующим образом:
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;
Производить желаемый результат:
MultiZone [1].nMONOL [2] = {5,4}
MultiZone [2].nMONOL [4] = {6,7,8,9}
Подход № 2
Поговорил с другом, чтобы вдохновиться альтернативным подходом.
Этот второй подход - попытка обойти ограничение языка, согласно которому массивы типов имеют одинаковую длину (по крайней мере, когда вы пытаетесь определить их встроенными). Для этого положитесь на матрицу, в которой 0
или какое-то другое значение, которое имеет смысл дополняет матрицу. Внутренний для модели вы можете иметь внутренний (_int
), чтобы уточнить, что вы используете. Но в этом нет необходимости, если вы гарантируете, что все циклы и т. Д. Настроены на переход от 1:nSURFS (т. Е. Значения 0 никогда не будут использоваться.
Также примечание о nZones в Подходе #1 все еще применяется при желании.
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;
Производить желаемый результат:
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}
Подход № 3
Немного более простая версия подхода № 2. Обратите внимание, что при использовании nMONOL в ZONE
введите зацикливание на nSURFS или создайте внутреннюю переменную, чтобы не использовать 0
ценности.
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;