def add_EQ_constraints(n, o, scaling=1e-1): float_regex = "[0-9]*\.?[0-9]+" level = float(re.findall(float_regex, o)[0]) if o[-1] == 'c': ggrouper = n.generators.bus.map(n.buses.country) lgrouper = n.loads.bus.map(n.buses.country) sgrouper = n.storage_units.bus.map(n.buses.country) else: ggrouper = n.generators.bus lgrouper = n.loads.bus sgrouper = n.storage_units.bus load = n.snapshot_weightings @ \ n.loads_t.p_set.groupby(lgrouper, axis=1).sum() inflow = n.snapshot_weightings @ \ n.storage_units_t.inflow.groupby(sgrouper, axis=1).sum() inflow = inflow.reindex(load.index).fillna(0.) rhs = scaling * ( level * load - inflow ) lhs_gen = linexpr((n.snapshot_weightings * scaling, get_var(n, "Generator", "p").T) ).T.groupby(ggrouper, axis=1).apply(join_exprs) lhs_spill = linexpr((-n.snapshot_weightings * scaling, get_var(n, "StorageUnit", "spill").T) ).T.groupby(sgrouper, axis=1).apply(join_exprs) lhs_spill = lhs_spill.reindex(lhs_gen.index).fillna("") lhs = lhs_gen + lhs_spill define_constraints(n, lhs, ">=", rhs, "equity", "min")
def add_CCL_constraints(n, config): agg_p_nom_limits = config['electricity'].get('agg_p_nom_limits') try: agg_p_nom_minmax = pd.read_csv(agg_p_nom_limits, index_col=list(range(2))) except IOError: logger.exception("Need to specify the path to a .csv file containing " "aggregate capacity limits per country in " "config['electricity']['agg_p_nom_limit'].") logger.info("Adding per carrier generation capacity constraints for " "individual countries") gen_country = n.generators.bus.map(n.buses.country) # cc means country and carrier p_nom_per_cc = (pd.DataFrame( {'p_nom': linexpr((1, get_var(n, 'Generator', 'p_nom'))), 'country': gen_country, 'carrier': n.generators.carrier}) .dropna(subset=['p_nom']) .groupby(['country', 'carrier']).p_nom .apply(join_exprs)) minimum = agg_p_nom_minmax['min'].dropna() if not minimum.empty: minconstraint = define_constraints(n, p_nom_per_cc[minimum.index], '>=', minimum, 'agg_p_nom', 'min') maximum = agg_p_nom_minmax['max'].dropna() if not maximum.empty: maxconstraint = define_constraints(n, p_nom_per_cc[maximum.index], '<=', maximum, 'agg_p_nom', 'max')
def add_BAU_constraints(n, config): mincaps = pd.Series(config['electricity']['BAU_mincapacities']) lhs = (linexpr( (1, get_var(n, 'Generator', 'p_nom'))).groupby(n.generators.carrier).apply(join_exprs)) define_constraints(n, lhs, '>=', mincaps[lhs.index], 'Carrier', 'bau_mincaps')
def add_BAU_constraints(n, config): mincaps = pd.Series(config["electricity"]["BAU_mincapacities"]) lhs = (linexpr( (1, get_var(n, "Generator", "p_nom"))).groupby(n.generators.carrier).apply(join_exprs)) define_constraints(n, lhs, ">=", mincaps[lhs.index], "Carrier", "bau_mincaps")
def add_CCL_constraints(n, config): agg_p_nom_limits = config["electricity"].get("agg_p_nom_limits") try: agg_p_nom_minmax = pd.read_csv(agg_p_nom_limits, index_col=list(range(2))) except IOError: logger.exception("Need to specify the path to a .csv file containing " "aggregate capacity limits per country in " "config['electricity']['agg_p_nom_limit'].") logger.info("Adding per carrier generation capacity constraints for " "individual countries") gen_country = n.generators.bus.map(n.buses.country) # cc means country and carrier p_nom_per_cc = (pd.DataFrame({ "p_nom": linexpr((1, get_var(n, "Generator", "p_nom"))), "country": gen_country, "carrier": n.generators.carrier, }).dropna(subset=["p_nom"]).groupby(["country", "carrier"]).p_nom.apply(join_exprs)) minimum = agg_p_nom_minmax["min"].dropna() if not minimum.empty: minconstraint = define_constraints(n, p_nom_per_cc[minimum.index], ">=", minimum, "agg_p_nom", "min") maximum = agg_p_nom_minmax["max"].dropna() if not maximum.empty: maxconstraint = define_constraints(n, p_nom_per_cc[maximum.index], "<=", maximum, "agg_p_nom", "max")
def add_battery_constraints(n): nodes = n.buses.index[n.buses.carrier == "battery"] if nodes.empty or ('Link', 'p_nom') not in n.variables.index: return link_p_nom = get_var(n, "Link", "p_nom") lhs = linexpr((1,link_p_nom[nodes + " charger"]), (-n.links.loc[nodes + " discharger", "efficiency"].values, link_p_nom[nodes + " discharger"].values)) define_constraints(n, lhs, "=", 0, 'Link', 'charger_ratio')
def add_SAFE_constraints(n, config): peakdemand = (1. + config['electricity']['SAFE_reservemargin']) *\ n.loads_t.p_set.sum(axis=1).max() conv_techs = config['plotting']['conv_techs'] exist_conv_caps = n.generators.query('~p_nom_extendable & carrier in @conv_techs')\ .p_nom.sum() ext_gens_i = n.generators.query('carrier in @conv_techs & p_nom_extendable').index lhs = linexpr((1, get_var(n, 'Generator', 'p_nom')[ext_gens_i])).sum() rhs = peakdemand - exist_conv_caps define_constraints(n, lhs, '>=', rhs, 'Safe', 'mintotalcap')
def add_SAFE_constraints(n, config): peakdemand = (1.0 + config["electricity"]["SAFE_reservemargin"] ) * n.loads_t.p_set.sum(axis=1).max() conv_techs = config["plotting"]["conv_techs"] exist_conv_caps = n.generators.query( "~p_nom_extendable & carrier in @conv_techs").p_nom.sum() ext_gens_i = n.generators.query( "carrier in @conv_techs & p_nom_extendable").index lhs = linexpr((1, get_var(n, "Generator", "p_nom")[ext_gens_i])).sum() rhs = peakdemand - exist_conv_caps define_constraints(n, lhs, ">=", rhs, "Safe", "mintotalcap")