Библиотека Parametrised Modelica и возможность использования моделей в качестве параметров - часть 2 - PullRequest
1 голос
/ 14 марта 2019

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

В моем примере здесь у меня есть два параметра моегоКомплектация, разъем LCon, а также модель CType.Разъем влияет на все модели в комплектации.Модель CType влияет только на одну модель RType в оборудовании (и имеет более близкое внутреннее-внешнее отношение) к этой модели.

Когда я адаптирую пакет Equipment к требованиям приложений LCon2 и CTyp2, я могу сделать это водин раз, как показано ниже.

   code1

   package Equipment2
          import BR5i.Equipment;
          extends Equipment(redeclare connector LCon=LCon2,
                      redeclare model CType=CType2);
   end Equipment2;    

Однако я думаю, что код (в долгосрочной перспективе) будет более читабельным, если я разделю эти две адаптации на две разные части.Я пытаюсь код ниже, но не работает.Текст ошибки: Не удается найти объявление класса для RType - когда я запускаю его в JModelica.

   code2

   package Equipment2
       import BR5i.Equipment;
       extends Equipment(redeclare connector LCon=LCon2);
   end Equipment2;

   model BRType2        
       import BR5i.Equipment2.RType;
       extends RType(redeclare model CType=CType2);
   end BRType2;

(И для кода 2 библиотека была изменена, поэтому параметр CType был перемещен на уровень оборудования вниз к отдельной модели RType, гдеCType должен служить параметром. И, наконец, я хочу, чтобы BRType2 для кода 2 соответствовал Equipment2.RType из кода 1).

Интересно, возможно ли вообще внести изменения в несколько шагов, подобных этой,т.е. сначала RType получит новый соединитель LCon2, а затем на следующем шаге RType, теперь импортированный из Equipment2, должен заменить CType на CType2?

Я понимаю, что код должен рассматриваться не как последовательность «операторов присваивания», а скорее как параллель.На мой взгляд, логика «уравнений» в коде 2 должна позволить получить правильный BRType2.

Ответы [ 5 ]

2 голосов
/ 28 марта 2019

Ваш "code2" приведет к BRType2 , а не с измененным CType.Переопределение означает не «изменить пакет A, чтобы он выглядел так», а скорее «это должно быть похоже на пакет А, но с этими изменениями».Таким образом, чтобы получить желаемый результат, вы должны сделать что-то вроде:

package Equipment2
    import BR5i.Equipment;
    extends Equipment(redeclare connector LCon=LCon2);
end Equipment2;

model BRType2
    // Equipment2 has the change in LCon, so extend RType from there instead
    import Equipment2.RType;
    extends RType(redeclare model CType=CType2);
end BRType2;

Также обратите внимание, что этот подход не даст ожидаемых результатов, если Equipment содержит какие-либо экземпляры или другие ссылки на Rtype, как они бы ссылалисьна неизмененный RType, а не на BRType2.

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

1 голос
/ 18 апреля 2019

У меня не было времени проанализировать вашу проблему в деталях, но я хотел бы отметить, что если какой-то код принят в одном инструменте, но не принят в другом, это не обязательно означает, что ошибка заключается в инструмент, который не принимает код. С течением времени семантика Modelica стала немного более строгой, чтобы сделать Modelica более безопасным в использовании и более удобным для переноса между инструментами. Поскольку ядро ​​OpenModelica является одним из самых старых в мире, известно, что он принимает большой объем кода, который на самом деле не является (больше не во многих случаях) легальным Modelica в последних версиях.

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

Всего наилучшего, / Hubertus

1 голос
/ 02 апреля 2019

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

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

Теперь я добавлю внутреннюю модель для сбора, котораяопишите некоторую реакцию между веществами.Изначально у нас есть модель реакции NoReaction, которая оставляет вещества в сборном резервуаре без какой-либо реакции.Другая модель реакции - это реакция 3, которая показывает разложение вещества 3.

Проблема, которую я хочу выделить, заключается в том, что, если мы сначала адаптируем оборудование с разъемом для, скажем, трех веществ.А затем во втором раунде измените модель реакции адаптированного оборудования3 на модель реакции Reaction3, затем компилятор JModelica выдаст сообщение об ошибке, а OpenModelica - нет и выдаст результаты моделирования, которые в порядке.Это помечено в коде как вариант 2.

