Dymola/Modelica - 如何仅在稳定状态下计算信号的平均值?
Dymola/Modelica - How can I calculate the mean of a signal only in the steady state?
我正在努力计算我的 Modelica 模型中连续信号的平均值。问题是我只对计算稳态的平均值感兴趣。例如,在所附模型(最小、可重现示例)中,我想计算 40 到 60 秒之间的平均值。因此,我首先尝试使用 Modelica.Blocks.Math.ContinuousMean
但 t_0
是受保护的,所以我在我的个人库中写了一个类似的代码(它也是附件)。
但是,有一个错误,我无法弄清楚发生了什么。有人可以阐明这个简单的问题吗?提前致谢!!!
型号:
model MeanExampleWhosebug
parameter Modelica.SIunits.Time period=3;
final parameter Real angularFrecuency=(2*Modelica.Constants.pi)/period;
parameter Real amplitude=2;
Real signal;
Real mean;
PersonalLibrary.Utilities.ContinuosMeanStartTime meanBlock(t_0=40);
equation
signal = amplitude*sin(angularFrecuency*time) + log(time*100 + 1);
meanBlock.u = signal;
meanBlock.y = mean;
end MeanExampleWhosebug;
块保存在个人图书馆:
block ContinuosMeanStartTime "Similar block as Continuos Mean in MSL but with unprotected Start time (t_0)"
extends Modelica.Blocks.Icons.Block;
parameter Modelica.SIunits.Time t_eps(min=0.0) = 1e-7 "Mean value calculation starts at startTime + t_eps";
parameter Modelica.SIunits.Time t_0(min=0.0) = 0 "Start time";
Modelica.Blocks.Interfaces.RealInput u "Noisy input signal";
Modelica.Blocks.Interfaces.RealOutput y "Expectation (mean) value of the input signal";
protected
Real mu "Internal integrator variable";
initial equation
mu = u;
equation
der(mu) = noEvent(if time >= t_0 + t_eps then (u - mu)/(time - t_0) else 0);
y = noEvent(if time >= t_0 + t_eps then mu else u);
end ContinuosMeanStartTime;
最后,这里有一些显示我想要实现的结果(已经用其他软件编辑结果)。
最好的问候。
注意:顺便问一下,有没有其他方法可以访问MSL中的受保护参数而不是写入新块?
目前不能用t_eps
实现,只是为了防止被零除。
如果 t_0
被曝光,可能会改变它。
当我 运行 你的代码时,我收到一个错误,指出奇点出现在 t=40.
我认为你基本上在 t= t_0 + t_eps 处遇到了一个数值问题,因为你突然在 mu 上有了一个具有特征值的微分方程time-t_0,在 if 条件变为真之后是 t_eps,因此非常小,是求解器的问题。
这里有一些解决方法:
- 使用另一个求解器(对我来说 DASSL 没有 运行 通过,但 LSODAR 有效),有些求解器可能更适合您的特定数值挑战
- 增加 t_eps(对我来说 t_eps > 1e-6 的模型 运行s 左右),所以时间的特征值= t_0 + t_eps 变大
- 删除 noEvent(我不太确定为什么这会解决问题,我的猜测是,然后事件触发 DASSL 的重置,并减小其步长, 因此可以处理快速特征值。这也可以解释为什么原始模型 Modelica.Blocks.Math.ContinuousMean 在时间 = t_0 + t_eps 起作用,因为这里的 if 语句在开始后立即变为真的模拟,其中 DASSL 处于与事件发生后相似的状态并且使用非常小的步长。但这些只是有根据的猜测。)
你的代码的另一件事是,如果你想创建绿线,你必须将 ContinuosMeanStartTime 块的输出更改为
y = mu;
否则你会得到 信号 作为你在 time= 40 + t_eps.
之前的平均值
我正在努力计算我的 Modelica 模型中连续信号的平均值。问题是我只对计算稳态的平均值感兴趣。例如,在所附模型(最小、可重现示例)中,我想计算 40 到 60 秒之间的平均值。因此,我首先尝试使用 Modelica.Blocks.Math.ContinuousMean
但 t_0
是受保护的,所以我在我的个人库中写了一个类似的代码(它也是附件)。
但是,有一个错误,我无法弄清楚发生了什么。有人可以阐明这个简单的问题吗?提前致谢!!!
型号:
model MeanExampleWhosebug
parameter Modelica.SIunits.Time period=3;
final parameter Real angularFrecuency=(2*Modelica.Constants.pi)/period;
parameter Real amplitude=2;
Real signal;
Real mean;
PersonalLibrary.Utilities.ContinuosMeanStartTime meanBlock(t_0=40);
equation
signal = amplitude*sin(angularFrecuency*time) + log(time*100 + 1);
meanBlock.u = signal;
meanBlock.y = mean;
end MeanExampleWhosebug;
块保存在个人图书馆:
block ContinuosMeanStartTime "Similar block as Continuos Mean in MSL but with unprotected Start time (t_0)"
extends Modelica.Blocks.Icons.Block;
parameter Modelica.SIunits.Time t_eps(min=0.0) = 1e-7 "Mean value calculation starts at startTime + t_eps";
parameter Modelica.SIunits.Time t_0(min=0.0) = 0 "Start time";
Modelica.Blocks.Interfaces.RealInput u "Noisy input signal";
Modelica.Blocks.Interfaces.RealOutput y "Expectation (mean) value of the input signal";
protected
Real mu "Internal integrator variable";
initial equation
mu = u;
equation
der(mu) = noEvent(if time >= t_0 + t_eps then (u - mu)/(time - t_0) else 0);
y = noEvent(if time >= t_0 + t_eps then mu else u);
end ContinuosMeanStartTime;
最后,这里有一些显示我想要实现的结果(已经用其他软件编辑结果)。 最好的问候。
注意:顺便问一下,有没有其他方法可以访问MSL中的受保护参数而不是写入新块?
目前不能用t_eps
实现,只是为了防止被零除。
如果 t_0
被曝光,可能会改变它。
当我 运行 你的代码时,我收到一个错误,指出奇点出现在 t=40.
我认为你基本上在 t= t_0 + t_eps 处遇到了一个数值问题,因为你突然在 mu 上有了一个具有特征值的微分方程time-t_0,在 if 条件变为真之后是 t_eps,因此非常小,是求解器的问题。
这里有一些解决方法:
- 使用另一个求解器(对我来说 DASSL 没有 运行 通过,但 LSODAR 有效),有些求解器可能更适合您的特定数值挑战
- 增加 t_eps(对我来说 t_eps > 1e-6 的模型 运行s 左右),所以时间的特征值= t_0 + t_eps 变大
- 删除 noEvent(我不太确定为什么这会解决问题,我的猜测是,然后事件触发 DASSL 的重置,并减小其步长, 因此可以处理快速特征值。这也可以解释为什么原始模型 Modelica.Blocks.Math.ContinuousMean 在时间 = t_0 + t_eps 起作用,因为这里的 if 语句在开始后立即变为真的模拟,其中 DASSL 处于与事件发生后相似的状态并且使用非常小的步长。但这些只是有根据的猜测。)
你的代码的另一件事是,如果你想创建绿线,你必须将 ContinuosMeanStartTime 块的输出更改为
y = mu;
否则你会得到 信号 作为你在 time= 40 + t_eps.
之前的平均值