diff --git a/examples/get_costs_example/get_costs.py b/examples/get_costs_example/get_costs.py new file mode 100644 index 000000000..09dd1cd1d --- /dev/null +++ b/examples/get_costs_example/get_costs.py @@ -0,0 +1,223 @@ +# -*- coding: utf-8 -*- +r""" +General description +------------------- +Example that shows how to use of the processing methods get_set_costs_from_lpfile, time_dependent_values_as_dataframe and time_independent_values_as_dataframe. + +The methods are combined to get the actual caused costs per timestep and the caused scalar costs e.g. invest-costs + +The energysystem is copied from the exampel generic_invest_limit + +There are two supply chains. The energy systems looks like that: + +.. code-block:: text + + bus_a_0 bus_a_1 + | | + source_a_0 --->|---> trafo_a --->|--->demand_a + | + source_a_1--->| + | + + bus_b_0 bus_b_1 + | | + source_b_0 --->|---> trafo_b --->|--->demand_b + | + source_b_1--->| + | + +Everything is identical - the costs for the sources, the demand, the efficiency +of the Converter. And both Converter have an investment at the output. +The source '\*_1' is in both cases very expensive, so that +a investment is probably done in the converter. +Now, both investments share a third resource, which is called "space" in this +example. (This could be anything, and you could use as many additional +resources as you want.) And this resource is limited. In this case, every +converter capacity unit, which might be installed, needs 2 space for +'trafo a', and 1 space per installed capacity for 'trafo b'. +And the total space is limited to 24. +See what happens, have fun ;) + +Code +---- +Download source code: :download:`example_generic_invest.py ` + +.. dropdown:: Click to display code + + .. literalinclude:: /../examples/generic_invest_limit/example_generic_invest.py + :language: python + :lines: 62- + +Installation requirements +------------------------- +This example requires oemof.solph (v0.5.x), install by: + +.. code:: bash + + pip install oemof.solph[examples] + +License +------- +Johannes Röder + +`MIT license `_ +""" + +import logging +import os + +from oemof import solph +from oemof.solph import _experimental_processing + + +def main(): + data = [0, 15, 30, 35, 20, 25, 27, 10, 5, 2, 15, 40, 20, 0, 0] + + # create an energy system + idx = solph.create_time_index(2020, number=len(data)) + es = solph.EnergySystem(timeindex=idx, infer_last_interval=False) + + # Parameter: costs for the sources + c_0 = 10 + c_1 = 100 + + epc_invest = 500 + + # commodity a + bus_a_0 = solph.Bus(label="bus_a_0") + bus_a_1 = solph.Bus(label="bus_a_1") + es.add(bus_a_0, bus_a_1) + + es.add( + solph.components.Source( + label="source_a_0", + outputs={bus_a_0: solph.Flow(variable_costs=c_0)}, + ) + ) + + es.add( + solph.components.Source( + label="source_a_1", + outputs={bus_a_1: solph.Flow(variable_costs=c_1)}, + ) + ) + + es.add( + solph.components.Sink( + label="demand_a", + inputs={bus_a_1: solph.Flow(fix=data, nominal_value=1)}, + ) + ) + + # commodity b + bus_b_0 = solph.Bus(label="bus_b_0") + bus_b_1 = solph.Bus(label="bus_b_1") + es.add(bus_b_0, bus_b_1) + es.add( + solph.components.Source( + label="source_b_0", + outputs={bus_b_0: solph.Flow(variable_costs=data)}, + ) + ) + + es.add( + solph.components.Source( + label="source_b_1", + outputs={bus_b_1: solph.Flow(variable_costs=c_1)}, + ) + ) + + es.add( + solph.components.Sink( + label="demand_b", + inputs={bus_b_1: solph.Flow(fix=data, nominal_value=1)}, + ) + ) + + # Converter a + es.add( + solph.components.Converter( + label="trafo_a", + inputs={bus_a_0: solph.Flow()}, + outputs={ + bus_a_1: solph.Flow( + nominal_value=solph.Investment( + ep_costs=epc_invest, custom_attributes={"space": 2} + ) + ) + }, + conversion_factors={bus_a_1: 0.8}, + ) + ) + + # Converter b + es.add( + solph.components.Converter( + label="trafo_b", + inputs={bus_b_0: solph.Flow()}, + outputs={ + bus_b_1: solph.Flow( + nominal_value=solph.Investment( + ep_costs=epc_invest, custom_attributes={"space": 1} + ) + ) + }, + conversion_factors={bus_a_1: 0.8}, + ) + ) + + # create an optimization problem and solve it + om = solph.Model(es) + + # add constraint for generic investment limit + om = solph.constraints.additional_investment_flow_limit( + om, "space", limit=24 + ) + + # export lp file + filename = os.path.join( + solph.helpers.extend_basic_path("lp_files"), "GenericInvest.lp" + ) + logging.info("Store lp-file in {0}.".format(filename)) + om.write(filename, io_options={"symbolic_solver_labels": True}) + + # solve model + om.solve(solver="cbc", solve_kwargs={"tee": True}) + + # to get the set costs use the method get_set_costs_from_lpfile + + set_tdc, set_tic = _experimental_processing.get_set_costs_from_lpfile(filename, om) + + # create result object. The last timestep has to be removed + results = solph.processing.results(om, remove_last_time_point=True) + + # now get the timedependent optimized values as dataframe + + dataframe_tdv = _experimental_processing.time_dependent_values_as_dataframe( + results + ) + + # now get the timeindependent optimized values as dataframe + dataframe_tiv = _experimental_processing.time_independent_values_as_dataframe( + results + ) + + # filter values with costs + + td_intersect = set_tdc.columns.intersection(dataframe_tdv.columns) + ti_intersect = set_tic.columns.intersection(dataframe_tiv.columns) + + # calculate costs + time_dependent_costs = dataframe_tdv[td_intersect] * set_tdc[td_intersect] + + time_independent_costs = ( + dataframe_tiv[ti_intersect] * set_tic[ti_intersect] + ) + + print(time_dependent_costs) + + print(time_independent_costs) + + +if __name__ == "__main__": + main() diff --git a/src/oemof/solph/_experimental_processing.py b/src/oemof/solph/_experimental_processing.py new file mode 100644 index 000000000..5b7982282 --- /dev/null +++ b/src/oemof/solph/_experimental_processing.py @@ -0,0 +1,271 @@ +# -*- coding: utf-8 -*- + +"""Modules for providing a convenient data structure + for solph cost and results. + +Information about the possible usage is provided within the examples. + +SPDX-FileCopyrightText: Uwe Krien +SPDX-FileCopyrightText: Simon Hilpert +SPDX-FileCopyrightText: Cord Kaldemeyer +SPDX-FileCopyrightText: Stephan Günther +SPDX-FileCopyrightText: henhuy +SPDX-FileCopyrightText: Johannes Kochems +SPDX-FileCopyrightText: Patrik Schönfeldt + +SPDX-License-Identifier: MIT + +""" + +import re + +import numpy as np +import pandas as pd + + +def get_set_costs_from_lpfile(filename, model, timeindex=[]): + """returns costs dependent and independent of time based on lp file + + Parameters + ---------- + filename: path + file direction of lp file of model + model : solph.Model + solved oemof model + timeindex: datetime + regarded timeindex, otherwise timeindex get from the model + + Returns + ------- + Dataframes: + time_depenent_costs, time_independent_costs + """ + + with open(filename) as f: + contents = f.read() + rows = ( + contents.split("objective:")[1] + .split("s.t.")[0] + .replace("+", "") + .split("\n") + ) + + data_frame = pd.DataFrame(i.split(" ") for i in rows).dropna() + data_frame.columns = ["cost", "name"] + data_frame["cost"] = data_frame["cost"].astype("float") + + # calculate time depenedent costs + # filter time dependent values and drop invest values + data_frame_time_dependent = data_frame[ + data_frame.name.isin( + [ + nam + for nam in data_frame.name + if re.findall("_+[0-9]+_", nam) + and not re.findall("invest", nam) + ] + ) + ].copy() + + # get the timevalue + + if len(timeindex) > 0: + tmindex = timeindex + + else: + tmindex = model.es.timeindex[:-1] + try: + data_frame_time_dependent["time"] = [ + tmindex[ + int( + re.search(r"(\(.+\))", i) + .group() + .split(")")[0] + .split("_")[-1] + ) + ] + for i in data_frame_time_dependent.name + ] + except ValueError: + error_message = ( + "Timeindex has to be given as parameter " + + "or has to be set within the model" + ) + raise ValueError(error_message) + + flow_costs = data_frame_time_dependent[ + data_frame_time_dependent.name.str.match("flow") + ].copy() + flow_costs["unique_name"] = [ + re.sub(r"_\d+_\d+\)", "", re.search(r"\(.+\)", i).group()).replace( + "(", "" + ) + for i in flow_costs.name + ] + + non_flow_costs = data_frame_time_dependent[ + data_frame_time_dependent.name.str.match(r"^((?!flow).)*$") + ].copy() + non_flow_costs["unique_name"] = [ + re.sub(r"_\d+_\d+\)", "", name.split("(")[1]) + + "_" + + name.split("(")[0].split("_", 1)[1] + for name in non_flow_costs.name + ] + + data_time_dependent = pd.concat([non_flow_costs, flow_costs]) + + pivot_data = pd.pivot( + data_time_dependent, + index=["time"], + columns="unique_name", + values="cost", + ) + + time_dependent_costs_all_pivot = pivot_data.replace(np.nan, 0) + + # calculation time independent costs + + # remove time independent data + + time_independent_costs = data_frame[ + data_frame.name.isin( + [ + nam + for nam in data_frame.name + if not re.findall(r"_+[0-9]+_", nam) + ] + ) + ].copy() + + # renaming (remove unnecessary strings) + time_independent_costs.loc[:, "name"] = [ + name.split("_", 1)[1].split("(")[0] + + "_" + + name.split("(")[1].split(")")[0] + for name in time_independent_costs.name + ] + + # invest costs + + invest_costs = data_frame[ + data_frame.name.isin( + [nam for nam in data_frame.name if re.findall("invest", nam)] + ) + ].copy() + + # renaming (remove unnecessary strings) + invest_costs.loc[:, "name"] = [ + re.sub(r"_\d+\)", "", re.search(r"invest+\(.+\)", i).group()).replace( + "(", "_" + ) + for i in invest_costs.name + ] + + time_independent_costs = pd.concat([time_independent_costs, invest_costs]) + time_independent_costs = time_independent_costs.reindex( + columns=["cost", "name"] + ) + + # transform to dataframe with name as columns + trans_tic = time_independent_costs.T + trans_tic.columns = trans_tic.loc["name"] + trans_tic = ( + trans_tic.reset_index().rename_axis(None, axis=1).drop("index", axis=1) + ) + trans_tic = trans_tic.drop([1]) + return time_dependent_costs_all_pivot, trans_tic + + +def time_dependent_values_as_dataframe(results, timeindex=[]): + """returns timedependent results as dataframe + + Parameters + ---------- + results : results + results from oemof.solph.processing + method results(remove_last_time_point=True) + Note: remove_last_time_point must be set to True! + timeindex: datetime + add timeindex manually, otherwise timeindex is numerated + + Returns + ------- + DataFrame + """ + + # get flows of energysystem + flows = [x for x in results.keys() if x[1] is not None] + if len(timeindex) > 0: + tmindex = timeindex + else: + tmindex = results[flows[0]]["sequences"].index + dataframe = {"time": tmindex} + for flow in flows: + name = str(flow[0].label + "_" + str(flow[1].label)) + component = results[flow]["sequences"] + for attribute in component: + tmp = getattr(component, attribute) + tmp2 = getattr(tmp, "values") + dataframe.update({str(name): list(tmp2)}) + + # get nodes of energysystem + nodes = [x for x in results.keys() if x[1] is None] + + for node in nodes: + name = node[0].label + component = results[node]["sequences"] + for attribute in component: + tmp = getattr(component, attribute) + tmp2 = getattr(tmp, "values") + dataframe.update({str(name + "_" + attribute): list(tmp2)}) + + dataframe = pd.DataFrame(dataframe) + dataframe = dataframe.set_index("time") + return dataframe + + +def time_independent_values_as_dataframe(results, timeindex=[]): + """ + + get scalar values of nodes as dataframe + + + Parameters + ---------- + oemof_results : results + results from oemof.solph.processing method results() + + Returns + ------- + Dataframe + """ + nodes = [x for x in results.keys() if x[1] is None] + + data_scalar = {} + + for node in nodes: + # get the scalars of the component + scalar = results[node]["scalars"] + for num, value in enumerate(scalar.axes[0].values): + data_scalar.update( + {value + "_" + str(node[0].label): [scalar.T[num]]} + ) + + # get flows of energysystem + flows = [x for x in results.keys() if x[1] is not None] + + for flow in flows: + # get the scalars of the component + scalar = results[flow]["scalars"] + for num, value in enumerate(scalar.axes[0].values): + name = ( + str(value) + + "_" + + str(flow[0].label) + + "_" + + str(flow[1].label) + ) + data_scalar.update({name: [scalar.T[num]]}) + + return pd.DataFrame.from_dict(data_scalar) diff --git a/tests/lp_files/costs_from_lpfile.lp b/tests/lp_files/costs_from_lpfile.lp new file mode 100644 index 000000000..d9fad64c4 --- /dev/null +++ b/tests/lp_files/costs_from_lpfile.lp @@ -0,0 +1,1259 @@ +\* Source Pyomo model name=Model *\ + +min +objective: ++0.5 InvestmentFlowBlock_invest(diesel_b_el1_0) ++3 flow(b_el1_storage_0_0) ++3 flow(b_el1_storage_0_1) ++3 flow(b_el1_storage_0_2) ++3 flow(b_el1_storage_0_3) ++3 flow(b_el1_storage_0_4) ++3 flow(b_el1_storage_0_5) ++3 flow(b_el1_storage_0_6) ++3 flow(b_el1_storage_0_7) ++3 flow(b_el1_storage_0_8) ++3 flow(b_el1_storage_0_9) ++3 flow(b_el1_storage_0_10) ++3 flow(b_el1_storage_0_11) ++3 flow(b_el1_storage_0_12) ++3 flow(b_el1_storage_0_13) ++3 flow(b_el1_storage_0_14) ++3 flow(b_el1_storage_0_15) ++3 flow(b_el1_storage_0_16) ++3 flow(b_el1_storage_0_17) ++3 flow(b_el1_storage_0_18) ++3 flow(b_el1_storage_0_19) ++3 flow(b_el1_storage_0_20) ++3 flow(b_el1_storage_0_21) ++3 flow(b_el1_storage_0_22) ++3 flow(b_el1_storage_0_23) ++2 flow(b_diesel_diesel_0_0) ++2 flow(b_diesel_diesel_0_1) ++2 flow(b_diesel_diesel_0_2) ++2 flow(b_diesel_diesel_0_3) ++2 flow(b_diesel_diesel_0_4) ++2 flow(b_diesel_diesel_0_5) ++2 flow(b_diesel_diesel_0_6) ++2 flow(b_diesel_diesel_0_7) ++2 flow(b_diesel_diesel_0_8) ++2 flow(b_diesel_diesel_0_9) ++2 flow(b_diesel_diesel_0_10) ++2 flow(b_diesel_diesel_0_11) ++2 flow(b_diesel_diesel_0_12) ++2 flow(b_diesel_diesel_0_13) ++2 flow(b_diesel_diesel_0_14) ++2 flow(b_diesel_diesel_0_15) ++2 flow(b_diesel_diesel_0_16) ++2 flow(b_diesel_diesel_0_17) ++2 flow(b_diesel_diesel_0_18) ++2 flow(b_diesel_diesel_0_19) ++2 flow(b_diesel_diesel_0_20) ++2 flow(b_diesel_diesel_0_21) ++2 flow(b_diesel_diesel_0_22) ++2 flow(b_diesel_diesel_0_23) ++1 flow(diesel_b_el1_0_0) ++1 flow(diesel_b_el1_0_1) ++1 flow(diesel_b_el1_0_2) ++1 flow(diesel_b_el1_0_3) ++1 flow(diesel_b_el1_0_4) ++1 flow(diesel_b_el1_0_5) ++1 flow(diesel_b_el1_0_6) ++1 flow(diesel_b_el1_0_7) ++1 flow(diesel_b_el1_0_8) ++1 flow(diesel_b_el1_0_9) ++1 flow(diesel_b_el1_0_10) ++1 flow(diesel_b_el1_0_11) ++1 flow(diesel_b_el1_0_12) ++1 flow(diesel_b_el1_0_13) ++1 flow(diesel_b_el1_0_14) ++1 flow(diesel_b_el1_0_15) ++1 flow(diesel_b_el1_0_16) ++1 flow(diesel_b_el1_0_17) ++1 flow(diesel_b_el1_0_18) ++1 flow(diesel_b_el1_0_19) ++1 flow(diesel_b_el1_0_20) ++1 flow(diesel_b_el1_0_21) ++1 flow(diesel_b_el1_0_22) ++1 flow(diesel_b_el1_0_23) ++2.5 flow(storage_b_el2_0_0) ++2.5 flow(storage_b_el2_0_1) ++2.5 flow(storage_b_el2_0_2) ++2.5 flow(storage_b_el2_0_3) ++2.5 flow(storage_b_el2_0_4) ++2.5 flow(storage_b_el2_0_5) ++2.5 flow(storage_b_el2_0_6) ++2.5 flow(storage_b_el2_0_7) ++2.5 flow(storage_b_el2_0_8) ++2.5 flow(storage_b_el2_0_9) ++2.5 flow(storage_b_el2_0_10) ++2.5 flow(storage_b_el2_0_11) ++2.5 flow(storage_b_el2_0_12) ++2.5 flow(storage_b_el2_0_13) ++2.5 flow(storage_b_el2_0_14) ++2.5 flow(storage_b_el2_0_15) ++2.5 flow(storage_b_el2_0_16) ++2.5 flow(storage_b_el2_0_17) ++2.5 flow(storage_b_el2_0_18) ++2.5 flow(storage_b_el2_0_19) ++2.5 flow(storage_b_el2_0_20) ++2.5 flow(storage_b_el2_0_21) ++2.5 flow(storage_b_el2_0_22) ++2.5 flow(storage_b_el2_0_23) ++0.4 GenericInvestmentStorageBlock_invest(storage_0) + +s.t. + +c_e_BusBlock_balance(b_el1_0_0)_: +-1 flow(b_el1_storage_0_0) ++1 flow(diesel_b_el1_0_0) += 0 + +c_e_BusBlock_balance(b_el1_0_1)_: +-1 flow(b_el1_storage_0_1) ++1 flow(diesel_b_el1_0_1) += 0 + +c_e_BusBlock_balance(b_el1_0_2)_: +-1 flow(b_el1_storage_0_2) ++1 flow(diesel_b_el1_0_2) += 0 + +c_e_BusBlock_balance(b_el1_0_3)_: +-1 flow(b_el1_storage_0_3) ++1 flow(diesel_b_el1_0_3) += 0 + +c_e_BusBlock_balance(b_el1_0_4)_: +-1 flow(b_el1_storage_0_4) ++1 flow(diesel_b_el1_0_4) += 0 + +c_e_BusBlock_balance(b_el1_0_5)_: +-1 flow(b_el1_storage_0_5) ++1 flow(diesel_b_el1_0_5) += 0 + +c_e_BusBlock_balance(b_el1_0_6)_: +-1 flow(b_el1_storage_0_6) ++1 flow(diesel_b_el1_0_6) += 0 + +c_e_BusBlock_balance(b_el1_0_7)_: +-1 flow(b_el1_storage_0_7) ++1 flow(diesel_b_el1_0_7) += 0 + +c_e_BusBlock_balance(b_el1_0_8)_: +-1 flow(b_el1_storage_0_8) ++1 flow(diesel_b_el1_0_8) += 0 + +c_e_BusBlock_balance(b_el1_0_9)_: +-1 flow(b_el1_storage_0_9) ++1 flow(diesel_b_el1_0_9) += 0 + +c_e_BusBlock_balance(b_el1_0_10)_: +-1 flow(b_el1_storage_0_10) ++1 flow(diesel_b_el1_0_10) += 0 + +c_e_BusBlock_balance(b_el1_0_11)_: +-1 flow(b_el1_storage_0_11) ++1 flow(diesel_b_el1_0_11) += 0 + +c_e_BusBlock_balance(b_el1_0_12)_: +-1 flow(b_el1_storage_0_12) ++1 flow(diesel_b_el1_0_12) += 0 + +c_e_BusBlock_balance(b_el1_0_13)_: +-1 flow(b_el1_storage_0_13) ++1 flow(diesel_b_el1_0_13) += 0 + +c_e_BusBlock_balance(b_el1_0_14)_: +-1 flow(b_el1_storage_0_14) ++1 flow(diesel_b_el1_0_14) += 0 + +c_e_BusBlock_balance(b_el1_0_15)_: +-1 flow(b_el1_storage_0_15) ++1 flow(diesel_b_el1_0_15) += 0 + +c_e_BusBlock_balance(b_el1_0_16)_: +-1 flow(b_el1_storage_0_16) ++1 flow(diesel_b_el1_0_16) += 0 + +c_e_BusBlock_balance(b_el1_0_17)_: +-1 flow(b_el1_storage_0_17) ++1 flow(diesel_b_el1_0_17) += 0 + +c_e_BusBlock_balance(b_el1_0_18)_: +-1 flow(b_el1_storage_0_18) ++1 flow(diesel_b_el1_0_18) += 0 + +c_e_BusBlock_balance(b_el1_0_19)_: +-1 flow(b_el1_storage_0_19) ++1 flow(diesel_b_el1_0_19) += 0 + +c_e_BusBlock_balance(b_el1_0_20)_: +-1 flow(b_el1_storage_0_20) ++1 flow(diesel_b_el1_0_20) += 0 + +c_e_BusBlock_balance(b_el1_0_21)_: +-1 flow(b_el1_storage_0_21) ++1 flow(diesel_b_el1_0_21) += 0 + +c_e_BusBlock_balance(b_el1_0_22)_: +-1 flow(b_el1_storage_0_22) ++1 flow(diesel_b_el1_0_22) += 0 + +c_e_BusBlock_balance(b_el1_0_23)_: +-1 flow(b_el1_storage_0_23) ++1 flow(diesel_b_el1_0_23) += 0 + +c_e_BusBlock_balance(b_el2_0_0)_: ++1 flow(storage_b_el2_0_0) += 0.0 + +c_e_BusBlock_balance(b_el2_0_1)_: ++1 flow(storage_b_el2_0_1) += 100 + +c_e_BusBlock_balance(b_el2_0_2)_: ++1 flow(storage_b_el2_0_2) += 100 + +c_e_BusBlock_balance(b_el2_0_3)_: ++1 flow(storage_b_el2_0_3) += 100 + +c_e_BusBlock_balance(b_el2_0_4)_: ++1 flow(storage_b_el2_0_4) += 100 + +c_e_BusBlock_balance(b_el2_0_5)_: ++1 flow(storage_b_el2_0_5) += 100 + +c_e_BusBlock_balance(b_el2_0_6)_: ++1 flow(storage_b_el2_0_6) += 100 + +c_e_BusBlock_balance(b_el2_0_7)_: ++1 flow(storage_b_el2_0_7) += 100 + +c_e_BusBlock_balance(b_el2_0_8)_: ++1 flow(storage_b_el2_0_8) += 100 + +c_e_BusBlock_balance(b_el2_0_9)_: ++1 flow(storage_b_el2_0_9) += 100 + +c_e_BusBlock_balance(b_el2_0_10)_: ++1 flow(storage_b_el2_0_10) += 100 + +c_e_BusBlock_balance(b_el2_0_11)_: ++1 flow(storage_b_el2_0_11) += 100 + +c_e_BusBlock_balance(b_el2_0_12)_: ++1 flow(storage_b_el2_0_12) += 100 + +c_e_BusBlock_balance(b_el2_0_13)_: ++1 flow(storage_b_el2_0_13) += 100 + +c_e_BusBlock_balance(b_el2_0_14)_: ++1 flow(storage_b_el2_0_14) += 100 + +c_e_BusBlock_balance(b_el2_0_15)_: ++1 flow(storage_b_el2_0_15) += 100 + +c_e_BusBlock_balance(b_el2_0_16)_: ++1 flow(storage_b_el2_0_16) += 100 + +c_e_BusBlock_balance(b_el2_0_17)_: ++1 flow(storage_b_el2_0_17) += 100 + +c_e_BusBlock_balance(b_el2_0_18)_: ++1 flow(storage_b_el2_0_18) += 100 + +c_e_BusBlock_balance(b_el2_0_19)_: ++1 flow(storage_b_el2_0_19) += 100 + +c_e_BusBlock_balance(b_el2_0_20)_: ++1 flow(storage_b_el2_0_20) += 100 + +c_e_BusBlock_balance(b_el2_0_21)_: ++1 flow(storage_b_el2_0_21) += 100 + +c_e_BusBlock_balance(b_el2_0_22)_: ++1 flow(storage_b_el2_0_22) += 100 + +c_e_BusBlock_balance(b_el2_0_23)_: ++1 flow(storage_b_el2_0_23) += 100 + +c_e_ConverterBlock_relation(diesel_b_diesel_b_el1_0_0)_: ++2 flow(b_diesel_diesel_0_0) +-1 flow(diesel_b_el1_0_0) += 0 + +c_e_ConverterBlock_relation(diesel_b_diesel_b_el1_0_1)_: ++2 flow(b_diesel_diesel_0_1) +-1 flow(diesel_b_el1_0_1) += 0 + +c_e_ConverterBlock_relation(diesel_b_diesel_b_el1_0_2)_: ++2 flow(b_diesel_diesel_0_2) +-1 flow(diesel_b_el1_0_2) += 0 + +c_e_ConverterBlock_relation(diesel_b_diesel_b_el1_0_3)_: ++2 flow(b_diesel_diesel_0_3) +-1 flow(diesel_b_el1_0_3) += 0 + +c_e_ConverterBlock_relation(diesel_b_diesel_b_el1_0_4)_: ++2 flow(b_diesel_diesel_0_4) +-1 flow(diesel_b_el1_0_4) += 0 + +c_e_ConverterBlock_relation(diesel_b_diesel_b_el1_0_5)_: ++2 flow(b_diesel_diesel_0_5) +-1 flow(diesel_b_el1_0_5) += 0 + +c_e_ConverterBlock_relation(diesel_b_diesel_b_el1_0_6)_: ++2 flow(b_diesel_diesel_0_6) +-1 flow(diesel_b_el1_0_6) += 0 + +c_e_ConverterBlock_relation(diesel_b_diesel_b_el1_0_7)_: ++2 flow(b_diesel_diesel_0_7) +-1 flow(diesel_b_el1_0_7) += 0 + +c_e_ConverterBlock_relation(diesel_b_diesel_b_el1_0_8)_: ++2 flow(b_diesel_diesel_0_8) +-1 flow(diesel_b_el1_0_8) += 0 + +c_e_ConverterBlock_relation(diesel_b_diesel_b_el1_0_9)_: ++2 flow(b_diesel_diesel_0_9) +-1 flow(diesel_b_el1_0_9) += 0 + +c_e_ConverterBlock_relation(diesel_b_diesel_b_el1_0_10)_: ++2 flow(b_diesel_diesel_0_10) +-1 flow(diesel_b_el1_0_10) += 0 + +c_e_ConverterBlock_relation(diesel_b_diesel_b_el1_0_11)_: ++2 flow(b_diesel_diesel_0_11) +-1 flow(diesel_b_el1_0_11) += 0 + +c_e_ConverterBlock_relation(diesel_b_diesel_b_el1_0_12)_: ++2 flow(b_diesel_diesel_0_12) +-1 flow(diesel_b_el1_0_12) += 0 + +c_e_ConverterBlock_relation(diesel_b_diesel_b_el1_0_13)_: ++2 flow(b_diesel_diesel_0_13) +-1 flow(diesel_b_el1_0_13) += 0 + +c_e_ConverterBlock_relation(diesel_b_diesel_b_el1_0_14)_: ++2 flow(b_diesel_diesel_0_14) +-1 flow(diesel_b_el1_0_14) += 0 + +c_e_ConverterBlock_relation(diesel_b_diesel_b_el1_0_15)_: ++2 flow(b_diesel_diesel_0_15) +-1 flow(diesel_b_el1_0_15) += 0 + +c_e_ConverterBlock_relation(diesel_b_diesel_b_el1_0_16)_: ++2 flow(b_diesel_diesel_0_16) +-1 flow(diesel_b_el1_0_16) += 0 + +c_e_ConverterBlock_relation(diesel_b_diesel_b_el1_0_17)_: ++2 flow(b_diesel_diesel_0_17) +-1 flow(diesel_b_el1_0_17) += 0 + +c_e_ConverterBlock_relation(diesel_b_diesel_b_el1_0_18)_: ++2 flow(b_diesel_diesel_0_18) +-1 flow(diesel_b_el1_0_18) += 0 + +c_e_ConverterBlock_relation(diesel_b_diesel_b_el1_0_19)_: ++2 flow(b_diesel_diesel_0_19) +-1 flow(diesel_b_el1_0_19) += 0 + +c_e_ConverterBlock_relation(diesel_b_diesel_b_el1_0_20)_: ++2 flow(b_diesel_diesel_0_20) +-1 flow(diesel_b_el1_0_20) += 0 + +c_e_ConverterBlock_relation(diesel_b_diesel_b_el1_0_21)_: ++2 flow(b_diesel_diesel_0_21) +-1 flow(diesel_b_el1_0_21) += 0 + +c_e_ConverterBlock_relation(diesel_b_diesel_b_el1_0_22)_: ++2 flow(b_diesel_diesel_0_22) +-1 flow(diesel_b_el1_0_22) += 0 + +c_e_ConverterBlock_relation(diesel_b_diesel_b_el1_0_23)_: ++2 flow(b_diesel_diesel_0_23) +-1 flow(diesel_b_el1_0_23) += 0 + +c_e_InvestmentFlowBlock_total_rule(b_el1_storage_0)_: +-1 InvestmentFlowBlock_invest(b_el1_storage_0) ++1 InvestmentFlowBlock_total(b_el1_storage_0) += 0 + +c_e_InvestmentFlowBlock_total_rule(storage_b_el2_0)_: +-1 InvestmentFlowBlock_invest(storage_b_el2_0) ++1 InvestmentFlowBlock_total(storage_b_el2_0) += 0 + +c_e_InvestmentFlowBlock_total_rule(diesel_b_el1_0)_: +-1 InvestmentFlowBlock_invest(diesel_b_el1_0) ++1 InvestmentFlowBlock_total(diesel_b_el1_0) += 0 + +c_u_InvestmentFlowBlock_max(b_el1_storage_0_0)_: ++1 flow(b_el1_storage_0_0) +-1 InvestmentFlowBlock_total(b_el1_storage_0) +<= 0 + +c_u_InvestmentFlowBlock_max(b_el1_storage_0_1)_: ++1 flow(b_el1_storage_0_1) +-1 InvestmentFlowBlock_total(b_el1_storage_0) +<= 0 + +c_u_InvestmentFlowBlock_max(b_el1_storage_0_2)_: ++1 flow(b_el1_storage_0_2) +-1 InvestmentFlowBlock_total(b_el1_storage_0) +<= 0 + +c_u_InvestmentFlowBlock_max(b_el1_storage_0_3)_: ++1 flow(b_el1_storage_0_3) +-1 InvestmentFlowBlock_total(b_el1_storage_0) +<= 0 + +c_u_InvestmentFlowBlock_max(b_el1_storage_0_4)_: ++1 flow(b_el1_storage_0_4) +-1 InvestmentFlowBlock_total(b_el1_storage_0) +<= 0 + +c_u_InvestmentFlowBlock_max(b_el1_storage_0_5)_: ++1 flow(b_el1_storage_0_5) +-1 InvestmentFlowBlock_total(b_el1_storage_0) +<= 0 + +c_u_InvestmentFlowBlock_max(b_el1_storage_0_6)_: ++1 flow(b_el1_storage_0_6) +-1 InvestmentFlowBlock_total(b_el1_storage_0) +<= 0 + +c_u_InvestmentFlowBlock_max(b_el1_storage_0_7)_: ++1 flow(b_el1_storage_0_7) +-1 InvestmentFlowBlock_total(b_el1_storage_0) +<= 0 + +c_u_InvestmentFlowBlock_max(b_el1_storage_0_8)_: ++1 flow(b_el1_storage_0_8) +-1 InvestmentFlowBlock_total(b_el1_storage_0) +<= 0 + +c_u_InvestmentFlowBlock_max(b_el1_storage_0_9)_: ++1 flow(b_el1_storage_0_9) +-1 InvestmentFlowBlock_total(b_el1_storage_0) +<= 0 + +c_u_InvestmentFlowBlock_max(b_el1_storage_0_10)_: ++1 flow(b_el1_storage_0_10) +-1 InvestmentFlowBlock_total(b_el1_storage_0) +<= 0 + +c_u_InvestmentFlowBlock_max(b_el1_storage_0_11)_: ++1 flow(b_el1_storage_0_11) +-1 InvestmentFlowBlock_total(b_el1_storage_0) +<= 0 + +c_u_InvestmentFlowBlock_max(b_el1_storage_0_12)_: ++1 flow(b_el1_storage_0_12) +-1 InvestmentFlowBlock_total(b_el1_storage_0) +<= 0 + +c_u_InvestmentFlowBlock_max(b_el1_storage_0_13)_: ++1 flow(b_el1_storage_0_13) +-1 InvestmentFlowBlock_total(b_el1_storage_0) +<= 0 + +c_u_InvestmentFlowBlock_max(b_el1_storage_0_14)_: ++1 flow(b_el1_storage_0_14) +-1 InvestmentFlowBlock_total(b_el1_storage_0) +<= 0 + +c_u_InvestmentFlowBlock_max(b_el1_storage_0_15)_: ++1 flow(b_el1_storage_0_15) +-1 InvestmentFlowBlock_total(b_el1_storage_0) +<= 0 + +c_u_InvestmentFlowBlock_max(b_el1_storage_0_16)_: ++1 flow(b_el1_storage_0_16) +-1 InvestmentFlowBlock_total(b_el1_storage_0) +<= 0 + +c_u_InvestmentFlowBlock_max(b_el1_storage_0_17)_: ++1 flow(b_el1_storage_0_17) +-1 InvestmentFlowBlock_total(b_el1_storage_0) +<= 0 + +c_u_InvestmentFlowBlock_max(b_el1_storage_0_18)_: ++1 flow(b_el1_storage_0_18) +-1 InvestmentFlowBlock_total(b_el1_storage_0) +<= 0 + +c_u_InvestmentFlowBlock_max(b_el1_storage_0_19)_: ++1 flow(b_el1_storage_0_19) +-1 InvestmentFlowBlock_total(b_el1_storage_0) +<= 0 + +c_u_InvestmentFlowBlock_max(b_el1_storage_0_20)_: ++1 flow(b_el1_storage_0_20) +-1 InvestmentFlowBlock_total(b_el1_storage_0) +<= 0 + +c_u_InvestmentFlowBlock_max(b_el1_storage_0_21)_: ++1 flow(b_el1_storage_0_21) +-1 InvestmentFlowBlock_total(b_el1_storage_0) +<= 0 + +c_u_InvestmentFlowBlock_max(b_el1_storage_0_22)_: ++1 flow(b_el1_storage_0_22) +-1 InvestmentFlowBlock_total(b_el1_storage_0) +<= 0 + +c_u_InvestmentFlowBlock_max(b_el1_storage_0_23)_: ++1 flow(b_el1_storage_0_23) +-1 InvestmentFlowBlock_total(b_el1_storage_0) +<= 0 + +c_u_InvestmentFlowBlock_max(storage_b_el2_0_0)_: ++1 flow(storage_b_el2_0_0) +-1 InvestmentFlowBlock_total(storage_b_el2_0) +<= 0 + +c_u_InvestmentFlowBlock_max(storage_b_el2_0_1)_: ++1 flow(storage_b_el2_0_1) +-1 InvestmentFlowBlock_total(storage_b_el2_0) +<= 0 + +c_u_InvestmentFlowBlock_max(storage_b_el2_0_2)_: ++1 flow(storage_b_el2_0_2) +-1 InvestmentFlowBlock_total(storage_b_el2_0) +<= 0 + +c_u_InvestmentFlowBlock_max(storage_b_el2_0_3)_: ++1 flow(storage_b_el2_0_3) +-1 InvestmentFlowBlock_total(storage_b_el2_0) +<= 0 + +c_u_InvestmentFlowBlock_max(storage_b_el2_0_4)_: ++1 flow(storage_b_el2_0_4) +-1 InvestmentFlowBlock_total(storage_b_el2_0) +<= 0 + +c_u_InvestmentFlowBlock_max(storage_b_el2_0_5)_: ++1 flow(storage_b_el2_0_5) +-1 InvestmentFlowBlock_total(storage_b_el2_0) +<= 0 + +c_u_InvestmentFlowBlock_max(storage_b_el2_0_6)_: ++1 flow(storage_b_el2_0_6) +-1 InvestmentFlowBlock_total(storage_b_el2_0) +<= 0 + +c_u_InvestmentFlowBlock_max(storage_b_el2_0_7)_: ++1 flow(storage_b_el2_0_7) +-1 InvestmentFlowBlock_total(storage_b_el2_0) +<= 0 + +c_u_InvestmentFlowBlock_max(storage_b_el2_0_8)_: ++1 flow(storage_b_el2_0_8) +-1 InvestmentFlowBlock_total(storage_b_el2_0) +<= 0 + +c_u_InvestmentFlowBlock_max(storage_b_el2_0_9)_: ++1 flow(storage_b_el2_0_9) +-1 InvestmentFlowBlock_total(storage_b_el2_0) +<= 0 + +c_u_InvestmentFlowBlock_max(storage_b_el2_0_10)_: ++1 flow(storage_b_el2_0_10) +-1 InvestmentFlowBlock_total(storage_b_el2_0) +<= 0 + +c_u_InvestmentFlowBlock_max(storage_b_el2_0_11)_: ++1 flow(storage_b_el2_0_11) +-1 InvestmentFlowBlock_total(storage_b_el2_0) +<= 0 + +c_u_InvestmentFlowBlock_max(storage_b_el2_0_12)_: ++1 flow(storage_b_el2_0_12) +-1 InvestmentFlowBlock_total(storage_b_el2_0) +<= 0 + +c_u_InvestmentFlowBlock_max(storage_b_el2_0_13)_: ++1 flow(storage_b_el2_0_13) +-1 InvestmentFlowBlock_total(storage_b_el2_0) +<= 0 + +c_u_InvestmentFlowBlock_max(storage_b_el2_0_14)_: ++1 flow(storage_b_el2_0_14) +-1 InvestmentFlowBlock_total(storage_b_el2_0) +<= 0 + +c_u_InvestmentFlowBlock_max(storage_b_el2_0_15)_: ++1 flow(storage_b_el2_0_15) +-1 InvestmentFlowBlock_total(storage_b_el2_0) +<= 0 + +c_u_InvestmentFlowBlock_max(storage_b_el2_0_16)_: ++1 flow(storage_b_el2_0_16) +-1 InvestmentFlowBlock_total(storage_b_el2_0) +<= 0 + +c_u_InvestmentFlowBlock_max(storage_b_el2_0_17)_: ++1 flow(storage_b_el2_0_17) +-1 InvestmentFlowBlock_total(storage_b_el2_0) +<= 0 + +c_u_InvestmentFlowBlock_max(storage_b_el2_0_18)_: ++1 flow(storage_b_el2_0_18) +-1 InvestmentFlowBlock_total(storage_b_el2_0) +<= 0 + +c_u_InvestmentFlowBlock_max(storage_b_el2_0_19)_: ++1 flow(storage_b_el2_0_19) +-1 InvestmentFlowBlock_total(storage_b_el2_0) +<= 0 + +c_u_InvestmentFlowBlock_max(storage_b_el2_0_20)_: ++1 flow(storage_b_el2_0_20) +-1 InvestmentFlowBlock_total(storage_b_el2_0) +<= 0 + +c_u_InvestmentFlowBlock_max(storage_b_el2_0_21)_: ++1 flow(storage_b_el2_0_21) +-1 InvestmentFlowBlock_total(storage_b_el2_0) +<= 0 + +c_u_InvestmentFlowBlock_max(storage_b_el2_0_22)_: ++1 flow(storage_b_el2_0_22) +-1 InvestmentFlowBlock_total(storage_b_el2_0) +<= 0 + +c_u_InvestmentFlowBlock_max(storage_b_el2_0_23)_: ++1 flow(storage_b_el2_0_23) +-1 InvestmentFlowBlock_total(storage_b_el2_0) +<= 0 + +c_u_InvestmentFlowBlock_max(diesel_b_el1_0_0)_: ++1 flow(diesel_b_el1_0_0) +-1 InvestmentFlowBlock_total(diesel_b_el1_0) +<= 0 + +c_u_InvestmentFlowBlock_max(diesel_b_el1_0_1)_: ++1 flow(diesel_b_el1_0_1) +-1 InvestmentFlowBlock_total(diesel_b_el1_0) +<= 0 + +c_u_InvestmentFlowBlock_max(diesel_b_el1_0_2)_: ++1 flow(diesel_b_el1_0_2) +-1 InvestmentFlowBlock_total(diesel_b_el1_0) +<= 0 + +c_u_InvestmentFlowBlock_max(diesel_b_el1_0_3)_: ++1 flow(diesel_b_el1_0_3) +-1 InvestmentFlowBlock_total(diesel_b_el1_0) +<= 0 + +c_u_InvestmentFlowBlock_max(diesel_b_el1_0_4)_: ++1 flow(diesel_b_el1_0_4) +-1 InvestmentFlowBlock_total(diesel_b_el1_0) +<= 0 + +c_u_InvestmentFlowBlock_max(diesel_b_el1_0_5)_: ++1 flow(diesel_b_el1_0_5) +-1 InvestmentFlowBlock_total(diesel_b_el1_0) +<= 0 + +c_u_InvestmentFlowBlock_max(diesel_b_el1_0_6)_: ++1 flow(diesel_b_el1_0_6) +-1 InvestmentFlowBlock_total(diesel_b_el1_0) +<= 0 + +c_u_InvestmentFlowBlock_max(diesel_b_el1_0_7)_: ++1 flow(diesel_b_el1_0_7) +-1 InvestmentFlowBlock_total(diesel_b_el1_0) +<= 0 + +c_u_InvestmentFlowBlock_max(diesel_b_el1_0_8)_: ++1 flow(diesel_b_el1_0_8) +-1 InvestmentFlowBlock_total(diesel_b_el1_0) +<= 0 + +c_u_InvestmentFlowBlock_max(diesel_b_el1_0_9)_: ++1 flow(diesel_b_el1_0_9) +-1 InvestmentFlowBlock_total(diesel_b_el1_0) +<= 0 + +c_u_InvestmentFlowBlock_max(diesel_b_el1_0_10)_: ++1 flow(diesel_b_el1_0_10) +-1 InvestmentFlowBlock_total(diesel_b_el1_0) +<= 0 + +c_u_InvestmentFlowBlock_max(diesel_b_el1_0_11)_: ++1 flow(diesel_b_el1_0_11) +-1 InvestmentFlowBlock_total(diesel_b_el1_0) +<= 0 + +c_u_InvestmentFlowBlock_max(diesel_b_el1_0_12)_: ++1 flow(diesel_b_el1_0_12) +-1 InvestmentFlowBlock_total(diesel_b_el1_0) +<= 0 + +c_u_InvestmentFlowBlock_max(diesel_b_el1_0_13)_: ++1 flow(diesel_b_el1_0_13) +-1 InvestmentFlowBlock_total(diesel_b_el1_0) +<= 0 + +c_u_InvestmentFlowBlock_max(diesel_b_el1_0_14)_: ++1 flow(diesel_b_el1_0_14) +-1 InvestmentFlowBlock_total(diesel_b_el1_0) +<= 0 + +c_u_InvestmentFlowBlock_max(diesel_b_el1_0_15)_: ++1 flow(diesel_b_el1_0_15) +-1 InvestmentFlowBlock_total(diesel_b_el1_0) +<= 0 + +c_u_InvestmentFlowBlock_max(diesel_b_el1_0_16)_: ++1 flow(diesel_b_el1_0_16) +-1 InvestmentFlowBlock_total(diesel_b_el1_0) +<= 0 + +c_u_InvestmentFlowBlock_max(diesel_b_el1_0_17)_: ++1 flow(diesel_b_el1_0_17) +-1 InvestmentFlowBlock_total(diesel_b_el1_0) +<= 0 + +c_u_InvestmentFlowBlock_max(diesel_b_el1_0_18)_: ++1 flow(diesel_b_el1_0_18) +-1 InvestmentFlowBlock_total(diesel_b_el1_0) +<= 0 + +c_u_InvestmentFlowBlock_max(diesel_b_el1_0_19)_: ++1 flow(diesel_b_el1_0_19) +-1 InvestmentFlowBlock_total(diesel_b_el1_0) +<= 0 + +c_u_InvestmentFlowBlock_max(diesel_b_el1_0_20)_: ++1 flow(diesel_b_el1_0_20) +-1 InvestmentFlowBlock_total(diesel_b_el1_0) +<= 0 + +c_u_InvestmentFlowBlock_max(diesel_b_el1_0_21)_: ++1 flow(diesel_b_el1_0_21) +-1 InvestmentFlowBlock_total(diesel_b_el1_0) +<= 0 + +c_u_InvestmentFlowBlock_max(diesel_b_el1_0_22)_: ++1 flow(diesel_b_el1_0_22) +-1 InvestmentFlowBlock_total(diesel_b_el1_0) +<= 0 + +c_u_InvestmentFlowBlock_max(diesel_b_el1_0_23)_: ++1 flow(diesel_b_el1_0_23) +-1 InvestmentFlowBlock_total(diesel_b_el1_0) +<= 0 + +c_e_GenericInvestmentStorageBlock_total_storage_rule(storage_0)_: +-1 GenericInvestmentStorageBlock_invest(storage_0) ++1 GenericInvestmentStorageBlock_total(storage_0) += 0 + +c_e_GenericInvestmentStorageBlock_init_content_fix(storage)_: ++1 GenericInvestmentStorageBlock_init_content(storage) += 0 + +c_e_GenericInvestmentStorageBlock_balance_first(storage)_: +-1 flow(b_el1_storage_0_0) ++1.25 flow(storage_b_el2_0_0) +-1 GenericInvestmentStorageBlock_init_content(storage) ++1 GenericInvestmentStorageBlock_storage_content(storage_0) += 0 + +c_e_GenericInvestmentStorageBlock_balance(storage_0_1)_: +-1 flow(b_el1_storage_0_1) ++1.25 flow(storage_b_el2_0_1) +-1 GenericInvestmentStorageBlock_storage_content(storage_0) ++1 GenericInvestmentStorageBlock_storage_content(storage_1) += 0 + +c_e_GenericInvestmentStorageBlock_balance(storage_0_2)_: +-1 flow(b_el1_storage_0_2) ++1.25 flow(storage_b_el2_0_2) +-1 GenericInvestmentStorageBlock_storage_content(storage_1) ++1 GenericInvestmentStorageBlock_storage_content(storage_2) += 0 + +c_e_GenericInvestmentStorageBlock_balance(storage_0_3)_: +-1 flow(b_el1_storage_0_3) ++1.25 flow(storage_b_el2_0_3) +-1 GenericInvestmentStorageBlock_storage_content(storage_2) ++1 GenericInvestmentStorageBlock_storage_content(storage_3) += 0 + +c_e_GenericInvestmentStorageBlock_balance(storage_0_4)_: +-1 flow(b_el1_storage_0_4) ++1.25 flow(storage_b_el2_0_4) +-1 GenericInvestmentStorageBlock_storage_content(storage_3) ++1 GenericInvestmentStorageBlock_storage_content(storage_4) += 0 + +c_e_GenericInvestmentStorageBlock_balance(storage_0_5)_: +-1 flow(b_el1_storage_0_5) ++1.25 flow(storage_b_el2_0_5) +-1 GenericInvestmentStorageBlock_storage_content(storage_4) ++1 GenericInvestmentStorageBlock_storage_content(storage_5) += 0 + +c_e_GenericInvestmentStorageBlock_balance(storage_0_6)_: +-1 flow(b_el1_storage_0_6) ++1.25 flow(storage_b_el2_0_6) +-1 GenericInvestmentStorageBlock_storage_content(storage_5) ++1 GenericInvestmentStorageBlock_storage_content(storage_6) += 0 + +c_e_GenericInvestmentStorageBlock_balance(storage_0_7)_: +-1 flow(b_el1_storage_0_7) ++1.25 flow(storage_b_el2_0_7) +-1 GenericInvestmentStorageBlock_storage_content(storage_6) ++1 GenericInvestmentStorageBlock_storage_content(storage_7) += 0 + +c_e_GenericInvestmentStorageBlock_balance(storage_0_8)_: +-1 flow(b_el1_storage_0_8) ++1.25 flow(storage_b_el2_0_8) +-1 GenericInvestmentStorageBlock_storage_content(storage_7) ++1 GenericInvestmentStorageBlock_storage_content(storage_8) += 0 + +c_e_GenericInvestmentStorageBlock_balance(storage_0_9)_: +-1 flow(b_el1_storage_0_9) ++1.25 flow(storage_b_el2_0_9) +-1 GenericInvestmentStorageBlock_storage_content(storage_8) ++1 GenericInvestmentStorageBlock_storage_content(storage_9) += 0 + +c_e_GenericInvestmentStorageBlock_balance(storage_0_10)_: +-1 flow(b_el1_storage_0_10) ++1.25 flow(storage_b_el2_0_10) +-1 GenericInvestmentStorageBlock_storage_content(storage_9) ++1 GenericInvestmentStorageBlock_storage_content(storage_10) += 0 + +c_e_GenericInvestmentStorageBlock_balance(storage_0_11)_: +-1 flow(b_el1_storage_0_11) ++1.25 flow(storage_b_el2_0_11) +-1 GenericInvestmentStorageBlock_storage_content(storage_10) ++1 GenericInvestmentStorageBlock_storage_content(storage_11) += 0 + +c_e_GenericInvestmentStorageBlock_balance(storage_0_12)_: +-1 flow(b_el1_storage_0_12) ++1.25 flow(storage_b_el2_0_12) +-1 GenericInvestmentStorageBlock_storage_content(storage_11) ++1 GenericInvestmentStorageBlock_storage_content(storage_12) += 0 + +c_e_GenericInvestmentStorageBlock_balance(storage_0_13)_: +-1 flow(b_el1_storage_0_13) ++1.25 flow(storage_b_el2_0_13) +-1 GenericInvestmentStorageBlock_storage_content(storage_12) ++1 GenericInvestmentStorageBlock_storage_content(storage_13) += 0 + +c_e_GenericInvestmentStorageBlock_balance(storage_0_14)_: +-1 flow(b_el1_storage_0_14) ++1.25 flow(storage_b_el2_0_14) +-1 GenericInvestmentStorageBlock_storage_content(storage_13) ++1 GenericInvestmentStorageBlock_storage_content(storage_14) += 0 + +c_e_GenericInvestmentStorageBlock_balance(storage_0_15)_: +-1 flow(b_el1_storage_0_15) ++1.25 flow(storage_b_el2_0_15) +-1 GenericInvestmentStorageBlock_storage_content(storage_14) ++1 GenericInvestmentStorageBlock_storage_content(storage_15) += 0 + +c_e_GenericInvestmentStorageBlock_balance(storage_0_16)_: +-1 flow(b_el1_storage_0_16) ++1.25 flow(storage_b_el2_0_16) +-1 GenericInvestmentStorageBlock_storage_content(storage_15) ++1 GenericInvestmentStorageBlock_storage_content(storage_16) += 0 + +c_e_GenericInvestmentStorageBlock_balance(storage_0_17)_: +-1 flow(b_el1_storage_0_17) ++1.25 flow(storage_b_el2_0_17) +-1 GenericInvestmentStorageBlock_storage_content(storage_16) ++1 GenericInvestmentStorageBlock_storage_content(storage_17) += 0 + +c_e_GenericInvestmentStorageBlock_balance(storage_0_18)_: +-1 flow(b_el1_storage_0_18) ++1.25 flow(storage_b_el2_0_18) +-1 GenericInvestmentStorageBlock_storage_content(storage_17) ++1 GenericInvestmentStorageBlock_storage_content(storage_18) += 0 + +c_e_GenericInvestmentStorageBlock_balance(storage_0_19)_: +-1 flow(b_el1_storage_0_19) ++1.25 flow(storage_b_el2_0_19) +-1 GenericInvestmentStorageBlock_storage_content(storage_18) ++1 GenericInvestmentStorageBlock_storage_content(storage_19) += 0 + +c_e_GenericInvestmentStorageBlock_balance(storage_0_20)_: +-1 flow(b_el1_storage_0_20) ++1.25 flow(storage_b_el2_0_20) +-1 GenericInvestmentStorageBlock_storage_content(storage_19) ++1 GenericInvestmentStorageBlock_storage_content(storage_20) += 0 + +c_e_GenericInvestmentStorageBlock_balance(storage_0_21)_: +-1 flow(b_el1_storage_0_21) ++1.25 flow(storage_b_el2_0_21) +-1 GenericInvestmentStorageBlock_storage_content(storage_20) ++1 GenericInvestmentStorageBlock_storage_content(storage_21) += 0 + +c_e_GenericInvestmentStorageBlock_balance(storage_0_22)_: +-1 flow(b_el1_storage_0_22) ++1.25 flow(storage_b_el2_0_22) +-1 GenericInvestmentStorageBlock_storage_content(storage_21) ++1 GenericInvestmentStorageBlock_storage_content(storage_22) += 0 + +c_e_GenericInvestmentStorageBlock_balance(storage_0_23)_: +-1 flow(b_el1_storage_0_23) ++1.25 flow(storage_b_el2_0_23) +-1 GenericInvestmentStorageBlock_storage_content(storage_22) ++1 GenericInvestmentStorageBlock_storage_content(storage_23) += 0 + +c_e_GenericInvestmentStorageBlock_balanced_cstr(storage)_: +-1 GenericInvestmentStorageBlock_init_content(storage) ++1 GenericInvestmentStorageBlock_storage_content(storage_23) += 0 + +c_e_GenericInvestmentStorageBlock_storage_capacity_inflow(storage_0)_: ++1 InvestmentFlowBlock_total(b_el1_storage_0) +-0.16666666666666666 GenericInvestmentStorageBlock_total(storage_0) += 0 + +c_e_GenericInvestmentStorageBlock_storage_capacity_outflow(storage_0)_: ++1 InvestmentFlowBlock_total(storage_b_el2_0) +-0.16666666666666666 GenericInvestmentStorageBlock_total(storage_0) += 0 + +c_u_GenericInvestmentStorageBlock_max_storage_content(storage_0_0)_: +-1 GenericInvestmentStorageBlock_total(storage_0) ++1 GenericInvestmentStorageBlock_storage_content(storage_0) +<= 0 + +c_u_GenericInvestmentStorageBlock_max_storage_content(storage_0_1)_: +-1 GenericInvestmentStorageBlock_total(storage_0) ++1 GenericInvestmentStorageBlock_storage_content(storage_1) +<= 0 + +c_u_GenericInvestmentStorageBlock_max_storage_content(storage_0_2)_: +-1 GenericInvestmentStorageBlock_total(storage_0) ++1 GenericInvestmentStorageBlock_storage_content(storage_2) +<= 0 + +c_u_GenericInvestmentStorageBlock_max_storage_content(storage_0_3)_: +-1 GenericInvestmentStorageBlock_total(storage_0) ++1 GenericInvestmentStorageBlock_storage_content(storage_3) +<= 0 + +c_u_GenericInvestmentStorageBlock_max_storage_content(storage_0_4)_: +-1 GenericInvestmentStorageBlock_total(storage_0) ++1 GenericInvestmentStorageBlock_storage_content(storage_4) +<= 0 + +c_u_GenericInvestmentStorageBlock_max_storage_content(storage_0_5)_: +-1 GenericInvestmentStorageBlock_total(storage_0) ++1 GenericInvestmentStorageBlock_storage_content(storage_5) +<= 0 + +c_u_GenericInvestmentStorageBlock_max_storage_content(storage_0_6)_: +-1 GenericInvestmentStorageBlock_total(storage_0) ++1 GenericInvestmentStorageBlock_storage_content(storage_6) +<= 0 + +c_u_GenericInvestmentStorageBlock_max_storage_content(storage_0_7)_: +-1 GenericInvestmentStorageBlock_total(storage_0) ++1 GenericInvestmentStorageBlock_storage_content(storage_7) +<= 0 + +c_u_GenericInvestmentStorageBlock_max_storage_content(storage_0_8)_: +-1 GenericInvestmentStorageBlock_total(storage_0) ++1 GenericInvestmentStorageBlock_storage_content(storage_8) +<= 0 + +c_u_GenericInvestmentStorageBlock_max_storage_content(storage_0_9)_: +-1 GenericInvestmentStorageBlock_total(storage_0) ++1 GenericInvestmentStorageBlock_storage_content(storage_9) +<= 0 + +c_u_GenericInvestmentStorageBlock_max_storage_content(storage_0_10)_: +-1 GenericInvestmentStorageBlock_total(storage_0) ++1 GenericInvestmentStorageBlock_storage_content(storage_10) +<= 0 + +c_u_GenericInvestmentStorageBlock_max_storage_content(storage_0_11)_: +-1 GenericInvestmentStorageBlock_total(storage_0) ++1 GenericInvestmentStorageBlock_storage_content(storage_11) +<= 0 + +c_u_GenericInvestmentStorageBlock_max_storage_content(storage_0_12)_: +-1 GenericInvestmentStorageBlock_total(storage_0) ++1 GenericInvestmentStorageBlock_storage_content(storage_12) +<= 0 + +c_u_GenericInvestmentStorageBlock_max_storage_content(storage_0_13)_: +-1 GenericInvestmentStorageBlock_total(storage_0) ++1 GenericInvestmentStorageBlock_storage_content(storage_13) +<= 0 + +c_u_GenericInvestmentStorageBlock_max_storage_content(storage_0_14)_: +-1 GenericInvestmentStorageBlock_total(storage_0) ++1 GenericInvestmentStorageBlock_storage_content(storage_14) +<= 0 + +c_u_GenericInvestmentStorageBlock_max_storage_content(storage_0_15)_: +-1 GenericInvestmentStorageBlock_total(storage_0) ++1 GenericInvestmentStorageBlock_storage_content(storage_15) +<= 0 + +c_u_GenericInvestmentStorageBlock_max_storage_content(storage_0_16)_: +-1 GenericInvestmentStorageBlock_total(storage_0) ++1 GenericInvestmentStorageBlock_storage_content(storage_16) +<= 0 + +c_u_GenericInvestmentStorageBlock_max_storage_content(storage_0_17)_: +-1 GenericInvestmentStorageBlock_total(storage_0) ++1 GenericInvestmentStorageBlock_storage_content(storage_17) +<= 0 + +c_u_GenericInvestmentStorageBlock_max_storage_content(storage_0_18)_: +-1 GenericInvestmentStorageBlock_total(storage_0) ++1 GenericInvestmentStorageBlock_storage_content(storage_18) +<= 0 + +c_u_GenericInvestmentStorageBlock_max_storage_content(storage_0_19)_: +-1 GenericInvestmentStorageBlock_total(storage_0) ++1 GenericInvestmentStorageBlock_storage_content(storage_19) +<= 0 + +c_u_GenericInvestmentStorageBlock_max_storage_content(storage_0_20)_: +-1 GenericInvestmentStorageBlock_total(storage_0) ++1 GenericInvestmentStorageBlock_storage_content(storage_20) +<= 0 + +c_u_GenericInvestmentStorageBlock_max_storage_content(storage_0_21)_: +-1 GenericInvestmentStorageBlock_total(storage_0) ++1 GenericInvestmentStorageBlock_storage_content(storage_21) +<= 0 + +c_u_GenericInvestmentStorageBlock_max_storage_content(storage_0_22)_: +-1 GenericInvestmentStorageBlock_total(storage_0) ++1 GenericInvestmentStorageBlock_storage_content(storage_22) +<= 0 + +c_u_GenericInvestmentStorageBlock_max_storage_content(storage_0_23)_: +-1 GenericInvestmentStorageBlock_total(storage_0) ++1 GenericInvestmentStorageBlock_storage_content(storage_23) +<= 0 + +bounds + 0 <= InvestmentFlowBlock_invest(b_el1_storage_0) <= +inf + 0 <= InvestmentFlowBlock_invest(storage_b_el2_0) <= +inf + 0 <= InvestmentFlowBlock_invest(diesel_b_el1_0) <= +inf + 0 <= flow(b_el1_storage_0_0) <= +inf + 0 <= flow(b_el1_storage_0_1) <= +inf + 0 <= flow(b_el1_storage_0_2) <= +inf + 0 <= flow(b_el1_storage_0_3) <= +inf + 0 <= flow(b_el1_storage_0_4) <= +inf + 0 <= flow(b_el1_storage_0_5) <= +inf + 0 <= flow(b_el1_storage_0_6) <= +inf + 0 <= flow(b_el1_storage_0_7) <= +inf + 0 <= flow(b_el1_storage_0_8) <= +inf + 0 <= flow(b_el1_storage_0_9) <= +inf + 0 <= flow(b_el1_storage_0_10) <= +inf + 0 <= flow(b_el1_storage_0_11) <= +inf + 0 <= flow(b_el1_storage_0_12) <= +inf + 0 <= flow(b_el1_storage_0_13) <= +inf + 0 <= flow(b_el1_storage_0_14) <= +inf + 0 <= flow(b_el1_storage_0_15) <= +inf + 0 <= flow(b_el1_storage_0_16) <= +inf + 0 <= flow(b_el1_storage_0_17) <= +inf + 0 <= flow(b_el1_storage_0_18) <= +inf + 0 <= flow(b_el1_storage_0_19) <= +inf + 0 <= flow(b_el1_storage_0_20) <= +inf + 0 <= flow(b_el1_storage_0_21) <= +inf + 0 <= flow(b_el1_storage_0_22) <= +inf + 0 <= flow(b_el1_storage_0_23) <= +inf + 0 <= flow(b_diesel_diesel_0_0) <= +inf + 0 <= flow(b_diesel_diesel_0_1) <= +inf + 0 <= flow(b_diesel_diesel_0_2) <= +inf + 0 <= flow(b_diesel_diesel_0_3) <= +inf + 0 <= flow(b_diesel_diesel_0_4) <= +inf + 0 <= flow(b_diesel_diesel_0_5) <= +inf + 0 <= flow(b_diesel_diesel_0_6) <= +inf + 0 <= flow(b_diesel_diesel_0_7) <= +inf + 0 <= flow(b_diesel_diesel_0_8) <= +inf + 0 <= flow(b_diesel_diesel_0_9) <= +inf + 0 <= flow(b_diesel_diesel_0_10) <= +inf + 0 <= flow(b_diesel_diesel_0_11) <= +inf + 0 <= flow(b_diesel_diesel_0_12) <= +inf + 0 <= flow(b_diesel_diesel_0_13) <= +inf + 0 <= flow(b_diesel_diesel_0_14) <= +inf + 0 <= flow(b_diesel_diesel_0_15) <= +inf + 0 <= flow(b_diesel_diesel_0_16) <= +inf + 0 <= flow(b_diesel_diesel_0_17) <= +inf + 0 <= flow(b_diesel_diesel_0_18) <= +inf + 0 <= flow(b_diesel_diesel_0_19) <= +inf + 0 <= flow(b_diesel_diesel_0_20) <= +inf + 0 <= flow(b_diesel_diesel_0_21) <= +inf + 0 <= flow(b_diesel_diesel_0_22) <= +inf + 0 <= flow(b_diesel_diesel_0_23) <= +inf + 0 <= flow(diesel_b_el1_0_0) <= +inf + 0 <= flow(diesel_b_el1_0_1) <= +inf + 0 <= flow(diesel_b_el1_0_2) <= +inf + 0 <= flow(diesel_b_el1_0_3) <= +inf + 0 <= flow(diesel_b_el1_0_4) <= +inf + 0 <= flow(diesel_b_el1_0_5) <= +inf + 0 <= flow(diesel_b_el1_0_6) <= +inf + 0 <= flow(diesel_b_el1_0_7) <= +inf + 0 <= flow(diesel_b_el1_0_8) <= +inf + 0 <= flow(diesel_b_el1_0_9) <= +inf + 0 <= flow(diesel_b_el1_0_10) <= +inf + 0 <= flow(diesel_b_el1_0_11) <= +inf + 0 <= flow(diesel_b_el1_0_12) <= +inf + 0 <= flow(diesel_b_el1_0_13) <= +inf + 0 <= flow(diesel_b_el1_0_14) <= +inf + 0 <= flow(diesel_b_el1_0_15) <= +inf + 0 <= flow(diesel_b_el1_0_16) <= +inf + 0 <= flow(diesel_b_el1_0_17) <= +inf + 0 <= flow(diesel_b_el1_0_18) <= +inf + 0 <= flow(diesel_b_el1_0_19) <= +inf + 0 <= flow(diesel_b_el1_0_20) <= +inf + 0 <= flow(diesel_b_el1_0_21) <= +inf + 0 <= flow(diesel_b_el1_0_22) <= +inf + 0 <= flow(diesel_b_el1_0_23) <= +inf + 0 <= flow(storage_b_el2_0_0) <= +inf + 0 <= flow(storage_b_el2_0_1) <= +inf + 0 <= flow(storage_b_el2_0_2) <= +inf + 0 <= flow(storage_b_el2_0_3) <= +inf + 0 <= flow(storage_b_el2_0_4) <= +inf + 0 <= flow(storage_b_el2_0_5) <= +inf + 0 <= flow(storage_b_el2_0_6) <= +inf + 0 <= flow(storage_b_el2_0_7) <= +inf + 0 <= flow(storage_b_el2_0_8) <= +inf + 0 <= flow(storage_b_el2_0_9) <= +inf + 0 <= flow(storage_b_el2_0_10) <= +inf + 0 <= flow(storage_b_el2_0_11) <= +inf + 0 <= flow(storage_b_el2_0_12) <= +inf + 0 <= flow(storage_b_el2_0_13) <= +inf + 0 <= flow(storage_b_el2_0_14) <= +inf + 0 <= flow(storage_b_el2_0_15) <= +inf + 0 <= flow(storage_b_el2_0_16) <= +inf + 0 <= flow(storage_b_el2_0_17) <= +inf + 0 <= flow(storage_b_el2_0_18) <= +inf + 0 <= flow(storage_b_el2_0_19) <= +inf + 0 <= flow(storage_b_el2_0_20) <= +inf + 0 <= flow(storage_b_el2_0_21) <= +inf + 0 <= flow(storage_b_el2_0_22) <= +inf + 0 <= flow(storage_b_el2_0_23) <= +inf + 0 <= GenericInvestmentStorageBlock_invest(storage_0) <= +inf + 0 <= InvestmentFlowBlock_total(b_el1_storage_0) <= +inf + 0 <= InvestmentFlowBlock_total(storage_b_el2_0) <= +inf + 0 <= InvestmentFlowBlock_total(diesel_b_el1_0) <= +inf + 0 <= GenericInvestmentStorageBlock_total(storage_0) <= +inf + 0 <= GenericInvestmentStorageBlock_init_content(storage) <= +inf + 0 <= GenericInvestmentStorageBlock_storage_content(storage_0) <= +inf + 0 <= GenericInvestmentStorageBlock_storage_content(storage_1) <= +inf + 0 <= GenericInvestmentStorageBlock_storage_content(storage_2) <= +inf + 0 <= GenericInvestmentStorageBlock_storage_content(storage_3) <= +inf + 0 <= GenericInvestmentStorageBlock_storage_content(storage_4) <= +inf + 0 <= GenericInvestmentStorageBlock_storage_content(storage_5) <= +inf + 0 <= GenericInvestmentStorageBlock_storage_content(storage_6) <= +inf + 0 <= GenericInvestmentStorageBlock_storage_content(storage_7) <= +inf + 0 <= GenericInvestmentStorageBlock_storage_content(storage_8) <= +inf + 0 <= GenericInvestmentStorageBlock_storage_content(storage_9) <= +inf + 0 <= GenericInvestmentStorageBlock_storage_content(storage_10) <= +inf + 0 <= GenericInvestmentStorageBlock_storage_content(storage_11) <= +inf + 0 <= GenericInvestmentStorageBlock_storage_content(storage_12) <= +inf + 0 <= GenericInvestmentStorageBlock_storage_content(storage_13) <= +inf + 0 <= GenericInvestmentStorageBlock_storage_content(storage_14) <= +inf + 0 <= GenericInvestmentStorageBlock_storage_content(storage_15) <= +inf + 0 <= GenericInvestmentStorageBlock_storage_content(storage_16) <= +inf + 0 <= GenericInvestmentStorageBlock_storage_content(storage_17) <= +inf + 0 <= GenericInvestmentStorageBlock_storage_content(storage_18) <= +inf + 0 <= GenericInvestmentStorageBlock_storage_content(storage_19) <= +inf + 0 <= GenericInvestmentStorageBlock_storage_content(storage_20) <= +inf + 0 <= GenericInvestmentStorageBlock_storage_content(storage_21) <= +inf + 0 <= GenericInvestmentStorageBlock_storage_content(storage_22) <= +inf + 0 <= GenericInvestmentStorageBlock_storage_content(storage_23) <= +inf +end diff --git a/tests/test_experimental_get_costs.py b/tests/test_experimental_get_costs.py new file mode 100644 index 000000000..060202cc3 --- /dev/null +++ b/tests/test_experimental_get_costs.py @@ -0,0 +1,129 @@ +# -*- coding: utf-8 - + +"""Tests the processing module of solph. + +This file is part of project oemof (github.com/oemof/oemof). It's copyrighted +by the contributors recorded in the version control history of the file, +available from its original location oemof/tests/test_py + +SPDX-License-Identifier: MIT +""" + +import os + +import pandas + +from oemof.solph import EnergySystem +from oemof.solph import Investment +from oemof.solph import Model +from oemof.solph import _experimental_processing +from oemof.solph import processing +from oemof.solph.buses import Bus +from oemof.solph.components import Converter +from oemof.solph.components import GenericStorage +from oemof.solph.components import Sink +from oemof.solph.flows import Flow + + +class TestParameterResult: + @classmethod + def setup_class(cls): + cls.period = 24 + cls.es = EnergySystem( + timeindex=pandas.date_range( + "2016-01-01", periods=cls.period, freq="H" + ), + infer_last_interval=True, + ) + + # BUSSES + b_el1 = Bus(label="b_el1") + b_el2 = Bus(label="b_el2") + b_diesel = Bus(label="b_diesel", balanced=False) + cls.es.add(b_el1, b_el2, b_diesel) + + # TEST DIESEL: + dg = Converter( + label="diesel", + inputs={b_diesel: Flow(variable_costs=2)}, + outputs={ + b_el1: Flow( + variable_costs=1, nominal_value=Investment(ep_costs=0.5) + ) + }, + conversion_factors={b_el1: 2}, + ) + + batt = GenericStorage( + label="storage", + inputs={b_el1: Flow(variable_costs=3)}, + outputs={b_el2: Flow(variable_costs=2.5)}, + loss_rate=0.00, + initial_storage_level=0, + invest_relation_input_capacity=1 / 6, + invest_relation_output_capacity=1 / 6, + inflow_conversion_factor=1, + outflow_conversion_factor=0.8, + nominal_storage_capacity=Investment(ep_costs=0.4), + ) + + cls.demand_values = [0.0] + [100] * 23 + demand = Sink( + label="demand_el", + inputs={b_el2: Flow(nominal_value=1, fix=cls.demand_values)}, + ) + cls.es.add(dg, batt, demand) + cls.om = Model(cls.es) + cls.om.receive_duals() + cls.om.solve() + cls.mod = Model(cls.es) + cls.mod.solve() + + def test_get_set_costs_from_lpfile(self): + self.om.write( + os.path.join( + os.getcwd(), "tests", "lp_files", "costs_from_lpfile.lp" + ), + io_options={"symbolic_solver_labels": True}, + ) + + lp_file = os.path.join( + os.getcwd(), "tests", "lp_files", "costs_from_lpfile.lp" + ) + tdc, tic = _experimental_processing.get_set_costs_from_lpfile( + lp_file, self.om + ) + + expected_values_tdc = { + "b_diesel_diesel": 2, + "diesel_b_el1": 1, + "b_el1_storage": 3, + "storage_b_el2": 2.5, + } + for name, val in expected_values_tdc.items(): + assert all(tdc[name] == val) + + period = 0 + expected_values_tic = { + "invest_diesel_b_el1_" + str(period): 0.5, + "invest_storage_" + str(period): 0.4, + } + for name, val in expected_values_tic.items(): + assert tic[name][0] == val + + def test_get_time_dependent_results_as_dataframe(self): + results = processing.results(self.om, remove_last_time_point=True) + results_dataframe = _experimental_processing.time_dependent_values_as_dataframe( + results + ) + + assert isinstance(results_dataframe, pandas.DataFrame) + + def test_time_indepentden_results_as_dataframe(self): + + results = processing.results(self.om, remove_last_time_point=True) + results_dataframe = _experimental_processing.time_independent_values_as_dataframe( + results + ) + + assert isinstance(results_dataframe, pandas.DataFrame)