Opened 6 years ago

Last modified 3 years ago

#5496 new defect

Model structure and Jacobian for vectorized models

Reported by: Rüdiger Franke Owned by: Lennart Ochel
Priority: high Milestone:
Component: Backend Version:
Keywords: Cc: Karim Adbdelhak

Description

FMU export with -d,newInst,-nfScalarize generates wrong FMI ModelStructure and Jacobian.
See this example from the test suite:

https://github.com/OpenModelica/OpenModelica-testsuite/blob/master/openmodelica/cppruntime/testVectorizedBlocks.mos

Here is a version extended with the additional output y_sum and reduced to n=3:

model VectorizedBlocksTest
  parameter Integer n = 3;
  Modelica.Blocks.Interfaces.RealInput u[n](start = 1:n);
  Modelica_Synchronous.ClockSignals.Clocks.PeriodicRealClock periodicClock1(period = 0.1, useSolver=true, solverMethod="ImplicitEuler");
  Modelica_Synchronous.RealSignals.Sampler.AssignClockVectorized assignClock1(n = n);
  Modelica.Blocks.Continuous.Integrator integrator1[n](y_start = 1:n);
  Modelica.Blocks.Interfaces.RealOutput y[n];
  Modelica.Blocks.Interfaces.RealOutput y_sum;
equation
  y_sum = sum(y);
  connect(u, assignClock1.u);
  connect(periodicClock1.y, assignClock1.clock);
  connect(assignClock1.y, integrator1.u);
  connect(integrator1.y, y);
  annotation(
    uses(Modelica(version = "3.2.2"), Modelica_Synchronous(version = "0.92.1")));
end VectorizedBlocksTest;

Apply this command sequence

setCommandLineOptions("--simCodeTarget=Cpp"); getErrorString();
setCommandLineOptions("--std=3.3"); getErrorString();
setCommandLineOptions("-d=newInst"); getErrorString();
//setCommandLineOptions("-d=newInst,disableFMIDependency"); getErrorString();
//setCommandLineOptions("-d=newInst,-nfScalarize"); getErrorString();

loadFile("VectorizedBlocksTest.mo"); getErrorString();
translateModelFMU(VectorizedBlocksTest, version = "2.0"); getErrorString();

The flag -d=newInst gives the correct model structure (see modelDescription.xml):

  <ModelStructure>
    <Outputs>
      <Unknown index="29" dependencies="1 26" dependenciesKind="dependent depend
ent" />
      <Unknown index="30" dependencies="2 27" dependenciesKind="dependent depend
ent" />
      <Unknown index="31" dependencies="3 28" dependenciesKind="dependent depend
ent" />
      <Unknown index="32" dependencies="1 2 3 26 27 28" dependenciesKind="depend
ent dependent dependent dependent dependent dependent" />
    </Outputs>
    <DiscreteStates>
      <Unknown index="23" dependencies="1 26" dependenciesKind="dependent depend
ent" />
      <Unknown index="24" dependencies="2 27" dependenciesKind="dependent depend
ent" />
      <Unknown index="25" dependencies="3 28" dependenciesKind="dependent depend
ent" />
    </DiscreteStates>
  </ModelStructure>

The flags -d=newInst,disableFMIDependency bypass dependency analysis and just list the correct variables in the model structure:

  <ModelStructure>
    <Outputs>
      <Unknown index="29" dependencies="" dependenciesKind="" />
      <Unknown index="30" dependencies="" dependenciesKind="" />
      <Unknown index="31" dependencies="" dependenciesKind="" />
      <Unknown index="32" dependencies="" dependenciesKind="" />
    </Outputs>
    <DiscreteStates>
      <Unknown index="23" dependencies="" dependenciesKind="" />
      <Unknown index="24" dependencies="" dependenciesKind="" />
      <Unknown index="25" dependencies="" dependenciesKind="" />
    </DiscreteStates>
  </ModelStructure>

The flags -d=newInst,-nfScalarize lead to a wrong dependency analysis:

  <ModelStructure>
    <Outputs>
      <Unknown index="29" dependencies="1 26" dependenciesKind="dependent depend
ent" />
      <Unknown index="32" dependencies="1 26" dependenciesKind="dependent depend
ent" />
    </Outputs>
    <DiscreteStates>
      <Unknown index="23" dependencies="1 26" dependenciesKind="dependent depend
ent" />
    </DiscreteStates>
  </ModelStructure>

The vectorized sim code obtained with -d=newInst,-nfScalarize,dumpSimCode reads:

25: $CLKPRE.integrator1.y=integrator1.y [Real[3] ]
16: assignClock1.u=u [Real[3] ]
17: assignClock1.y=assignClock1.u [Real[3] ]
18: integrator1.u=assignClock1.y [Real[3] ]
19 FOR-LOOP:  for $i in (1:3) loop
$DER.integrator1[$i].y=integrator1[$i].u[Real ]
end for;
20 FOR-LOOP:  for i in (1:3) loop
integrator1[i].y=(if firstTick() then 0.0 else $DER.integrator1[i].y) * interval() + previous(integrator1[i].y)[Real ]
end for;
21: $outputAlias_y=integrator1.y [Real[3] ]
22: $outputAlias_y_sum=sum($outputAlias_y) [Real ]
23: y_sum=$outputAlias_y_sum [Real ]
24: y=$outputAlias_y [Real[3] ]

The Jacobian code of the backend needs to be extended with the treatment of

  • 1:1 assignments of arrays
  • for-loops
  • sum of vector

Change History (5)

comment:1 by Rüdiger Franke, 6 years ago

Cc: Karim Adbdelhak added

comment:2 by Francesco Casella, 5 years ago

Milestone: 1.14.01.16.0

Releasing 1.14.0 which is stable and has many improvements w.r.t. 1.13.2. This issue is rescheduled to 1.16.0

comment:3 by Francesco Casella, 4 years ago

Milestone: 1.16.01.17.0

Retargeted to 1.17.0 after 1.16.0 release

comment:4 by Francesco Casella, 4 years ago

Milestone: 1.17.01.18.0

Retargeted to 1.18.0 because of 1.17.0 timed release.

comment:5 by Francesco Casella, 3 years ago

Milestone: 1.18.0

Ticket retargeted after milestone closed

Note: See TracTickets for help on using tickets.