Simulations

MIKE+Py enables you to configure and execute MIKE+ simulations programmatically from Python scripts, which is particularly useful for automating workflows like scenario analysis or calibration.

import mikeplus as mp

db = mp.open('data/Dyrup_uncalibrated_copy.sqlite')

Running Simulations

By Active Simulation

You can run the simulation setup that is currently marked as “active” in the MIKE+ project.

First, you can identify the active simulation setup’s MUID:

active_sim_muid = db.active_simulation
active_sim_muid
'rainfall'

To run the active simulation, call db.run() without specifying a simulation_muid. It will return a list of Path objects pointing to the generated result files.

result_files_active = db.run()
for rf in result_files_active:
    print(rf.name)
rainfallBaseDefault_Network_HD.res1d
rainfallBaseDefault_Surface_runoff.res1d

By Simulation MUID

More commonly, you’ll want to run a specific simulation setup, regardless of which one is currently active. You can do this by providing the simulation_muid argument to db.run().

You can find available simulation setup MUIDs by inspecting a project table, like msm_Project:

db.tables.msm_Project.select(["ScenarioName", "Description"]).to_dataframe()
ScenarioName Description
rainfall Base None

To run the simulation setup named ‘rainfall’:

result_files_rainfall = db.run(simulation_muid="rainfall")
for rf in result_files_rainfall:
    print(rf.name)
rainfallBaseDefault_Network_HD.res1d
rainfallBaseDefault_Surface_runoff.res1d

Practical Example

A common use case is to run the same simulation configuration but for different scenarios. In this example, we’ll run the scenarios created in the previous section.

Recall that two scenarios were created in addition to the base scenario:

Code for generating scenarios (based on previous section)
selection_name = "Flow_Meter_B_Catchments"

# Catchment MUIDs draining to Flow Meter B
catchment_muids_to_modify = (
    db.tables.m_Selection
        .select(['ItemMUID'])
        .where(f"{db.tables.m_Selection.columns.SelectionID} = {mp.to_sql(selection_name)}")
        .where(f"{db.tables.m_Selection.columns.TableName} = {mp.to_sql(db.tables.msm_Catchment.name)}")
        .to_dataframe()['ItemMUID']
        .tolist()
)


alternative_2000 = db.alternative_groups["Catchments and hydrology data"].create("Time of Concentration = 2000s")
scenario_2000 = db.scenarios.create("Time of Concentration = 2000s")
scenario_2000.set_alternative(alternative_2000)

alternative_3000 = db.alternative_groups["Catchments and hydrology data"].create("Time of Concentration = 3000s")
scenario_3000 = db.scenarios.create("Time of Concentration = 3000s")
scenario_3000.set_alternative(alternative_3000)

scenario_2000.activate()
(
db.tables.msm_Catchment
    .update({
        db.tables.msm_Catchment.columns.ModelAConcTime : 2000
    })
    .by_muid(catchment_muids_to_modify)
    .execute()
)

scenario_3000.activate()
(
db.tables.msm_Catchment
    .update({
        db.tables.msm_Catchment.columns.ModelAConcTime : 3000
    })
    .by_muid(catchment_muids_to_modify)
    .execute()
)

list(db.scenarios)
[Scenario <Base>,
 Scenario <Time of Concentration = 2000s>,
 Scenario <Time of Concentration = 3000s>]

Let’s inspect our model simulation setups.

df_sim_setups = db.tables.msm_Project.select(["ScenarioName", "Description"]).to_dataframe()
df_sim_setups
ScenarioName Description
rainfall Base None

We will use the simulation setup with MUID ‘rainfall’, iteratively running all scenarios by modifying the ScenarioName.

simulation_setup_muid = "rainfall"
scenarios_to_run = [
    db.scenarios.base,
    db.scenarios.by_name("Time of Concentration = 2000s"),
    db.scenarios.by_name("Time of Concentration = 3000s"),
]
scenario_results = {}

for scenario in scenarios_to_run:

    # Update the simulation setup to use the current scenario
    (
        db.tables.msm_Project
            .update({
                db.tables.msm_Project.columns.ScenarioName: scenario.name
            })
            .by_muid(simulation_setup_muid)
            .execute()
    )
    
    # Run simulation
    result_paths = db.run(simulation_muid=simulation_setup_muid)

    # Store result paths
    scenario_results[scenario.name] = [p.name for p in result_paths]

# Print all files generated
for scenario_name, files in scenario_results.items():
    print(f"Scenario '{scenario_name}'")
    for file in files:
        print(f"\t- {file}")
Scenario 'Base'
    - rainfallBaseDefault_Network_HD.res1d
    - rainfallBaseDefault_Surface_runoff.res1d
Scenario 'Time of Concentration = 2000s'
    - rainfallTime of Concentration = 2000sDefault_Network_HD.res1d
    - rainfallTime of Concentration = 2000sDefault_Surface_runoff.res1d
Scenario 'Time of Concentration = 3000s'
    - rainfallTime of Concentration = 3000sDefault_Network_HD.res1d
    - rainfallTime of Concentration = 3000sDefault_Surface_runoff.res1d