вариант 1. С другой стороны, если две совершенно разные повторные декларации выполняются одновременно, т. Е. Оба изменили соединитель LiquidCon и модель ReactionType, тогда он работает в обеих JModelica.и OpenModelica.

Ниже автономный код и пример Test теперь является альтернативой 2 и генерирует ошибку в JModelica 2.4, но работает в OpenModelica.Мне не ясно, чего ожидать от самой модели Modelica.

    package DEMO_v14

        // Here I have put together a small demo-library to illustrate questions
        // around structuring handling of medium. The key structures are taken
        // from MSL fluid, I think it is fair to say.

        // Author: Jan Peter Axelsson

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

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

        package Medium2
            replaceable constant String name = "Two components"    "Medium name";
            replaceable constant Integer nc = 2                    "Number of substances";
            replaceable type Concentration = Real[nc]              "Substance conc";
            replaceable constant Real[nc] mw = {10, 20}            "Substance weight";  
            constant Integer A = 1                                 "Substance index";
            constant Integer B = 2                                 "Substance index";   
        end Medium2;

        package Medium3 
            import M2 = DEMO_v14.Medium2;
            extends M2
                (name="Three components"                           "Medium name",
                 nc=3                                              "Number of substances",
                 mw = cat(1,M2.mw,{30})                            "Substance weight",
                 redeclare type Concentration = Real[nc]           "Substance conc");
            constant Integer C = 3                                 "Substance index";   
        end Medium3;

        connector LiquidCon3
            Medium3.Concentration c                                "Substance conc";
            flow Real F (unit="m3/s")                              "Flow rate";
        end LiquidCon3;

        model Reaction3
            constant Integer nc = 3;
            outer Real[nc] c;
            outer Real[nc] q;           
        equation
            q[1] = 0;
            q[2] = 0;
            q[3] =-c[3];
        end Reaction3;      

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

        package Equipment
            replaceable connector LiquidCon
            end LiquidCon;

    //      replaceable model ReactionType                         // Alternative 1
    //      end ReactionType;

            model PumpType
                LiquidCon inlet, outlet;                                                     
                RealInput Fsp;
            equation
                inlet.F = Fsp;                                         
                connect(outlet, inlet);                          
            end PumpType;

            model FeedtankType
                LiquidCon outlet;                                  
                constant Integer medium_nc = size(outlet.c,1);
                parameter Real[medium_nc] c_in (each unit="kg/m3") 
                                = {1.0*k for k in 1:medium_nc}     "Feed inlet conc";                        
                parameter Real V_0 (unit="m3") = 100               "Initial feed volume";
                Real V(start=V_0, fixed=true, unit="m3")           "Feed volume";
            equation    
                for i in 1:medium_nc loop
                    outlet.c[i] = c_in[i];
                end for;
                der(V) = outlet.F;               
            end FeedtankType;

            model HarvesttankType
                // Connection to reaction
                replaceable model ReactionType                     // Alternative 2 
                end ReactionType;

                ReactionType reaction;
                inner Real[medium_nc] c                            "Substance conc";
                inner Real[medium_nc] q                            "Reaction rate";     

                LiquidCon inlet, port;                                   
                constant Integer medium_nc = size(inlet.c,1);
                parameter Real V_0 (unit="m3") = 1.0   "Initial harvest liquid volume";
                parameter Real[medium_nc] m_0 
                      (each unit="kg/m3") = zeros(medium_nc)       "Initial substance mass";
                Real[medium_nc] m 
                      (start=m_0, each fixed=true)                 "Substance mass";
                Real V(start=V_0, fixed=true, unit="m3")           "Harvest liquid volume";
            equation
                for i in 1:medium_nc loop
                    der(m[i]) = inlet.c[i]*inlet.F + q[i];
                    c[i] = m[i]/V;
                    port.c[i] = c[i];
                end for;
                der(V) = inlet.F;               
            end HarvesttankType;

            model NoReaction
                constant Integer nc = Medium.nc;
                outer Real[nc] c;
                outer Real[nc] q;           
            equation
                for i in 1:nc loop
                    q[i] = 0;
                end for;
            end NoReaction;     

        end Equipment;

    //  ---------------------------------------------------------------------------------------------   
    //     Control 
    //  ---------------------------------------------------------------------------------------------

        package Control
            block FixValueType
                RealOutput out;
                parameter Real val=0;
            equation
                out = val;
            end FixValueType;
        end Control;

    //  ---------------------------------------------------------------------------------------------
    //  Adaptation of library for the actual culture and media
    //  ---------------------------------------------------------------------------------------------

    //  package Equipment3                                                     // Alternative  1
    //      import DEMO_v14.Equipment;
    //      extends Equipment(redeclare connector LiquidCon=LiquidCon3,
    //                        redeclare model ReactionType=Reaction3);
    //  end Equipment3;

        package Equipment3                                                     // Alternative 2
            import DEMO_v14.Equipment;
            extends Equipment(redeclare connector LiquidCon=LiquidCon3);
        end Equipment3;

        model HarvesttankType3
            import DEMO_v14.Equipment3.HarvesttankType;
            extends HarvesttankType(redeclare model ReactionType=Reaction3);
        end HarvesttankType3;

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

        model Test
            Medium3 medium;
            Equipment3.FeedtankType feedtank;
    //      Equipment3.HarvesttankType harvesttank;                            // Alternative 1 
            HarvesttankType3 harvesttank;                                      // Alternative 2
            Equipment3.PumpType pump;
            Control.FixValueType Fsp(val=0.2);
        equation
            connect(feedtank.outlet, pump.inlet);
            connect(pump.outlet, harvesttank.inlet);
            connect(Fsp.out, pump.Fsp);
        end Test;

    end DEMO_v14;
