Параметризованная библиотека Modelica и возможность «отложить» настройку структурного параметра - часть 3

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

Приведенный ниже пример представляет собой очень краткий пример, иллюстрирующий один из способов разделения кода. Здесь я позволил не определять число компонентов nc в частичном пакете MediumBase. Позже, когда EquipmentLib будет адаптирована к реальной среде, тогда nc получит значение. Это то, что я имею в виду под «задержкой» настройки структурного параметра. Код хорошо работает как в JModelica, так и в OpenModelica.

    package DEMO_v30

        // Author: Jan Peter Axelsson

    //  ---------------------------------------------------------------------------------------------
    //     Interfaces  
    //  ---------------------------------------------------------------------------------------------

        import Modelica.Blocks.Interfaces.RealInput;
        import Modelica.Blocks.Interfaces.RealOutput;

        partial package MediumBase
            constant Integer nc                                    "Number of components";
            replaceable type Concentration = Real[nc]              "Component conc";        
        end MediumBase;

        package Medium3 
            extends MediumBase (nc=3);  
        end Medium3;

    //  ---------------------------------------------------------------------------------------------
    //     Equipment dependent on the medium  
    //  ---------------------------------------------------------------------------------------------

        package EquipmentLib
            replaceable package Medium = MediumBase                // formal parameter - EquipmentLib
                constrainedby MediumBase;
            model ReactorType
                parameter Medium.Concentration c_0 = ones(Medium.nc) "Initial component conc";
                Medium.Concentration c (start=c_0, each fixed=true)  "Component conc";  
            equation   
                for i in 1:Medium.nc loop
                    der(c[i]) = -c[i];
                end for;        
            end ReactorType;    
        end EquipmentLib;

    //  ---------------------------------------------------------------------------------------------
    //     Adaptation of package Equipment to Medium3
    //  ---------------------------------------------------------------------------------------------

        package Equipment
            import DEMO_v30.EquipmentLib;
            extends EquipmentLib(redeclare package Medium=Medium3);
        end Equipment;

    //  ---------------------------------------------------------------------------------------------
    //     Examples of systems 
    //  ---------------------------------------------------------------------------------------------

        model Test
            Equipment.ReactorType reactor;
        end Test;

    end DEMO_v30;

Однако в немного более крупных примерах с той же структурой кода у меня возникают некоторые проблемы:

  • В JModelica я получаю предупреждение о том, что «Константа nc не имеет выражения привязки»
  • В OpenModelica я получаю сообщение об ошибке: «Не удалось оценить структурный параметр (или константу) .. nc, который дает размеры массива c [MediumBase.nc]. Размер массива должен быть известен во время компиляции '

Для меня это сообщение не имеет смысла, поскольку nc известен во время компиляции, на уровне адаптации EquipmentLib. На самом деле эту проблему можно решить, присвоив nc в MediumBase «фиктивное» значение nc = 1 в Medium Base, а затем изменив это значение nc во время компиляции на значение, предоставленное при адаптации EquipmentLib.

Итак, мои вопросы:

  1. На мой взгляд, лучше оставить nc undefined, а затем убедиться, что значение установлено во время компиляции, в то время как изменение константы во время компиляции выглядит сомнительным, но, возможно, (все еще) разрешенным в Modelica. В спецификации языка Modelica я вижу в Приложении A, что константа требуется (только), чтобы она была постоянной во время моделирования, то есть не во время компиляции. В приложении E8.2 я вижу, что, возможно, следует выполнить начальное назначение nc, но не уверен. Буду признателен за комментарий по этому поводу.
  2. Как могло случиться, что с несколько большим примером компиляторы JModelica и OpenModelica выдают предупреждение и ошибку, соответственно?
  3. Что в спецификации Modelica говорится о том, что находится прямо здесь?

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


person janpeter    schedule 22.02.2020    source источник


Ответы (2)


1) Теоретически я понимаю, что вы имеете в виду, но стандарт языка modelica требует, чтобы каждая модель (кроме соединителей и частичных моделей) была действительна сама по себе. Кажется, это не имеет отношения к вашему случаю, поскольку вы определили частичный пакет, проблема здесь в том, что вы определили массив в той же области, которая структурно зависит от этой переменной. Поэтому я настоятельно рекомендую указать значение по умолчанию, которое можно проверить.

2) Я действительно не могу воспроизвести проблему. С OpenModelica все работает нормально даже для nc=10000. Медленно, но работает (в будущем мы работаем над ускорением работы с массивами / векторами). Я работаю с ночной сборкой (OpenModelica 1.16.0 ~ dev-102-g5c1a023).

3) См. 1). Как правило, я могу просто добавить, что вы должны использовать Проверочную модель (единичная галочка на зеленом круге вверху в середине) для каждого компонента индивидуально, чтобы проверить, соответствует ли все, что вы делаете, языку modelica. Вы также можете использовать кнопку создания экземпляра рядом с ним, чтобы посмотреть на плоскую модель, которая будет сгенерирована из вашего кода.

Кроме того, я бы рекомендовал использовать флаг компиляции -d=newInst (при условии, что вы работаете с одной из более новых версий). При этом используется новый экземпляр, более строгий по спецификации modelica и гораздо более эффективный.

person kabdelhak    schedule 24.02.2020
comment
1) Насколько я понимаю, частичная модель и пакет вполне могут быть неполными, поскольку они не используются сами по себе. И мой частичный пакет MediumBase, по сути, гарантирует, что при замене Medium этот пакет действительно имеет параметр nc, а когда формируется полный пакет, это число должно быть на месте. 2) И я рад, что и JModelica, и OpenModelica принимают опубликованный мной код и в некоторой степени подтверждают мое понимание. 3) Но для более крупной модели, не с точки зрения nc, а с несколькими дополнительными уровнями кода, я получаю предупреждение и ошибку компилятора от JModelican и OpenModelica. Modelica spec говорят что? - person janpeter; 25.02.2020

Теперь я подтвердил, что мой опубликованный код действительно работает, и для частичного пакета (или модели) вы можете определять переменные, которые не имеют значений или векторов с неопределенным размером, при условии, что они во время компиляции полностью определены. Более сложный код с аналогичной структурой, из-за которого возникла упомянутая мною проблема, теперь также решен. Код работает как с JModelica 2.14, так и с OpenModelica 1.16 nightly build ... b48. Интересно, что код не работает на версии 1.15 или более ранней. Благодаря моему контакту в Modelon Маркусу Олссону!

person janpeter    schedule 26.02.2020