A comprehensive framework for analyzing energy storage systems using OSeMOSYS with time-series clustering and temporal disaggregation methods.
Warning
This library is under active development. For latest release and updates, please check the GitHub repository.
Overview#
Storage-in-OSeMOSYS implements four different temporal representation methods for energy system optimization, each addressing the challenge of modeling energy storage systems with varying levels of computational complexity and accuracy:
🔄 Model_Cluster: Time-series clustering approach for representative day selection
📊 Model_Kotzur: Kotzur temporal disaggregation method with daily mapping
⏰ Model_Welsch: Welsch temporal representation with fixed patterns
🔗 Model_Niet: Niet temporal method with direct chronological linking
Key Features#
🔄 Time-series clustering for representative day selection using K-means
📊 Multiple temporal methods comparing different storage modeling approaches
⚡ OSeMOSYS integration with OtoOle for seamless data processing
📈 Automated visualization and comparative results analysis
🛠️ Modular design with utilities for configuration management
🔧 GLPK solver integration for linear programming optimization
🐍 Python 3.13 support with modern pathlib usage
📋 Conda environment management with comprehensive Makefile
Research Context#
This framework addresses the critical challenge of modeling energy storage systems in large-scale energy planning. Storage systems fundamentally differ from conventional generation and demand technologies because they move energy across time, creating complex temporal dependencies that are computationally expensive to model accurately.
The Storage Modeling Challenge#
Energy storage modeling is complex because:
🔁 Time-shifting behavior: Storage moves energy across time periods rather than just producing or consuming
⏳ State continuity: The state of charge depends on all previous time periods
🔗 Temporal coupling: Decisions in one hour affect options in future hours
⚡ Multi-scale dynamics: From minute-level frequency regulation to seasonal energy shifting
Our Solution#
Storage-in-OSeMOSYS provides a systematic comparison of four established temporal representation methods, allowing researchers to:
Evaluate trade-offs between computational efficiency and model accuracy
Compare results across different temporal abstraction approaches
Select appropriate methods based on specific research questions and constraints
Understand limitations of each approach for storage system analysis
About Storage Modelling#
Storage modeling is complex because storage systems behave differently than generation or demand. Storages move energy across time, not just produce or consume it. This means:
🔁 1. Storage shifts energy in time
Unlike solar panels (generate) or homes (consume), storage stores energy when it’s abundant and releases it when needed. That means:
You can't look at one hour in isolation — what happened before matters.
The state of charge (SOC) today depends on all previous hours.
Analogy: It's like a savings account — what you can spend today depends on how much you saved earlier.
⏳ 2. Time resolution matters
Should you model every single hour? Every day? A few representative days? Each choice impacts:
Accuracy (high resolution = realistic, but slow to compute)
Computational effort (simplified models lose detail)
If you model storage with only a few sample days, you risk missing important patterns, like a long wind lull or weekend charging habits.
🔗 3. Storage needs continuity
Many simplification techniques (e.g. clustering days) break the continuity of storage:
The model might forget how full the battery was yesterday.
Artificial resets can distort when charging/discharging actually happens.
This makes it tricky to model seasonal storage or multi-day balancing.
⚡ 4. Storage interacts with everything Storage isn’t just an isolated battery:
It interacts with renewables (absorbing variability)
It supports grid reliability (fast response)
It responds to prices, constraints, and emissions goals
So modeling it well requires integrating with the rest of the energy system.
state of the art energy storage algorithms:#
Niet (Direct Link) — “Continuous Diary”#
Analogy: Imagine someone writes in their diary every hour without skipping, and each day picks up exactly where the last one left off. The emotional ups and downs (mood swings) are smooth and continuous over the week.
Key idea: Full hourly resolution; perfect continuity over time.
Use case: Most accurate but data-heavy.
Welsch (Fixed-Pattern) — “Photocopied Day”#
Analogy: This person writes down one typical day of feelings and then photocopies that same page for each day of the week. So Monday, Tuesday, etc., look exactly the same.
Key idea: Same daily pattern repeated; no inter-day variation.
Use case: Fast and simple but ignores variation between days.
Kotzur (Unverified Cluster) — “Alternating Diaries”#
Analogy: This person has two types of days — maybe “busy” and “lazy” days — and alternates between those two. They use pre-written diary templates for each. But they don’t bother connecting one day’s feelings to the next, so it can feel jumpy or inconsistent.
Key idea: Captures daily diversity using clusters, but no continuity.
Use case: Captures more variety than Welsch but lacks smooth transitions.
Novo (Hourly-Verified) — “Linked Journaling”#
Analogy: This person still uses simplified mood templates for different kinds of days, but they always make sure each day starts where the previous one left off. So it feels realistic and connected, even if it's not a full diary.
Key idea: Combines typical days with continuity between hours.
Use case: A practical middle ground between realism and simplicity.
A detailed comparison:
📊 Comparative Table of Storage Modeling Methods#
Feature |
Niet |
Welsch |
Kotzur |
Novo |
|---|---|---|---|---|
Period Linking |
Direct Link |
Enhanced Periods (Fixed Pattern) |
Enhanced Periods (Day Cluster Mapping) |
Enhanced Periods (Hourly-Verified Clustering) |
Time Representation |
Representative periods (e.g. days, weeks) |
Representative days (fixed mapping) |
Representative days (arbitrary sequence allowed) |
Full hourly resolution mapped to rep days |
Chronological Continuity |
✅ Maintained between periods |
❌ Not maintained (days are independent) |
✅ Maintained via day-sequence mapping |
✅ Maintained at hourly level |
SoC Linkage Between Periods |
✅ Explicit (stepwise linkage) |
❌ No linkage; each rep day repeats independently |
✅ Daily SoC updated using mapped intra-day values |
✅ Fully verified SoC with hourly mapping |
Intra-Day Resolution |
Average or period-level |
Full 24-hour profile (rep day) |
Full 24-hour profile (rep day) |
Full 24-hour profile (mapped to full year) |
Reset or Loop Behavior |
None; sequential linkage |
Yes; rep day is repeated N times |
Resets daily but allows arbitrary day ordering |
No reset; each hour is mapped and verified |
Flexibility in Time Sequencing |
Low (predefined order of rep periods) |
Very low (repeats identical rep day pattern) |
High (any chronological day can map to any rep day) |
Very high (full hourly reconstruction) |
Computational Cost |
Low (simple stepwise link across periods) |
Very low (repeats rep day) |
Medium (needs intra-day dynamics + daily tracking) |
High (full hourly SoC tracking and bounds checking) |
Storage Bounds Verification |
Implicit per period |
Start/End of rep day only |
Only for intra-day cycles; inter-day bounds ignored |
✅ Enforced at each hour |
Use Case |
Fast approximation with minimal memory effects |
Simple seasonal or weekday/weekend modeling |
Captures non-repetitive variation (e.g. windless days) |
High-fidelity operational modeling (e.g., reliability) |
Documentation Structure#
User Guide:
- Environment Setup Guide
- Workflow Guide
- Configuration Guide
Technical Reference:
- API Reference
- Module Overview
- Core Utilities (
src.utilities) - Time-Series Clustering (
src.cluster) - Simulation Management (
src.simulation) - Data Processing Functions
- Temporal Mapping Functions
- Visualization (
src.graph_generator) - Results Analysis (
src.table_generator) - Configuration Updates (
src.yaml_operations) - File Operations
- Error Handling
- Usage Examples
- Model Specifications
- Results Analysis
Examples & Tutorials:
Quick Start#
1. Environment Setup#
# Clone repository
git clone https://github.com/DeltaE/storage-in-OSeMOSYS.git
cd storage-in-OSeMOSYS
# Setup conda environment
make setup
conda activate storage_osemosys
# Verify installation
make test-env
2. Basic Usage#
# Run analysis with default configuration
python main.py
# Check results
ls Results/
3. Configuration#
Edit config/config.yaml to customize:
scenario_name: "k4h1WND"
days_in_year: 365
n_clusters: 4
hour_grouping: 1
Project Team#
Research Lead: Bruno Borba
Development Support: Md Eliasinul Islam
Affiliation: Delta E+ Research Lab, Simon Fraser University
License: MIT License
Citation#
If you use Storage-in-OSeMOSYS in your research, please cite:
@software{storage_osemosys_2025,
title={Storage-in-OSeMOSYS: A Framework for Temporal Representation Methods in Energy Storage Modeling},
author={Islam, Md Eliasinul},
organization={Delta E+ Research Lab, Simon Fraser University},
year={2025},
url={https://github.com/DeltaE/storage-in-OSeMOSYS}
}
Note
For technical support, please open an issue on GitHub. For research collaboration inquiries, contact the Delta E+ Research Lab.