So far, the focus of this chapter has been on acausal modeling. But Modelica also supports causal formalisms. The main reason for the emphasis on acausal modeling is that it lends itself very well to the modeling of physical systems. It enables models of physical systems to be assembled schematically rather than mathematically while also automatically formulating conservation equations to ensure proper bookkeeping.
Block diagrams are a different way of approach modeling. The emphasis
in block diagram is on creating component models that represent a wide
range of mathematical operations. The operations are then performed
on (generally time-varying) signals and yield, in turn, other
signals. In fact, we will introduce a special kind of model
in
this section, called a block
, that is restricted to having only
input
and output
signals.
In this section, we’ll first look at how to construct causal blocks representing some basic mathematical operations. We’ll then see how those blocks can be used in two different ways. The first way will be to model a simple physical system. We’ll include some discussion contrasting the causal and acausal approaches. The second way to use such blocks is to model control systems. As we’ll see, using blocks to construct control systems is a much more natural fit for the block diagram formalism.
Fortunately, Modelica allows both causal and acausal approaches and, as we’ll see shortly, even allows them to be mixed. The result is that Modelica allows the model developer to use whichever approach works best in a given context.
In this section, we will leverage several definitions from the Modelica Standard Library starting with the connectors:
connector RealInput = input Real "'input Real' as connector";
connector RealOutput = output Real "'output Real' as connector";
As the names suggest, RealInput
and RealOutput
are connectors
for representing real valued input and output signals respectively.
When drawn in a diagram, the RealInput
connector takes the form of
a blue solid triangle:
The RealOutput
connector is a blue triangle outline:
We will leverage the Modelica Standard Library for several different
partial
block definitions. The first partial
definition we’ll
use is the SO
, or “single output”, definition:
partial block SO "Single Output continuous control block"
extends Modelica.Blocks.Icons.Block;
RealOutput y "Connector of Real output signal" annotation ...
end SO;
Obviously, this definition is used for blocks that have a single
output. By convention, this output signal is named y
. Another
definition we’ll use is the SISO
or “single input, single output”
block:
partial block SISO "Single Input Single Output continuous control block"
extends Modelica.Blocks.Icons.Block;
RealInput u "Connector of Real input signal" annotation ...
RealOutput y "Connector of Real output signal" annotation ...
end SISO;
This model adds an input signal, u
, in addition to the output
signal, y
. Finally, for blocks with multiple inputs, the MISO
block defines the input signal, u
, as a vector:
partial block MISO "Multiple Input Single Output continuous control block"
extends Modelica.Blocks.Icons.Block;
parameter Integer nin=1 "Number of inputs";
RealInput u[nin] "Connector of Real input signals" annotation ...
RealOutput y "Connector of Real output signal" annotation ...
end MISO;
The parameter nin
is used to specify the number of inputs to the
block.
It is worth pointing out that all of the blocks we are about to define are also available in the Modelica Standard Library. But we’ll create our own versions here just to demonstrate how such models can be defined.
Constant
¶Probably the simplest block we can imagine is one that simply outputs
a constant value. Since this model has a single output, it extends
from the SO
block:
within ModelicaByExample.Components.BlockDiagrams.Components;
block Constant "A constant source"
parameter Real k "Constant output value";
extends Icons.Axes;
extends Interfaces.SO;
equation
y = k;
end Constant;
When rendered, the block looks like this:
Gain
¶Another simple block
is a “gain block” which multiplies an input
signal by a constant to compute its output signal. Such a block will
have a single input signal and a single output signal. As such, it
extends from the SISO
model as follows:
within ModelicaByExample.Components.BlockDiagrams.Components;
block Gain "A gain block model"
extends Interfaces.SISO;
parameter Real k "Gain coefficient";
equation
y = k*u;
end Gain;
When rendered, the block looks like this:
Sum
¶The Sum
block can operate on an arbitrary number of input
signals. For this reason, it extends from the MISO
block:
within ModelicaByExample.Components.BlockDiagrams.Components;
block Sum "Block that sums its inputs"
extends Interfaces.MISO;
equation
y = sum(u);
end Sum;
The Sum
block uses the sum function to compute the sum
over the array of input signals, u
, to compute the output signal
y
.
When rendered, the block looks like this:
Product
¶The Product
block is nearly identical to the Sum
block except
that it uses the product function:
within ModelicaByExample.Components.BlockDiagrams.Components;
block Product "Block that outputs the product of its inputs"
extends Interfaces.MISO;
equation
y = product(u);
end Product;
When rendered, the block looks like this:
Feedback
¶The Feedback
block differs from the previous blocks because it
doesn’t extend from any definitions in the Modelica Standard Library.
Instead, it explicitly declares all of the connectors it uses:
within ModelicaByExample.Components.BlockDiagrams.Components;
block Feedback "A block to compute feedback terms"
Interfaces.RealInput u1
annotation ...
Interfaces.RealInput u2 annotation ...
Interfaces.RealOutput y
annotation ...
equation
y = u1-u2;
end Feedback;
The output of the Feedback
block is the difference between the two
input
signals u1
and u2
.
When rendered, the block looks like this:
Integrator
¶The Integrator
block is another SISO
block that integrates the
input signal, u
, to compute the output signal, y
. Since this
block
performs an integral, it requires an initial condition which
is specified using the parameter y0
:
within ModelicaByExample.Components.BlockDiagrams.Components;
block Integrator
"This block integrates the input signal to compute the output signal"
parameter Real y0 "Initial condition";
extends Interfaces.SISO;
initial equation
y = y0;
equation
der(y) = u;
end Integrator;
When rendered, the block looks like this:
Now that we’ve created this assortment of blocks, we’ll explore how
they can be used to model a couple of example systems. As we’ll see,
the suitability of causal block
components varies from application
to application.
The first system that we will model using our block
definitions is
the heat transfer example we presented earlier in this chapter. However, this time, instead of using
acausal components to build our model, we’ll build it up in terms of
the mathematical operations associated with our block
definitions.
Since these blocks represent mathematical operations, let us first revisit the equation associated with this example:
The following block diagram will solve for the temperature profile, :
The Modelica source code for this example is:
within ModelicaByExample.Components.BlockDiagrams.Examples;
model NewtonCooling "Newton cooling system modeled with blocks"
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 mass";
parameter Real c_p = 1.2 "Specific heat";
parameter Real T_inf = from_degC(25) "Ambient temperature";
Components.Integrator T(y0=from_degC(90))
annotation ...
Components.Gain gain(k=-1)
annotation ...
Components.Constant ambient(k=T_inf)
annotation ...
Components.Sum sum(nin=2)
annotation ...
Components.Gain gain1(k=h*A/(m*c_p))
annotation ...
equation
connect(T.y, gain.u) annotation ...
connect(sum.y, gain1.u) annotation ...
connect(gain.y, sum.u[2]) annotation ...
connect(ambient.y, sum.u[1]) annotation ...
connect(gain1.y, T.u) annotation ...
end NewtonCooling;
The temperature, , is represented in this model by the
variable T.y
. Simulating this system, we get the following
solution for the temperature:
As we can see, the solution is exactly the same as it has been for all previous incarnations of this example.
So far, we’ve seen this particular problem formulated three different ways. The first formulation described the mathematical structure using a single equation. The second formulation used acausal component models of individual physical effects to represent the same dynamics. Finally, we have this most recent block diagram formulation. But the real question is, which ones of these approaches is the most appropriate for this particular problem?
There are really two extreme cases to consider. If we wanted to solve only this one particular configuration of this problem with a single thermal capacitance convecting heat to some infinite ambient reservoir, the equation based version would probably be the best choice since the behavior of the entire problem can be expressed by the single equation:
m*c_p*der(T) = h*A*(T_inf-T) "Newton's law of cooling";
Such an equation can be typed in very quickly. In contrast, the component based versions would require the user to drag, drop and connect component models which would invariably take longer.
However, if you intend to create variations of the problem combining different modes of heat transfer, different boundary conditions, etc., then the acausal version is better. This is because while some investment is required to create the component models, they can be reconfigured almost trivially.
One might say the same is true for the block diagram version of the model (i.e., that it can be trivially reconfigured), but that is not the case. The block diagram version of the model is a mathematical representation of the problem, not a schematic based formulation. If you create variations of this heat transfer problem that specify alternative boundary conditions, add more thermal inertias or include additional modes of heat transfer, the changes to a schematic will be simple. However, for a block diagram formulation you will need to completely reformulate the block diagram. This is because the resulting mathematical equations might be very different when expressed in state-space form. One of the big advantages of the acausal, schematic based approach is that the Modelica compiler will translate the textbook equations into state-space form automatically. This saves a great deal of tedious, time-consuming and error prone work on the part of the model developer and this is precisely why the acausal approach is preferred.
For the next example, we’ll mix both causal components, the blocks we’ve developed in this section, with acausal components, the Heat Transfer Components developed earlier in this chapter. This will prove to be a powerful combination, since it allows us to represent the physical components schematically, but allows us to express the control strategy mathematically.
Here is a schematic diagram showing how both approaches can be combined:
When modeling a physical system together with a control system, the physical components and effects will use an acausal formulation. The components representing the control strategy will typically use a causal formulation. What bridges the gap between these two approaches are the sensors and actuators. The sensors measure some aspect of the system (temperature in this example) and the actuators apply some “influence” over the system (in this case, a heat flux).
The actuator models will generally have signals as inputs combined with an acausal connection to the physical system (through which the “influence”, like a force or an electric current, will be applied). This is reversed for the sensor models where the causal connectors will be outputs and the acausal connectors will be used to “sense” some aspect of the physical system (like a voltage, temperature, etc.).
Our example model can be expressed in Modelica as:
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;
Looking at the model, we can see that the initial temperature is and the ambient temperature is . In addition, the setpoint temperature (the desired temperature) is . So unlike our previous examples where the system temperature eventually came to rest at the ambient temperature, this system should approach the setpoint temperature due to the influence of the control system. Simulating this system, we get the following temperature response:
We can increase the “gain” of the controller, k
, and we see a
different response:
However, we can see from the following plot that much more heat output was required from our actuator in order to achieve the faster response in the second case:
This is just a very simple example of how combining physical response with control allows model developers to explore how overall system performance is impacted by both physical and control strategy design.
In this section, we’ve seen how to define causal block
components
and use them to model both the physical and control related behavior.
We’ve even seen how these causal components can be combined with
acausal components to yield a “best of both worlds” combination where
control features are implemented with causal components while physical
components use acausal components.