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;