Model Creation in Powersim
When you create a model in Powersim, you can use it with the Epicenter platform by:
Creating and uploading your model file to the Model folder of your project. (Note that Epicenter considers your "model file" to be your Powersim project file. This is true regardless of how many components, simulations, or submodels are present in your Powersim project file.)
Optionally, creating a model context file and uploading it to the Model folder of your project.
Then, when you create a user interface for your Powersim model on Epicenter, each user's interaction includes:
- Logging in and creating a run
- Calling the
step
orstepTo
method to advance the Powersim model - Retrieving and updating variables, based on user decisions and the appropriate time or step.
- Index of available Powersim operations
- Index of available Powersim variables
Creating and Uploading your Model File
To use a Powersim project file, save it in .sip format.
Use the Epicenter user interface to upload your model file (.sip) to the Model folder within your project.
Note: The Powersim .sip file includes the state of your model. However, once you upload a .sip file to Epicenter, all Epicenter runs start from the initial state of the Powersim model, regardless of the state in which your model was saved.
Creating a Run
A "run" is a collection of end user interactions with the project and its model. Every time an end user wants to interact with a project, you as the project author need to create a new run.
If you are using the Interface Builder to create your interface, the name of your model file is detected automatically, and a run is created automatically when an end user visits this project page.
If you are using one of the Epicenter APIs, you'll need to create the run yourself. Powersim is only available with the Epicenter v2 APIs and later (see more on the version history).
For example, using the Run API Service (JavaScript), you might use:
var rs = new F.service.Run({
account: 'acme-simulations',
project: 'supply-chain-game',
token: 'eyJhbGciOiJSUzI1NiJ9'
});
rs.create('supply-chain-model.sip');
Or if you're using the Run API (RESTful), you might use:
curl -X POST \
'https://api.forio.com/v2/run/acme-simulations/supply-chain-game' \
--header 'Content-Type:application/json' \
--header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9' \
--data '{"model": "supply-chain-model.sip"}'
Advancing the Model
The Interface Builder and Epicenter APIs both allow you to manipulate a run using operations exposed by the model. For Powersim models, there are three available operations: step
, stepTo
, and clear
.
To advance the Powersim model for a particular run, use the step
or stepTo
operation.
- The
step
operation advances the run a specified number of PowersimTime unit
s, rounded to the nearest multiple of PowersimTimestep
s. It has one optional argument, a floating point number for steps (PowersimTime unit
s) to advance. The default value is1
. The return value is the currentTimestep
. - The
stepTo
operation advances the run up to a particular Powersim time, or the end of the model. It has one argument, which can be either:- An integer: step the model to that time but not past.
- The string
"end"
: step the run to the end (the PowersimStop time
). - A string: for calendar-dependent sims, the IS0-8601 representation of the date (e.g.
"YYYY-MM-DD"
); step the model to that date but not past.
If you are using the Interface Builder to create your project's interface, you can select Step
under Add Operations for the Properties of a button. Optionally, you can select from the Parameters drop-down to choose how far to step (1 step, 10 steps, or to the end of the model). There is not an explicit stepTo
available from the Interface Builder.
If you are using one of the Epicenter APIs, for example, you could advance the model by three steps using the Epicenter.js Run API Service:
rs.load('runID').then(function()
{ rs.do('step', [3]); });
Or if you're using the Run API (RESTful), you might use:
curl -X POST \
'https://api.forio.com/v2/run/acme-simulations/supply-chain-game/runID/operations/step' \
--header 'Content-Type:application/json' \
--header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9' \
--data '{"arguments": [3]}'
Retrieving and Updating Variables
You can retrieve and update Powersim variables for each Powersim project using the variable name.
In the Interface Builder, enter the variable name under the Variable property of decisions, tables, or other components. In Flow.js, add the variable to an element on the page, for example using data-f-bind
.
Unlike some other modeling languages supported by Epicenter, Powersim models are necessarily time-based: they deal in discrete steps, and the model advances over time. For this reason, each variable is actually an array of values over steps.
Important Notes on Variables
Steps are 0-based. Including the step is optional when you reference a variable. Leaving it off returns the entire array. Only variables in the current step can be updated. The value from any step (including the current step) can be retrieved.
To retrieve the value of a variable in the current time step, you can either include the current time step as an array index, or append
.POINT_IN_TIME
to the name of the variable when you look it up.To retrieve the value of an arrayed variable with the array collapsed for each step, append
.COLLAPSED_ARRAY
to the name of the variable when you look it up.Variables that are marked as
Start-up
variables in Powersim can only be updated before the firststep
call to advance the model. Other variables may be upated at any time. (If you're not sure about a particular variable, you can Introspect the run and check the access field for that variable:BEFORE
means you can only update the variable before the model is advanced;ALWAYS
means you can update the variable any time after the run is created.)Variable names are not case sensitive in Powersim, but they are once you use them in Epicenter. For example, you should make sure that the variable names in your project's user interface match their case with the variable names in your model context file.
Each variable name takes the form:
[[component:]simulation:]variable[.subvariable[.subvariable[...]]]
for example
Component 1:Simulation 1:Rate_1
where there can be arbitrarily many subvariables. If no component is given, the default is assumed. If no component and no simulation are given, the defaults are assumed. The "default" is whichever interface window had focus when your .sip file was last saved in Powersim.
Variables that you want to save in the Epicenter backend database need to be noted in the model context file.
Scalars
To update or reference a scalar variable, use the variable name. Optionally, include the step in square brackets, [s]
. Only variables in the current step can be updated. The value from any step (including the current step) can be retrieved.
Unlike some other modeling languages supported by Epicenter, Powersim models are necessarily time-based: they deal in discrete steps, and the model advances over time. For this reason, each variable is actually an array of values over steps.
For example, suppose you have the variable Budget
, which changes over time:
Budget | Step |
80 | 0 |
100 | 1 |
120 | 2 |
130 | 3 |
If you are using Flow.js, by default the value at the current step is selected. You can also specify a particular step. This looks like:
<!-- update Budget for current step -->
<input data-f-bind="Budget"></input>
<!-- Budget for step 2: returns "120". can reference, but not update -->
<span data-f-bind="Budget[2]"></span>
You can list values of an array (that is, your variable over all steps) using the data-f-foreach
attribute.
And if you are using the Run API, this looks like:
<!-- update Budget for current step -->
curl -X PATCH \
'https://api.forio.com/v2/run/acme-simulations/sample-powersim-model/000001576cef3f70efd8cdea64036fa396ec/variables' \
--header 'Content-Type:application/json' \
--header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9' \
--data '{"Budget": 95}'
<!-- Budget for step 2: returns "120". can reference, but not update -->
curl -G \
'https://api.forio.com/v2/run/acme-simulations/sample-powersim-model/000001576cef3f70efd8cdea64036fa396ec/variables/Budget[2]' \
--header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9'
<!-- Budget for current step, using the value of the step (3): returns 130 -->
curl -G \
'https://api.forio.com/v2/run/acme-simulations/sample-powersim-model/000001576cef3f70efd8cdea64036fa396ec/variables/Budget[3]' \
--header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9'
<!-- Budget for current step, using the POINT_IN_TIME notation: returns 130 -->
curl -G \
'https://api.forio.com/v2/run/acme-simulations/sample-powersim-model/000001576cef3f70efd8cdea64036fa396ec/variables/Budget.POINT_IN_TIME' \
--header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9'
Using the Run API, you can also ask for the variable over all steps. For example:
curl -G \
'https://api.forio.com/v2/run/acme-simulations/sample-powersim-model/000001576cef3f70efd8cdea64036fa396ec/variables/Budget' \
--header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9'
returns:
[
80,
100,
120,
130
]
Arrays
To update or reference an element of an array, use square brackets and strings to describe the index of the array: [indexName]
. Optionally, include the step as the second subscript: [indexName,s]
. Only variables in the current step can be updated. The value from any step (including the current step) can be retrieved.
For example, suppose in Powersim you have:
Sales, Apples | Sales, Oranges | Step |
80 | 180 | 0 |
100 | 200 | 1 |
120 | 220 | 2 |
130 | 230 | 3 |
140 | 240 | 4 |
If you are using Flow.js, this looks like:
<!-- get sales of apples in step 3: returns 130 -->
<span data-f-bind="Sales[apples,3]"></span>
<!-- set sales of apples and oranges sold in current step
(step 4), requires two different inputs -->
<input data-f-bind="Sales[apples]"></input>
<input data-f-bind="Sales[oranges]"></input>
You can list values of an array (that is, your variable over all steps) using the data-f-foreach
attribute.
And if you are using the Run API, this looks like:
<!-- get sales of apples in step 3: returns 130 -->
curl -G \
'https://api.forio.com/v2/run/acme-simulations/sample-powersim-model/000001576cef3f70efd8cdea64036fa396ec/variables/Sales[apples,3]' \
--header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9'
<!-- set sales of apples and oranges sold in current step
(step 4), requires two different updates -->
curl -X PATCH \
'https://api.forio.com/v2/run/acme-simulations/sample-powersim-model/000001576cef3f70efd8cdea64036fa396ec/variables' \
--header 'Content-Type:application/json' \
--header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9' \
--data '{"Sales[apples]": 150, "Sales[oranges]": 250}'
Using the Run API, you can also ask for the variable over all steps. For example:
curl -G \
'https://api.forio.com/v2/run/acme-simulations/sample-powersim-model/000001576cef3f70efd8cdea64036fa396ec/variables/Sales' \
--header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9'
returns:
{
"apples": [
80,
100,
120,
130,
140
],
"oranges": [
180,
200,
220,
230,
240
]
}
This format is easier to parse if you are looking for the values from a specific dimension of your array.
To retrieve the values in the current time step only, append .POINT_IN_TIME
to the name of the variable when you look it up:
curl -G \
'https://api.forio.com/v2/run/acme-simulations/sample-powersim-model/000001576cef3f70efd8cdea64036fa396ec/variables/Sales.POINT_IN_TIME' \
--header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9'
returns:
{
"apples": 140,
"oranges": 240
}
To retrieve the values of your arrayed variable with the array collapsed for each step, append .COLLAPSED_ARRAY
to the name of the variable when you look it up:
curl -G \
'https://api.forio.com/v2/run/acme-simulations/sample-powersim-model/000001576cef3f70efd8cdea64036fa396ec/variables/Sales.COLLAPSED_ARRAY' \
--header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9'
returns:
[
[
80, // "apples" dimension for the first step
180 // "oranges" dimension for the first step
],
[
100, // "apples" dimension for the second step
200 // "oranges" dimension for the second step
],
[
120, // etc.
220
],
[
130,
230
],
[
140,
240
]
]
This format is easier to parse if you are looking for all values from a specific step of your model, and can be helpful for example if you are graphing the values over steps.
Note that you cannot update variables which do not exist (including arrayed variables, for example Sales[pineapple]
if your only products are apples
and oranges
). In other words, you cannot create new variables this way; your variables must already be defined in your model.
Determining the Current Time or Step
In some situations, you may know already the time or step for which you want to view or update variables. If you are not sure, can ask the model:
For the current step, read from the
Step
variable. This variable is automatically included for you and always holds the current Powersim step. (It is a scalar value, not an array.)For example, using the Run API Service (JavaScript), you might use:
rs.load('runID', {include: 'Step'});
Or if you're using the Run API (RESTful), you might use:
curl -G \ 'https://api.forio.com/v2/run/acme-simulations/supply-chain-game/runID/variables/Step' \ --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9' \
For information on what has been simulated so far, read from the
Time
variable. This variable is automatically included for you and always holds an array of the time values that have been stepped to so far.For example, using the Run API Service (JavaScript), you might use:
rs.load('runID', {include: 'Time'});
Or if you're using the Run API (RESTful), you might use:
curl -G \ 'https://api.forio.com/v2/run/acme-simulations/supply-chain-game/runID/variables/Time' \ --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9' \
Note that the elements of the Time array may be strings or floating point numbers, depending on your Powersim simulation.
- If the simulation is calendar-independent, all times and time information are returned as floats (e.g.
1
,4
). - If the simulation is calendar-dependent, all times and time information are returned as strings following the ISO-8601 standard, that is, in one of the following formats:
YYYY-MM-DD
YYYY-MM-DDTHH:MM:SS
YYYY-MM-DDTHH:MM:SSZ
YYYY-MM-DDTHH:MM:SS.SSS
YYYY-MM-DDTHH:MM:SS.SSSZ
- If the simulation is calendar-independent, all times and time information are returned as floats (e.g.
For additional time details, read from the
Start Time
,Final Time
, orTime Step
variables.
Index of Available Powersim Operations
clear
- Arguments: none
- Result: Sets the current run back to its initial step (e.g.
Time
of 0).
reset
- Arguments: none
- Result: Returns a new run, that is, a new instantiation of your model for an end user to play with. (Remember that a run is a collection of interactions with a model.) For example, this is useful if your end user needs to "start over" to create a new scenario within your project.
- Note that this can ONLY be called from your project's user interface if you are using the Interface Builder or Flow.js. (Under the hood, this is not an operation as defined for the RESTful Run API. If you are building your project's user interface with the Epicenter RESTful APIs, you should just create a new run instead of calling
clear
.)
step
- Arguments:
- Optional, floating point number for steps (Powersim
Time unit
s) to advance. If not provided,1
is assumed.
- Optional, floating point number for steps (Powersim
- Result: Advances the run the specified number of Powersim
Time unit
s, rounded to the nearest multiple of PowersimTimestep
. Returns the currentTimestep
. - More info
- Arguments:
stepTo
Arguments:
Integer, the Powersim
Time unit
to step to (but not past). Note that this is independent of the initial time. For example, if theTime unit
is months,stepTo(6)
always goes to month 6 — regardless of whether the initial time is 0 or 2.or
The string
"end"
, step the run to the end (the PowersimStop time
).or
- A string following the ISO-8601 standard, e.g.
YYYY-MM-DD
orYYYY-MM-DDTHH:MM:SS.SSSZ
. This option is only available if the Powersim simulation is calendar-dependent.
Result: Advances the run up a particular Powersim
Time unit
, or the end of the model.- More info
Index of Available Powersim Variables
In addition to any variables in your Powersim model, the following variables are available for reference when you are running a Powersim model on Epicenter.
Final Time
, aliasStopTime
: The end of your simulation.Time
: An array of the simulation times that you have stepped through so far.Time Step
, aliasTimeStep
: The value of the PowersimTimeStep
variable.Time Unit
, aliasTimeUnit
: The time unit from Powersim, e.g. "months".Start Time
, aliasStartTime
: The beginning of your simulation.Step
: The current step. Steps are 0-based.
For example, in a model in which we have stepped twice and then asked for all of these variables, using the Run API (RESTful):
curl -G \
'https://api.forio.com/v2/run/acme-simulations/supply-chain-game/000001577c0c5359720faa8b0c4b32e182d9/variables?include=Time,Start Time,Final Time,Time Step' \
--header 'Authorization: Bearer eyJhbGciOiJSUzI1NiJ9' \
which returns:
{
"Start Time": 2015,
"Final Time": 2020,
"Time": [
2015,
2016,
2017
],
"Time Step": 1,
"Step": 2
}