是否只能在algorithm
的{{1}}范围内对整数表达式进行非离散分配?
如果算法中需要很多模型参数,那么直接在模型的算法部分计算输出值就会简单得多。
如果使用函数,则必须从环境中传递所有需要的参数值作为函数的输入。
在我看来,Modelica规范迫使一个人在函数内本地封装具有非离散赋值的整数。
这种整数赋值的一个可能用例是,人们希望将传递特性表示为具有紧凑支持的平滑基函数的总和。
对于计算,某个输入值x 1的输出值必须确定其支持包含x的基函数的索引。
我将一个更简单的列表数据线性插值的情况作为工作示例,其中必须找到插值间隔(即使这样的插值不可微)。
代码中的function
并不是真的需要,因为如果未给出注释noEvent(...)
,函数的算法部分内的关系不会生成事件。
尽管如此,我还是将它包含在显示整数GenerateEvents=true
的非离散赋值的位置。
i
在以下模型中,model testInterpol
function interpol
input Real x;
input Real tab[:,2];
output Real y;
protected
Integer i;
algorithm
i:=size(tab,1);
for ii in 2:size(tab,1) loop
if noEvent(x < tab[ii,1]) then
i := ii;
break;
end if;
end for;
y := tab[i-1,2] + (tab[i,2]-tab[i-1,2])/(tab[i,1]-tab[i-1,1])*(x-tab[i-1,1]);
end interpol;
Real x = 10*sin(8*atan(1.0)*time);
parameter Real tab[:,2]={{1,1},{2,4},{3,9},{5,25},{6,36}};
Real y;
equation
y = interpol(x,tab);
end testInterpol;
的类型已从Interpol
更改为function
。
请注意,这意味着对model
的使用进行了一些修改。
Interpol
OpenModelica 1.9.3 + dev(r25613)接受model testInterpolModel
model Interpol
input Real x;
input Real tab[:,2];
output Real y;
protected
Integer i;
algorithm
i:=size(tab,1);
for ii in 2:size(tab,1) loop
if noEvent(x < tab[ii,1]) then
i := ii;
break;
end if;
end for;
y := tab[i-1,2] + (tab[i,2]-tab[i-1,2])/(tab[i,1]-tab[i-1,1])*(x-tab[i-1,1]);
end Interpol;
Real x = 10*sin(8*atan(1.0)*time);
parameter Real tab[:,2]={{1,1},{2,4},{3,9},{5,25},{6,36}};
Real y;
Interpol interpol(x=x,tab=tab,y=y);
end testInterpolModel;
Dymola拒绝该模型,并显示以下错误消息:
testInterpolModel
在Modelica规范3.3 rev。的第12.2节“作为专业类的功能”中。 1人发现以下声明:
函数内部的函数组件就像它们具有离散时间可变性一样。
我不太清楚这意味着什么。如果只有规范中的这个句子并且没有使用Modelica工具的经验,那么可以认为函数的算法部分的语句仅在事件实例中进行评估,因为它们表现得好像它们具有离散时间的可变性。
但是,这种印象是错误的。如果注释Trying to assign a discrete variable inside a loop controlled by higher variability:
interpol.i = ii;
未明确设置为GenerateEvents
,函数的语句将始终执行,函数内的关系不会生成事件。
这在规范的第8.5节“事件和同步”中说明:
when子句中的所有方程式和赋值语句以及函数类中的所有赋值语句都被隐式地视为
true
函数,即这些运算符范围内的关系永远不会引发状态或时间事件。
Modelica错误跟踪器中已存在相关的票证:Ticket-Comment-Link
我有一个模糊的想法是,在函数和模型中处理整数变量的差异的实际原因是什么。
模型中的算法在概念上可以被解释为关于输入和输出的匿名函数(参见规范中的第11.1.2节“在模型中执行算法”)。在算法中分配的所有变量都成为匿名函数的输出,可以在算法之外的方程中使用。
但是,这些变量可能会在模型的其他部分引入不连续性。
命名函数的情况不同。无法从外部访问未声明为输入或输出的变量。因此,可以安全地设计函数,使得整数变量不会在整个模型中引入不连续性。
我的印象是,如果可以声明算法局部变量,问题就会解决。对于一个实例,可以允许在 noEvent
- 关键字之后声明algorithm
- i
等本地变量。
另一种解决方案是重新引入Modelica-Specification 1的关键字algorithm
。已经存在old Modelica ticket,其中在评论中提出了这样的重新引入。该提案只获得批准但没有任何反应。
关键字nondiscrete
可以在上面第二个示例代码中的nondiscrete
前面使用。由于变量Integer i;
和作业i
在这种情况下为i:=ii;
,因此nodiscrete
在算法中也是合法的。