Как хранить и интерполировать многомерные массивы переменных размеров в Modelica? - PullRequest
2 голосов
/ 31 марта 2020

У меня есть таблицы больших размеров (A1, A2, ...) по крайней мере с 3 измерениями (скажем, b, c, d), которые можно представить, как показано на рисунке, где размер массива n_b, n_ c и n_d являются переменными.

package Arrays

  record A
    extends Modelica.Icons.Record;
    parameter Real b[:] "base array";
    parameter Arrays.Baseclasses.B b_target[:] "target array";

  end A;

  package Baseclasses
    record D
        extends Modelica.Icons.Record;
        parameter Real E[:];
        parameter Real F[:];

    end D;

    record C
      extends Modelica.Icons.Record;
      parameter Real d[:] "base array";
      parameter Arrays.Baseclasses.D d_target[:] "target array";

    end C;

    record B
      extends Modelica.Icons.Record;
      parameter Real c[:] "base array";
      parameter Arrays.Baseclasses.C c_target[:] "target array";
    end B;
  end Baseclasses;

  package Example
    model A
      Arrays.A a(b={1}, b_target={Arrays.Baseclasses.B(c={2}, c_target={
            Arrays.Baseclasses.C(d={3,4}, d_target={Arrays.Baseclasses.D(E={4,5},
            F={5,8}),Arrays.Baseclasses.D(E={2,3}, F={3,4})})})});
    end A;
  end Example;
  annotation (uses(Modelica(version="3.2.2")));
end Arrays;

enter image description here

Для этого типа структуры я получаю следующую ошибку:

Current version of the Modelica translator can only handle
array of components with fixed size.
But component a.b_target[1].c_target[1].d_target had non-fixed array dimensions [:].
In file: C:/....../Arrays.mo

All variables used in size expressions must be declared as constants or parameters.

Could not find member c_target[1] in record expression Arrays.Baseclasses.B(
{2}, 
{Arrays.Baseclasses.C(
{3, 4}, 
{Arrays.Baseclasses.D({4, 5}, {5, 8}), Arrays.Baseclasses.D({2, 3}, {3, 4})})}).

Could not find member c_target[1] in record expression Arrays.Baseclasses.B(
{2}, 
{Arrays.Baseclasses.C(
{3, 4}, 
{Arrays.Baseclasses.D({4, 5}, {5, 8}), Arrays.Baseclasses.D({2, 3}, {3, 4})})}).

The model contained invalid expressions.

Check of class aborted.

WARNINGS have been issued.

ERRORS have been issued.

One У меня было наблюдение, что, когда я устанавливаю значение n_d постоянным, например:

    record C
      extends Modelica.Icons.Record;
      parameter Real d[2] "base array";
      parameter Arrays.Baseclasses.D d_target[2] "target array";

, ошибка исчезает. Означает ли это, что переводчик Modelica допускает использование массивов переменного размера до двух измерений и выше, чем размер фиксированного массива? Если так, есть ли способ обойти это, чтобы получить запись с многомерным массивом переменного размера?

1 Ответ

2 голосов
/ 01 апреля 2020

Я бы сказал, что вы столкнулись с ошибкой.

Массивы могут иметь более двух измерений с неизвестным размером, как показано в этом небольшом примере (который отлично работает в Dymola, но не по какой-то причине в OpenModelica ... )

model MultDim
  Real A[:,:,:,:] = {B, B};
  Real B[:,:,:] = {C};
  Real C[:,:] = {D, D, D, D};
  Real D[:] = {1, 2, 3};
end MultDim;

В вашем случае у вас есть вектор записей, где каждая запись содержит другой вектор записей и т. Д., Поэтому проблема более сложная, чем описанная выше. Дело не только в многомерности с неизвестным размером.

Я упростил ваш код до минимального примера с той же проблемой. Это может быть полезно для других, чтобы быстрее понять проблему. Обратите внимание, что проблема уже возникает на уровне B, когда вы используете промежуточные переменные.

package Arrays2
  record A
    parameter B b[:];
  end A;

  record B
    parameter C c[:];
  end B;

  record C
    parameter D d[:];
  end C;

  record D
  end D;

  model Example_ok
      B b( c={ C( d={ D() }) });
  end Example_ok;

  model Example_fail
    A a(b={ B( c={ C(d={ D() }) }) });
  end Example_fail;

  model Example_fail2
    // if we use intermediate variables,
    // the example already fails at B-level.
    B b = B(c={ c });
    C c = C(d={ D() });
  end Example_fail2;
end Arrays2;
...