具有零时间常数的一阶 Modelica 模型

First order Modelica model with null time constant

我想弄清楚在 Modelica 中是否有可能(并且在语义上合法)模拟一阶传递函数的模型,时间常数等于零(下面的 T)。我使用的是 OpenModelica 1.15.0~dev-48-g3656b95,但我是在一般的 Modelica 上下文中提问的。

我的背景是在 Modelica 模型上试验模型降阶,这让我尝试使用 Modelica.Blocks.Continuous.FirstOrder 有时为空 时间常数。但是,为了使讨论更简单,这是我正在研究的平面模型(标准 FirstOrder 块的简化和改编):

model FirstOrderZero
  import Modelica.SIunits;

  Real u "input";
  Real y "output";

  parameter Real k(unit="1")=1 "Gain";
  constant SIunits.Time T=0 "Time Constant";

equation
  u = 1;
  der(y) = (k*u - y)/T;

end FirstOrderZero;

我理解 Modelica 工具运行符号方程分析的方式,时间常数 T 应该是 constant 而不是 parameter。实际上,对于 T=0,微分方程退化为代数方程 y = k*u。除非 Modelica 仿真工具可以为 T 的不同值生成不同的代码路径(我认为没有 Modelica 工具可以做到这一点,除了未来的 Modia 之外?),T 是否为 null 的事实应该在方程分析开始时决定。

我不明白的是为什么上面的模型无法模拟("division by zero at time 0 [...] where divisor expression is 0.0" 使用 OM 1.15 dev)而 它有效 当最后一个方程被重写为:

 T*der(y) = (k*u - y);

我假设符号方程分析应该自动重新制定方程? (我可以通过 OM Transformational Debugger 看到等式变为 der(y) = (k - y)/0.0,当然,在模拟时会中断)。

或者,用空常量除法编写 Modelica 方程在语法上是非法的吗?

T 的可变性

如果时间常数 T 是常量,则参数或(离散)变量取决于您要执行的操作。

  • 常量的值在翻译过程中得到修复
  • 翻译后可以更改参数(因此在模拟开始之前),但不能在模拟期间更改
  • 离散变量可以在模拟过程中改变它们的值,但只能在事件实例中改变
  • 连续变量可以在模拟过程中改变它们的值

有关详细信息,请参阅 Modelica 规范 3.4 中的 4.4.4 Component Variability Prefixes discrete, parameter, constant

对于一阶元素,您通常使用在模拟过程中不会改变的传递函数,但用户应该能够设置 T 的值。因此 parameter 将是自然的选择。

为什么你的模拟失败了

通过为 T 使用常量,与使用参数相比,Modelica 工具可以更优化您的方程式。根据您编写方程式的方式,您最终会得到不同的优化方程式。

对于 constant T=0,您的原始模型减少到

model FirstOrderZero
  Real u, y;
  parameter Real k=1;
equation 
  u = 1;
  der(y) = (k*u - y)/0;
end FirstOrderZero;

要求解 y 需要其导数 der(y) - 但无法计算,因为总是会被零除。

在第二种情况下 T*der(y) = (k*u - y); 你的模型减少到

model FirstOrderZero
  Real u, y;
  parameter Real k=1;
equation 
  u = 1;
  0 * der(y) = (k*u - y);
end FirstOrderZero;

等式 0 * der(y) = (k*u - y) 结果 0 = (k*u - y),因此 y = k*u。没有被零除,可以模拟模型

你看,尽管 Modelica 是一种非因果语言,但如何编写方程式可能很重要。

你能做什么

T=0的一阶元件不再是一阶元件,只是比例增益。要对其建模,请使用块 Modelica.Blocks.Continuous.TransferFunction.

如果 T 不为零,参数化如下:

Modelica.Blocks.Continuous.TransferFunction transferFunction(b={k}, a={T,1})

如果它的零使用

Modelica.Blocks.Continuous.TransferFunction transferFunction(b={k}, a={1})