How to eliminate dead code in Dymola/Modelica
Asked Answered
U

3

5

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;
Unsearchable answered 22/7, 2019 at 19:35 Comment(0)
E
4

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
Exerciser answered 12/8, 2019 at 11:41 Comment(1)
Thanks for your response. I tried all of the solutions you listed. However, the translated modelica and generated code still has the sine block.Unsearchable
M
1

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));
Marder answered 23/7, 2019 at 7:18 Comment(2)
Hello Markus, I already have all outputs turned off in the annotation. I am not directly running dymosim.exe, rather exporting the code for use in a RT system. That's why I am trying to reduce the computation of unnecessary elements at the C-code levelUnsearchable
Understood. In this case my answer doesn't help a lot. Looking forward to other answers, because I don't know how this optimization could be done.Marder
A
1

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.

Abyssinia answered 9/8, 2019 at 7:51 Comment(1)
Thanks for your response. I already had this flag enabled, but it still doesn't remove code that isn't involved in generating outputs (the sine block).Unsearchable

© 2022 - 2024 — McMap. All rights reserved.