7

特定のコンポーネント(私の場合は流体ポート)が存在するかどうかに基づいて、わずかに異なる方程式を持つモデルを構築しようとしています。

次のようなコードは機能しません。

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

どうすればこれを回避できますか?

4

3 に答える 3

10

条件コンポーネントを使用する場合は、注意が必要ないくつかの制限があります。Modelica 3.3仕様のセクション4.4.5は、それをうまくまとめています。「条件がfalseの場合、コンポーネント、その修飾子、およびコンポーネントに関連する接続方程式はすべて削除されます」と表示されます。これを使用して問題を解決する方法をすぐに説明しますが、最初に、解決策が機能しない理由を説明したいと思います。

問題はモデルのチェックに関係しています。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.xが存在しない場合、存在する可能性はありませんcomponentしかし、私たちは一般的にそのようなことを証明できますか?いいえ。

そのため、条件付きコンポーネントが導入されたときに、関係する変数と方程式のセットが「同期しなくなる」ことがないように常に簡単に保証できる保守的なセマンティクスが実装されました。

仕様の内容に戻りましょう。「条件がfalseの場合、コンポーネント、その修飾子、およびコンポーネントに関連する接続方程式はすべて削除されます」

あなたの場合、解決策は非常に単純である可能性があります。component「x」の宣言方法によっては、に変更を加えることができます。

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

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

残りの2つの選択肢があります。まず、方程式をのcomponent.x中に入れcomponentます。2つ目は、コネクタを導入するcomponentことです。接続すると、必要な方程式が生成されます。変更の場合と同様に(これは偶然ではありません)、xある種の入力コネクタに関連付けてから、次のようにすることができます。

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

connectさて、3つのケース(修正、方程式の内部化、使用)をすべて検討した後、どれも機能しないという結論に達したと想像できます。その場合は、コンポーネントの設計方法に問題があることをお勧めします。これらの制限が発生する理由は、コンポーネント自体が正しいかどうかをチェックする必要性に関連しています。これには、コンポーネントが完全である必要があります(仕様の用語では「バランスが取れている」)。

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

于 2013-02-04T13:56:16.187 に答える
1

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

これがお役に立てば幸いです。

マルコ

于 2013-02-04T10:56:34.760 に答える
0

グラフィカルレイヤーに表示されないダミーコンポーネントを作成することもできます。

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;

次に、これが2ポートモデルで使用される場合

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

..。

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

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

于 2014-02-12T14:43:06.587 に答える