示例#1
0
def load_constraints(backend_model):
    sets = backend_model.__calliope_model_data__['sets']

    if 'loc_carriers_system_balance_constraint' in sets:
        backend_model.system_balance = po.Expression(
            backend_model.loc_carriers_system_balance_constraint,
            backend_model.timesteps,
            initialize=0.0
        )

        backend_model.system_balance_constraint = po.Constraint(
            backend_model.loc_carriers_system_balance_constraint,
            backend_model.timesteps,
            rule=system_balance_constraint_rule
        )

    if 'loc_techs_balance_supply_constraint' in sets:
        backend_model.balance_supply_constraint = po.Constraint(
            backend_model.loc_techs_balance_supply_constraint,
            backend_model.timesteps,
            rule=balance_supply_constraint_rule
        )

    if 'loc_techs_balance_demand_constraint' in sets:
        backend_model.balance_demand_constraint = po.Constraint(
            backend_model.loc_techs_balance_demand_constraint,
            backend_model.timesteps,
            rule=balance_demand_constraint_rule
        )

    if 'loc_techs_balance_transmission_constraint' in sets:
        backend_model.balance_transmission_constraint = po.Constraint(
            backend_model.loc_techs_balance_transmission_constraint,
            backend_model.timesteps,
            rule=balance_transmission_constraint_rule
        )

    if 'loc_techs_resource_availability_supply_plus_constraint' in sets:
        backend_model.balance_supply_plus_constraint = po.Constraint(
            backend_model.loc_techs_resource_availability_supply_plus_constraint,
            backend_model.timesteps,
            rule=balance_supply_plus_constraint_rule
        )

    if 'loc_techs_balance_supply_plus_constraint' in sets:
        backend_model.resource_availability_supply_plus_constraint = po.Constraint(
            backend_model.loc_techs_balance_supply_plus_constraint,
            backend_model.timesteps,
            rule=resource_availability_supply_plus_constraint_rule
        )

    if 'loc_techs_balance_storage_constraint' in sets:
        backend_model.balance_storage_constraint = po.Constraint(
            backend_model.loc_techs_balance_storage_constraint,
            backend_model.timesteps,
            rule=balance_storage_constraint_rule
        )
示例#2
0
def load_constraints(backend_model):
    sets = backend_model.__calliope_model_data["sets"]
    run_config = backend_model.__calliope_run_config

    if "loc_techs_cost_constraint" in sets:
        backend_model.cost_constraint = po.Constraint(
            backend_model.costs,
            backend_model.loc_techs_cost,
            rule=cost_constraint_rule)

    # FIXME: remove check for operate from constraint files, avoid investment costs more intelligently?
    if ("loc_techs_cost_investment_constraint" in sets
            and run_config["mode"] != "operate"):
        # Right-hand side expression can be later updated by MILP investment costs
        backend_model.cost_investment_rhs = po.Expression(
            backend_model.costs,
            backend_model.loc_techs_cost_investment_constraint,
            initialize=0.0,
        )

        backend_model.cost_investment_constraint = po.Constraint(
            backend_model.costs,
            backend_model.loc_techs_cost_investment_constraint,
            rule=cost_investment_constraint_rule,
        )

    if "loc_techs_om_cost" in sets:
        # Right-hand side expression can be later updated by export costs/revenue
        backend_model.cost_var_rhs = po.Expression(
            backend_model.costs,
            backend_model.loc_techs_om_cost,
            backend_model.timesteps,
            initialize=0.0,
        )
    if "loc_techs_cost_var_constraint" in sets:
        # Constraint is built over a different loc_techs set to expression, as
        # it is updated in conversion.py and conversion_plus.py constraints
        backend_model.cost_var_constraint = po.Constraint(
            backend_model.costs,
            backend_model.loc_techs_cost_var_constraint,
            backend_model.timesteps,
            rule=cost_var_constraint_rule,
        )
示例#3
0
def build_expressions(backend_model, model_data, expression_definitions):
    build_order_dict = {
        expr: config.get("build_order", 0)
        for expr, config in expression_definitions.items()
    }
    build_order = sorted(build_order_dict, key=build_order_dict.get)

    for expr_name in build_order:
        subset = create_valid_subset(model_data, expr_name,
                                     expression_definitions[expr_name])
        if subset is None:
            continue
        expression_function = _load_rule_function(
            f"{expr_name}_expression_rule")
        if expression_function:
            kwargs = dict(rule=expression_function)
        else:
            kwargs = dict(initialize=0.0)
        setattr(backend_model, expr_name, po.Expression(subset, **kwargs))
