問題の説明
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 MaterialStock
StockPort
ゼロ以下で排出できないストックコンポーネントmodel LinearDecline
接続されたストックを一定の速度 (ここでは 1 に設定) で排出することをモデル化するフロー要素FlowPort
(つまり、シンク) を持つフロー要素
主なモデルは、単純に を開始しstock
、それがで直線的に減少initialValue = 5
する に接続されています。process
declineRate = 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
を使用した私の実験も成功していません。)noEvent
if