Skip to content

Multi-Year Tutorial

This tutorial runs a multi-year (dynamic) planning study with an explicit horizon, phased investment steps, and capacity expansion. It builds on the concepts from the Typical-Year Tutorial.

1. Create the project

import microgridspy as mgp

mgp.create_project(
    "tutorial_multiyear",
    formulation="multi_year",
    system_type="off_grid",
    resources=["solar", "wind"],
    horizon_years=20,  # planning horizon H = 20 years
    capacity_expansion=True,  # allow staged expansion
    investment_steps_years=[5, 5, 5, 5],  # four 5-year investment steps
    start_year_label="2026",
    scenarios=2,  # two stochastic scenarios
)

Compared with the typical-year case, the dynamic formulation adds a year axis and investment steps (\(\tau\)), each defining an investment cohort with its own installation time, lifetime, and financial parameters.

2. Populate the multi-year inputs

The time-series files now carry an extra year dimension:

  • load_demand.csv — scenario × year, 8760 hourly rows each. This is where you encode demand growth across the horizon.
  • resource_availability.csv — scenario × year × resource.
  • renewables.yaml, battery.yaml, generator.yaml — techno-economic inputs indexed by investment step where relevant (CAPEX trajectories, WACC, lifetimes).

See the multi-year tab of the Data Reference for the exact axes, units, and mandatory conditions.

3. Validate and solve

mgp.validate_project("tutorial_multiyear")
model = mgp.solve("tutorial_multiyear", solver="highs")
results = model.results()  # a MultiYearResults object

4. Inspect the horizon results

print(results.kpis)  # present-value cost, renewable share, ...
# per-year installed capacity, dispatch, and cost breakdowns resolved over the horizon

What the model solved

The dynamic formulation minimized the expected discounted system cost over the horizon (the multi-year objective): each investment cohort's capital cost is converted to a WACC-based annuity, system-level cash flows are discounted with the social discount rate, and installed capacity is non-decreasing across steps. The objective follows an annuity-based convention — only annualized payments within the horizon are counted (a salvage value may be reported in post-processing but does not enter the optimization). Sizing (here-and-now) is shared across scenarios while dispatch (recourse) is scenario-specific.

Example projects

The Kalobeyei_* case studies exercise the multi-year formulation with real-world data and are a useful reference for how a complete multi-year input set is structured. They are published as a separate dataset — doi:10.5281/zenodo.22958510 — and walked through in the Examples section. For a smaller set that needs no download, the package bundles demo_multi_year (see mgp.list_examples()).