OpenModelica中停止时间过高时FFT的模拟结果错误或没有

OpenModelica中停止时间过高时FFT的模拟结果错误或没有,modelica,openmodelica,Modelica,Openmodelica,我使用OpenModelica的realFFT库来分析PWM信号中的频率。 当我分析10 kHz以下的频率时,一切正常。 但是,一旦我将最大频率设置为10 kHz以上,我的模拟要么计算错误的结果,要么崩溃,要么说它模拟了,但没有显示结果 到目前为止,我发现: 我的采样周期为8.3us,采样数为ns=6000,最大频率为f_max=12kHz,分辨率为f_res=20Hz,这导致停止时间>=(6000-1)*8.3us-->停止时间>=0.05s(根据库)。 所以我用这个stopTime进行了模拟

我使用OpenModelica的realFFT库来分析PWM信号中的频率。 当我分析10 kHz以下的频率时,一切正常。 但是,一旦我将最大频率设置为10 kHz以上,我的模拟要么计算错误的结果,要么崩溃,要么说它模拟了,但没有显示结果

到目前为止,我发现: 我的采样周期为8.3us,采样数为ns=6000,最大频率为f_max=12kHz,分辨率为f_res=20Hz,这导致停止时间>=(6000-1)*8.3us-->停止时间>=0.05s(根据库)。 所以我用这个stopTime进行了模拟,它工作了,但是当我设置stopTime=0.1s时,它没有显示任何结果,只是说它模拟得很好。当我进一步将停止时间增加到0.2秒时,它计算出了错误的结果

这对我来说没有意义,为什么它会因为停止时间增加而失败呢? 这可能是OpenModelica的另一个问题,并且可以与Dymola配合使用吗

以下是我的模型:

model TestRealFFT
  Modelica.Blocks.Sources.Pulse pulse1(amplitude = 1, offset = 0, period = 100e-6, width = 40) annotation(
    Placement(visible = true, transformation(origin = {-168, 16}, extent = {{-60, -60}, {60, 60}}, rotation = 0)));
  FFTmath fFTmath1(f_max = 12000, f_res = 20) annotation(
    Placement(visible = true, transformation(origin = {176, 8}, extent = {{-80, -80}, {80, 80}}, rotation = 0)));
equation
  connect(pulse1.y, fFTmath1.u) annotation(
    Line(points = {{-102, 16}, {68, 16}, {68, 8}, {80, 8}}, color = {0, 0, 127}));
  annotation(
    stopTime = 2,
    Diagram(coordinateSystem(extent = {{-300, -250}, {300, 250}})),
    Icon(coordinateSystem(extent = {{-300, -250}, {300, 250}})),
    __OpenModelica_commandLineOptions = "",
    experiment(StartTime = 0, StopTime = 0.2, Tolerance = 1e-06, Interval = 8e-06));
end TestRealFFT;

