Tutorial: Advanced System Dynamics Modelling
System dynamics modelling in Simantics is another free domain specific modelling tool that is included into the basic installation. This tutorial introduces the basic features of the system dynamcics modelling tools.
In this tutorial, we are going to bild a work model with two projects and shared workforce. Both the workforce and a separate project (work) are going to be created as modules, so they can be reused several times. Actually the model doesn't limit the number of projects at all.
Contents
Creating model and modules
Let's start by creating the work model and the needed modules. First create a new model by right-clicking on the model browser and selecting New->Model. Alternatively you can select File->New Model from the main menu.
Then create two new modules to your model. Right-click on the Modules folder and select New->Module.
Name your model WorkModel and modules Workforce and Work. You can rename them by right-clicking on the item on the model browser and selecting Rename.
Initial configuration
We will use a top-down approach in our model, so first we will make a simple model configuration with our modules. Open our model configuration by double-clicking Configuration in your model browser.
Drag one Workforce module and one Work module from your model browser to the WorkModel diagram. The modules are automatically named with a suffix number. Rename the modules to Workforce and Work1. You can rename objects on the diagram by double-clicking them or selecting them with one click and renaming them on the properties view below the diagram.
When the modules are on the diagram, we should think what values we would like to get from the modules and what values would we like to use in the modules.
Workforce needs to know, how much work is required and it should give provide information on how much work can be done. To provide the information on how much work can be done, we need an Input variable. Variables can be dragged to the diagram from Symbols view or by using shortcut keys (Shift+I for Input variable). Drag an input variable to the diagram and name it TotalPossibleWorkingSpeed.
Work module on the other hand provides information on how much work is required in it and it needs to know when the work has to be ready. Create an input variable RequiredWorkingSpeed1 and an Auxiliary variable Work1CompletionTime and place all variables like in the picture on the right.
Connect the variables to modules using dependency connections (arrows). Connections are created by holding down Alt key and first clicking on the variable where to start the connection and then clicking on the variable where to end.
Now we have the initial idea of the model, so let's configure the modules.
Workforce module
Open Workforce module by selecting it from the diagram, right-clicking it and selecting Show Module.
Create a Stock variable and name it WorkforceStock. Stock variables are created the same way as Input and Auxiliary variables. The level of the stock is controlled with a valve and a flow. To create the flow, hold down Alt and right-click on an empty space left of the stock. Then left-click on the stock. A cloud, valve and a flow is created. Rename the valve to NetResourcing.
NetResourcing works both ways. To display this also visually, delete the cloud by selecting it and pressing delete on your keyboard. Then create a flow starting from NetResourcing valve and ending on an empty space next to it.
Now you have used all the basic components and connections. From now on the instructions will be a more simplified.
Next we will create four Auxiliary variables: TimeToAllocateResources, WorkforceRequired, Productivity and PossibleWorkingSpeed. Place and connect them accordign to the picture on the right.
To be able to simulate the model, all variables must have valid equations. To configure an equation, select a variable. Variables properties are shown in the Equation view and you can input the required equations in the text fields. For some variables, you need to change the type of the variable to Parameter. The change is made from the pull-down menu Type. You can copy the equations directly from here or type them manually. Variables connected to the selected variable are shown in the Variables list. To speed up typing, you can double click on a variable name and it will be inserted to the equation.
WorkforceStock
Initial value: 0
NetResourcing
= (WorkforceRequired - WorkforceStock)/TimeToAllocateResources
TimeToAllocateResources
Type: Parameter
= 2
Productivity
Type: Parameter
= 1
PossibleWorkingSpeed
= WorkforceStock * Productivity
Is Output
Variables can be set as output by selecting Is Output option from Additional information tab of the variable.
On a previous phase, we wanted to give the value of RequiredWorkingSpeed1 to this workforce module. To get that value, we need to create an input. Create input RequiredWorkingSpeedInput, connect it to WorkforceRequired and write the following equation to WorkforceRequired.
WorkForceRequired
= RequiredWorkingSpeedInput/Productivity
Now this module is ready to be used as a part of the model.
Work module
Open Work module by selecting it from the WorkModel diagram, right-clicking it and selecting Show Module. Alternatively you can double click Work on the model browser.
Create the basic flow of work with stocks and flows like in the picture on the right.
The idea of the model is that first there is work. Work is done at a certain speed. When working, errors are also made. When errors are found, the amount of Errors is reduced, errors are removed from WorkDone and moved back to WorkToDo.
Work needs to be stopped when the project is ready. Since the simulator might face some difficulties to determine the projects readyness when project is almost ready, we need to implement some smoothing to the limit. OpenModelica doesn't yet have a builtin function for smoothing, so we need to implement our own.
Use the following equations for variables:
ProjectIsReady
Initial value: 0
ProjectReadyness
= (xidz(WorkDone, ProjectWorkAmount, 0.0) - ProjectIsReady) / 0.08
xidz is short for function X if devided by zero.
As you can see, ProjectWorkAmount is highlighted. Your model doesn't contain such variable and it is not connected to ProjectReadyness. Create an Input variable ProjectWorkAmount with default value 1000 and connect it to ProjectReadyness. The reason we are using input variable is that you can determine the default size of a project, but if you want to change it, you can change it from outside the module.
Next we need to define how errors are found. For that we need new variables: WorkQuality and ErrorsFoundTime. Create the variables and connections according to the picture and give variables their equations.
ErrorsGenerated
= (1-WorkQuality) * WorkingSpeed
ErrorsFoundRate
= Errors/ErrorsFoundTime
WorkQuality
Type: Parameter
= 0.9
ErrorsFoundTime
Type: WithLookup
With Lookup: xidz(WorkDone, ProjectWorkAmount, 0.0)
Lookup table: {{0,5},{0.5,3},{1,0.5},{2,0.5}}
WithLookup is a variable type where the value is interpolated from a 2-dimensional table (Lookup table) using the value determined in the "With Lookup" field.
To calculate our own need of workforce we need WorkCompletionTime input variable and the following auxliary variables:
RequiredWorkingSpeed
= if ProjectIsReady < 1 then xidz(WorkToDo, TimeToDeadline, MaximumWorkingSpeed) else 0
Is Output
MaximumWorkingSpeed
Type: Parameter
= 500
TimeToDeadline
= max(0, WorkCompletionTime-time)
time is a universal variable that gives the current simulation time.
We need to decide how the workforce is allocated between all the work modules that are using the same workforce. For that we need to know how much work can be done and how much workforce other works require.
Create two Inputs, RequiredWorkingSpeedTotalInput and PossibleWorkingSpeedInput, and an auxiliary variable WorkAllocation.
WorkAllocation
= xidz(RequiredWorkingSpeed, RequiredWorkingSpeedTotalInput, 0.0) * PossibleWorkingSpeedInput
Finally let's give initial values for all the remaining variables:
WorkingSpeed
= if ProjectIsReady < 1 then WorkAllocation else 0
WorkToDo
Initial value: ProjectWorkAmount
WorkDone
Initial value: 0
Errors
Initial value: 0
Connecting modules
Our modules are complete. Let's get back to the WorkModel Configuration. Set Work1CompletionTime as Parameter and give it value 10.
Connections between modules are made in the properties of the module. Select Work and open tab Inputs from the properties. The table lists all input variables in the module that are available. Clicking on the Refers to output column will open a drop-down menu that shows all available variables that are connected to the module. By selecting a variable, you connect that variable to the input.
Work1 need also information on how much working speed is required by all works. Since Work1 is the only work, create a dependency connection from RequiredWorkingSpeed1 and connect it to RequiredWorkingSpeedTotalInput.
In Outputs tab, make the only possible connection.
Workforce module has only one input and one output. Create the only possible connections.
Now your model is ready for simulation!
Simulating the model
To make the simulation time longer, select Configuration on the model browser. Give the model Stop time 24.0
To run simulations, you must activate an experiment. Expand the experiments folder on your model browser. There is one ready-made experiment. Double click on the experiment and the experiment control buttons appear on the toolbar. Press the play button .
System shows the simulation progress in the progress bar on the lower right corner of the screen.
When the progress indicator disappears, the simulation is complete.
Now you can select a variable and see its simulation results in the trend view. For example WorkDone variable in Work1 module will give the following graph.
Adding modules
We created the WorkModule to be reusable. To use two WorkModules in the model, you must do the following.
Populate a second WorkModule to WorkModel configuration and name it Work2.
Create RequiredWorkingSpeed2 input variable and Work2CompletionTime auxiliary variable.
We need a sum of all working speed requirements to give to the work modules. For this purpose, create an auxiliary variable RequiredWorkingSpeedTotal which sums the requirements.
You can also have a different size work. To make Work2 smaller, create an auxiliary variable Work2Amount.
Use the following equations:
Work2CompletionTime
Type: Parameter
= 13
Work2Amount
Type: Parameter
= 800
RequiredWorkingSpeedTotal
= RequiredWorkingSpeed1 + RequiredWorkingSpeed2
Make the connections shown in the picture and connect the inputs and outputs to the modules.
Work1 Inputs
RequiredWorkingSpeedTotalInput -> RequiredWorkingSpeedTotal
Work2 Outputs
RequiredWorkingSpeed -> RequiredWorkingSpeed2