Events 如何在Modelica中使用布尔开关来防止库存耗尽到零以下? 问题描述

Events 如何在Modelica中使用布尔开关来防止库存耗尽到零以下? 问题描述,events,modelica,openmodelica,systemmodeler,Events,Modelica,Openmodelica,Systemmodeler,我正在构建一个库来支持Modelica中的like建模。与Cellier等人的研究不同,我相信可以很好地利用acausal连接器:通过连接器将股票价值作为“潜在”进行传输,从而能够构建紧凑的组件(例如,流程=流程) 在SD中,我们可能会将材料(“质量”)股票与可能成为负值的信息类股票区分开来。为了支持这一点,我使用了质量端口的以下定义(此处给出了库存端口的定义-其对应的流量端口将仅具有布尔输入变量而不是输出变量,稍后将给出): 布尔开关指示库存的每个端口是否允许填充或排放 对于“物料库存”,停止

我正在构建一个库来支持Modelica中的like建模。与Cellier等人的研究不同,我相信可以很好地利用acausal连接器:通过连接器将股票价值作为“潜在”进行传输,从而能够构建紧凑的组件(例如,流程=流程)

在SD中,我们可能会将材料(“质量”)股票与可能成为负值的信息类股票区分开来。为了支持这一点,我使用了质量端口的以下定义(此处给出了
库存端口的定义-其对应的
流量端口将仅具有布尔输入变量而不是输出变量,稍后将给出):

布尔开关指示库存的每个端口是否允许填充或排放

对于“物料库存”,停止流出开关应防止库存排放到零以下。不幸的是,在下面的示例中,这将不起作用:库存将被排放到略低于零的位置

使用连接器的最小示例 以下
TestModel
使用这些构建块:

  • 函数约束rate(指示的速率、停止流入、停止流出)
    用于返回符合给定约束的速率(即布尔开关)

  • 连接器StockPort
    如上所述

  • connector FlowPort
    StockPort
  • model MaterialStock
    带有一个
    StockPort
    且在零度以下不可排水的库存组件
  • 模型线性倾斜
    带有一个
    出油口(即水槽)的流量元件,该出油口以恒定速率(此处设置为1)对连接的物料进行排水建模
主模型只需启动一个
股票
,其
初始值=5
,该股票连接到一个
过程
,即
递减率=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;
model TestModel“停止在零度以下消耗库存”
函数constrainedRate“根据库存信号设置端口速率”
输入实际指示数据“流量元件端口的建议速率”;
输入“来自连接股票的信号”;
输入布尔停止流出“来自连接股票的信号”;
输出实际“使用率”;
受保护的
//检查指示利率是否为负值(例如,流入相关股票)
布尔indRateIsInflow=指示值小于0;
算法
//如果停止信号与流量特征匹配,则将速率设置为零
实际流率:=如果流入率为流入率且停止流入
然后0
否则,如果不流入并停止流出
然后0
其他指标为D;
末端约束状态;
连接器流量端口“用于表示库存和流量连接”
实际库存“关联库存的当前库存水平(如潜力)或特殊库存的流量数据”;
实际流量“影响材料库存的流量”;
输入布尔stopInflow“True表示没有任何东西可以流入股票”;
输入布尔stopOutflow“True表示库存中没有任何东西可以流出”;
末端出油口;
连接器StockPort“用于表示库存和流量连接”
实际股票“股票现值”;
流量实际利率“影响库存的流量”;
输出布尔stopInflow“True表示没有任何东西可以流入库存”;
输出布尔stopOutflow“True表示库存中没有任何东西可以流出”;
斯托克波特终点;
模型材料库存“零度以下不能排放的库存”
斯托克港流出;
参数实初始值;
受保护的
实x(开始=初始值);
方程式
//股票的变动率
der(x)=流出率;
//端口应具有库存级别信息
流出量.存量=x;
//流入股票是不受限制的
流出。停止流入=假;
//如果库存为负,则提供布尔信号

你能测试一下这个溶液吗?使用Modelica.Constants.eps对我很有用。我还使用了Dassl,它适用于不同的步长。 我将以下行从更改为:

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

您是否尝试过设置布尔值,不是通过与0比较,而是通过一些较小的值,如Modelica.Constants.eps或similiar?例如:stopOutflow=x@f.wue谢谢。我刚刚试过,但不幸的是没有用。我试过DASSL(固定间隔大小)和Euler(不同步长),但您的解决方案在Wolfram System Modeler(4.3)或Open Modelica中都不起作用。我添加了
assert(x>=0,“股票必须始终为正”)
以使模拟在出现负值时停止。它总是停下来。我在dymola中进行了测试,也许这就是产生不同结果的原因。您机器上的负值是否也很小(如e-12)或更大?有
outflow.stock=noEvent(如果x>0,那么x else 0)
起作用。在这种情况下,数字“问题”停留在组件内部,如果绝对需要,当x正常时,
。最后,这取决于你想建模什么。如果经常出现接近零的库存值(接近零是指e-4左右),您可能需要使用noEvent或when解决方案。但是,如果您对较大的值进行建模,则您的模型很可能对如此小的值无效。因此,你可以使用比eps(我相信是e-15)更大的。我不明白为什么建模更大的值会使非零检查无效——它们根本不适用?
// 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;
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.]