0 голосов
/ 14 мая 2019

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

Пара комментариев к исправленным ошибкам кода.

  1. В модельном тесте у меня есть привычка делать экземпляр Среды интереса. На самом деле нельзя (и не очень важно) создавать экземпляр пакета, подобного этому, в Modelica, хотя текущие версии JModelica и OpenModelica поддерживают его. Причина, по которой я делаю этот экземпляр пакета Medium, двоякая:

    1. Мне нужно, как правило, в тесте (но не в этом примере) иметь доступ к информации в пакете носителя для настройки. Например, если я подключаю датчик к сборному резервуару и этот датчик относится к семени, то мне нужно указать, какое вещество я хочу измерить, и что лучше всего сделать, используя мнемонику положения вещества в хранилище векторов состояний в среде пакета. Конечно, я могу импортировать мнемонику, необходимую для конфигурации, одну за другой, но более короткую и более удобочитаемую, чтобы использовать пакет среды.

    2. Из FMU хорошо иметь возможность доступа к информации в пакете носителя. Этот пакет может содержать не только мнемонику, но и различные факты о среде, которую мы хотим использовать при разработке специализированного пользовательского интерфейса для FMU и интерактивного моделирования. Это то, что я делаю в Python, используя JModelica. Это работает на самом деле хорошо, как сейчас с JModelica и PyFMI, но то, что я узнал, запрещено в Modelica.

  2. В нескольких местах я передаю количество компонентов в среде nc различным моделям оборудования. И я делаю эту передачу nc несколько напрямую, используя соединитель и «измеряю» размер вектора. Это не нормально делать так в Modelica во время компиляции. Также это работает и в JModelica, и в OpenModelica в настоящее время, но не в Димоле. Я разрешаю это, вводя локальную константу в общий пакет «Оборудование», который не указан, но получает соответствующий номер позже, когда пакет адаптируется к среде, которая должна использоваться. Затем он получает значение medium.nc

Эти изменения делают код более общепринятым, я надеюсь, и, по крайней мере, работают для JModelica, OpenModelica и Dymola. Однако я не слишком доволен решениями, поскольку они не соответствуют моим пользовательским требованиям, как описано выше.

Кроме того, с этим «решением» «альтернатива 2» - адаптация библиотеки в два (или более этапа) не имеет значения - что в конце концов было ключевым вопросом в посте. Я постараюсь переформулировать этот вопрос на небольшом примере в новом посте позже.