示例#4
0
def load_constraints(backend_model):
    sets = backend_model.__calliope_model_data["sets"]

    if "loc_carriers_system_balance_constraint" in sets:
        backend_model.system_balance = po.Expression(
            backend_model.loc_carriers_system_balance_constraint,
            backend_model.timesteps,
            initialize=0.0,
        )

        backend_model.system_balance_constraint = po.Constraint(
            backend_model.loc_carriers_system_balance_constraint,
            backend_model.timesteps,
            rule=system_balance_constraint_rule,
        )

    if "loc_techs_balance_supply_constraint" in sets:
        backend_model.balance_supply_constraint = po.Constraint(
            backend_model.loc_techs_balance_supply_constraint,
            backend_model.timesteps,
            rule=balance_supply_constraint_rule,
        )

    if "loc_techs_balance_demand_constraint" in sets:
        # Add a required_resource expression to share computed values between constraints
        backend_model.required_resource = po.Expression(
            backend_model.loc_techs_balance_demand_constraint,
            backend_model.timesteps,
            initialize=0.0,
        )
        backend_model.balance_demand_constraint = po.Constraint(
            backend_model.loc_techs_balance_demand_constraint,
            backend_model.timesteps,
            rule=balance_demand_constraint_rule,
        )

    if "loc_techs_balance_transmission_constraint" in sets:
        backend_model.balance_transmission_constraint = po.Constraint(
            backend_model.loc_techs_balance_transmission_constraint,
            backend_model.timesteps,
            rule=balance_transmission_constraint_rule,
        )

    if "loc_techs_resource_availability_supply_plus_constraint" in sets:
        backend_model.balance_supply_plus_constraint = po.Constraint(
            backend_model.
            loc_techs_resource_availability_supply_plus_constraint,
            backend_model.timesteps,
            rule=balance_supply_plus_constraint_rule,
        )

    if "loc_techs_balance_supply_plus_constraint" in sets:
        backend_model.resource_availability_supply_plus_constraint = po.Constraint(
            backend_model.loc_techs_balance_supply_plus_constraint,
            backend_model.timesteps,
            rule=resource_availability_supply_plus_constraint_rule,
        )

    if "loc_techs_balance_storage_constraint" in sets:
        backend_model.balance_storage_constraint = po.Constraint(
            backend_model.loc_techs_balance_storage_constraint,
            backend_model.timesteps,
            rule=balance_storage_constraint_rule,
        )

    if "loc_techs_balance_storage_inter_cluster_constraint" in sets:
        backend_model.balance_storage_inter_cluster_constraint = po.Constraint(
            backend_model.loc_techs_balance_storage_inter_cluster_constraint,
            backend_model.datesteps,
            rule=balance_storage_inter_cluster_rule,
        )

    if "loc_techs_storage_initial_constraint" in sets:
        backend_model.storage_initial_constraint = po.Constraint(
            backend_model.loc_techs_storage_initial_constraint,
            rule=storage_initial_rule,
        )
