2

コードを一般ライブラリとアプリケーション コードの 2 つの部分に分割するための適切な方法を見つけることに取り組んでいます。私が使用する例には通常、液体が含まれており、一般ライブラリを液体内のコンポーネントの数に依存しないようにしたいと考えています。アイデアは、アプリケーション コードが使用される液体媒体を設定し、一般的なライブラリから機器をインポートして、これらの機器を実際の媒体に適合させるというものです。

以下の例は、このコードの分割を行う 1 つの方法を示す非常に簡潔な例です。ここでは、部分パッケージ MediumBase でコンポーネント数の値 nc を未定義にします。その後、EquipmentLib が実際のメディアに適合されたときに、値を取得します。これが、構造パラメータの「遅延」設定の意味です。このコードは、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 では、「配列 c[MediumBase.nc] の次元を与える構造パラメーター (または定数) .. nc を評価できませんでした」というエラーが表示されます。配列の次元はコンパイル時に知っている必要があります '

nc はコンパイル時に、EquipmentLib が適用されるレベルで既知であるため、このメッセージは私には意味がありません。この問題は、MediumBase の nc に Medium Base の「ダミー」値 nc=1 を与えることで実際に解決できます。その nc は、コンパイル中に EquipmentLib が適合されたときに提供される値に変更されます。

だから私の質問は:

  1. 私には、 nc を未定義のままにしてから、コンパイル中に値が設定されていることを確認する方が良いように見えますが、コンパイル中に定数を変更することは疑わしいように見えますが、おそらく (まだ) Modelica では許可されています。IN Modelica 言語仕様の付録 A で、定数の要件は、(のみ) シミュレーション中に定数であることがわかります。つまり、コンパイル中には定数ではありません。付録 E8​​.2 では、おそらく nc の初期割り当てを行う必要があることがわかりますが、よくわかりません。ただし、これについてのコメントをいただければ幸いです。
  2. JModelica と OpenModelica のやや大きな例のコンパイラで、それぞれ警告とエラーが発生するのはどうしてでしょうか?
  3. Modelica の仕様は、ここにあるものについて何と言っていますか?

必要に応じて、より大きな例を提供できますが、ここではより一般的な答えになると思います。

4

2 に答える 2

0

1)理論的にはあなたの言いたいことは理解できますが、modelica言語標準では、すべてのモデル(コネクタと部分モデルを除く)が単独で有効である必要があります。部分パッケージを定義したため、これはあなたのケースには関係ないようです。ここでの問題は、この変数に構造的に依存する同じスコープで配列を定義したことです。したがって、確認できるデフォルト値を提供することを強くお勧めします。

2) 実際に問題を再現できません。OpenModelica を使用すると、すべてが正常に動作しnc=10000ます。遅いですが動作します (将来、配列/ベクトルを高速化することに取り組んでいます)。私は夜間ビルド (OpenModelica 1.16.0~dev-102-g5c1a023) を使用しています。

3) 1)参照。一般的に、コンポーネントごとに Check Model (緑の円の上の中央にある単一のチェックマーク) を使用して、行うすべてが modelica 言語に準拠しているかどうかを確認する必要があることを追加できます。そのすぐ横にあるインスタンス化ボタンを使用して、コードから生成されるフラット モデルを確認することもできます。

さらに、コンパイル フラグを使用することをお勧めし-d=newInstます (新しいバージョンのいずれかで作業している場合)。これは、modelica 仕様により厳密で、はるかに効率的な新しいインスタンス化を使用します。

于 2020-02-24T15:25:38.470 に答える