def constraint_maximum_emissions(model, dict_values, dict_model=None): r""" Resulting in an energy system adhering to a maximum amount of emissions. Parameters ---------- model: :oemof-solph: <oemof.solph.model> Model to which constraint is added. dict_values: dict All simulation parameters dict_model: None To match other constraint function's format Notes ----- Tested with: - D2.test_constraint_maximum_emissions() """ maximum_emissions = dict_values[CONSTRAINTS][MAXIMUM_EMISSIONS][VALUE] if maximum_emissions is not None: # Updates the model with the constraint for maximum amount of emissions constraints.emission_limit(model, limit=maximum_emissions) logging.info("Added maximum emission constraint.") answer = model else: answer = None return answer
def constraint_maximum_emissions(model, dict_values): r""" Resulting in an energy system adhering to a maximum amount of emissions. Parameters ---------- model: :oemof-solph: <oemof.solph.model> Model to which constraint is added. dict_values: dict All simulation parameters Notes ----- Tested with: - D2.test_constraint_maximum_emissions() """ maximum_emissions = dict_values[CONSTRAINTS][MAXIMUM_EMISSIONS][VALUE] # Updates the model with the constraint for maximum amount of emissions constraints.emission_limit(model, limit=maximum_emissions) logging.info("Added maximum emission constraint.") return model
variable_costs=10, emission_factor=0.01, actual_value=[0.1, 0.2, 0.3], fixed=True)})) energysystem.add(solph.Source(label='gas-source', outputs={ bel: solph.Flow(variable_costs=10, emission_factor=0.2)})) energysystem.add(solph.Transformer( label="pp_gas", inputs={ bgas: solph.Flow()}, outputs={ bel: solph.Flow(nominal_value=200)}, conversion_factors={ bel: 0.58})) model = solph.Model(energysystem) # add the emission constraint constraints.emission_limit(model, limit=100) model.total_emissions.pprint() model.solve() print(model.total_emissions())
def compute(datapackage, solver="gurobi"): """ """ config = Scenario.from_path( os.path.join("scenarios", datapackage + ".toml") ) emission_limit = config["scenario"].get("co2_limit") temporal_resolution = config.get("model", {}).get("temporal_resolution", 1) datapackage_dir = os.path.join("datapackages", datapackage) # create results path scenario_path = os.path.join("results", datapackage) if not os.path.exists(scenario_path): os.makedirs(scenario_path) output_path = os.path.join(scenario_path, "output") if not os.path.exists(output_path): os.makedirs(output_path) # copy package either aggregated or the original one (only data!) if temporal_resolution > 1: logging.info("Aggregating for temporal aggregation ... ") path = aggregation.temporal_skip( os.path.join(datapackage_dir, "datapackage.json"), temporal_resolution, path=scenario_path, name="input", ) else: path = processing.copy_datapackage( os.path.join(datapackage_dir, "datapackage.json"), os.path.abspath(os.path.join(scenario_path, "input")), subset="data", ) es = EnergySystem.from_datapackage( os.path.join(path, "datapackage.json"), attributemap={}, typemap=facades.TYPEMAP, ) m = Model(es) if emission_limit is not None: constraints.emission_limit(m, limit=emission_limit) flows = {} for (i, o) in m.flows: if hasattr(m.flows[i, o], "emission_factor"): flows[(i, o)] = m.flows[i, o] # add emission as expression to model BUSES = [b for b in es.nodes if isinstance(b, Bus)] def emission_rule(m, b, t): expr = sum( m.flow[inflow, outflow, t] * m.timeincrement[t] * getattr(flows[inflow, outflow], "emission_factor", 0) for (inflow, outflow) in flows if outflow is b ) return expr m.emissions = Expression(BUSES, m.TIMESTEPS, rule=emission_rule) m.receive_duals() m.solve(solver) m.results = m.results() pp.write_results(m, output_path) modelstats = outputlib.processing.meta_results(m) modelstats.pop("solver") modelstats["problem"].pop("Sense") # TODO: This is not model stats -> move somewhere else! modelstats["temporal_resolution"] = temporal_resolution modelstats["emission_limit"] = emission_limit with open(os.path.join(scenario_path, "modelstats.json"), "w") as outfile: json.dump(modelstats, outfile, indent=4) supply_sum = ( pp.supply_results( results=m.results, es=m.es, bus=[b.label for b in es.nodes if isinstance(b, Bus)], types=[ "dispatchable", "volatile", "conversion", "backpressure", "extraction", # "storage", "reservoir", ], ) # .clip(0) .sum().reset_index() ) supply_sum["from"] = supply_sum.apply( lambda x: "-".join(x["from"].label.split("-")[1::]), axis=1 ) supply_sum.drop("type", axis=1, inplace=True) supply_sum = ( supply_sum.set_index(["from", "to"]).unstack("from") / 1e6 * temporal_resolution ) supply_sum.columns = supply_sum.columns.droplevel(0) summary = supply_sum # pd.concat([supply_sum, excess_share], axis=1) ## grid imports = pd.DataFrame() link_results = pp.component_results(m.es, m.results).get("link") link_results.to_csv( os.path.join(scenario_path, "output", "transmission.csv") ) for b in [b.label for b in es.nodes if isinstance(b, Bus)]: if link_results is not None and m.es.groups[b] in list( link_results.columns.levels[0] ): ex = link_results.loc[ :, (m.es.groups[b], slice(None), "flow") ].sum(axis=1) im = link_results.loc[ :, (slice(None), m.es.groups[b], "flow") ].sum(axis=1) net_import = im - ex net_import.name = m.es.groups[b] imports = pd.concat([imports, net_import], axis=1) summary["total_supply"] = summary.sum(axis=1) summary["RE-supply"] = ( summary["wind-onshore"] + summary["wind-offshore"] + summary["biomass-st"] + summary["hydro-ror"] + summary["hydro-reservoir"] + summary["solar-pv"] ) if "other-res" in summary: summary["RE-supply"] += summary["other-res"] summary["RE-share"] = summary["RE-supply"] / summary["total_supply"] summary["import"] = imports[imports > 0].sum() / 1e6 * temporal_resolution summary["export"] = imports[imports < 0].sum() / 1e6 * temporal_resolution summary.to_csv(os.path.join(scenario_path, "summary.csv")) emissions = ( pd.Series({key: value() for key, value in m.emissions.items()}) .unstack() .T ) emissions.to_csv(os.path.join(scenario_path, "emissions.csv"))