From a0dd90a3f0f93552c4d111532c27d718cca9dde6 Mon Sep 17 00:00:00 2001 From: philipp235 <70669937+philipp235@users.noreply.github.com> Date: Thu, 3 Sep 2020 01:15:55 +0200 Subject: [PATCH 01/21] Add files via upload --- src/oemof/solph/1_system.py | 118 +++++++ src/oemof/solph/2_system.py | 110 ++++++ src/oemof/solph/analysing_toolbox_v1_8.py | 403 ++++++++++++++++++++++ src/oemof/solph/exnet.py | 120 +++++++ 4 files changed, 751 insertions(+) create mode 100644 src/oemof/solph/1_system.py create mode 100644 src/oemof/solph/2_system.py create mode 100644 src/oemof/solph/analysing_toolbox_v1_8.py create mode 100644 src/oemof/solph/exnet.py diff --git a/src/oemof/solph/1_system.py b/src/oemof/solph/1_system.py new file mode 100644 index 000000000..1ce7ef9ce --- /dev/null +++ b/src/oemof/solph/1_system.py @@ -0,0 +1,118 @@ +import oemof.solph as solph +from collections import namedtuple +import oemof.solph.exnet as ex +from oemof.outputlib import * +import math +import pandas as pd +import time +class Label(namedtuple('label', ['location','name', 'energy_carrier'])): + __slots__ = () + def __str__(self): + return '_'.join(map(str, self._asdict().values())) + +datetimeindex = pd.date_range('1/1/2017', periods=3, freq='H') + + + +es = solph.EnergySystem(timeindex=datetimeindex) +input_list=[] +input_list.append(-1) +i=0 +while i<101: + ob=i/100 + input_list.append(ob) + i=i+1 +output_list=[] +output_list.append(0) + +for ob in input_list: + if ob!=-1: + s=math.sqrt(ob) + output_list.append(s) + +##################################################################################################### +##################################################################################################### +##################################################################################################### + +b_gas1 = ex.GasBus(label=Label(name='b_gas1', location='C1', energy_carrier=''), slack=True) + +b_gas2 = ex.GasBus(label=Label(name='b_gas2', location='C2', energy_carrier='')) + +b_gas3 = ex.GasBus(label=Label(name='b_gas3', location='C1', energy_carrier='')) + + +gas_line_12=ex.GasLine(label='gas_line_12', + inputs={b_gas1: solph.Flow(nominal_value=200)}, + outputs={b_gas2: solph.Flow(nominal_value=200)}, + input_list=input_list, + output_list=output_list, + K_1=100, + conv_factor=0.99) + +gas_line_13=ex.GasLine(label='gas_line_13', + inputs={b_gas1: solph.Flow(nominal_value=200)}, + outputs={b_gas3: solph.Flow(nominal_value=200)}, + input_list=input_list, + output_list=output_list, + K_1=100, + conv_factor=0.99) + +gas_line_23=ex.GasLine(label='gas_line_23', + inputs={b_gas2: solph.Flow(nominal_value=200)}, + outputs={b_gas3: solph.Flow(nominal_value=200)}, + input_list=input_list, + output_list=output_list, + K_1=100, + conv_factor=0.99) + +gas_line_32=ex.GasLine(label='gas_line_32', + inputs={b_gas3: solph.Flow(nominal_value=200)}, + outputs={b_gas2: solph.Flow(nominal_value=200)}, + input_list=input_list, + output_list=output_list, + K_1=100, + conv_factor=0.99) + + +##################################################################################################### +##################################################################################################### +##################################################################################################### + +source_1=solph.Source(label='source_1', + outputs={b_gas1: solph.Flow(nominal_value=300)}) + + +sink_1=solph.Sink(label='sink_1', + inputs={b_gas2: solph.Flow(nominal_value=100, actual_value=[1,1,0], fixed=True)}) +# +sink_2=solph.Sink(label='sink_2', + inputs={b_gas3: solph.Flow(nominal_value=100, actual_value=[1,0,1], fixed=True)}) + + + +es.add(b_gas1) +es.add(b_gas2) +es.add(b_gas3) +es.add(gas_line_12) +es.add(gas_line_13) +es.add(gas_line_23) +es.add(gas_line_32) + +es.add(source_1) +es.add(sink_1) +es.add(sink_2) + +model = solph.Model(es) +model.solve(solver='cbc') +model.results() +results = processing.results(model) + + +locationssystem=[] +locationssystem.append('C1') + +from oemof.analysing_toolbox_v1_8 import * + +bk=blackbox(results, locationssystem, get_allpotentials=True) + + diff --git a/src/oemof/solph/2_system.py b/src/oemof/solph/2_system.py new file mode 100644 index 000000000..772b7cbd4 --- /dev/null +++ b/src/oemof/solph/2_system.py @@ -0,0 +1,110 @@ +import oemof.solph as solph +from collections import namedtuple +import oemof.solph.exnet as ex +import pandas as pd +from oemof.outputlib import * +import math + +class Label(namedtuple('label', ['location','name', 'energy_carrier'])): + __slots__ = () + def __str__(self): + return '_'.join(map(str, self._asdict().values())) + +datetimeindex = pd.date_range('1/1/2017', periods=3, freq='H') + +es = solph.EnergySystem(timeindex=datetimeindex) + +input_list=[] +input_list.append(-1) +i=0 +while i<101: + ob=i/100 + input_list.append(ob) + i=i+1 +output_list=[] +output_list.append(0) +for ob in input_list: + if ob!=-1: + s=math.sqrt(ob) + output_list.append(s) + +##################################################################################################### +##################################################################################################### +##################################################################################################### + +b_gas1 = ex.GasBus(label=Label(name='b_gas1', location='C1', energy_carrier=''), slack=True) + +b_gas2 = ex.GasBus(label=Label(name='b_gas2', location='C1', energy_carrier='')) + +b_gas3 = ex.GasBus(label=Label(name='b_gas3', location='C1', energy_carrier='')) + +b_gas4 = ex.GasBus(label=Label(name='b_gas4', location='C1', energy_carrier='')) + +gas_line_12=ex.GasLine(label='gas_line_12', + inputs={b_gas1: solph.Flow(nominal_value=200)}, + outputs={b_gas2: solph.Flow(nominal_value=200)}, + input_list=input_list, + output_list=output_list, + K_1=100, + conv_factor=0.99) + +gas_line_23=ex.GasLine(label='gas_line_23', + inputs={b_gas2: solph.Flow(nominal_value=200)}, + outputs={b_gas3: solph.Flow(nominal_value=200)}, + input_list=input_list, + output_list=output_list, + K_1=100, + conv_factor=0.99) + +gas_line_24=ex.GasLine(label='gas_line_24', + inputs={b_gas2: solph.Flow(nominal_value=200)}, + outputs={b_gas4: solph.Flow(nominal_value=200)}, + input_list=input_list, + output_list=output_list, + K_1=100, + conv_factor=0.99) + + + + +##################################################################################################### +##################################################################################################### +##################################################################################################### + +source_1=solph.Source(label='source_1', + outputs={b_gas1: solph.Flow(nominal_value=300)}) + + +sink_1=solph.Sink(label='sink_1', + inputs={b_gas4: solph.Flow(nominal_value=10, actual_value=[1,1,0], fixed=True)}) +# +sink_2=solph.Sink(label='sink_2', + inputs={b_gas3: solph.Flow(nominal_value=10, actual_value=[1,0,1], fixed=True)}) + + + +es.add(b_gas1) +es.add(b_gas2) +es.add(b_gas3) +es.add(b_gas4) +es.add(gas_line_12) +es.add(gas_line_23) +es.add(gas_line_24) + + +es.add(source_1) +es.add(sink_1) +es.add(sink_2) + +model = solph.Model(es) +model.solve(solver='cbc', solve_kwargs={'tee': True}) +model.results() +results = processing.results(model) + + +locationssystem=[] +locationssystem.append('C1') + +from oemof.analysing_toolbox_v1_8 import * + +bk=blackbox(results, locationssystem, get_allpotentials=True) \ No newline at end of file diff --git a/src/oemof/solph/analysing_toolbox_v1_8.py b/src/oemof/solph/analysing_toolbox_v1_8.py new file mode 100644 index 000000000..d459ff627 --- /dev/null +++ b/src/oemof/solph/analysing_toolbox_v1_8.py @@ -0,0 +1,403 @@ +# -*- coding: utf-8 -*- +''' +General description +------------------- +This is the blackbox function. The aim of this function is to monitor inputs and outputs +of an locationsystem (more explanation in the example) in oemof. + +Installation requirements +------------------------- +This example depends on an installation of oemof + +20.03.2019 - philipp.gradl@stud.unileoben.ac.at +''' + + +from oemof.solph.custom import * +import oemof.solph as solph +import pandas as pd + + + + +def blackbox(results, locationsystem, get_inputs=False, get_outputs=False, get_innerflows=False, get_capacities=False, get_potentials=False, get_allpotentials=False): + i=1 + + input_data=get_input(results, locationsystem) + output_data=get_output(results, locationsystem) + innerflow_data=get_innerflow(results, locationsystem) + capacity_data=get_capacity(results, locationsystem) + potential_data=get_potential(results, locationsystem) + allpotential_data = get_allpotential(results) + combined_dataframe = pd.concat([input_data, output_data, innerflow_data, capacity_data, potential_data, allpotential_data], axis=1, sort=False) + + results=combined_dataframe + + if get_inputs==True: + results=results,input_data + + if get_outputs==True: + if type(results)==type(tuple()): + results=results+tuple([output_data]) + + if type(results)!=type(tuple()): + results=results,get_outputs + + if get_innerflows==True: + if type(results) == type(tuple()): + results = results + tuple([innerflow_data]) + + if type(results) != type(tuple()): + results = results, innerflow_data + + if get_capacities == True: + if type(results) == type(tuple()): + results = results + tuple([capacity_data]) + + if type(results) != type(tuple()): + results = results, capacity_data + + if get_potentials==True: + if type(results)==type(tuple()): + results=results+tuple([potential_data]) + + if type(results)!=type(tuple()): + results=results,potential_data + + if get_allpotentials==True: + if type(results) == type(tuple()): + results = results + tuple([allpotential_data]) + + if type(results) != type(tuple()): + results = results, allpotential_data + return results + + + + + +################################################################################### +def res_key(results): + result_keys=[] + for key in results.keys(): + result_keys.append(key) + return result_keys + + +################################################################################### +def get_input(results, locationsystem): + in_data=pd.DataFrame() + result_keys=res_key(results) + for key in result_keys: + if hasattr(key[0], 'label') and hasattr(key[1], 'label'): + if type(key[0]) != type(solph.Source()) and type(key[1]) != type(solph.Source()) and type(key[0]) != type(solph.Sink()) and type(key[1]) != type(solph.Sink()): + if hasattr(key[0].label, 'location')==True and hasattr(key[1].label, 'location')==True: + if key[0].label.location != '' and key[1].label.location != '': + if key[0].label.location not in locationsystem: + if key[1].label.location in locationsystem: + put_data_ob=pd.DataFrame(results[key]['sequences']) + column=put_data_ob.columns[0] + label = label_function(results, key) + put_data_ob=put_data_ob.rename(columns={column:label}) + in_data=pd.concat([in_data,put_data_ob], axis=1) + + if hasattr(key[1].label, 'location')==True: + if hasattr(key[0].label, 'location')==False: + if key[1].label.location in locationsystem: + overlap=ob_location_test(key[0]) + if overlap==False: + put_data_ob = pd.DataFrame(results[key]['sequences']) + column=put_data_ob.columns[0] + label = label_function(results, key) + put_data_ob = put_data_ob.rename(columns={column: label}) + in_data = pd.concat([in_data, put_data_ob], axis=1) + + if hasattr(key[0].label, 'location')==True: + if key[0].label.location == '': + if key[1].label.location in locationsystem: + overlap = ob_location_test(key[0]) + if overlap == False: + put_data_ob = pd.DataFrame(results[key]['sequences']) + column = put_data_ob.columns[0] + label = label_function(results, key) + put_data_ob = put_data_ob.rename(columns={column: label}) + in_data = pd.concat([in_data, put_data_ob], axis=1) + + if type(key[0]) == type(Link()): + if hasattr(key[1].label, 'location'): + if key[1].label.location in locationsystem: + put_data_ob = pd.DataFrame(results[key]['sequences']) + column = put_data_ob.columns[0] + label = label_function(results, key) + put_data_ob = put_data_ob.rename(columns={column: label}) + in_data = pd.concat([in_data, put_data_ob], axis=1) + + if type(key[0]) == type(solph.Source()): + if hasattr(key[1].label, 'location'): + if key[1].label.location in locationsystem: + put_data_ob = pd.DataFrame(results[key]['sequences']) + column = put_data_ob.columns[0] + label = label_function(results, key) + put_data_ob = put_data_ob.rename(columns={column: label}) + in_data = pd.concat([in_data, put_data_ob], axis=1) + + + + + + return in_data + +#################################################################################### + +def ob_location_test(object): + input_location_list=[] + output_location_list=[] + for input in object.inputs: + if hasattr(input, 'label'): + if hasattr(input.label, 'location'): + input_location_list.append(input.label.location) + for output in object.outputs: + if hasattr(output, 'label'): + if hasattr(output.label, 'location'): + output_location_list.append(output.label.location) + + overlap=False + + for location_ob_in in input_location_list: + for location_ob_out in output_location_list: + if location_ob_in==location_ob_out: + overlap=True + + return overlap + + +#################################################################################### +def get_output(results, locationsystem): + out_data=pd.DataFrame() + + result_keys=res_key(results) + + for key in result_keys: + if hasattr(key[0], 'label') and hasattr(key[1], 'label'): + if type(key[0]) != type(solph.Source()) and type(key[1]) != type(solph.Source()) and type(key[0]) != type(solph.Sink()) and type(key[1]) != type(solph.Sink()): + if hasattr(key[0].label, 'location')==True and hasattr(key[1].label, 'location')==True: + if key[0].label.location != '' and key[1].label.location != '': + if key[0].label.location in locationsystem: + if key[1].label.location not in locationsystem: + put_data_ob=pd.DataFrame(results[key]['sequences']) + column=put_data_ob.columns[0] + label = label_function(results, key) + put_data_ob=put_data_ob.rename(columns={column:label}) + out_data=pd.concat([out_data,put_data_ob], axis=1) + + if hasattr(key[0].label, 'location')==True: + if hasattr(key[1].label, 'location')==False: + if key[0].label.location in locationsystem: + overlap=ob_location_test(key[1]) + if overlap==False: + put_data_ob = pd.DataFrame(results[key]['sequences']) + column=put_data_ob.columns[0] + label = label_function(results, key) + put_data_ob = put_data_ob.rename(columns={column: label}) + out_data = pd.concat([out_data, put_data_ob], axis=1) + + if hasattr(key[1].label, 'location')==True: + if key[1].label.location == '': + if key[0].label.location in locationsystem: + overlap = ob_location_test(key[1]) + if overlap == False: + put_data_ob = pd.DataFrame(results[key]['sequences']) + column=put_data_ob.columns[0] + label=label_function(results, key) + put_data_ob = put_data_ob.rename(columns={column: label}) + out_data = pd.concat([out_data, put_data_ob], axis=1) + + if type(key[1])==type(Link()): + if hasattr(key[0].label, 'location'): + if key[0].label.location in locationsystem: + put_data_ob = pd.DataFrame(results[key]['sequences']) + column = put_data_ob.columns[0] + label = label_function(results, key) + put_data_ob = put_data_ob.rename(columns={column: label}) + out_data = pd.concat([out_data, put_data_ob], axis=1) + + if type(key[1]) == type(solph.Sink()): + if hasattr(key[0].label, 'location'): + if key[0].label.location in locationsystem: + put_data_ob = pd.DataFrame(results[key]['sequences']) + column = put_data_ob.columns[0] + label = label_function(results, key) + put_data_ob = put_data_ob.rename(columns={column: label}) + out_data = pd.concat([out_data, put_data_ob], axis=1) + + + return out_data +#################################################################################### +def get_innerflow(results, locationsystem): + innerflow_data=pd.DataFrame() + result_keys=res_key(results) + key_list=[] + for key in result_keys: + if type(key[0])!=type(solph.Source()) and type(key[1])!=type(solph.Source()) and type(key[0])!=type(solph.Sink()) and type(key[1])!=type(solph.Sink()): + if type(key[0])!=type(Link()) and type(key[1])!=type(Link()): + if hasattr(key[0], 'label')and hasattr(key[1], 'label'): + if hasattr(key[0].label, 'location') and hasattr(key[1].label, 'location'): + if key[0].label.location in locationsystem and key[1].label.location in locationsystem: + key_list.append(key) + + if key[0].label.location=='' and key[1].label.location in locationsystem: + overlap=ob_location_test(key[0]) + if overlap==True: + key_list.append(key) + + if key[1].label.location=='' and key[0].label.location in locationsystem: + overlap=ob_location_test(key[1]) + if overlap==True: + key_list.append(key) + + if hasattr(key[0], 'label')and hasattr(key[1], 'label'): + if hasattr(key[0].label, 'location')==False or hasattr(key[1].label, 'location')==False: + if hasattr(key[0].label, 'location'): + if key[0].label.location in locationsystem: + overlap=ob_location_test(key[1]) + if overlap==True: + key_list.append(key) + + if hasattr(key[1].label, 'location'): + if key[1].label.location in locationsystem: + overlap=ob_location_test(key[0]) + if overlap==True: + key_list.append(key) + + for key in key_list: + put_data_ob = pd.DataFrame(results[key]['sequences']) + column = put_data_ob.columns[0] + label = label_function(results, key) + put_data_ob = put_data_ob.rename(columns={column: label}) + innerflow_data = pd.concat([innerflow_data, put_data_ob], axis=1) + + return innerflow_data +#################################################################################### +def label_function(results, key): + data=pd.DataFrame(results[key]['sequences']) + column=data.columns[0] + + if hasattr(key[0], 'label') and hasattr(key[1], 'label'): + if type(key[0].label)!=str and type(key[1].label)!=str: + label = tuple(key[0].label) + tuple(key[1].label) + tuple([column]) + + if hasattr(key[0], 'label')==False or hasattr(key[1], 'label')==False: + ob=find_the_ob(key) + label_0=ob.label + if type(label_0)==str: + label_0=[label_0] + label=tuple(label_0)+ tuple([column]) + + if hasattr(key[0], 'label') and hasattr(key[1], 'label'): + if type(key[0].label)==str: + label_key_0=tuple([key[0].label]) + + if type(key[1].label)==str: + label_key_1=tuple([key[1].label]) + + if type(key[0].label) != str: + label_key_0 = tuple(key[0].label) + + if type(key[1].label) != str: + label_key_1 = tuple(key[1].label) + + label=label_key_0+label_key_1 + + return label +#################################################################################### +def find_the_ob(key): + if hasattr(key[0], 'label')==True: + ob=key[0] + if hasattr(key[1], 'label')==True: + ob=key[1] + + return ob +#################################################################################### +def get_capacity(results, locationsystem): + capacity_dataframe=pd.DataFrame() + key_list=res_key(results) + for key in key_list: + if hasattr(key[0], 'label')==False or hasattr(key[1], 'label')==False: + relevant=False + if hasattr(key[0], 'inputs'): + for input in key[0].inputs: + if hasattr(input, 'label'): + if hasattr(input.label, 'location'): + if input.label.location in locationsystem: + relevant=True + + if hasattr(key[0], 'outputs'): + for output in key[0].outputs: + if hasattr(output, 'label'): + if hasattr(output.label, 'location'): + if output.label.location in locationsystem: + relevant=True + + if hasattr(key[1], 'inputs'): + for input in key[1].inputs: + if hasattr(input, 'label'): + if hasattr(input.label, 'location'): + if input.label.location in locationsystem: + relevant = True + + if hasattr(key[1], 'outputs'): + for output in key[1].outputs: + if hasattr(output, 'label'): + if hasattr(output.label, 'location'): + if output.label.location in locationsystem: + relevant = True + + if relevant==True: + cap_frame=results[key]['sequences'] + column = cap_frame.columns[0] + label = label_function(results, key) + cap_frame = cap_frame.rename(columns={column: label}) + capacity_dataframe = pd.concat([capacity_dataframe, cap_frame], axis=1) + + return capacity_dataframe + + +def get_potential(results, locationsystem): + potential_data=pd.DataFrame() + res_list=res_key(results) + key_list=[] + for key in res_list: + if key[0]!=None and key[1]==None: + if hasattr(key[0], 'label'): + if hasattr(key[0].label, 'location'): + if key[0].label.location in locationsystem: + key_list.append(key) + + + for key in key_list: + put_data_ob = pd.DataFrame(results[key]['sequences']) + column = put_data_ob.columns[0] + label = key[0].label + put_data_ob = put_data_ob.rename(columns={column: label}) + potential_data = pd.concat([potential_data, put_data_ob], axis=1) + + return potential_data + +def get_allpotential(results): + potential_data=pd.DataFrame() + res_list=res_key(results) + key_list=[] + for key in res_list: + if key[0]!=None and key[1]==None: + if hasattr(key[0], 'label'): + key_list.append(key) + + + for key in key_list: + put_data_ob = pd.DataFrame(results[key]['sequences']) + column = put_data_ob.columns[0] + label = key[0].label + put_data_ob = put_data_ob.rename(columns={column: label}) + potential_data = pd.concat([potential_data, put_data_ob], axis=1) + + return potential_data diff --git a/src/oemof/solph/exnet.py b/src/oemof/solph/exnet.py new file mode 100644 index 000000000..a433ba052 --- /dev/null +++ b/src/oemof/solph/exnet.py @@ -0,0 +1,120 @@ +# -*- coding: utf-8 -*- +''' +General description +------------------- +The goal of GasBus and GasLine is to implement a piecewise linear model. The gas flow is the result of a pressure difference and has a non-linear relationship. + +Installation requirements +------------------------- +This example depends on an installation of oemof + +02.03.2020 - philipp.gradl@stud.unileoben.ac.at +''' +from oemof.solph.network import Bus, Transformer +from pyomo.core import * + + +class GasBus(Bus): + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.slack=kwargs.get('slack', False) + self.p_max = kwargs.get('p_max', 1000) + self.p_min = kwargs.get('p_min', -1000) + + + +class GasLineBlock(SimpleBlock): + CONSTRAINT_GROUP = True + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + def _create(self, group=None): + + if group is None: + return None + + m = self.parent_block() + + self.GASLINE_PL = Set(initialize=[n for n in group]) + + self.GAS_BUSES = Set(initialize=[s for s in m.es.nodes if isinstance(s, GasBus)]) + + + + self.pressure=Var(self.GAS_BUSES, m.TIMESTEPS, bounds=(0,1)) + + self.delta_pressure = Var(self.GASLINE_PL, m.TIMESTEPS, bounds=(-1,1)) + + self.energy_flow = Var(self.GASLINE_PL, m.TIMESTEPS) + + for n in self.GASLINE_PL: + for t in m.TIMESTEPS: + for ob in list(n.outputs.keys()): + if ob.slack == True: + self.pressure[ob,t].value=1 + self.pressure[ob,t].fix() + + for ob in list(n.inputs.keys()): + if ob.slack == True: + self.pressure[ob,t].value=1 + self.pressure[ob,t].fix() + + +################################################################################################################################## + self.piecewise = Piecewise(self.GASLINE_PL, + m.TIMESTEPS, + self.energy_flow, + self.delta_pressure, + pw_pts=n.input_list, + pw_constr_type='EQ', + pw_repn='CC', + f_rule=n.output_list) + +################################################################################################################################## + def flow_eq_pressure(block,n,t): + expr = 0 + expr += (self.pressure[list(n.outputs.keys())[0],t]-self.pressure[list(n.inputs.keys())[0],t]) + expr += self.delta_pressure[n,t] + + return expr == 0 + + self.flow_eq_pressure = Constraint(self.GASLINE_PL, m.TIMESTEPS, rule=flow_eq_pressure) + + def energy_flow_out(block, n, t): + expr = 0 + expr += - m.flow[n, list(n.outputs.keys())[0], t] + expr += self.energy_flow[n,t]*n.K_1 + + return expr == 0 + + self.energy_flow_out = Constraint(self.GASLINE_PL, m.TIMESTEPS, rule=energy_flow_out) + + def energy_flow_in(block, n, t): + expr = 0 + expr += - m.flow[list(n.inputs.keys())[0],n, t]*n.conv_factor + expr += self.energy_flow[n,t]*n.K_1 + + return expr == 0 + + self.energy_flow_in = Constraint(self.GASLINE_PL, m.TIMESTEPS, rule=energy_flow_in) + + + + + +class GasLine(Transformer): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.conv_factor = kwargs.get('conv_factor', 1) + self.K_1=kwargs.get('K_1') + self.input_list = list(kwargs.get('input_list', [])) + self.output_list = list(kwargs.get('output_list', [])) + + if len(self.inputs) > 1 or len(self.outputs) > 1: + raise ValueError("Component GasLine must not have more than \ + one input and one output!") + + def constraint_group(self): + return GasLineBlock From c07d7f1ca96de6aad88dd7370d73cd263ac5bb5c Mon Sep 17 00:00:00 2001 From: philipp235 <70669937+philipp235@users.noreply.github.com> Date: Thu, 3 Sep 2020 01:37:46 +0200 Subject: [PATCH 02/21] Update exnet.py --- src/oemof/solph/exnet.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/oemof/solph/exnet.py b/src/oemof/solph/exnet.py index a433ba052..5d52c1223 100644 --- a/src/oemof/solph/exnet.py +++ b/src/oemof/solph/exnet.py @@ -19,8 +19,8 @@ class GasBus(Bus): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.slack=kwargs.get('slack', False) - self.p_max = kwargs.get('p_max', 1000) - self.p_min = kwargs.get('p_min', -1000) + self.p_max = kwargs.get('p_max', 1) + self.p_min = kwargs.get('p_min', -1) From fccfb479ade6f5ad6bc6d3121dfc5d08fde10a91 Mon Sep 17 00:00:00 2001 From: philipp235 <70669937+philipp235@users.noreply.github.com> Date: Tue, 8 Sep 2020 18:56:27 +0200 Subject: [PATCH 03/21] Delete analysing_toolbox_v1_8.py --- src/oemof/solph/analysing_toolbox_v1_8.py | 403 ---------------------- 1 file changed, 403 deletions(-) delete mode 100644 src/oemof/solph/analysing_toolbox_v1_8.py diff --git a/src/oemof/solph/analysing_toolbox_v1_8.py b/src/oemof/solph/analysing_toolbox_v1_8.py deleted file mode 100644 index d459ff627..000000000 --- a/src/oemof/solph/analysing_toolbox_v1_8.py +++ /dev/null @@ -1,403 +0,0 @@ -# -*- coding: utf-8 -*- -''' -General description -------------------- -This is the blackbox function. The aim of this function is to monitor inputs and outputs -of an locationsystem (more explanation in the example) in oemof. - -Installation requirements -------------------------- -This example depends on an installation of oemof - -20.03.2019 - philipp.gradl@stud.unileoben.ac.at -''' - - -from oemof.solph.custom import * -import oemof.solph as solph -import pandas as pd - - - - -def blackbox(results, locationsystem, get_inputs=False, get_outputs=False, get_innerflows=False, get_capacities=False, get_potentials=False, get_allpotentials=False): - i=1 - - input_data=get_input(results, locationsystem) - output_data=get_output(results, locationsystem) - innerflow_data=get_innerflow(results, locationsystem) - capacity_data=get_capacity(results, locationsystem) - potential_data=get_potential(results, locationsystem) - allpotential_data = get_allpotential(results) - combined_dataframe = pd.concat([input_data, output_data, innerflow_data, capacity_data, potential_data, allpotential_data], axis=1, sort=False) - - results=combined_dataframe - - if get_inputs==True: - results=results,input_data - - if get_outputs==True: - if type(results)==type(tuple()): - results=results+tuple([output_data]) - - if type(results)!=type(tuple()): - results=results,get_outputs - - if get_innerflows==True: - if type(results) == type(tuple()): - results = results + tuple([innerflow_data]) - - if type(results) != type(tuple()): - results = results, innerflow_data - - if get_capacities == True: - if type(results) == type(tuple()): - results = results + tuple([capacity_data]) - - if type(results) != type(tuple()): - results = results, capacity_data - - if get_potentials==True: - if type(results)==type(tuple()): - results=results+tuple([potential_data]) - - if type(results)!=type(tuple()): - results=results,potential_data - - if get_allpotentials==True: - if type(results) == type(tuple()): - results = results + tuple([allpotential_data]) - - if type(results) != type(tuple()): - results = results, allpotential_data - return results - - - - - -################################################################################### -def res_key(results): - result_keys=[] - for key in results.keys(): - result_keys.append(key) - return result_keys - - -################################################################################### -def get_input(results, locationsystem): - in_data=pd.DataFrame() - result_keys=res_key(results) - for key in result_keys: - if hasattr(key[0], 'label') and hasattr(key[1], 'label'): - if type(key[0]) != type(solph.Source()) and type(key[1]) != type(solph.Source()) and type(key[0]) != type(solph.Sink()) and type(key[1]) != type(solph.Sink()): - if hasattr(key[0].label, 'location')==True and hasattr(key[1].label, 'location')==True: - if key[0].label.location != '' and key[1].label.location != '': - if key[0].label.location not in locationsystem: - if key[1].label.location in locationsystem: - put_data_ob=pd.DataFrame(results[key]['sequences']) - column=put_data_ob.columns[0] - label = label_function(results, key) - put_data_ob=put_data_ob.rename(columns={column:label}) - in_data=pd.concat([in_data,put_data_ob], axis=1) - - if hasattr(key[1].label, 'location')==True: - if hasattr(key[0].label, 'location')==False: - if key[1].label.location in locationsystem: - overlap=ob_location_test(key[0]) - if overlap==False: - put_data_ob = pd.DataFrame(results[key]['sequences']) - column=put_data_ob.columns[0] - label = label_function(results, key) - put_data_ob = put_data_ob.rename(columns={column: label}) - in_data = pd.concat([in_data, put_data_ob], axis=1) - - if hasattr(key[0].label, 'location')==True: - if key[0].label.location == '': - if key[1].label.location in locationsystem: - overlap = ob_location_test(key[0]) - if overlap == False: - put_data_ob = pd.DataFrame(results[key]['sequences']) - column = put_data_ob.columns[0] - label = label_function(results, key) - put_data_ob = put_data_ob.rename(columns={column: label}) - in_data = pd.concat([in_data, put_data_ob], axis=1) - - if type(key[0]) == type(Link()): - if hasattr(key[1].label, 'location'): - if key[1].label.location in locationsystem: - put_data_ob = pd.DataFrame(results[key]['sequences']) - column = put_data_ob.columns[0] - label = label_function(results, key) - put_data_ob = put_data_ob.rename(columns={column: label}) - in_data = pd.concat([in_data, put_data_ob], axis=1) - - if type(key[0]) == type(solph.Source()): - if hasattr(key[1].label, 'location'): - if key[1].label.location in locationsystem: - put_data_ob = pd.DataFrame(results[key]['sequences']) - column = put_data_ob.columns[0] - label = label_function(results, key) - put_data_ob = put_data_ob.rename(columns={column: label}) - in_data = pd.concat([in_data, put_data_ob], axis=1) - - - - - - return in_data - -#################################################################################### - -def ob_location_test(object): - input_location_list=[] - output_location_list=[] - for input in object.inputs: - if hasattr(input, 'label'): - if hasattr(input.label, 'location'): - input_location_list.append(input.label.location) - for output in object.outputs: - if hasattr(output, 'label'): - if hasattr(output.label, 'location'): - output_location_list.append(output.label.location) - - overlap=False - - for location_ob_in in input_location_list: - for location_ob_out in output_location_list: - if location_ob_in==location_ob_out: - overlap=True - - return overlap - - -#################################################################################### -def get_output(results, locationsystem): - out_data=pd.DataFrame() - - result_keys=res_key(results) - - for key in result_keys: - if hasattr(key[0], 'label') and hasattr(key[1], 'label'): - if type(key[0]) != type(solph.Source()) and type(key[1]) != type(solph.Source()) and type(key[0]) != type(solph.Sink()) and type(key[1]) != type(solph.Sink()): - if hasattr(key[0].label, 'location')==True and hasattr(key[1].label, 'location')==True: - if key[0].label.location != '' and key[1].label.location != '': - if key[0].label.location in locationsystem: - if key[1].label.location not in locationsystem: - put_data_ob=pd.DataFrame(results[key]['sequences']) - column=put_data_ob.columns[0] - label = label_function(results, key) - put_data_ob=put_data_ob.rename(columns={column:label}) - out_data=pd.concat([out_data,put_data_ob], axis=1) - - if hasattr(key[0].label, 'location')==True: - if hasattr(key[1].label, 'location')==False: - if key[0].label.location in locationsystem: - overlap=ob_location_test(key[1]) - if overlap==False: - put_data_ob = pd.DataFrame(results[key]['sequences']) - column=put_data_ob.columns[0] - label = label_function(results, key) - put_data_ob = put_data_ob.rename(columns={column: label}) - out_data = pd.concat([out_data, put_data_ob], axis=1) - - if hasattr(key[1].label, 'location')==True: - if key[1].label.location == '': - if key[0].label.location in locationsystem: - overlap = ob_location_test(key[1]) - if overlap == False: - put_data_ob = pd.DataFrame(results[key]['sequences']) - column=put_data_ob.columns[0] - label=label_function(results, key) - put_data_ob = put_data_ob.rename(columns={column: label}) - out_data = pd.concat([out_data, put_data_ob], axis=1) - - if type(key[1])==type(Link()): - if hasattr(key[0].label, 'location'): - if key[0].label.location in locationsystem: - put_data_ob = pd.DataFrame(results[key]['sequences']) - column = put_data_ob.columns[0] - label = label_function(results, key) - put_data_ob = put_data_ob.rename(columns={column: label}) - out_data = pd.concat([out_data, put_data_ob], axis=1) - - if type(key[1]) == type(solph.Sink()): - if hasattr(key[0].label, 'location'): - if key[0].label.location in locationsystem: - put_data_ob = pd.DataFrame(results[key]['sequences']) - column = put_data_ob.columns[0] - label = label_function(results, key) - put_data_ob = put_data_ob.rename(columns={column: label}) - out_data = pd.concat([out_data, put_data_ob], axis=1) - - - return out_data -#################################################################################### -def get_innerflow(results, locationsystem): - innerflow_data=pd.DataFrame() - result_keys=res_key(results) - key_list=[] - for key in result_keys: - if type(key[0])!=type(solph.Source()) and type(key[1])!=type(solph.Source()) and type(key[0])!=type(solph.Sink()) and type(key[1])!=type(solph.Sink()): - if type(key[0])!=type(Link()) and type(key[1])!=type(Link()): - if hasattr(key[0], 'label')and hasattr(key[1], 'label'): - if hasattr(key[0].label, 'location') and hasattr(key[1].label, 'location'): - if key[0].label.location in locationsystem and key[1].label.location in locationsystem: - key_list.append(key) - - if key[0].label.location=='' and key[1].label.location in locationsystem: - overlap=ob_location_test(key[0]) - if overlap==True: - key_list.append(key) - - if key[1].label.location=='' and key[0].label.location in locationsystem: - overlap=ob_location_test(key[1]) - if overlap==True: - key_list.append(key) - - if hasattr(key[0], 'label')and hasattr(key[1], 'label'): - if hasattr(key[0].label, 'location')==False or hasattr(key[1].label, 'location')==False: - if hasattr(key[0].label, 'location'): - if key[0].label.location in locationsystem: - overlap=ob_location_test(key[1]) - if overlap==True: - key_list.append(key) - - if hasattr(key[1].label, 'location'): - if key[1].label.location in locationsystem: - overlap=ob_location_test(key[0]) - if overlap==True: - key_list.append(key) - - for key in key_list: - put_data_ob = pd.DataFrame(results[key]['sequences']) - column = put_data_ob.columns[0] - label = label_function(results, key) - put_data_ob = put_data_ob.rename(columns={column: label}) - innerflow_data = pd.concat([innerflow_data, put_data_ob], axis=1) - - return innerflow_data -#################################################################################### -def label_function(results, key): - data=pd.DataFrame(results[key]['sequences']) - column=data.columns[0] - - if hasattr(key[0], 'label') and hasattr(key[1], 'label'): - if type(key[0].label)!=str and type(key[1].label)!=str: - label = tuple(key[0].label) + tuple(key[1].label) + tuple([column]) - - if hasattr(key[0], 'label')==False or hasattr(key[1], 'label')==False: - ob=find_the_ob(key) - label_0=ob.label - if type(label_0)==str: - label_0=[label_0] - label=tuple(label_0)+ tuple([column]) - - if hasattr(key[0], 'label') and hasattr(key[1], 'label'): - if type(key[0].label)==str: - label_key_0=tuple([key[0].label]) - - if type(key[1].label)==str: - label_key_1=tuple([key[1].label]) - - if type(key[0].label) != str: - label_key_0 = tuple(key[0].label) - - if type(key[1].label) != str: - label_key_1 = tuple(key[1].label) - - label=label_key_0+label_key_1 - - return label -#################################################################################### -def find_the_ob(key): - if hasattr(key[0], 'label')==True: - ob=key[0] - if hasattr(key[1], 'label')==True: - ob=key[1] - - return ob -#################################################################################### -def get_capacity(results, locationsystem): - capacity_dataframe=pd.DataFrame() - key_list=res_key(results) - for key in key_list: - if hasattr(key[0], 'label')==False or hasattr(key[1], 'label')==False: - relevant=False - if hasattr(key[0], 'inputs'): - for input in key[0].inputs: - if hasattr(input, 'label'): - if hasattr(input.label, 'location'): - if input.label.location in locationsystem: - relevant=True - - if hasattr(key[0], 'outputs'): - for output in key[0].outputs: - if hasattr(output, 'label'): - if hasattr(output.label, 'location'): - if output.label.location in locationsystem: - relevant=True - - if hasattr(key[1], 'inputs'): - for input in key[1].inputs: - if hasattr(input, 'label'): - if hasattr(input.label, 'location'): - if input.label.location in locationsystem: - relevant = True - - if hasattr(key[1], 'outputs'): - for output in key[1].outputs: - if hasattr(output, 'label'): - if hasattr(output.label, 'location'): - if output.label.location in locationsystem: - relevant = True - - if relevant==True: - cap_frame=results[key]['sequences'] - column = cap_frame.columns[0] - label = label_function(results, key) - cap_frame = cap_frame.rename(columns={column: label}) - capacity_dataframe = pd.concat([capacity_dataframe, cap_frame], axis=1) - - return capacity_dataframe - - -def get_potential(results, locationsystem): - potential_data=pd.DataFrame() - res_list=res_key(results) - key_list=[] - for key in res_list: - if key[0]!=None and key[1]==None: - if hasattr(key[0], 'label'): - if hasattr(key[0].label, 'location'): - if key[0].label.location in locationsystem: - key_list.append(key) - - - for key in key_list: - put_data_ob = pd.DataFrame(results[key]['sequences']) - column = put_data_ob.columns[0] - label = key[0].label - put_data_ob = put_data_ob.rename(columns={column: label}) - potential_data = pd.concat([potential_data, put_data_ob], axis=1) - - return potential_data - -def get_allpotential(results): - potential_data=pd.DataFrame() - res_list=res_key(results) - key_list=[] - for key in res_list: - if key[0]!=None and key[1]==None: - if hasattr(key[0], 'label'): - key_list.append(key) - - - for key in key_list: - put_data_ob = pd.DataFrame(results[key]['sequences']) - column = put_data_ob.columns[0] - label = key[0].label - put_data_ob = put_data_ob.rename(columns={column: label}) - potential_data = pd.concat([potential_data, put_data_ob], axis=1) - - return potential_data From 60ac1514aa3399ab469534c0f75ac184be5faf67 Mon Sep 17 00:00:00 2001 From: philipp235 <70669937+philipp235@users.noreply.github.com> Date: Tue, 8 Sep 2020 18:57:50 +0200 Subject: [PATCH 04/21] Update 1_system.py --- src/oemof/solph/1_system.py | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/src/oemof/solph/1_system.py b/src/oemof/solph/1_system.py index 1ce7ef9ce..5f370b4a5 100644 --- a/src/oemof/solph/1_system.py +++ b/src/oemof/solph/1_system.py @@ -1,19 +1,12 @@ import oemof.solph as solph -from collections import namedtuple import oemof.solph.exnet as ex from oemof.outputlib import * import math import pandas as pd import time -class Label(namedtuple('label', ['location','name', 'energy_carrier'])): - __slots__ = () - def __str__(self): - return '_'.join(map(str, self._asdict().values())) datetimeindex = pd.date_range('1/1/2017', periods=3, freq='H') - - es = solph.EnergySystem(timeindex=datetimeindex) input_list=[] input_list.append(-1) @@ -84,7 +77,7 @@ def __str__(self): sink_1=solph.Sink(label='sink_1', inputs={b_gas2: solph.Flow(nominal_value=100, actual_value=[1,1,0], fixed=True)}) -# + sink_2=solph.Sink(label='sink_2', inputs={b_gas3: solph.Flow(nominal_value=100, actual_value=[1,0,1], fixed=True)}) @@ -106,13 +99,3 @@ def __str__(self): model.solve(solver='cbc') model.results() results = processing.results(model) - - -locationssystem=[] -locationssystem.append('C1') - -from oemof.analysing_toolbox_v1_8 import * - -bk=blackbox(results, locationssystem, get_allpotentials=True) - - From ca3c6ef32415abee5a4d513b1e85db9d09804882 Mon Sep 17 00:00:00 2001 From: philipp235 <70669937+philipp235@users.noreply.github.com> Date: Tue, 8 Sep 2020 18:58:28 +0200 Subject: [PATCH 05/21] Update 2_system.py --- src/oemof/solph/2_system.py | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/oemof/solph/2_system.py b/src/oemof/solph/2_system.py index 772b7cbd4..609f5c227 100644 --- a/src/oemof/solph/2_system.py +++ b/src/oemof/solph/2_system.py @@ -1,15 +1,9 @@ import oemof.solph as solph -from collections import namedtuple import oemof.solph.exnet as ex import pandas as pd from oemof.outputlib import * import math -class Label(namedtuple('label', ['location','name', 'energy_carrier'])): - __slots__ = () - def __str__(self): - return '_'.join(map(str, self._asdict().values())) - datetimeindex = pd.date_range('1/1/2017', periods=3, freq='H') es = solph.EnergySystem(timeindex=datetimeindex) @@ -100,11 +94,3 @@ def __str__(self): model.solve(solver='cbc', solve_kwargs={'tee': True}) model.results() results = processing.results(model) - - -locationssystem=[] -locationssystem.append('C1') - -from oemof.analysing_toolbox_v1_8 import * - -bk=blackbox(results, locationssystem, get_allpotentials=True) \ No newline at end of file From f6ab3474750f71ab239751dbbd704088ef0f1898 Mon Sep 17 00:00:00 2001 From: philipp235 <70669937+philipp235@users.noreply.github.com> Date: Tue, 8 Sep 2020 23:16:08 +0200 Subject: [PATCH 06/21] Delete 2_system.py --- src/oemof/solph/2_system.py | 96 ------------------------------------- 1 file changed, 96 deletions(-) delete mode 100644 src/oemof/solph/2_system.py diff --git a/src/oemof/solph/2_system.py b/src/oemof/solph/2_system.py deleted file mode 100644 index 609f5c227..000000000 --- a/src/oemof/solph/2_system.py +++ /dev/null @@ -1,96 +0,0 @@ -import oemof.solph as solph -import oemof.solph.exnet as ex -import pandas as pd -from oemof.outputlib import * -import math - -datetimeindex = pd.date_range('1/1/2017', periods=3, freq='H') - -es = solph.EnergySystem(timeindex=datetimeindex) - -input_list=[] -input_list.append(-1) -i=0 -while i<101: - ob=i/100 - input_list.append(ob) - i=i+1 -output_list=[] -output_list.append(0) -for ob in input_list: - if ob!=-1: - s=math.sqrt(ob) - output_list.append(s) - -##################################################################################################### -##################################################################################################### -##################################################################################################### - -b_gas1 = ex.GasBus(label=Label(name='b_gas1', location='C1', energy_carrier=''), slack=True) - -b_gas2 = ex.GasBus(label=Label(name='b_gas2', location='C1', energy_carrier='')) - -b_gas3 = ex.GasBus(label=Label(name='b_gas3', location='C1', energy_carrier='')) - -b_gas4 = ex.GasBus(label=Label(name='b_gas4', location='C1', energy_carrier='')) - -gas_line_12=ex.GasLine(label='gas_line_12', - inputs={b_gas1: solph.Flow(nominal_value=200)}, - outputs={b_gas2: solph.Flow(nominal_value=200)}, - input_list=input_list, - output_list=output_list, - K_1=100, - conv_factor=0.99) - -gas_line_23=ex.GasLine(label='gas_line_23', - inputs={b_gas2: solph.Flow(nominal_value=200)}, - outputs={b_gas3: solph.Flow(nominal_value=200)}, - input_list=input_list, - output_list=output_list, - K_1=100, - conv_factor=0.99) - -gas_line_24=ex.GasLine(label='gas_line_24', - inputs={b_gas2: solph.Flow(nominal_value=200)}, - outputs={b_gas4: solph.Flow(nominal_value=200)}, - input_list=input_list, - output_list=output_list, - K_1=100, - conv_factor=0.99) - - - - -##################################################################################################### -##################################################################################################### -##################################################################################################### - -source_1=solph.Source(label='source_1', - outputs={b_gas1: solph.Flow(nominal_value=300)}) - - -sink_1=solph.Sink(label='sink_1', - inputs={b_gas4: solph.Flow(nominal_value=10, actual_value=[1,1,0], fixed=True)}) -# -sink_2=solph.Sink(label='sink_2', - inputs={b_gas3: solph.Flow(nominal_value=10, actual_value=[1,0,1], fixed=True)}) - - - -es.add(b_gas1) -es.add(b_gas2) -es.add(b_gas3) -es.add(b_gas4) -es.add(gas_line_12) -es.add(gas_line_23) -es.add(gas_line_24) - - -es.add(source_1) -es.add(sink_1) -es.add(sink_2) - -model = solph.Model(es) -model.solve(solver='cbc', solve_kwargs={'tee': True}) -model.results() -results = processing.results(model) From ceb4fd978a6f0997b88f7063ca20815b3cf9dbd9 Mon Sep 17 00:00:00 2001 From: philipp235 <70669937+philipp235@users.noreply.github.com> Date: Tue, 8 Sep 2020 23:16:16 +0200 Subject: [PATCH 07/21] Delete 1_system.py --- src/oemof/solph/1_system.py | 101 ------------------------------------ 1 file changed, 101 deletions(-) delete mode 100644 src/oemof/solph/1_system.py diff --git a/src/oemof/solph/1_system.py b/src/oemof/solph/1_system.py deleted file mode 100644 index 5f370b4a5..000000000 --- a/src/oemof/solph/1_system.py +++ /dev/null @@ -1,101 +0,0 @@ -import oemof.solph as solph -import oemof.solph.exnet as ex -from oemof.outputlib import * -import math -import pandas as pd -import time - -datetimeindex = pd.date_range('1/1/2017', periods=3, freq='H') - -es = solph.EnergySystem(timeindex=datetimeindex) -input_list=[] -input_list.append(-1) -i=0 -while i<101: - ob=i/100 - input_list.append(ob) - i=i+1 -output_list=[] -output_list.append(0) - -for ob in input_list: - if ob!=-1: - s=math.sqrt(ob) - output_list.append(s) - -##################################################################################################### -##################################################################################################### -##################################################################################################### - -b_gas1 = ex.GasBus(label=Label(name='b_gas1', location='C1', energy_carrier=''), slack=True) - -b_gas2 = ex.GasBus(label=Label(name='b_gas2', location='C2', energy_carrier='')) - -b_gas3 = ex.GasBus(label=Label(name='b_gas3', location='C1', energy_carrier='')) - - -gas_line_12=ex.GasLine(label='gas_line_12', - inputs={b_gas1: solph.Flow(nominal_value=200)}, - outputs={b_gas2: solph.Flow(nominal_value=200)}, - input_list=input_list, - output_list=output_list, - K_1=100, - conv_factor=0.99) - -gas_line_13=ex.GasLine(label='gas_line_13', - inputs={b_gas1: solph.Flow(nominal_value=200)}, - outputs={b_gas3: solph.Flow(nominal_value=200)}, - input_list=input_list, - output_list=output_list, - K_1=100, - conv_factor=0.99) - -gas_line_23=ex.GasLine(label='gas_line_23', - inputs={b_gas2: solph.Flow(nominal_value=200)}, - outputs={b_gas3: solph.Flow(nominal_value=200)}, - input_list=input_list, - output_list=output_list, - K_1=100, - conv_factor=0.99) - -gas_line_32=ex.GasLine(label='gas_line_32', - inputs={b_gas3: solph.Flow(nominal_value=200)}, - outputs={b_gas2: solph.Flow(nominal_value=200)}, - input_list=input_list, - output_list=output_list, - K_1=100, - conv_factor=0.99) - - -##################################################################################################### -##################################################################################################### -##################################################################################################### - -source_1=solph.Source(label='source_1', - outputs={b_gas1: solph.Flow(nominal_value=300)}) - - -sink_1=solph.Sink(label='sink_1', - inputs={b_gas2: solph.Flow(nominal_value=100, actual_value=[1,1,0], fixed=True)}) - -sink_2=solph.Sink(label='sink_2', - inputs={b_gas3: solph.Flow(nominal_value=100, actual_value=[1,0,1], fixed=True)}) - - - -es.add(b_gas1) -es.add(b_gas2) -es.add(b_gas3) -es.add(gas_line_12) -es.add(gas_line_13) -es.add(gas_line_23) -es.add(gas_line_32) - -es.add(source_1) -es.add(sink_1) -es.add(sink_2) - -model = solph.Model(es) -model.solve(solver='cbc') -model.results() -results = processing.results(model) From 96363500875c55203f1bf7e314e91012e029155a Mon Sep 17 00:00:00 2001 From: philipp235 <70669937+philipp235@users.noreply.github.com> Date: Tue, 8 Sep 2020 23:16:24 +0200 Subject: [PATCH 08/21] Delete exnet.py --- src/oemof/solph/exnet.py | 120 --------------------------------------- 1 file changed, 120 deletions(-) delete mode 100644 src/oemof/solph/exnet.py diff --git a/src/oemof/solph/exnet.py b/src/oemof/solph/exnet.py deleted file mode 100644 index 5d52c1223..000000000 --- a/src/oemof/solph/exnet.py +++ /dev/null @@ -1,120 +0,0 @@ -# -*- coding: utf-8 -*- -''' -General description -------------------- -The goal of GasBus and GasLine is to implement a piecewise linear model. The gas flow is the result of a pressure difference and has a non-linear relationship. - -Installation requirements -------------------------- -This example depends on an installation of oemof - -02.03.2020 - philipp.gradl@stud.unileoben.ac.at -''' -from oemof.solph.network import Bus, Transformer -from pyomo.core import * - - -class GasBus(Bus): - - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self.slack=kwargs.get('slack', False) - self.p_max = kwargs.get('p_max', 1) - self.p_min = kwargs.get('p_min', -1) - - - -class GasLineBlock(SimpleBlock): - CONSTRAINT_GROUP = True - - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - - def _create(self, group=None): - - if group is None: - return None - - m = self.parent_block() - - self.GASLINE_PL = Set(initialize=[n for n in group]) - - self.GAS_BUSES = Set(initialize=[s for s in m.es.nodes if isinstance(s, GasBus)]) - - - - self.pressure=Var(self.GAS_BUSES, m.TIMESTEPS, bounds=(0,1)) - - self.delta_pressure = Var(self.GASLINE_PL, m.TIMESTEPS, bounds=(-1,1)) - - self.energy_flow = Var(self.GASLINE_PL, m.TIMESTEPS) - - for n in self.GASLINE_PL: - for t in m.TIMESTEPS: - for ob in list(n.outputs.keys()): - if ob.slack == True: - self.pressure[ob,t].value=1 - self.pressure[ob,t].fix() - - for ob in list(n.inputs.keys()): - if ob.slack == True: - self.pressure[ob,t].value=1 - self.pressure[ob,t].fix() - - -################################################################################################################################## - self.piecewise = Piecewise(self.GASLINE_PL, - m.TIMESTEPS, - self.energy_flow, - self.delta_pressure, - pw_pts=n.input_list, - pw_constr_type='EQ', - pw_repn='CC', - f_rule=n.output_list) - -################################################################################################################################## - def flow_eq_pressure(block,n,t): - expr = 0 - expr += (self.pressure[list(n.outputs.keys())[0],t]-self.pressure[list(n.inputs.keys())[0],t]) - expr += self.delta_pressure[n,t] - - return expr == 0 - - self.flow_eq_pressure = Constraint(self.GASLINE_PL, m.TIMESTEPS, rule=flow_eq_pressure) - - def energy_flow_out(block, n, t): - expr = 0 - expr += - m.flow[n, list(n.outputs.keys())[0], t] - expr += self.energy_flow[n,t]*n.K_1 - - return expr == 0 - - self.energy_flow_out = Constraint(self.GASLINE_PL, m.TIMESTEPS, rule=energy_flow_out) - - def energy_flow_in(block, n, t): - expr = 0 - expr += - m.flow[list(n.inputs.keys())[0],n, t]*n.conv_factor - expr += self.energy_flow[n,t]*n.K_1 - - return expr == 0 - - self.energy_flow_in = Constraint(self.GASLINE_PL, m.TIMESTEPS, rule=energy_flow_in) - - - - - -class GasLine(Transformer): - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self.conv_factor = kwargs.get('conv_factor', 1) - self.K_1=kwargs.get('K_1') - self.input_list = list(kwargs.get('input_list', [])) - self.output_list = list(kwargs.get('output_list', [])) - - if len(self.inputs) > 1 or len(self.outputs) > 1: - raise ValueError("Component GasLine must not have more than \ - one input and one output!") - - def constraint_group(self): - return GasLineBlock From 342e91b1b79853ff773511658f58856defe1580f Mon Sep 17 00:00:00 2001 From: philipp235 <70669937+philipp235@users.noreply.github.com> Date: Tue, 8 Sep 2020 23:16:41 +0200 Subject: [PATCH 09/21] Add files via upload --- src/oemof/solph/1_system.py | 92 +++++++++++++++++++++++++++++ src/oemof/solph/exnet.py | 115 ++++++++++++++++++++++++++++++++++++ 2 files changed, 207 insertions(+) create mode 100644 src/oemof/solph/1_system.py create mode 100644 src/oemof/solph/exnet.py diff --git a/src/oemof/solph/1_system.py b/src/oemof/solph/1_system.py new file mode 100644 index 000000000..0cd76090c --- /dev/null +++ b/src/oemof/solph/1_system.py @@ -0,0 +1,92 @@ +import oemof.solph as solph +import oemof.solph.exnet as ex +from oemof.outputlib import * +import math +import pandas as pd +import time + +datetimeindex = pd.date_range('1/1/2017', periods=3, freq='H') + +es = solph.EnergySystem(timeindex=datetimeindex) +input_list = [] +input_list.append(-1) +i = 0 +while i < 101: + ob = i / 100 + input_list.append(ob) + i = i + 1 +output_list = [] +output_list.append(0) + +for ob in input_list: + if ob != -1: + s = math.sqrt(ob) + output_list.append(s) + +b_gas1 = ex.GasBus(label='b_gas1', slack=True) +b_gas2 = ex.GasBus(label='b_gas2') +b_gas3 = ex.GasBus(label='b_gas3') + + +gas_line_12 = ex.GasLine(label='gas_line_12', + inputs={b_gas1: solph.Flow(nominal_value=200)}, + outputs={b_gas2: solph.Flow(nominal_value=200)}, + input_list=input_list, + output_list=output_list, + K_1=100, + conv_factor=0.99) + +gas_line_13 = ex.GasLine(label='gas_line_13', + inputs={b_gas1: solph.Flow(nominal_value=200)}, + outputs={b_gas3: solph.Flow(nominal_value=200)}, + input_list=input_list, + output_list=output_list, + K_1=100, + conv_factor=0.99) + +gas_line_23 = ex.GasLine(label='gas_line_23', + inputs={b_gas2: solph.Flow(nominal_value=200)}, + outputs={b_gas3: solph.Flow(nominal_value=200)}, + input_list=input_list, + output_list=output_list, + K_1=100, + conv_factor=0.99) + +gas_line_32 = ex.GasLine(label='gas_line_32', + inputs={b_gas3: solph.Flow(nominal_value=200)}, + outputs={b_gas2: solph.Flow(nominal_value=200)}, + input_list=input_list, + output_list=output_list, + K_1=100, + conv_factor=0.99) + +source_1 = solph.Source(label='source_1', + outputs={b_gas1: solph.Flow(nominal_value=300)}) + + +sink_1 = solph.Sink(label='sink_1', + inputs={b_gas2: solph.Flow(nominal_value=100, + actual_value=[1, 1, 0], + fixed=True)}) + +sink_2 = solph.Sink(label='sink_2', + inputs={b_gas3: solph.Flow(nominal_value=100, + actual_value=[1, 0, 1], + fixed=True)}) + +es.add(b_gas1) +es.add(b_gas2) +es.add(b_gas3) +es.add(gas_line_12) +es.add(gas_line_13) +es.add(gas_line_23) +es.add(gas_line_32) + +es.add(source_1) +es.add(sink_1) +es.add(sink_2) + +model = solph.Model(es) +model.solve(solver='cbc') +model.results() +results = processing.results(model) diff --git a/src/oemof/solph/exnet.py b/src/oemof/solph/exnet.py new file mode 100644 index 000000000..74cfc5b7b --- /dev/null +++ b/src/oemof/solph/exnet.py @@ -0,0 +1,115 @@ +# -*- coding: utf-8 -*- +''' +General description +------------------- +The goal of GasBus and GasLine is to implement a piecewise linear model. +The gas flow is the result of a pressure difference and +has a non-linear relationship. + +Installation requirements +------------------------- +This example depends on an installation of oemof + +02.03.2020 - philipp.gradl@stud.unileoben.ac.at +''' +from oemof.solph.network import Bus, Transformer +from pyomo.core import * + + +class GasBus(Bus): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.slack = kwargs.get('slack', False) + self.p_max = kwargs.get('p_max', 1) + self.p_min = kwargs.get('p_min', -1) + + +class GasLineBlock(SimpleBlock): + CONSTRAINT_GROUP = True + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + def _create(self, group=None): + if group is None: + return None + + m = self.parent_block() + + self.GASLINE_PL = Set(initialize=[n for n in group]) + + self.GAS_BUSES = Set(initialize=[s for s in m.es.nodes + if isinstance(s, GasBus)]) + + self.pressure = Var(self.GAS_BUSES, m.TIMESTEPS, bounds=(0, 1)) + + self.delta_pressure = Var(self.GASLINE_PL, m.TIMESTEPS, bounds=(-1, 1)) + + self.energy_flow = Var(self.GASLINE_PL, m.TIMESTEPS) + + for n in self.GASLINE_PL: + for t in m.TIMESTEPS: + for ob in list(n.outputs.keys()): + if ob.slack is True: + self.pressure[ob, t].value = 1 + self.pressure[ob, t].fix() + + for ob in list(n.inputs.keys()): + if ob.slack is True: + self.pressure[ob, t].value = 1 + self.pressure[ob, t].fix() + + self.piecewise = Piecewise(self.GASLINE_PL, + m.TIMESTEPS, + self.energy_flow, + self.delta_pressure, + pw_pts=n.input_list, + pw_constr_type='EQ', + pw_repn='CC', + f_rule=n.output_list) + + def flow_eq_pressure(block, n, t): + expr = 0 + expr += (self.pressure[list(n.outputs.keys())[0], t] - + self.pressure[list(n.inputs.keys())[0], t]) + expr += self.delta_pressure[n, t] + + return expr == 0 + + self.flow_eq_pressure = Constraint(self.GASLINE_PL, + m.TIMESTEPS, + rule=flow_eq_pressure) + + def energy_flow_out(block, n, t): + expr = 0 + expr += - m.flow[n, list(n.outputs.keys())[0], t] + expr += self.energy_flow[n, t]*n.K_1 + + return expr == 0 + + self.energy_flow_out = Constraint(self.GASLINE_PL, + m.TIMESTEPS, + rule=energy_flow_out) + + def energy_flow_in(block, n, t): + expr = 0 + expr += - m.flow[list(n.inputs.keys())[0], n, t]*n.conv_factor + expr += self.energy_flow[n, t]*n.K_1 + + return expr == 0 + + self.energy_flow_in = Constraint(self.GASLINE_PL, + m.TIMESTEPS, + rule=energy_flow_in) + + +class GasLine(Transformer): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.conv_factor = kwargs.get('conv_factor', 1) + self.K_1 = kwargs.get('K_1') + self.input_list = list(kwargs.get('input_list', [])) + self.output_list = list(kwargs.get('output_list', [])) + + def constraint_group(self): + return GasLineBlock From 916227017172b87ee6a9a644e4dfb8f8132a6915 Mon Sep 17 00:00:00 2001 From: philipp235 <70669937+philipp235@users.noreply.github.com> Date: Tue, 8 Sep 2020 23:25:13 +0200 Subject: [PATCH 10/21] Delete 1_system.py --- src/oemof/solph/1_system.py | 92 ------------------------------------- 1 file changed, 92 deletions(-) delete mode 100644 src/oemof/solph/1_system.py diff --git a/src/oemof/solph/1_system.py b/src/oemof/solph/1_system.py deleted file mode 100644 index 0cd76090c..000000000 --- a/src/oemof/solph/1_system.py +++ /dev/null @@ -1,92 +0,0 @@ -import oemof.solph as solph -import oemof.solph.exnet as ex -from oemof.outputlib import * -import math -import pandas as pd -import time - -datetimeindex = pd.date_range('1/1/2017', periods=3, freq='H') - -es = solph.EnergySystem(timeindex=datetimeindex) -input_list = [] -input_list.append(-1) -i = 0 -while i < 101: - ob = i / 100 - input_list.append(ob) - i = i + 1 -output_list = [] -output_list.append(0) - -for ob in input_list: - if ob != -1: - s = math.sqrt(ob) - output_list.append(s) - -b_gas1 = ex.GasBus(label='b_gas1', slack=True) -b_gas2 = ex.GasBus(label='b_gas2') -b_gas3 = ex.GasBus(label='b_gas3') - - -gas_line_12 = ex.GasLine(label='gas_line_12', - inputs={b_gas1: solph.Flow(nominal_value=200)}, - outputs={b_gas2: solph.Flow(nominal_value=200)}, - input_list=input_list, - output_list=output_list, - K_1=100, - conv_factor=0.99) - -gas_line_13 = ex.GasLine(label='gas_line_13', - inputs={b_gas1: solph.Flow(nominal_value=200)}, - outputs={b_gas3: solph.Flow(nominal_value=200)}, - input_list=input_list, - output_list=output_list, - K_1=100, - conv_factor=0.99) - -gas_line_23 = ex.GasLine(label='gas_line_23', - inputs={b_gas2: solph.Flow(nominal_value=200)}, - outputs={b_gas3: solph.Flow(nominal_value=200)}, - input_list=input_list, - output_list=output_list, - K_1=100, - conv_factor=0.99) - -gas_line_32 = ex.GasLine(label='gas_line_32', - inputs={b_gas3: solph.Flow(nominal_value=200)}, - outputs={b_gas2: solph.Flow(nominal_value=200)}, - input_list=input_list, - output_list=output_list, - K_1=100, - conv_factor=0.99) - -source_1 = solph.Source(label='source_1', - outputs={b_gas1: solph.Flow(nominal_value=300)}) - - -sink_1 = solph.Sink(label='sink_1', - inputs={b_gas2: solph.Flow(nominal_value=100, - actual_value=[1, 1, 0], - fixed=True)}) - -sink_2 = solph.Sink(label='sink_2', - inputs={b_gas3: solph.Flow(nominal_value=100, - actual_value=[1, 0, 1], - fixed=True)}) - -es.add(b_gas1) -es.add(b_gas2) -es.add(b_gas3) -es.add(gas_line_12) -es.add(gas_line_13) -es.add(gas_line_23) -es.add(gas_line_32) - -es.add(source_1) -es.add(sink_1) -es.add(sink_2) - -model = solph.Model(es) -model.solve(solver='cbc') -model.results() -results = processing.results(model) From f03c2f79b0e4fd2ac424e5f0b974386871e47a84 Mon Sep 17 00:00:00 2001 From: philipp235 <70669937+philipp235@users.noreply.github.com> Date: Tue, 8 Sep 2020 23:27:17 +0200 Subject: [PATCH 11/21] Add files via upload --- src/oemof/solph/1_system.py | 95 +++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 src/oemof/solph/1_system.py diff --git a/src/oemof/solph/1_system.py b/src/oemof/solph/1_system.py new file mode 100644 index 000000000..8a270ea35 --- /dev/null +++ b/src/oemof/solph/1_system.py @@ -0,0 +1,95 @@ +import oemof.solph as solph +import oemof.solph.exnet as ex +from oemof.outputlib import * +import math +import pandas as pd +import time + +# Please run this file as normal project +# when oemof verison with exnet is installed + +datetimeindex = pd.date_range('1/1/2017', periods=3, freq='H') + +es = solph.EnergySystem(timeindex=datetimeindex) +input_list = [] +input_list.append(-1) +i = 0 +while i < 101: + ob = i / 100 + input_list.append(ob) + i = i + 1 +output_list = [] +output_list.append(0) + +for ob in input_list: + if ob != -1: + s = math.sqrt(ob) + output_list.append(s) + +b_gas1 = ex.GasBus(label='b_gas1', slack=True) +b_gas2 = ex.GasBus(label='b_gas2') +b_gas3 = ex.GasBus(label='b_gas3') + + +gas_line_12 = ex.GasLine(label='gas_line_12', + inputs={b_gas1: solph.Flow(nominal_value=200)}, + outputs={b_gas2: solph.Flow(nominal_value=200)}, + input_list=input_list, + output_list=output_list, + K_1=100, + conv_factor=0.99) + +gas_line_13 = ex.GasLine(label='gas_line_13', + inputs={b_gas1: solph.Flow(nominal_value=200)}, + outputs={b_gas3: solph.Flow(nominal_value=200)}, + input_list=input_list, + output_list=output_list, + K_1=100, + conv_factor=0.99) + +gas_line_23 = ex.GasLine(label='gas_line_23', + inputs={b_gas2: solph.Flow(nominal_value=200)}, + outputs={b_gas3: solph.Flow(nominal_value=200)}, + input_list=input_list, + output_list=output_list, + K_1=100, + conv_factor=0.99) + +gas_line_32 = ex.GasLine(label='gas_line_32', + inputs={b_gas3: solph.Flow(nominal_value=200)}, + outputs={b_gas2: solph.Flow(nominal_value=200)}, + input_list=input_list, + output_list=output_list, + K_1=100, + conv_factor=0.99) + +source_1 = solph.Source(label='source_1', + outputs={b_gas1: solph.Flow(nominal_value=300)}) + + +sink_1 = solph.Sink(label='sink_1', + inputs={b_gas2: solph.Flow(nominal_value=100, + actual_value=[1, 1, 0], + fixed=True)}) + +sink_2 = solph.Sink(label='sink_2', + inputs={b_gas3: solph.Flow(nominal_value=100, + actual_value=[1, 0, 1], + fixed=True)}) + +es.add(b_gas1) +es.add(b_gas2) +es.add(b_gas3) +es.add(gas_line_12) +es.add(gas_line_13) +es.add(gas_line_23) +es.add(gas_line_32) + +es.add(source_1) +es.add(sink_1) +es.add(sink_2) + +model = solph.Model(es) +model.solve(solver='cbc') +model.results() +results = processing.results(model) From 013ede769387ffee2ca7534c76dc138519ffc97f Mon Sep 17 00:00:00 2001 From: philipp235 <70669937+philipp235@users.noreply.github.com> Date: Tue, 8 Sep 2020 23:49:11 +0200 Subject: [PATCH 12/21] Update exnet.py --- src/oemof/solph/exnet.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/oemof/solph/exnet.py b/src/oemof/solph/exnet.py index 74cfc5b7b..e52cdf459 100644 --- a/src/oemof/solph/exnet.py +++ b/src/oemof/solph/exnet.py @@ -13,8 +13,7 @@ 02.03.2020 - philipp.gradl@stud.unileoben.ac.at ''' from oemof.solph.network import Bus, Transformer -from pyomo.core import * - +from pyomo.core import Var, SimpleBlock, Set, Piecewise, Constraint class GasBus(Bus): def __init__(self, *args, **kwargs): From 70960309c25b5e3680d1a6100103ca1da35dfb96 Mon Sep 17 00:00:00 2001 From: philipp235 <70669937+philipp235@users.noreply.github.com> Date: Tue, 8 Sep 2020 23:49:29 +0200 Subject: [PATCH 13/21] Delete 1_system.py --- src/oemof/solph/1_system.py | 95 ------------------------------------- 1 file changed, 95 deletions(-) delete mode 100644 src/oemof/solph/1_system.py diff --git a/src/oemof/solph/1_system.py b/src/oemof/solph/1_system.py deleted file mode 100644 index 8a270ea35..000000000 --- a/src/oemof/solph/1_system.py +++ /dev/null @@ -1,95 +0,0 @@ -import oemof.solph as solph -import oemof.solph.exnet as ex -from oemof.outputlib import * -import math -import pandas as pd -import time - -# Please run this file as normal project -# when oemof verison with exnet is installed - -datetimeindex = pd.date_range('1/1/2017', periods=3, freq='H') - -es = solph.EnergySystem(timeindex=datetimeindex) -input_list = [] -input_list.append(-1) -i = 0 -while i < 101: - ob = i / 100 - input_list.append(ob) - i = i + 1 -output_list = [] -output_list.append(0) - -for ob in input_list: - if ob != -1: - s = math.sqrt(ob) - output_list.append(s) - -b_gas1 = ex.GasBus(label='b_gas1', slack=True) -b_gas2 = ex.GasBus(label='b_gas2') -b_gas3 = ex.GasBus(label='b_gas3') - - -gas_line_12 = ex.GasLine(label='gas_line_12', - inputs={b_gas1: solph.Flow(nominal_value=200)}, - outputs={b_gas2: solph.Flow(nominal_value=200)}, - input_list=input_list, - output_list=output_list, - K_1=100, - conv_factor=0.99) - -gas_line_13 = ex.GasLine(label='gas_line_13', - inputs={b_gas1: solph.Flow(nominal_value=200)}, - outputs={b_gas3: solph.Flow(nominal_value=200)}, - input_list=input_list, - output_list=output_list, - K_1=100, - conv_factor=0.99) - -gas_line_23 = ex.GasLine(label='gas_line_23', - inputs={b_gas2: solph.Flow(nominal_value=200)}, - outputs={b_gas3: solph.Flow(nominal_value=200)}, - input_list=input_list, - output_list=output_list, - K_1=100, - conv_factor=0.99) - -gas_line_32 = ex.GasLine(label='gas_line_32', - inputs={b_gas3: solph.Flow(nominal_value=200)}, - outputs={b_gas2: solph.Flow(nominal_value=200)}, - input_list=input_list, - output_list=output_list, - K_1=100, - conv_factor=0.99) - -source_1 = solph.Source(label='source_1', - outputs={b_gas1: solph.Flow(nominal_value=300)}) - - -sink_1 = solph.Sink(label='sink_1', - inputs={b_gas2: solph.Flow(nominal_value=100, - actual_value=[1, 1, 0], - fixed=True)}) - -sink_2 = solph.Sink(label='sink_2', - inputs={b_gas3: solph.Flow(nominal_value=100, - actual_value=[1, 0, 1], - fixed=True)}) - -es.add(b_gas1) -es.add(b_gas2) -es.add(b_gas3) -es.add(gas_line_12) -es.add(gas_line_13) -es.add(gas_line_23) -es.add(gas_line_32) - -es.add(source_1) -es.add(sink_1) -es.add(sink_2) - -model = solph.Model(es) -model.solve(solver='cbc') -model.results() -results = processing.results(model) From 86b9feded964425f82deb72096b2c8e1cdf4d119 Mon Sep 17 00:00:00 2001 From: philipp235 <70669937+philipp235@users.noreply.github.com> Date: Wed, 9 Sep 2020 00:06:58 +0200 Subject: [PATCH 14/21] Update blocks.py --- src/oemof/solph/blocks.py | 79 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/src/oemof/solph/blocks.py b/src/oemof/solph/blocks.py index 4ca7ec4fd..c67739bee 100644 --- a/src/oemof/solph/blocks.py +++ b/src/oemof/solph/blocks.py @@ -26,6 +26,85 @@ from pyomo.core.base.block import SimpleBlock +class GasLineBlock(SimpleBlock): + CONSTRAINT_GROUP = True + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + def _create(self, group=None): + if group is None: + return None + + m = self.parent_block() + + self.GASLINE_PL = Set(initialize=[n for n in group]) + + self.GAS_BUSES = Set(initialize=[s for s in m.es.nodes + if isinstance(s, GasBus)]) + + self.pressure = Var(self.GAS_BUSES, m.TIMESTEPS, bounds=(0, 1)) + + self.delta_pressure = Var(self.GASLINE_PL, m.TIMESTEPS, bounds=(-1, 1)) + + self.energy_flow = Var(self.GASLINE_PL, m.TIMESTEPS) + + for n in self.GASLINE_PL: + for t in m.TIMESTEPS: + for ob in list(n.outputs.keys()): + if ob.slack is True: + self.pressure[ob, t].value = 1 + self.pressure[ob, t].fix() + + for ob in list(n.inputs.keys()): + if ob.slack is True: + self.pressure[ob, t].value = 1 + self.pressure[ob, t].fix() + + self.piecewise = Piecewise(self.GASLINE_PL, + m.TIMESTEPS, + self.energy_flow, + self.delta_pressure, + pw_pts=n.input_list, + pw_constr_type='EQ', + pw_repn='CC', + f_rule=n.output_list) + + def flow_eq_pressure(block, n, t): + expr = 0 + expr += (self.pressure[list(n.outputs.keys())[0], t] - + self.pressure[list(n.inputs.keys())[0], t]) + expr += self.delta_pressure[n, t] + + return expr == 0 + + self.flow_eq_pressure = Constraint(self.GASLINE_PL, + m.TIMESTEPS, + rule=flow_eq_pressure) + + def energy_flow_out(block, n, t): + expr = 0 + expr += - m.flow[n, list(n.outputs.keys())[0], t] + expr += self.energy_flow[n, t]*n.K_1 + + return expr == 0 + + self.energy_flow_out = Constraint(self.GASLINE_PL, + m.TIMESTEPS, + rule=energy_flow_out) + + def energy_flow_in(block, n, t): + expr = 0 + expr += - m.flow[list(n.inputs.keys())[0], n, t]*n.conv_factor + expr += self.energy_flow[n, t]*n.K_1 + + return expr == 0 + + self.energy_flow_in = Constraint(self.GASLINE_PL, + m.TIMESTEPS, + rule=energy_flow_in) + + class Flow(SimpleBlock): r""" Flow block with definitions for standard flows. From 272fd96f5d1186db6d6ea3b130f80c59fa0e3e18 Mon Sep 17 00:00:00 2001 From: philipp235 <70669937+philipp235@users.noreply.github.com> Date: Wed, 9 Sep 2020 00:08:36 +0200 Subject: [PATCH 15/21] Update custom.py --- src/oemof/solph/custom.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/oemof/solph/custom.py b/src/oemof/solph/custom.py index 76e6e7bc1..213d41fcd 100644 --- a/src/oemof/solph/custom.py +++ b/src/oemof/solph/custom.py @@ -37,6 +37,26 @@ from oemof.solph.plumbing import sequence +class GasBus(Bus): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.slack = kwargs.get('slack', False) + self.p_max = kwargs.get('p_max', 1) + self.p_min = kwargs.get('p_min', -1) + + +class GasLine(Transformer): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.conv_factor = kwargs.get('conv_factor', 1) + self.K_1 = kwargs.get('K_1') + self.input_list = list(kwargs.get('input_list', [])) + self.output_list = list(kwargs.get('output_list', [])) + + def constraint_group(self): + return GasLineBlock + + class ElectricalBus(Bus): r"""A electrical bus object. Every node has to be connected to Bus. This Bus is used in combination with ElectricalLine objects for linear optimal From 4d06463a8333bfe8673c1fc2212eb98c531a0d49 Mon Sep 17 00:00:00 2001 From: philipp235 <70669937+philipp235@users.noreply.github.com> Date: Wed, 9 Sep 2020 00:08:52 +0200 Subject: [PATCH 16/21] Delete exnet.py --- src/oemof/solph/exnet.py | 114 --------------------------------------- 1 file changed, 114 deletions(-) delete mode 100644 src/oemof/solph/exnet.py diff --git a/src/oemof/solph/exnet.py b/src/oemof/solph/exnet.py deleted file mode 100644 index e52cdf459..000000000 --- a/src/oemof/solph/exnet.py +++ /dev/null @@ -1,114 +0,0 @@ -# -*- coding: utf-8 -*- -''' -General description -------------------- -The goal of GasBus and GasLine is to implement a piecewise linear model. -The gas flow is the result of a pressure difference and -has a non-linear relationship. - -Installation requirements -------------------------- -This example depends on an installation of oemof - -02.03.2020 - philipp.gradl@stud.unileoben.ac.at -''' -from oemof.solph.network import Bus, Transformer -from pyomo.core import Var, SimpleBlock, Set, Piecewise, Constraint - -class GasBus(Bus): - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self.slack = kwargs.get('slack', False) - self.p_max = kwargs.get('p_max', 1) - self.p_min = kwargs.get('p_min', -1) - - -class GasLineBlock(SimpleBlock): - CONSTRAINT_GROUP = True - - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - - def _create(self, group=None): - if group is None: - return None - - m = self.parent_block() - - self.GASLINE_PL = Set(initialize=[n for n in group]) - - self.GAS_BUSES = Set(initialize=[s for s in m.es.nodes - if isinstance(s, GasBus)]) - - self.pressure = Var(self.GAS_BUSES, m.TIMESTEPS, bounds=(0, 1)) - - self.delta_pressure = Var(self.GASLINE_PL, m.TIMESTEPS, bounds=(-1, 1)) - - self.energy_flow = Var(self.GASLINE_PL, m.TIMESTEPS) - - for n in self.GASLINE_PL: - for t in m.TIMESTEPS: - for ob in list(n.outputs.keys()): - if ob.slack is True: - self.pressure[ob, t].value = 1 - self.pressure[ob, t].fix() - - for ob in list(n.inputs.keys()): - if ob.slack is True: - self.pressure[ob, t].value = 1 - self.pressure[ob, t].fix() - - self.piecewise = Piecewise(self.GASLINE_PL, - m.TIMESTEPS, - self.energy_flow, - self.delta_pressure, - pw_pts=n.input_list, - pw_constr_type='EQ', - pw_repn='CC', - f_rule=n.output_list) - - def flow_eq_pressure(block, n, t): - expr = 0 - expr += (self.pressure[list(n.outputs.keys())[0], t] - - self.pressure[list(n.inputs.keys())[0], t]) - expr += self.delta_pressure[n, t] - - return expr == 0 - - self.flow_eq_pressure = Constraint(self.GASLINE_PL, - m.TIMESTEPS, - rule=flow_eq_pressure) - - def energy_flow_out(block, n, t): - expr = 0 - expr += - m.flow[n, list(n.outputs.keys())[0], t] - expr += self.energy_flow[n, t]*n.K_1 - - return expr == 0 - - self.energy_flow_out = Constraint(self.GASLINE_PL, - m.TIMESTEPS, - rule=energy_flow_out) - - def energy_flow_in(block, n, t): - expr = 0 - expr += - m.flow[list(n.inputs.keys())[0], n, t]*n.conv_factor - expr += self.energy_flow[n, t]*n.K_1 - - return expr == 0 - - self.energy_flow_in = Constraint(self.GASLINE_PL, - m.TIMESTEPS, - rule=energy_flow_in) - - -class GasLine(Transformer): - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self.conv_factor = kwargs.get('conv_factor', 1) - self.K_1 = kwargs.get('K_1') - self.input_list = list(kwargs.get('input_list', [])) - self.output_list = list(kwargs.get('output_list', [])) - - def constraint_group(self): - return GasLineBlock From 023d3b77dbc19e93fd90b80aae9c1d499c871167 Mon Sep 17 00:00:00 2001 From: philipp235 <70669937+philipp235@users.noreply.github.com> Date: Wed, 9 Sep 2020 00:10:55 +0200 Subject: [PATCH 17/21] Update blocks.py --- src/oemof/solph/blocks.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/oemof/solph/blocks.py b/src/oemof/solph/blocks.py index c67739bee..23a663037 100644 --- a/src/oemof/solph/blocks.py +++ b/src/oemof/solph/blocks.py @@ -103,8 +103,8 @@ def energy_flow_in(block, n, t): self.energy_flow_in = Constraint(self.GASLINE_PL, m.TIMESTEPS, rule=energy_flow_in) - - + + class Flow(SimpleBlock): r""" Flow block with definitions for standard flows. From 1d5602d336696d473869e8cd77e9e89cebf048ce Mon Sep 17 00:00:00 2001 From: philipp235 <70669937+philipp235@users.noreply.github.com> Date: Wed, 9 Sep 2020 00:16:33 +0200 Subject: [PATCH 18/21] Update blocks.py --- src/oemof/solph/blocks.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/oemof/solph/blocks.py b/src/oemof/solph/blocks.py index 23a663037..e82f9ccaf 100644 --- a/src/oemof/solph/blocks.py +++ b/src/oemof/solph/blocks.py @@ -23,6 +23,7 @@ from pyomo.core import NonNegativeReals from pyomo.core import Set from pyomo.core import Var +from pyomo.core import Piecewise from pyomo.core.base.block import SimpleBlock From 0f3f771cdd93a6017e05f404e15c759eb1f47d07 Mon Sep 17 00:00:00 2001 From: philipp235 <70669937+philipp235@users.noreply.github.com> Date: Wed, 9 Sep 2020 00:18:28 +0200 Subject: [PATCH 19/21] Update blocks.py --- src/oemof/solph/blocks.py | 80 --------------------------------------- 1 file changed, 80 deletions(-) diff --git a/src/oemof/solph/blocks.py b/src/oemof/solph/blocks.py index e82f9ccaf..4ca7ec4fd 100644 --- a/src/oemof/solph/blocks.py +++ b/src/oemof/solph/blocks.py @@ -23,89 +23,9 @@ from pyomo.core import NonNegativeReals from pyomo.core import Set from pyomo.core import Var -from pyomo.core import Piecewise from pyomo.core.base.block import SimpleBlock -class GasLineBlock(SimpleBlock): - CONSTRAINT_GROUP = True - - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - - def _create(self, group=None): - if group is None: - return None - - m = self.parent_block() - - self.GASLINE_PL = Set(initialize=[n for n in group]) - - self.GAS_BUSES = Set(initialize=[s for s in m.es.nodes - if isinstance(s, GasBus)]) - - self.pressure = Var(self.GAS_BUSES, m.TIMESTEPS, bounds=(0, 1)) - - self.delta_pressure = Var(self.GASLINE_PL, m.TIMESTEPS, bounds=(-1, 1)) - - self.energy_flow = Var(self.GASLINE_PL, m.TIMESTEPS) - - for n in self.GASLINE_PL: - for t in m.TIMESTEPS: - for ob in list(n.outputs.keys()): - if ob.slack is True: - self.pressure[ob, t].value = 1 - self.pressure[ob, t].fix() - - for ob in list(n.inputs.keys()): - if ob.slack is True: - self.pressure[ob, t].value = 1 - self.pressure[ob, t].fix() - - self.piecewise = Piecewise(self.GASLINE_PL, - m.TIMESTEPS, - self.energy_flow, - self.delta_pressure, - pw_pts=n.input_list, - pw_constr_type='EQ', - pw_repn='CC', - f_rule=n.output_list) - - def flow_eq_pressure(block, n, t): - expr = 0 - expr += (self.pressure[list(n.outputs.keys())[0], t] - - self.pressure[list(n.inputs.keys())[0], t]) - expr += self.delta_pressure[n, t] - - return expr == 0 - - self.flow_eq_pressure = Constraint(self.GASLINE_PL, - m.TIMESTEPS, - rule=flow_eq_pressure) - - def energy_flow_out(block, n, t): - expr = 0 - expr += - m.flow[n, list(n.outputs.keys())[0], t] - expr += self.energy_flow[n, t]*n.K_1 - - return expr == 0 - - self.energy_flow_out = Constraint(self.GASLINE_PL, - m.TIMESTEPS, - rule=energy_flow_out) - - def energy_flow_in(block, n, t): - expr = 0 - expr += - m.flow[list(n.inputs.keys())[0], n, t]*n.conv_factor - expr += self.energy_flow[n, t]*n.K_1 - - return expr == 0 - - self.energy_flow_in = Constraint(self.GASLINE_PL, - m.TIMESTEPS, - rule=energy_flow_in) - - class Flow(SimpleBlock): r""" Flow block with definitions for standard flows. From a2c07f5ee235d0ce142d59479c9592511f9cdb6b Mon Sep 17 00:00:00 2001 From: philipp235 <70669937+philipp235@users.noreply.github.com> Date: Wed, 9 Sep 2020 00:19:44 +0200 Subject: [PATCH 20/21] Update custom.py --- src/oemof/solph/custom.py | 80 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/src/oemof/solph/custom.py b/src/oemof/solph/custom.py index 213d41fcd..bdeb4d289 100644 --- a/src/oemof/solph/custom.py +++ b/src/oemof/solph/custom.py @@ -20,6 +20,7 @@ import logging +from pyomo.core import Piecewise from pyomo.core.base.block import SimpleBlock from pyomo.environ import Binary from pyomo.environ import BuildAction @@ -57,6 +58,85 @@ def constraint_group(self): return GasLineBlock +class GasLineBlock(SimpleBlock): + CONSTRAINT_GROUP = True + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + def _create(self, group=None): + if group is None: + return None + + m = self.parent_block() + + self.GASLINE_PL = Set(initialize=[n for n in group]) + + self.GAS_BUSES = Set(initialize=[s for s in m.es.nodes + if isinstance(s, GasBus)]) + + self.pressure = Var(self.GAS_BUSES, m.TIMESTEPS, bounds=(0, 1)) + + self.delta_pressure = Var(self.GASLINE_PL, m.TIMESTEPS, bounds=(-1, 1)) + + self.energy_flow = Var(self.GASLINE_PL, m.TIMESTEPS) + + for n in self.GASLINE_PL: + for t in m.TIMESTEPS: + for ob in list(n.outputs.keys()): + if ob.slack is True: + self.pressure[ob, t].value = 1 + self.pressure[ob, t].fix() + + for ob in list(n.inputs.keys()): + if ob.slack is True: + self.pressure[ob, t].value = 1 + self.pressure[ob, t].fix() + + self.piecewise = Piecewise(self.GASLINE_PL, + m.TIMESTEPS, + self.energy_flow, + self.delta_pressure, + pw_pts=n.input_list, + pw_constr_type='EQ', + pw_repn='CC', + f_rule=n.output_list) + + def flow_eq_pressure(block, n, t): + expr = 0 + expr += (self.pressure[list(n.outputs.keys())[0], t] - + self.pressure[list(n.inputs.keys())[0], t]) + expr += self.delta_pressure[n, t] + + return expr == 0 + + self.flow_eq_pressure = Constraint(self.GASLINE_PL, + m.TIMESTEPS, + rule=flow_eq_pressure) + + def energy_flow_out(block, n, t): + expr = 0 + expr += - m.flow[n, list(n.outputs.keys())[0], t] + expr += self.energy_flow[n, t]*n.K_1 + + return expr == 0 + + self.energy_flow_out = Constraint(self.GASLINE_PL, + m.TIMESTEPS, + rule=energy_flow_out) + + def energy_flow_in(block, n, t): + expr = 0 + expr += - m.flow[list(n.inputs.keys())[0], n, t]*n.conv_factor + expr += self.energy_flow[n, t]*n.K_1 + + return expr == 0 + + self.energy_flow_in = Constraint(self.GASLINE_PL, + m.TIMESTEPS, + rule=energy_flow_in) + + class ElectricalBus(Bus): r"""A electrical bus object. Every node has to be connected to Bus. This Bus is used in combination with ElectricalLine objects for linear optimal From 686dcc87aaf9e3199dc8c8bb9184a5df91e85795 Mon Sep 17 00:00:00 2001 From: philipp235 <70669937+philipp235@users.noreply.github.com> Date: Fri, 25 Sep 2020 00:44:36 +0200 Subject: [PATCH 21/21] Add files via upload --- tests/test_scripts/test_solph/gasline_test.py | 95 +++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 tests/test_scripts/test_solph/gasline_test.py diff --git a/tests/test_scripts/test_solph/gasline_test.py b/tests/test_scripts/test_solph/gasline_test.py new file mode 100644 index 000000000..8a270ea35 --- /dev/null +++ b/tests/test_scripts/test_solph/gasline_test.py @@ -0,0 +1,95 @@ +import oemof.solph as solph +import oemof.solph.exnet as ex +from oemof.outputlib import * +import math +import pandas as pd +import time + +# Please run this file as normal project +# when oemof verison with exnet is installed + +datetimeindex = pd.date_range('1/1/2017', periods=3, freq='H') + +es = solph.EnergySystem(timeindex=datetimeindex) +input_list = [] +input_list.append(-1) +i = 0 +while i < 101: + ob = i / 100 + input_list.append(ob) + i = i + 1 +output_list = [] +output_list.append(0) + +for ob in input_list: + if ob != -1: + s = math.sqrt(ob) + output_list.append(s) + +b_gas1 = ex.GasBus(label='b_gas1', slack=True) +b_gas2 = ex.GasBus(label='b_gas2') +b_gas3 = ex.GasBus(label='b_gas3') + + +gas_line_12 = ex.GasLine(label='gas_line_12', + inputs={b_gas1: solph.Flow(nominal_value=200)}, + outputs={b_gas2: solph.Flow(nominal_value=200)}, + input_list=input_list, + output_list=output_list, + K_1=100, + conv_factor=0.99) + +gas_line_13 = ex.GasLine(label='gas_line_13', + inputs={b_gas1: solph.Flow(nominal_value=200)}, + outputs={b_gas3: solph.Flow(nominal_value=200)}, + input_list=input_list, + output_list=output_list, + K_1=100, + conv_factor=0.99) + +gas_line_23 = ex.GasLine(label='gas_line_23', + inputs={b_gas2: solph.Flow(nominal_value=200)}, + outputs={b_gas3: solph.Flow(nominal_value=200)}, + input_list=input_list, + output_list=output_list, + K_1=100, + conv_factor=0.99) + +gas_line_32 = ex.GasLine(label='gas_line_32', + inputs={b_gas3: solph.Flow(nominal_value=200)}, + outputs={b_gas2: solph.Flow(nominal_value=200)}, + input_list=input_list, + output_list=output_list, + K_1=100, + conv_factor=0.99) + +source_1 = solph.Source(label='source_1', + outputs={b_gas1: solph.Flow(nominal_value=300)}) + + +sink_1 = solph.Sink(label='sink_1', + inputs={b_gas2: solph.Flow(nominal_value=100, + actual_value=[1, 1, 0], + fixed=True)}) + +sink_2 = solph.Sink(label='sink_2', + inputs={b_gas3: solph.Flow(nominal_value=100, + actual_value=[1, 0, 1], + fixed=True)}) + +es.add(b_gas1) +es.add(b_gas2) +es.add(b_gas3) +es.add(gas_line_12) +es.add(gas_line_13) +es.add(gas_line_23) +es.add(gas_line_32) + +es.add(source_1) +es.add(sink_1) +es.add(sink_2) + +model = solph.Model(es) +model.solve(solver='cbc') +model.results() +results = processing.results(model)