Ниже библиотеки DEMO_v18_alt1, а затем после этого приложения d18_alt1_app7

    package DEMO_v18_alt1

        // Here I have put together a small demo-library to illustrate questions
        // around structuring handling of medium. The key structures are taken
        // from MSL fluid, I think it is fair to say.

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

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

        package Medium2
            replaceable constant String name = "Two components"    "Medium name";
            replaceable constant Integer nc = 2                    "Number of substances";
            replaceable type Concentration = Real[nc]              "Substance conc";
            replaceable constant Real[nc] mw = {10, 20}            "Substance weight";  
            constant Integer A = 1                                 "Substance index";
            constant Integer B = 2                                 "Substance index";   
        end Medium2;

        package Medium3 
            import M2 = DEMO_v18_alt1.Medium2;
            extends M2
                (name="Three components"                           "Medium name",
                 nc=3                                              "Number of substances",
                 mw = cat(1,M2.mw,{30})                            "Substance weight",
                 redeclare type Concentration = Real[nc]           "Substance conc");
            constant Integer C = 3                                 "Substance index";   
        end Medium3;

        model Reaction3
            constant Integer nc = 3;
            outer Real[nc] c;
            outer Real[nc] q;           
        equation
            q[1] = 0;
            q[2] = 0;
            q[3] =-c[3];
        end Reaction3;      

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

        package Equipment

            constant Integer nc;

            connector LiquidCon
                Real[nc] c                                         "Substance conc";
                flow Real F (unit="m3/s")                          "Flow rate";
            end LiquidCon;              

            replaceable model ReactionType = NoReaction            // Alternative 1
                constrainedby ReactionTypeInterface;               

            partial model ReactionTypeInterface                    // Alternative 1
                outer Real[nc] c, q;
            end ReactionTypeInterface;

            model NoReaction                                       // Alternative 1
                extends ReactionTypeInterface;          
            equation
                for i in 1:nc loop
                    q[i] = 0;
                end for;
            end NoReaction;             

            model PumpType
                LiquidCon inlet, outlet;                                                     
                RealInput Fsp;
            equation
                inlet.F = Fsp;                                         
                connect(outlet, inlet);                          
            end PumpType;

            model FeedtankType
                LiquidCon outlet;                                  
                parameter Real[nc] c_in (each unit="kg/m3") 
                                = {1.0*k for k in 1:nc}            "Feed inlet conc";                        
                parameter Real V_0 (unit="m3") = 100               "Initial feed volume";
                Real V(start=V_0, fixed=true, unit="m3")           "Feed volume";
            equation    
                for i in 1:nc loop
                    outlet.c[i] = c_in[i];
                end for;
                der(V) = outlet.F;               
            end FeedtankType;

            model HarvesttankType
                // Connection to reaction
                // replaceable model ReactionType = NoReaction constrainedby ReactionTypeInterface;   // Alternative 2

                ReactionType reaction;
                inner Real[nc] c                            "Substance conc";
                inner Real[nc] q                            "Reaction rate";        

                LiquidCon inlet, port;                                   
                parameter Real V_0 (unit="m3") = 1.0   "Initial harvest liquid volume";
                parameter Real[nc] m_0 
                      (each unit="kg/m3") = zeros(nc)       "Initial substance mass";
                Real[nc] m 
                      (start=m_0, each fixed=true)                 "Substance mass";
                Real V(start=V_0, fixed=true, unit="m3")           "Harvest liquid volume";
            equation
                for i in 1:nc loop
                    der(m[i]) = inlet.c[i]*inlet.F + q[i];
                    c[i] = m[i]/V;
                    port.c[i] = c[i];
                end for;
                der(V) = inlet.F;               
            end HarvesttankType;

        end Equipment;

    //  ---------------------------------------------------------------------------------------------   
    //     Control 
    //  ---------------------------------------------------------------------------------------------

        package Control
            block FixValueType
                RealOutput out;
                parameter Real val=0;
            equation
                out = val;
            end FixValueType;
        end Control;

    //  ---------------------------------------------------------------------------------------------
    //  Adaptation of library for the actual culture and media
    //  ---------------------------------------------------------------------------------------------

        package Equipment3                                         // Alternative 1
            import DEMO_v18_alt1.Equipment;
            extends Equipment(nc=Medium3.nc,
                              redeclare model ReactionType=Reaction3);
        end Equipment3;

    //  package Equipment3                                         // Alternative 2
    //      import DEMO_v18_alt2.Equipment;
    //      extends Equipment(nc=Medium3.nc);
    //  end Equipment3;

    //  model HarvesttankType3
    //      import DEMO_v18_alt2.Equipment3.HarvesttankType;
    //      extends HarvesttankType(redeclare model ReactionType=Reaction3);
    //  end HarvesttankType3;

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

        model Test
            package medium = DEMO_v18_alt1.Medium3;                // Not accessible in FMU though
            Equipment3.FeedtankType feedtank;
            Equipment3.HarvesttankType harvesttank;                // Alternative 1 
    //      HarvesttankType3 harvesttank;                          // Alternative 2
            Equipment3.PumpType pump;
            Control.FixValueType Fsp(val=0.2);
        equation
            connect(feedtank.outlet, pump.inlet);
            connect(pump.outlet, harvesttank.inlet);
            connect(Fsp.out, pump.Fsp);
        end Test;

    end DEMO_v18_alt1;

