Search code examples
modelicaopenmodelica

Can not assign values to an array when using sample() function


I'm trying to implement a DFT on my own because the FFT example in OpenModelica is not working for me and I can't figure out why. But I'm already stuck sampling a sine function and assigning the sampled values to a buffer array. This is why I tried to make it even simpler and just assign a counter variable "iTick" to the array which still doesn't work. See the basic example.

Can anyone tell me why this is not working and how I can actually assign a value to the array when using the sample() function ??

block DFT
  import Modelica.Constants.pi;

  parameter Integer N = 360 "Total number of samples";

  Integer iTick;
  Real y_buf[N];


algorithm

when sample(0, 0.1) then     
  iTick :=iTick + 1;

  if iTick >= 1 and iTick <= N then
    y_buf[iTick] := iTick;
  end if;
end when;

end DFT;
[358] 14:56:15 Symbolisch Warnung
The linear system: 
1 : $PRE.y_buf[2] = y_buf[2]
2 : y_buf[2] = $PRE.y_buf[2]
[
  -1.0 , 1.0 ;
  1.0 , -1.0
]
  *
[
  y_buf[2] ;
  $PRE.y_buf[2]
]
  =
[
  0.0 ;
  0.0
]
 might be structurally or numerically singular for variable $PRE.y_buf[2] since U(2,2) = 0.0. It might be hard to solve. Compilation continues anyway.

[359] 14:56:15 Symbolisch Warnung
The linear system: 
1 : $PRE.y_buf[1] = y_buf[1]
2 : y_buf[1] = $PRE.y_buf[1]
[
  -1.0 , 1.0 ;
  1.0 , -1.0
]
  *
[
  y_buf[1] ;
  $PRE.y_buf[1]
]
  =
[
  0.0 ;
  0.0
]
 might be structurally or numerically singular for variable $PRE.y_buf[1] since U(2,2) = 0.0. It might be hard to solve. Compilation continues anyway.

[360] 14:56:15 Übersetzung Warnung
Assuming fixed start value for the following 2 variables:
         y_buf[360]:DISCRETE(fixed = false )  type: Real  [360]
         iTick:DISCRETE(fixed = false )  type: Integer 

Solution

  • Your "Symbolisch Warnung" disappears once you initialize iTick and y_buf. However, the code still does not work. OpenModelica simulates it, but the items of y_buf are never updated.

    This issue might be related to this question where the delay operator is not working in algorithm sections. Therefore, I suggest a similar workaround: Try to avoid the algorithm section. With an equation section and proper initialization, your minimal example could look as follows:

    block DFT
      import Modelica.Constants.pi;
    
      parameter Integer N = 360 "Total number of samples";
    
      Integer iTick(start=0, fixed=true);
      Real y_buf[N](start=fill(0, N), fixed=fill(true, N));
    
    equation 
    
      when sample(0, 0.1) then
        iTick = pre(iTick) + 1;
      end when;
    
      for i in 1:N loop
        when iTick >= i then
          y_buf[i] =  iTick;
        end when;
      end for;
    
    end DFT;