Getting Physical

Although the previous section got us started with representing mathematical behavior, it doesn’t convey any connection to physical behavior. In this section, we’ll explore how to build models that represent the modeling of physical behavior. Along the way, we will highlight some of the language features we can leverage that will not only tie these models to physical and engineering domains, but, as we shall see, they can even help us avoid mistakes.

Let’s start with the following example:

model NewtonCooling "An example of Newton's law of cooling"
  parameter Real T_inf "Ambient temperature";
  parameter Real T0 "Initial temperature";
  parameter Real h "Convective cooling coefficient";
  parameter Real A "Surface area";
  parameter Real m "Mass of thermal capacitance";
  parameter Real c_p "Specific heat";
  Real T "Temperature";
initial equation
  T = T0 "Specify initial value for T";
equation
  m*c_p*der(T) = h*A*(T_inf-T) "Newton's law of cooling";
end NewtonCooling;

As we saw in the examples in our discussion of Simple First Order System, the previous example consists of a model definition that includes variables and equations.

However, this time we see the word parameter for the first time. Generally speaking, the parameter keyword is used to indicate variables whose value is known a priori (i.e., prior to the simulation). More precisely, parameter is a keyword that specifies the variability of a variable. This will be discussed more thoroughly in the section on Variability. But for now, we can think of a parameter as a variable whose value we must provide.

Looking at our NewtonCooling example, we see there are five parameters: T_inf, T0, h, A, m and c_p. We don’t need to bother explaining what these variables are because the model itself includes a descriptive string for each one. At the moment, there are no values for these parameters, but we will return to that topic shortly. As with all the variables we have seen so far, these are all of type Real.

Let’s examine the rest of this model. The next variable is T (also a Real). Since this variable doesn’t have the parameter qualifier, its value is determined by the equations in the model.

Next we see the two equation sections. The first is an initial equation section which specifies how the variable T should be initialized. It should be pretty clear that the initial value for T is going to be whatever value was given (by us) for the parameter T0.

The other equation is the differential equation that governs the behavior of T. Mathematically, we could express this equation as:

m c_p \dot{T} = h A (T_{\infty}-T)

but in Modelica, we write it as:

m*c_p*der(T) = h*A*(T_inf-T)

Note that this is really no different from the equation we saw in our FirstOrder model from the Simple First Order System example.

One thing worth noting is that the equation in our NewtonCooling example contains an expression on the left hand side. In Modelica, it is not necessary for each equation to be an explicit equation for a single variable. An equation can contain arbitrary expressions on either side of the equals sign. It is the compiler’s job to determine how to use these equations to solve for the variables contained in the equations.

Another thing that distinguishes our NewtonCooling example from the FirstOrder model is that we can independently adjust the different parameter values. Furthermore, these parameter values are tied to physical, measurable properties of the materials or environmental conditions. In other words, this version is slightly more physical than the simple mathematical relationship used in the FirstOrder model because it is related to physical properties.

Now, we can’t really run the NewtonCooling model as is because it lacks values for the six parameters. In order to create a model that is ready to be simulated, we need to provide those values, e.g.,

model NewtonCoolingWithDefaults "Cooling example with default parameter values"
  parameter Real T_inf=25 "Ambient temperature";
  parameter Real T0=90 "Initial temperature";
  parameter Real h=0.7 "Convective cooling coefficient";
  parameter Real A=1.0 "Surface area";
  parameter Real m=0.1 "Mass of thermal capacitance";
  parameter Real c_p=1.2 "Specific heat";
  Real T "Temperature";
initial equation
  T = T0 "Specify initial value for T";
equation
  m*c_p*der(T) = h*A*(T_inf-T) "Newton's law of cooling";
end NewtonCoolingWithDefaults;

The only real difference here is that each of the parameter variables now has a value specified. One way to think about the NewtonCooling model is that we could not simulate it because it had 7 variables (total) and only one equation (see the section on Initialization for an explanation of why the initial equation doesn’t really count). However, the NewtonCoolingWithDefaults model has, conceptually speaking, 7 equations (6 of them coming from specifying the values of the parameter variables + one in the equation section) and 7 unknowns.

If we simulate the NewtonCoolingWithDefaults model, we get the following solution for T.

/static/_images/NCWD.svg

Physical Units

As mentioned already in this section, these examples are a bit more physical because they include individual physical parameters that correspond to individual properties of our real world system. However, we are still missing something. Although these variables represent physical quantities like temperature, mass, etc., we haven’t explicitly given them any physical types.

As you may have already guessed, the variable T is a temperature. This is made clear in the descriptive text associated with the variable. Furthermore, it doesn’t take a very deep analysis of our previous model to determine that T0 and T_inf must also be temperatures.

