def mga_objective(network, snapshots, direction, options): mga_variables = options['mga_variables'] expr_list = [] for i, variable in enumerate(mga_variables): if variable == 'transmission': expr_list.append( linexpr((direction[i], get_var(network, 'Link', 'p_nom'))).sum()) if variable == 'co2_emission': expr_list.append( linexpr((direction[i], get_var( network, 'Generator', 'p').filter(network.generators.index[ network.generators.type == 'ocgt']))).sum().sum()) elif variable == 'H2' or variable == 'battery': expr_list.append( linexpr((direction[i], get_var( network, 'StorageUnit', 'p_nom').filter(network.storage_units.index[ network.storage_units.carrier == variable]))).sum()) else: expr_list.append( linexpr( (direction[i], get_var(network, 'Generator', 'p_nom').filter(network.generators.index[ network.generators.type == variable]))).sum()) mga_obj = join_exprs(np.array(expr_list)) write_objective(network, mga_obj)
def mga_constraint(network, snapshots, options): scale = 1e-6 # This function creates the MGA constraint gen_capital_cost = linexpr((scale * network.generators.capital_cost, get_var(network, 'Generator', 'p_nom'))).sum() gen_marginal_cost = linexpr((scale * network.generators.marginal_cost, get_var(network, 'Generator', 'p'))).sum().sum() store_capital_cost = linexpr((scale * network.storage_units.capital_cost, get_var(network, 'StorageUnit', 'p_nom'))).sum() link_capital_cost = linexpr( (scale * network.links.capital_cost, get_var(network, 'Link', 'p_nom'))).sum() # total system cost cost_scaled = join_exprs( np.array([ gen_capital_cost, gen_marginal_cost, store_capital_cost, link_capital_cost ])) # MGA slack if options['mga_slack_type'] == 'percent': slack = network.old_objective * options[ 'mga_slack'] + network.old_objective elif options['mga_slack_type'] == 'fixed': slack = options['baseline_cost'] * options['mga_slack'] + options[ 'baseline_cost'] define_constraints(network, cost_scaled, '<=', slack * scale, 'GlobalConstraint', 'MGA_constraint')
def netzbooster_constraints(n, snapshots): """ add to the LOPF the additional Netzbooster constraints """ # Define indices & parameters n.determine_network_topology() sub = n.sub_networks.at["0", "obj"] sub.calculate_PTDF() sub.calculate_BODF() snapshots = snapshots #n.snapshots buses = sub.buses_i() lines = sub.lines_i() outages = [l for l in lines if "outage" in l] ptdf = pd.DataFrame(sub.PTDF, index=lines, columns=buses) lodf = pd.DataFrame(sub.BODF, index=lines, columns=lines) logger.info("define variables") # i = buses # t = snapshots # k = outages # P_i + >= 0 define_variables(n, 0, inf, "Bus", "P_pos", axes=[buses]) # P_i - >= 0 define_variables(n, 0, inf, "Bus", "P_neg", axes=[buses]) # p_{i,t,k} + >= 0 define_variables( n, 0, inf, "Bus", "p_pos", axes=[snapshots, pd.MultiIndex.from_product([buses, outages])]) # p_{i,t,k} + >= 0 define_variables( n, 0, inf, "Bus", "p_neg", axes=[snapshots, pd.MultiIndex.from_product([buses, outages])]) logger.info("define constraints") # # Define constraints # ########### p_pos(i,k,t) <= P_pos(i) ########## P_pos_extend = expand_series( get_var(n, "Bus", "P_pos").loc[buses], snapshots).T.reindex(pd.MultiIndex.from_product([buses, outages]), axis=1, level=0) lhs_1 = linexpr((1, P_pos_extend[buses]), (-1, get_var(n, "Bus", "p_pos").loc[snapshots, buses])) define_constraints(n, lhs_1, ">=", 0., "Bus", "UpLimitPos") # ######### p_neg(i,k,t) <= P_neg(i) ######### P_neg_extend = expand_series( get_var(n, "Bus", "P_neg").loc[buses], snapshots).T.reindex(pd.MultiIndex.from_product([buses, outages]), axis=1, level=0) lhs_2 = linexpr((1, P_neg_extend[buses]), (-1, get_var(n, "Bus", "p_pos").loc[snapshots, buses])) define_constraints(n, lhs_2, ">=", 0., "Bus", "UpLimitNeg") # ######## sum(i, p_pos(i,k,t) - p_neg(i,k,t)) = 0 ######### lhs_3 = linexpr((1, get_var(n, "Bus", "p_pos").loc[snapshots].groupby( level=1, axis=1).sum()), (-1, get_var( n, "Bus", "p_neg").loc[snapshots].groupby(level=1, axis=1).sum())) define_constraints(n, lhs_3, "==", 0., "Bus", "FlexBal") # ## |f(l,t) + LODF(l,k) * f(k,t) + sum_i (PTDF(l,i) * (p_neg(i,k, t) - p_pos(i,k, t)))| <= F(l) ######## # f(l,t) + LODF(l,k) * f(k,t) + sum_i (PTDF(l,i) * (p_neg(i,k, t) - p_pos(i,k, t))) <= F(l) # f(l,t) here: f pandas DataFrame(index=snapshots, columns=lines) f = get_var(n, "Line", "s") # F(l) -> line capacity for n.lines.s_nom_extendable=False F = n.lines.s_nom # p pos (index=snapshots, columns=[bus, outage]) p_pos = get_var(n, "Bus", "p_pos") # p neg (index=snapshots, columns=[bus, outage]) p_neg = get_var(n, "Bus", "p_neg") for k in outages: for l in lines.difference(pd.Index( [k])): # all l except for outage line for t in snapshots: lhs = '' # sum_i (PTDF(l,i) * (p_neg(i,k, t) - p_pos(i,k, t))) v1 = linexpr( (ptdf.loc[l], p_neg.loc[t].xs( k, level=1)), # sum_i (PTDF(l,i) * (p_neg(i,k, t)) (-1 * ptdf.loc[l], p_pos.loc[t].xs(k, level=1) ) # sum_i (- PTDF(l,i) * (p_pos(i,k, t)) ) lhs += '\n' + join_exprs(v1.sum()) # f(l,t) + LODF(l,k) * f(k,t) v = linexpr( (1, f.loc[t, l]), # f(l,t) (lodf.loc[l, k], f.loc[t, k])) # LODF(l,k) * f(k,t) lhs += '\n' + join_exprs(v) rhs = F.loc[l] define_constraints(n, lhs, "<=", rhs, "booster1", "capacity_limit") define_constraints(n, lhs, ">=", -rhs, "booster2", "capacity_limit2")