и вот код приложения

    encapsulated package d18_alt1_app7 

        // Here I put together an application for 7 substances - print 8 pt
        // and import code from the library DEMO.

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

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

        package Medium7
            import M2 = DEMO_v18_alt1.Medium2;
            extends M2
                (name = "Seven components"                      "Medium name", 
                nc = 7                                          "Number of substances",
                mw = cat(1,M2.mw,{30,40,50,60,70})              "Substance weight",
                redeclare type Concentration = Real[nc]         "Substance conc");
            constant Integer C = 3                              "Substance index";
            constant Integer D = 4                              "Substance index";  
            constant Integer E = 5                              "Substance index";  
            constant Integer F = 6                              "Substance index";  
            constant Integer G = 7                              "Substance index";  
        end Medium7;

        model Reaction7
            constant Integer nc = 7;
            outer Real[nc] c;
            outer Real[nc] q;           
        equation
            q[1] = 0;
            q[2] = 0;
            q[3] = 0;
            q[4] = 0;       
            q[5] = 0;               
            q[6] = 0;       
            q[7] =-c[7];
        end Reaction7;  

    //  ---------------------------------------------------------------------------------------------
    //     Adaptation of library DEMO_v18_alt1 to Medium7 and Reaction7  
    //  ---------------------------------------------------------------------------------------------

        package Equipment7
            import DEMO_v18_alt1.Equipment;
            extends Equipment(nc=Medium7.nc,
                              redeclare model ReactionType=Reaction7);
        end Equipment7;

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

        import DEMO_v18_alt1.Control;

        model Test
            package medium = d18_alt1_app7.Medium7;                // Not accessible in FMU though
            Equipment7.PumpType pump;
            Equipment7.FeedtankType feedtank;
            Equipment7.HarvesttankType harvesttank;
            Control.FixValueType Fsp(val=0.2);
        equation
            connect(feedtank.outlet, pump.inlet);
            connect(pump.outlet, harvesttank.inlet);
            connect(Fsp.out, pump.Fsp);
        end Test;

    end d18_alt1_app7;
0 голосов
/ 22 апреля 2019

Я согласен с тем, что для безопасной параметризации библиотечного пакета вы делаете гибкость настолько малой, насколько это возможно. Вы можете в пакете иметь постоянное целое число nc, которое вы дадите числу Medium3.nc во время адаптации пакета. И тогда соединитель LiquidCon определяется внутри пакета Equipment и имеет декларацию вектора концентрации как Real [nc] c; Другая информация о Medium чем nc может быть внесена в приложение Test на уровне конфигурации, а не как адаптация пакета Equipment, и не обсуждается в этом примере, но в других связанных постах. Таким образом, процесс адаптации пакета будет максимально безопасным.

Другая адаптация, которая включает введение ReactionType в HarvesttankType (который теперь адаптирован к фактическому nc), должна быть очень гибкой, чтобы этот библиотечный пакет представлял какой-либо интерес. То, что нам требуется от ReactionType, - это иметь интерфейс: external Real (nc] c, q), который мы можем описать в частичной модели и использовать конструкцию с ограничениями, чтобы обеспечить некоторую безопасность.