示例#5
0
def create_model(data, dt=1, timesteps=None, objective='cost', dual=True):
    """Create a pyomo ConcreteModel urbs object from given input data.

    Args:
        - data: a dict of up to 12
        - dt: timestep duration in hours (default: 1)
        - timesteps: optional list of timesteps, default: demand timeseries
        - objective: Either "cost" or "CO2" for choice of objective function,
          default: "cost"
        - dual: set True to add dual variables to model output
          (marginally slower), default: True

    Returns:
        a pyomo ConcreteModel object
    """

    # Optional
    if not timesteps:
        timesteps = data['demand'].index.tolist()
    m = pyomo_model_prep(data, timesteps)  # preparing pyomo model
    m.name = 'urbs'
    m.created = datetime.now().strftime('%Y%m%dT%H%M')
    m._data = data

    # Parameters

    # weight = length of year (hours) / length of simulation (hours)
    # weight scales costs and emissions from length of simulation to a full
    # year, making comparisons among cost types (invest is annualized, fixed
    # costs are annual by default, variable costs are scaled by weight) and
    # among different simulation durations meaningful.
    m.weight = pyomo.Param(
        initialize=float(8760) / (len(m.timesteps) * dt),
        doc='Pre-factor for variable costs and emissions for an annual result')

    # dt = spacing between timesteps. Required for storage equation that
    # converts between energy (storage content, e_sto_con) and power (all other
    # quantities that start with "e_")
    m.dt = pyomo.Param(initialize=dt,
                       doc='Time step duration (in hours), default: 1')

    # import objective function information
    m.obj = pyomo.Param(
        initialize=objective,
        doc='Specification of minimized quantity, default: "cost"')

    # Sets
    # ====
    # Syntax: m.{name} = Set({domain}, initialize={values})
    # where name: set name
    #       domain: set domain for tuple sets, a cartesian set product
    #       values: set values, a list or array of element tuples

    # generate ordered time step sets
    m.t = pyomo.Set(initialize=m.timesteps,
                    ordered=True,
                    doc='Set of timesteps')

    # modelled (i.e. excluding init time step for storage) time steps
    m.tm = pyomo.Set(within=m.t,
                     initialize=m.timesteps[1:],
                     ordered=True,
                     doc='Set of modelled timesteps')

    # support timeframes (e.g. 2020, 2030...)
    indexlist = set()
    for key in m.commodity_dict["price"]:
        indexlist.add(tuple(key)[0])
    m.stf = pyomo.Set(initialize=indexlist,
                      doc='Set of modeled support timeframes (e.g. years)')

    # site (e.g. north, middle, south...)
    indexlist = set()
    for key in m.commodity_dict["price"]:
        indexlist.add(tuple(key)[1])
    m.sit = pyomo.Set(initialize=indexlist, doc='Set of sites')

    # commodity (e.g. solar, wind, coal...)
    indexlist = set()
    for key in m.commodity_dict["price"]:
        indexlist.add(tuple(key)[2])
    m.com = pyomo.Set(initialize=indexlist, doc='Set of commodities')

    # commodity type (i.e. SupIm, Demand, Stock, Env)
    indexlist = set()
    for key in m.commodity_dict["price"]:
        indexlist.add(tuple(key)[3])
    m.com_type = pyomo.Set(initialize=indexlist, doc='Set of commodity types')

    # process (e.g. Wind turbine, Gas plant, Photovoltaics...)
    indexlist = set()
    for key in m.process_dict["inv-cost"]:
        indexlist.add(tuple(key)[2])
    m.pro = pyomo.Set(initialize=indexlist, doc='Set of conversion processes')

    # cost_type
    m.cost_type = pyomo.Set(initialize=m.cost_type_list,
                            doc='Set of cost types (hard-coded)')

    # tuple sets
    m.sit_tuples = pyomo.Set(
        within=m.stf * m.sit,
        initialize=tuple(m.site_dict["area"].keys()),
        doc='Combinations of support timeframes and sites')
    m.com_tuples = pyomo.Set(
        within=m.stf * m.sit * m.com * m.com_type,
        initialize=tuple(m.commodity_dict["price"].keys()),
        doc='Combinations of defined commodities, e.g. (2018,Mid,Elec,Demand)')
    m.pro_tuples = pyomo.Set(
        within=m.stf * m.sit * m.pro,
        initialize=tuple(m.process_dict["inv-cost"].keys()),
        doc='Combinations of possible processes, e.g. (2018,North,Coal plant)')
    m.com_stock = pyomo.Set(
        within=m.com,
        initialize=commodity_subset(m.com_tuples, 'Stock'),
        doc='Commodities that can be purchased at some site(s)')

    if m.mode['int']:
        # tuples for operational status of technologies
        m.operational_pro_tuples = pyomo.Set(
            within=m.sit * m.pro * m.stf * m.stf,
            initialize=[(sit, pro, stf, stf_later)
                        for (sit, pro, stf,
                             stf_later) in op_pro_tuples(m.pro_tuples, m)],
            doc='Processes that are still operational through stf_later'
            '(and the relevant years following), if built in stf'
            'in stf.')

        # tuples for rest lifetime of installed capacities of technologies
        m.inst_pro_tuples = pyomo.Set(
            within=m.sit * m.pro * m.stf,
            initialize=[(sit, pro, stf)
                        for (sit, pro, stf) in inst_pro_tuples(m)],
            doc='Installed processes that are still operational through stf')

    # commodity type subsets
    m.com_supim = pyomo.Set(
        within=m.com,
        initialize=commodity_subset(m.com_tuples, 'SupIm'),
        doc='Commodities that have intermittent (timeseries) input')
    m.com_demand = pyomo.Set(
        within=m.com,
        initialize=commodity_subset(m.com_tuples, 'Demand'),
        doc='Commodities that have a demand (implies timeseries)')
    m.com_env = pyomo.Set(
        within=m.com,
        initialize=commodity_subset(m.com_tuples, 'Env'),
        doc='Commodities that (might) have a maximum creation limit')

    # process tuples for area rule
    m.pro_area_tuples = pyomo.Set(
        within=m.stf * m.sit * m.pro,
        initialize=tuple(m.proc_area_dict.keys()),
        doc='Processes and Sites with area Restriction')

    # process input/output
    m.pro_input_tuples = pyomo.Set(
        within=m.stf * m.sit * m.pro * m.com,
        initialize=[(stf, site, process, commodity)
                    for (stf, site, process) in m.pro_tuples
                    for (s, pro, commodity) in tuple(m.r_in_dict.keys())
                    if process == pro and s == stf],
        doc='Commodities consumed by process by site,'
        'e.g. (2020,Mid,PV,Solar)')
    m.pro_output_tuples = pyomo.Set(
        within=m.stf * m.sit * m.pro * m.com,
        initialize=[(stf, site, process, commodity)
                    for (stf, site, process) in m.pro_tuples
                    for (s, pro, commodity) in tuple(m.r_out_dict.keys())
                    if process == pro and s == stf],
        doc='Commodities produced by process by site, e.g. (2020,Mid,PV,Elec)')

    # process tuples for maximum gradient feature
    m.pro_maxgrad_tuples = pyomo.Set(
        within=m.stf * m.sit * m.pro,
        initialize=[(stf, sit, pro) for (stf, sit, pro) in m.pro_tuples
                    if m.process_dict['max-grad'][stf, sit, pro] < 1.0 / dt],
        doc='Processes with maximum gradient smaller than timestep length')

    # process tuples for partial feature
    m.pro_partial_tuples = pyomo.Set(
        within=m.stf * m.sit * m.pro,
        initialize=[(stf, site, process)
                    for (stf, site, process) in m.pro_tuples
                    for (s, pro, _) in tuple(m.r_in_min_fraction_dict.keys())
                    if process == pro and s == stf],
        doc='Processes with partial input')

    m.pro_partial_input_tuples = pyomo.Set(
        within=m.stf * m.sit * m.pro * m.com,
        initialize=[(stf, site, process, commodity)
                    for (stf, site, process) in m.pro_partial_tuples
                    for (s, pro,
                         commodity) in tuple(m.r_in_min_fraction_dict.keys())
                    if process == pro and s == stf],
        doc='Commodities with partial input ratio,'
        'e.g. (2020,Mid,Coal PP,Coal)')

    m.pro_partial_output_tuples = pyomo.Set(
        within=m.stf * m.sit * m.pro * m.com,
        initialize=[(stf, site, process, commodity)
                    for (stf, site, process) in m.pro_partial_tuples
                    for (s, pro,
                         commodity) in tuple(m.r_out_min_fraction_dict.keys())
                    if process == pro and s == stf],
        doc='Commodities with partial input ratio, e.g. (Mid,Coal PP,CO2)')

    # Variables

    # costs
    m.costs = pyomo.Var(m.cost_type,
                        within=pyomo.Reals,
                        doc='Costs by type (EUR/a)')

    # commodity
    m.e_co_stock = pyomo.Var(
        m.tm,
        m.com_tuples,
        within=pyomo.NonNegativeReals,
        doc='Use of stock commodity source (MW) per timestep')

    # process
    m.cap_pro_new = pyomo.Var(m.pro_tuples,
                              within=pyomo.NonNegativeReals,
                              doc='New process capacity (MW)')

    # process capacity as expression object
    # (variable if expansion is possible, else static)
    m.cap_pro = pyomo.Expression(m.pro_tuples,
                                 rule=def_process_capacity_rule,
                                 doc='total process capacity')

    m.tau_pro = pyomo.Var(m.t,
                          m.pro_tuples,
                          within=pyomo.NonNegativeReals,
                          doc='Power flow (MW) through process')
    m.e_pro_in = pyomo.Var(
        m.tm,
        m.pro_input_tuples,
        within=pyomo.NonNegativeReals,
        doc='Power flow of commodity into process (MW) per timestep')
    m.e_pro_out = pyomo.Var(m.tm,
                            m.pro_output_tuples,
                            within=pyomo.NonNegativeReals,
                            doc='Power flow out of process (MW) per timestep')

    # Add additional features
    # called features are declared in distinct files in features folder
    if m.mode['tra']:
        if m.mode['dpf']:
            m = transmission.add_transmission_dc(m)
        else:
            m = add_transmission(m)
    if m.mode['sto']:
        m = add_storage(m)
    if m.mode['dsm']:
        m = add_dsm(m)
    if m.mode['bsp']:
        m = add_buy_sell_price(m)
    if m.mode['tve']:
        m = add_time_variable_efficiency(m)
    else:
        m.pro_timevar_output_tuples = pyomo.Set(
            within=m.stf * m.sit * m.pro * m.com,
            doc='empty set needed for (partial) process output')

    # Equation declarations
    # equation bodies are defined in separate functions, referred to here by
    # their name in the "rule" keyword.

    # commodity
    m.res_vertex = pyomo.Constraint(
        m.tm,
        m.com_tuples,
        rule=res_vertex_rule,
        doc='storage + transmission + process + source + buy - sell == demand')
    m.res_stock_step = pyomo.Constraint(
        m.tm,
        m.com_tuples,
        rule=res_stock_step_rule,
        doc='stock commodity input per step <= commodity.maxperstep')
    m.res_stock_total = pyomo.Constraint(
        m.com_tuples,
        rule=res_stock_total_rule,
        doc='total stock commodity input <= commodity.max')
    m.res_env_step = pyomo.Constraint(
        m.tm,
        m.com_tuples,
        rule=res_env_step_rule,
        doc='environmental output per step <= commodity.maxperstep')
    m.res_env_total = pyomo.Constraint(
        m.com_tuples,
        rule=res_env_total_rule,
        doc='total environmental commodity output <= commodity.max')

    # process
    m.def_process_input = pyomo.Constraint(
        m.tm,
        m.pro_input_tuples - m.pro_partial_input_tuples,
        rule=def_process_input_rule,
        doc='process input = process throughput * input ratio')
    m.def_process_output = pyomo.Constraint(
        m.tm, (m.pro_output_tuples - m.pro_partial_output_tuples -
               m.pro_timevar_output_tuples),
        rule=def_process_output_rule,
        doc='process output = process throughput * output ratio')
    m.def_intermittent_supply = pyomo.Constraint(
        m.tm,
        m.pro_input_tuples,
        rule=def_intermittent_supply_rule,
        doc='process output = process capacity * supim timeseries')
    m.res_process_throughput_by_capacity = pyomo.Constraint(
        m.tm,
        m.pro_tuples,
        rule=res_process_throughput_by_capacity_rule,
        doc='process throughput <= total process capacity')
    m.res_process_maxgrad_lower = pyomo.Constraint(
        m.tm,
        m.pro_maxgrad_tuples,
        rule=res_process_maxgrad_lower_rule,
        doc='throughput may not decrease faster than maximal gradient')
    m.res_process_maxgrad_upper = pyomo.Constraint(
        m.tm,
        m.pro_maxgrad_tuples,
        rule=res_process_maxgrad_upper_rule,
        doc='throughput may not increase faster than maximal gradient')
    m.res_process_capacity = pyomo.Constraint(
        m.pro_tuples,
        rule=res_process_capacity_rule,
        doc='process.cap-lo <= total process capacity <= process.cap-up')

    m.res_area = pyomo.Constraint(
        m.sit_tuples,
        rule=res_area_rule,
        doc='used process area <= total process area')

    m.res_throughput_by_capacity_min = pyomo.Constraint(
        m.tm,
        m.pro_partial_tuples,
        rule=res_throughput_by_capacity_min_rule,
        doc='cap_pro * min-fraction <= tau_pro')
    m.def_partial_process_input = pyomo.Constraint(
        m.tm,
        m.pro_partial_input_tuples,
        rule=def_partial_process_input_rule,
        doc='e_pro_in = '
        ' cap_pro * min_fraction * (r - R) / (1 - min_fraction)'
        ' + tau_pro * (R - min_fraction * r) / (1 - min_fraction)')
    m.def_partial_process_output = pyomo.Constraint(
        m.tm, (m.pro_partial_output_tuples -
               (m.pro_partial_output_tuples & m.pro_timevar_output_tuples)),
        rule=def_partial_process_output_rule,
        doc='e_pro_out = '
        ' cap_pro * min_fraction * (r - R) / (1 - min_fraction)'
        ' + tau_pro * (R - min_fraction * r) / (1 - min_fraction)')

    if m.mode['int']:
        m.res_global_co2_limit = pyomo.Constraint(
            m.stf,
            rule=res_global_co2_limit_rule,
            doc='total co2 commodity output <= global.prop CO2 limit')

    # costs
    m.def_costs = pyomo.Constraint(m.cost_type,
                                   rule=def_costs_rule,
                                   doc='main cost function by cost type')

    # objective and global constraints
    if m.obj.value == 'cost':

        if m.mode['int']:
            m.res_global_co2_budget = pyomo.Constraint(
                rule=res_global_co2_budget_rule,
                doc='total co2 commodity output <= global.prop CO2 budget')
        else:
            m.res_global_co2_limit = pyomo.Constraint(
                m.stf,
                rule=res_global_co2_limit_rule,
                doc='total co2 commodity output <= Global CO2 limit')

        m.objective_function = pyomo.Objective(
            rule=cost_rule,
            sense=pyomo.minimize,
            doc='minimize(cost = sum of all cost types)')

    elif m.obj.value == 'CO2':

        m.res_global_cost_limit = pyomo.Constraint(
            rule=res_global_cost_limit_rule,
            doc='total costs <= Global cost limit')

        m.objective_function = pyomo.Objective(
            rule=co2_rule,
            sense=pyomo.minimize,
            doc='minimize total CO2 emissions')

    else:
        raise NotImplementedError("Non-implemented objective quantity. Set "
                                  "either 'cost' or 'CO2' as the objective in "
                                  "runme.py!")

    if dual:
        m.dual = pyomo.Suffix(direction=pyomo.Suffix.IMPORT)

    return m