But what about the other variables like h or A? What do they represent? Even more important, are the equations physically consistent? By physically consistent, we mean that both sides of the equations have the same physical units (e.g., temperature, mass, power).

We could convey the physical units of the different variables more rigorously by actually including them in the variable declarations, like so:

model NewtonCoolingWithUnits "Cooling example with physical units"
  parameter Real T_inf(unit="K")=298.15 "Ambient temperature";
  parameter Real T0(unit="K")=363.15 "Initial temperature";
  parameter Real h(unit="W/(m2.K)")=0.7 "Convective cooling coefficient";
  parameter Real A(unit="m2")=1.0 "Surface area";
  parameter Real m(unit="kg")=0.1 "Mass of thermal capacitance";
  parameter Real c_p(unit="J/(K.kg)")=1.2 "Specific heat";

  Real T(unit="K") "Temperature";
initial equation
  T = T0 "Specify initial value for T";
equation
  m*c_p*der(T) = h*A*(T_inf-T) "Newton's law of cooling";
end NewtonCoolingWithUnits;

Note that each of the variable declarations now includes the text (unit="...") to associate a physical unit with the variable. What this additional text does is specify a value for the unit attribute associated with the variable. Attributes are special properties that each variable has. The set of attributes a variable can have depends on the type of the variable (this is discussed in more detail in the upcoming section on Variables).

At first glance, it may not seem obvious why specifying the unit attribute (e.g., (unit="K")) is any better than simply adding "Temperature" to the descriptive string following the variable. In fact, one might even argue it is worse because “Temperature” is more descriptive than just a single letter like “K”.

However, setting the unit attribute is actually a more formal approach for two reasons. The first reason is that the Modelica specification defines relationships for all the standard SI unit attributes (e.g., K, kg, m). This includes complex unit types that can be composed of other base units (e.g., N).

The other reason is that the Modelica specification also defines rules for how to compute the units of complex mathematical expressions. In this way, the Modelica specification defines everything that is necessary to unit check Modelica models for errors or physical inconsistencies. This is a big win for model developers because adding units not only makes the models clearer, it provides better diagnostics in the case of errors.

Physical Types

But truth be told, there is one drawback of the code for our NewtonCoolingWithUnits example and that is that we have to repeat the unit attribute specification for every variable. Furthermore, as mentioned previously, K isn’t nearly as descriptive as “Temperature”.

Fortunately, we have a simple solution to both problems because Modelica allows us to define derived types. So far, all the variables we have declared have been of type Real. The problem with Real is that it could be anything (e.g., a voltage, a current, a temperature). What we’d like to do is narrow things down a bit. This is where derived types come in. To see how to define derived types and then use them in declarations, consider the following example:

model NewtonCoolingWithTypes "Cooling example with physical types"
  // Types
  type Temperature=Real(unit="K", min=0);
  type ConvectionCoefficient=Real(unit="W/(m2.K)", min=0);
  type Area=Real(unit="m2", min=0);
  type Mass=Real(unit="kg", min=0);
  type SpecificHeat=Real(unit="J/(K.kg)", min=0);

  // Parameters
  parameter Temperature T_inf=298.15 "Ambient temperature";
  parameter Temperature T0=363.15 "Initial temperature";
  parameter ConvectionCoefficient h=0.7 "Convective cooling coefficient";
  parameter Area A=1.0 "Surface area";
  parameter Mass m=0.1 "Mass of thermal capacitance";
  parameter SpecificHeat c_p=1.2 "Specific heat";

  // Variables
  Temperature T "Temperature";
initial equation
  T = T0 "Specify initial value for T";
equation
  m*c_p*der(T) = h*A*(T_inf-T) "Newton's law of cooling";
end NewtonCoolingWithTypes;

You can read the definition type Temperature=Real(unit="K", min=0); as “Let us define a new type, Temperature, that is a specialization of the built-in type Real with physical units of Kelvin (K) and a minimum possible value of 0”.

From this example, we can see that once we define a physical type like Temperature, we can use it to declare multiple variables (e.g., T, T_inf and T0) without having to specify the unit or min attribute for each variable. Also, we get to use the familiar name Temperature instead of the SI unit, K. You might be wondering what other attributes are available when creating derived types. For further discussion, see the section on Built-In Types.

At this point, you might find the idea of defining Temperature, ConvectionCoefficient, SpecificHeat and Mass in every model extremely tedious. It would be, if it were truly necessary. But don’t worry, there is an easy solution to this as you will see in a later section where we discuss Importing Physical Types.