Modelica中无事件的开/关控制

Modelica中无事件的开/关控制,modelica,Modelica,我试图控制一个基于电网电压的并网光伏系统。 这个想法是这样的:当电网电压上升到VMax以上时,我想关闭系统进行延时关闭。当超时结束时,我想再次打开,但仅当电网电压低于VMax时 我目前有两个实现;两者都在创造许多活动,我想知道是否有更有效的方法。现在是这样实施的: package Foo model PVControl1 "Generating most events" parameter Real VMax=253; parameter Real timeOff=60; input Rea

我试图控制一个基于电网电压的并网光伏系统。 这个想法是这样的:当电网电压上升到VMax以上时,我想关闭系统进行延时关闭。当超时结束时,我想再次打开,但仅当电网电压低于VMax时

我目前有两个实现;两者都在创造许多活动,我想知道是否有更有效的方法。现在是这样实施的:

package Foo
model PVControl1 "Generating most events"

parameter Real VMax=253;
parameter Real timeOff=60;

input Real P_init "uncontrolled power";
input Real VGrid;
Real P_final "controlled power";
Boolean switch (start = true) "if true, system is producing";
discrete Real restartTime (start=-1, fixed=true) 
  "system is off until time>restartTime";

equation
when {VGrid > VMax, time > pre(restartTime)} then
  if VGrid > VMax then
    switch = false;
    restartTime = time + timeOff;
  else
    switch = true;
    restartTime = -1;
  end if;
end when;

if pre(switch) then
  P_final = P_init;
else
  P_final = 0;
end if;
end PVControl1;

model PVControl2;
  "Generating less events, but off-time is no multiple of timeOff"

parameter Real VMax=253;
parameter Real timeOff=60;

input Real P_init "uncontrolled power";
input Real VGrid;
Real P_final "controlled power";
discrete Real stopTime( start=-1-timeOff, fixed=true) 
  "system is off until time > stopTime + timeOff";

equation 
when VGrid > VMax then
  stopTime=time;
end when;

if noEvent(VGrid > VMax) or noEvent(time < stopTime + timeOff) then
  P_final = 0;
else
  P_final = P_init;
end if;
end PVControl2;

model TestPVControl;
  "Simulate 1000s to get an idea"

PVControl pvControl2(P_init=4000, VGrid = 300*sin(time/100));
end TestPVControl;

end foo;
包Foo
模型PVControl1“生成大多数事件”
参数Real VMax=253;
参数Real-timeOff=60;
输入实P_init“不受控功率”;
输入真实矢量网格;
实际P_最终“受控功率”;
布尔开关(start=true)“如果为true,则系统正在生成”;
离散实时重启时间(start=-1,fixed=true)
“系统关闭,直到时间>重新启动时间”;
方程式
当{VGrid>VMax,time>pre(restartTime)}时
如果VGrid>VMax,则
开关=假;
重启时间=时间+关闭时间;
其他的
开关=真;
重启时间=-1;
如果结束;
结束时;
如果是前置(开关),则
P_final=P_init;
其他的
P_final=0;
如果结束;
末端控制1;
模型PV2;
生成的事件较少,但“关闭时间”不是“关闭时间”的倍数
参数Real VMax=253;
参数Real-timeOff=60;
输入实P_init“不受控功率”;
输入真实矢量网格;
实际P_最终“受控功率”;
离散实时停止时间(start=-1-timeOff,fixed=true)
“系统关闭,直到时间>停止时间+关闭”;
方程式
当VGrid>VMax时
停止时间=时间;
结束时;
如果noEvent(VGrid>VMax)或noEvent(时间<停止时间+关闭时间),则
P_final=0;
其他的
P_final=P_init;
如果结束;
末端控制2;
模型控制;
“模拟1000秒获得想法”
PVControl pvControl2(P_init=4000,VGrid=300*sin(时间/100));
结束测试控制;
完富;;
运行时,我使用PVControl1获得8个事件,使用PVControl2获得4个事件。 看看PVControl2,实际上我只需要在VGrid变得比VMax大的时刻发生一个事件。这将只提供2个事件。当VGrid再次降至VMax以下时,将生成其他2个事件

有没有办法进一步改进我的模型?
谢谢
罗尔

我有几点意见。我认为您将事件视为when子句中的等式被激活时的事件。但这并不完全正确。当离散变量的值发生变化时发生事件。关键是,连续积分器必须在该点停止,方程与新值积分

为了理解这种情况对您的影响,您应该考虑匿名表达式(如您的WHO子句中的一个)可能被视为一个匿名的离散变量。换句话说,您可以将其视为等同于:

Boolean c1 = VGrid > VMax;

when c1 then
  ...
end when;
…需要注意的是,当
VGrid
大于
VMax
和小于
VMax
时,都会发生事件(即
c1
值的变化)。现在考虑这个问题:

Boolean c1 = VGrid > VMax;
Boolean c2 = time > pre(restartTime);

when {c1, c2} then
  ...
end when;
现在您有了更多的事件,因为涉及到两个条件,每次其中一个改变值时都会生成事件

话虽如此,您是否真的存在性能问题?通常,只有在“抖动”(条件值因积分过程中的数值噪声而改变符号的情况下)时,此类事件才会成为问题。您是否有任何数字表明这些事件在多大程度上是一个问题?了解您正在使用什么工具来模拟这些东西也可能会有所帮助

最后,从您的逻辑中我不明白的一件事是,如果VGrid>VMax,然后在超时之后,VGrid仍然大于VMax,会发生什么


假设它正确地处理了最后一种情况,我认为PVControl2实际上是您想要的(并且生成了我预期的事件数量以及我预期的原因)。

可能我的答案是一年半太晚了,但在这种情况下,系统似乎不僵硬,在这种情况下,显式积分器(如Dymola中的CERK积分器)将使模拟运行时间更快

迈克尔,谢谢你的回答。澄清一下:我使用的是dymola 7.4 FOD1。是的,这些事件是一个问题。我有一个相当大的模型,33个光伏系统连接到电网(每个系统看到不同的VGrid)。当我激活PVControl1时,模型速度急剧减慢(系数3),一年内我有35k个事件。不幸的是,当我尝试PVControl2时,dymola在翻译或编译时崩溃。我正在与dymola支持部门联系以解决此问题。实际上,主要的问题仍然存在:有没有一种方法可以在不产生事件的情况下关闭我的光伏系统?我当然可以这样关闭它:
P_final=if noEvent(VGrid>VMax),那么0 else P_init我将没有事件,但模型变得不稳定,甚至无法求解,因为解算器不知道是打开还是关闭它(关闭它将使VGrid再次降低到VMax以下)。我唯一能想到的是查看积分参数和/或公差。你有一个非常长的运行模拟(1年),动态速度非常快(切换周期为60秒?)。这可能是因为积分器浪费了大量的精力,试图占用非常大的时间步,但由于事件截断了时间步而失败。虽然通常我最不推荐使用固定时间步积分器,但它在您的情况下可能是有意义的(至少值得一试)。除此之外,尝试不同的积分算法和不同的公差,看看这是否有帮助。学习永远不会太迟。。。我仍在处理同一类型的模型,所以我将查看此解算器。不过,我担心这个系统很僵硬,但也许它能工作。感谢您的回答,欢迎来到stackoverflow:-)