Simantics System Dynamics
Contents
Simantics System Dynamics
Simantics System Dynamics is currently the only open source modelling and simulating tool for Simantics. Simantics System Dynamics is under development and will go through some changes in the future. New features will be added and old ones improved according to the needs of the modellers. New features include module libraries and different analysis tools.
This documentation introduces you to the current version of Simantics System Dynamics. Documentation includes the basic modelling principles and a guide on how to model system dynamics models with Simantics System Dynamics. If you like to get to know the tool better and try modelling and simulating yourself, install the software and try our basic and advanced tutorials!
Introduction to System Dynamics Simulation
System Dynamics
System dynamics is an approach to understanding different organizations, markets and other complex systems and their dynamic behavior. System dynamics modelling in Simantics is a free modelling tool. See installation instructions.
Model
System dynamics model is generally understood as the model configuration. In this tool, the model contains also other components. Model can have Operating interfaces that enable the use of the model with simple controls. Operating interfaces are configured separately and when using them, the complex model is hidden from the user. Experiments are the way to simulate the model. In the future, you can have experiments with different configurations, for example different initial values for some parameters. In that way, you don't have to always configure the model for different scenarios. Modules folder contains all the different module types in your model and you can create new module types there.
Components
Most of the components you can use in your models are basic system dynamics components. The modularity of the models introduces two additional components, Modules and Inputs. All the components are explained below.
- Auxiliary
- Auxiliary is the most basic variable you can use. It represents a single value or a mathematical expression. There are different types of auxiliary variables currently in the system: Auxiliary, Parameter, Constant and WithLookup. Auxiliary is the default type. Parameters are single values that the user can change. When only parameters are changed, the model simulates faster, because the system does not have to recompile the model. WithLookup is a special variable that has an expression and a lookup table. The expresssion defines what value is taken from the defined table.
- Dependency
- Dependency is an arrow that connects two components. It means that the value of the variable from which the arrow starts is used to calculate the value of the variable where the arrow ends.
- Flow
- Flow connects clouds, valves and stocks. Flow represents an actual flow of something from stocks or clouds to stocks or clouds. There has to be at least one valve in a flow and the system creates it automatically, if none of the ends of the flow is a valve.
- Valve
- Valve regulates the rate of a flow. The value of a valve is automatically used in calculating the level of an adjacent stock. Valves behave just like Auxiliary variables but look different and you can connect also flows to them.
- Stock
- The value of a stock variable is an integral of flows leaving and flows arriving to the variable. The integral is calculated automatically from the valves that are connected to the variable with flow connections. You must give an initial value to the stock. Initial value can be a single value or an equation. You can use values of other variables to calculate the initial value.
- Cloud
- Cloud is not a variable. It represents a starting or ending point of a flow, if it is not in the scope of the model.
- Module
- Modules enable structural modeling. Modules are defined just like the basic model configuration, but the module component hides the actual configuration. You can only connect dependency connections into the module and dependency connections from the module must end to Input variables. The interface of the module is defined using input and output variables in the configuration of the module. All variable types can be set as output variables. If a variable is an output variable, its font is bold.
- Input
- Input variables are the way of getting values from other modules. Inputs look like auxiliary variables except their font is italics. You can set a default value to the input variable in case it is not connected to any variable. Connections are made from the modules properties, when the module is populated. Input doesn't have to be connected with an arrow to a module. If the variable has no connections, it can get values from a higher level in the hierarchy. If an input is connected to an output, the output and its module are shown below the variable using dot notation.
Modeling principles
System dynamics modelling is much more than just mathematical formulas and nice graphs. Models are ways of communicating. There are some basic principles in system dynamics modelling that make the models easier to read and understand. You do not have to apply these principles to simulate models, but using them makes it easier for you to communicate your model to others.
- Variable names
- Variables names should be nouns, not verbs. The names should be positive: for example it is easier to understand that satisfaction decreases than dissatisfaction rises.
- Variable names can and should have multiple words, if they are needed. Unfortunately current version of the tool does not support spaces in variable names. A good practice is to use CamelCase if name contains multiple words. This means that you start every word woth a capital letter (example: ExampleVariable).
- Connections
- You should try to avoid overlapping dependency arrows. In some situations, however, it is not possible. Dependencies should also form distinctive loops, if there is a loop. It makes it easier to read and understand the model and its behavior.
- Graphical annotations
- System dynamics contains usually annotations for loops, polarities, delays and so on. Currently those annotations are not supported, but the support will be added later. Annotations are important, again, for communicating the behavior of the model.
Installation Instructions
System dynamics tool is a provided with the Simantics platform.
- Download installer from Simantics download page
- Install the program to a directory without spaces.
- Run Simantics-Sysdyn.exe
- (Default path in windows: C:\Simantics\Sysdyn\1.2\simantics-sysdyn\Simantics-Sysdyn.exe)
OpenModelica is used to build and simulate the models. Simantics platform has integrated OpenModelica 1.7 for Windows environments. For other versions and other environments you need to install OpenModelica.
Workbench
- Diagram
Diagram is the area where you will graphically modify your model. Diagrams are built from elements that can be dragged from Symbols view or populated using shortcut keys. - Model Browser
Model browser shows the structure of your model and all items related to it.
Symbols view is stacked with the model browser and used for dragging elements to diagrams. - Properties
Property view shows the selected variable's properties. Property view has a different layout depending on the type of the selected component. The view can also have different tabs depending on the component type. Basic tabs are with variables are Equation and Additional information. - Trend
Trend view shows the graphical representation of the values of the selected value over time. For the trend to be shown, a simulation has to be run. The view shows always the results of the latest run, but you can save results of a simulation and show them in the same trend with results from another simulation. Values view and Dependencies are stacked with Trend view and can also be used for analyzing the model. - Experiment controls
Experiment controls are shown when an experiment is active. Experiment is activated by double clicking an experiment in the model browser. With the experiment control, you can start simulation runs and save simulation results.
If you accidentally close a view, you can reopen them from Window->Show View->Other...
Modelling
Basic modelling
Basic modelling functions enable you to create and configure models. System dynamics modeling is basically pretty simple, so with these instructions you can build small and also very large models. The tricky part is writing all the expressions and adjusting the model so that it actually tells you something.
- Creating a new model
- Start a new model by right-clicking the model browser and selecting New->Model or from the main menu File->New Model.
- Creating a new module type
- Create a new module type by right-clicking on the Modules-folder and selecting New->Module. This creates a new module type that you can populate to your other modules and the model configuration.
- Configuring a model
- Model configuration can be opened by double clicking Configuration in the model browser.
- Configuring modules
- Configuration of a module type can be opened by double clicking the module type you want to configure. You can also open the configuration of a module from a diagram, when a module has been populated to that diagram, by right-clicking the module and selecting Show Module. When opening modules from diagram, the opened diagram knows to which diagram the module has been populated and can show the connections between the modules. Keep in mind that when making changes to a module, the changes apply to all instances of the module!
- Populate variables
- You can drag variables to a diagram from symbol view. You can also populate variables using shortcut keys
- Populate modules
- Modules are populated from the model browser. Just drag the module you want to populate from the Modules folder to a diagram.
- Create connections
- There are two types of connections: dependencies and flows. Both are created basically the same way. Hold Alt down and click on a variable. Left click starts a dependency, right click starts a flow. Both are ended to another variable with a left click.
- Flows can also be started and ended to an empty spot in the diagram. If there is no start or end variable, a cloud will be created. Also if start or end is not a valve, a new valve is created in the middle of the flow.
- There are some restrictions on what connections can be made, but don't worry, the user interface won't let you do connections that are not allowed.
- Connections between modules
- Outside the module
- You can connect variables to variables in modules like this:
MODULE -----> INPUT or ANY VARIABLE -----> MODULE
- This is just the visual configuration, but you need those connections to really connect variables in the module's properties.
- In Inputs -tab you select which variables you connect to inputs inside the module. In Outputs -tab you select which variables you lift from the module to inputs outside it.
- Inside the module
- Input variables get values from outside the module
- Output variables can send their values outside the module. From the variable properties, select Additional Information and press Is Output
- Configure variables
- Select a single variable from diagram or model browser. The properties of the variables are shown in the equation view and you can modify them.
- Export model
- To export your model to a file, select your model from the model browser, right-click and from the context menu choose Export->Model. Select the folder where to export your model, give the file a name and press Save. You do not need to export a model to Save it, the model is automatically saved in your database. Export can be used to for example create different versions of the model, create backups or to transport it to another database.
- Import model
- Right-click on the model browser and select Import->Model. Browse to your .tg file and select open. The model is added to your model browser.
Shortcut and control keys
Shortcut keys for configuring a model on diagram.
Esc | Cancel operations (e.g. connection and rename). |
Shift + A | Hover Auxiliary at the cursor position, populate with left mouse button. |
Shift + S | Hover Stock at the cursor position, populate with left mouse button. |
Shift + C | Hover Cloud at the cursor position, populate with left mouse button. |
Shift + V | Hover Valve at the cursor position, populate with left mouse button. |
Shift + I | Hover Input at the cursor position, populate with left mouse button. |
Alt + left mouse button | Start an arrow from a variable. End to another variable by clicking left mouse button. |
Alt + right mouse button | Start flow from a variable. End by clicking left mouse button.
If a flow is not started or ended on to a variable, a cloud will be created to that end. |
Delete | Remove selected variables |
Ctrl + left mouse button | Select multiple variables |
Mouse wheel or + and - |
Diagram zoom |
drag(mouse3) or drag(shift + any mouse button) |
Diagram pan |
Ctrl + Z | Undo diagram action |
Ctrl + Y | Redo diagram action |
Ctrl + C | Copy selected elements |
Ctrl + X | Cut selected elements |
Ctrl + V | Paste copied or cut elements |
G | Show / hide grid |
R | Show / hide ruler |
Other shortcut keys can be found selecting Window -> Preferences from the main menu. Keys are located in General -> Keys.
Simulation
- Simulate model
- To simulate a model, you need to activate an experiment. Browse to an experiment in you model browser and double click on the experiment. Experiment controls appear to the main tool bar. Click on the play button to run a simulation.
- Analyze results
- There are currently three analysis tools in the system dynamics tool.
- Trend
- Values
- Dependencies
- Compare results
- You can compare different results of the same model by saving simulation results and displaying the saved results side by side with other results. You can save your results after simulating by clicking the save button on your experiment controls. The saved results appear to model browser under the active experiment. To show the results on trends and tables, right-click on the result and select Show on charts.
Operating Interfaces
How interfaces can be created, how they can be used, current components
- Create
- Right-click on Operating interfaces and select New->Operating UI. Open the Operating User Interface by double clicking it.
- Configure
- Operating UIs have their own set of widgets. Widget symbols can be seen in the Symbols view and dragged to the diagram. The properties of the widgets can be modified from the properties view (same as equation view).
- To connect a variable to a widget, just drag it from the model browser to the widget.
- You can use monitors as labels, but to change the text on the monitor, you have to switch to operating mode by clicking .
- Use
- To use the interface you have created, you have to switch to operating mode by clicking . Activate a simulation, run it and the trends will show the results. You can switch values of parameters with the widgets and simulate again.
Multidimensional variables
Modeling
Models with multidimensional variables look just like any other models. The structure of the models is replicated givin multiple indexes to variables. For users with programming background, notation Variable[] may be familiar. In system dynamic modeling we need to give names to the indexes. Instead of using numbers to define the indexes, like in normal programming, we use enumerations. The steps to create a model with multidimensional variables are as follows (with examples):
- Create the model structure
Model with multidimensional variables looks just like any other model.
- Create Enumerations and define the indexes
Enumerations are created by right-clicking configuration and selecting New->Enumeration.
Define enumeration indexes by adding as many indexes as you want. Rename the indexes by selecting them and then clicking on them again. - Add Enumerations for variables
Select the variable that you want to be multidimensional. From the Indexes -tab in the property view, move the wanted enumerations to the right. The order of the enumerations does matter. - Define equations for all possible indexes
Multidimensional variable can be thought as a multidimensional table. Each cell of the table needs to have an expression or a value. A cell cannot have multiple definitions. All cells can be defined in one expression like in the following example. E1 and E2 have both three indexes, so the resulting definition can be {{1,2,3},{4,5,6},{7,8,9}}.
Expressions
Values for all cells in the variable matrix can be defined in a single expression.
In many situations, it is however more clear to define separate expressions for each cell or blocks.
- Define range for the expression
- Define the expression (dimensions of the defined range and the result of the expression must match!)
- Create a new expression
- Select the new expression
Repeat until there is value for each cell. There must be exactly one value for each cell.
Array slices
Many times it is useful to access a slice of a multidimensional variable. In this chapter, we will use the following example variable:
enumeration E1 = one, two, three enumeration E2 = eins, zwei, drei Auxiliary[E1, E2] = {{1,2,3},{4,5,6},{7,8,9}}
The whole variable can be accessed in three different ways:
- Auxiliary
- Auxiliary[E1, E2]
- Auxiliary[:, :]
The following explains different methods for accessing parts of the variable
// Single cell Auxiliary[one, eins] = 1
// Slices Auxiliary[one, E2] = {1,2,3} Auxiliary[E1, zwei] = {{2},{5},{8}} // In addition to single cells and the whole enumeration range, a subrange of the enumeration can be used Auxiliary[two : three, E2] = {{4,5,6},{7,8,9}} Auxiliary[one : two, zwei : drei] = {{2,3},{5,6}}
The syntax for accessing parts of variables can be used in both expression range definitions and in expressions.
Arithmetic Operators
Arithmetic operations are defined in Modelica. Below are examples of different operations.
- Addition and substraction
Addition and substraction are calculated elementwise
{1,2,3} - {0,2,3} = {1,0,0} {{2,2},{4,4}} + {{8,8},{1,1}} = {{10,10},{5,5}} {1,2,3} - {1,2} = ERROR! Different array sizes
- Division
Division with a scalar
{5,10,15} / 5 = {1,2,3} 5 / {5,10,15} = ERROR! not allowed
Division with an array
{1,2,3} / {1,2,3} = ERROR! not allowed // Elementwise {1,2,3} ./ {1,2,3} = {1,1,1}
- Multiplication
Multiplication with a scalar
{1,2,3} * 2 = {2,4,6} 5 * {1,2,3} = {5,10,15}
Matrix multiplication with an array
{{3,4},{5,6}} * {1,2} = {11,17} {{3,4},{5,6}} * {1,2,3} = ERROR! incompatible array sizes //Elementwise {1,2} .* {1,2} = {1,4} Real[3,2] c = {{1,2},{3,4},{5,6}}; Real[2,2] d = {{3,4},{5,6}}; Real[2,2] cd; cd = c[2:3, :] .* d; // Result: {{9,16},{25,36}}
Builtin functions
Modelica has some builtin functions that help using multidimensional variables. This chapter introduces some of the builtin functions.
- Dimension and size functions
We will use the same example variable as previously.
enumeration E1 = one, two, three enumeration E2 = eins, zwei, drei Auxiliary[E1, E2] = {{1,2,3},{4,5,6},{7,8,9}}
- ndims(A)
The number of dimensions in array A
ndims(Auxiliary) = 2
- size(A, i)
The size of dimension i in array A
size(Auxiliary, 2) = 3
- size(A)
A vector of length ndims(A) containing the dimension sizes of A
size(Auxiliary) = {3,3}
- Construction functions
In addition to normal array constructing, a special construction functions can be used.
- zeros(n1,n2,n3,...)
An array full of zeros with dimensions n1 x n2 x n2 x ...
zeros(2, 2) = {{0,0}, {0,0}}
- ones(n1,n2,n3,...)
An array full of ones with dimensions n1 x n2 x n2 x ...
ones(2, 2) = {{1,1}, {1,1}}
- fill(s,n1,n2,n3)
Like zeros() and ones(), but with user defined value (s) for array elements.
fill(3,2,2) = {{3,3}, {3,3}}
- identity(n)
Creates an n x n integer identity matrix with ones on the diagonal and all other elements zero.
identity(3) = 1 0 0 0 1 0 0 0 1
- diagonal(v)
Constructs a square matrix with elements of vector v on the diagonal and all other elements zero.
diagonal({1,2,3}) = 1 0 0 0 2 0 0 0 3
- linspace(x1,x2,n)
Constracts a Real vector from x1 to x2 with n equally spaced elements.
linspace(2,5,4) = {2,3,4,5}
- Reduction functions
Reduction functions reduce arrays to scalars.
- min(A)
Returns the minimum value in array A.
Real A = {{1,2},{3,4}} min(A) = 1
- max(A)
Returns the maximum value in array A.
Real A = {{1,2},{3,4}} max(A) = 4
- sum(A)
Returns the sum of values in array A.
Real A = {{1,2},{3,4}} sum(A) = 10 // 1 + 2 + 3 + 4
- product(A)
Returns the product of values in array A.
Real A = {{1,2},{3,4}} product(A) = 24 // 1 * 2 * 3 * 4
- Using functions with iterators
Functions min(A), max(A), sum(A) and product(A) reduce arrays to scalars. When you use multidimensional variables, you will most probably like to reduce less dimensions. This can be achieved using iterators with reduction functions. The result is constructed as an array, if curly brackets {} are used to enclose the expression.
enumeration E1 = one, two, three enumeration E2 = eins, zwei, drei Auxiliary[E1, E2] = {{1,2,3},{4,5,6},{7,8,9}} AuxiliarySum[E1] = {sum( Auxiliary[ i , E2 ] ) for i in E1} // Result: {6, 15, 24} /* Same as: {sum(Auxiliary[one, E2]), sum(Auxiliary[two, E2]), sum(Auxiliary[three, E2])} {sum({1,2,3}), sum({4,5,6}), sum({7,8,9})} */
One expression can have multiple iterators.
{sum(Array[ i, j, E3]) for i in E1, j in E2} // Dimensions reduced from 3 to 2
The range doesn't have to be the whole enumeration. Subranges can also be used.
{sum( Auxiliary[ i , eins : zwei ] ) for i in E1.one : E1.two} // Result: {3, 9} /* Same as {sum(Auxiliary[one, eins : zwei]), sum(Auxiliary[two, eins : zwei])} {sum({1,2}), sum({4,5})} */
Simulation results
Multidimensional variables provide multiple results for the same variable. One result for each index. The trend view clutters very quickly when you add dimensions to the variables.
The clutter can be reduced by selecting which enumeration indexes are shown in charts. Select an enumeration and tick the indexes that you want to show. The same settings apply to each variable that uses the enumeration. This way you can follow an interesting index throughout the model.
Array Variables in Modules
You can also use array variables inside modules. Enumeration need to be defined separately for each module type and added to all necessary variables, also inputs and outputs (see Modeling).
When defining a module, modeler may not want to restrict the size of the array variable. In many cases the same module structure could be used for both large and small arrays. For example if the module is a project, a project may have three or even twenty phases. In this case the enumerations inside modules need to be set as replaceable.
In this example, the original enumeration that the modeler used had two indexes. We are using an instance of this module, but we need to use array variables that have three indexes instead of two. We are using two variables and an instance of the module.
In the parent configuration, we have used an enumeration with three indexes in the two variables.
The replacement can be defined in the properties of the module instance. When the module instance is selected, a table with all the replaceable enumerations is shown. By clickin on the cell next to the enumeration, a drop-down box is shown with all the enumerations in the parent module. If an enumeration is selected, it will replace the enumeration inside the module during simulation. The replacement will not, however, show elsewhere in the model.
When creating replaceable enumerations in modules, modelers need to be very careful. Direct references to single enumeration elements are not allowed, since the enumeration elements will change, if the enumeration is replaced for simulation!
Functions
Modelica provides a convenient way to use functions in your models. You can create your own functions, import complete function libraries and share function libraries to be used in all of your models.
Creating functions
You can create new functions to the Functions -folder in your model or to function library folders. Right-click on the folder and select New->Function.
Functions that can be found from Functions -folder can be used in your variable definitions.
Functions are defined using Modelica language. The variables used in the function are defined in the declaration section. Function needs an output and an arbitrary number of inputs. Modelica specification enables use of multiple outputs, but this feature is not supported. The inputs are given in the same order as they are used in calling the function.
Algorithm section defines the actual functionality of the function. In algorithm sections you must use assignments ":=" instead of just plain "=". All the assignments are calculated in the order they are written.
Below is an example of a simple function. For more examples, see the built-in functions provided with the tool and Modelica specifications.
Function libraries
Functions can be collected into libraries. This is a good way of organizing your functions. If function is located in a library, you need to append the library name to the function call (e.g. ExampleFunctionLibrary.ExampleFunction(arg1, arg2)). With libraries, you can also have functions with same names (e.g. library1.func(arg) and library2.func(arg)).
There are three types of function libraries: normal function library, built-in function library and shared function library. Normal function libraries can be created to a model and are available only in that model. Built-in libraries are available in all models and calls to built-in functions should not include the library name. Shared functions are available to all models in your workspace, but you need to enable them to each model individually.
Create a new function library by right-clicking on Functions folder, Shared functions folder or other module library.
If you create a shared function library, the library can be added to other models or removed from current model by selecting the Shared Functions -folder and using the properties view.
External functions
Modelica allows you to use external functions that are programmed using C language. Below is a simple example of using a function that returns the sum of two arguments.
double exampleCFunction(double x, double y) { double res; res = x + y; return res; }
You need to create an Object file (.o) of your code, import it to a function and define the function to use the library and function that you created. If you don’t have a C-compiler, you can use the one provided by the Simantics installation
(e.g. simantics_home/plugins/org.simantics.openmodelica.win32_x/MinGW/bin/mingw32_gcc.exe -g -O -c ExampleCFunctionCode.c).
You can use the external function like any other function in your variables. Using equation ExampleExternalFunction(Stock1, 10) in an auxiliary variable (Auxiliary2) gives the following result.
In addition to .o -files, you can import .c and .h files. By including these to the function, the source code can be reviewed and later by you or others that use the function.
Modelica functions
Modelica has built-in functions that can be used anywhere and are not visible in function libraries. This section covers a large number of those functions. For functions related to array variables, see see builtin functions for arrays.
abs(x) | Returns the absolute value of x. Expanded into "(if x >= 0 then x else -x)". |
acos(x) | Inverse cosine. |
asin(x) | Inverse sine. |
atan(x) | Inverse tangent. |
atan2(x1,x2) | four quadrant inverse tangent. |
cat(n,A,B,...) | General concatenation function that concatenates arrays A,B,... along the nth dimension. |
ceil(x) | Returns the smallest integer not less than x, the closest integer above x. |
cos(x) | Cosine. |
cosh(x) | Hyperbolic cosine. |
cross(x,y) | Returns the 3-vector cross product of the 3-vectors x and y. |
delay(expr, delayTime) | Returns the value of expr at the time time-delayTime. The value of expr is returned when time <= time.start + delayTime. |
der(x) | Time derivative of x. X must be have continuous-time variability. |
div(x, y) | Returns the algebraic quotient x/y with any fractional part discarted. E.g. div(10,3) = 3. |
edge(b) | Returns true when the value of the boolean expression b changes. Expanded into (b and not pre(b)). |
exp(x) | Exponential, base e. |
floor(x) | Returns the largest integer not greater than x, the closest integer below x. |
initial() | Returns true at the beginning of the simulation. |
integer(x) | Returns the largest integer not greater than x as an integer. |
log(x) | Natural logarithm. (base e, x > 0) |
log10(x) | Base 10 logarithm. (x > 0) |
mod(x, y) | Returns the integer modulus of x/y: mod(x,y) = x - floor(x/y) * y. |
noEvent(expr) | noEvent around an expression causes the expression to NOT generate event. |
pre(x) | Returns the preceding value of y from time event that has occured before current time. |
rem(x, y) | Returns the integer remainder of x/y: rem(x,y) = x - div(x,y) * y. |
sample(start, interval) | Returns true and triggers time events at times start + i * interval (i=0,1,...). |
sign(x) | Returns -1 if x is negative, 1 if x is positive. Expanded into "(if x > 0 then 1 else if x < 0 then -1 else 0)". |
sin(x) | Sine. |
sinh(x) | Hyperbolic sine. |
sqrt(x) | Square root of x. The value of x must be greater or equal to 0 or an assertion error occurs. |
tan(x) | Tangent. |
tanh(x) | Hyperbolic tangent. |
terminal() | Returns true at the end of a successful simulation. |
Simantics | System Dynamics Modelling
Tutorial: Basic System Dynamics Modelling
System dynamics modelling in Simantics is a free modelling tool that is included into the basic installation. This tutorial introduces the basic features of the system dynamics modelling tool.
Tutorial: Advanced System Dynamics Modelling
This tutorial introduces the more advanced features of the system dynamics modelling tool: Modules and Operating interfaces