型号FFTmath
导入Modelica.Constants.{pi};
导入Modelica.Math.FastFourierTransform.*;
导入Modelica.SIunits.*;
Modelica.Blocks.Interfaces.RealInput u注释(
位置(可视=真,变换(原点={-120,0},区段={-20,-20},{20,20},旋转=0),iconTransformation(原点={-120,0},区段={-20,-20},{20,20},旋转=0));
参数频率f_max=12000“最大关注频率”;
参数频率f_res=20“频率分辨率”;
最终参数整数ns=realffsamplepoints(f_max,f_res,f_max_factor=5)“样本数”;
最终参数整数nf=div(ns,2)+1“频点数”;
最终参数Integer nfi=max(1,min(Integer(ceil(f_max/f_res))+1,nf));
最终参数频率f_i[nfi](每个固定=假)“相关频点的FFT频率”;
参数时间采样周期=1/(2*f_res*div(ns,2));
输出整数信息(开始=0,固定=true)“来自FFT计算的信息标志”;
整数iTick(开始=0,固定=true);
离散实Buf[ns](开始=零(ns),每个固定=真)“输入缓冲区”;
实A_i[nfi](开始=零(nfi),每个固定=真)“FFT振幅”;
实Phi_i[nfi](开始=零(nfi),每个固定=真)“FFT相位”;
实y(开始=0,固定=真);
//“计算FFT的信号”;
初始方程
对于1:nfi循环中的i
f_i[i]=(i-1)*f_res;
结束于;
方程式
算法
当采样(0,采样周期)时
iTick:=iTick+1;
y:=u;

如果iTick看起来像OpenModelica中的bug。请开一张关于这件事的票

问题1庞大的结果文件正在中断
使用OpenModelica(v1.14.0-dev-26633-gd9901afc5b)模拟0.05秒模拟时间时,结果mat文件已为1.06 GB。在0.1秒的时间内,您将获得大约2.1 GB的容量和损坏的标头

问题2错误结果
当您模拟区间[0,0.2]时,解决方案是完全错误的。
y
的值约为1.4e+31,
time
上升到5e+218。可能是因为结果文件已损坏。
但是,即使你减少了容差和间隔,它也无法正确模拟,可能是因为大量的事件

在Dymola 2019中工作,但需要大量时间打开结果文件

model FFTmath
  import Modelica.Constants.{pi};
  import Modelica.Math.FastFourierTransform.*;
  import Modelica.SIunits.*;
  Modelica.Blocks.Interfaces.RealInput u annotation(
    Placement(visible = true, transformation(origin = {-120, 0}, extent = {{-20, -20}, {20, 20}}, rotation = 0), iconTransformation(origin = {-120, 0}, extent = {{-20, -20}, {20, 20}}, rotation = 0)));
  parameter Frequency f_max = 12000 "Maximum frequency of interest";
  parameter Frequency f_res = 20 "Frequency resolution";
  final parameter Integer ns = realFFTsamplePoints(f_max, f_res, f_max_factor = 5) "Number of samples";
  final parameter Integer nf = div(ns, 2) + 1 "Number of frequency points";
  final parameter Integer nfi = max(1, min(integer(ceil(f_max / f_res)) + 1, nf));
  final parameter Frequency f_i[nfi](each fixed = false) "FFT frequencies of interested frequency points";
  parameter Time samplePeriod = 1 / (2 * f_res * div(ns, 2));
  output Integer info(start = 0, fixed = true) "Information flag from FFT computation";
  Integer iTick(start = 0, fixed = true);
  discrete Real Buf[ns](start = zeros(ns), each fixed = true) "Input buffer";
  Real A_i[nfi](start = zeros(nfi), each fixed = true) "FFT amplitudes";
  Real Phi_i[nfi](start = zeros(nfi), each fixed = true) "FFT phases";
  Real y(start = 0, fixed = true);
  // "Signal from which FFT is computed";
initial equation
  for i in 1:nfi loop
    f_i[i] = (i - 1) * f_res;
  end for;
equation

algorithm
  when sample(0, samplePeriod) then
    iTick := iTick + 1;
    y := u;
    if iTick <= ns then
      Buf[iTick] := y;
    end if;
    if iTick == ns then
      (info, A_i, Phi_i) := realFFT(Buf, nfi);
    end if;
  end when;
//3 * sin(2  * pi * f1 * time) + sin(2 * pi * f2 * time);
  annotation(
    Documentation(Icon(graphics = {Text(origin = {-42, 62}, extent = {{110, -78}, {-30, 18}}, textString = "FFT"), Rectangle(origin = {0, -79}, fillPattern = FillPattern.Solid, extent = {{-80, -1}, {80, 1}}), Rectangle(origin = {-79, -49}, fillPattern = FillPattern.Solid, extent = {{-1, -29}, {1, 29}}), Polygon(origin = {-79, -15}, fillPattern = FillPattern.Solid, points = {{0, -5}, {-6, -5}, {0, 5}, {6, -5}, {6, -5}, {0, -5}}), Polygon(origin = {85, -79}, rotation = -90, fillPattern = FillPattern.Solid, points = {{0, -5}, {-6, -5}, {0, 5}, {6, -5}, {6, -5}, {0, -5}}), Rectangle(origin = {-59, -65}, fillPattern = FillPattern.Solid, extent = {{-1, 23}, {1, -15}}), Ellipse(origin = {-59, -39}, fillPattern = FillPattern.Solid, extent = {{-3, 3}, {3, -3}}, endAngle = 360), Ellipse(origin = {-49, -61}, fillPattern = FillPattern.Solid, extent = {{-3, 3}, {3, -3}}, endAngle = 360), Ellipse(origin = {-19, -53}, fillPattern = FillPattern.Solid, extent = {{-3, 3}, {3, -3}}, endAngle = 360), Ellipse(origin = {25, -67}, fillPattern = FillPattern.Solid, extent = {{-3, 3}, {3, -3}}, endAngle = 360), Ellipse(origin = {31, -49}, fillPattern = FillPattern.Solid, extent = {{-3, 3}, {3, -3}}, endAngle = 360), Rectangle(origin = {-49, -65}, fillPattern = FillPattern.Solid, extent = {{-1, 1}, {1, -15}}), Rectangle(origin = {31, -65}, fillPattern = FillPattern.Solid, extent = {{-1, 15}, {1, -15}}), Rectangle(origin = {-19, -63}, fillPattern = FillPattern.Solid, extent = {{-1, 7}, {1, -15}}), Rectangle(origin = {25, -63}, fillPattern = FillPattern.Solid, extent = {{-1, -5}, {1, -15}}), Ellipse(origin = {-67, -61}, fillPattern = FillPattern.Solid, extent = {{-3, 3}, {3, -3}}, endAngle = 360), Rectangle(origin = {-67, -63}, fillPattern = FillPattern.Solid, extent = {{-1, 1}, {1, -15}}), Rectangle(origin = {37, -63}, fillPattern = FillPattern.Solid, extent = {{-1, -5}, {1, -15}}), Ellipse(origin = {37, -67}, fillPattern = FillPattern.Solid, extent = {{-3, 3}, {3, -3}}, endAngle = 360), Line(points = {{-100, 100}, {100, 100}, {100, -100}, {-100, -100}, {-100, 100}, {-100, 100}}, thickness = 0.5)}),
    Diagram,
    __OpenModelica_commandLineOptions = "");
end FFTmath;