OpenModelica新前端编译报错:离散变量未在when语句左值的解决方法
OpenModelica新前端编译报错的修复方案
问题说明
使用OpenModelica 1.22.1-64bit版本时,SimpleTest2模型在旧前端可正常编译,但新前端编译时报错:
Following variable is discrete, but does not appear on the LHS of a when-statement: 'x'
原模型代码
model SimpleTest2 "just a simple model - Compilation etc." Modelica.Blocks.Interfaces.RealInput u annotation(Placement(visible = true, transformation(origin = {-100, 40}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-80, 40}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); Modelica.Blocks.Interfaces.RealOutput y annotation(Placement(visible = true, transformation(origin = {100, 20}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {100, 20}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); protected discrete Real x; algorithm x := u; when change(x) then y := y + 2; end when; annotation(Icon(coordinateSystem(extent = {{-100, -100}, {100, 100}}, preserveAspectRatio = true, initialScale = 0.1, grid = {2, 2})), Diagram(coordinateSystem(extent = {{-100, -100}, {100, 100}}, preserveAspectRatio = true, initialScale = 0.1, grid = {2, 2}), graphics = {Rectangle(origin = {-6.15, 2.93}, fillColor = {0, 133, 199}, fillPattern = FillPattern.HorizontalCylinder, extent = {{-77.89, 83.75}, {88.14, -92.53}})})); end SimpleTest2;
报错原因
新前端严格执行Modelica规范:离散变量必须在when语句的左侧(LHS)赋值,确保其仅在事件触发点更新。原代码中discrete Real x直接在algorithm块的非when部分赋值,不符合规范要求。
修改方案
将x的赋值逻辑移至when语句中,同时可以合并冗余的事件检查逻辑,修改后的代码如下:
model SimpleTest2 "just a simple model - Compilation etc." Modelica.Blocks.Interfaces.RealInput u annotation(Placement(visible = true, transformation(origin = {-100, 40}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-80, 40}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); Modelica.Blocks.Interfaces.RealOutput y annotation(Placement(visible = true, transformation(origin = {100, 20}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {100, 20}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); protected discrete Real x; algorithm when change(u) then x := u; y := y + 2; end when; annotation(Icon(coordinateSystem(extent = {{-100, -100}, {100, 100}}, preserveAspectRatio = true, initialScale = 0.1, grid = {2, 2})), Diagram(coordinateSystem(extent = {{-100, -100}, {100, 100}}, preserveAspectRatio = true, initialScale = 0.1, grid = {2, 2}), graphics = {Rectangle(origin = {-6.15, 2.93}, fillColor = {0, 133, 199}, fillPattern = FillPattern.HorizontalCylinder, extent = {{-77.89, 83.75}, {88.14, -92.53}})})); end SimpleTest2;
关键修改点
- 把
x := u移到when change(u)的语句块内,让离散变量x仅在u变化时更新,符合Modelica规范 - 合并原有的
when change(x)逻辑到同一个when块中,既保留原模型功能(u变化时y加2),又避免冗余的事件检查
如果需要保留原有的change(x)触发逻辑,也可以采用以下修改方式:
model SimpleTest2 "just a simple model - Compilation etc." Modelica.Blocks.Interfaces.RealInput u annotation(Placement(visible = true, transformation(origin = {-100, 40}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-80, 40}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); Modelica.Blocks.Interfaces.RealOutput y annotation(Placement(visible = true, transformation(origin = {100, 20}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {100, 20}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); protected discrete Real x; algorithm when change(u) then x := u; end when; when change(x) then y := y + 2; end when; annotation(Icon(coordinateSystem(extent = {{-100, -100}, {100, 100}}, preserveAspectRatio = true, initialScale = 0.1, grid = {2, 2})), Diagram(coordinateSystem(extent = {{-100, -100}, {100, 100}}, preserveAspectRatio = true, initialScale = 0.1, grid = {2, 2}), graphics = {Rectangle(origin = {-6.15, 2.93}, fillColor = {0, 133, 199}, fillPattern = FillPattern.HorizontalCylinder, extent = {{-77.89, 83.75}, {88.14, -92.53}})})); end SimpleTest2;
内容的提问来源于stack exchange,提问作者Prims
相关产品推荐
相关产品推荐

