Как передать несколько переменных из одной модели в другую (внутреннюю / внешнюю)

Допустим, у нас есть следующая модель:

Коллекционер:

model Collector
  Real collect_here;
annotation(defaultComponentPrefixes="inner");
end Collector;

и следующая модель потенциально несколько раз:

model Calculator
  outer Collector collector;
  Real calculatedVariable = 2*time;

equation 
  calculatedVariable = collector.collect_here;

end Calculator;

Приведенный выше код работает, если calcModel присутствует в моделируемой системе только один раз. Если модель существует более одного раза, я получаю особую систему. Это демонстрирует пример ниже. Изменение параметра works приводит либо к исправной, либо к неисправной системе.

model Example
  parameter Boolean works = true;

  inner Collector collector;
  Calculator calculator1;
  Calculator calculator2 if not works;

end Example;

Использование массива внутри коллектора для передачи в него нескольких переменных не решает эту проблему.

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


person Phil    schedule 13.11.2018    source источник


Ответы (2)


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

Чтобы дать немного больше понимания: на самом деле проверка Collector не удастся, так как начиная с Modelica 3.0 каждый компонент должен быть сбалансирован (то есть он должен иметь столько же неизвестных, сколько состояний), что не относится к Collector, поскольку у него есть один неизвестно, но нет уравнения. Это сильно ограничивает возможные применения конструкции inner/outer, поскольку в основном каждая переменная должна вычисляться там, где она определена.

В данном примере это компенсируется во всей системе, если используется ровно один Calculator. Так что эта единственная комбинация будет работать. Хотя это работает, этого делать не следует - по очевидной причине высокой вероятности ошибок (и все подмодели должны пройти проверку).

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

  1. Вы хотите построить несколько переменных из одной точки, которая будет коллектором. Для этой цели наиболее простым способом должен быть «выбор переменных»: см. Dymola Manual Vol. 1, раздел «4.3.11 Сопоставление и выбор переменных» о том, как их применять.
  2. Вы хотите выполнить математическую операцию с этими переменными. Тогда было бы полезно иметь векторизованный ввод переменного размера. Это разрешает произвольное количество подключений к этому входу. Для примера взгляните на: Modelica.Blocks.Math.MultiSum
  3. Вы хотите направить несколько сигналов между разными моделями (что маловероятно, судя по вашему описанию, но все же): тогда expandable connectors будет хорошей возможностью. Чтобы получить представление о том, что это на самом деле, взгляните на Modelica.Blocks.Examples.BusUsage.

Надеюсь, это поможет, в противном случае, пожалуйста, более четко укажите, чего вы действительно хотите достичь с помощью своего кода.

person Markus A.    schedule 13.11.2018
comment
Я хочу собрать данные о потерях тепла, рассчитанные на основе набора моделей, чтобы их было легче обрабатывать при анализе системы. - person Phil; 14.11.2018
comment
Вам нужен вектор для каждой отдельной потери тепла или достаточно их суммы? В сумме это должен быть самый простой способ использовать компоненты из Modelica.Thermal.HeatTransfer, например, в Modelica.Thermal.HeatTransfer.Examples.Motor, где все тепловые потоки направляются в environment. По процессу анализа, думаете ли вы о том, чтобы сделать это в Modelica или в автономном режиме после моделирования? - person Markus A.; 14.11.2018
comment
Хотя первым шагом является сложение тепловых потерь отдельных компонентов, следующим шагом является сложение суммы других переменных, таких как мощность. Так что мне нужно общее применимое решение проблемы. Сумму предполагается вычислить в процессе моделирования. - person Phil; 14.11.2018
comment
Единственное, что мне сейчас приходит в голову, это использовать вариант 2 из моего исходного ответа. Это немного громоздко, так как вам нужно провести линию для каждого сигнала, но я не могу придумать общий способ сделать это ... - person Markus A.; 14.11.2018
comment
Я просто попробовал это и добавил к моделям соединение (переменную, multiSum.u [X]), но размер ввода multiSum -X- необходимо ввести для каждого из операторов соединения. Из-за размера наших моделей это сейчас практически невозможно или, скорее, невозможно. В библиотеке TransiEnt уже есть решение моей проблемы, но сейчас мне сложно его понять. Добавлю решение, когда разберусь. - person Phil; 14.11.2018

Несколько дней назад я подготовил демонстрационную библиотеку для такого сценария. Вы можете получить к нему доступ по адресу https://gist.github.com/beutlich/e630b2bf6cdf3efe6e Если вы читаете документацию по Example2, вы можете увидеть ссылку на статью из H. Elmqvis et. al., что является ключом к решению вашей проблемы. То есть вам нужен соединитель и унаследованные соединения от каждого калькулятора к одному коллектору.

person tbeu    schedule 14.11.2018