We’ll start our discussion of component models by building some component models in the heat transfer domain. These models will allow us to recreate the models we saw previously, but this time using component models to represent each of the various effects. Investing the time to make component models will then allow us to easily combine the underlying physical behavior to create models for a wide variety of thermal systems.
In our previous discussion on Simple Domains we described how a thermal connector could be described. For the component models in this section, we will utilize the thermal connector models from the Modelica Standard Library. These connectors are defined as follows:
within Modelica.Thermal.HeatTransfer;
package Interfaces "Connectors and partial models"
partial connector HeatPort "Thermal port for 1-dim. heat transfer"
Modelica.SIunits.Temperature T "Port temperature";
flow Modelica.SIunits.HeatFlowRate Q_flow
"Heat flow rate (positive if flowing from outside into the component)";
end HeatPort;
connector HeatPort_a "Thermal port for 1-dim. heat transfer (filled rectangular icon)"
extends HeatPort;
annotation ...
end HeatPort_a;
connector HeatPort_b "Thermal port for 1-dim. heat transfer (unfilled rectangular icon)"
extends HeatPort;
annotation ...
end HeatPort_b;
end Interfaces;
Careful inspection of these connector definitions shows that
HeatPort_a
and HeatPort_b
are identical in terms of their
content to the HeatPort
model. The only difference is that
HeatPort_a
and HeatPort_b
have distinguishing graphical icons.
The component models presented in the remainder of this section will utilize these connector definitions.
When building component models, the goal is to create component models that implement (only) one physical effect (e.g., capacitance, convection). By implementing component models in this way, we will see that they can then be combined in any infinite number of different configurations without the need to add any more equations. This kind of reuse of equations makes the model developer more productive and avoids opportunities to introduce errors.
Our first component model will be a model of lumped thermal capacitance with uniform temperature distribution. The equation we wish to associate with this component model is:
The Modelica model (with the Icon
annotation removed) representing
this equation is quite simple:
within ModelicaByExample.Components.HeatTransfer;
model ThermalCapacitance "A model of thermal capacitance"
parameter Modelica.SIunits.HeatCapacity C "Thermal capacitance";
parameter Modelica.SIunits.Temperature T0 "Initial temperature";
Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a node
annotation ...
initial equation
node.T = T0;
equation
C*der(node.T) = node.Q_flow;
end ThermalCapacitance;
where C
is the thermal capacitance and T0
is the initial
temperature.
Note the presence of the node
connector in this model. This is
how the ThermalCapacitance
component model interacts with the
“outside world”. We will use the temperature at the node
,
node.T
to represent the temperature of the thermal capacitance.
The flow
variable, node.Q_flow
, represents the flow of heat
into the thermal capacitance. We can see this when looking at the
equation for the thermal capacitance:
C*der(node.T) = node.Q_flow;
Note that when node.Q_flow
is positive, the temperature of the
thermal capacitance, node.T
, will increase. This confirms that we
have followed the Modelica convention that flow
variables on a
connector represent a flow of the conserved quantity, heat in this
case, into the component (a more thorough discussion of
Accounting will be presented shortly).
Using this model alone, we can already build a simple “system” model as follows:
within ModelicaByExample.Components.HeatTransfer.Examples;
model Adiabatic "A model without any heat transfer"
ThermalCapacitance cap(C=0.12, T0(displayUnit="K") = 363.15)
"Thermal capacitance component"
annotation ...
end Adiabatic;
This model contains only the thermal capacitance element (as indicated
by the declaration of the variable cap
of type
ThermalCapacitance
) and no other heat transfer elements (e.g.,
conduction, convection, radiation). Ignore the Placement
annotation for the moment, we’ll provide a complete explanation in a
later section on Component Model Annotations.
Using the graphical annotations in the model (some of which were left out of the previous listing) it can be rendered as:
Since no heat enters or leaves the thermal capacitance component,
cap
, the temperature of the capacitance remains constant as shown
in the following plot:
To quickly add some heat transfer, we could define another component
model to represent heat transfer to some ambient temperature. Such a
model could be represented in Modelica (again, without the Icon
annotation) as follows:
within ModelicaByExample.Components.HeatTransfer;
model ConvectionToAmbient "An overly specialized model of convection"
parameter Modelica.SIunits.CoefficientOfHeatTransfer h;
parameter Modelica.SIunits.Area A;
parameter Modelica.SIunits.Temperature T_amb "Ambient temperature";
Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a port_a
annotation ...
equation
port_a.Q_flow = h*A*(port_a.T-T_amb) "Heat transfer equation";
end ConvectionToAmbient;
This model includes parameters for the heat transfer coefficient,
h
, the surface area, A
and the ambient temperature, T_amb
.
This model is attached to other heat transfer elements through the
connector port_a
.
Again, we must pay close attention to the sign convention. Recall
from our previous discussion of Thermal Capacitance that
Modelica follows a sign convention that a positive value for a
flow
variable represents flow into the component. In particular,
let’s take a close look at the equation in the ConvectionToAmbient
model:
port_a.Q_flow = h*A*(port_a.T-T_amb) "Heat transfer equation";
Note that when port_a.T
is greater than T_amb
, the sign of
port_a.Q_flow
is positive. That means heat is flowing
into this component. In other words, when port_a.T
is greater
than T_amb
, this component will take heat away from
port_a
(and, conversely, when T_amb
is greater than
port_a.T
, it will inject heat into port_a
).
Having such a component model available enables us to combine it with
the ThermalCapacitance
model and simulate a system just like we
modeled in some of our earlier heat transfer examples using the following Modelica code:
within ModelicaByExample.Components.HeatTransfer.Examples;
model CoolingToAmbient "A model using convection to an ambient condition"
ThermalCapacitance cap(C=0.12, T0(displayUnit="K") = 363.15)
"Thermal capacitance component"
annotation ...
ConvectionToAmbient conv(h=0.7, A=1.0, T_amb=298.15)
"Convection to an ambient temprature"
annotation ...
equation
connect(cap.node, conv.port_a) annotation ...
end CoolingToAmbient;
In this model, we see two components have been declared, cap
and
conv
. The parameters for each of these components are also
specified when they are declared. The following is a schematic for
the CoolingToAmbient
model:
But what is really remarkable about this model is the equation section:
equation
connect(cap.node, conv.port_a) annotation ...
This statement introduces one of the most important features in
Modelica. Note that statement appears within an equation
section. While the connect
operator looks like a function, it is
much more than that. It represents the equations that should be
generated to model the interaction between the two specified
connectors, cap.node
and conv.port_a
.
In this context, a connection does two important things. The first thing it does is to generate an equation that equates the “across” variables on either connector. In this case, that means the following equation:
cap.node.T = conv.port_a.T "Equating across variables";
In addition, a connection generates an equation for all the through
variables as well. The equation that is generated is a conservation
equation. You can think of this conservation equation as a
generalization of Kirchoff’s current law to any conserved quantity.
Basically, it represents the fact that the connection itself has no
“storage” ability and that whatever amount of the conserved quantity,
in this case heat, that flows out of one component must go into the
other(s). So in this case, the connect statement will generate the
following equation with respect to the flow
variables:
cap.node.Q_flow + conv.port_a.Q_flow = 0 "Sum of heat flows must be zero";
Note the sign convention here. All the flow
variables are summed.
We will examine more complex cases shortly where multiple components
are interacting. But in this simple case, with only two components,
we see clearly that if one value for Q_flow
is positive, the other
must be negative. In other words, if heat is flowing out of one
component, it must be flowing into another. These conservation
equations ensure that we have a proper accounting of conserved
quantities throughout our network and that no amount of the conserved
quantity gets “lost”.
A very simple way to summarize the behavior of a connection, in the context of a thermal problem, is to think of a connection as a perfectly conducting element with no thermal capacitance.
If we simulate the CoolingToAmbient
model above, we get the
following temperature trajectory:
There is one slight issue with the CoolingToAmbient
model. We
mentioned earlier that when building component models it is best to
isolate each individual physical effect to its own component. But we’ve
actually lumped two different effects into one component. As we will
see in a moment, this limits the reusability of the component models.
But first, let’s refactor the code to separate these effects out and
then we’ll revisit the system level model using these new components.
The first new component is a Convection
model. In this case, we
won’t make any assumptions about the temperature at either end.
Instead, we’ll only assume that each is connected to something with an
appropriate thermal connector. The result is a model like this one:
within ModelicaByExample.Components.HeatTransfer;
model Convection "Modeling convection between port_a and port_b"
parameter Modelica.SIunits.CoefficientOfHeatTransfer h;
parameter Modelica.SIunits.Area A;
Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a port_a
annotation ...
Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_b port_b
annotation ...
equation
port_a.Q_flow + port_b.Q_flow = 0 "Conservation of energy";
port_a.Q_flow = h*A*(port_a.T-port_b.T) "Heat transfer equation";
end Convection;
This model contains two equations. The first equation:
port_a.Q_flow + port_b.Q_flow = 0 "Conservation of energy";
represents the fact that this component does not store heat. The
equation enforces the constraint that whatever heat flows in from one
connector must flow out from the other (which is exactly the same
behavior we saw from the connect
statement earlier in this
section). The next equation:
port_a.Q_flow = h*A*(port_a.T-port_b.T) "Heat transfer equation";
captures the heat transfer relationship for convection by expressing the relationship between the flow of heat through this component and the temperatures on either end.
Number of equations
All our previous models had one connector and one equation. The
Convection
model has two connectors. As a result, it has two
equations. A simple rule of thumb is that you need as many
equations as connectors. But keep in mind that this rule of thumb
assumes that you are using connectors with only one through
variable on them and no “internal variables” in your model
(e.g., protected
variables). The upcoming section on
Component Models will provide a more comprehensive discussion on
determining how many equations a component requires.
Specifically, it will provide guidance on how to build so-called
Balanced Components.
Now that we have the convection model, we need something to represent
the ambient conditions. We need something like a thermal capacitance
model, but one that maintains a constant temperature. Imagine if we
took the ThermalCapacitance
model and gave a very large value for
its capacitance, C
. Then we’d have something that changed
temperature very slowly. But what we want is something that doesn’t
change temperature at all, as if it had a C
value that was
infinitely large.
This kind of model comes up frequently and it is commonly called an “infinite reservoir” model. Typically, such a model is characterized by the fact that no matter how much of the conserved quantity (heat in this case) flows into or out of the component, the across variable remains constant. In an electrical context, such a model would represent electrical ground. In a mechanical context, it would represent a mechanical ground (something that didn’t change position, regardless of how much force was applied).
We will represent our ambient conditions using the
AmbientConditions
model:
within ModelicaByExample.Components.HeatTransfer;
model AmbientCondition
"Model of an \"infinite reservoir\" at some ambient temperature"
parameter Modelica.SIunits.Temperature T_amb "Ambient temperature";
Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a node annotation ...
equation
node.T = T_amb;
end AmbientCondition;
Since we are talking about the heat transfer domain, this model is an infinite reservoir for heat and no matter how much heat flows into or out of this component, its temperature remains the same.
Using these new Convection
and an AmbientCondition
models, we
can reconstruct our simple system level heat transfer model using
the following:
within ModelicaByExample.Components.HeatTransfer.Examples;
model Cooling "A model using generic convection to ambient conditions"
ThermalCapacitance cap(C=0.12, T0(displayUnit="K") = 363.15)
"Thermal capacitance component"
annotation ...
Convection convection(h=0.7, A=1.0)
annotation ...
AmbientCondition amb(T_amb(displayUnit="K") = 298.15)
annotation ...
equation
connect(convection.port_a, cap.node) annotation ...
connect(amb.node, convection.port_b) annotation ...
end Cooling;
When rendered, the model looks like this:
This may not seem like much of an improvement. Although we went to
the trouble to break up the ConvectionToAmbient
model into individual
Convection
and AmbientTemperature
models, we still end up with
the same fundamental behavior, i.e.,
The big benefit of breaking down ConvectionToAmbient
into
Convection
and AmbientTemperature
models is the ability to
recombine them in different ways. The following schematic is just one
example of how the handful of fundamental components we’ve constructed
so far can be rearranged to form an entirely new (and more complex)
model:
In fact, with these components we can now make arbitrarily complex networks of components and still never have to worry about formulating the associated equations that describe their dynamics. Everything that is required to do this has already been captured in our component models. This allows us to focus on the process of creating and designing our system and leave the tedious, time-consuming and error prone work of manipulating equations behind.