示例#6
0
def add_transmission(m):

    # tranmission (e.g. hvac, hvdc, pipeline...)
    indexlist = set()
    for key in m.transmission_dict["eff"]:
        indexlist.add(tuple(key)[3])
    m.tra = pyomo.Set(
        initialize=indexlist,
        doc='Set of transmission technologies')

    # transmission tuples
    m.tra_tuples = pyomo.Set(
        within=m.stf * m.sit * m.sit * m.tra * m.com,
        initialize=tuple(m.transmission_dict["eff"].keys()),
        doc='Combinations of possible transmissions, e.g. '
            '(2020,South,Mid,hvac,Elec)')

    if m.mode['int']:
        m.operational_tra_tuples = pyomo.Set(
            within=m.sit * m.sit * m.tra * m.com * m.stf * m.stf,
            initialize=[(sit, sit_, tra, com, stf, stf_later)
                        for (sit, sit_, tra, com, stf, stf_later)
                        in op_tra_tuples(m.tra_tuples, m)],
            doc='Transmissions that are still operational through stf_later'
                '(and the relevant years following), if built in stf'
                'in stf.')
        m.inst_tra_tuples = pyomo.Set(
            within=m.sit * m.sit * m.tra * m.com * m.stf,
            initialize=[(sit, sit_, tra, com, stf)
                        for (sit, sit_, tra, com, stf)
                        in inst_tra_tuples(m)],
            doc='Installed transmissions that are still operational'
                'through stf')

    # Variables
    m.cap_tra_new = pyomo.Var(
        m.tra_tuples,
        within=pyomo.NonNegativeReals,
        doc='New transmission capacity (MW)')

    # transmission capacity as expression object
    m.cap_tra = pyomo.Expression(
        m.tra_tuples,
        rule=def_transmission_capacity_rule,
        doc='total transmission capacity')

    m.e_tra_in = pyomo.Var(
        m.tm, m.tra_tuples,
        within=pyomo.NonNegativeReals,
        doc='Power flow into transmission line (MW) per timestep')
    m.e_tra_out = pyomo.Var(
        m.tm, m.tra_tuples,
        within=pyomo.NonNegativeReals,
        doc='Power flow out of transmission line (MW) per timestep')

    # transmission
    m.def_transmission_output = pyomo.Constraint(
        m.tm, m.tra_tuples,
        rule=def_transmission_output_rule,
        doc='transmission output = transmission input * efficiency')
    m.res_transmission_input_by_capacity = pyomo.Constraint(
        m.tm, m.tra_tuples,
        rule=res_transmission_input_by_capacity_rule,
        doc='transmission input <= total transmission capacity')
    m.res_transmission_capacity = pyomo.Constraint(
        m.tra_tuples,
        rule=res_transmission_capacity_rule,
        doc='transmission.cap-lo <= total transmission capacity <= '
            'transmission.cap-up')
    m.res_transmission_symmetry = pyomo.Constraint(
        m.tra_tuples,
        rule=res_transmission_symmetry_rule,
        doc='total transmission capacity must be symmetric in both directions')

    return m
