OpenModelica中WHEN语句导致的非线性错误

OpenModelica中WHEN语句导致的非线性错误,modelica,openmodelica,Modelica,Openmodelica,我正在使用OpenModelica对一个复杂的系统进行建模,并且面临一个棘手的错误 错误出现在when语句中,如图所示 am使用when语句确定膨胀阀中的质量流量 为了确认错误出现在when语句中,我删除了它,并将质量流量与计算质量流量的公式相等,这意味着问题出现在when语句中 如果有人能帮助我,请通常的解决方案是在离散值变量上引入pre。不幸的是没有,所以我们必须介绍一个 所以不是 when level<min_level then port.e_dbM=0.12;

我正在使用OpenModelica对一个复杂的系统进行建模,并且面临一个棘手的错误 错误出现在when语句中,如图所示 am使用when语句确定膨胀阀中的质量流量 为了确认错误出现在when语句中,我删除了它,并将质量流量与计算质量流量的公式相等,这意味着问题出现在when语句中
如果有人能帮助我,请

通常的解决方案是在离散值变量上引入pre。不幸的是没有,所以我们必须介绍一个

所以不是

  when level<min_level then 
    port.e_dbM=0.12;
  end when;
它将是:

   Boolean belowMin=level<min_level;
 equation
  when pre(belowMin) then
    port.e_dbM=0.12;
  end when;
艾尔斯当也是如此


这是中问题的答案和错误消息的副本:-我们可能需要一个更通用的问题和答案作为此问题的标准答案。

通常的循环解决方案是在离散值变量上引入pre。不幸的是没有,所以我们必须介绍一个

所以不是

  when level<min_level then 
    port.e_dbM=0.12;
  end when;
它将是:

   Boolean belowMin=level<min_level;
 equation
  when pre(belowMin) then
    port.e_dbM=0.12;
  end when;
艾尔斯当也是如此


这是中问题的答案和错误消息的副本:-我们可能需要一个更通用的问题和答案作为规范。

从您的描述中,我看到变量dbM是一个连续变量。我认为使用when语句是不正确的。让我们先解决这个问题

推理:when语句中的条件仅在条件指示器开始改变其符号的时间点触发事件一次,即液位值-min值为正值后变为负值。数值解算器通常能够成功识别符号发生这种变化的时间点。在这个时间点,比如说,一个事件被触发

触发事件后,将在时间t_e计算when语句中的等式。对于以下模拟时间步,即t>t_e,不再计算该方程。相反,connect语句生成的公式作为默认公式而不是when语句中的公式

因此,尝试使用if语句而不是when语句来表示边界条件。if语句类似于微积分中的分支函数,这里就是这种情况

我认为另一个答案所述的同样情况也可能发生在if中。您可能需要遵循此处所述的类似方法

如果If语句仍然存在错误,则可以尝试noEvent操作符,请参阅。这不是精确正确的数字,但仍然是缩小此类错误可能原因的一种方法

更新:如何使用if而不是when: 为了用简单的用例来说明这个想法,假设主方程如下所示:

myMassFlowRate = port_e.dbM; 
为了表示边界条件,可以引入辅助变量:

if liquid_level_value < min_value then 
  tmp = 0.012;
elseif liquid_level_value > max_value then
  tmp = 0; 
else
  tmp = port_e.dbM;
end if;
myMassFlowRate = tmp;
可变液位可通过I/O端口进行通信,以设置流速:

if level == normal then 
   myMassFlowRate = port_e.dbM; 
elseif level == below then
   myMassFlowRate = 0; 
else 
   myMassFlowRate = 0.012; 
end if; 

这与你的描述相符。使用when直接设置实变量只是重新初始化。

从您的描述中,我看到变量dbM是一个连续变量。我认为使用when语句是不正确的。让我们先解决这个问题

推理:when语句中的条件仅在条件指示器开始改变其符号的时间点触发事件一次,即液位值-min值为正值后变为负值。数值解算器通常能够成功识别符号发生这种变化的时间点。在这个时间点,比如说,一个事件被触发

触发事件后,将在时间t_e计算when语句中的等式。对于以下模拟时间步,即t>t_e,不再计算该方程。相反,connect语句生成的公式作为默认公式而不是when语句中的公式

因此,尝试使用if语句而不是when语句来表示边界条件。if语句类似于微积分中的分支函数,这里就是这种情况

我认为另一个答案所述的同样情况也可能发生在if中。您可能需要遵循此处所述的类似方法

如果If语句仍然存在错误,则可以尝试noEvent操作符,请参阅。这不是精确正确的数字,但仍然是缩小此类错误可能原因的一种方法

