Skip to main content

Simulation

A Simulation Configuration is automatically created alongside a Plan.

Update Simulation Configuration Arguments

Before a plan can be simulated, the simulation arguments must be set.

Note

If your Mission Model defines default values for an argument, you do not need to set those arguments in order to use the default value.

mutation updateSimulationArguments($plan_id: Int!, $arguments: jsonb!) {
update_simulation(where: { plan_id: { _eq: $plan_id } }, _set: { arguments: $arguments }) {
affected_rows
}
}

Query for Mission Model Configuration Effective Arguments

The getModelEffectiveArguments returns the same structure as getActivityEffectiveArguments; a set of effective arguments given a set of required (and overridden) arguments.

query getModelEffectiveArgs($modelId: ID!, $arguments: ModelArguments!) {
getModelEffectiveArguments(missionModelId: $modelId, modelArguments: $arguments) {
arguments
errors
success
}
}

Update Simulation Bounds

By default, a simulation will go from plan start to plan end. If you would like to run simulation on only a subset of the plan, you must first update the simulation bounds in the Simulation Configuration. The following mutation will update the bounds. Notice that simulation bounds are in the timestamptz format YYYY-MM-DD hh:mm:ss+0 or YYYY-MM-DDThh:mm:ssZ.

mutation updateSimulationBounds(
$plan_id: Int!
$simulation_start_time: timestamptz!
$simulation_end_time: timestamptz!
) {
update_simulation(
where: { plan_id: { _eq: $plan_id } }
_set: { simulation_start_time: $simulation_start_time, simulation_end_time: $simulation_end_time }
) {
affected_rows
}
}

Create a Simulation Configuration Preset

Rather than defining the simulation arguments in the Simulation Configuration, they can be assigned in a Simulation Configuration Preset, also known as a Simulation Preset. This mutation will create a Simulation Configuration Preset and returns its ID:

mutation CreateSimulationPreset($simulationPresetInsertInput: simulation_template_insert_input!) {
insert_simulation_template_one(object: $simulationPresetInsertInput) {
id
}
}

Here is an example query variable that creates a Simulation Configuration Preset that sets the initial fruit count to 50.

{
"simulationPresetInsertInput": {
"description": "Only 50 Starting Fruit",
"model_id": 1,
"arguments": {
"initialFruitCount": 50
}
}
}

Update a Simulation Configuration Preset

mutation UpdateSimulationPreset($simulationPresetId: Int!, $updatedPreset: simulation_template_set_input!) {
update_simulation_template_by_pk(pk_columns: { id: $simulationPresetId }, _set: $updatedPreset) {
id
}
}

Assign a Simulation Configuration Preset to a Simulation Configuration

If you know the ID of a Simulation Configuration Preset, you can use the following mutation to assign it to a Plan's Simulation Configuration:

mutation AssignSimulationConfigurationPreset($plan_id: Int!, $simulation_template_id: Int!) {
update_simulation(where: { plan_id: { _eq: $plan_id } }, _set: { simulation_template_id: $simulation_template_id }) {
simulation_template_id
}
}

Run Simulation

query Simulate($planId: Int!) {
simulate(planId: $planId) {
reason
simulationDatasetId
status
}
}

Forcibly Rerun Simulation

Occasionally, there may be a need to resimulate a plan without changing any arguments, for example if there was a network failure during a prior run. In these cases, simulation can be forcibly rerun by providing the force argument to the simulate endpoint.

query ForceResimulate($planId: Int!) {
simulate(planId: $planId, force: true) {
reason
simulationDatasetId
status
}
}

Query for Simulation Results

The output of a simulation is stored in a simulation_dataset. A simulation_dataset has both profiles (aka states or resources), and simulated activities. The following query fetches the latest simulation_dataset for a given plan:

query GetLatestSimulationDataset($planId: Int!) {
latest_dataset: simulation(where: { plan_id: { _eq: $planId } }) {
simulation_datasets(order_by: { id: desc }, limit: 1) {
id
status
reason
arguments
simulation_start_time
simulation_end_time
dataset {
id
profiles {
id
name
type
profile_segments {
profile_id
dynamics
start_offset
}
}
}
simulated_activities {
activity_directive {
id
metadata
}
activity_type_name
attributes
directive_id
duration
end_time
id
parent_id
start_offset
start_time
}
}
}
}

Query for Profile Segments

Note for performance it can sometimes be beneficial to request profile segments separately. The profile segments are the actual simulated resource data:

query GetProfileSegments($datasetId: Int!) {
profile_segment(where: { dataset_id: { _eq: $datasetId } }) {
profile_id
dynamics
start_offset
}
}

You can further filter this query to only fetch a subset of profiles:

query GetProfileSegments($dataset_id: Int!, $resources: [String!]!) {
profile(where: {_and: {name: {_in: $resources}, dataset_id: {_eq: $dataset_id}}}) {
name
profile_segments {
profile_id
dynamics
start_offset
}
}
}

Query for Simulated Activities (Spans)

For performance, it can sometimes be beneficial to request the simulated activity directives (otherwise known as "simulated activities" or "spans") separately.

query GetSpans($simulationDatasetId: Int!) {
simulated_activity(where: {simulation_dataset_id: {_eq: $simulationDatasetId}}) {
activity_type_name
attributes
duration
id
parent_id
simulation_dataset_id
start_offset
}
}

Query for Resource Types in a Mission Model

query GetResourceTypes($modelId: Int!) {
resource_type(where: {model_id: {_eq: $modelId}}) {
name
schema
}
}

Query for Simulation Resource Data at a Given Time

Once a simulation has been run, you can query for the profile segments at a certain duration into the results. This can be useful for seeding initial conditions when running a Temporal Subset Simulation.

query GetResources($dataset_id: Int!, $start_offset: interval!) {
getResourcesAtStartOffset(args: { _dataset_id: $dataset_id, _start_offset: $start_offset }) {
id
dataset_id
dynamics
is_gap
name
start_offset
type
}
}

Notice that start_offset is a Postgres interval of the format hh:mm:ss.