2013-02-03 10 views
6

特定のコンポーネントが存在するかどうか(私の場合は流体ポート)に基づいて、わずかに異なる方程式を持つモデルを作成しようとしています。条件付きコンポーネントの宣言とそれに続く場合式

次のようなコードは動作しません。

parameter Boolean use_component=false; 
Component component if use_component; 
equation 
if use_component then 
    component.x = 0; 
end if; 

私はこの問題を回避するにはどうすればよいですか?

答えて

8

、これが役立つことを願って、あなたが知っておく必要があるいくつかの制限があります。 Modelica 3.3仕様の4.4.5節はそれをうまくまとめています。それは "条件が偽である場合、コンポーネント、その修飾子、およびコンポーネントを含む接続方程式 が削除されます"と表示されます。この問題を解決するためにこれを使用する方法を数秒で説明しますが、まずはソリューションが機能しない理由を説明します。

問題はモデルの確認と関係があります。あなたのケースでは、式component.xとコンポーネントcomponentのどちらかが存在するか、存在しないことが明らかです。これは、それらを同じブール変数に束縛しているためです。しかし、もしあなたがこれをしていなかったらどうすればいいでしょう:

parameter Real some_number; 
Component component if some_number*some_number>4.0; 
equation 
if some_number>=-2 and some_number<=2 then 
    component.x = 0; 
end if; 

これは論理的にあなたのケースと同じことがわかります。 componentが存在しない場合、component.xが存在する可能性はありません。しかし、我々はそのようなことを証明することができます一般に?いいえ。

条件付きコンポーネントが導入されたとき、関係する変数と式のセットが決して「同期外れ」にならないことを常に自明に保つことができる控えめなセマンティクスが実装されました。解決策はできる、あなたのケースのために

を「条件がfalseの場合、コンポーネント、その修飾、およびコンポーネントを含むすべての接続の方程式 が、削除されている」:

は、私たちは仕様が言うに戻るにしてみましょう潜在的に非常に単純です。 「x」の宣言方法に応じて、componentに変更を加えることができます。

parameter Boolean use_component=false; 
Component component(x=0) if use_component; 

このエレガンスは変更のみcomponentおよびcomponentが存在しておりません、どちらも修正(式)である場合に適用されることです。したがって、変数xとそれに関連する方程式は "同期"しています。しかし、これはすべてのケースで機能しません(IIRC、xにはinput修飾子が必要です。これはおそらくあなたのケースで可能でしょうか?)。

残りの2つの選択肢があります。まず、式component.xcomponentの中に入れます。 2番目の方法は、componentにコネクタを導入し、接続すると、必要な式が生成されます。変更の場合(これは偶然ではありません)と同じように、あなたはいくつかの種類の入力コネクタとxを関連付けた後、これを行うことができます:今

parameter Boolean use_component; 
Component component if use_component; 
Constant zero(k=0); 
equation 
connect(k.y, component.x); 

を、私は、すべての3例(修正を考慮した後のことを想像できます方程式を内部化してconnectを使用すると)、どちらもうまく動作しないという結論に至ります。このような場合は、コンポーネントの設計方法に問題があることをお勧めします。これらの制限が発生する理由は、正確にコンポーネントを確認する必要性に関連します。これには、コンポーネントが完全であることが必要です(仕様の用語では「平衡」)。

私が上記のアプローチで問題を解決できない場合は、本当にバランスのとれた問題があると思われ、おそらくコンポーネントの境界を何とか再定義する必要があると思われます。このような場合は、あなたがしようとしていることの詳細をここに別の質問をすることをお勧めします。

1

これがうまくいかない理由は、コンポーネントがアクティブでない場合、パーザは変数 "component.x"の宣言を検索して存在しないと考えていると思います。注釈に「Evaluate = true」を挿入しても機能しません。 私の意見では、最もクリーンな解決策は、等式レベルで作業し、同じブロック内の異なる式のセットを有効にすることです。正しいコネクターとparamersでラッパー・モデルを作成することができます。それが因果モデルであれば、例えばモデルを関数としてパラメーター化するために置き換え可能なクラスを使用できます。そうでなければ、因果モデルの場合は、 ifステートメント。 別の可能性のある回避策は、2つの異なるモデルを1つのブロック内に配置することです。そのため、変数を式セクションに使用して、条件付き接続を構築して、選択した動作でブロックを使用できるようにします。言い換えれば、内側に2つのブロックを持つ "ラップモデル"を構築​​し、if文内のラップモデルのコネクタに接続式を配置することができます。使用されていないブロックであっても、一貫したシステムの照会ができるように、モデルを構築することを忘れないでください。 しかし、これは最適な解決策ではありません。なぜなら、ブロックが大きければすべてがコンパイルされるので、コンパイルに長い時間を待たなければならないからです。あなたが条件コンポーネントを使用したい場合は

私はマルコ

0

また、グラフィカル層に表示されていないダミー部品作ることができます。これは、2ポートモデル

Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a heatport if use_heat_port; 
DummyHeatPort dummy_heatport; 

に使用されますときに

connector DummyHeatPort 
    "Dummy heatport to facilitate optional heatport. Use this with a conditional heatport by connecting it to the heatport. Then use the -DummyHeatPort.Q_flow in the thermal energy balance." 
    Modelica.SIunits.Temperature T "Port temperature"; 
    flow Modelica.SIunits.HeatFlowRate Q_flow 
    "Heat flow rate (positive if flowing from outside into the component)"; 
end DummyHeatPort; 

を...

equation 
flowport_a.H_flow + flowport_b.H_flow - dummy_heatport.Q_flow = storage 
    "thermal energy balance"; 
    connect(dummy_heatport, heatport); 

ヒートポートが存在する場合はヒートポートが使用されますが、それ以外の場合はエラーは発生しません。