问题描述
我正在构建一个库来支持系统动力学 (SD),例如 Modelica 中的建模。与Cellier 等人免费提供的库不同。我相信人们可以很好地利用非因果连接器:通过连接器将库存价值作为“潜在”传输可以构建紧凑的组件(例如流程 = 流程)。
在 SD 中,我们可能会将物质(“大众”)股票与可能变为负数的信息股票区分开来。为了支持这一点,我对质量端口使用以下定义(这里给出 a 的定义StockPort
- 它的对应物 aFlowPort
将简单地具有布尔输入变量而不是输出变量,稍后给出):
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
一个带有一个FlowPort
(即 Sink)的流量元素,它模拟以恒定速率(此处设置为 1)排出连接的库存
主模型简单地启动一个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;
使用 DASSL 从 模拟模型StartTime = 0
揭示StopTime = 10
变量的预期行为stock.outflow.stock
:
不幸的是,该值略低于零t = 5.0
。
不知何故,事件(股票价值 <= 0)被检测到太晚了。我能做些什么?
(到目前为止,imo 不优雅的解决方法是使用when
事件(状态事件)reinit
将库存值归零。我在语句和布尔条件上使用noEvent
包装器的实验if
也没有成功。)