Source code for multi_run_period

import argparse
import os
import numpy as np
import copy

from energy_hub.param_var import ConstantOrVar
from energy_hub import EHubModel
from energy_hub.utils import constraint
from energy_hub.input_data import InputData
from outputter import print_section, output_excel
import excel_to_request_format
import pylp
from pylp import RealVariable, BinaryVariable, IntegerVariable

import pdb

DOMAIN_TO_VARIABLE = {
    'Continuous': RealVariable,
    'Integer': IntegerVariable,
    'Binary': BinaryVariable,
}


[docs] @constraint() def same_converter_constraint(converter, hubs): """ Constraint to ensure the capacities are kept constant across all the subproblems. """ #TODO: Check that storage capacites are also kept the same for i in range(len(hubs)-1): yield hubs[i].capacities[converter] == hubs[i+1].capacities[converter]
[docs] @constraint() def same_storage_constraint(storage, hubs): """ Constraint to ensure the capacities are kept constant across all the subproblems. """ #TODO: Check that storage capacites are also kept the same for i in range(len(hubs)-1): yield hubs[i].storage_capacity[storage] == hubs[i+1].storage_capacity[storage]
[docs] def split_hubs(excel=None, request=None, max_carbon=None, num_periods=1, len_periods=24, num_periods_in_sample_period=1, sample_period_position=0): """ Splits a PyEHub into a series of smaller hubs with a given period. """ if excel: request = excel_to_request_format.convert(excel) if request: _data = InputData(request) else: raise RuntimeError("Can't create hubs with no data.") hubs = [] if ((num_periods*len_periods*num_periods_in_sample_period) > len(request['time_series'][0]['data'])): raise IndexError("Not enough data to cover all the periods.") if (num_periods_in_sample_period <= sample_period_position): raise IndexError("Not enough periods in sample to start at the given position.") for i in range(0, num_periods): temp_request = copy.deepcopy(request) for stream in temp_request['time_series']: stream['data'] = stream['data'][len_periods*(i + i*(num_periods_in_sample_period-1) + sample_period_position) : len_periods*(i+1 + i*(num_periods_in_sample_period-1) + sample_period_position)] hub = EHubModel(request=temp_request, max_carbon=max_carbon) hubs.append(hub) return hubs
[docs] def merge_hubs(hubs): """ Compiles and combines the constraints of each subproblem into one list. :param hubs: List of EHubs. :return: The list of constraints for each hub combined with the capacities constraint to ensure the same converter capacities across all EHubs. """ constraints = [] for hub in hubs: hub.recompile() for constr in hub.constraints: constraints.append(constr) for converter in hubs[0].technologies: for c in same_converter_constraint(converter, hubs): constraints.append(c) for storage in hubs[0].storages: for c in same_storage_constraint(storage, hubs): constraints.append(c) return constraints
#TODO: Finish and move to outputter?
[docs] def multi_run_output(hubs, factor): """ Function for collecting the correct info from the multiple EHub models and combining them into one set of results :param hubs: the EHub models now containing their solutions :param factor: If the models are samples for larger time scales """ absolute_cost = hubs[0].solution_dict['investment_cost'] for result in hubs: absolute_cost += result.solution_dict['maintenance_cost']*factor + result.solution_dict['operating_cost']* factor return absolute_cost
[docs] def run_split_period(excel=None, request=None, output_filename=None, max_carbon=None, num_periods=1, len_periods=24, num_periods_in_sample_period=1, sample_period_position=0, solver='glpk'): """ Core function for splitting a PyEHub model into smaller problems to solve together. :param excel: Input excel file if the hub to be split is in excel. Converted into request format before being split into subproblems. :param request: Input in request JSON format if the hub to be split is in JSON. :param output_filename: Name for file to right the output to if an output file is being used. :param max_carbon: Max carbon value if using a capped carbon value. :param num_periods: Number of sub problem EHubs to be solved together. :param len_periods: Number of time steps per sub problem EHub to be solved. :param num_periods_in_sample_period: Number of periods being grouped together to be represented by 1 sub problem EHub. Example: One week representing a whole month would be ~four periods in a sample period. :param sample_period_position: Which period in the grouped sample to use as the representative EHub. Example the second week of every month would be two. :param solver: Which MILP solver to use. :return: The status of pylp's solving, the list of hubs (each with their solution), and the absolute cost (cost of all the subproblems added together with the correct factor) """ hubs = split_hubs(excel, request, max_carbon, num_periods, len_periods, num_periods_in_sample_period, sample_period_position) constraints = merge_hubs(hubs) #TODO: Make sure storage looping is working for each sub_hub objective = hubs[0].investment_cost for hub in hubs: objective += hub.operating_cost + hub.maintenance_cost status = pylp.solve(objective=objective, constraints=constraints, minimize=True, solver=solver) output = multi_run_output(hubs, num_periods_in_sample_period) return status, hubs, output