|
Coensys, Inc. |
|
| System Dynamics Models Using AnyLogic 6Anylogic supports development of sophisticated web based system dynamics models in an intuitive graphical environment. System Dynamics was developed by J. Forrester at MIT in 1961. System dynamics models capture the causal structure of a system. The causal relationships can be non-linear, have delays in them, and can represent feedback loops in the system. System dynamics models capture the aggregate behavior of a system that arises due to the causal structure of the system. Here are the typical steps in developing a model:
A
system dynamics model consists of stocks and flows.
Stocks are typically Nouns and represent a state of a system - Things that accumulate over time. Examples of stocks are: Volume of water (Gallons), Account Balance, Number of Employees, Inventory, etc. Flows are typically Verbs Represent rates of change or activities. Examples are: Add Water (Gallons /min), Cash flow, Hiring Rate, Sales, etc. Click here to see a dynamically changing SD simulation. Building SD models in Anylogic is easy: Example System Dynamics Model in Anylogic
Example System Dynamics Model as Published on Web
System Dynamics Modeling with Anylogic 6
Developed by Jay W.
Forrester in the 1950s, System Dynamics “the study of information-feedback
characteristics of industrial activity to show how organizational structure,
amplification (in policies), and time delays (in decisions and actions) interact
to influence the success of the enterprise”. The range of System Dynamics
applications includes also urban, social, ecological types of systems. In System
Dynamics the real-world processes are represented in terms of stocks (e.g. of
material, knowledge, people, money), flows between these stocks, and information
that determines the values of the flows. System Dynamics abstracts from single
events and entities and takes an aggregate view concentrating on policies. To
approach the problem in SD style one has to describe the system behavior as a
number of interacting feedback loops, balancing or reinforcing, just like shown
on the figure below, and maybe delay structures.
In this classic textbook
model of product diffusion Potential Adopters become adopters at Adoption Rate
that depends on advertising and word of mouth promotion. Important things to
know about system dynamics modeling: ·
as long as the
model works only with aggregates, the items in that same stock are
indistinguishable, they do not have individuality; ·
the modeler has
to think in terms of global structural dependencies and has to provide accurate
quantitative data for them. Stock and Flow Diagrams
AnyLogic allows you to
create complex dynamic models using standard System Dynamics graphical notation.
In AnyLogic you draw stock and flow diagrams in the graphical editor diagram
using special system dynamics variables supported by AnyLogic: stocks, flows and
auxiliaries. Stocks (also known as
levels, accumulations, or state variables) change their value continuously over
time. Flows, also known as rates, change the value of stocks. In turn, stocks in
a system determine the values of flows. Intermediate concepts are known as
auxiliaries and can change instantaneously. Stock
value is calculated according to the integral function you specify. The function
should be defined in the following form: <inflow
1> + <inflow 2> … - <outflow 1> - <outflow 2> … The value of inflows i.e.
flows that increase stock value, are added and the value of outflows, i.e. flows
that decrease stock are subtracted from the current value of the stock.
Stock
and flow diagram in AnyLogic AnyLogic visualizes the
resulting dependencies between system dynamics variables with arrows.
Dependencies between stocks and flows are shown with thick yellow arrows.
Inflows are shown as arrows pointing from flow top stock and outflows vice versa
- from stock to flow. Thin arrow pointing from variable A to variable B
means that variable A is mentioned in the equation of variable B. Stocks
1.
Choose the Stock
2.
Click in the
graphical editor where you want to place the stock. 3.
In the Equation
section of the Properties view, define a differential equation for a
stock. Type the right hand of the equation in the d(<stock_name>)/dt =
edit box. 4.
Specify the initial
value of the stock in the Initial value edit box. Flows
1.
Double-click the
stock where the flow flows out and then click the stock where the flow flows in.
2.
AnyLogic creates
new flow variable and makes it an outflow for the first stock and an inflow
for the second one. Arrows appeared on the stock and flow diagram denote
flow influence on stocks. 3.
Go to the General
page of the Properties view to set up properties of the flow. 4.
If you need to
rename the flow, you should use refactoring. Type new name of the flow in the Name
edit box. When finished typing, please press Ctrl+Enter to
rename flow names mentioned in formulas of stocks also 5.
Type the formula
calculatig the value of the flow in the <flow_name>= edit box.
Auxiliaries
1.
Choose the Flow
Aux Variable
2.
Click in the
graphical editor where you want to place the variable. 3.
Type the formula
for a variable in the <variable_name>= edit box. 4.
If you are
creating an auxiliary that will have the constant value, check the Constant
check box. Table Functions
AnyLogic supports special
type of functions - table functions. A table
function is a function defined in the table form. You can simply
make it continuous by interpolating and/or extrapolating. You may need table
functions to define a complex non-linear relationship which cannot be described
as a composition of standard functions, or to bring experimental data defined as
a table function to a continuous mode. Table function works in the
following way: the user defines a function by giving a number of (argument,
value) pairs, i.e. a number of base points on XY chart. AnyLogic builds the
table function based on the given data and the chosen interpolation type. A call
of a function with some value passed as a function argument, will return a
(possibly, interpolated) value of the function. A number of behaviors are
supported for the case x is out of original argument range.
1.
Choose the Table
Function
2.
Click in the
graphical editor where you want to place the table function icon. 3.
Go to the General
page of the Properties view and specify the function properties. 4.
Specify the name
of the function in the Name edit box. 5.
Define data for a
table function in the Table data table. Each "argument-value"
pair is specified in an individual row of the table. To define pair of values,
go to the last row of the Table data table and enter the argument value
in the Argument cell and the function value in the Function cell.
To remove some pair of values, select the corresponding row of the table
and click the
6.
Specify how the
table function should be interpolated using the Interpolation drop-down
list. 7.
Specify how the
table function should behave when its argument is out of range using the Out
of range drop-down list.
Table Function Interpolation
Table function can be
interpolated. The possible interpolation types are listed below. None – No interpolation applied. Step – Step interpolation. The function value between two points is the
same as in the point with less argument value. Linear – Linear interpolation. The points are connected with straight-line
segments. Spline – 4th order spline interpolation. The points are connected with 4th
order polynomial segments. For each point 0th, 1st, and 2nd derivatives of right
and left segments are equal. The 2nd derivative in the ending points equals
zero. If you want to get a smooth
curve, the spline interpolation is the best. However, it takes more time to
calculate a spline interpolation than a linear one. So, if a discontinuous
function is acceptable, use the linear interpolation.
1.
Select the table
function icon in the graphical editor or in the Project view. 2.
On the General
page of the Properties view, choose the corresponding interpolation type
from the Interpolation drop-down list. Table Function Behavior in Infeasible Area
The feasible area of a table
function is the function’s range, if the function is interpolated; or it is
the defined set of points only, if no interpolation is set. You should define
what should happen if a table function argument lies out of feasible area.
Supported behavior types are the following: Error – If argument lies out of feasible area, runtime error is raised and a
message box reporting about the error is displayed. Nearest– The function is extrapolated by using the nearest valid argument,
i.e. for all arguments to the left (right) of the range, the function takes the
value the function has in the leftmost (rightmost) point. Repeating – The function is extrapolated by repeating, i.e. it is
made periodic with the function range as a period. Custom – If argument lies out of feasible area, table function returns a
custom value, defined in the Value edit box below this option.
1.
Select the table
function icon in the graphical editor or in the Project view. 2.
On the General
page of the Properties view, choose the corresponding function behavior
type from the Out of range drop-down list. Accessing Table Function Values
To get the value of a table
function for some argument, call the table function as any other
function by its name, passing the argument value as the function parameter.
For instance, if you have a table function named lookup1
in your model, to get the function value for the argument 5, call: lookup1(5); Alternatively, you can use
the method get(double
x) of the table
function. For the example, considered above, the function call should be: lookup1.get(5); Both functions are
identical. They return the table function value corresponding to the given
argument, subject to the currently set interpolation type and out of range
handling. In case the function only supports discrete values (that were provided
as the argument set), and no interpolation is allowed, a call of such a function with
an argument not matching any argument entry would result in exception thrown. Arrays
Some problems require
multi-dimensional data. Alike some other traditional system dynamics tools,
AnyLogic supports arrays. Array
is a storage of numbers that may have any number of dimensions. Each dimension
has finite number of indexes - subscripts. Arrays are used when it is
necessary to store a large set of coefficients and access them or when there are
multiple model layers. The latter case is useful when you have defined a model
for some subsystem and there are other subsystems, which have the same
structure, as the first one, but other numerical parameters. One can
implement such multi-dimensional models making copies of the default diagram and
changing the parameters. Such approach has one great disadvantage: if you want
to change the model, you need do it so much times, as many layers you have; the
diagram grows and becomes incomprehensive. Array allows you to create a single
diagram for all the layers. Therefore, model remains compact, and changes
you make will affect the whole model, but not a single layer. For example, you create
a model of a nation’s health, describing some social or health processes in
respect to different groups of population. You may need to separate people by
three characteristics: gender, age group, and social group. This example fit
well in the array concept. Instead of dealing with multple model describing
different groups of people, you can just define an array with such
enumerations: Gender(male,
female), Age(child, teenager, adult, aged), and SocialGroup(wealthy,
middleclass, deprived).
Dimensions
Dimensions
are used for defining dimensions for array variables. There are three types of
dimensions in AnyLogic: enumerations, ranges and sub-dimensions. Enumerations
An
enumeration is a list of named items allowing you to refer to
the array elements. For example, if you are working with a population
model, you define age characteristics as Age
emumeration with elements: Child,
Teenager, Adult, Aged. Ranges
Ranges
are interval definitions that can be used to specify dimensions for array
variables. When you define an array using enumerations, you can refer to the
elements of the array using self-descriptive names of enumeration elements.
When defining arrays using numerical ranges, you access array elements by index
numbers. Sub-dimensions
Sub-dimensions
allow defining sub-ranges of dimensions. It is very useful when you have
some particular sub-dimension referred in multiple places of your model,
for example in sub-arrays definitions. Rather than dealing with
sub-dimension definitions, you may simply create such sub-dimension
once and then refer to it by its name whenether you need this sub-dimension
definition. You can define sub-dimension
both for enumerations and ranges as well. To define a sub-dimension,
you should specify the lower and upper elements of a range that contain the
elements of a sub-dimension. ·
In the case of a
sub-dimension of an enumeration, you specify the lower and upper elements of an
existing enumeration. The subrange will then contain the elements of the
enumeration between these borders. ·
In the case of a
sub-dimension of a range, you specify upper and lower integer indexes for each
interval of a sub-range. For example, if you have a range Age
defined as 1..100, you may define a sub-dimension Young
Age 1..21. This
sub-dimension will contain dimension elements with indexes between 1 and 21
only. Defining a Dimension
1.
In the Model
view, right-click the model you are currently working with, and choose New|Dimension…
from the popup menu. 2.
The New
Dimension dialog box opens. Specify the name of the new dimension in the Name
edit box, optionally specify the description of the dimension in the Description
edit box and click Finish to complete the process.
1.
Select the
dimension in the graphical editor or in the Project view. 2.
Go to the General
page of the Properties view. 3.
Choose Enumeration
option from the Define as group of buttons. 4.
Each item is
defined in a separate row of the table. To define an item, go to the last row of
the Specify items table and type the item name in the Name cell
and the item integer value in the Value cell. 5.
To remove an
item, select it in the table and click the
1.
Select the
dimension in the graphical editor or in the Project view. 2.
Go to the General
page of the Properties view. 3.
Choose Range
option from the Define as group of buttons. 4.
Specify the
elements of the range by entering the expression in the Range edit
box, i.e
1.
Select the
dimension in the graphical editor or in the Project view. 2.
Go to the General
page of the Properties view. 3.
Choose Sub-dimension
of option from the Define as group of buttons. 4.
Choose the
original dimension from the drop-down-list to the right. 5.
Specify the
dimension elements you want to include in the sub-dimension. 6.
If the original
dimension is an enumeration, set check boxes in the Select elements table
to the left of the enumeration elements you want to include in your
sub-dimension. To remove an element, clear the corresponding check box. 7.
If the original
dimension is a range, type in the expression defining the resulting sub-range in
the edit box, i.e Defining an Array Variable
1.
Select the
variable in a graphical editor or in the Project view. 2.
To make the
selected variable a variable of type array, check the Array check
box on the General page of the Properties view. 3.
You can see that
the variable's shape in the graphical editor is now enclosed in square brackets.
In this way AnyLogic visualize array variables.
Array
variables in the graphical editor 4.
Click in the {...}
to the right of the check box. The Array page of the Properties
view will be shown. 5.
Define the
dimensions of your array variable. Add the dimensions you need from the Available
list to the Selection list. To add some dimension, select it in the Available
list and click the
6.
If needed, you
can remove some selected dimensions any time you like. To remove a dimension,
select it in the Selection list and click the
7.
The order of
dimensions is also important. You can reorder the dimensions by clicking
Initializing an Array Variable
When defined a variable of
type array, you need to set initial value for array elements. The simpliest
case is when you initialize all array elements with the same value.
1.
Select the
variable in a graphical editor or in the Project view. 2.
Go to the General
page of the Properties view. 3.
Enter initial value
or a formula calculating the initial value in the Initial value edit box.
Sometimes you need setting
some groups of elements of a hyper-array separately. AnyLogic enables defining formulas
initializing different layers of an array. To set an initial value for some
specific sub-array of an array, you should specify the list of subscripts
identifying element(s) of the array that should get the initial value and
specify the initial value itself. You should specify subscripts for all the
dimensions of an array. Let's
illustrate it by our example of a model studying smoking rate where
the average smoking rate of people in respect to gender, age, and social group
is defined as Smoking_Rate
array with the following enumerations as dimensions: Gender(male, female), Age(child, teenager, adult,
aged), SocialGroup(wealthy, middleclass, deprived). The examples of possible
subscript lists for this array are listed in the table below.
1.
Select the
variable in a graphical editor or in the Project view. 2.
Go to the General
page of the Properties view. 3.
Specify the list
of subscripts identifying element(s) of the array that should get the
initial value. By default, all array dimensions are selected. You should
modify this dimension list by specifying some particular elements for those
enumerations that are presented in the sub-array by only one
enumeration element. 4.
For such
dimensions, click on the dimension name in the {...} to the right of the Array
check box and choose the required enumeration element from the drop-down list. 5.
Enter the formula
calculating the initial value for the defined sub-array in the <array_name>=
edit box 6.
If you need to
define one more formula initializing another sub-array, click the Add formula
button and define new formula in the same way. 7.
To remove a
formula, click the
Array Functions
Sometimes you need
performing aggregation operations on elements of arrays. AnyLogic supports
a set of aggregation functions over arrays listed in the table below:
You can perform calculations
on a subset of an array. In this case you should enumerate the dimensions
forming the sub-array as function arguments. For example, if you have an array people
with dimensions (
Region, Gender, AgeGroup ),
calling: people.sum(
NORTH, INDEX_CAN_VARY, ADULT ) will calculate the number of
adults of both genders in the north region. Please refer to AnyLogic API
Reference to find more information about functions syntax and parameters: com.xj.anylogic.engine.HyperArray Delay Function
Delay function is frequently
needed in system dynamics for modeling postponed effects, i.e. situations
when it takes some time for decision-making, or for some processes to occur
before the action is taken. For example, in the classic
Bass Diffusion model, delay function is used to model discard rate. In this
model people move back from the adopter population to the pool of potential
adopters when the product they have purchased is discarded or consumed. So, the
discard flow is nothing else but the adoption flow delayed on the average life
time of the product. delay
function can be called in formulas of flow variables. Please do not be
confused that this function does not appear in the code completion wizard.Do not
pay attention to it and just type the expression you need. delay
function has two notations: ·
delay(<flow>, <delay time>, <initial
value>) The
function delays the flow specified as the function's first argument on the
specified delay time. flow can
be a flow variable, or a numeric expression of any complexity. delay time can
be either a constant or a numeric expression (e.g. a function call, or a numeric
parameter). Thus, the delay value can change during the simulation. The delay
function with zero or negative delay time returns the original flow. Until
delay time is reached, the function will return the initial value.
·
delay(<flow>, <delay time>)
The
simplified notation of the function. Is used when the initial value
is zero. So, in the example described
above the formula for the DiscardRate will be: delay(AdoptionRate, ProductLifeTime) The plot on the figure below
illustrates how the delay function works:
|