对整数变量的非离散赋值

Tob*_*ias 18 modelica

表达式的非离散赋值是否只能在algorithm一个整数内function

如果算法中需要许多模型参数,则直接在模型的算法部分中计算输出值会简单得多.

如果使用函数,则必须从环境中传递所有需要的参数值作为函数的输入.

在我看来,Modelica规范迫使一个人在函数内本地封装具有非离散赋值的整数.

这种整数赋值的一个可能的用例是,人们希望将传递特性表示为具有紧凑支持的平滑基函数的总和.

对于计算,某个输入值x 1的输出值必须确定其支持包含x的基函数的索引.

我将列表数据的线性插值的更简单的情况作为工作示例,其中必须找到插值间隔(即使这样的插值不可微).

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;
Run Code Online (Sandbox Code Playgroud)

在以下模型中,类型Interpol从更改functionmodel.

请注意,这意味着对使用的一些修改Interpol.

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;
Run Code Online (Sandbox Code Playgroud)
  • OpenModelica 1.9.3 + dev(r25613)接受 testInterpolModel

  • Dymola拒绝该模型,并显示以下错误消息:

    Trying to assign a discrete variable inside a loop controlled by higher variability:
    interpol.i = ii;
    
    Run Code Online (Sandbox Code Playgroud)

在第12.2节"Modelica规范3.3版本的"作为专业类的功能"中.1人发现以下声明:

函数内部的函数组件表现得好像它们具有离散时间的可变性.

我不太清楚这意味着什么.如果只有规范中的这个句子并且没有使用Modelica工具的经验,那么可以认为函数的算法部分的语句仅在事件实例中进行评估,因为它们表现得好像它们具有离散时间的可变性.但是,这种印象是错误的.如果GenerateEvents未明确设置注释,则始终执行函数的语句,并且函数内的关系不会生成事件true.

这在规范的第8.5节"事件和同步"中说明:

when子句中的所有方程式和赋值语句以及函数类中的所有赋值语句都被隐式地视为noEvent函数,即这些运算符范围内的关系不会引发状态或时间事件.

Modelica错误跟踪器中已存在相关票证:Ticket-Comment-Link

我有一个含糊的想法是,在函数和模型中处理整数变量的差异的实际原因是什么.

模型中的算法在概念上可以被解释为关于输入和输出的匿名函数(参见规范中的第11.1.2节"在模型中执行算法").在算法中分配的所有变量都成为匿名函数的输出,并且可以在算法之外的等式中使用.

但是,这些变量可能会在模型的其他部分引入不连续性.

命名函数的情况不同.无法从外部访问未声明为输入或输出的变量.因此,可以安全地设计该函数,使得整数变量不会在整个模型中引入不连续性.

我的印象是,如果可以声明算法局部变量,问题就会得到解决.对于一个实例,一个可能允许声明algorithm-本地变量,如i 之后algorithm-keyword.

另一种解决方案是重新引入nondiscreteModelica-Specification 1 的关键字.已经存在一个旧的Modelica票证,其中在评论中提出了这样的重新引入.该提案只获得批准但没有任何反应.

该关键字nondiscrete可以在Integer i;上面的第二个示例代码中使用.由于变量i和赋值i:=ii;nodiscrete在这种情况下noEvent在算法中也是合法的.