forio Toggle navigation

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:

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 Powersim Time units, rounded to the nearest multiple of Powersim Timesteps. It has one optional argument, a floating point number for steps (Powersim Time units) to advance. The default value is 1. The return value is the current Timestep.
  • 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 Powersim Stop 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 first step 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:

BudgetStep
800
1001
1202
1303

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, ApplesSales, OrangesStep
801800
1002001
1202202
1302303
1402404

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
  • For additional time details, read from the Start Time, Final Time, or Time 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 units) to advance. If not provided, 1 is assumed.
    • Result: Advances the run the specified number of Powersim Time units, rounded to the nearest multiple of Powersim Timestep. Returns the current Timestep.
    • More info
  • 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 the Time 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 Powersim Stop time).

        or

      • A string following the ISO-8601 standard, e.g. YYYY-MM-DD or YYYY-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, alias StopTime: The end of your simulation.
  • Time: An array of the simulation times that you have stepped through so far.
  • Time Step, alias TimeStep: The value of the Powersim TimeStep variable.
  • Time Unit, alias TimeUnit: The time unit from Powersim, e.g. "months".
  • Start Time, alias StartTime: 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
}