def compute(es=None, **arguments): """Creates the optimization model, solves it and writes back results to energy system object Parameters ---------- es : :class:`oemof.solph.network.EnergySystem` object Energy system holding nodes, grouping functions and other important information. **arguments : key word arguments Arguments passed from command line """ if es.temporal is not None: m = Model(es, objective_weighting=es.temporal['weighting']) else: m = Model(es) logging.info('Model creation time: ' + stopwatch()) m.receive_duals() if arguments['--debug']: filename = 'renpass_model.lp' logging.info('Writing lp-file to {}.'.format(filename)) m.write(filename, io_options={'symbolic_solver_labels': True}) m.solve(solver=arguments['--solver'], solve_kwargs={'tee': True}) logging.info('Optimization time: ' + stopwatch()) return m
def setUpClass(cls): cls.period = 24 cls.es = EnergySystem(timeindex=pandas.date_range( '2016-01-01', periods=cls.period, freq='H')) # 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 = Transformer( label='diesel', inputs={b_diesel: Flow(variable_costs=2)}, outputs={ b_el1: Flow(variable_costs=1, investment=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)}, capacity_loss=0.00, initial_capacity=0, invest_relation_input_capacity=1 / 6, invest_relation_output_capacity=1 / 6, inflow_conversion_factor=1, outflow_conversion_factor=0.8, fixed_costs=35, investment=Investment(ep_costs=0.4), ) cls.demand_values = [100] * 8760 cls.demand_values[0] = 0.0 demand = Sink(label="demand_el", inputs={ b_el2: Flow(nominal_value=1, actual_value=cls.demand_values, fixed=True) }) 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_bus_to_sink_outputs_in_results_dataframe(self): bus = Bus(uid="bus") source = FS( label="source", outputs={bus: Flow(nominal_value=1, actual_value=0.5, fixed=True)}) sink = Sink(label="sink", inputs={bus: Flow(nominal_value=1)}) es = self.es om = OM(es) es.results = om.results() es.results[bus][sink] = [0.7] rdf = RDF(energy_system=es) try: eq_( rdf.loc[(slice(None), slice(None), slice(None), "sink"), :].val[0], 0.7, "Output from bus to sink does not have the correct value.") except KeyError: self.failed = True if self.failed: ok_( False, "Output from bus to sink does not appear in results dataframe." ) es.results[bus][bus] = [-1] rdf = RDF(energy_system=es) try: eq_( rdf.loc[(slice(None), slice(None), slice(None), "sink"), :].val[0], 0.7, "Output from bus to sink does not have the correct value.") except KeyError: self.failed = True if self.failed: ok_( False, "Output from bus (with duals) to sink " + "does not appear in results dataframe.")
def test_issue_74(self): Storage.optimization_options.update({'investment': True}) bus = Bus(uid="bus") store = Storage(uid="store", inputs=[bus], outputs=[bus], c_rate_out=0.1, c_rate_in=0.1) sink = Sink(uid="sink", inputs=[bus], val=[1]) es = self.es om = OM(es) om.objective.set_value(-1) es.results = om.results() try: es.dump() except AttributeError as ae: self.failed = ae if self.failed: ok_( False, "EnergySystem#dump should not raise `AttributeError`: \n" + " Error message: " + str(self.failed))
def optimize(input_data_dir, results_data_dir, solver='cbc', debug=False): r""" Takes the specified datapackage, creates an energysystem and solves the optimization problem. """ # create energy system object logging.info("Creating EnergySystem from datapackage") es = EnergySystem.from_datapackage( os.path.join(input_data_dir, "datapackage.json"), attributemap={}, typemap=TYPEMAP, ) # create model from energy system (this is just oemof.solph) logging.info("Creating the optimization model") m = Model(es) # if you want dual variables / shadow prices uncomment line below # m.receive_duals() # save lp file together with optimization results if debug: lp_file_dir = os.path.join(results_data_dir, 'model.lp') logging.info(f"Saving the lp-file to {lp_file_dir}") m.write(lp_file_dir, io_options={'symbolic_solver_labels': True}) # select solver 'gurobi', 'cplex', 'glpk' etc logging.info(f'Solving the problem using {solver}') m.solve(solver=solver) # get the results from the the solved model(still oemof.solph) es.results = m.results() es.params = outputlib.processing.parameter_as_dict(es) # now we use the write results method to write the results in oemof-tabular # format logging.info(f'Writing the results to {results_data_dir}') es.dump(results_data_dir)
def run_add_constraints_example(solver='cbc', nologg=False): if not nologg: logging.basicConfig(level=logging.INFO) # ##### creating an oemof solph optimization model, nothing special here ## # create an energy system object for the oemof solph nodes es = EnergySystem(timeindex=pd.date_range('1/1/2017', periods=4, freq='H')) # add some nodes boil = Bus(label="oil", balanced=False) blig = Bus(label="lignite", balanced=False) b_el = Bus(label="b_el") es.add(boil, blig, b_el) sink = Sink(label="Sink", inputs={ b_el: Flow(nominal_value=40, actual_value=[0.5, 0.4, 0.3, 1], fixed=True) }) pp_oil = Transformer( label='pp_oil', inputs={boil: Flow()}, outputs={b_el: Flow(nominal_value=50, variable_costs=25)}, conversion_factors={b_el: 0.39}) pp_lig = Transformer( label='pp_lig', inputs={blig: Flow()}, outputs={b_el: Flow(nominal_value=50, variable_costs=10)}, conversion_factors={b_el: 0.41}) es.add(sink, pp_oil, pp_lig) # create the model om = Model(energysystem=es) # add specific emission values to flow objects if source is a commodity bus for s, t in om.flows.keys(): if s is boil: om.flows[s, t].emission_factor = 0.27 # t/MWh if s is blig: om.flows[s, t].emission_factor = 0.39 # t/MWh emission_limit = 60e3 # add the outflow share om.flows[(boil, pp_oil)].outflow_share = [1, 0.5, 0, 0.3] # Now we are going to add a 'sub-model' and add a user specific constraint # first we add a pyomo Block() instance that we can use to add our # constraints. Then, we add this Block to our previous defined # Model instance and add the constraints. myblock = po.Block() # create a pyomo set with the flows (i.e. list of tuples), # there will of course be only one flow inside this set, the one we used to # add outflow_share myblock.MYFLOWS = po.Set(initialize=[ k for (k, v) in om.flows.items() if hasattr(v, 'outflow_share') ]) # pyomo does not need a po.Set, we can use a simple list as well myblock.COMMODITYFLOWS = [ k for (k, v) in om.flows.items() if hasattr(v, 'emission_factor') ] # add the sub-model to the oemof Model instance om.add_component('MyBlock', myblock) def _inflow_share_rule(m, s, e, t): """pyomo rule definition: Here we can use all objects from the block or the om object, in this case we don't need anything from the block except the newly defined set MYFLOWS. """ expr = (om.flow[s, e, t] >= om.flows[s, e].outflow_share[t] * sum(om.flow[i, o, t] for (i, o) in om.FLOWS if o == e)) return expr myblock.inflow_share = po.Constraint(myblock.MYFLOWS, om.TIMESTEPS, rule=_inflow_share_rule) # add emission constraint myblock.emission_constr = po.Constraint( expr=(sum(om.flow[i, o, t] for (i, o) in myblock.COMMODITYFLOWS for t in om.TIMESTEPS) <= emission_limit)) # solve and write results to dictionary # you may print the model with om.pprint() om.solve(solver=solver) logging.info("Successfully finished.")
import oemof.tabular.tools.postprocessing as pp # create path for results (we use the datapackage_dir to store results) results_path = 'results' if not os.path.exists(results_path): os.makedirs(results_path) # create energy system object es = EnergySystem.from_datapackage( os.path.join("./datapackage", "datapackage.json"), attributemap={}, typemap=TYPEMAP, ) # create model from energy system (this is just oemof.solph) m = Model(es) # if you want dual variables / shadow prices uncomment line below # m.receive_duals() # select solver 'gurobi', 'cplex', 'glpk' etc m.solve("glpk") # get the results from the the solved model(still oemof.solph) m.results = m.results() # now we use the write results method to write the results in oemof-tabular # format pp.write_results(m, results_path) print("process completed")
) # create path for results (we use the datapackage_dir to store results) results_path = os.path.join( os.path.expanduser("~"), "oemof-results", name, "output") if not os.path.exists(results_path): os.makedirs(results_path) # create energy system object es = EnergySystem.from_datapackage( os.path.join(datapackage_dir, "datapackage.json"), attributemap={}, typemap=TYPEMAP, ) # create model from energy system (this is just oemof.solph) m = Model(es) # if you want dual variables / shadow prices uncomment line below # m.receive_duals() # select solver 'gurobi', 'cplex', 'glpk' etc m.solve("cbc") # get the results from the the solved model(still oemof.solph) m.results = m.results() # now we use the write results method to write the results in oemof-tabular # format pp.write_results(m, results_path)
def run_basic_energysystem(args): n_val_wind = args[0] n_val_solar = args[1] start = time.time() # initialize and provide data energysystem = EnergySystem(timeindex=datetimeindex) # buses bcoal = Bus(label='coal', balanced=False) bgas = Bus(label='gas', balanced=False) bel = Bus(label='electricity') energysystem.add(bcoal, bgas, bel) # sources energysystem.add( Source(label='wind', outputs={ bel: Flow(actual_value=data['wind'], nominal_value=n_val_wind, fixed=True) })) energysystem.add( Source(label='pv', outputs={ bel: Flow(actual_value=data['pv'], nominal_value=n_val_solar, fixed=True) })) # excess and shortage to avoid infeasibilies energysystem.add(Sink(label='excess_el', inputs={bel: Flow()})) energysystem.add( Source(label='shortage_el', outputs={bel: Flow(variable_costs=200)})) # demands (electricity/heat) energysystem.add( Sink(label='demand_el', inputs={ bel: Flow(nominal_value=65, actual_value=data['demand_el'], fixed=True) })) # power plants energysystem.add( Transformer(label='pp_coal', inputs={bcoal: Flow()}, outputs={bel: Flow(nominal_value=20.2, variable_costs=25)}, conversion_factors={bel: 0.39})) energysystem.add( Transformer(label='pp_gas', inputs={bgas: Flow()}, outputs={bel: Flow(nominal_value=41, variable_costs=40)}, conversion_factors={bel: 0.50})) # create optimization model based on energy_system optimization_model = Model(energysystem=energysystem) # solve problem optimization_model.solve(solver=solver, solve_kwargs={ 'tee': False, 'keepfiles': False }) results = outputlib.processing.results(optimization_model) results_el = outputlib.views.node(results, 'electricity') el_sequences = results_el['sequences'] el_prod = el_sequences[[(('wind', 'electricity'), 'flow'), (('pv', 'electricity'), 'flow'), (('pp_coal', 'electricity'), 'flow'), (('pp_gas', 'electricity'), 'flow'), (('shortage_el', 'electricity'), 'flow')]] inputs = outputlib.processing.convert_keys_to_strings( outputlib.processing.parameter_as_dict(optimization_model)) nom_vals = [[key, value['scalars']['nominal_value']] for key, value in inputs.items() if 'nominal_value' in value['scalars']] nom_vals = pd.DataFrame(nom_vals, columns=['flow', 'nominal_value']) summed_flows = [ (key, value['sequences'].sum()[0]) for key, value in outputlib.processing.convert_keys_to_strings( results).items() ] summed_flows = pd.DataFrame(summed_flows, columns=['flow', 'summed_flows']) end = time.time() print('simulation lasted: ', end - start, 'sec') return el_prod
temp_env=input_data['temp_env'], u_value=u_value, expandable=True, capacity_cost=50, storage_capacity_cost=400, minimum_storage_capacity=1, # TODO: setting to zero should give an error! min_storage_level=input_data['min_storage_level'], max_storage_level=input_data['max_storage_level'], efficiency=1, marginal_cost=0.0001) energysystem.add(bus_heat, heat_source, shortage, excess, heat_demand, thermal_storage) # Create and solve the optimization model optimization_model = Model(energysystem) optimization_model.solve(solver=solver, solve_kwargs={ 'tee': False, 'keepfiles': False }) # Get results results = processing.results(optimization_model) string_results = processing.convert_keys_to_strings(results) sequences = {k: v['sequences'] for k, v in string_results.items()} df = pd.concat(sequences, axis=1) # Print storage sizing built_storage_capacity = results[thermal_storage, None]['scalars']['invest'] initial_storage_capacity = results[thermal_storage,
here = os.path.abspath(os.path.dirname(__file__)) name = 'simple_model' preprocessed = sys.argv[1] optimized = sys.argv[2] if not os.path.exists(optimized): os.mkdir(optimized) es = EnergySystem.from_datapackage( os.path.join(preprocessed, "datapackage.json"), attributemap={}, typemap=TYPEMAP, ) # create model from energy system (this is just oemof.solph) m = Model(es) # select solver 'gurobi', 'cplex', 'glpk' etc m.solve(solver='cbc') # get the results from the the solved model(still oemof.solph) es.results = m.results() # now we use the write results method to write the results in oemoftabular # format es.dump(optimized)
es.add(Source(label="gen_1", outputs={ b_1: Flow(nominal_value=100, variable_costs=50)})) es.add(Sink(label="load_0", inputs={ b_0: Flow(nominal_value=150, actual_value=[0, 1], fixed=True)})) es.add(Sink(label="load_1", inputs={ b_1: Flow(nominal_value=150, actual_value=[1, 0], fixed=True)})) m = Model(energysystem=es) # m.write('transshipment.lp', io_options={'symbolic_solver_labels': True}) m.solve(solver='cbc', solve_kwargs={'tee': True, 'keepfiles': False}) m.results() graph = create_nx_graph(es, m) draw_graph(graph, plot=True, layout='neato', node_size=3000, node_color={ 'b_0': '#cd3333', 'b_1': '#7EC0EE', 'b_2': '#eeac7e'})
inflow_conversion_factor=0.9, outflow_conversion_factor=0.9) # an excess and a shortage variable can help to avoid infeasible problems excess_el = Sink(label='excess_el', inputs={bus_el: Flow()}) shortage_el = Source(label='shortage_el', outputs={bus_el: Flow(variable_costs=100000)}) # ## Add all to the energysystem energysystem.add(bus_coal, bus_gas, bus_el, source_gas, source_coal, wind, pv, demand_el, pp_coal, storage_el, excess_el, shortage_el) # ## Create an Optimization Model and solve it # create optimization model based on energy_system optimization_model = Model(energysystem=energysystem) # solve problem optimization_model.solve(solver=solver) # ## Get results results_main = outputlib.processing.results(optimization_model) results_meta = outputlib.processing.meta_results(optimization_model) params = outputlib.processing.parameter_as_dict(energysystem) # ## Pass results to energysystem.results object before saving energysystem.results['main'] = results_main energysystem.results['meta'] = results_meta energysystem.params = params # ## Save results - Dump the energysystem (to ~/home/user/.oemof by default)
es = EnergySystem() el0 = elec.ElectricalBus('el0') el1 = elec.ElectricalBus('el1') el2 = elec.ElectricalBus('el2') line0 = elec.Line(from_bus=el0, to_bus=el1, capacity=60, reactance=0.0001) line1 = elec.Line(from_bus=el1, to_bus=el2, capacity=60, reactance=0.0001) line2 = elec.Line(from_bus=el2, to_bus=el0, capacity=60, reactance=0.0001) gen0 = fc.Dispatchable("gen0", capacity=100, bus=el0, marginal_cost=50, carrier='coal') gen1 = fc.Dispatchable("gen1", capacity=100, bus=el1, marginal_cost=25, carrier='gas') load0 = fc.Load("load0", bus=el2, amount=100, profile=[1]) es.add(el0, el1, el2, line0, line1, line2, gen0, gen1, load0) m = Model(es) m.solve() m.write('lopf-model.lp')
bus=heat_bus_NDE, tech="grid", carrier="heat", marginal_cost=costs.at["vom", "excess_heat"])) es.add( fc.Excess(label="excess_heat_SDE", bus=heat_bus_SDE, tech="grid", carrier="heat", marginal_cost=costs.at["vom", "excess_heat"])) print("Demand data have been read.") # OEMoF Model Creation m = Model(es) print("OSeEM-DE is ready to solve.") # LP File m.write(os.path.join(results_path, "investment.lp"), io_options={"symbolic_solver_labels": True}) # Shadow Price m.receive_duals() # Solve m.solve("cbc") m.results = m.results() print("OSeEM-DE solved the optimization problem. :)")
def test_depreciated_graph_call(): es = ES() om = Model(energysystem=es) warnings.filterwarnings('ignore', category=FutureWarning) graph.create_nx_graph(optimization_model=om)
examples = ["dispatch", "investment", "foreignkeys"] for example in examples: print("Runnig postprocessing example with datapackage {}".format(example)) es = EnergySystem.from_datapackage( pkg.resource_filename( "oemof.tabular", "examples/datapackages/{}/datapackage.json".format(example), ), attributemap={}, typemap=TYPEMAP, ) es.timeindex = es.timeindex[0:5] m = Model(es) m.solve(solver="cbc") # skip foreignkeys example as not all buses are present if example != "foreignkeys": br = pp.bus_results(es, m.results(), select="scalars") if example == "investment": br["bus0"].xs([es.groups["bus0"], "invest"], level=[1, 2]) pp.supply_results(results=m.results(), es=es, bus=["heat-bus"]) pp.supply_results(results=m.results(), es=es, bus=["bus0", "bus1"]) pp.demand_results(results=m.results(), es=es, bus=["bus0", "bus1"])
def test_dispatch_one_time_step(solver='cbc', periods=1): """Create an energy system and optimize the dispatch at least costs.""" # ######################### create energysystem components ################ Node.registry = None # resource buses bgas = Bus(label='gas', balanced=False) # electricity and heat bel = Bus(label='b_el') bth = Bus(label='b_th') # an excess and a shortage variable can help to avoid infeasible problems excess_el = Sink(label='excess_el', inputs={bel: Flow()}) # sources wind = Source( label='wind', outputs={bel: Flow(actual_value=0.5, nominal_value=66.3, fixed=True)}) # demands (electricity/heat) demand_el = Sink( label='demand_elec', inputs={bel: Flow(nominal_value=85, actual_value=0.3, fixed=True)}) demand_th = Sink( label='demand_therm', inputs={bth: Flow(nominal_value=40, actual_value=0.2, fixed=True)}) # combined heat and power plant (chp) pp_chp = Transformer(label='pp_chp', inputs={bgas: Flow()}, outputs={ bel: Flow(nominal_value=30, variable_costs=42), bth: Flow(nominal_value=40) }, conversion_factors={ bel: 0.3, bth: 0.4 }) # heatpump with a coefficient of performance (COP) of 3 b_heat_source = Bus(label='b_heat_source') heat_source = Source(label='heat_source', outputs={b_heat_source: Flow()}) cop = 3 heat_pump = Transformer(label='heat_pump', inputs={ bel: Flow(), b_heat_source: Flow() }, outputs={bth: Flow(nominal_value=10)}, conversion_factors={ bel: 1 / 3, b_heat_source: (cop - 1) / cop }) energysystem = EnergySystem(timeindex=[1]) energysystem.add(bgas, bel, bth, excess_el, wind, demand_el, demand_th, pp_chp, b_heat_source, heat_source, heat_pump) # ################################ optimization ########################### # create optimization model based on energy_system optimization_model = Model(energysystem=energysystem, timeincrement=1) # solve problem optimization_model.solve(solver=solver) # write back results from optimization object to energysystem optimization_model.results() # ################################ results ################################ data = views.node(processing.results(om=optimization_model), 'b_el') # generate results to be evaluated in tests results = data['sequences'].sum(axis=0).to_dict() test_results = { (('wind', 'b_el'), 'flow'): 33, (('b_el', 'demand_elec'), 'flow'): 26, (('b_el', 'excess_el'), 'flow'): 5, (('b_el', 'heat_pump'), 'flow'): 3, } for key in test_results.keys(): eq_(int(round(results[key])), int(round(test_results[key])))
label='storage', inputs={bel: Flow()}, outputs={bel: Flow()}, capacity_loss=0.00, initial_capacity=0.5, invest_relation_input_capacity=1 / 6, invest_relation_output_capacity=1 / 6, inflow_conversion_factor=0.95, outflow_conversion_factor=0.95, investment=Investment(ep_costs=costs['storage']['epc'])) ################################################################# # Create model and solve ################################################################# m = Model(energysystem) # om.write(filename, io_options={'symbolic_solver_labels': True}) m.solve(solver='cbc', solve_kwargs={'tee': True}) results = processing.results(m) views.node(results, 'storage') views.node(results, 'micro_grid')['sequences'].plot(drawstyle='steps') plt.show() graph = create_graph(energysystem, m) draw_graph(graph,
shortage = Source(label='shortage', outputs={bus_heat: Flow(variable_costs=1e6)}) excess = Sink(label='excess', inputs={bus_heat: Flow()}) heat_demand = Sink( label='heat_demand', inputs={bus_heat: Flow(nominal_value=1, fix=demand_timeseries)}) thermal_storage = facades.StratifiedThermalStorage( label='thermal_storage', bus=bus_heat, diameter=input_data['diameter'], height=input_data['height'], temp_h=input_data['temp_h'], temp_c=input_data['temp_c'], temp_env=input_data['temp_env'], u_value=u_value, min_storage_level=input_data['min_storage_level'], max_storage_level=input_data['max_storage_level'], capacity=input_data['maximum_heat_flow_charging'], efficiency=1, marginal_cost=0.0001) energysystem.add(bus_heat, heat_source, shortage, excess, heat_demand, thermal_storage) # Create and solve the optimization model optimization_model = Model(energysystem)
Source( label="gen_0", outputs={b_el0: Flow(nominal_value=100, variable_costs=50)}, ) ) es.add( Source( label="gen_1", outputs={b_el1: Flow(nominal_value=100, variable_costs=25)}, ) ) es.add(Sink(label="load", inputs={b_el2: Flow(nominal_value=100, fix=[1, 1])})) m = Model(energysystem=es) # m.write('lopf.lp', io_options={'symbolic_solver_labels': True}) m.solve(solver="cbc", solve_kwargs={"tee": True, "keepfiles": False}) m.results() graph = create_nx_graph(es) draw_graph( graph, plot=True, layout="neato", node_size=3000,
outputs={bel: Flow(nominal_value=30e6, variable_costs=23.2)}, conversion_factors={bel: 0.38}, )) energysystem.add( Transformer( label="pp_oil", inputs={boil: Flow()}, outputs={bel: Flow(nominal_value=98e6, variable_costs=8)}, conversion_factors={bel: 0.33}, )) # ################################ optimization ########################### # create optimization model based on energy_system optimization_model = Model(energysystem=energysystem) # solve problem optimization_model.solve(solver=solver, solve_kwargs={ "tee": True, "keepfiles": False }) # write back results from optimization object to energysystem optimization_model.results() # ################################ results ################################ # subset of results that includes all flows into and from electrical bus # sequences are stored within a pandas.DataFrames and scalars e.g.
ext = fc.ExtractionTurbine(label='ext', carrier=gas, tech='ext', commitable=False, electricity_bus=el1, heat_bus=heat, capacity=10, thermal_efficiency=0.4, electric_efficiency=0.4, condensing_efficiency=0.5) conv = fc.Conversion('conv', from_bus=el2, to_bus=heat, efficiency=0.95, capacity=2) load = fc.Load('load', bus=el1, amount=1000, profile=[0.005, 0.00034, 0.0434]) # Connection conn = fc.Connection('conn', from_bus=el1, to_bus=el2, loss=0.07, capacity=100) es.add(el1, el2, heat, biomass, bp, st, wind, sto, conv, load, conn, gas, ext) m = Model(es) m.pprint() m.write('model.lp', io_options={'symbolic_solver_labels': True})
for f in os.listdir('data/sequences/'): fname = os.path.join('data', 'sequences', f) df = pd.read_csv(fname, sep=';') df = df.iloc[:timesteps] df.to_csv(fname, index=False, sep=';') config = building.read_build_config('config.toml') es = EnergySystem.from_datapackage( "datapackage.json", attributemap={}, typemap=facades.TYPEMAP, ) m = Model(es) m.write('tmp.lp', io_options={"symbolic_solver_labels": True}) m.receive_duals() m.solve('gurobi') m.results = m.results() if os.path.exists('results'): shutil.rmtree('results') os.mkdir('results') pp.write_results(m, 'results', scalars=False)
def test_dispatch_example(solver='cbc', periods=24*5): """Create an energy system and optimize the dispatch at least costs.""" Node.registry = None filename = os.path.join(os.path.dirname(__file__), 'input_data.csv') data = pd.read_csv(filename, sep=",") # ######################### create energysystem components ################ # resource buses bcoal = Bus(label='coal', balanced=False) bgas = Bus(label='gas', balanced=False) boil = Bus(label='oil', balanced=False) blig = Bus(label='lignite', balanced=False) # electricity and heat bel = Bus(label='b_el') bth = Bus(label='b_th') # an excess and a shortage variable can help to avoid infeasible problems excess_el = Sink(label='excess_el', inputs={bel: Flow()}) # shortage_el = Source(label='shortage_el', # outputs={bel: Flow(variable_costs=200)}) # sources ep_wind = economics.annuity(capex=1000, n=20, wacc=0.05) wind = Source(label='wind', outputs={bel: Flow( fix=data['wind'], investment=Investment(ep_costs=ep_wind, existing=100))}) ep_pv = economics.annuity(capex=1500, n=20, wacc=0.05) pv = Source(label='pv', outputs={bel: Flow( fix=data['pv'], investment=Investment(ep_costs=ep_pv, existing=80))}) # demands (electricity/heat) demand_el = Sink(label='demand_elec', inputs={bel: Flow(nominal_value=85, fix=data['demand_el'])}) demand_th = Sink(label='demand_therm', inputs={bth: Flow(nominal_value=40, fix=data['demand_th'])}) # power plants pp_coal = Transformer(label='pp_coal', inputs={bcoal: Flow()}, outputs={bel: Flow(nominal_value=20.2, variable_costs=25)}, conversion_factors={bel: 0.39}) pp_lig = Transformer(label='pp_lig', inputs={blig: Flow()}, outputs={bel: Flow(nominal_value=11.8, variable_costs=19)}, conversion_factors={bel: 0.41}) pp_gas = Transformer(label='pp_gas', inputs={bgas: Flow()}, outputs={bel: Flow(nominal_value=41, variable_costs=40)}, conversion_factors={bel: 0.50}) pp_oil = Transformer(label='pp_oil', inputs={boil: Flow()}, outputs={bel: Flow(nominal_value=5, variable_costs=50)}, conversion_factors={bel: 0.28}) # combined heat and power plant (chp) pp_chp = Transformer(label='pp_chp', inputs={bgas: Flow()}, outputs={bel: Flow(nominal_value=30, variable_costs=42), bth: Flow(nominal_value=40)}, conversion_factors={bel: 0.3, bth: 0.4}) # heatpump with a coefficient of performance (COP) of 3 b_heat_source = Bus(label='b_heat_source') heat_source = Source(label='heat_source', outputs={b_heat_source: Flow()}) cop = 3 heat_pump = Transformer(label='el_heat_pump', inputs={bel: Flow(), b_heat_source: Flow()}, outputs={bth: Flow(nominal_value=10)}, conversion_factors={ bel: 1/3, b_heat_source: (cop-1)/cop}) datetimeindex = pd.date_range('1/1/2012', periods=periods, freq='H') energysystem = EnergySystem(timeindex=datetimeindex) energysystem.add(bcoal, bgas, boil, bel, bth, blig, excess_el, wind, pv, demand_el, demand_th, pp_coal, pp_lig, pp_oil, pp_gas, pp_chp, b_heat_source, heat_source, heat_pump) # ################################ optimization ########################### # create optimization model based on energy_system optimization_model = Model(energysystem=energysystem) # solve problem optimization_model.solve(solver=solver) # write back results from optimization object to energysystem optimization_model.results() # ################################ results ################################ # generic result object results = processing.results(om=optimization_model) # subset of results that includes all flows into and from electrical bus # sequences are stored within a pandas.DataFrames and scalars e.g. # investment values within a pandas.Series object. # in this case the entry data['scalars'] does not exist since no investment # variables are used data = views.node(results, 'b_el') # generate results to be evaluated in tests comp_results = data['sequences'].sum(axis=0).to_dict() comp_results['pv_capacity'] = results[(pv, bel)]['scalars'].invest comp_results['wind_capacity'] = results[(wind, bel)]['scalars'].invest test_results = { (('wind', 'b_el'), 'flow'): 9239, (('pv', 'b_el'), 'flow'): 1147, (('b_el', 'demand_elec'), 'flow'): 7440, (('b_el', 'excess_el'), 'flow'): 6261, (('pp_chp', 'b_el'), 'flow'): 477, (('pp_lig', 'b_el'), 'flow'): 850, (('pp_gas', 'b_el'), 'flow'): 934, (('pp_coal', 'b_el'), 'flow'): 1256, (('pp_oil', 'b_el'), 'flow'): 0, (('b_el', 'el_heat_pump'), 'flow'): 202, 'pv_capacity': 44, 'wind_capacity': 246, } for key in test_results.keys(): eq_(int(round(comp_results[key])), int(round(test_results[key])))
energysystem.add( Transformer(label='heat_pump', inputs={ bel: Flow(), b_heat_source: Flow() }, outputs={bth: Flow(nominal_value=10)}, conversion_factors={ bel: 1 / 3, b_heat_source: (cop - 1) / cop })) # ################################ optimization ########################### # create optimization model based on energy_system optimization_model = Model(energysystem=energysystem) # solve problem optimization_model.solve(solver=solver, solve_kwargs={ 'tee': True, 'keepfiles': False }) # write back results from optimization object to energysystem optimization_model.results() # ################################ results ################################ # subset of results that includes all flows into and from electrical bus # sequences are stored within a pandas.DataFrames and scalars e.g.
in_breakpoints = np.arange(0, 110, 25) pwltf = solph.custom.PiecewiseLinearTransformer( label='pwltf', inputs={b_gas: solph.Flow(nominal_value=100, variable_costs=1)}, outputs={b_el: solph.Flow()}, in_breakpoints=in_breakpoints, conversion_function=conv_func, pw_repn='CC') # 'CC', 'DCC', 'INC', 'MC' # DCC TODO: Solve problem in outputlib with DCC energysystem.add(pwltf) # create and solve the optimization model optimization_model = Model(energysystem) optimization_model.write('/home/jann/Desktop/my_model.lp', io_options={'symbolic_solver_labels': True}) optimization_model.solve(solver=solver, solve_kwargs={ 'tee': False, 'keepfiles': False }) results = outputlib.processing.results(optimization_model) string_results = outputlib.processing.convert_keys_to_strings(results) df = outputlib.processing.create_dataframe(optimization_model) sequences = {k: v['sequences'] for k, v in string_results.items()} df = pd.concat(sequences, axis=1) df[('efficiency', None, None)] = df[('pwltf', 'electricity', 'flow')].divide(df[('gas', 'pwltf',
thdemand = Sink(label='thdemand', inputs={thbus: Flow(nominal_value=40, actual_value=data['demand_th'], fixed=True)}) # Creating the excess sink and the shortage source excess_el = Sink(label='excess_el', inputs={elbus: Flow()}) shortage_el = Source(label='shortage_el', outputs={elbus: Flow(variable_costs=1e20)}) # Adding all the components to the energy system es.add(excess_el, shortage_el, thdemand, eldemand, heat_pump, el_storage, chp_gas, pv, gas, gasbus, thbus, elbus) # Create the model for optimization and run the optimization opt_model = Model(es) opt_model.solve(solver='cbc') logging.info('Optimization successful') # Post-processing and data visualization results_main = outputlib.processing.results(opt_model) results_meta = outputlib.processing.meta_results(opt_model) params = outputlib.processing.parameter_as_dict(es) print(results_meta) print(results_main[gasbus, chp_gas]['sequences'].head())
def diesel_only(mode, feedin, initial_batt_cap, cost, iterstatus=None, PV_source=True, storage_source=True, logger=False): if logger == 1: logger.define_logging() ##################################### Initialize the energy system################################################## # times = pd.DatetimeIndex(start='04/01/2017', periods=10, freq='H') times = feedin.index energysystem = EnergySystem(timeindex=times) # switch on automatic registration of entities of EnergySystem-object=energysystem Node.registry = energysystem # add components b_el = Bus(label='electricity') b_dc = Bus(label='electricity_dc') b_oil = Bus(label='diesel_source') demand_feedin = feedin['demand_el'] Sink(label='demand', inputs={ b_el: Flow(actual_value=demand_feedin, nominal_value=1, fixed=True) }) Sink(label='excess', inputs={b_el: Flow()}) Source(label='diesel', outputs={b_oil: Flow()}) generator1 = custom.DieselGenerator( label='pp_oil_1', fuel_input={b_oil: Flow(variable_costs=cost['pp_oil_1']['var'])}, electrical_output={ b_el: Flow(nominal_value=186, min=0.3, max=1, nonconvex=NonConvex(om_costs=cost['pp_oil_1']['o&m']), fixed_costs=cost['pp_oil_1']['fix']) }, fuel_curve={ '1': 42, '0.75': 33, '0.5': 22, '0.25': 16 }) generator2 = custom.DieselGenerator( label='pp_oil_2', fuel_input={b_oil: Flow(variable_costs=cost['pp_oil_2']['var'])}, electrical_output={ b_el: Flow(nominal_value=186, min=0.3, max=1, nonconvex=NonConvex(om_costs=cost['pp_oil_2']['o&m']), fixed_costs=cost['pp_oil_2']['fix'], variable_costs=0) }, fuel_curve={ '1': 42, '0.75': 33, '0.5': 22, '0.25': 16 }) generator3 = custom.DieselGenerator( label='pp_oil_3', fuel_input={b_oil: Flow(variable_costs=cost['pp_oil_3']['var'])}, electrical_output={ b_el: Flow(nominal_value=320, min=0.3, max=1, nonconvex=NonConvex(om_costs=cost['pp_oil_3']['o&m']), fixed_costs=cost['pp_oil_3']['fix'], variable_costs=0) }, fuel_curve={ '1': 73, '0.75': 57, '0.5': 38, '0.25': 27 }) # List all generators in a list called gen_set gen_set = [generator1, generator2, generator3] sim_params = get_sim_params(cost) if mode == 'simulation': nominal_cap_pv = sim_params['pv']['nominal_capacity'] inv_pv = None nominal_cap_batt = sim_params['storage']['nominal_capacity'] inv_batt = None elif mode == 'investment': nominal_cap_pv = None inv_pv = sim_params['pv']['investment'] nominal_cap_batt = None inv_batt = sim_params['storage']['investment'] else: raise ( UserWarning, 'Energysystem cant be build. Check if mode is spelled correctely. ' 'It can be either [simulation] or [investment]') if PV_source == 1: PV = Source(label='PV', outputs={ b_dc: Flow(nominal_value=nominal_cap_pv, fixed_costs=cost['pv']['fix'], actual_value=feedin['PV'], fixed=True, investment=inv_pv) }) else: PV = None if storage_source == 1: storage = components.GenericStorage( label='storage', inputs={b_dc: Flow()}, outputs={ b_dc: Flow(variable_costs=cost['storage']['var'], fixed_costs=cost['storage']['fix']) }, nominal_capacity=nominal_cap_batt, capacity_loss=0.00, initial_capacity=initial_batt_cap, nominal_input_capacity_ratio=0.546, nominal_output_capacity_ratio=0.546, inflow_conversion_factor=0.92, outflow_conversion_factor=0.92, capacity_min=0.5, capacity_max=1, investment=inv_batt, initial_iteration=iterstatus) else: storage = None if storage_source == 1 or PV_source == 1: inverter1 = add_inverter(b_dc, b_el, 'Inv_pv') ################################# optimization ############################ # create Optimization model based on energy_system logging.info("Create optimization problem") m = Model(energysystem) ################################# constraints ############################ sr_requirement = 0.2 sr_limit = demand_feedin * sr_requirement rm_requirement = 0.4 rm_limit = demand_feedin * rm_requirement constraints.spinning_reserve_constraint(m, sr_limit, groups=gen_set, storage=storage) # constraints.n1_constraint(m, demand_feedin, groups=gen_set) constraints.gen_order_constraint(m, groups=gen_set) constraints.rotating_mass_constraint(m, rm_limit, groups=gen_set, storage=storage) return [m, gen_set]
examples = ["dispatch", "investment", "foreignkeys"] for example in examples: print("Runnig postprocessing example with datapackage {}".format(example)) es = EnergySystem.from_datapackage( pkg.resource_filename( "oemof.tabular", "examples/datapackages/{}/datapackage.json".format(example), ), attributemap={}, typemap=TYPEMAP, ) es.timeindex = es.timeindex[0:5] m = Model(es) m.solve(solver="cbc") # skip foreignkeys example as not all buses are present if example != "foreignkeys": br = pp.bus_results(es, m.results(), select="scalars") if example == "investment": br["bus0"].xs([es.groups["bus0"], "invest"], level=[1, 2]) pp.supply_results(results=m.results(), es=es, bus=["heat-bus"]) pp.supply_results(results=m.results(), es=es, bus=["bus0", "bus1"]) pp.demand_results(results=m.results(), es=es, bus=["bus0", "bus1"])