示例#7
0
def add_transmission_dc(m):
    # defining transmission tuple sets for transport and DCPF model separately
    tra_tuples = set()
    tra_tuples_dc = set()
    for key in m.transmission_dict['reactance']:
        tra_tuples.add(tuple(key))
    for key in m.transmission_dc_dict['reactance']:
        tra_tuples_dc.add(tuple(key))
    tra_tuples_tp = tra_tuples - tra_tuples_dc
    tra_tuples_dc = remove_duplicate_transmission(tra_tuples_dc)
    tra_tuples = tra_tuples_dc | tra_tuples_tp

    # tranmission (e.g. hvac, hvdc, pipeline...)
    indexlist = set()
    for key in m.transmission_dict["eff"]:
        indexlist.add(tuple(key)[3])
    m.tra = pyomo.Set(
        initialize=indexlist,
        doc='Set of transmission technologies')

    # Transport and DCPF transmission tuples
    m.tra_tuples = pyomo.Set(
        within=m.stf * m.sit * m.sit * m.tra * m.com,
        initialize=tuple(tra_tuples),
        doc='Combinations of possible transmissions,'
            'without duplicate dc transmissions'
            ' e.g. (2020,South,Mid,hvac,Elec)')

    # DCPF transmission tuples
    m.tra_tuples_dc = pyomo.Set(
        within=m.stf * m.sit * m.sit * m.tra * m.com,
        initialize=tuple(tra_tuples_dc),
        doc='Combinations of possible bidirectional dc'
            'transmissions, e.g. (2020,South,Mid,hvac,Elec)')

    # Transport transmission tuples
    m.tra_tuples_tp = pyomo.Set(
        within=m.stf * m.sit * m.sit * m.tra * m.com,
        initialize=tuple(tra_tuples_tp),
        doc='Combinations of possible transport transmissions,'
            'e.g. (2020,South,Mid,hvac,Elec)')

    if m.mode['int']:
        m.operational_tra_tuples = pyomo.Set(
            within=m.sit * m.sit * m.tra * m.com * m.stf * m.stf,
            initialize=[(sit, sit_, tra, com, stf, stf_later)
                        for (sit, sit_, tra, com, stf, stf_later)
                        in op_tra_tuples(m.tra_tuples, m)],
            doc='Transmissions that are still operational through stf_later'
                '(and the relevant years following), if built in stf'
                'in stf.')
        m.inst_tra_tuples = pyomo.Set(
            within=m.sit * m.sit * m.tra * m.com * m.stf,
            initialize=[(sit, sit_, tra, com, stf)
                        for (sit, sit_, tra, com, stf)
                        in inst_tra_tuples(m)],
            doc='Installed transmissions that are still operational'
                'through stf')

    # Variables
    m.cap_tra_new = pyomo.Var(
        m.tra_tuples,
        within=pyomo.NonNegativeReals,
        doc='New transmission capacity (MW)')

    # transmission capacity as expression object
    m.cap_tra = pyomo.Expression(
        m.tra_tuples,
        rule=def_transmission_capacity_rule,
        doc='total transmission capacity')

    m.e_tra_abs = pyomo.Var(
        m.tm, m.tra_tuples_dc,
        within=pyomo.NonNegativeReals,
        doc='Absolute power flow on transmission line (MW) per timestep')
    m.e_tra_in = pyomo.Var(
        m.tm, m.tra_tuples,
        within=e_tra_domain_rule,
        doc='Power flow into transmission line (MW) per timestep')
    m.e_tra_out = pyomo.Var(
        m.tm, m.tra_tuples,
        within=e_tra_domain_rule,
        doc='Power flow out of transmission line (MW) per timestep')

    m.voltage_angle = pyomo.Var(
        m.tm, m.stf, m.sit,
        within=pyomo.Reals,
        doc='Voltage angle of a site')

    # transmission
    m.def_transmission_output = pyomo.Constraint(
        m.tm, m.tra_tuples,
        rule=def_transmission_output_rule,
        doc='transmission output = transmission input * efficiency')
    m.def_dc_power_flow = pyomo.Constraint(
        m.tm, m.tra_tuples_dc,
        rule=def_dc_power_flow_rule,
        doc='transmission output = (angle(in)-angle(out))/ 57.2958 '
            '* -1 *(-1/reactance) * (base voltage)^2')
    m.def_angle_limit = pyomo.Constraint(
        m.tm, m.tra_tuples_dc,
        rule=def_angle_limit_rule,
        doc='-angle limit < angle(in) - angle(out) < angle limit')
    m.e_tra_abs1 = pyomo.Constraint(
        m.tm, m.tra_tuples_dc,
        rule=e_tra_abs_rule1,
        doc='transmission dc input <= absolute transmission dc input')
    m.e_tra_abs2 = pyomo.Constraint(
        m.tm, m.tra_tuples_dc,
        rule=e_tra_abs_rule2,
        doc='-transmission dc input <= absolute transmission dc input')

    m.res_transmission_input_by_capacity = pyomo.Constraint(
        m.tm, m.tra_tuples,
        rule=res_transmission_input_by_capacity_rule,
        doc='transmission input <= total transmission capacity')
    m.res_transmission_dc_input_by_capacity = pyomo.Constraint(
        m.tm, m.tra_tuples_dc,
        rule=res_transmission_dc_input_by_capacity_rule,
        doc='-dcpf transmission input <= total transmission capacity')
    m.res_transmission_capacity = pyomo.Constraint(
        m.tra_tuples,
        rule=res_transmission_capacity_rule,
        doc='transmission.cap-lo <= total transmission capacity <= '
            'transmission.cap-up')
    m.res_transmission_symmetry = pyomo.Constraint(
        m.tra_tuples_tp,
        rule=res_transmission_symmetry_rule,
        doc='total transmission capacity must be symmetric in both directions')

    return m
