This blog post is a continuation from a previous post on the Modelica Language. This blog post goes into a little more detail regarding variable definition and syntax in equations and algorithms. The Class Restriction of a class can restrict the ability to use certain elements and methods, also described in the previous post.
Generic Definitions of Elements within Classes
Variable
Variables can take many forms, mainly dependent on the type defined. They can be scalar or a matrix of Reals, Integers, Booleans or Strings, or can be more complex containing a set of information. The same format can form as a base and can be expanded with prefixes to define the different uses, with the same syntax. If the variable is left without a prefix then it will not appear in a parameter dialog box, and it should only be used within the class. If a variable has been defined then it must be calculated somewhere in the class or it will cause an error.
Variable definitions are formed from a type definition, a name and can include a description in quotation marks and finish with a semicolon.
Type nameOfVariable "Description of variable";
An example of this could be:
Modelica.SIUnits.Velocity v "Velocity of flange";
Type definitions are very useful when defining a variable as they can contain information that can help build a model. You can define any variable using the basic Real, Integer, Boolean or String types. However, when defining a Real variable there can be units, display units, type grouping associated with the variable. These are all implemented when you define a type that references a type class, all common types are contained in Modelica.SIUnits. This allows Dymola to check units match and allows the user to switch between units when plotting and when entering parameter values for model objects.
There are some points where a variable type is a record, such as in Modelica.Mechanics.MultiBody. Frames.angularVelocity1, shown below, R references the Modelica.Mechanics.MultiBody. Frames.Orientation record. This allows the variable to contain a set of 2 Real variables, T and w, both of which are needed to define the output. This saves requiring to define both when they are associated.
Variable Sizes
Variables do not need to be scalars in their definition, they can be vectors or matrices; such as in the case of a multibody velocity, which is defined in terms of x, y and z velocity. This can be applied by using the square brackets to define the size either after the type definition or the name of the variable. Demonstrated in the image, w is a multibody angular velocity. When populating vectors the format is to use curly brackets with commas between each element.
parameter Modelica.SIUnits.Velocity[3] v = {1,0,0} "Velocity of frame";
or
parameter Modelica.SIUnits.Velocity v[3] = {1,0,0} "Velocity of frame";
When defining the size of a matrix the size of each dimension is separated by a comma, whereas when populating the matrix the rows are separated using a semicolon:
parameter Real T_rel[3,3]=[1, 0, 0; 0, 1, 0; 0, 0, 1] "Relative transformation matrix";
There are some instances where the size of the array is not known when creating a component; in those instances a colon is used to declare an “arbitrary” size.
parameter Real data[:,:] "Matrix of data";
Variable Prefixes
Below are a few of the most common variable prefixes:
parameter
Parameter definitions are similar to the variable definition, but include the parameter definition at before the type. They are variables that are fixed after initialisation, therefore cannot be calculated using time changing variables. By default, parameters appear in the parameter dialog box for a class.
While any variable can contain an annotation, they are very useful when defining parameters as they can control the appearance and location of them in the dialog box. As with any annotation, most of the time they will appear as a green “a” as they are collapsed, and can be opened by clicking on them. They are not required when defining a parameter, and if a user inputs just the letter “a” then this causes an error.
parameter Modelica.SIUnits.Mass m=1 "Mass of the body" a;
constant
Constants are very similar to parameters as they remain constant during the simulation. Unlike parameters they cannot be modified from the parameter dialog box.
input
Commonly used in functions, they are dynamic input variables that are used as an input to the calculations. They appear in the class’s dialog box and can be used to reference other dynamic variables when used.
output
Similar to the input, they are used to interface with other classes when a function is used (outputs of functions are declared using the output prefix.
final
A final prefix is used to restrict modification to parameter, class and variable settings when using the class. For example, when a constant is not intended to be changed but is used throughout a model then a final parameter can be used, which doesn’t appear in dialog boxes but is fixed at initialisation.
final parameter Modelica.SIunits.Acceleration g=9.81 "Gravitational acceleration constant";
The final declaration can also be used elsewhere when a parameter is propagated and the link is not intended to be broken; or when the choice of a replaceable component has been made and shouldn’t be changed for anything else.
Component Definitions
When a class is used within another, it is called a component. The majority of the time it is preferable to modify components in the diagram layer where possible; this maintains the correct syntax. But sometimes it may become necessary to modify them in the text layer. For this the layout is very similar to using variables, with a couple of key differences.
Component definitions are formed from a class path, a name and can include a description in quotation marks and can include annotations and finish with a semicolon:
Modelica.Mechanics.Rotational.Components.Damper damper(d=0.1, useHeatPort=true) "1D rotational damper" a;
The key difference that is found when modifying a component is that it is done within brackets after the name, where parameters/inputs/components are modified by name. Each parameter change must be separated using a comma.
Modifications of components can rely on calculations, as long as the variability and syntax match. For example, you are unable to modify a parameter by referencing a time varying variable; likewise you are unable to define an Integer parameter by referencing a Real parameter.
In many cases it is useful to propagate the parameters to a higher level to constrain the behaviour of the class to a single group of parameters.
Annotations normally contain placement information which controls the location of components and objects in the diagram layer.
replaceable definition
Components and functions can be replaceable to allow controlled variability of a class. This is utilised most easily by right clicking on the replaceable component and selecting Change Class. There is an extended blog post describing this detailing Inheritance within Dymola. It is a more advanced type of class control and can make it considerably more complex.
protected and public variables
Within classes it can be useful to restrict all variables (only used internally, not of use outside the class) to internal use only. Dymola has the ability to limit the view and access to variables if they are declared in a protected section.
When looking at Modelica.Math.Vectors.sort (shown on the right) there are a lot of variables such as gap or wv that are not of use externally. The inputs and outputs have been defined and these are the variables that are available to be modified and used outside the model. Below those variables is a protected clause and then internal variables declared within it.
All elements within a class are public unless made protected. Multiple sections of public and protected elements can exist. For an element to be public either no protected definition is made before the declaration of the element; or a public definition is made after a protected definition.
input Modelica.SIUnits.Velocity v[3] = {1,0,0} "Velocity of frame"; protected Integer yIndex = 2 "Index of the y velocity of a multibody velocity vector"; public output Modelica.SIUnits.Velocity v_y = v[2] "y velocity of frame";
Above shows an example of 2 sections of public code, the input and output, and a protected variable, yIndex. But it is not recommended to have multiple public or protected sections as it can make the text layer confusing and difficult to navigate. For more information on keeping your code layer organised, there is a blog post about how to clean up a Dirty Code Layer.
Written by: David Briant – Project Engineer
Please get in touch if you have any questions or have got a topic in mind that you would like us to write about. You can submit your questions / topics via: Tech Blog Questions / Topic Suggestion.