См. Код DEMO_v17_alt1 и d17_alt1_app7 ниже.

Тем не менее, я бы предпочел написать код как alt2 и оставить тип реакции и т. Д. Определенным только для HarvesttankType, а не для всего пакета Equipment. Это должно было бы обеспечить двухэтапную процедуру адаптации библиотеки. Первый уровень приспособить оборудование к числу средних компонентов. Второй уровень адаптирует теперь адаптированный HarvesttankType к ReactionType. Это невозможно в JModelica, но на самом деле в OpenModelica.

Таким образом, только alt1 работает в JModelica 2.4, а alt1 и alt2 работают в OpenModelica 1.13.2 (и бета-версии 1.14). Что говорит текущее определение Modelica?

Код библиотеки DEMO_v17_alt1:

    package DEMO_v17_alt1

        // Here I have put together a small demo-library to illustrate questions
        // around structuring handling of medium. The key structures are taken
        // from MSL fluid, I think it is fair to say.

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

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

        package Medium2
            replaceable constant String name = "Two components"    "Medium name";
            replaceable constant Integer nc = 2                    "Number of substances";
            replaceable type Concentration = Real[nc]              "Substance conc";
            replaceable constant Real[nc] mw = {10, 20}            "Substance weight";  
            constant Integer A = 1                                 "Substance index";
            constant Integer B = 2                                 "Substance index";   
        end Medium2;

        package Medium3 
            import M2 = DEMO_v17_alt1.Medium2;
            extends M2
                (name="Three components"                           "Medium name",
                 nc=3                                              "Number of substances",
                 mw = cat(1,M2.mw,{30})                            "Substance weight",
                 redeclare type Concentration = Real[nc]           "Substance conc");
            constant Integer C = 3                                 "Substance index";   
        end Medium3;

        model Reaction3
            constant Integer nc = 3;
            outer Real[nc] c;
            outer Real[nc] q;           
        equation
            q[1] = 0;
            q[2] = 0;
            q[3] =-c[3];
        end Reaction3;      

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

        package Equipment

            constant Integer nc;

            connector LiquidCon
                Real[nc] c                                         "Substance conc";
                flow Real F (unit="m3/s")                          "Flow rate";
            end LiquidCon;              

            replaceable model ReactionType = NoReaction            // Alternative 1
                constrainedby ReactionTypeInterface;               

            partial model ReactionTypeInterface                    // Alternative 1
                outer Real[nc] c, q;
            end ReactionTypeInterface;

            model NoReaction                                       // Alternative 1
                extends ReactionTypeInterface;          
            equation
                for i in 1:nc loop
                    q[i] = 0;
                end for;
            end NoReaction;             

            model PumpType
                LiquidCon inlet, outlet;                                                     
                RealInput Fsp;
            equation
                inlet.F = Fsp;                                         
                connect(outlet, inlet);                          
            end PumpType;

            model FeedtankType
                LiquidCon outlet;                                  
                constant Integer medium_nc = size(outlet.c,1);
                parameter Real[medium_nc] c_in (each unit="kg/m3") 
                                = {1.0*k for k in 1:medium_nc}     "Feed inlet conc";                        
                parameter Real V_0 (unit="m3") = 100               "Initial feed volume";
                Real V(start=V_0, fixed=true, unit="m3")           "Feed volume";
            equation    
                for i in 1:medium_nc loop
                    outlet.c[i] = c_in[i];
                end for;
                der(V) = outlet.F;               
            end FeedtankType;

            model HarvesttankType
                // Connection to reaction
                // replaceable model ReactionType = NoReaction constrainedby ReactionTypeInterface;   // Alternative 2

                ReactionType reaction;
                inner Real[medium_nc] c                            "Substance conc";
                inner Real[medium_nc] q                            "Reaction rate";     

                LiquidCon inlet, port;                                   
                constant Integer medium_nc = size(inlet.c,1);
                parameter Real V_0 (unit="m3") = 1.0   "Initial harvest liquid volume";
                parameter Real[medium_nc] m_0 
                      (each unit="kg/m3") = zeros(medium_nc)       "Initial substance mass";
                Real[medium_nc] m 
                      (start=m_0, each fixed=true)                 "Substance mass";
                Real V(start=V_0, fixed=true, unit="m3")           "Harvest liquid volume";
            equation
                for i in 1:medium_nc loop
                    der(m[i]) = inlet.c[i]*inlet.F + q[i];
                    c[i] = m[i]/V;
                    port.c[i] = c[i];
                end for;
                der(V) = inlet.F;               
            end HarvesttankType;

        end Equipment;

    //  ---------------------------------------------------------------------------------------------   
    //     Control 
    //  ---------------------------------------------------------------------------------------------

        package Control
            block FixValueType
                RealOutput out;
                parameter Real val=0;
            equation
                out = val;
            end FixValueType;
        end Control;

    //  ---------------------------------------------------------------------------------------------
    //     Adaptation of library DEMO_v17_alt1 to Medium3 and Reaction3
    //  ---------------------------------------------------------------------------------------------

        package Equipment3                                         // Alternative 1
            import DEMO_v17_alt1.Equipment;
            extends Equipment(nc=Medium3.nc,
                              redeclare model ReactionType=Reaction3);
        end Equipment3;

    //  package Equipment3                                         // Alternative 2
    //      import DEMO_v17_alt2.Equipment;
    //      extends Equipment(nc=3);
    //  end Equipment3;

    //  model HarvesttankType3
    //      import DEMO_v17_alt2.Equipment3.HarvesttankType;
    //      extends HarvesttankType(redeclare model ReactionType=Reaction3);
    //  end HarvesttankType3;

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

        model Test
            Medium3 medium;
            Equipment3.FeedtankType feedtank;
            Equipment3.HarvesttankType harvesttank;                // Alternative 1 
    //      HarvesttankType3 harvesttank;                          // Alternative 2
            Equipment3.PumpType pump;
            Control.FixValueType Fsp(val=0.2);
        equation
            connect(feedtank.outlet, pump.inlet);
            connect(pump.outlet, harvesttank.inlet);
            connect(Fsp.out, pump.Fsp);
        end Test;

    end DEMO_v17_alt1;