示例#8
0
文件: storage.py 项目: wuyou33/urbs
def add_storage(m):

    # storage (e.g. hydrogen, pump storage)
    indexlist = set()
    for key in m.storage_dict["eff-in"]:
        indexlist.add(tuple(key)[2])
    m.sto = pyomo.Set(initialize=indexlist, doc='Set of storage technologies')

    # storage tuples
    m.sto_tuples = pyomo.Set(within=m.stf * m.sit * m.sto * m.com,
                             initialize=tuple(m.storage_dict["eff-in"].keys()),
                             doc='Combinations of possible storage by site,'
                             'e.g. (2020,Mid,Bat,Elec)')

    # tuples for intertemporal operation
    if m.mode['int']:
        m.operational_sto_tuples = pyomo.Set(
            within=m.sit * m.sto * m.com * m.stf * m.stf,
            initialize=[(sit, sto, com, stf, stf_later)
                        for (sit, sto, com, stf,
                             stf_later) in op_sto_tuples(m.sto_tuples, m)],
            doc='Processes that are still operational through stf_later'
            '(and the relevant years following), if built in stf'
            'in stf.')
        m.inst_sto_tuples = pyomo.Set(
            within=m.sit * m.sto * m.com * m.stf,
            initialize=[(sit, sto, com, stf)
                        for (sit, sto, com, stf) in inst_sto_tuples(m)],
            doc='Installed storages that are still operational through stf')

    # storage tuples for storages with fixed initial state
    m.sto_init_bound_tuples = pyomo.Set(
        within=m.stf * m.sit * m.sto * m.com,
        initialize=tuple(m.stor_init_bound_dict.keys()),
        doc='storages with fixed initial state')

    # storage tuples for storages with given energy to power ratio
    m.sto_ep_ratio_tuples = pyomo.Set(
        within=m.stf * m.sit * m.sto * m.com,
        initialize=tuple(m.sto_ep_ratio_dict.keys()),
        doc='storages with given energy to power ratio')

    # Variables
    m.cap_sto_c_new = pyomo.Var(m.sto_tuples,
                                within=pyomo.NonNegativeReals,
                                doc='New storage size (MWh)')
    m.cap_sto_p_new = pyomo.Var(m.sto_tuples,
                                within=pyomo.NonNegativeReals,
                                doc='New  storage power (MW)')

    # storage capacities as expression objects
    m.cap_sto_c = pyomo.Expression(m.sto_tuples,
                                   rule=def_storage_capacity_rule,
                                   doc='Total storage size (MWh)')
    m.cap_sto_p = pyomo.Expression(m.sto_tuples,
                                   rule=def_storage_power_rule,
                                   doc='Total storage power (MW)')

    m.e_sto_in = pyomo.Var(m.tm,
                           m.sto_tuples,
                           within=pyomo.NonNegativeReals,
                           doc='Power flow into storage (MW) per timestep')
    m.e_sto_out = pyomo.Var(m.tm,
                            m.sto_tuples,
                            within=pyomo.NonNegativeReals,
                            doc='Power flow out of storage (MW) per timestep')
    m.e_sto_con = pyomo.Var(m.t,
                            m.sto_tuples,
                            within=pyomo.NonNegativeReals,
                            doc='Energy content of storage (MWh) in timestep')

    # storage rules
    m.def_storage_state = pyomo.Constraint(
        m.tm,
        m.sto_tuples,
        rule=def_storage_state_rule,
        doc='storage[t] = (1 - sd) * storage[t-1] + in * eff_i - out / eff_o')
    m.res_storage_input_by_power = pyomo.Constraint(
        m.tm,
        m.sto_tuples,
        rule=res_storage_input_by_power_rule,
        doc='storage input <= storage power')
    m.res_storage_output_by_power = pyomo.Constraint(
        m.tm,
        m.sto_tuples,
        rule=res_storage_output_by_power_rule,
        doc='storage output <= storage power')
    m.res_storage_state_by_capacity = pyomo.Constraint(
        m.t,
        m.sto_tuples,
        rule=res_storage_state_by_capacity_rule,
        doc='storage content <= storage capacity')
    m.res_storage_power = pyomo.Constraint(
        m.sto_tuples,
        rule=res_storage_power_rule,
        doc='storage.cap-lo-p <= storage power <= storage.cap-up-p')
    m.res_storage_capacity = pyomo.Constraint(
        m.sto_tuples,
        rule=res_storage_capacity_rule,
        doc='storage.cap-lo-c <= storage capacity <= storage.cap-up-c')
    m.def_initial_storage_state = pyomo.Constraint(
        m.sto_init_bound_tuples,
        rule=def_initial_storage_state_rule,
        doc='storage content initial == and final >= storage.init * capacity')
    m.res_storage_state_cyclicity = pyomo.Constraint(
        m.sto_tuples,
        rule=res_storage_state_cyclicity_rule,
        doc='storage content initial <= final, both variable')
    m.def_storage_energy_power_ratio = pyomo.Constraint(
        m.sto_ep_ratio_tuples,
        rule=def_storage_energy_power_ratio_rule,
        doc='storage capacity = storage power * storage E2P ratio')

    return m