2
votes

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

1

1 Answers

3
votes

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.