и код приложения d17_alt1_app7

    encapsulated package d17_alt1_app7 


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

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

        package Medium7
            import M2 = DEMO_v17_alt1.Medium2;
            extends M2
                (name = "Seven components"                      "Medium name", 
                nc = 7                                          "Number of substances",
                mw = cat(1,M2.mw,{30,40,50,60,70})              "Substance weight",
                redeclare type Concentration = Real[nc]         "Substance conc");
            constant Integer C = 3                              "Substance index";
            constant Integer D = 4                              "Substance index";  
            constant Integer E = 5                              "Substance index";  
            constant Integer F = 6                              "Substance index";  
            constant Integer G = 7                              "Substance index";  
        end Medium7;

        model Reaction7
            constant Integer nc = 7;
            outer Real[nc] c;
            outer Real[nc] q;           
        equation
            q[1] = 0;
            q[2] = 0;
            q[3] = 0;
            q[4] = 0;       
            q[5] = 0;               
            q[6] = 0;       
            q[7] =-c[7];
        end Reaction7;  

    //  ---------------------------------------------------------------------------------------------
    //     Adaptation of library DEMO_v17_alt1 to Medium7 and Reaction7  
    //  ---------------------------------------------------------------------------------------------

        package Equipment7
            import DEMO_v17_alt1.Equipment;
            extends Equipment(nc=Medium7.nc,
                              redeclare model ReactionType=Reaction7);
        end Equipment7;

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

        import DEMO_v17_alt1.Control;

        model Test
            Medium7 medium;                 // Instance not necessary but helpful for user interface
            Equipment7.PumpType pump;
            Equipment7.FeedtankType feedtank;
            Equipment7.HarvesttankType harvesttank;
            Control.FixValueType Fsp(val=0.2);
        equation
            connect(feedtank.outlet, pump.inlet);
            connect(pump.outlet, harvesttank.inlet);
            connect(Fsp.out, pump.Fsp);
        end Test;

    end d17_alt1_app7;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...