Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to eliminate dead code in Dymola/Modelica

I am trying to slim down a very complex model to improve performance, and noticed big performance changes when I add or remove variables into the signal bus, especially multi-body frames.

I am wondering if there is any setting that can eliminate code that isn't involved in generating outputs from the model.

I tried setting the bus connector to "protected" to ensure it doesn't become an output but the code to calculate them is still being generated.

I also tried these flags but it doesn't eliminate the dead code:

Advanced.Embedded.OptimizeForOutputs=true;
Advanced.SubstituteVariablesUsedOnce=true;
Evaluate=true;
Advanced.EvaluateAlsoTop=true;
Advanced.SubstituteVariablesUsedOnce=true;

This is a simple model to replicate the scenario:

simple modelica model

model TestBusConnector
  extends Modelica.Icons.Example;
protected 
        Modelica.Blocks.Examples.BusUsage_Utilities.Interfaces.ControlBus controlBus
    annotation (Placement(transformation(extent={{-20,-20},{20,20}})));
public 
  Modelica.Blocks.Sources.Sine sine(freqHz=1)
    annotation (Placement(transformation(extent={{-40,-50},{-20,-30}})));
  Modelica.Blocks.Sources.Constant const(k=0)
    annotation (Placement(transformation(extent={{-10,50},{10,70}})));
  Modelica.Blocks.Interfaces.RealOutput y
    annotation (Placement(transformation(extent={{90,-10},{110,10}})));
equation 
  connect(y, const.y) annotation (Line(points={{100,0},{60,0},{60,60},{11,60}}, color={0,0,127}));
  connect(sine.y, controlBus.testBusVariable)
    annotation (Line(points={{-19,-40},{0,-40},{0,0}}, color={0,0,127}));
  annotation (experiment(__Dymola_fixedstepsize=0.001, __Dymola_Algorithm="Euler"),
      __Dymola_experimentFlags(Advanced(
        InlineMethod=0,
        InlineOrder=2,
        InlineFixedStep=0.001)),
    __Dymola_experimentSetupOutput(
      states=false,
      derivatives=false,
      inputs=false,
      outputs=false,
      auxiliaries=false,
      equidistant=false,
      events=false));
end TestBusConnector;

Code generated from Dymola 2019 FD01 is shown below:

include <dsblock6.c>

PreNonAliasNew(0)
StartNonAlias(0)
DeclareVariable("sine.amplitude", "Amplitude of sine wave", 1, 0.0,0.0,0.0,0,513)
DeclareVariable("sine.freqHz", "Frequency of sine wave [Hz]", 1, 0.0,0.0,0.0,0,513)
DeclareVariable("sine.phase", "Phase of sine wave [rad|deg]", 0, 0.0,0.0,0.0,0,513)
DeclareVariable("sine.offset", "Offset of output signal", 0, 0.0,0.0,0.0,0,513)
DeclareVariable("sine.startTime", "Output = offset for time < startTime [s]", 0,\
 0.0,0.0,0.0,0,513)
DeclareVariable("sine.y", "Connector of Real output signal", 0.0, 0.0,0.0,0.0,0,512)
DeclareVariable("const.k", "Constant output value", 0, 0.0,0.0,0.0,0,513)
DeclareVariable("const.y", "Connector of Real output signal", 0, 0.0,0.0,0.0,0,513)
DeclareOutput("y", "", 0, 0.0, 0.0,0.0,0.0,0,513)
DeclareAlias2("controlBus.testBusVariable", "Connector of Real output signal", \
"sine.y", 1, 5, 5, 1028)
EndNonAlias(0)

#define DymolaHaveUpdateInitVars 1
#include <dsblock5.c>

DYMOLA_STATIC void UpdateInitVars(double*time, double* X_, double* XD_, double* U_, double* DP_, int IP_[], Dymola_bool LP_[], double* F_, double* Y_, double* W_, double QZ_[], double duser_[], int iuser_[], void*cuser_[],struct DYNInstanceData*did_,int initialCall) {
}
StartDataBlock
EndDataBlock

The translated modelica code (dsmodel.mof) still has the calculation for the sine block.

// Translated Modelica model generated by Dymola from Modelica model 
//  TEMP.TEST.TestBusConnector


// -----------------------------------------------------------------------------

// Initial Section
  sine.amplitude := 1;
  sine.freqHz := 1;
  sine.phase := 0;
  sine.offset := 0;
  sine.startTime := 0;
  const.k := 0;
  const.y := 0;
  y := 0.0;




// -----------------------------------------------------------------------------

// Conditionally Accepted Section
  sine.y := (if time < 0 then 0 else sin(6.283185307179586*time));

// -----------------------------------------------------------------------------

// Eliminated alias variables
  // To have eliminated alias variables listed, set
  //   Advanced.OutputModelicaCodeWithAliasVariables = true
  // before translation. May give much output.

Ideally, I would like the model to translate to:

y := 0.0;
like image 558
Srikanth Sivaramakrishnan Avatar asked Jul 22 '19 19:07

Srikanth Sivaramakrishnan


3 Answers

The reason the other answers don't work is that your model is not consistent with your question: "I am wondering if there is any setting that can eliminate code that isn't involved in generating outputs from the model."

By connecting the control-bus to sine.y you implicitly create an output, and thus sine.y is involved in generating outputs from the model.

That can be avoided in one of the following ways:

  • Remove the connection between sine.y and controlBus
  • Change controlBus to be protected
  • Change so that controlBus isn't at the top-level
like image 180
Hans Olsson Avatar answered Oct 16 '22 19:10

Hans Olsson


It's not a direct answer to your question, but still it could help to improve performance. Part of the computational effort you are trying to avoid is generated by computing variables in the result file. This can be avoided by the settings below:

Selection of variables to store in the result file

This can be set as an annotation in the model itself using:

  annotation (__Dymola_experimentSetupOutput(
      states=false,
      derivatives=false,
      inputs=false,
      auxiliaries=false));
like image 28
Markus A. Avatar answered Oct 16 '22 18:10

Markus A.


There is another flag which could help. It does not give the result you expected, but it might be still useful:

Advanced.Define.AutoRemoveAuxiliaries = true;

The Dymola User Manual 2 describes the flag as follows:

Removes code for auxiliary variables that neither influences the simulation state nor the outputs. This improves performance a bit.

From this description my expectation was that the code is generated like you asked for, but unfortunately it is not the case.

like image 1
marco Avatar answered Oct 16 '22 18:10

marco