4

問題の説明

Modelica でのモデリングのようなシステム ダイナミクス (SD)をサポートするライブラリを構築しています。Cellierらによる無料で入手可能なライブラリとは異なります。非因果的コネクタをうまく利用できると確信しています。コネクタを介してストック値を「潜在的」として送信することで、コンパクトなコンポーネント (フロー = プロセスなど) を構築できます。

SD では、材料 (「質量」) の在庫と、マイナスになる可能性のある情報在庫を区別することができます。これをサポートするために、質量ポートに次の定義を使用しています(ここで a の定義を与えますStockPort- その対応する a はFlowPort、単に出力変数の代わりにブール入力変数を持ち、後で与えられます):

 connector StockPort "Used to represent stock and flow connections"
    Real stock "Current value of material in the stock";
    flow Real rate "Flow that affects the stock";
    // Boolean switches
    output Boolean stopInflow "True indicates that nothing can flow into the stock";
    output Boolean stopOutflow "True indicates that nothing can flow out of the stock";
 end StockPort;

ブールスイッチは、ストックのポートごとに、充填または排出が許可されているかどうかを示します。

材料在庫」の場合、stopOutflowスイッチは在庫がゼロ以下にならないようにする必要があります。残念ながら、次の例ではこれはうまくいきません:在庫はゼロをわずかに下回って排出されます。

コネクタを使用した最小限の例

以下TestModelでは、これらのビルディング ブロックを使用します。

  • function constrainedRate( indicated rate, stopInflow, stopOutflow)指定された制約 (つまり、ブール スイッチ) に準拠するレートを返すために使用されます。

  • connector StockPort上記のように

  • connector FlowPortに対応するStockPort
  • model MaterialStockStockPortゼロ以下で排出できないストックコンポーネント
  • model LinearDecline接続されたストックを一定の速度 (ここでは 1 に設定) で排出することをモデル化するフロー要素FlowPort(つまり、シンク) を持つフロー要素

なモデルは、単純に を開始しstock、それがで直線的に減少initialValue = 5する に接続されています。processdeclineRate = 1

model TestModel "Stop draining a stock below zero"

  function constrainedRate "Set rate for a port according to signals from stock" 
    input Real indicatedRate "Proposed rate for port of flow element";
    input Boolean stopInflow "Signal from connected stock";
    input Boolean stopOutflow "Signal from connected stock";
    output Real actualRate "The rate to use";
  protected
    // check whether indicated rate is negative (e.g. an inflow to the connected stock)
    Boolean indRateIsInflow = indicatedRate < 0;
  algorithm
    // set rate to zero if stopSignal matches character of flow
    actualRate := if indRateIsInflow and stopInflow 
          then 0 
        elseif not indRateIsInflow and stopOutflow 
          then 0 
        else indicatedRate;
  end constrainedRate;

  connector FlowPort "Used to represent stock and flow connections"
    Real stock "The current stock level (e.g. Potential) of a connected stock or flow data for special stocks";
    flow Real rate "Flows that affect the material stock";
    input Boolean stopInflow "True indicates that nothing can flow into the stock";
    input Boolean stopOutflow "True indicates that nothing can flow out of the stock";
  end FlowPort;

  connector StockPort "Used to represent stock and flow connections"
    Real stock "Current value of stock";
    flow Real rate "Flow that affects the stock";
    output Boolean stopInflow "True indicates that nothing can flow into the stock";
    output Boolean stopOutflow "True indicates that nothing can flow out of the stock";
  end StockPort;

  model MaterialStock "Stock that cannot be drained below zero"
    StockPort outflow;
    parameter Real initialValue;
  protected
    Real x(start = initialValue);
  equation
    // rate of change for the stock
    der(x) = outflow.rate;
    // ports shall have level information for stock
    outflow.stock = x;
    // inflow to stock is unrestricted
    outflow.stopInflow = false;
    // provide Boolean signal in case of negative stock
    outflow.stopOutflow = x <= 0;
  end MaterialStock;

  model LinearDecline "Decline of stock at a constant rate"
    FlowPort massPort;
    parameter Real declineRate(min = 0) "Rate of decline (positive rate diminishes stock)";
  protected
    // a positive rate should drain the stock (which here matches Modelica's rule for flows)
    Real rate(min = 0);
  equation
    rate = declineRate;
    // observe stock signals and constraints
    assert(rate >= 0, "Rate must be positive and will be set to zero", level = AssertionLevel.warning);
  // set the rate according to constraints given by stock
    massPort.rate = constrainedRate( max(rate, 0), massPort.stopInflow, massPort.stopOutflow );
  end LinearDecline;

  // main model
  MaterialStock stock( initialValue = 5 );
  LinearDecline process( declineRate = 1 );
equation
  connect( stock.outflow, process.massPort );
end TestModel;

StartTime = 0からまでのDASSL を使用してモデルをシミュレートするStopTime = 10と、変数 の予想される動作が明らかになりますstock.outflow.stock

株価

残念ながら、以降は値がわずかにゼロを下回っていますt = 5.0

どういうわけか、イベント (在庫値 <= 0) の検出が遅すぎます。私に何ができる?

(これまでのところ、最も洗練されていない治療法は、whenイベント (状態イベント) を使用して株式の値をゼロにすることでした。ステートメントとブール条件でラッパーreinitを使用した私の実験も成功していません。)noEventif

4

1 に答える 1

2

このソリューションをテストしていただけますか? Modelica.Constants.eps を使用するとうまくいきます。Dassl も使用しましたが、さまざまなステップサイズで機能しました。次の行を次のように変更しました。

// provide Boolean signal in case of negative stock
outflow.stopOutflow = x <= 0;

// provide Boolean signal in case of negative stock
outflow.stopOutflow = x <= Modelica.Constants.eps;

次に、出力配列 (この投稿では Python で表示):

Output using a zero instead of eps:
[ 5.00000000e+00  4.00000000e+00  3.00000000e+00  2.00000000e+00
  1.00000000e+00  0.00000000e+00 -7.37276906e-12 -7.37276906e-12
 -7.37276906e-12 -7.37276906e-12 -7.37276906e-12 -7.37276906e-12
 -7.37276906e-12 -7.37276906e-12]
Output using eps:
[5. 4. 3. 2. 1. 0. 0. 0. 0. 0. 0. 0. 0.]
于 2019-02-18T19:40:27.887 に答える