Tags and keywords
The Modelica By Example target code is:
within ModelicaByExample.Components.BlockDiagrams.Examples;
model MultiDomainControl
"Mixing thermal components with blocks for sensing, actuation and control"
import Modelica.SIunits.Conversions.from_degC;
parameter Real h = 0.7 "Convection coefficient";
parameter Real A = 1.0 "Area";
parameter Real m = 0.1 "Thermal maass";
parameter Real c_p = 1.2 "Specific heat";
parameter Real T_inf = from_degC(25) "Ambient temperature";
parameter Real T_bar = from_degC(30.0) "Desired temperature";
parameter Real k = 2.0 "Controller gain";
Components.Constant setpoint(k=T_bar)
annotation ...
Components.Feedback feedback
annotation ...
Components.Gain controller_gain(k=k) "Gain for the proportional control"
annotation ...
HeatTransfer.ThermalCapacitance cap(C=m*c_p, T0 = from_degC(90))
"Thermal capacitance component"
annotation ...
HeatTransfer.Convection convection2(h=h, A=A)
annotation ...
HeatTransfer.AmbientCondition
amb(T_amb(displayUnit="K") = T_inf)
annotation ...
Components.IdealTemperatureSensor sensor annotation ...
Components.HeatSource heatSource
annotation ...
equation
connect(setpoint.y, feedback.u1) annotation ...
connect(feedback.y, controller_gain.u) annotation ...
connect(convection2.port_a, cap.node) annotation ...
connect(amb.node, convection2.port_b) annotation ...
connect(sensor.y, feedback.u2) annotation ...
connect(heatSource.node, cap.node) annotation ...
connect(controller_gain.y, heatSource.u) annotation ...
connect(sensor.node, cap.node) annotation ...
end MultiDomainControl;
The Modelica By Example page also gives this patch diagram:
The Modelica By Example page does not give the Modelica code for IdealTemperatureSensor
or HeatSource
, but it's not too hard to figure out what they are doing. The HeatSource
just takes in a temperature difference value scaled by the controller gain and outputs heat (there's no physical scaling factor within the component).
To make things easier to track, some slightly different naming is used in this SysML/SysPhS trail version.
As always in this trail we need to workaround this:
If you look at the Modelica By Example code above you'll see that the 'start' values for the parameters of the component usages are set via parameters on the parent component, either via a single parameter or a combination of parameters in an equation.
For the case of a single parent parameter we've already seen that this can be handled easily in SysML using Context-Specific Values with a value carried directly by a Slot on an instance. We'll do this in this example for k
on the setpoint:Constant
temperature, and the parameter _tBar
is «UNUSED»:
- Pro: One fewer value property in the SysML model.
- Pro: the Context-Specific Value can easily be seen as an initial value in the Internal Block Diagram (IBD).
- Con: It won't be available as a GUI-settable parameter at runtime in the Modelica tool.
It can also be handled using a Context-Specific Value and an OpaqueExpression on a Slot:
- Pro: From the Modelica point of view this is more flexible, because the binding will export as an inline equation with a dependency on a Modelica variable for which the initial value can be set at runtime.
- Con: The initial value is not numerically displayed on the component in the Internal Block Diagram (IBD), one has to additionally show the symbol of the driving value property with its default displayed.
Setting an OpaqueExpression on a Slot it also a bit fiddly:
And it turns out there is an additional very tricky tool issue that makes things a little bit harder when there is just one driving value property (unless you know the sneaky workaround):
And yes, it did take ages to track that down and find the HACK !
In the case where there is more than one driving variable (such as for cap.c = mCap * cCap
) using a Slot with an OpaqueExpression to carry the Context-Specific Value is probably the way to go.
However, beware also of another minor issue:
The exported Modelica code for the SysML/SysPhS block MultiDomainControl
is:
model MultiDomainControl
MultiDomainControl _MultiDomainControl;
model MultiDomainControl
Constant setpoint(k.start=303.15,k.fixed=true);
Feedback feedback;
Gain gain(k.start=1*kGain,k.fixed=true);
ThermalCapacitance cap(c.start=mCap*cCap,c.fixed=true,node.t.start=363.15,node.t.fixed=true);
Convection convection2(h.start=1*hConv,h.fixed=true,a.start=1*aConv,a.fixed=true);
AmbientCondition amb(tAmb.start=1*tInf,tAmb.fixed=true);
IdealTemperatureSensor sensor;
HeatSource heatSource;
parameter Real hConv(start=0.7,fixed=true);
parameter Real aConv(start=1.0,fixed=true);
parameter Real mCap(start=0.1,fixed=true);
parameter Real cCap(start=1.2,fixed=true);
parameter Real tInf(start=298.15,fixed=true);
parameter Real _tBar(start=303.15,fixed=true);
parameter Real kGain(start=2.0,fixed=true);
equation
connect(convection2.hPB,amb.node);
connect(cap.node,convection2.hPA);
connect(heatSource.h,cap.node);
connect(cap.node,sensor.h);
connect(sensor.o,feedback.u2);
connect(setpoint.y,feedback.u1);
connect(gain.y,heatSource.i);
connect(feedback.y,gain.u);
end MultiDomainControl;
model Constant
extends SO;
parameter Real k;
equation
y=k;
end Constant;
model Feedback
extends DISO;
equation
y=u1-u2;
end Feedback;
model Gain
extends SISO;
parameter Real k;
equation
y=k*u;
end Gain;
model ThermalCapacitance
parameter HeatCapacitance c;
parameter Temperature _t0;
HeatPortA node;
equation
c*der(node.t)=node.hFR;
end ThermalCapacitance;
model Convection
parameter CoefficientOfHeatTransfer h;
parameter Area a;
HeatPortA hPA;
HeatPortB hPB;
equation
hPA.hFR+hPB.hFR=0;
hPA.hFR=h*a*(hPA.t-hPB.t);
end Convection;
model AmbientCondition
HeatPortA node;
parameter Temperature tAmb;
equation
node.t=tAmb;
end AmbientCondition;
model IdealTemperatureSensor
Modelica.Blocks.Interfaces.RealOutput o;
HeatPortA h;
equation
o=h.t;
h.hFR=0;
end IdealTemperatureSensor;
model HeatSource
Modelica.Blocks.Interfaces.RealInput i;
HeatPortB h;
equation
h.hFR=-i;
end HeatSource;
connector HeatPortB
extends HeatFlowElement;
end HeatPortB;
connector HeatPortA
extends HeatFlowElement;
end HeatPortA;
model SO
Modelica.Blocks.Interfaces.RealOutput y;
end SO;
model DISO
Modelica.Blocks.Interfaces.RealInput u1;
Modelica.Blocks.Interfaces.RealOutput y;
Modelica.Blocks.Interfaces.RealInput u2;
end DISO;
model SISO
Modelica.Blocks.Interfaces.RealInput u;
Modelica.Blocks.Interfaces.RealOutput y;
end SISO;
connector HeatFlowElement
flow HeatFlowRate hFR;
Temperature t;
end HeatFlowElement;
type HeatCapacitance=Real(unit="J/K");
type Temperature=Real(unit="K");
type CoefficientOfHeatTransfer=Real(unit="W/(m2.K)");
type Area=Real(unit="m2");
type HeatFlowRate=Real(unit="J/s");
end MultiDomainControl;
Note how in the plot the temperature as measured at the sensor actually goes below the setpoint temperature 303.15 K because there is competition with the lower ambient temperature 298.15 via the thermal convection component.