A Python-based power grid optimization framework for modeling energy systems with renewable integration and policy constraints.
- Status & Roadmap
- Prerequisites
- Installation
- Running the Network
- Project Structure
- Optimization Framework
- Testing
- Current State: Development
- Key Features:
- Power grid network modeling
- Renewable integration optimization
- Policy constraint handling
- Multi-region transmission modeling
- Policy implementation from graph data (see network.py TODO)
- Improved data validation for input files
- Documentation for data file formats
- Unit test coverage
- Performance optimization for large networks
- Python 3.8+
- pip
- (optional) Jupyter Notebook
- Clone the repository:
git clone <repository-url>
cd <repository-name>- Create and activate a virtual environment (recommended):
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate- Install dependencies:
pip install -r requirements.txt- Configure your settings in
config.py:
# Edit regions of interest
REGIONS = ['ERC_FRNT', 'ERC_PHDL', 'ERC_REST', 'ERC_WEST']
# Adjust time window
START_HOUR = 0 # Start hour of the year (0-8759)
NUM_HOURS = 24 # Number of hours to optimize
# Modify paths if needed
INPUT_GRAPH_PATH = 'Data/Default/US/graph.json'- Run the optimization:
python run_network.py- Check the outputs:
- Results will be saved to
optimization_results.json(configurable in config.py) - Logs will be written to
optimization_output.log - Enable DEBUG_MODE in config.py for additional output
The config.py file allows you to customize:
- Regions: Which geographical areas to include
- Time Window: Start time and duration of optimization
- Network Parameters: Line efficiency and other technical parameters
- Input/Output: File paths for data, logs, and results
- Debug Settings: Toggle detailed debug output
# Load a pre-built graph
graph = graph_from_json('Data/Default/US/graph.json')
# Create a subgraph for specific regions
regions = ['ERC_FRNT', 'ERC_PHDL', 'ERC_REST', 'ERC_WEST']
sub_g = subgraph(graph, regions)
# Create optimization network
network = Network()
network.add_plants(plants) # Add plant data
# Define time window
time_steps = range(24) # 24-hour optimization
# Create and solve optimization
opt_model = OptimizationModel(network, time_steps)
results = opt_model.solve()src/: Core source codeoptimization/: Optimization model componentsnetwork.py: Core class managing the optimization network structure- Uses NetworkX's
DiGraphto represent the power grid - Handles nodes (regions, policies) and edges (transmission lines)
- Manages policies and plant assignments
- Uses NetworkX's
base/andbuses/:Region: Represents geographical areas containing assetsPolicy: Handles renewable requirements for different jurisdictions
assets/:Producer: Power plants with capacity, costs, emissionsStore: Energy storage facilitiesLoad: Power demand centersLine: Transmission lines connecting regions
model.py:- Uses Pyomo for optimization
- Defines variables, constraints, and objective function components for each asset type
graph/: Network graph handlinginputs/: Data processing utilities
Data/: Input data files
- Region: Represents geographical areas containing assets.
- Policy: Handles renewable requirements for different jurisdictions.
Each node can contain multiple assets:
- Producers (e.g., power plants)
- Loads (e.g., power demand centers)
- Storage facilities (e.g., batteries)
- Producer: Represents power plants with attributes like capacity, costs, and emissions.
- Store: Represents energy storage facilities.
- Load: Represents centers of power demand.
- Line: Represents transmission lines connecting regions.
The framework uses Pyomo for optimization. Each asset type defines:
- Variables (e.g., production levels, storage levels).
- Constraints (e.g., capacity limits, renewable requirements).
- Objective function components (e.g., costs).
The system is modular:
- Each component (region, plant, line) defines its own optimization variables and constraints.
- The
Networkclass orchestrates interactions between components. - Policies act as cross-cutting concerns, adding constraints across multiple assets.
The project uses pytest for testing. Tests are organized into:
- Feasibility tests (
test_feasibility.py): Basic network operation - Edge case tests (
test_edge_cases.py): Boundary conditions and error cases
Run all tests:
pytestRun specific test categories:
pytest -v -m optimization # Run optimization-related tests
pytest tests/test_feasibility.py # Run feasibility tests onlyTests use fixture data defined in conftest.py to create test networks:
# Example test using fixtures
def test_empty_network(self, empty_graph):
"""Test that empty network has zero generation and cost"""
network = Network().set_graph(graph_from_dict(empty_graph))
result = network.optimize()
assert result.objective_value == 0Common test scenarios are provided as fixtures:
empty_graph: Empty network with no nodes or edgessingle_node_graph: Single region with generator and loadtwo_node_graph: Two connected regions with transmission
- Use the provided fixtures or create new ones in
conftest.py - Create network using the
Network().set_graph()pattern:
network = Network().set_graph(graph_from_dict(test_graph))- Add appropriate assertions:
# Test generation matches load
assert sum(gen.production for gen in result.generators.values()) == total_load
# Test transmission limits
assert result.lines["line1"].flow <= line_capacity- Add markers for test categorization:
@pytest.mark.optimization
def test_my_feature():
...optimization_results.json: Optimization results.optimization_output.log: Detailed logging output.