Source code for prepshot.model

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""This module defines the PREP-SHOT model. The model is created using 
the pyoptinterface library.
"""

from prepshot.utils import cartesian_product
from prepshot._model.demand import AddDemandConstraints
from prepshot._model.generation import AddGenerationConstraints
from prepshot._model.cost import AddCostObjective
from prepshot._model.co2 import AddCo2EmissionConstraints
from prepshot._model.hydro import AddHydropowerConstraints
from prepshot._model.storage import AddStorageConstraints
from prepshot._model.nondispatchable import AddNondispatchableConstraints
from prepshot._model.transmission import AddTransmissionConstraints
from prepshot._model.investment import AddInvestmentConstraints
from prepshot.logs import timer
from prepshot.solver import get_solver
from prepshot.solver import set_solver_parameters

[docs]def define_model( params : dict ) -> object: """This function creates the model class depending on predefined solver. Parameters ---------- params : dict parameters for the model Returns ------- object A pyoptinterface Model object depending on the solver Raises ------ ValueError Unsupported or undefined solver """ solver = get_solver(params) model = solver.Model() model.params = params set_solver_parameters(model) return model
[docs]def define_basic_sets(model : object) -> None: """Define sets for the model. Parameters ---------- model : object Model object to be solved. """ params = model.params basic_sets = ["year", "zone", "tech", "hour", "month"] tech_types = ["storage", "nondispatchable", "dispatchable", "hydro"] model.tech_types = tech_types for set_name in basic_sets: setattr(model, set_name, params[set_name]) # TODO: Generate the hour_p set based on the hour set model.hour_p = [0] + params['hour'] tech_category = params['technology_type'] # tech_category: { # 'Coal': 'dispatchable', # 'Solar': 'nondispatchable', # ... # } for tech_type in tech_types: tech_set = [k for k, v in tech_category.items() if v == tech_type] setattr(model, f"{tech_type}_tech", tech_set) if params['isinflow']: model.station = params['stcd']
[docs]def define_complex_sets(model : object) -> None: """Create complex sets based on simple sets and some conditations. The existing capacity between two zones is set to empty (i.e., No value is filled in the Excel cell), which means that these two zones cannot have newly built transmission lines. If you want to enable two zones which do not have any existing transmission lines, to build new transmission lines in the planning horizon, you need to set their capacity as zero explicitly. Parameters ---------- model : object Model to be solved. """ trans_sets = model.params['transmission_line_existing_capacity'].keys() for z_i, z1_i in cartesian_product(model.zone, model.zone): if (z_i, z1_i) not in trans_sets: model.params['transmission_line_existing_capacity'][z_i, z1_i] = 0 model.params['transmission_line_efficiency'][z_i, z1_i] = 0
# TODO: Set the capacity of new transmission lines to 0
[docs]def define_variables(model : object) -> None: """Define variables for the model. Parameters ---------- model : object Model to be solved. """ model.cap_newtech = model.add_variables( model.year, model.zone, model.tech, lb=0 ) model.cap_newline = model.add_variables( model.year, model.zone, model.zone, lb=0 ) model.gen = model.add_variables( model.hour, model.month, model.year, model.zone, model.tech, lb=0 ) model.storage = model.add_variables( model.hour_p, model.month, model.year, model.zone, model.tech, lb=0 ) model.charge = model.add_variables( model.hour, model.month, model.year, model.zone, model.tech, lb=0 ) model.trans_export = model.add_variables( model.hour, model.month, model.year, model.zone, model.zone, lb=0 ) if model.params['isinflow']: model.genflow = model.add_variables( model.station, model.hour, model.month, model.year, lb=0 ) model.spillflow = model.add_variables( model.station, model.hour, model.month, model.year, lb=0 ) model.withdraw = model.add_variables( model.station, model.hour, model.month, model.year, lb=0 ) model.storage_reservoir = model.add_variables( model.station, model.hour_p, model.month, model.year, lb=0 ) model.output = model.add_variables( model.station, model.hour, model.month, model.year, lb=0 )
[docs]def define_constraints(model : object) -> None: """Define constraints for the model. Parameters ---------- model : object Model to be solved. """ AddInvestmentConstraints(model) AddGenerationConstraints(model) AddTransmissionConstraints(model) AddCo2EmissionConstraints(model) AddNondispatchableConstraints(model) AddStorageConstraints(model) AddHydropowerConstraints(model) AddDemandConstraints(model)
[docs]@timer def create_model(params : dict) -> object: """Create the PREP-SHOT model. Parameters ---------- params : dict Dictionary of parameters for the model. Returns ------- object Model object. """ model = define_model(params) define_basic_sets(model) define_complex_sets(model) define_variables(model) define_constraints(model) AddCostObjective(model) return model