﻿id	summary	reporter	owner	description	type	status	priority	milestone	component	version	resolution	keywords	cc
5144	Inefficient translation of models with vectorized components	Rüdiger Franke	Per Östlund	"This issue follows up #5110. It sketches an important use case for arrays: vectorized model components. The following model was created using OMEdit (stripped graphical annotations here):
{{{#!mo
model Vectorized
  parameter Integer n = 3;
  Modelica.Blocks.Continuous.Integrator integrator1[n];
  Modelica.Blocks.Interfaces.RealInput u[n];
  Modelica.Blocks.Interfaces.RealOutput y[n];
equation
  connect(u, integrator1.u);
  connect(integrator1.y, y);
  annotation(
    uses(Modelica(version = ""3.2.2"")));
end Vectorized;
}}}
`omc -d=newInst,-nfScalarize` only declares `u` and `y` as arrays and rolls out everything else:
{{{#!mo
class Vectorized
  parameter Integer n = 3;
  parameter Real integrator1[1].k(unit = ""1"") = 1.0 ""Integrator gain"";
  parameter enumeration(NoInit, SteadyState, InitialState, InitialOutput) integrator1[1].initType = Modelica.Blocks.Types.Init.InitialState ""Type of initialization (1: no init, 2: steady state, 3,4: initial output)"";
  parameter Real integrator1[1].y_start = 0.0 ""Initial or guess value of output (= state)"";
  Real integrator1[1].u ""Connector of Real input signal"";
  Real integrator1[1].y(start = integrator1[1].y_start) ""Connector of Real output signal"";
  parameter Real integrator1[2].k(unit = ""1"") = 1.0 ""Integrator gain"";
  parameter enumeration(NoInit, SteadyState, InitialState, InitialOutput) integrator1[2].initType = Modelica.Blocks.Types.Init.InitialState ""Type of initialization (1: no init, 2: steady state, 3,4: initial output)"";
  parameter Real integrator1[2].y_start = 0.0 ""Initial or guess value of output (= state)"";
  Real integrator1[2].u ""Connector of Real input signal"";
  Real integrator1[2].y(start = integrator1[2].y_start) ""Connector of Real output signal"";
  parameter Real integrator1[3].k(unit = ""1"") = 1.0 ""Integrator gain"";
  parameter enumeration(NoInit, SteadyState, InitialState, InitialOutput) integrator1[3].initType = Modelica.Blocks.Types.Init.InitialState ""Type of initialization (1: no init, 2: steady state, 3,4: initial output)"";
  parameter Real integrator1[3].y_start = 0.0 ""Initial or guess value of output (= state)"";
  Real integrator1[3].u ""Connector of Real input signal"";
  Real integrator1[3].y(start = integrator1[3].y_start) ""Connector of Real output signal"";
  input Real[3] u;
  output Real[3] y;
initial equation
  integrator1[3].y = integrator1[3].y_start;
  integrator1[2].y = integrator1[2].y_start;
  integrator1[1].y = integrator1[1].y_start;
equation
  u[1] = integrator1[1].u;
  u[2] = integrator1[2].u;
  u[3] = integrator1[3].u;
  integrator1[1].y = y[1];
  integrator1[2].y = y[2];
  integrator1[3].y = y[3];
  der(integrator1[1].y) = integrator1[1].k * integrator1[1].u;
  der(integrator1[2].y) = integrator1[2].k * integrator1[2].u;
  der(integrator1[3].y) = integrator1[3].k * integrator1[3].u;
end Vectorized;
}}}

The desired result should read instead:
{{{#!mo
class VectorizedDesired
  parameter Integer n = 3;
  parameter Real integrator1.k[n](unit = ""1"") = 1.0 ""Integrator gain"";
  parameter enumeration(NoInit, SteadyState, InitialState, InitialOutput) integrator1.initType[n] = Modelica.Blocks.Types.Init.InitialState, ""Type of initialization (1: no init, 2: steady state, 3,4: initial output)"";
  parameter Real integrator1.y_start[n] = 0.0 ""Initial or guess value of output (= state)"";
  Real integrator1.u[n] ""Connector of Real input signal"";
  Real integrator1.y[n](start = integrator1.y_start) ""Connector of Real output signal"";
  input Real[3] u;
  output Real[3] y;
initial equation
  integrator1.y = integrator1.y_start;
equation
  u = integrator1.u;
  integrator1.y = y;
  der(integrator1.y) = integrator1.k .* integrator1.u;
end VectorizedDesired;
}}}
A couple of interesting questions arises:
1. Should array dimensions be ""normalized"" by collecting them at the end, i.e. `integrator1.u[n]` instead of `integrator1[n].u`?
2. Can `n` be kept as structural parameter during the translation?
2. Is `each` required for `Real integrator1.y[n](start = 0.0)`. The current implementation (see #5110) works fine without `each`.
3. Are initializations of arrays with scalars allowed, i.e. `parameter Real integrator1.y_start[n] = 0.0`? This would simplify the generation of efficient code, i.e. a for loop assigning `0.0` to each array element instead of creation of a temporary array resulting from `fill(0.0, n)`.
4. Note: the operator changes from `*` to `.*`! This appears quite tricky if possible at all in the general case.
5. Shall the frontend better introduce a for loop for all equations of a vectorized component and the backend keep that loop, analyzing only one iteration of it?
{{{#!mo
...
equation
  for i in 1:n loop
    u[i] = integrator1.u[i];
    integrator1.y[i] = y[i];
    der(integrator1.y[i]) = integrator1.k[i] * integrator1.u[i];
  end for;
end VectorizedDesired;
}}}
"	enhancement	closed	high	2.0.0	New Instantiation		fixed		Adrian Pop Willi Braun Bernhard Bachmann Francesco Casella Karim Adbdelhak