更新:如何使用if而不是when: 为了用简单的用例来说明这个想法,假设主方程如下所示:

myMassFlowRate = port_e.dbM; 
为了表示边界条件,可以引入辅助变量:

if liquid_level_value < min_value then 
  tmp = 0.012;
elseif liquid_level_value > max_value then
  tmp = 0; 
else
  tmp = port_e.dbM;
end if;
myMassFlowRate = tmp;
可变液位可通过I/O端口进行通信,以设置流速:

if level == normal then 
   myMassFlowRate = port_e.dbM; 
elseif level == below then
   myMassFlowRate = 0; 
else 
   myMassFlowRate = 0.012; 
end if; 
这个
与您的描述相符。使用when直接设置一个实变量只是一个重新初始化。

在花了很多天的时间试图解决发布的问题后,我找到了一个解决非线性错误的方法 我在WHEN Station内部使用了一个布尔值,该布尔值将使用IF Station控制质量流量,如下所示:

 when liquid_level_valve < min_valve then
 open_valve = true;
elsewhen liquid_level_valve > max_valve then
 open_valve = false;
end when;
port_e.dbM = if open_tev then dbM_valve else 1 / 100000;
其中,使用与阀门相对应的方程式计算dbM。 现在我的系统可以正常工作了


感谢所有试图帮助我的人

在花了许多天的时间试图解决发布的问题后,我找到了解决非线性错误的方法 我在WHEN Station内部使用了一个布尔值,该布尔值将使用IF Station控制质量流量,如下所示:

 when liquid_level_valve < min_valve then
 open_valve = true;
elsewhen liquid_level_valve > max_valve then
 open_valve = false;
end when;
port_e.dbM = if open_tev then dbM_valve else 1 / 100000;
其中,使用与阀门相对应的方程式计算dbM。 现在我的系统可以正常工作了


感谢所有试图帮助我的人

您是如何申报port_e.dbM的?它是声明为离散变量还是连续变量?当我使用流连接器时,它是否涉及到其他方程式?我将其命名为connecter,以便其:。连接器端口e,端口s;变量dbM怎么样。我的印象是它是一个连续变量而不是离散变量,即它被声明为实dbM而不是离散实dbM?。在这种情况下,我怀疑您需要使用if语句而不是when-statement;流量介质。质量流量dbM;中等绝对压力p;流介质比焓h;端部连接器_A;您是如何声明port_e.dbM的?它是声明为离散变量还是连续变量?当我使用流连接器时,它是否涉及到其他方程式?我将其命名为connecter,以便其:。连接器端口e,端口s;变量dbM怎么样。我的印象是它是一个连续变量而不是离散变量,即它被声明为实dbM而不是离散实dbM?。在这种情况下,我怀疑您需要使用if语句而不是when-statement;流量介质。质量流量dbM;中等绝对压力p;流介质比焓h;端部连接器_A;感谢您花时间回答我,我尝试了您的建议,但仍然得到相同的错误我不明白您是否完全添加了以下内容-如果是,我不知道:Boolean belowMin=levelmax\u level;当prebelowMin然后port.e_dbM=0.12时的方程;elsewhen PreboveMax然后port.e_dbM=0.0;结束时;感谢您花时间回答我,我尝试了您的建议,但仍然得到相同的错误我不明白您是否完全添加了以下内容-如果是,我不知道:Boolean belowMin=levelmax\u level;当prebelowMin然后port.e_dbM=0.12时的方程;elsewhen PreboveMax然后port.e_dbM=0.0;结束时;关于更多细节,我使用when语句控制进入储罐的质量流量,质量流量由when语句控制,当储罐中的液位低于某个最小值时,质量流量将通过一个确定的方程式计算,当储罐中的液位达到最大液位时,质量流量将等于零,我不能使用IF语句,这是我从描述中理解的,我认为使用when是错误的。很明显,不能在if语句中直接设置dbM,否则方程组将不一致,即方程组多于未知数。需要一个额外的辅助变量,请参阅后面的更新答案。有关更多详细信息,我使用when语句控制进入储罐的质量流量,质量流量由when语句控制,当储罐中的液位低于某个最小值时,质量流量将通过一个确定的方程式计算,当储罐中的液位达到最大液位时,质量流量将等于零,我不能使用IF语句,这是我从描述中理解的,我认为使用when是错误的。很明显,不能在if语句中直接设置dbM,否则方程组将不一致,即方程组多于未知数。需要一个额外的辅助变量,请参阅答案的更新以了解背后的想法。