modelicaopenmodelica

How to use an initial equation to determine parameter values?


I am trying to declare a table that is correlated to another one. My goal is to declare a table with dimensions (nlines, 2) and then create another table that starts with a given value and evolves in the same manner as the first table. To achieve this, I use initial equations because I want the correlated data to be ready before the simulation starts.

However, in the simple model below, I encounter an issue where the correlated table contains only zeros.

Is there an error in my code?

Is it possible to achieve this using a component without adding additional code to my model?

code :

model CorrelateCoefficients
  import Modelica.Blocks.Sources;
  import Modelica.Utilities.Streams;
  import Modelica.Math.Vectors;

// Original tables with reduced dimensions
  parameter Real Flow_A[5, 2] = [0, 0.600; 100, 0.500; 200, 0.400; 300, 0.300; 400, 0.200];
                                 
  parameter Real Flow_B[5, 2] = [0, 2.000; 100, 1.500; 200, 1.000; 300, 0.500; 400, 0.250];
  // Parameters
  parameter Real coef_conv_A = 1000;
  parameter Real coef_conv_B = 5000;
  // Variables for correlated tables
  parameter Real correlatedCoef_A[size(Flow_A, 1), 2];
  parameter Real correlatedCoef_B[size(Flow_B, 1), 2];
  // Use the correlated tables in TimeTable blocks for visualization
  Modelica.Blocks.Sources.TimeTable CorrelatedCoef_A(table = correlatedCoef_A, timeScale = 1) annotation(
    Placement(transformation(origin={20,38}, extent={{-10,-10},{10,10}})));
  
  Modelica.Blocks.Sources.TimeTable CorrelatedCoef_B(table = correlatedCoef_B, timeScale = 1) annotation(
    Placement(transformation(origin={20,2}, extent={{-10,-10},{10,10}})));
  Modelica.Blocks.Sources.TimeTable timeTable(table = Flow_A)  annotation(
    Placement(transformation(origin = {-60, 42}, extent = {{-10, -10}, {10, 10}})));
  Modelica.Blocks.Sources.TimeTable timeTable1(table = Flow_B)  annotation(
    Placement(transformation(origin = {-56, -2}, extent = {{-10, -10}, {10, 10}})));
initial equation
// Correlate coef_conv_A with Flow_A
  for i in 1:size(Flow_A, 1) loop
    correlatedCoef_A[i, 1] = Flow_A[i, 1];
    correlatedCoef_A[i, 2] = (Flow_A[i, 2] / max(Flow_A[:, 2])) * coef_conv_A;
  end for;
// Correlate coef_conv_B with Flow_B
  for i in 1:size(Flow_B, 1) loop
    correlatedCoef_B[i, 1] = Flow_B[i, 1];
    correlatedCoef_B[i, 2] = Flow_B[i, 2] / max(Flow_B[:, 2]) * coef_conv_B;
  end for;
// Print the correlated tables for debugging
  for i in 1:size(correlatedCoef_A, 1) loop
    Streams.print("Time: " + String(correlatedCoef_A[i, 1]) + ", Coefficient A: " + String(correlatedCoef_A[i, 2]));
  end for;

  for i in 1:size(correlatedCoef_B, 1) loop
    Streams.print("Time: " + String(correlatedCoef_B[i, 1]) + ", Coefficient B: " + String(correlatedCoef_B[i, 2]));
  end for;



annotation(
    uses(Modelica(version = "4.0.0")));
end CorrelateCoefficients;

Solution

  • By default, parameters need to be computed when they are declared (=binding equation). There is a possibility though e.g. mentioned in Modelica Specification Section 4.4.3. By adding fixed=false to the parameter's definition, they can be computed in the initial equation section. For your example code, this means that the declaration of the parameters need to be changed to:

      parameter Real correlatedCoef_A[size(Flow_A, 1), 2](each fixed=false);
      parameter Real correlatedCoef_B[size(Flow_B, 1), 2](each fixed=false);
    

    With the change above, the code works in OpenModelica and Dymola (even the 'each' can be skipped in Dymola). I think this should do what you need, although slight changes to the code are necessary...