I have developed a model for a configurable variable, meaning that the variable may be defined by a parameter, specified via a real input, or left undefined so that it can be solved for.
model ConfigurableReal
"Configurable variable that can be set by parameter, by real input, or left undetermined"
parameter Boolean isSpecifiedByParameter = false
"true if value is specified by paramter"
annotation(Dialog(group="Specify by Parameter", enable = not isSpecifiedByInput));
parameter Boolean isSpecifiedByInput = false
"true if value is specified by real input"
annotation(Dialog(group = "Specify by Real Input", enable=not isSpecifiedByParameter));
parameter Real specifiedValue(unit=unitString) = 0
"specified value to use if isSpecifiedByParameter == true"
annotation(Dialog(group="Specify by Parameter", enable = isSpecifiedByParameter));
// Conditionally declare the realInput
Modelica.Blocks.Interfaces.RealInput realInput if isSpecifiedByInput
annotation (Placement(transformation(extent={{-140,-20},{-100,20}})));
Real value "active value";
protected
Modelica.Blocks.Sources.Constant constantBlock(final k = specifiedValue) if isSpecifiedByParameter
"constant block to hold specified input";
Modelica.Blocks.Interfaces.RealInput value_ "connected value";
equation
value = value_;
// Connect the real input to the value if the real input exists
// This only happens if isSpecifiedByInput==true, because the RealInput is
// conditionally declared above
connect(realInput, value_);
// Connect the constant block to the value if the value is specified by parameter
// This only happens if isSpecifiedByParameter == true, because the Constant is
// conditionally declared above
connect(constantBlock.y, value_);
annotation (Icon(coordinateSystem(preserveAspectRatio=false), graphics={
Rectangle(
extent={{-80,40},{80,-40}},
lineColor={28,108,200},
fillColor={255,255,255},
fillPattern=FillPattern.Solid),
Text(
extent={{-70,30},{70,-32}},
lineColor={28,108,200},
textString="Config
Variable"),
Text(
extent={{-100,80},{100,50}},
lineColor={28,108,200},
fillColor={255,255,255},
fillPattern=FillPattern.Solid,
textString=DynamicSelect("", "value = " + String(value, significantDigits=4))),
Text(
extent={{-100,-50},{100,-80}},
lineColor={28,108,200},
fillColor={255,255,255},
fillPattern=FillPattern.Solid,
textString="%name")}),
Diagram(
coordinateSystem(preserveAspectRatio=false)));
end ConfigurableReal;
Now I would like to extend the model in a way that leverages the quantity/unit types instead of only Reals. Is it possible to assign variable type via a parameter? For instance, is it possible to declare a variable as shown below?
parameter String variableType = "Pressure";
parameter typeOf(variableType) variableType;
If so, I could define the variable types in the ConfigurableReal model to reference the variableType object and write a configurable pressure model by:
model ConfigurablePressure extends ConfigurableReal(final variableType="Pressure");
If not, is there something in Modelica like C# Type Parameters?
In the end, I am really trying to find a way to extend my ConfigurableReal model so that it can be a ConfigurablePressure, ConfigurableTemperature, ConfigurableMassFlowRate,..., containing units in parameter inputs and simulation results without having to copy and paste the model code for each variable type and manually assign the variable types in each class.
Any help is greatly appreciated.
Thanks, Justin
Justin, what you really want is to use redeclare
+ replaceable
. You mention C# type parameters. Modelica does have something like that, but they don't quite look (syntactically) the same and they have some additional constraints because of the mathematical constraints of Modelica.
If you haven't already read the chapter on Architecture in my book, that will give you a start.
To complete the analogy to C# type parameters, consider this model:
model Circuit
replaceable Resistor R constrainedby Element;
...
end Circuit;
This says that R
must have be a subtype of Element
. By default, it is a Resistor
, but you can change that. Note that Element
and Resistor
or both types. So you are changing the type of R
by changing them. You change the with redeclare
(see book).
In that case, the "type parameter" only applies to one variable, R
. But you can do this in a more C# like way with:
model Circuit
replaceable model X = Resistor constrainedby Element;
X R1;
X R2;
}
In C#, this would be something like:
class Circuit<X> where X : Element {
X R1;
X R2;
}
(except that C# doesn't defaults as far as I can remember)
I have to run, but I hope that helps.