An optimal sizing model and post-optimal budget analysis framework for standalone PV-Battery-Hydrogen energy system
Optimal sizing and post-optimal budget-resilience analysis of a stand-alone PV–Battery–Hydrogen Energy Storage System (BHESS) across three European climate regions (Vaasa, Vienna, Naples), reproducing the methodology and results of:
T. Tran and J. Songok, "Budget-Constrained Sizing Optimization for Battery-Hydrogen Hybrid Systems Across European Climate Regions," Proceedings of SEEP2026, Tor Vergata University, Rome, Italy, 20–23 July 2026. Paper ID: SEEP-1063.
This repository contains the modeling framework only. The conference paper and presentation slides are not included here; see the Citation section below for how to reference the published work once available.
A stand-alone, fully islanded system (PV array, battery, PEM electrolyser, PEM fuel cell, H₂ tank) is sized to meet an hourly electrical and hydrogen demand over a full year (8,760 h), minimizing lifecycle Net Present Cost (NPC) subject to reliability constraints (LPSP, LOLE). After the unconstrained optimum is found, the available investment (CAPEX) is progressively reduced and the model is re-solved at each budget level to study:
- how PV / battery / electrolyser / fuel cell / tank capacities are reallocated as budget shrinks,
- how NPC, LCOE, and LCOH evolve,
- how far each location (Vaasa, Vienna, Naples) can tolerate budget reduction before becoming infeasible.
The optimization is formulated as an LP in Pyomo and solved with Gurobi.
.
├── Model_BHESS.py # Standalone script (HPC/Puhti-ready)
├── configurable_pv_battery_hydrogen_budget_resilience.ipynb # Notebook version (interactive)
├── data/
│ └── Input_sample.csv # Hourly irradiance/temperature/load data (8,760 rows)
├── requirements.txt
└── README.md
The script expects
Input_sample.csvnext to itself; the notebook expects it underdata/Input_sample.csvrelative to the notebook's working directory. Adjust the path variables at the top of either file if your layout differs.
Input_sample.csv contains 8,760 hourly rows with the following columns:
| Column | Description | Unit |
|---|---|---|
Month, Season, Hour |
Calendar/time index | — |
Irradiance_<Vaasa/Vienna/Naples> |
Global horizontal irradiance (PVGIS, 2023) | W/m² |
Temp_<Vaasa/Vienna/Naples> |
Ambient temperature (PVGIS, 2023) | °C |
Case_1_Residential_Elec [kWh] / ..._H2toFuel [kg] |
Case 1 (residential) demand | kWh, kg/h |
Case_2_Hospital_Elec [kWh] / ..._H2toFuel [kg] |
Case 2 (hospital) demand | kWh, kg/h |
Case_3_Manufacture_Elec [kWh] / ..._H2toFuel [kg] |
Case 3 (industrial, used in the paper) demand | kWh, kg/h |
The electrical profile for Case 3 is adapted from the "Industrial-1-shift Fabricated Metals" facility dataset; the hydrogen profile is a constant 1.5 kg/h, representative of a medium-sized fleet of H₂-powered forklifts.
Intended for batch / HPC use (e.g. Puhti/CSC with SLURM). Edit the scenario selectors at the top of the file, then run:
pip install -r requirements.txt
python Model_BHESS.pySet location to one of 'Vaasa', 'Vienna', 'Naples' and CASE to
one of 'C1', 'C2', 'C3'. The script:
- Solves the unconstrained baseline optimal sizing problem.
- Prints NPC, CAPEX, LCOE, LCOH, LPSP, LOLE, and component sizes.
- Runs a post-optimal budget sweep (CAPEX capped at 80%–100% of the baseline in 1% steps) and re-solves at each level.
- Writes
LCOH_Result_<location>_<CASE>.xlsxwith aResultssheet (sizing + hourly dispatch) and aBudget_Sweepsheet.
Same model and workflow as the script, reorganized into cells for
interactive exploration. Open with Jupyter, adjust location / CASE in
the scenario cell, and run all cells top to bottom. Outputs are written to
an outputs/ folder created next to the notebook.
Both entry points call SolverFactory('gurobi') and require a working
Gurobi installation and license (free academic licenses are available).
See:
A full 8,760-hour LP solve can take from a few minutes to several hours
depending on hardware; the script sets an 8-hour wall-clock limit
(TimeLimit = 28800) as a safety net for HPC job limits.
Both the script and the notebook produce an Excel workbook
LCOH_Result_<location>_<CASE>.xlsx with:
Resultssheet — baseline component sizing (PV, battery, electrolyser, fuel cell, tank), NPC, CAPEX, LPSP, LOLE, LCOE, LCOH, and the full 8,760-hour hourly dispatch table (PV generation/dispatch, battery SOC, H₂ production/consumption, tank SOH, curtailment).Budget_Sweepsheet — one row per budget factor (80%–100% of baseline CAPEX), with the re-optimized sizing, NPC, LCOE, LCOH, LPSP, and LOLE at each level.
If you use this code or data, please cite the SEEP2026 paper:
@inproceedings{tran2026bhess,
title = {Budget-Constrained Sizing Optimization for Battery-Hydrogen
Hybrid Systems Across European Climate Regions},
author = {Tran, Tram and Songok, Joel},
booktitle = {Proceedings of SEEP2026},
address = {Tor Vergata University, Rome, Italy},
year = {2026},
note = {Paper ID: SEEP-1063}
}This research was funded by CETP, the Clean Energy Transition Partnership, under the 2023 CETP joint call for research proposals (GA N° Cetp-FP-2023-00567), co-funded by the European Union.