4
votes

I have an application where I am using Dymola as a development environment, but will be exporting models in FMU form to be used in another application. The systems that I am modeling have interchangeable components, making them a great fit for modeling in Modelica. But, I am not sure that I can leverage that capability when I want to export the models in FMU form.

Consider the very simple package below. The goal of the package is to define two very simple models, and allow the user to select between the possible models when executing the model. While this is easy to do within a Modelica IDE, I need similar capability within an FMU.

The partial model defines a model where y = p0 + p1*x. The two extended models simply assign different values to parameters p0 and p1. Finally, the TestModel adds a parameter named modelIndex, which is used in conditional expressions defining the two possible model types. Within Dymola this works great, as the user can easily set the value of the parameter modelIndex. I am trying to figure out if it is possible to accomplish this via an FMU by making modelIndex an input to the FMU. But compilation fails if I set the annotation Evaluate=false for the modelIndex variable. The stated error is: "Current version of the Modelica translator can only handle conditional components with fixed condition.... All variables used in condition of conditional declaration must be declared as constants or parameters."

If anyone can help provide guidance on how to create a conditional FMU, it will be greatly appreciated. This simple example only used to demonstrate the issue. The true system being modeled has 4-5 primary components, each which have 5+ possible different models, yielding a large set of possible permutations. Simply batch exporting all of the configurations is likely not feasible.

Thanks! Justin

package ConfigurableModel 
  "Package to test whether or not models can be configured by external inputs"
  partial model partialModel 
    "Partial model used to control selectable options in Dymola"

    Modelica.Blocks.Interfaces.RealInput x(start = 1) "input value";
    Modelica.Blocks.Interfaces.RealOutput y "output value";

    parameter Real p0 = 0;
    parameter Real p1 = 0;

  equation 
    y = p0 + p1*x;
      annotation (Icon(coordinateSystem(preserveAspectRatio=false)), Diagram(
      coordinateSystem(preserveAspectRatio=false)));
  end partialModel;

  model linearModel_NoOffset "Linear model with no offset"
    extends partialModel(p0 = 0, p1 = 1);
  end linearModel_NoOffset;

  model linearModel_Offset "Linear model with offset"
    extends partialModel(p0=1, p1=1);
  end linearModel_Offset;

  model TestModel "Model to test configurability"
    // parameter Integer modelIndex = 2 "1 = linear_NoOffset, 2 = linear_Offset" annotation(Evaluate=false);

    parameter Integer modelIndex = 2 "1 = linear_NoOffset, 2 = linear_Offset";

    // Conditional instances, only one model is created based upon value of modelIndex
    linearModel_NoOffset linear_NoOffset if modelIndex == 1;
    linearModel_Offset linear_Offset if modelIndex == 2;

    // Input and output blocks
    Modelica.Blocks.Sources.Constant xMaster(k=1) annotation (Placement(transformation(extent={{-100,-10},{-80,10}})));
    Modelica.Blocks.Interfaces.RealOutput yMaster annotation (Placement(transformation(extent={{100,-10},{120,10}})));

  equation 
    // Note that only the connections for the components that exist will be used

    // Connect input to each model instance
    connect(xMaster.y, linear_NoOffset.x);
    connect(xMaster.y, linear_Offset.x);

    // Connect output to each model instance
    connect(yMaster, linear_NoOffset.y);
    connect(yMaster, linear_Offset.y);

      annotation (Icon(coordinateSystem(preserveAspectRatio=false)), Diagram(
      coordinateSystem(preserveAspectRatio=false)));
  end TestModel;
    annotation (uses(Modelica(version="3.2.1")));
end ConfigurableModel;
2

2 Answers

2
votes

To my understanding, this is not possible directly with FMI. The object oriented features of Modelica like the conditional instantiation are handled during the symbolic processing of Modelica before generating the C-Code which is part of an FMU (as C-Code or in compiled form). Through the conditional instantiation many properties of the the exported FMUs could be changed (e.g. having different numbers of states). So you could not have a single modeldescription.xml file in the FMU describing the properties of an FMU. You could consider splitting your model in several FMUs and deal with the variability of subsystems by exchanging some of them. However, this might result in a more complicated numerical task than with the original overall Modelica model,as no optimization on the overall model can be performed as by the Modelica compiler on the overall model. One advantage in your example is, that your partial model already has causal interfaces (RealInput and RealOutput) A workaround to come near to your intended solution could be, that you include both the submodels linear_NoOffset and linear_Offset (without "if modelIndex == xy") in your model, include switches triggered by the modelIndex to switch between the signals to and from the two submodels. Might result in some computational overhead as both submodels are present an are evaluated.

2
votes

Your problem sounds like it could be solved using the approach of Elmqvist (2014), although I did not hear much more on the subject since then. I'm not sure if any automatic approach has been added to Dymola, but you could try to model switching your models explicitly.